In this blog we see all about Workflows development in D365fo
Output as shown in below
boolean ret;
ret = super(_workflowType);
if (this.WorkflowStatus == WorkflowStatus::Draft)
{
ret = true;
}
return ret;
}
EmployeeTable employeeTable;
ttsbegin;
select firstonly forupdate employeeTable
where employeeTable.RecId == _recId;
employeeTable.EmployeeWFStatus = _status;
employeeTable.update();
ttscommit;
}
/// The CustomWorkflowTypeEventHandler workflow event handler.
/// </summary>
public class CustomWorkflowTypeEventHandler implements WorkflowCanceledEventHandler,
WorkflowCompletedEventHandler,
WorkflowStartedEventHandler
{
public void started(WorkflowEventArgs _workflowEventArgs)
{
// TODO: Write code to execute once the workflow is started.
EmployeeTable::updateWorkFlowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::Pending);
}
public void canceled(WorkflowEventArgs _workflowEventArgs)
{
// TODO: Write code to execute once the workflow is canceled.
EmployeeTable::updateWorkFlowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::Draft);
}
public void completed(WorkflowEventArgs _workflowEventArgs)
{
// TODO: Write code to execute once the workflow is completed.
EmployeeTable::updateWorkFlowStatus(_workflowEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::Completed);
}
}
Step8:- Add code in Submitmanagerclass
Code:-
/// <summary>
/// The CustomWorkflowTypeSubmitManager menu item action event handler.
/// </summary>
public class CustomWorkflowTypeSubmitManager
{
public static void main(Args _args)
{
// TODO: Write code to execute once a work item is submitted.
EmployeeTable employeetable;
CustomWorkflowTypeSubmitManager submitManger = new CustomWorkflowTypeSubmitManager();
recId _recId =_args.record().RecId;
WorkflowCorrelationId _workflowCorrelationId;
workflowTypeName _workflowTypeName = workFlowTypeStr("CustomWorkflowType");
WorkflowComment note = "";
WorkflowSubmitDialog workflowSubmitDialog;
workflowSubmitDialog = WorkflowSubmitDialog::construct(_args.caller().getActiveWorkflowConfiguration());
workflowSubmitDialog.run();
if (workflowSubmitDialog.parmIsClosedOK())
{
employeetable = _args.record();
note = workflowSubmitDialog.parmWorkflowComment();
try
{
ttsbegin;
_workflowCorrelationId = Workflow::activateFromWorkflowType(_workflowTypeName, employeetable.RecId, note, NoYes::No);
employeetable.WorkflowStatus = WorkflowStatus::Submitted;
employeetable.update();
ttscommit;
info("Submitted to workflow.");
}
catch (Exception::Error)
{
error("Error on workflow activation.");
}
}
_args.caller().updateWorkFlowControls();
}
}
Step 9:-Add Workflow Approval
Provide details created in above steps
After clicking next system will create some classes and action menuitems
Step10:-Add code in Approval event handler
Code:-
/// <summary>
/// The CustomWorkflowApprovalEventHandler workflow outcome event handler.
/// </summary>
public final class CustomWorkflowApprovalEventHandler implements WorkflowElementCanceledEventHandler,
WorkflowElemChangeRequestedEventHandler,
WorkflowElementCompletedEventHandler,
WorkflowElementReturnedEventHandler,
WorkflowElementStartedEventHandler,
WorkflowElementDeniedEventHandler,
WorkflowWorkItemsCreatedEventHandler
{
public void started(WorkflowElementEventArgs _workflowElementEventArgs)
{
// TODO: Write code to execute once the workflow is started.
EmployeeTable::updateWorkFlowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::InReview);
}
public void canceled(WorkflowElementEventArgs _workflowElementEventArgs)
{
// TODO: Write code to execute once the workflow is canceled.
EmployeeTable::updateWorkFlowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::Draft);
}
public void completed(WorkflowElementEventArgs _workflowElementEventArgs)
{
// TODO: Write code to execute once the workflow is completed.
EmployeeTable::updateWorkFlowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::Completed);
}
public void denied(WorkflowElementEventArgs _workflowElementEventArgs)
{
// TODO: Write code to execute once the workflow is denied.
EmployeeTable::updateWorkFlowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::Rejected);
}
public void changeRequested(WorkflowElementEventArgs _workflowElementEventArgs)
{
// TODO: Write code to execute once change is requested for the workflow.
EmployeeTable::updateWorkFlowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::ChangeRequest);
}
public void returned(WorkflowElementEventArgs _workflowElementEventArgs)
{
// TODO: Write code to execute once the workflow is returned.
EmployeeTable::updateWorkFlowStatus(_workflowElementEventArgs.parmWorkflowContext().parmRecId(), WorkflowStatus::Rejected);
}
public void created(WorkflowWorkItemsEventArgs _workflowWorkItemsEventArgs)
{
// TODO: Write code to execute once work items are created.
}
}
Step11:-Write code in Resubmit class
/// <summary>
/// The CustomWorkflowApprovalResubmitActionMgr menu item action event handler.
/// </summary>
public class CustomWorkflowApprovalResubmitActionMgr
{
public static void main(Args _args)
{
// TODO: Write code to execute once work items are resubmitted.
if (!_args.record() || !_args.caller())
{
throw error(Error::wrongUseOfFunction(funcName()));
}
WorkflowWorkItemTable workItem = _args.caller().getActiveWorkflowWorkItem();
if (workItem)
{
try
{
WorkflowWorkItemActionDialog dialog = WorkflowWorkItemActionDialog::construct(
workItem,
WorkflowWorkItemActionType::Resubmit,
new MenuFunction(_args.menuItemName(),_args.menuItemType()));
dialog.run();
if (dialog.parmIsClosedOK())
{
workItem = _args.caller().getActiveWorkflowWorkItem();
WorkflowWorkItemActionManager::dispatchWorkItemAction(
workItem,
dialog.parmWorkflowComment(),
dialog.parmTargetUser(),
WorkflowWorkItemActionType::Resubmit,
_args.menuItemName());
RecID recID = _args.record().RecId;
ttsbegin;
EmployeeTable::updateWorkFlowStatus(recID, WorkflowStatus::Submitted);
info("@AccountsPayable:VendBankAccountChangeProposalResubmit_Success");
ttscommit;
}
}
catch(exception::Error)
{
info("@AccountsPayable:VednBankAccountChangeProposalResubmit_Error");
}
}
// make sure changes in status are reflected on the caller
if (FormDataUtil::isFormDataSource(_args.record()))
{
FormDataSource callerDS = FormDataUtil::getFormDatasource(_args.record());
callerDS.reread();
callerDS.refresh();
}
_args.caller().updateWorkflowControls();
}
}
Step12:-Change labels for action menu items that have been created by systems
Note:- for cancel put Recall
Step 13:-In form design properties changes properties of Workflow
Configure workflow in front and assign required approvers.
Thankyou!!
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)