You are on page 1of 46

Workflows - Development

An easy to understand guide for creating new workflow templates in Microsoft Dynamics AX 2009
Created By

Sumit Loya

Table of Contents
1. Workflow Development ........................................................................................................................ 3 1.1 Introduction .................................................................................................................................. 3 Accounts Payable workflow templates ................................................................................. 3 Accounts Receivables workflow templates .......................................................................... 4 Expense Management workflow templates ......................................................................... 4 General Ledger workflow templates..................................................................................... 5

1.1.1 1.1.2 1.1.3 1.1.4 1.2

Development of Workflow Artifacts ............................................................................................. 5 Workflow Categories............................................................................................................. 5 Workflow Templates ............................................................................................................. 7 Workflow Documents ........................................................................................................... 8

1.2.1 1.2.2 1.2.3

Create a Query .................................................................................................................................. 8 Create a Class .................................................................................................................................... 9 1.2.4 Template Event Handlers and Cancel Managers ................................................................ 12

Create a Cancel Manager class ....................................................................................................... 12 Create Event Handler Class ............................................................................................................. 14 1.2.5 Workflow Tasks ................................................................................................................... 16

Create Task Event Handlers and Delegate Menu Item ................................................................... 17 Configuring Task Outcomes ............................................................................................................ 21 1.2.6 Workflow Approvals............................................................................................................ 24

Create Approval Event Handlers ..................................................................................................... 26 Configuring Approval Outcomes ..................................................................................................... 28 1.2.7 1.3 Attaching Tasks and Approvals to Workflow Templates .................................................... 32

Enabling Workflows on Forms .................................................................................................... 32 Table Modifications............................................................................................................. 32 Form Modifications ............................................................................................................. 37 Creation of a Submit Class .................................................................................................. 37

1.3.1 1.3.2 1.3.3

Attach Submit Action Menu Item to Workflow Template .............................................................. 44 Attach Resubmit Action Menu Item to Approvals and Tasks ......................................................... 45 1.4 In the End .................................................................................................................................... 46

Microsoft Dynamics AX 2009

Page | 2

1. Workflow Development
1.1 Introduction
A workflow is a depiction of a sequence of operations, declared as work of a person, a group of persons, an organization of staff, or one or more simple or complex mechanisms. Workflow may be seen as any abstraction of real work, segregated in work share, work split or other types of ordering. Workflow is a module in Microsoft Dynamics AX 2009 that allows flexible task and approval routes for documents created by users. For example, a purchase requisition may need to be approved by a number of different employees according to the requisition's total amount, and each employee has to approve it before the next employee in the approval route. In this article, I am going to discuss about how to develop new workflow templates that can be configured and implemented. By default Microsoft has provided following templates: 1.1.1 Accounts Payable workflow templates The Accounts Payable module provides the following workflow templates. Workflow template Project purchase requisition approval Purchase requisition approval Vendor bank remittance template Vendor disbursement template Vendor draw promissory note template Invoice approval journal template Vendor invoice recording template Invoice register template Vendor redraw promissory Use this template to Create project purchase requisition approval workflows.

Create approval workflows for purchase requisitions.

Create approval workflows for vendor bank remittance journals.

Create approval workflows for vendor disbursement journals.

Create approval workflows for vendor draw promissory note journals.

Create approval workflows for invoice approval journals.

Create approval workflows for vendor invoice recording journals.

Create approval workflows for invoice register journals. Create approval workflows for vendor redraw promissory note journals.

Microsoft Dynamics AX 2009

Page | 3

note template Vendor settle promissory note template Create approval workflows for vendor settle promissory note journals.

1.1.2 Accounts Receivables workflow templates The Accounts Receivables module provides the following workflow templates. Workflow template Customer bank remittance template Customer draw bill of exchange template Customer payment template Customer protest bill of exchange template Customer redraw bill of exchange template Customer settle bill of exchange template Use this template to Create approval workflows for customer bank remittance journals.

Create approval workflows for customer draw bill of exchange journals.

Create approval workflows for customer payment journals. Create approval workflows for customer protest bill of exchange journals. Create approval workflows for customer redraw bill of exchange journals. Create approval workflows for customer settle bill of exchange journals.

1.1.3 Expense Management workflow templates The Expense Management module provides the following workflow templates. Workflow template Cash advance request template Expense template Non-project line item workflow template Project expense line workflow template Use this template to Create approval workflows for cash advance requests in Expense Management. Create approval workflows for documents in Expense Management. Create approval workflows for non-project line items in Expense Management. Create approval workflows for project expense line items in Expense Management.

Microsoft Dynamics AX 2009

Page | 4

1.1.4 General Ledger workflow templates The General Ledger module provides the following workflow templates. Workflow template Allocations template Daily template Eliminations template Fixed assets budget template Post fixed assets template Use this template to Create approval workflows for allocations journals. Create approval workflows for daily journals. Create approval workflows for eliminations journals. Create approval workflows for fixed assets budget journals. Create approval workflows for fixed assets journals.

The sections that follow describe how we can create a new workflow.

1.2 Development of Workflow Artifacts


Broadly creating workflows require creating / modifying following workflow artifacts: Workflow Categories Workflow Templates Workflow Documents Tasks Approvals Let us take each of these artifacts one by one to understand how to we can successfully create a new workflow. We will take an example of purchase order approval. A finance executive has to get an approval before posting the purchase invoice. The purchase order workflow should do the following: It should check the completeness of the purchase order (May be users have posted a purchase order without setting any value. Scenarios like these have to be accounted for.) It should have a approval process, wherein a supervisor has to give a go ahead before the purchase order is invoiced Let us see how we can create a workflow process for this requirement. 1.2.1 Workflow Categories A workflow category defines the module in which the workflow will be available or for which module the workflow is applicable to. Modules are defined by the SysModule enum. In case you have created a new module in AX you can add your module to SysModule enum. It is not always necessary to define a

