All that we would like to do is to submit to the workflow, as if approving a project quotation.
Running the code below works... But the changes may not be immediately apparent:
static void ZZZ_WorkflowApprove(Args _args)
{
// Variable declaration.
recId _recId = SalesQuotationTable::find(@'P120139-2').RecId;
WorkflowTypeName _workflowTypeName = workflowtypestr("PSAProjQuotationTemplate");
WorkflowComment _initialNote = strFmt("Accepted");
WorkflowCorrelationId _workflowCorrelationId;
// Activate the workflow from a template.
_workflowCorrelationId = Workflow::activateFromWorkflowType(
_workflowTypeName, _recId, _initialNote, NoYes::No);
}
We can find the name of our workflow in the WorkflowTable entity, looking up the DocumentTableName field value, and obtaining the corresponding Name... Excuse my ignorance with Workflows but I couldn't find an AX form to list them all.To Approve/Reject a work item that is submitted to the workflow try the following snippet, for example approving a project budget:
ProjId _projId = '120152';
ProjBudget _projBudget = ProjBudget::findOrCreateProjectBudget(_projId);
while select workflowWorkItemTable where
(workflowWorkItemTable.Type == WorkflowWorkItemType::WorkItem) &&
(workflowWorkItemTable.Status == WorkflowWorkItemStatus::Pending) &&
//workflowWorkItemTable.DueDateTime < DateTimeUtil::getSystemDateTime() &&
workflowWorkItemTable.RefRecId == _projBudget.RecId &&
workflowWorkItemTable.RefTableId == _projBudget.TableId
{
WorkflowWorkItemActionManager::dispatchWorkItemAction(
workflowWorkItemTable,
"@SYS325206",//Approved budget
curUserId(),
WorkflowWorkItemActionType::Complete,
"ProjBudgetOrigWorkflowApprove",
false);
}
As indicated above, I'm ignorant as to workflows and had to spend a while investigating how to 'launch' the process behind them. A quick look for AX 2009 and AX 2012 appears to be the same, yet for me still I still couldn't control properly the parallelism of handling the two separate processes. Use the following at your own risk (a progress bar would be nice):
private void waitWorkFlow(Common _common)
{
SysWorkflowMessageQueueManager queueManager;
WorkflowWorkItemDueDateJob workItemDueDateJob;
int seconds = 0;
int sleepTime = (1 * 1000); //Milliseconds
int maxWaitTime = 60;
// "Microsoft internal use only."
queueManager = SysWorkflowMessageQueueManager::construct();
queueManager.run();
workItemDueDateJob = new WorkflowWorkItemDueDateJob();
workItemDueDateJob.run();
// Check for 'Completed' status, otherwise wait...
while (Workflow::findTrackingStatusForDocument(_common)
.TrackingStatus != WorkflowTrackingStatus::Completed
&& seconds < maxWaitTime)
{
sleep(sleepTime);
seconds += 1;
}
}
Finally a few useful workflow related links: