Tuesday, 15 October 2013

Workflow

Workflow differences in MS AX Versions


AX 2009
AX 2012


> Separate workflow component have to be installed  > Requires IIS and .NET Business Connector > Requires additional security setup
> Simplify workflow deployment and installation > Host the .NET Workflow runtime in AOS   > Separate installation no longer required.
> Workflow server components need to be installed on a web server running Internet Information Services (IIS).
>  Workflow server components are now automatically installed when installing the Microsoft Dynamics AX AOS. This new deployment significantly simplifies the administrative effort required to set up the workflow infrastructure.
> Forward only, sequential workflows.  > Only interactive elements (tasks and approvals)  > Support for sub-workflows
>  Expand workflow capabilities by providing broader applicability   > Introduce branching   > Introduce automated tasks  > Introduce line-item workflow support   > Introduce line-item workflow support  > Introduce parallelism
> Business user configures workflows using a Microsoft Dynamics AX client form
> Improve the workflow editing experience and usability  > Introduce a graphical workflow editor  > Support for “drag-and-drop” of workflow elements  > Familiar property editing experience
No Flow-Control Elements
 > Several new elements were added to help you design workflows. These elements will help create workflows that have alternate branches or branches that run at the same time. These elements include the following:   1.) Conditional decision: A point at which a workflow divides into two branches. The system will decide which branch to use by evaluating the submitted document to determine whether it meets a specified condition. 2.) Manual decision: A point at which a workflow divides into two branches. A user must take an action, and the action taken will determine which branch is used to process the submitted document. 3.) Parallel activity: A workflow element that includes two or more branches that run at the same time.
> No advanced workflow controls
> Workflow for Microsoft Dynamics AX 2012 supports advanced workflow flow controls. They include starting and ending elements, manual and conditional decisions, parallel activity and parallel branches, automated tasks, and sequence flows. Business users can now author workflows that correspond more closely to real life business processes using graphical elements that help them to better visualize the process flow.
> No Automated Task
> An automated task is a type of workflow element that does not involve human interaction. For example, an automated task can perform a credit check, run a report, or update a record. The purpose of an automated task is to execute business logic as part of a workflow that is implemented to automate a business process.
> No Line-Item Workflows
> Workflows for line items on a document can be implemented. By providing support for line-item workflows, workflow now supports more business process scenarios. For example, you might define a workflow for timesheets where each line item on the timesheet is approved by a specific project manager.   > A line-item workflow is configured and instantiated for different types of line item records that are related to a header. A header-line workflow can be configured to pause until other workflows are run on any number of line records.

Creation of Workflow module and workflow example in ax 2012:

In Microsoft Dynamics AX, modules are enabled for workflow. However, in some cases, you will need to create a new module that contains workflow. In each module that contains workflow, a Workflows list menu item must be added to the Setup pane. The following procedures are described in this topic:
  • Creating a new module enumeration.
  • Creating a display menu item for the Workflows list.
  • Creating a menu for the new module.
  • How to display the new menu in the client.