Microsoft Dynamics AX 2009

Page | 5

workflow category as you can make use of available workflow categories. Following are the available categories in AX 2009: ExpenseManagement LedgerJournalWFApprovalCustomer LedgerJournalWFApprovalLedger LedgerJournalWFApprovalVendor PurchCategory For our example we will be using an existing category PurchCategory. In case these categories are not applicable to your scenario, you can go ahead and create new categories. To create new workflow categories follow the procedure below: 1. 2. 3. 4. 5. 6. Open AOT Expand the Workflow node Right-click on the Workflow Category node and select New Workflow Category. A new workflow category called WorkflowCategory1 will be created. Right-click on the newly created workflow category and select Properties You can specify the following:

Property Description A unique name for the category Name A meaningful label for the category Ex: Purchase order Label Description about the category Help Text The module to which the category is applicable Module See the following screen shot:

Microsoft Dynamics AX 2009

Page | 6

1.2.2 Workflow Templates The workflow template is an artifact that governs the creation of workflow configurations for implementing business policies. 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. In this section we will create a new workflow template for our purchase order approval scenario and attach it with the existing workflow category PurchCategory. Follow the procedure below to create a new workflow template: 1. 2. 3. 4. 5. 6. Open the AOT Expand the Workflow node Right-click on the Workflow Templates node and select New Workflow Template A new workflow template named WorkflowTemplate1 will be created Right-click on the newly created workflow template and select Properties Set the following properties Name property to PurchOrderApproval Value PurchOrderApproval Purchase order approval Use this template to create purchase order approval workflows. PurchCategory

Property Name Label HelpText Category 7. Save the newly created workflow template See the screen shot below:

Microsoft Dynamics AX 2009

Page | 7

1.2.3 Workflow Documents A workflow document specifies what data will be subjected to workflow approval process. It defines what data is affected and how many tables are involved in the workflow process. It can define one or more tables and all or selected fields on that table. This is done by using a query. A query defines what tables are used to determine that a workflow can be initiated. Use a class to bind that query to the workflow template. In this section we will create a query and a class that will bind the query with the workflow template. Do the following: Create a Query 1. Open the AOT 2. Right-click on the Query node and select New Query 3. Rename the query to PurchOrderDocument 4. Expand the Data Sources node in the newly created query 5. Right-click and select New Data Source 6. Right-click the newly created data source and select Properties 7. Set the following properties Property Value PurchTable Name PurchTable Table 8. Next expand the PurchTable data source and right-click on the Data Sources node inside the PurchTable data source 9. Select New Data Source and set the following Properties Property Value PurchLine Name PurchLine Table OuterJoin JoinMode Yes Relations 10. Next expand the PurchLine data source and right-click on the Data Sources node inside the PurchLine data source 11. Select New Data Source and set the following Properties Property Name Table JoinMode Relations 12. Save the Query See the screen shot below: Value InventDim InventDim InnerJoin Yes

Microsoft Dynamics AX 2009

Page | 8

Create a Class 1. In the AOT, right-click on the Classes node and select New Class 2. Create/Modify following methods in the new class and save it Method classDeclaration checkContext getQueryName parmTotalAmount Description A validation method that checks the table using this class is PurchTable only Returns the name of the query as a string Returns the total amount for the purchase order (A corresponding field will be created in the workflow configuration form for this method) Returns the total amount excluding taxes for the purchase order (A corresponding field will be created in the workflow configuration form for this method) Returns an instantiated instance of the class

parmTotalAmountExclTax

construct

3. Following are the implementations for these methods

Microsoft Dynamics AX 2009

Page | 9

class PurchOrderDocument extends WorkflowDocument { } protected void checkContext(tableId _tableId, RecId _recId) { ; if (_tableId != tablenum(PurchTable)) { // Workflow context table id reference: %1 is not valid throw error(strfmt("@SYS107963", _tableId)); } if (_recId == 0) { // Workflow context record id is zero. throw error(strfmt("@SYS107964")); } } QueryName getQueryName() { return querystr(PurchOrderDocument); } public static PurchOrderDocument construct() { return new PurchOrderDocument(); }

Microsoft Dynamics AX 2009

Page | 10

public PurchReqAmountApproval parmTotalAmount(CompanyId _companyId, tableId _tableId, RecId _recId) { AmountCur totalAmount; PurchTable purchTable; ; this.checkContext(_tableId, _recId); purchTable = PurchTable::findRecId(_recId); totalAmount = conpeek(PurchTotals::newPurchTable (purchTable).displayFields(), TradeTotals::posTotalAmount()); return Currency::mstAmount(totalAmount, CompanyInfo::find().CurrencyCode); } public PurchReqAmountApprovalExclTax parmTotalAmountExclTax(CompanyId _companyId, tableId _tableId, RecId _recId) { AmountCur totalAmount; PurchTable purchTable; PurchTotals totals; ; this.checkContext(_tableId, _recId); purchTable = PurchTable::findRecId(_recId); totals = PurchTotals::newPurchTable(purchTable); totalAmount = conpeek(totals.displayFields(), TradeTotals::posTotalAmount()) - conpeek(totals.displayFields(), TradeTotals::posTaxTotal()); return Currency::mstAmount(totalAmount, CompanyInfo::find().CurrencyCode); }

Microsoft Dynamics AX 2009

Page | 11

Attach the Document with the Workflow Template 1. Traverse to Workflow Workflow Templates PurchOrderApproval 2. Right-click and select Properties 3. For the property Document set value as PurchOrderDocument

1.2.4 Template Event Handlers and Cancel Managers Create a Cancel Manager class As the name suggests the cancel manager class is used for cancelling a workflow. This class should inherit from WorkflowCancelManager class. Do the following: 1. Open the AOT, traverse to Classes node and create a new class 2. Create following methods in the new class and save the class class PurchOrderWorkflowCancelManager extends WorkflowCancelManager { } public static PurchOrderWorkflowCancelManager construct() { return new PurchOrderWorkflowCancelManager(); } public static void main(Args _args) { PurchOrderWorkflowCancelManager workflowCancelManager = PurchOrderWorkflowCancelManager::construct(); ; workflowCancelManager.run(_args); }

Microsoft Dynamics AX 2009

Page | 12

//Updates the PurchTable workflow state to pending cancellation public void updateDocument(Args _args) { FormDataSource purchTable_ds; PurchTable purchTable; ; purchTable_ds = _args.record().dataSource(); if (purchTable_ds) { purchTable_ds.reread(); purchTable purchTable.State = purchTable_ds.cursor(); = PurchReqWorkflowState::PendingCancellation;

purchTable_ds.write(); purchTable_ds.refresh(); } }

