0% found this document useful (0 votes)
37 views16 pages

AX 2012 Create Custom Workflow - D365 FinOps

The document describes how to create a custom workflow in Dynamics 365 Finance and Operations. Key steps include: 1. Defining workflow statuses and adding a field to the relevant table 2. Overriding methods to define submission criteria and update statuses 3. Creating workflow elements like the type, category, and query 4. Adding event handlers to update statuses during the workflow process 5. Designing the workflow by connecting states and elements This allows setting up an approval process for customers not available out of the box, with custom logic for submission, updating statuses, and handling events throughout the workflow lifecycle.

Uploaded by

Khorusaki
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views16 pages

AX 2012 Create Custom Workflow - D365 FinOps

The document describes how to create a custom workflow in Dynamics 365 Finance and Operations. Key steps include: 1. Defining workflow statuses and adding a field to the relevant table 2. Overriding methods to define submission criteria and update statuses 3. Creating workflow elements like the type, category, and query 4. Adding event handlers to update statuses during the workflow process 5. Designing the workflow by connecting states and elements This allows setting up an approval process for customers not available out of the box, with custom logic for submission, updating statuses, and handling events throughout the workflow lifecycle.

Uploaded by

Khorusaki
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

D365 FinOps

Technical and Functional Blog

AX 2012: Create Custom Workflow

Purpose:

The purpose of this document is to describe how we can develop a custom workflow template.

Business requirement:

Ability to have approval process for customers. Standard AX does not offer any workflow for
customers approval out-of-the-box.

Unit testing prerequisites:

The following steps must be completed before a workflow can be unit tested.

1. Configure workflow execution account.


2. Configure workflow batch jobs
◦ Configure workflow batch group
◦ Run workflow infrastructure configuration wizard
Development:

1. Create a workflow status Enum to have the following elements:

2. Add field of type workflow status enum to the CustTable table.


3. Override canSubmitToWorkflow() method of CustTable table to define workflow submission
criteria.

public boolean canSubmitToWorkflow(str _workflowType = '')


{
boolean canSubmit = false;

if (custTable.RecId &&
custTable.MzkWorkflowApprovalStatus ==
MzkCustWFApprovalStatus::NotSubmitted)
{
canSubmit = true;
}

return canSubmit;
}

4. Add a static method on CustTable table to update workflow status. This method will be called
from workflow event handlers and workflow approval event handlers.
static void mzkUpdateWorkflowStatus(RefRecId _recId,
MzkCustWorkflowStatus _status)
{
CustTable custTable;

custTable = CustTable::findRecId(_recId, true);

ttsBegin;
custTable.MzkWorkflowApprovalStatus = _status;
custTable.update();
ttsCommit;
}

5. Create a Query for the CustTable table.

6. Create a Workflow Category.


7. Create a Workflow Type using wizard.
Where,

◦ Category – Name of the workflow category.


◦ Query – Name of the query.
◦ Document menu item – Name of display menu item for the document form.

The following artifacts will be created:

◦ Workflow type
◦ Classes
◦ Document class which extends WorkflowDocument.
◦ EventHandler class which gives implementation to handle different workflow events.
◦ SubmitManager class.
◦ Action menu items:
◦ SubmitMenuItem pointing to SubmitManager class.
◦ CancelMenuItem pointing to WorkflowCancelManager class.

8. Enable Workflow on CustTable and CustTableListPage form by se�ing Design node


properties as follows:

◦ WorkflowEnabled – Yes.
◦ WorkflowDatasource – Name of the form datasource, CustTable.
◦ WorkflowType – Name of the custom workflow type created.

9. Give submit logic in SubmitManager class.


public static void main(Args _args)
{
MzkCustWorkflowTypeSubmitManager submitManager;

submitManager = new MzkCustWorkflowTypeSubmitManager();


submitManager.submit(_args);
}
public void submit(Args _args)
{
RecId _recId;
WorkflowCorrelationId _workflowCorrelationId;
workflowTypeName _workflowTypeName;
WorkflowComment _initialNote;
WorkflowSubmitDialog workflowSubmitDialog;

_recId = _args.record().RecId;
_workflowTypeName = workFlowTypeStr("MzkCustWorkflowType");
_initialNote = "";

// Opens the submit to workflow dialog.


workflowSubmitDialog = WorkflowSubmitDialog::construct(
_args.caller().getActiveWorkflowConfiguration());

workflowSubmitDialog.run();

if (workflowSubmitDialog.parmIsClosedOK())
{
_recId = _args.record().RecId;
// Get comments from the submit to workflow dialog.
_initialNote = workflowSubmitDialog.parmWorkflowComment();

try
{
ttsbegin;

_workflowCorrelationId = Workflow::activateFromWorkflowType(
_workflowTypeName, _recId, _initialNote, NoYes::No);

ttscommit;

// Updates the workflow button to diplay Actions instead of


Submit.
_args.caller().updateWorkflowControls();

info("Submitted to workflow.");
}
catch(exception::Error)
{
error("Error on workflow activation.");
}
}
}