To Add a Module to the ModuleAxapta Base Enum
1.      In the Application Object Tree (AOT), expand the Data Dictionary node, expand Base Enums, right-click ModuleAxapta, and then click New Element. A new enumeration displays under the ModuleAxapta node.
2.      Right-click the new enumeration, and then click Properties.
3.      In the Properties sheet, select the Label property, and then enter the label of the new module.
To Create a Display Menu Item for the Workflows List
1.      In the AOT, expand the Menu Items node.
2.      Right-click the Display node, and then click New Menu Item. A new menu item displays under the Display node.
3.      Right-click the new display menu item, and then click Properties.
4.      In the Properties sheet, set the following properties.
Property
Value
Name
Set to WorkflowConfigurations<xxx> where <xxx> is replaced by a reference to the name of the new module. For example, you could set this value to WorkflowConfigurationsRecruit for a new module named Recruiting.
Label
Set text or a label that represents the text for the workflows list in the client.
ObjectType
Set to Form.
Object
Set to WorkflowTableListPage.
EnumTypeParameter
Set to ModuleAxapta.
EnumParameter
Set to the enum created in the preceding procedure.
5.      In the AOT, right-click the new display menu item, and then click Save.
After the new module enum and display menu item are created, you can add them to the Menus node.
To Create a Menu for a New Module
1.      In the AOT, right-click the Menus node, and then click New Menu. A new menu displays under the Menus node.
2.      Right-click the new menu, and then click Properties.
3.      In the Properties sheet, set the following properties.
Property
Value
Name
Set to a label or name of the new module.
Label
Set to a label that represents the text to display for the new menu in the client.
4.      In the AOT, right-click the new menu, point to New, and then click New Submenu. A submenu node displays under menu node created in the previous step.
5.      Right-click the new submenu node, and then click Properties.
6.      In the Properties sheet, set the following properties.
Property
Value
Name
Set to Setup or another label that represents the text for the Setup pane in the client.
Label
Set to Setup or another label that represents the text for the Setup pane in the client.
NormalImage
Set to 3478. This will display a gears icon for the setup pane.
ImageLocation
Set to EmbeddedResource.
7.      In the AOT, right-click the Setup node created in the previous step, point to New, and then click New Menu item. A new menu item displays under the Setup node.
8.      Right-click the new menu item, and then click Properties.
9.      In the Properties sheet, set the MenuItemName property to the display menu item created in the previous procedure.
10.    In the AOT, right-click the new menu item, and then click Save.
After the menu for the new module is created, you must add a reference to the menu in the MainMenu node to display the menu in the client.
To Add a Menu to the Client
1.      In the AOT, expand the Menus node, right click MainMenus, point to New, and then click Menu reference. The Select: Menus window is displayed.
2.      In the Select: Menus window, select the new module menu that you created in the previous procedure, and drag the menu to the MainMenu node in the AOT.
3.      In the AOT, right-click the MainMenu node, and then click Save.
In which module ur working go thaty module and open module(procurement and sourcing)workflow open nd create new one then select our workflow type giving flow chart
Forms-totorial_workflow processor form –open and once excute
   Then workflow approval starting
Home- (workflow approved person)- work items
                                                                 - work items assigned to me
                                                                 - workflow history
Steps:
First create one enum type (approval state)
One table having
Enum field
Submitted by field
Submitted date field
And one edt field
Here in that table 5 methods mandatory
1.Find():
public static WFTable find(Name    Name, boolean _forupdate = false)
{
    WFTable WFTable;//        leaveRequests;
;
    WFTable.selectForUpdate(_forupdate);
    if(Name)
    {
        select WFTable
            where WFTable.Name == Name;
    }
    return WFTable;
}
2.findRecId():
static WFTable findRecId(RecId    _recId,
                           boolean  _forUpdate = false)
{
    WFTable WFTable;
    ;
    if (_recId)
    {
        WFTable.selectForUpdate(_forUpdate);
        select firstonly WFTable
            where WFTable.RecId == _recId;
    }
    return WFTable;
}
3.can submit():
public boolean canSubmit()
{
;
    if(this.WFEnabled == ApprovalState::NotSubmitted  && this.RecId)
        return true;
    else
        return false;
}
4.cansubmittedworkflow():
Display boolean CanSubmitToWorkFlow(str _workflowtype =  '')
{
 return this.canSubmit();
}
5.UpdateWorkflowState ():
public static void UpdateWorkflowState(RefRecId _recId, ApprovalState _state)
    {
        WFTable WFTable = WFTable::findRecId(_recId, true);
         //Vacations       vacations;
        ttsBegin;
        //if(WFTable.IsWorkflowToBeResubmitted)
           // nsgLeaveRequests.IsWorkflowToBeResubmitted = false;
        WFTable.WFEnabled = _state;
        /*nsgLeaveRequests.update();
       //Commented and added by Britto on 16/10/2012
       // if(nsgLeaveRequests.WorkflowState == WFDummiesWorkflowState::Approved && SystemSetup::find().AutomaticVacationTransfromEP)
       if(nsgLeaveRequests.WorkflowState == NSGLeaveReqWorkflowState::ApprovedII )
        {
         /*   Vacations::CreateFromEPLeaveRequest(nsgLeaveRequests.LeaveRequestId,
                                                nsgLeaveRequests.EmplId,
                                                nsgLeaveRequests.VacationType,
                                                nsgLeaveRequests.LeaveFrom,
                                                nsgLeaveRequests.LeaveTo,
                                                NASVacationInitiateType::FormRequest,
                                                nsgLeaveRequests.Destination);*/
            //nsgLeaveRequests.VacationTransId =Vacations::CreateFromEPLeaveReq(nsgLeaveRequests);
            nsgLeaveRequests.Comments += "\n" + "Final Approval" +"\n" + nsgLeaveRequests.mostRecentComment();
        }
          if(nsgLeaveRequests.WorkflowState == NSGLeaveReqWorkflowState::ApprovedII )
        {
                  nsgLeaveRequests.Comments += "\n" + "HR Dept Comments" +"\n" + nsgLeaveRequests.mostRecentComment();
        }
           if(nsgLeaveRequests.WorkflowState == NSGLeaveReqWorkflowState::Approved )
        {
              nsgLeaveRequests.Comments += "\n" + "Dept Head Comment" +"\n" + nsgLeaveRequests.mostRecentComment();
        }
        */
          WFTable.update();
        ttsCommit;
   }