After the class is ready create a new action type menu item for the class and attach it to the workflow template. Do the following: 1. Open the AOT and Traverse to Menu Items Action 2. Create new Menu Item and set the following properties Property Name Label HelpText Value PurchOrderCancel Cancel Select the action Cancel to cancel the purchase order after it has been submitted. Class PurchOrderWorkflowCancelManager Called from VendMisc

ObjectType Object RunOn SecurityKey 3. Save the menu item 4. Now traverse to Workflow Workflow Templates PurchOrderApproval 5. Right-click and select Properties 6. Set the property CancelMenuItem to PurchOrderCancel See the screen shot below:

Microsoft Dynamics AX 2009

Page | 13

Create Event Handler Class Event handler class handles logic to be implemented for the events started, completed and canceled. 1. Open the AOT, traverse to Classes node and create a new class 2. Create following methods in the new class and save the class public class PurchOrderWorkflowEventHandler implements WorkflowStartedEventHandler, WorkflowCanceledEventHandler, WorkflowCompletedEventHandler { } public void canceled(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::NotSubmitted); }

Microsoft Dynamics AX 2009

Page | 14

public void completed(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::WorkflowCompleted); } public void started(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::Submitted); } Note: You may get error as the method setWorkflowState is not available. Refer to Table modifications section to resolve this error. 3. Now traverse to Workflow Workflow Templates PurchOrderApproval 4. Right-click and select Properties 5. Set the properties StartedEventHandler, CompletedEventHandler, CanceledEventHandler to PurchOrderWorkflowEventHandler See the screen shot below:

Microsoft Dynamics AX 2009

Page | 15

1.2.5 Workflow Tasks Tasks are the most generic workflow elements. Tasks provide application specific behavior that you define in the AOT. Each task supports a single unit of work that is defined by one step. This means a workflow task can have only one step. A task does not have a fixed outcome. However, you can add any number of custom outcomes to the task, such as Completed or Skipped. Each task must have at least one outcome of type Complete and an action menu item for the task work item button to display in the user interface. This procedure describes how to create a new workflow task: 1. In the AOT, expand the Workflow node 2. Right-click the Tasks node and then select New Task. A new workflow task group displays under the Tasks node 3. Right-click the new workflow task and then click Properties 4. In the Properties sheet, set the following properties as required Property Description Value (For our scenario) Name The name that is used to reference the workflow task The label used for the workflow task in the user interface The description of the workflow task shown in the workflow configuration user interface The configuration key assigned to the task PurchOrderComplete

Label

Check mandatory lines

Help Text

Update order lines if mandatory data is missing

ConfigurationKe y Document

The workflow document enabled by the workflow task (This setting must match the Document property setting used in the workflow template for the approval.) The initial set of fields displayed in the unified work list dialog box. Select a field group from the root table specified in the Document property. The workflow task Document property setting must be set before you can select a field group The workflow event handler for the workflow started event

PurchOrderDocument

DocumentFieldP reviewGroup

Workflow (Set this property only after making changes to the top level table of the document. You can use any name but for demonstration purpose I am using Workflow)

StartedEventHa ndler

Microsoft Dynamics AX 2009

Page | 16

CanceledEventH andler ParticipantProvi der

The workflow event handler for the workflow canceled event The provider for participant resolution of the task. Set this property if the HierarchyProvider property is not set WorkflowUserGroupParticipa ntProvider (This is the standard participant provider. You can extend this provider and create your own provider if needed.) WorkflowWorkCalendarDueD ateProvider (This is the standard participant provider. You can extend this provider and create your own provider if needed.) WorkflowLimitHierarchyProvi der (This is the standard participant provider. You can extend this provider and create your own provider if needed.)

DueDateProvide r

The date provider for the due date resolution

HierarchyProvi der

The provider for the hierarchy resolution. Set this property if the ParticipantProvider property is not set

DocumentWebM The Web menu item that opens the workflow enuItem document form DocumentMenuI The rich client menu item that opens the workflow tem document form PurchTable (This is the existing Display menu item for purchase order form. This means the workflow will be implemented on purchase order form.)

ResubmitWebM enuItem ResubmitMenuI tem DelegateWebMe nuItem DelegateMenuIt em

The Web menu item that resubmits the workflow document to the workflow approval The rich client menu item that resubmits the workflow document to the workflow approval The Web menu item that starts the delegate action on a work item The rich client menu item that starts the delegate action on a work item We will set this property after creating a class for submitting the workflow.

Create Task Event Handlers and Delegate Menu Item Now let us create some event handler classes for the task that will set the state of the workflow after each of the events that may happen like started or canceled. Do the following: Microsoft Dynamics AX 2009 Page | 17

1. Open the AOT, traverse to Classes node and create a new class 2. Create following methods in the new class and save the class class PurchOrderCompleteEventHandler implements WorkflowElementCompletedEventHandler, WorkflowElementCanceledEventHandler, WorkflowElementReturnedEventHandler, WorkflowElemChangeRequestedEventHandler, WorkflowElementStartedEventHandler { } public void canceled(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::NotSubmitted); } public void completed(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::WorkflowCompleted); } public void started(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::Submitted); } public void changeRequested(WorkflowElementEventArgs _workflowElementEventArgs) { ; PurchTable::setWorkflowState(_workflowElementEventArgs.parmWorkflowContext ().parmRecId(), PurchReqWorkflowState::ChangeRequest); } public void returned(WorkflowElementEventArgs _workflowElementEventArgs) { ; PurchTable::setWorkflowState(_workflowElementEventArgs.parmWorkflowContext ().parmRecId(), PurchReqWorkflowState::Returned); }