10. Create a Workflow Approval element using the wizard.


11. Drag the newly created approval to the Supported elements node of the custom workflow
type.
12. Define workflow type event handlers in workflow type event handler class.

class MzkCustWorkflowTypeEventHandler implements


WorkflowCanceledEventHandler,
WorkflowCompletedEventHandler,
WorkflowStartedEventHandler
{
}

public void started(WorkflowEventArgs _workflowEventArgs)


{
CustTable::mzkUpdateWorkflowStatus(
_workflowEventArgs.parmWorkflowContext().parmRecId(),
MzkCustWFApprovalStatus::Submitted);
}
public void completed(WorkflowEventArgs _workflowEventArgs)
{
CustTable::mzkUpdateWorkflowStatus(
_workflowEventArgs.parmWorkflowContext().parmRecId(),
MzkCustWFApprovalStatus::Completed);
}

public void canceled(WorkflowEventArgs _workflowEventArgs)


{
CustTable::mzkUpdateWorkflowStatus(
_workflowEventArgs.parmWorkflowContext().parmRecId(),
MzkCustWFApprovalStatus::Canceled);
}

13. Define approval element event handlers in workflow approval element event handler class.

class MzkCustWFApprovalEventHandler implements


WorkflowElementCanceledEventHandler,
WorkflowElemChangeRequestedEventHandler,
WorkflowElementCompletedEventHandler,
WorkflowElementReturnedEventHandler,
WorkflowElementStartedEventHandler,
WorkflowElementDeniedEventHandler,
WorkflowWorkItemsCreatedEventHandler
{
}

public void started(WorkflowElementEventArgs _workflowElementEventArgs)


{
CustTable::mzkUpdateWorkflowStatus(
_workflowElementEventArgs.parmWorkflowContext().parmRecId(),
MzkCustWFApprovalStatus::Submitted);
}

public void changeRequested(WorkflowElementEventArgs


_workflowElementEventArgs)
{
CustTable::mzkUpdateWorkflowStatus(
_workflowElementEventArgs.parmWorkflowContext().parmRecId(),
MzkCustWFApprovalStatus::ChangeRequested);
}
public void canceled(WorkflowElementEventArgs _workflowElementEventArgs)
{
CustTable::mzkUpdateWorkflowStatus(
_workflowElementEventArgs.parmWorkflowContext().parmRecId(),
MzkCustWFApprovalStatus::PendingCancelation);
}

public void completed(WorkflowElementEventArgs _workflowElementEventArgs)


{
CustTable::mzkUpdateWorkflowStatus(
_workflowElementEventArgs.parmWorkflowContext().parmRecId(),
MzkCustWFApprovalStatus::Completed);
}

public void returned(WorkflowElementEventArgs _workflowElementEventArgs)


{
CustTable::mzkUpdateWorkflowStatus(
_workflowElementEventArgs.parmWorkflowContext().parmRecId(),
MzkCustWFApprovalStatus::Returned);
}

public void created(WorkflowWorkItemsEventArgs


_workflowWorkItemsEventArgs)
{
CustTable::mzkUpdateWorkflowStatus(

_workflowWorkItemsEventArgs.parmWorkflowElementEventArgs().parmWorkflowCo
ntext().parmRecId(),
MzkCustWFApprovalStatus::Created);
}

14. Define the resubmit action manager class.

public class MzkCustWFApprovalResubmitActionMgr


{
}
public static void main(Args _args)
{
RecID recID;
TableId tableId;
CustTable custTable;
WorkflowWorkItemTable workItem;
WorkflowWorkItemActionDialog workflowWorkItemActionDialog;

recID = _args.record().RecId;
tableId = _args.record().TableId;
custTable = _args.record();
workItem = _args.caller().getActiveWorkflowWorkItem();

if (workItem.RecId > 0)
{
try
{
workflowWorkItemActionDialog =
WorkflowWorkItemActionDialog::construct(
workItem,
WorkflowWorkItemActionType::Resubmit,
new
MenuFunction(_args.menuItemName(),_args.menuItemType()));

workflowWorkItemActionDialog.run();

if (workflowWorkItemActionDialog.parmIsClosedOK())
{
if (custTable.MzkWorkflowApprovalStatus ==
MzkCustWFApprovalStatus::ChangeRequested)
{
workItem =
_args.caller().getActiveWorkflowWorkItem();

WorkflowWorkItemActionManager::dispatchWorkItemAction(workItem,

workflowWorkItemActionDialog.parmWorkflowComment(),
workflowWorkItemActionDialog.parmTargetUser(),
WorkflowWorkItemActionType::Resubmit,
_args.menuItemName(),
false);

custTable.MzkWorkflowApprovalStatus
= MzkCustWFApprovalStatus::Submitted;

ttsbegin;
custTable.dataSource().write();
ttscommit;
}
else
{
throw Exception::Error;
}
}
}
catch(Exception::Error)
{
throw error(strfmt("Cannot resubmit workflow."));
}
}

_args.caller().updateWorkflowControls();
}