Then next Create a qury and add data sorce as our table
And then create form and desighn the form
Here in design properties set this three property as mandatory
(Workflow enabled-yes
Workflow datsource-ourtable name
Workflow type- our workflow type             ::this properties are set in last)
And then go to AOT:
1.Create workflow category
2.workflow type-rc-addins –create workflow type through wizard
3.approval- rc-addins –create workflow Approval through wizard
5. Incremental CIL
6. drag the approval to our workflow type supported element
And then
Write code in classes:
WFApprEventHandler():
Classdeclaratio():
class WFApprEventHandler implements    WorkflowElementCanceledEventHandler,  WorkflowElemChangeRequestedEventHandler,
                                                        WorkflowElementCompletedEventHandler, WorkflowElementReturnedEventHandler,
                                                        WorkflowElementStartedEventHandler, WorkflowElementDeniedEventHandler,
                                                        WorkflowWorkItemsCreatedEventHandler
{
}
Canceled():
public void canceled(WorkflowElementEventArgs _workflowElementEventArgs)
{
     WFTable::UpdateWorkflowState(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::Cancelled);
}
changeRequested():
public void changeRequested(WorkflowElementEventArgs _workflowElementEventArgs)
{
    WFTable::UpdateWorkflowState(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::ChangeRequest);
}
Completed():
public void completed(WorkflowElementEventArgs _workflowElementEventArgs)
{
    WFTable::UpdateWorkflowState(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::WorkflowCompleted);
}
created ():
public void created(WorkflowWorkItemsEventArgs _workflowWorkItemsEventArgs)
{
    // TODO:  Write code to execute once work items are created.
}
denied ():
public void denied(WorkflowElementEventArgs _workflowElementEventArgs)
{
   WFTable::UpdateWorkflowState(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::Returned);
}
returned ():
public void returned(WorkflowElementEventArgs _workflowElementEventArgs)
{
    WFTable::UpdateWorkflowState(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::Returned);
}
Started():
public void started(WorkflowElementEventArgs _workflowElementEventArgs)
{
    WFTable::UpdateWorkflowState(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::NotSubmitted);
}
WFTypeEventHandler():
Classdeclaration():
class WFTypeEventHandler implements    WorkflowCanceledEventHandler,  WorkflowCompletedEventHandler,
                                                        WorkflowStartedEventHandler
{
}
Canceled():
public void canceled(WorkflowEventArgs _workflowEventArgs)
{
    WFTable::UpdateWorkflowState(_workflowEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::Cancelled);
}
completed ():
public void completed(WorkflowEventArgs _workflowEventArgs)
{
    WFTable::UpdateWorkflowState(_workflowEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::WorkflowCompleted);
}
started ():
public void started(WorkflowEventArgs _workflowEventArgs)
{
    WFTable::UpdateWorkflowState(_workflowEventArgs.parmWorkflowContext().parmRecId(), ApprovalState::NotSubmitted);
}
WFTypeSubmitManager():
Classdeclaration():
public class WFTypeSubmitManager
{
    Name                        Name;
    WFTable                     WFTable;
    WorkflowVersionTable        workflowConfigurationTable;
    WorkflowComment             workflowComment;
    boolean                     submit;
    WorkflowWorkItemTable       workflowWorkItemTable;
    UserId                      userId;
    MenuItemName                menuItemName;
    WorkflowTypeName            workflowTemplateName;
    EPWorkflowControlContext    workflowControlContext;
}
dialogOk():
public boolean dialogOk()
{
    WorkflowSubmitDialog workflowSubmitDialog;
    WorkflowWorkItemActionDialog workflowWorkItemActionDialog;
    boolean ok;
    ;
    if (menuItemName == menuitemactionstr(WFTypeSubmitMenuItem))
    {
        workflowSubmitDialog = WorkflowSubmitDialog::construct(this.parmWorkflowConfigurationTable());
        workflowSubmitDialog.run();
        this.parmWorkflowComment(workflowSubmitDialog.parmWorkflowComment());
        ok = workflowSubmitDialog.parmIsClosedOK();
    }
    else if (menuItemName == menuitemactionstr(WFApprResubmitMenuItem))
    {
        workflowWorkItemActionDialog = WorkflowWorkItemActionDialog::construct( workflowWorkItemTable,
        WorkflowWorkItemActionType::Resubmit,
        new MenuFunction(menuitemactionstr(WFApprResubmitMenuItem), MenuItemType::Action));
        workflowWorkItemActionDialog.run();
        this.parmWorkflowComment(workflowWorkItemActionDialog.parmWorkflowComment());
        ok = workflowWorkItemActionDialog.parmIsClosedOK();
        userId = workflowWorkItemActionDialog.parmTargetUser();
    }
    return ok;
}
Init():
public void init( Common _documentRecord,
                    MenuItemName _menuItemName,
                    WorkflowVersionTable _workflowConfigurationTable,
                    WorkflowWorkItemTable _workflowWorkItemTable,
                    EPWorkflowControlContext _workflowControlContext
                    )
{
    this.parmWFTable(_documentRecord);
    this.parmSubmit(_menuItemName == menuitemactionstr (WFTypeSubmitMenuItem));
    this.parmMenuItemName(_menuItemName);
    if (_workflowControlContext)
    {
        this.parmWorkflowControlContext(_workflowControlContext);
        this.parmWorkflowWorkItemtable (_workflowControlContext.getActiveWorkflowWorkItem());
        this.parmWorkflowComment(_workflowControlContext.getWorkflowComment());
        this.parmWorkflowTemplateName (_workflowControlContext.getActiveWorkflowConfiguration().WorkflowTable().TemplateName);
    }
    else
    {
        this.parmWorkflowConfigurationTable(_workflowConfigurationTable);
        this.parmWorkflowWorkItemtable(_workflowWorkItemTable);
        this.parmWorkflowTemplateName (this.parmWorkflowConfigurationTable().WorkflowTable().TemplateName);
    }
}
parmMenuItemName():
public MenuItemName parmMenuItemName(MenuItemName _menuItemName = menuItemName)
{
    ;
    menuItemName = _menuItemName;
    return menuItemName;
}
parmSubmit ():
public boolean parmSubmit(boolean _submit = submit)
{
;
submit = _submit;
return submit;
}
parmWFTable():
public WFTable parmWFTable(WFTable _WFTable = WFTable)
{
    ;
    WFTable = _WFTable;
    return WFTable;
}
parmWorkflowComment():
public WorkflowComment parmWorkflowComment(WorkflowComment _workflowComment = workflowComment)
{
;
workflowComment = _workflowComment;
return workflowComment;
}
parmWorkflowConfigurationTable():
public WorkflowVersionTable parmWorkflowConfigurationTable(WorkflowVersionTable _workflowConfigurationTable = workflowConfigurationTable)
{
;
workflowConfigurationTable = _workflowConfigurationTable;
return workflowConfigurationTable;
}
parmWorkflowControlContext():
public EPWorkflowControlContext parmWorkflowControlContext(EPWorkflowControlContext _workflowControlContext = workflowControlContext)
{
;
workflowControlContext = _workflowControlContext;
return workflowControlContext;
}
parmWorkflowTemplateName():
public WorkflowTypeName parmWorkflowTemplateName(WorkflowTypeName _workflowTemplateName = workflowTemplateName)
{
;
workflowTemplateName = _workflowTemplateName;
return workflowTemplateName;
}
parmWorkflowWorkItemtable():
public WorkflowWorkItemTable parmWorkflowWorkItemtable(WorkflowWorkItemTable _workflowWorkItemTable = workflowWorkItemTable)
{
;
workflowWorkItemTable = _workflowWorkItemTable;
return workflowWorkItemTable;
}
reSubmit():
private void reSubmit()
{
    Object WFTable_ds;
    NoYes                   reSubmittingFromWeb;
    // If we have a workflow control context, we are being resubmitted from EP
    reSubmittingFromWeb = this.parmWorkflowControlContext() == null ? NoYes::No : NoYes::Yes;
    ttsbegin;
    WorkflowWorkItemActionManager::dispatchWorkItemAction( workflowWorkItemTable, workflowComment, userId, WorkflowWorkItemActionType::Resubmit, menuItemName, false);
    WFTable_ds = WFTable.dataSource();
    WFTable = WFTable::findRecId(WFTable.RecId, true);
    WFTable.WFEnabled = ApprovalState::Submitted;
    WFTable.doUpdate();
    if (WFTable_ds)
    {
        WFTable_ds.write();
        WFTable_ds.refresh();
    }
    ttscommit;
}
submit():
private void submit()
{
    Object WFTable_ds;
    NoYes activatingFromWeb;
    ;
    // If we have a workflow control context, we are being activated from EP
    activatingFromWeb = this.parmWorkflowControlContext() == null ? NoYes::No : NoYes::Yes;
    ttsBegin;
    Workflow::activateFromWorkflowType( this.parmWorkflowTemplateName(),WFTable.RecId, this.parmWorkflowComment(),activatingFromWeb, curuserid());
    WFTable_ds = WFTable.dataSource();
    WFTable = WFTable::findRecId(WFTable.RecId, true);
    WFTable.SubBy = curuserid();
  //  WFTable.SubDate = utcDateTime2SystemDateTime(DateTimeUtil::utcNow());
    WFTable.WFEnabled = ApprovalState::Submitted;
    WFTable.doUpdate();
    if (WFTable_ds)
    {
        WFTable_ds.write();
        WFTable_ds.reread();
        WFTable_ds.refresh();
    }
    ttsCommit;
}
construct():
public static WFTypeSubmitManager construct()
{
    return new WFTypeSubmitManager();
}
Main():
public static void main(Args args)
{
    WFTypeSubmitManager WFTypeSubmitManager;
    //EmplContract EmplContract;
    WFTable           WFTable;
     // Variable declaration.
    recId recId;
    WorkflowCorrelationId workflowCorrelationId;
    Object                          callerDataSource;
    // Hardcoded workflow type name
    workflowTypeName workflowTypeName = workflowtypestr("WFType");
    // Initial note is the information that users enter when they
    // submit the document for workflow.
    WorkflowComment initialNote = "Enter any comments here.";
    WorkflowSubmitDialog workflowSubmitDialog;
    // The name of the table containing the records for workflow.
    FormDataSource   WFTable_ds;
    // Workflow Control Context
    EPWorkflowControlContext workflowControlContext;
    ;
    WFTable = args.record();
    WFTypeSubmitManager = WFTypeSubmitManager::construct();
    if (args.menuItemName() == menuitemactionstr(WFTypeSubmitMenuItem) ||
        args.menuItemName() == menuitemactionstr(WFApprResubmitMenuItem))
    {
        WFTypeSubmitManager.init(args.record(), args.menuItemName(), args.caller().getActiveWorkflowConfiguration(), args.caller().getActiveWorkflowWorkItem(), null);
    }
    else
    {
        WFTypeSubmitManager.init(args.record(), args.menuItemName(), null, null, args.caller());
    }
    if (WFTypeSubmitManager.dialogOk())
    {
            if (WFTypeSubmitManager.parmSubmit())
            {
                WFTypeSubmitManager.submit();
            }
            else
            {
                WFTypeSubmitManager.reSubmit();
            }
            if (args.menuItemName() == menuitemactionstr(WFTypeSubmitMenuItem) ||
                args.menuItemName() == menuitemactionstr(WFApprResubmitMenuItem))
                    args.caller().updateWorkflowControls();
    }
    if (!webSession())
    {
        callerDataSource = args.record().dataSource();
        if (callerDataSource)
        {
            callerDataSource.research(true);
        }
        args.caller().updateWorkflowControls();
    }
}