Microsoft Dynamics AX 2009

Page | 18

Note: You may get error as the method setWorkflowState is not available. Refer to Table modifications section to resolve this error. 3. Now traverse to Workflow Tasks PurchOrderComplete 4. Right-click and select Properties 5. Set the properties StartedEventHandler and CanceledEventHandler to PurchOrderCompleteEventHandler Now let us set the value for property DelegateMenuItem. For this property we need to create a new action menu item. Follow the procedure below: 1. 2. 3. 4. Open the AOT Traverse to Menu Items Action Right-click and select New Menu Item Set the following properties Value PurchOrderDelegate Delegate Delegate purchase order to another. Class WorkflowWorkItemActionManager (You can create your own class extending this class for specific features while delegating the workflow.) Called from VendMisc Edit

Property Name Label HelpText ObjectType Object RunOn SecurityKey NeededAccessLevel

See the screen shot below:

Microsoft Dynamics AX 2009

Page | 19

5. Set this menu item as value for DelegateMenuItem property of PurchOrderComplete task See the screen shot below showing the task we created in this section:

Microsoft Dynamics AX 2009

Page | 20

Configuring Task Outcomes Our scenario has three outcomes: Complete, Reject, Request change Use the standard WorkflowWorkItemActionManager class that acts as an engine for all task outcomes. You are not required to do anything but set the workflow to either Completed, Rejected or change may be requested, therefore call the same class from three different menu items. The three 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. Follow the procedure below to create three new menu items for 3 outcomes. Note: In our scenario there are three outcomes for this task. But the number of outcomes depends from scenario to scenario and thus the number of menu items to be created also varies from task to task.

1. Open the AOT 2. Expand Menu Items 3. Create three Action type menu items with following details Property Name Label HelpText ObjectType Object RunOn SecurityKey NeededAccessLevel Name Label HelpText ObjectType Object RunOn SecurityKey NeededAccessLevel Name Label HelpText ObjectType Object Microsoft Dynamics AX 2009 Value Task Outcome: Complete PurchOrderTaskComplete Complete Complete purchase order. Class WorkflowWorkItemActionManager Called from VendMisc Edit Task Outcome: Reject PurchOrderTaskReject Reject Reject purchase order. Class WorkflowWorkItemActionManager Called from VendMisc Edit Task Outcome: RequestChange PurchOrderTaskRequestChange Request change Send change request to submitter Class WorkflowWorkItemActionManager Page | 21

RunOn SecurityKey NeededAccessLevel See the screen shots below:

Called from VendMisc Edit

4. Once these menu items are created attach these menu items with task outcomes 5. Traverse to AOT Workflows Tasks PurchOrderComplete 6. Expand the Outcomes node and create three new outcomes with following properties

Microsoft Dynamics AX 2009

Page | 22

Property Name Type Enabled ActionMenuItem EventHandler Name Type Enabled ActionMenuItem EventHandler Name Type Enabled ActionMenuItem EventHandler

Value Task Outcome: Complete Complete Complete Yes PurchOrderTaskComplete PurchOrderCompleteEventHandler Task Outcome: Reject Reject Return Yes PurchOrderTaskReject PurchOrderCompleteEventHandler Task Outcome: RequestChange RequestChange RequestChange Yes PurchOrderTaskRequestChange PurchOrderCompleteEventHandler

See the screen shots below:

Microsoft Dynamics AX 2009

Page | 23

1.2.6 Workflow Approvals Approvals are the specialized type of tasks. The main difference between tasks and approvals is that tasks can have only single step of work but approvals can have multiple steps and sub-workflows as well. Approvals are specialized workflow elements designed to support approval scenarios. Approvals have a set of fixed outcomes that the workflow supports. These outcomes are as follows: Approve - Outcome type Complete. Reject - Outcome type Return to the originator of the workflow. RequestChange - Outcome type ChangeRequested from the originator or another person in the workflow process. Deny - Outcome type Deny. The fixed outcomes listed earlier cannot be deleted in the AOT. However, you can set the workflow outcome Enabled property to No to disable the workflow outcome in the application. Each approval must have one outcome of type Complete and an action menu item for the approval work item button to display in the user interface. This procedure describes how to create a new workflow approval: 1. In the AOT, expand the Workflow node 2. Right-click the Approvals node and then select New Approval. A new workflow approval group displays under the Approvals node 3. Right-click the new workflow approval and then click Properties 4. In the Properties sheet, set the following properties as required Property Description Value (For our scenario) Name The name that is used to reference the workflow task PurchOrderApproval

Microsoft Dynamics AX 2009

Page | 24

Label

The label used for the workflow task in the user interface The description of the workflow task shown in the workflow configuration user interface The configuration key assigned to the task

Purchase Order Approval

Help Text

Approve purchase order

ConfigurationKe y Document

The workflow document enabled by the workflow task (This setting must match the Document property setting used in the workflow template for the approval.) The initial set of fields displayed in the unified work list dialog box. Select a field group from the root table specified in the Document property. The workflow task Document property setting must be set before you can select a field group The workflow event handler for the workflow started event

PurchOrderDocument

DocumentFieldP reviewGroup

