DSPWorkflowUtil d365fo x++

DSPWorkflowUtil d365fo x++

Code:

class DSPWorkflowUtil
{
    private static DSPWorkflowUtil workFlowUtilObject;


    public static DSPWorkflowUtil construct()
    {
        if(!workFlowUtilObject)
            workFlowUtilObject = new DSPWorkflowUtil();

        return workFlowUtilObject;
    }

    void submit(Args args)
    {
        recId recId;
        Common record;
        str note;
        WorkflowTypeName    workFlowType;
        WorkflowVersionTable workflowVersionTable;

        workflowVersionTable = args.caller().getActiveWorkflowConfiguration();
        WorkflowType = workflowVersionTable.workflowTable().TemplateName;
        WorkflowSubmitDialog workflowSubmitDialog;
        workflowSubmitDialog = WorkflowSubmitDialog::construct(workflowVersionTable);
        
        record = args.record();
        recId = record.RecId;
        ;
       
        if(!this.isValidToSubmit(record))
        {
            error("@DSPLabel:DSP001247");
            //Refresh caller form to change workflow status and to avoid submitting workflow again
            DSPUtil::refreshForm(args.caller());
            return;
        }

        workflowSubmitDialog.run();

        if (workflowSubmitDialog.parmisClosedOK())
        {
            note = workflowSubmitDialog.parmWorkflowComment();

            // Check validation again to avoid update anomaly
            if(!this.isValidToSubmit(record))
            {
                error("@DSPLabel:DSP001247");
                //Refresh caller form to change workflow status and to avoid submitting workflow again
                DSPUtil::refreshForm(args.caller());
                return;
            }

            try
            {
                Workflow::activateFromWorkflowType(workFlowType,recId,note,NoYes::No);

                this.callSubmitEventHandler(WorkflowType,recId);

                info("@DSPLabel:DSP002403");
            }
            catch (Exception::Error)
            {
                info("@DSPLabel:DSP002404");
            }

            //Refresh caller form to change workflow status and to avoid submitting workflow again
            DSPUtil::refreshForm(args.caller());
        }
        args.caller().updateWorkflowControls();
    }

    void reSubmit(Args _args)
    {
        WorkflowWorkItemTable           workItem            = _args.caller().getActiveWorkflowWorkItem();
        WorkflowWorkItemActionDialog    workflowWorkItemActionDialog;
        
        if (workItem.RecId > 0)
        {
            try
            {
                workflowWorkItemActionDialog = WorkflowWorkItemActionDialog::construct( workItem,
                                                                                    WorkflowWorkItemActionType::Resubmit,
                                                                                    new MenuFunction(_args.menuItemName(),_args.menuItemType()));
                workflowWorkItemActionDialog.run();
                if (workflowWorkItemActionDialog.parmIsClosedOK())
                {
 
                    workItem    = _args.caller().getActiveWorkflowWorkItem();
                    WorkflowWorkItemActionManager::dispatchWorkItemAction(  workItem,
                                                                    workflowWorkItemActionDialog.parmWorkflowComment(),
                                                                    workflowWorkItemActionDialog.parmTargetUser(),
                                                                    WorkflowWorkItemActionType::Resubmit,
                                                                    _args.menuItemName());
               
                }
            }
 
            catch(Exception::Error)
            {
                throw error('Error in resubmitting workflow');
            }
        }
        _args.caller().updateWorkflowControls();
    }

    public void callSubmitEventHandler(WorkflowTypeName _workflowTypeName, RecId _tableRecId)
    {
        SysDictWorkflowType sysDictWorkflowType;
        ClassName   workflowTypeClassName;
        DSPWorkflowSubmittedEventHandler workflowSubmittedEventHandler;
        classId classId;
        SysDictClass dictClass;

        sysDictWorkflowType = new SysDictWorkflowType(_workflowTypeName);
        
        if(sysDictWorkflowType)
        {
            workflowTypeClassName = sysDictWorkflowType.startedEventHandler();
            
            classId = className2Id(workflowTypeClassName);

            dictClass = new SysDictClass(classId);
            
            if(dictClass && dictClass.isImplementing(classNum(DSPWorkflowSubmittedEventHandler)))
            {
                WorkflowSubmittedEventHandler = dictClass.makeObject() as DSPWorkflowSubmittedEventHandler;

                if(WorkflowSubmittedEventHandler)
                    workflowSubmittedEventHandler.submitted(_tableRecId);
            }
            else
            {
                warning('Implement DSPWorkflowSubmittedEventHandler in workflow type event handler');
            }
        }
    }

    public MenuItemName getWorkFlowDocumentMenuItem(FormRun _fRun)
    {
        Args                args;
        FormRun             fRun;
        Common              record;
        MenuItemName        workFlowMenuItem;
        WorkflowTypeName    workFlowType;
        WorkflowVersionTable workflowVersionTable;
        SysDictWorkflowType sysDictWorkflowType;
        ;

        fRun = _fRun;
        
        if(fRun && fRun.args())
        {
            record    = fRun.args().record();
            WorkflowType = (record) ? this.getWorkflowRecordTemplateName(record) : '';

            if(workFlowType)
            {
                sysDictWorkflowType = new SysDictWorkflowType(workFlowType);

                if(sysDictWorkflowType)
                {
                    workFlowMenuItem = sysDictWorkflowType.documentMenuItem();
                }
            }
        }
        
        return workFlowMenuItem;
    }

