Thursday, August 11, 2016

Workflow Helper Class ax 2012 -- Creation helper



SysWorkflowEventDispatcher-->onWorkItemCreate
SysWorkflowWorkItemContext
public server static WorkflowWorkItemInstanceId onWorkItemCreate(
    SysWorkflowWorkItemContext _workItemContext,
    WorkflowWorkItemClaimed _isClaimed = NoYes::Yes,
    NoYes _useAutoDelegatation = NoYes::Yes,
    WorkflowComment _comment = '')
{
    WorkflowTrackingMessage trackingMessage;
    SysWorkflowTracking tracking;
    WorkflowWorkItemTable workItem;
    WorkflowStepTable stepTable;
    WorkflowElementTable elementTable;
    WorkflowVersionTable versionTable;
    Map mergeValues = new Map(Types::String, Types::String);
    SysDictWorkflowElement sysDictWorkflowElement;
    WorkflowDocument workflowDocument;
    Query query;
    userId user;
    menuItemName menuItemName;
    EventNotificationWorkflow notification;
    WorkflowWorkItemInstanceId workItemId;
    WorkflowOutcomeName completingOutcome;
    WorkflowStepInstruction stepInstruction;
    WorkflowConfigMessageText subject;
    SysWorkflowTable workflowTable;
    WorkflowElementId elementId;
    WorkflowDateTime emptyDateTime;
    LabelId labelId;
    Struct trackingPropertyBag;
    List trackingMessageArgs;
    WorkflowUserList autoDelegators;
    #Workflow
    setprefix(classstr(SysWorkflowEventDispatcher) + '-' + staticmethodstr(SysWorkflowEventDispatcher, onWorkItemCreate));
    if (_workItemContext == null)
    {
        throw error(strfmt("@SYS104836", staticmethodstr(SysWorkflowEventDispatcher, onWorkItemCreate), varstr(_workItemContext)));
    }
    changecompany(_workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmCompanyId())
    {
        // create the work item
        versionTable = WorkflowVersionTable::find(_workItemContext.parmWorkflowCorrelation().parmWorkflowConfigurationKey().parmConfigurationId());
        workflowTable = SysWorkflowTable::find(_workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmWorkflowCorrelationId());
        if (workflowTable.RecId == 0)
        {
            throw error("@SYS116100");
        }
        user = _workItemContext.parmAxaptaUser();
        if (_useAutoDelegatation == NoYes::Yes)
        {
            autoDelegators = WorkflowUserList::construct();
            user = SysWorkflowHelper::getDelegate(_workItemContext.parmAxaptaUser(), versionTable);
            if (strcmp(user, _workItemContext.parmAxaptaUser()) != 0)
            {
                autoDelegators.add(_workItemContext.parmAxaptaUser());
            }
        }
        else
        {
            autoDelegators = _workItemContext.parmDelegators();
        }
        // These system generated work items are configured at the element level i.e. there is not
        // a step associated with them.
        if (_workItemContext.parmWorkItemType() == WorkflowWorkItemType::RequestChange ||
            _workItemContext.parmWorkItemType() == WorkflowWorkItemType::Return ||
            _workItemContext.parmWorkItemType() == WorkflowWorkItemType::FinalApprover)
        {
            elementTable = WorkflowElementTable::find(_workItemContext.parmElementId());
            if (elementTable.RecId == 0)
            {
                throw error("@SYS106828");
            }
            elementId = elementTable.ElementId;
            select firstonly StepId from stepTable where stepTable.ElementId == elementTable.ElementId && stepTable.Sequence == 1;
            if (!stepTable.StepId)
            {
                throw error("@SYS106826");
            }
            // Assign the step id of the element's first step to the system
            // created work item i.e.the resubmit work item is always associated
            // with the element's first step. A resubmit always restarts at the
            // element not the individual steps therefore the resubmit work item
            // is always associated with element's first step.
            _workItemContext.parmWorkStepId(stepTable.StepId);
            // Make sure we clear out the due date for these work item types
            if (_workItemContext.parmWorkItemType() == WorkflowWorkItemType::RequestChange ||
                _workItemContext.parmWorkItemType() == WorkflowWorkItemType::Return)
            {
                _workItemContext.parmDueDate(emptyDateTime);
            }
            // now that we have set the step id in the context we can get the delegate user
            sysDictWorkflowElement = new SysDictWorkflowElement(elementTable.ElementType, elementTable.ElementName);
            if (!sysDictWorkflowElement)
            {
                throw error (strfmt("@SYS110280", elementTable.ElementType, elementTable.ElementName));
            }
            if (_workItemContext.parmWorkItemType() == WorkflowWorkItemType::FinalApprover)
            {
                stepInstruction = SysWorkflowHelper::getLocalizedLabelText(literalstr("@SYS124600"), user);
                subject = SysWorkflowHelper::getLocalizedLabelText(literalstr("@SYS124601"), user);
            }
            else
            {
                stepInstruction = SysWorkflowHelper::getLocalizedLabelText(literalstr("@SYS110261"), user);
                subject = _workItemContext.parmWorkItemType() == WorkflowWorkItemType::RequestChange ?
                    SysWorkflowHelper::getLocalizedLabelText(literalstr("@SYS113435"), user) :
                    SysWorkflowHelper::getLocalizedLabelText(literalstr("@SYS112540"), user);
            }
            menuItemName = sysDictWorkflowElement.documentMenuItem();
            if (!SysWorkflowHelper::userHasPermission(
                _workItemContext.parmWorkflowCorrelation().parmWorkflowContext(),
                elementTable.workflowVersionTable().workflowTable().TemplateName,
                sysDictWorkflowElement.resubmitMenuItem(),
                menuItemName,
                user))
            {
                throw error(strfmt("@SYS109561", user));
            }
        }
        else
        {
            stepTable = WorkflowStepTable::find(_workItemContext.parmWorkStepId());
            if (!stepTable)
            {
                throw error("@SYS106826");
            }
            sysDictWorkflowElement = new SysDictWorkflowElement(stepTable.workflowElementTable().ElementType, stepTable.workflowElementTable().ElementName);
            if (!sysDictWorkflowElement)
            {
                throw error (strfmt("@SYS110280", stepTable.workflowElementTable().ElementType, stepTable.workflowElementTable().ElementName));
            }
            // the getXXXX methods do the language conversion
            stepInstruction = stepTable.getInstruction(user);
            subject = stepTable.getDescription(user);
            menuItemName = sysDictWorkflowElement.documentMenuItem();
            completingOutcome = sysDictWorkflowElement.getCompletingOutcome();
            if (!SysWorkflowHelper::userHasPermission(
                _workItemContext.parmWorkflowCorrelation().parmWorkflowContext(),
                stepTable.workflowElementTable().workflowVersionTable().workflowTable().TemplateName,
                sysDictWorkflowElement.actionMenuItem(completingOutcome),
                menuItemName,
                user))
            {
                throw error(strfmt("@SYS109561", user));
            }
        }
        ttsbegin;
        workItem.Id                 = newguid();
        workItem.ActivityId         = _workItemContext.parmWorkflowActivityInstanceKey().parmWorkflowActivityInstanceId();
        workItem.ConfigurationId    = _workItemContext.parmWorkflowCorrelation().parmWorkflowConfigurationKey().parmConfigurationId();
        workItem.DueDateTime        = _workItemContext.parmDueDate();
        workItem.CorrelationId      = _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmWorkflowCorrelationId();
        workItem.ElementId          = _workItemContext.parmElementId();
        workItem.StepId             = _workItemContext.parmWorkStepId();
        workItem.RefTableId         = _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmTableId();
        workItem.RefRecId           = _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmRecId();
        workItem.CompanyId          = _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmCompanyId();
        workItem.Type               = _workItemContext.parmWorkItemType();
        // approvals are always claimed, single task work items are always claimed.
        // When there is more than one work item for a task then all the work items are unclaimed - this is determined by the caller
        workItem.IsClaimed          = stepTable.workflowElementTable().ElementType == WorkflowElementType::Approval ? NoYes::Yes : _isClaimed;
        workItem.IsRead             = NoYes::No;
        workItem.Status             = WorkflowWorkItemStatus::Pending;
        workItem.SubWorkflowId      = _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmSubWorkflowId();
        workItem.RootCorrelationId  = _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmRootCorrelationId();
        workItem.ParentCorrelationId = _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmParentCorrelationId();
        workItem.EscalationLevel = 0;
        workItem.UserId = user;
        // verify that final approver is not the originator
        if (_workItemContext.parmWorkItemType() == WorkflowWorkItemType::FinalApprover &&
            sysDictWorkflowElement.type() == WorkflowElementType::Approval)
        {
            if (strcmp(workItem.UserId, workflowTable.Originator) == 0)
            {
                throw error(strfmt("@SYS119362", workflowTable.Originator));
            }
            if (strcmp(workItem.UserId, workflowTable.Submitter) == 0)
            {
                throw error(strfmt("@SYS126948", workflowTable.Submitter));
            }
            // Final approver: %1
            trackingMessage = strfmt("@SYS108731", workItem.UserId);
            labelId = literalstr("@SYS108731");
            trackingMessageArgs = new List(Types::Class);
            trackingPropertyBag = new Struct (#WorkflowTrackingArgumentStruct);
            trackingPropertyBag.value(#WorkflowTrackingArgumentDataType, extendedtypestr(WorkflowUser));
            trackingPropertyBag.value(#WorkflowTrackingArgumentValue, workItem.UserId);
            trackingMessageArgs.addEnd(trackingPropertyBag);
            tracking = SysWorkflowTracking::newSysWorkflowTracking(
                _workItemContext.parmWorkflowCorrelation(),
                workItem.UserId,
                WorkflowTrackingContext::Approval,
                WorkflowTrackingType::FinalApproverRequired);
            tracking.parmTrackingMessage(trackingMessage);
            tracking.parmElementId(elementId);
            tracking.parmName(elementTable.Name);
            tracking.parmMessageLabelId(labelId);
            tracking.parmMessageArgs(trackingMessageArgs);
            WorkflowTrackingTable::saveTracking(tracking);
        }
        workItem.Subject = WorkflowDocumentField::substitutePlaceholderAsUser(
            workItem.UserId,
            workItem.CompanyId,
            workItem.RefTableId,
            workItem.RefRecId,
            versionTable.workflowTable().TemplateName,
            versionTable.Owner,
            workflowTable.Originator,
            workItem.UserId,
            subject,
            _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmWorkflowCorrelationId());
        workItem.Description = WorkflowDocumentField::substitutePlaceholderAsUser(
            workItem.UserId,
            workItem.CompanyId,
            workItem.RefTableId,
            workItem.RefRecId,
            versionTable.workflowTable().TemplateName,
            versionTable.Owner,
            workflowTable.Originator,
            workItem.UserId,
            stepInstruction,
            _workItemContext.parmWorkflowCorrelation().parmWorkflowContext().parmWorkflowCorrelationId());
        if (!workItem.Description)
        {
            // if no descripton use the subject
            workItem.Description = subject;
        }
        workItem.DocumentClassId = className2Id(sysDictWorkflowElement.document());
        workItem.MenuItemName = menuItemName;
        workflowDocument = classfactory.createClass(className2Id(sysDictWorkflowElement.document()));
        if (!workflowDocument)
        {
            throw error("@SYS108554");
        }
        query = workflowDocument.getQuery();
        if (!query)
        {
            throw error("@SYS96001");
        }
        workItem.DataSourceName = sysDictWorkflowElement.documentFormDatasourceName();
        // notify the assignee
        notification = EventNotificationWorkflow::newAction(
            workItem.UserId,
            workItem.Subject,
            DateTimeUtil::date(workItem.DueDateTime),
            workItem.getMenuFunction(),
            workItem.getRecord(),
            WorkflowParameters::find().WorkItemEmailId,
            mergeValues,
            workItem.Description,
            workItem.DataSourceName);
        workItem.NotificationId = notification.create();
        workItem.insert();
        // Assigned to: %1. Due date %2
        trackingMessage = strfmt("@SYS108739", workItem.UserId, _workItemContext.parmDueDate());
        labelId = literalstr("@SYS108739");
        trackingMessageArgs = new List(Types::Class);
        // add user arg
        trackingPropertyBag = new Struct (#WorkflowTrackingArgumentStruct);
        trackingPropertyBag.value(#WorkflowTrackingArgumentDataType, extendedtypestr(WorkflowUser));
        trackingPropertyBag.value(#WorkflowTrackingArgumentValue, workItem.UserId);
        trackingMessageArgs.addEnd(trackingPropertyBag);
        // add due date arg
        trackingPropertyBag = new Struct (#WorkflowTrackingArgumentStruct);
        trackingPropertyBag.value(#WorkflowTrackingArgumentDataType, extendedtypestr(WorkflowDueDate));
        if (_workItemContext.parmWorkItemType() == WorkflowWorkItemType::FinalApprover &&
            sysDictWorkflowElement.type() == WorkflowElementType::Approval)
        {
            trackingPropertyBag.value(#WorkflowTrackingArgumentValue, DateTimeUtil::toStr(DateTimeUtil::minValue()));
            trackingPropertyBag.value(#WorkflowTrackingArgumentDate, DateTimeUtil::minValue());
        }
        else
        {
            trackingPropertyBag.value(#WorkflowTrackingArgumentValue, DateTimeUtil::toStr(_workItemContext.parmDueDate()));
            trackingPropertyBag.value(#WorkflowTrackingArgumentDate, _workItemContext.parmDueDate());
        }
        trackingMessageArgs.addEnd(trackingPropertyBag);
        tracking = SysWorkflowTracking::newSysWorkflowTracking(
            _workItemContext.parmWorkflowCorrelation(),
            workItem.UserId,
            WorkflowTrackingContext::WorkItem,
            WorkflowTrackingType::Creation);
        tracking.parmTrackingMessage(trackingMessage);
        tracking.parmTrackingComment(_comment);
        tracking.parmWorkItemId(workItem.Id);
        tracking.parmWorkItemActivityInstanceId(workItem.ActivityId);
        tracking.parmElementId(workItem.ElementId);
        tracking.parmStepId(workItem.StepId);
        tracking.parmDueDate(workItem.DueDateTime);
        tracking.parmMessageLabelId(labelId);
        tracking.parmMessageArgs(trackingMessageArgs);
        WorkflowTrackingTable::saveTracking(tracking);
        SysWorkflowEventDispatcher::trackWorkItemDelegation(_workItemContext, workItem, autoDelegators);
        ttscommit;
        workItemId = workItem.Id;
    }
    return workItemId;
}

No comments:

Post a Comment

Convert Call stack to readable format in D365FO X++

//Input --container _xppCallStack = xSession::xppCallStack();  Public static str POL_formatXppCallStack(container _xppCallStack, int _skipFr...