Workflow (Set this property only after making changes to the top level table of the document. You can use any name but for demonstration purpose I am using Workflow) Refer the PurchReqComplete task in the AOT for more details. We will not be creating this event handler. Refer the PurchReqComplete task in the AOT for more details. We will not be creating this event handler. WorkflowUserGroupParticipa ntProvider (This is the standard participant provider. You can extend this provider and create your own provider if needed.) WorkflowWorkCalendarDueD ateProvider (This is the standard participant provider. You can extend this provider and create your own provider if needed.) WorkflowLimitHierarchyProvi der (This is the standard participant provider. You can extend this provider and create your own provider if

StartedEventHa ndler CanceledEventH andler ParticipantProvi der

The workflow event handler for the workflow canceled event

The provider for participant resolution of the task. Set this property if the HierarchyProvider property is not set

DueDateProvide r

The date provider for the due date resolution

HierarchyProvi der

The provider for the hierarchy resolution. Set this property if the ParticipantProvider property is not set

Microsoft Dynamics AX 2009

Page | 25

needed.) DocumentWebM The Web menu item that opens the workflow enuItem document form DocumentMenuI The rich client menu item that opens the workflow tem document form PurchTable (This is the existing Display menu item for purchase order form. This means the workflow will be implemented on purchase order form.)

ResubmitWebM enuItem ResubmitMenuI tem DelegateWebMe nuItem DelegateMenuIt em

The Web menu item that resubmits the workflow document to the workflow approval The rich client menu item that resubmits the workflow document to the workflow approval The Web menu item that starts the delegate action on a work item The rich client menu item that starts the delegate action on a work item PurchOrderDelegate (Created in the task section. Refer task section on how to create this menu item) We will set this property after creating a class for submitting the workflow.

Create Approval Event Handlers Now let us create an event handler class for the approval that will set the state of the workflow after each of the events that may happen like started or canceled. Do the following: 1. Open the AOT, traverse to Classes node and create a new class 2. Create following methods in the new class and save the class class PurchOrderApprovalEventHandler implements WorkflowElementCompletedEventHandler, WorkflowElementCanceledEventHandler, WorkflowElementReturnedEventHandler, WorkflowElemChangeRequestedEventHandler, WorkflowElementStartedEventHandler { } public void canceled(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::NotSubmitted); }

Microsoft Dynamics AX 2009

Page | 26

public void changeRequested(WorkflowElementEventArgs _workflowElementEventArgs) { ; PurchTable::setWorkflowState(_workflowElementEventArgs.parmWorkflowContext ().parmRecId(), PurchReqWorkflowState::ChangeRequest); } public void returned(WorkflowElementEventArgs _workflowElementEventArgs) { ; PurchTable::setWorkflowState(_workflowElementEventArgs.parmWorkflowContext ().parmRecId(), PurchReqWorkflowState::Returned); } public void started(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::Submitted); } public void completed(WorkflowEventArgs _workflowEventArgs) { ; PurchTable::setWorkflowState(_workflowEventArgs.parmWorkflowContext().parm RecId(), PurchReqWorkflowState::WorkflowCompleted); } Note: You may get error as the method setWorkflowState is not available. Refer to Table modifications section to resolve this error. 3. Now traverse to Workflow Tasks PurchOrderApproval 4. Right-click and select Properties 5. Set the properties StartedEventHandler and CanceledEventHandler to PurchOrderCompleteEventHandler See the screen shot below showing the properties of the approval we created in this section:

Microsoft Dynamics AX 2009

Page | 27

Configuring Approval Outcomes Use the standard WorkflowWorkItemActionManager class that acts as an engine for all approval outcomes. You are not required to do anything but set the workflow to either Approve, Reject or change may be requested, therefore call the same class from three different menu items. The three 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. Follow the procedure below to create three new menu items for 3 outcomes. Note: In our scenario there are three outcomes for this approval so we will be disabling the fourth outcome Deny.

1. Open the AOT 2. Expand Menu Items 3. Create three Action type menu items with following details

Microsoft Dynamics AX 2009

Page | 28

Property Name Label HelpText ObjectType Object RunOn SecurityKey NeededAccessLevel Name Label HelpText ObjectType Object RunOn SecurityKey NeededAccessLevel Name Label HelpText ObjectType Object RunOn SecurityKey NeededAccessLevel

Value Approval Outcome: Approve PurchOrderApprovalApprove Approve Approve purchase order. Class WorkflowWorkItemActionManager Called from VendMisc Edit Approval Outcome: Reject PurchOrderApprovalReject Reject Reject purchase order. Class WorkflowWorkItemActionManager Called from VendMisc Edit Approval Outcome: RequestChange PurchOrderApprovalRequestChange Request change Send change request to submitter Class WorkflowWorkItemActionManager Called from VendMisc Edit

See the screen shots below:

Microsoft Dynamics AX 2009

Page | 29

4. Once these menu items are created attach these menu items with task outcomes 5. Traverse to AOT Workflow Approvals PurchOrderApproval 6. Expand the Outcomes node and create three new outcomes with following properties Property Enabled ActionMenuItem EventHandler Value Approval Outcome: Approve Yes PurchOrderApprovalApprove PurchOrderApprovalEventHandler Approval Outcome: Deny

Microsoft Dynamics AX 2009

Page | 30

Enabled ActionMenuItem EventHandler Enabled ActionMenuItem EventHandler Enabled ActionMenuItem EventHandler See the screen shots below:

No

Task Outcome: Reject Yes PurchOrderApprovalReject PurchOrderApprovalEventHandler Task Outcome: RequestChange Yes PurchOrderApprovalRequestChange PurchOrderApprovalEventHandler

Microsoft Dynamics AX 2009

Page | 31

1.2.7 Attaching Tasks and Approvals to Workflow Templates The approvals / tasks needs to be attached to the template. The following procedure explains how to attach an approval / task to a template. 1. 2. 3. 4. 5. Open the AOT Expand Workflow Workflow Templates PurchOrderApproval Open another AOT window Expand Workflow Tasks Find PurchOrderComplete task; drag it on to the Required Elements node of the PurchOrderApproval workflow template 6. Next Expand Workflow Approvals 7. Find PurchOrderApproval approval; drag it on to the Required Elements node of the PurchOrderApproval workflow template