The section below describes briefly, the process of developing a new workflow.
To develop a new workflow, following artifacts or objects need to be created / modified:
·         Workflow Categories
·         Workflow Templates
·         Workflow Query (Document)
·         Workflow Approvals and Tasks (Tasks are optional)
·         Enabling the workflows on the form
·         Workflow submission classes
Let us go through each of these artifacts one by one:
Create Workflow Categories
A workflow category defines the module in which the workflow will be available. Modules are defined by the SysModule enum. You will be doing following here:
·         Create a new category in workflow categories node (AOT>>Workflow>>Workflow Categories)
·         Specify the name and module to which it belongs
Create Workflow Templates (AX 2012: Workflow Types)
A workflow template brings all the different elements of the workflow together. Workflow configurations are created based on a template, and many configurations can be based on the same template. The template defines which actions are allowed and which are required.
You will be doing following here:
·         Create a new template in the workflow templates node (AOT>>Workflow>>Workflow Templates) (AX 2012: AOT>>Workflow>>Workflow Types)
·         Specify a name and category to which it belongs
Next we create a work flow document.
Create Workflow Document
A query defines what tables are used to determine that a workflow can be initiated. Here you will do the following
·         Create a new query (AOT>>Queries)
·         Specify a name and Add required tables to the data source.
·         Create a new class extending from WorkFlowDocument class (AOT>>Classes)
·         Override the method getQueryName and return the name of newly created query
·         Save the class
·         Once query and its supporting class is created, attach this to Workflow template (Specify it under the Document property of template; AX 2012: type)
Next step is to attach Approvals and / or Tasks
Create Workflow Approvals (or Tasks):
An approval route may contain a number of outcomes. It may be approved, rejected, returned or a change may be requested (For task it will be complete, reject or request change). The Workflow Approval element determines which of these outcomes is allowed and what happens in the event of each outcome. Each outcome can trigger specific code by specifying a menu item for each item. Do the following to create an approval
·         Create a new approval object in the Approvals node. (AOT>>Workflow>>Approvals)
·         Specify a unique name for the approval
·         Specify the Document (The class created for query) in the Document property
·         Specify ParticipantProvider. Normally you specify WorkflowUserGroupParticipantProvider, but you can create your own participant provider. (Missing in AX 2012)
·         Specify DueDateProvider. Normally you specify WorkflowWorkCalendarDueDateProvider, but you can create your own due date provider. (Missing in AX 2012)
·         Specify HierarchyProvider. Normally you specify WorkflowLimitHierarchyProvider, but you can create your own hierarchy provider. (Missing in AX 2012)
·         Set the DocumentMenuItem to form menu item where you want the workflow to appear (Example sales order etc.)
·         Approval Outcomes:
·         Use a standard class that acts as an engine for all approval outcomes
·         You are not required to do anything but set the workflow to applicable outcomes, therefore call the same class from different menu items. The menu items simply allow you to use two different labels. In more complex workflows it may be necessary to override or copy and modify this class rather than use it directly. Example: If you have to set an outcome for Approved do the following:
1.       Create a new Action type menu item and specify a name to it
2.       Set ObjectType property to Class and Object property to WorkflowWorkItemActionManager
3.       Now get to Workflow>>Approvals>>Approval_you_created>>Outcomes>>Approve node and specify ActionMenuItem as new menuitem created before.
4.       Repeat Step 2 for all the outcomes you need
·         If you do not need an outcome you can simply disable it by changing Enabled property to No
·         Once completed, drag and drop this approval (or task) into the previously created workflow template (AX 2012: Worfklow Type)
Enable workflow on a form
Now that the workflow template is defined, you can specify which forms will use this template. Do the following:
·         Add a WorkflowState field (More can be added by CreatedBy, Time, Status etc.) to the required table
·         In the desired form, go to the design node properties and set property WorkFlowEnabled to “Yes”, set the WorkFlowDataSource (the table of the previous step) and (AX 2012 only) set the WorkflowType as defined above.
·         If you want, you can override the method canSubmitToWorkflow on the form and specify conditions when user can submit the record to workflow
After enabling the workflow on class, create a class to submit the records to workflow
Create a Submit to Workflow class
To submit a document to workflow, call standard code to prompt the user for a comment and to process the submission. (Look at PurchReqWorkflow class for an example)
·         After creating the submit to workflow class, create a corresponding action menu item
·         Now traverse to the workflow template (AX 2012: Worfklow Type) and specify this submit to workflow class menu item on the SubmitToWorkFlowMenuItem property
·         Once this is done you can then configure the workflow and test it. (You can refer the Workflows – Installation and Configuration document that I sent earlier for configuring the workflows)
This will give you a broad idea as to what needs to be done for creating a workflow.
Compile

In AX 2012 it is required to update CIL before the Workflow can be configured

No comments:

Post a Comment