15. Design the Workflow.

◦ Navigate to Accounts receivable > Setup > Accounts receivable workflows.


◦ Create a new workflow instance of the workflow type you created.
◦ Define the states from Start to End of the workflow.
◦ Drag approval element from Toolbox on the left to the Designer pane on the right.
◦ Connect the bo�om of Start state with top of the Approval element.
◦ Connect the bo�om of Approval element to the top of End state.
◦ Resolve any errors and warnings by se�ing workflow and approval element properties.
◦ Activate it.
16. Test the workflow. You should be able to see the workflow bar.
February 16, 2015
Development (AX 2012),
Dynamics AX 2012,
Technical (AX 2012),
Workflow

Published by muhammadanaskhan

Muhammad Anas Khan is a Dynamics 365 Finance Consultant. He


has 10+ years of professional experience in software development

and ERP consultancy.  View all posts by muhammadanaskhan

9 thoughts on “AX 2012: Create Custom Workflow”

1. manali
says:
January 21, 2016 at 3:29 pm
Hi,
I am having requirement about workflow that Employee Transfer is standard workflow
but when i am a�ching some conditions to workflow those customised field like
Department,Branch,Counter is not in those condition.

Can you tell me how to deal with this requirement.

Thanks,
Manali

1. muhammadanaskhan
says:
January 22, 2016 at 4:41 pm
Hi Manali,

Where are you a�aching these conditions? Please provide details.

2. Taskheer
says:
March 28, 2017 at 6:07 pm
Submit Bu�on is coming but after clicjing its remain the same and not going for approval,,
Please help.
1. muhammadanaskhan
says:
April 1, 2017 at 9:07 am
Have you implemented the business logic in the *SubmitManager class?

3. Taskheer
says:
April 2, 2017 at 10:37 am
I wri�en the following code in the submit method

TestExpenseTable testexpense;
WorkflowComment note=””;
WorkflowSubmitDialog workflowSubmitDialog;

workflowSubmitDialog =
WorkflowSubmitDialog::construct(_args.caller().getActiveWorkflowConfiguration());
workflowSubmitDialog.run();
if (workflowSubmitDialog.parmIsClosedOK())
{
testexpense = _args.record();
// Get comments from the submit to workflow dialog.
note = workflowSubmitDialog.parmWorkflowComment();
try
{

�sbegin;
testexpense.TestExpensestatus = TestExpensestatus::submit;
�scommit;
// Send an Infolog message.
info(“Submi�ed to workflow.”);
}

catch (Exception::Error)
{
error(“Error on workflow activation.”);
}
}

_args.caller().updateWorkFlowControls();

4. Taskheer
says:
April 2, 2017 at 10:39 am
I wri�en the following code in the submit method

TestExpenseTable testexpense;
WorkflowComment note=””;
WorkflowSubmitDialog workflowSubmitDialog;
workflowSubmitDialog =
WorkflowSubmitDialog::construct(_args.caller().getActiveWorkflowConfiguration());
workflowSubmitDialog.run();
if (workflowSubmitDialog.parmIsClosedOK())
{
testexpense = _args.record();
// Get comments from the submit to workflow dialog.
note = workflowSubmitDialog.parmWorkflowComment();
try
{

�sbegin;
testexpense.TestExpensestatus = TestExpensestatus::submit;
�scommit;
// Send an Infolog message.
info(“Submi�ed to workflow.”);
}

catch (Exception::Error)
{
error(“Error on workflow activation.”);
}
}

_args.caller().updateWorkFlowControls();

5. Tom
says:
April 22, 2017 at 9:33 pm
Hello. Have you worked up a version of this for AX7 (D365 for Operations)?

6. dynamicsoperations
says:
June 17, 2017 at 10:44 am
HI Mr . Muhammad Anas Khan,
Thanks for the post,
11. Drag the newly created approval to the Supported elements node of the custom
workflow type.
I am failing at this point and unable to drag and drop approval type into Workflow type
supported elements,
Can you please suggest the possibilities of this issue.
Environment : D 365.

Thanks & Regards,


Ganesh Vejendla.

7. yassine
says:
March 10, 2018 at 7:37 pm
Hi Muhammad Anas Khan,
Thanks for the post,
I have block in the workflow creation part
1. Create a workflow status Enum to have the following elements:
in which location in ax I find that

BLOG AT WORDPRESS.COM.

UP ↑

You might also like