1.3 Enabling Workflows on Forms


After the workflow artifacts have been developed we use them to enable the workflows on a form. In our scenario we will be adding / modifying following AX objects: Table Modifications (PurchTable) Form Modifications (PurchTable) Creation of a Submit Class 1.3.1 Table Modifications In this section we will be doing following Add three fields SubmittedBy, SubmittedDateTime, State Create a field group Workflow Create methods o canSubmit Checks if record can be submitted to workflow o mostRecentComment Returns the last comment written for the workflow

Microsoft Dynamics AX 2009

Page | 32

o o o

requiredAction The action that needs to be taken next requiredActionDueDate The date by which the action needs to be taken setWorkflowState Sets the state field status

Note the fields SubmittedBy and SubmittedDateTime are not required to be created mandatorily but the State field is necessary to perform different actions based on the status of the workflow. Let us first go ahead and create the three fields. Do the following: 1. Open AOT 2. Traverse to Data Dictionary Tables PurchTable 3. Add three fields with following properties Property Value Field : SubmittedBy SubmittedBy Name No AllowEditOnCreate No AllowEdit PurchReqSubmittedBy ExtendedDataType Field : SubmittedDateTime SubmittedDateTime Name No AllowEditOnCreate No AllowEdit PurchReqSubmittedDateTime ExtendedDataType Field : SubmittedDateTime State Name No AllowEditOnCreate No AllowEdit PurchReqWorkflowState EnumType Next we create the methods mentioned earlier. Add the following methods along with this implementation: public boolean canSubmit() { PurchLine purchLine; boolean ret = true; ; ret = ret && (this.PurchStatus == PurchStatus::Received); ret = ret && (this.State == PurchReqWorkflowState::NotSubmitted); select firstonly RecId from purchLine where purchLine.PurchId == this.PurchId; ret = ret && (purchLine.RecId != 0); return ret; }

Microsoft Dynamics AX 2009

Page | 33

display PurchReqMostRecentComment mostRecentComment() { WorkflowTrackingCommentTable workflowTrackingCommentTable; WorkflowWorkItemTable workflowWorkItemTable; WorkflowTrackingTable workflowTrackingTable; DirPartyTable dirPartyTable; EmplTable emplTable; PurchReqMostRecentComment comment; EmplId emplId; UserInfo userInfo; Name name; ; select firstonly workflowWorkItemTable order by CreatedDateTime desc where workflowWorkItemTable.RefTableId == this.TableId && workflowWorkItemTable.RefRecId == this.RecId && workflowWorkItemTable.CompanyId == this.DataAreaId && workflowWorkItemTable.Status == WorkflowWorkItemStatus::Completed; workflowTrackingTable = Workflow::findLastTrackingRecordForWorkItem (workflowWorkItemTable); workflowTrackingCommentTable = WorkflowTrackingCommentTable::find (workflowTrackingTable.TrackingId); emplId = SysCompanyUserInfo::find(workflowTrackingTable.User).EmplId; if (emplId) { select firstonly Name from dirPartyTable exists join emplTable where dirPartyTable.PartyId == emplTable.PartyId && emplTable.EmplId == emplId; name = dirPartyTable.Name + ' (' + emplId + ') : '; } else { select firstonly userInfo where userInfo.Id == workflowTrackingTable.User; name = userInfo.Name + ' (' + workflowTrackingTable.User + ') : '; } comment = strfmt("%1",DateTimeUtil::applyTimeZoneOffset (workflowTrackingCommentTable.CreatedDateTime, DateTimeUtil::getUserPreferredTimeZone())) + ' '; comment += name; comment += workflowTrackingCommentTable.Comment; return comment; }

Microsoft Dynamics AX 2009

Page | 34

display PurchReqRequiredAction requiredAction() { WorkflowWorkItemTable workflowWorkItemTable; PurchReqRequiredAction text; ; select firstonly workflowWorkItemTable where workflowWorkItemTable.RefTableId == this.TableId && workflowWorkItemTable.RefRecId == this.RecId && workflowWorkItemTable.CompanyId == this.DataAreaId && workflowWorkItemTable.UserId == curuserid() && workflowWorkItemTable.Status == WorkflowWorkItemStatus::Pending; if (workflowWorkItemTable.RecId) { switch (this.State) { case PurchReqWorkflowState::ChangeRequest : text = "@SYS109048"; break; case PurchReqWorkflowState::PendingApproval : text = "@SYS109902"; break; case PurchReqWorkflowState::PendingComplete : text = "@SYS112063"; break; } } return text; } display PurchReqRequiredActionDueDateStr requiredActionDueDate() { WorkflowWorkItemTable workflowWorkItemTable; PurchReqRequiredActionDueDateStr dueDateStr; ; select firstonly DueDateTime from workflowWorkItemTable where workflowWorkItemTable.RefTableId == this.TableId && workflowWorkItemTable.RefRecId == this.RecId && workflowWorkItemTable.CompanyId == this.DataAreaId && workflowWorkItemTable.UserId == curuserid() && workflowWorkItemTable.Status == WorkflowWorkItemStatus::Pending; if (workflowWorkItemTable.DueDateTime != DateTimeUtil::minValue()) { dueDateStr = strfmt("%1",DateTimeUtil::applyTimeZoneOffset (workflowWorkItemTable.DueDateTime, DateTimeUtil::getUserPreferredTimeZone())); } return dueDateStr; }

Microsoft Dynamics AX 2009

Page | 35