    public TemplateName getWorkflowRecordTemplateName(Common _record)
    {
        RecId recId;
        TableId tableId;
        TemplateName templateName;
        WorkflowTable workFlowTable;
        ;

        recId = _record.RecId;
        tableId = _record.TableId;

        select firstonly1 TemplateName
            from workFlowTable
            where workFlowTable.DocumentTableName == tableId2Name(tableId);

        templateName = workFlowTable.TemplateName;

        return templateName;
    }

    public WorkflowTable getWorkflowTable(Common _record)
    {
        RecId recId;
        TableId tableId;
        SysWorkflowTable sysWorkFlowTable;
        WorkflowTable workflowTable;
        ;

        recId = _record.RecId;
        tableId = _record.TableId;

        select firstonly1 workflowTable
            join sysWorkFlowTable
            where workflowTable.SequenceNumber == sysWorkFlowTable.ConfigurationSequenceNumber
            && sysWorkFlowTable.ContextTableId == tableId
            && sysWorkFlowTable.ContextRecId == recId;
        
        return workFlowTable;
    }

    public WorkflowTable getWorkflowTableByTableIdAndRecId(RefTableId _refTableId, RefRecId _refRecId)
    {
        RecId recId;
        TableId tableId;
        SysWorkflowTable sysWorkFlowTable;
        WorkflowTable workflowTable;
        ;

        recId = _refRecId;
        tableId = _refTableId;

        select firstonly1 workflowTable
            join sysWorkFlowTable
            where workflowTable.SequenceNumber == sysWorkFlowTable.ConfigurationSequenceNumber
            && sysWorkFlowTable.ContextTableId == tableId
            && sysWorkFlowTable.ContextRecId == recId;
        
        return workFlowTable;
    }

    public HcmPositionHierarchyTypeRecId getPositionHierarchyTypeForWorkflowByTableIdAndRecId(RefTableId _refTableId, RefRecId _refRecId)
    {
        HcmPositionHierarchyTypeRecId positionHierarchyTypeRecId;
        ;

        positionHierarchyTypeRecId = HcmPositionHierarchyTypeWorkflow::find(this.getWorkflowTableByTableIdAndRecId(_refTableId, _refRecId).SequenceNumber).PositionHierarchyType;

        return positionHierarchyTypeRecId;
    }

    public void resubmitWorkflow(RefTableId refTableId, RefRecId refRecId)
    {
        WorkflowWorkItemTable workItem;
        str comment;
        UserId user; // no  need to fill will be auto filled by originator
        MenuItemName menuItemName; // Not required yet
        System.Exception exception;

        try
        {
            workItem = this.getActiveWorkItem(refTableId, refRecId);
            WorkflowWorkItemActionManager::dispatchWorkItemAction(workItem, comment, user, WorkflowWorkItemActionType::Resubmit, menuItemName);
        }
        catch(exception)
        {
        }
    }

    private WorkflowWorkItemTable getActiveWorkItem(RefTableId refTableId, RefRecId refRecId)
    {
        WorkflowWorkItemTable workflowWorkItemTable;
        ;

        select firstonly1 workflowWorkItemTable
            order by workflowWorkItemTable.RecId desc
            where workflowWorkItemTable.RefRecId == refRecId 
            && workflowWorkItemTable.RefTableId == refTableId;

        return workflowWorkItemTable;
    }

    //To avoid update anomaly
    // User open two forms and submit request from both forms as other form data is not refreshed so its valid to submit record again
    private boolean isValidToSubmit(Common _common)
    {
        boolean ret;
        Common common;
        ;

        // Get latest record to avoid previous data
        common = DSPUtil::construct().findRecord(_common.TableId, _common.RecId, false);

        // Verify record is valid for submission
        ret = this.canSubmitToWorkflow(common) && DSPUtil::construct().isValidToSubmit(common);

        return ret;
    }

    private boolean canSubmitToWorkflow(Common _common)
    {
        boolean ret;
        SysDictTable dictTable;
        RefTableId tableId;
        RefRecId recId;
        boolean hasMethod;
        IdentifierName methodName;
        DictTable dt;
        ;

        methodName = 'canSubmitToWorkflow';

        if(_common)
        {
            tableId = _common.TableId;
            recId = _common.RecId;
            dictTable = new SysDictTable(tableId);
            hasMethod = SysDictTable::hasMethod(dictTable, methodName);

            if(hasMethod)
            {
                ret = dictTable.callObject(methodName, _common);
            }
        }

        return ret;
    }

}

Comments

Popular posts from this blog

D365FO – AX – X++ –Refresh, Reread, Research, and ExecuteQuery

Create Inventory Journal through Code in D365FO X++

SalesLine Reservation in D365fo x++