static void setWorkflowState(RecId _purchTableRecId, PurchReqWorkflowState _purchReqWorkflowState) { PurchTable purchTable; ; ttsbegin; purchTable purchTable.State = PurchTable::findRecId(_purchTableRecId, true); = _purchReqWorkflowState;

switch (_purchReqWorkflowState) { case PurchReqWorkflowState::NotSubmitted: purchTable.SubmittedBy = ''; purchTable.SubmittedDateTime = DateTimeUtil::minValue(); break; } purchTable.update(); ttscommit; } Next we create a new field group. Do the following: 1. Open AOT 2. Traverse to Data Dictionary Tables PurchTable Field Groups 3. Add field group with Name = Workflow and Label = Workflow 4. Add following elements (fields) to the field group a. State b. SubmittedBy c. SubmittedDateTime d. requiredAction (method) e. requiredActionDueDate (method) f. mostRecentComment (method) Modify PurchTableType class This modification is only for our scenario. Traverse to Classes PurchTableType class mayInvoiceBeUpdated method and copy following code before statement return ok; ok = ok && (purchTable.State == PurchReqWorkflowState::WorkflowCompleted);

Microsoft Dynamics AX 2009

Page | 36

1.3.2 Form Modifications Workflow on the form is enabled using properties on the design node, and by overriding a form method. Do the following: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Open AOT Traverse to Forms node and search for form PurchTable Next expand PurchTable Designs node Right-click on Design node and select Properties Set property WorkflowEnabled to Yes Set property WorkflowDatasource to PurchTable Expand Design Group:Table Tab:TabHeader TabPage:TabHeaderOther From the Data Sources section right-click on PurchTable and select Open New Window Find field group Workflow; Drag it onto the TabPage:TabHeaderOther Now expand the Form Methods node, override method canSubmitToWorkflow and add following implementation

public boolean canSubmitToWorkflow() { ; return purchTable.canSubmit(); } 11. Save the form Now workflow has been enabled on the form. But we still cannot submit as we need to create a class that Submits/Re-Submits a record to workflow. 1.3.3 Creation of a Submit Class In order to submit a record to workflow processor it is necessary that we create a class that prompts user to enter some comment and processes the submission. This class is also responsible to re-submit the record for workflow processing in case it has been already submitted and a change has been requested. Follow the procedure below to create the class: 1. Open the AOT and create a new class 2. Create following methods with the implementation as shown Method classDeclaration dialogOk init parmMenuItemName parmPurchTable parmSubmit Microsoft Dynamics AX 2009 Description Opens a dialog for submitting a purchase order Initializes the submit class Set/Get method for Menu Item Name Set/Get method for PurchTable record Set / Get method for Submit variable Page | 37

parmWorkflowComment parmWorkflowConfigurationTable parmWorkflowControlContext parmWorkflowTemplateName reSubmit submit construct main

Set / Get method for workflow comment Set / Get method for WorkflowConfigurationTable record Set / Get method for EPWorkflowControlContext class object Set / Get method for Workflow template name variable Processes and re-submits the record for workflow processing Activates purchase order workflow Instantiates and returns the class instance Submits a purchase order document and activates corresponding workflow

Here are the implementations for these methods: class PurchOrderWorkflow { PurchTable WorkflowConfigurationTable WorkflowComment boolean WorkflowWorkItemTable userId MenuItemName EPWorkflowControlContext WorkflowTemplateName }

purchTable; workflowConfigurationTable; workflowComment; submit; workflowWorkItemTable; userId; menuItemName; workflowControlContext; workflowTemplateName;

public MenuItemName parmMenuItemName(MenuItemName _menuItemName = menuItemName) { ; menuItemName = _menuItemName; return menuItemName; } public PurchTable parmPurchTable(PurchTable _purchTable = purchTable) { ; purchTable = _purchTable; return purchTable; } public boolean parmSubmit(boolean _submit = submit) { ; submit = _submit; return submit; }

Microsoft Dynamics AX 2009

Page | 38

public WorkflowComment parmWorkflowComment(WorkflowComment _workflowComment = workflowComment) { ; workflowComment = _workflowComment; return workflowComment; } public WorkflowConfigurationTable parmWorkflowConfigurationTable(WorkflowConfigurationTable _workflowConfigurationTable = workflowConfigurationTable) { ; workflowConfigurationTable = _workflowConfigurationTable; return workflowConfigurationTable; } public EPWorkflowControlContext parmWorkflowControlContext(EPWorkflowControlContext _workflowControlContext = workflowControlContext) { ; workflowControlContext = _workflowControlContext; return workflowControlContext; } public WorkflowTemplateName parmWorkflowTemplateName(WorkflowTemplateName _workflowTemplateName = workflowTemplateName) { ; workflowTemplateName = _workflowTemplateName; return workflowTemplateName; } public WorkflowWorkItemTable parmWorkflowWorkItemtable(WorkflowWorkItemTable _workflowWorkItemTable = workflowWorkItemTable) { ; workflowWorkItemTable = _workflowWorkItemTable; return workflowWorkItemTable; }

Microsoft Dynamics AX 2009

Page | 39

public boolean dialogOk() { WorkflowSubmitDialog WorkflowWorkItemActionDialog boolean ;

workflowSubmitDialog; workflowWorkItemActionDialog; ok;

if (menuItemName == menuitemactionstr(PurchOrderSubmitToWorkflow)) { workflowSubmitDialog = WorkflowSubmitDialog::construct(this.parmWorkflowConfigurationTable()); workflowSubmitDialog.run(); this.parmWorkflowComment(workflowSubmitDialog.parmWorkflowComment()); ok = workflowSubmitDialog.parmIsClosedOK(); } else if (menuItemName == menuitemactionstr(PurchOrderReSubmit)) { workflowWorkItemActionDialog = WorkflowWorkItemActionDialog::construct( workflowWorkItemTable, WorkflowWorkItemActionType::Resubmit, new MenuFunction(menuitemactionstr(PurchOrderReSubmit), MenuItemType::Action)); workflowWorkItemActionDialog.run(); this.parmWorkflowComment(workflowWorkItemActionDialog.parmWorkflowComment() ); ok = workflowWorkItemActionDialog.parmIsClosedOK(); userId = workflowWorkItemActionDialog.parmTargetUser(); } return ok; } public static PurchOrderWorkflow construct() { return new PurchOrderWorkflow(); }

Microsoft Dynamics AX 2009

Page | 40

public void init(

Common _documentRecord, MenuItemName _menuItemName, WorkflowConfigurationTable _workflowConfigurationTable, WorkflowWorkItemTable _workflowWorkItemTable, EPWorkflowControlContext _workflowControlContext ) { this.parmPurchTable(_documentRecord); this.parmSubmit(_menuItemName == menuitemactionstr (PurchOrderSubmitToWorkflow)); this.parmMenuItemName(_menuItemName); if (_workflowControlContext) { this.parmWorkflowControlContext(_workflowControlContext); this.parmWorkflowWorkItemtable (_workflowControlContext.getActiveWorkflowWorkItem()); this.parmWorkflowComment(_workflowControlContext.getWorkflowComment()); this.parmWorkflowTemplateName (_workflowControlContext.getActiveWorkflowConfiguration().TemplateName); } else { this.parmWorkflowConfigurationTable(_workflowConfigurationTable); this.parmWorkflowWorkItemtable(_workflowWorkItemTable); this.parmWorkflowTemplateName (this.parmWorkflowConfigurationTable().TemplateName); } }

Microsoft Dynamics AX 2009

Page | 41

void reSubmit() { Object purchTable_ds; ; ttsbegin; WorkflowWorkItemActionManager::dispatchWorkItemAction( workflowWorkItemTable, workflowComment, userId, WorkflowWorkItemActionType::Resubmit, menuItemName, false); purchTable_ds purchTable.State = purchTable.dataSource(); = PurchReqWorkflowState::Submitted;

if (purchTable_ds) { purchTable_ds.write(); purchTable_ds.refresh(); } ttscommit; } void submit() { Object NoYes ; EP activatingFromWeb = this.parmWorkflowControlContext() == null ? NoYes::No : NoYes::Yes; Workflow::activateFromWorkflowTemplate( this.parmWorkflowTemplateName(),purchTable.RecId, this.parmWorkflowComment(),activatingFromWeb, curuserid()); purchTable_ds purchTable.SubmittedBy purchTable.SubmittedDateTime purchTable.State if (purchTable_ds) { purchTable_ds.write(); purchTable_ds.refresh(); } } = = = = purchTable.dataSource(); curuserid(); DateTimeUtil::utcNow(); PurchReqWorkflowState::Submitted;

purchTable_ds; activatingFromWeb;

// If we have a workflow control context, we are being activated from

Microsoft Dynamics AX 2009

Page | 42

public static void main(Args args) { PurchOrderWorkflow purchOrderWorkflow; PurchTable purchTable; ; purchTable = args.record(); purchOrderWorkflow = PurchOrderWorkflow::construct(); if (args.menuItemName() == menuitemactionstr(PurchOrderSubmitToWorkflow) || args.menuItemName() == menuitemactionstr(PurchOrderReSubmit)) { purchOrderWorkflow.init(args.record(), args.menuItemName(), args.caller().getActiveWorkflowConfiguration(), args.caller().getActiveWorkflowWorkItem(), null); } else { purchOrderWorkflow.init(args.record(), args.menuItemName(), null, null, args.caller()); } if (purchOrderWorkflow.dialogOk()) { if (purchOrderWorkflow.parmSubmit()) { purchOrderWorkflow.submit(); } else { purchOrderWorkflow.reSubmit(); } if (args.menuItemName() == menuitemactionstr(PurchOrderSubmitToWorkflow) || args.menuItemName() == menuitemactionstr(PurchOrderReSubmit)) args.caller().updateWorkflowControls(); } } 3. Once you create this class save it 4. Now go ahead and create two action type menu items for this class (The names of which you have used in the class created above (PurchOrderSubmitToWorkflow, PurchOrderReSubmit) 5. Traverse to Menu Items Action and create the following menu items

Microsoft Dynamics AX 2009

Page | 43

Property Name Label HelpText ObjectType Object RunOn SecurityKey NeededAccessLevel Name Label HelpText ObjectType Object RunOn SecurityKey NeededAccessLevel

Value Menu Item: Submit PurchOrderSubmitToWorkflow Submit Submit purchase order workflow Class PurchOrderWorkflow Called from VendMisc Edit Menu Item: Resubmit PurchOrderApprovalReject Submit Resubmit purchase order workflow Class PurchOrderWorkflow Called from VendMisc Edit

Next we will attach these menu items with workflow templates and approvals / tasks Attach Submit Action Menu Item to Workflow Template 1. Open the AOT 2. Traverse to Workflow Workflow Templates 3. Find PurchOrderApproval template and set the property SubmitToWorkflowMenuItem as PurchOrderSubmitToWorkflow 4. Save the template See the screen shot below:

Microsoft Dynamics AX 2009

Page | 44

Attach Resubmit Action Menu Item to Approvals and Tasks 1. Open the AOT 2. Traverse to Workflow Tasks 3. Find PurchOrderComplete task and set the property ResubmitMenuItem as PurchOrderReSubmit 4. Save the Task See the screen shot below:

5. Next Traverse to Workflow Approvals 6. Find PurchOrderApproval approval and set the property ResubmitMenuItem as PurchOrderReSubmit 7. Save the Approval See the screen shot below:

Microsoft Dynamics AX 2009

Page | 45

Now the new workflow template is created and ready for configuration. Unless you create one active configuration for this workflow, the Submit button will not be visible on the purchase order form. To know more about configuring workflows click here.

1.4 In the End


We have seen how we can add new workflow templates rather easily for any feature of Dynamics AX. The workflow module is a highly configurable and flexible module. This document has demonstrated exhaustively how to develop a new workflow. For any help on development of workflows refer to help system of Dynamics AX and Purchase requisition workflow. This is the only workflow in standard AX that has covered almost all the artifacts and features of Workflow framework provided by Microsoft Dynamics AX 2009.

Microsoft Dynamics AX 2009

Page | 46

You might also like