Wednesday, 11 March 2020

Extend ‘canSubmitToWorkflow’ in standard & base tables without over-layering

This is how we can avoid over-layering while creating workflow on standard form.
CanSubmitToWorkflow
-> Extension of ‘CanSubmitToWorkflow’ method in standard table which is not overridden by standard:
 ‘CanSubmitToWorkflow’ is being called from FormDataUtil:: CanSubmitToWorkflow() method for which post event handler can be written, which is purely extension.

Following is the code snippet:
    /// <summary>
    /// Can submit to workflow
    /// </summary>
    /// <param name="args"></param>
    [PostHandlerFor(classStr(FormDataUtil), staticMethodStr(FormDataUtil, canSubmitToWorkflow))]
    public static void FormDataUtil_Post_canSubmitToWorkflow(XppPrePostArgs args)
    {
        Common             record               = args.getArg(identifierStr(_record));
        SalesTable          salesTable           = record as SalesTable;
        boolean            ret                  = args.getReturnValue();

        if (record.TableId == tableNum(SalesTable))
        {
            if (salesTable.WorkFlowStatus == VersioningDocumentState::Draft)
            {
                ret = boolean::true;
            }
            else
            {
                ret = boolean::false;
            }
        }
        args.setReturnValue(ret);                    
    }

-> Changing workflow properties in standard form through extension:
·         Copy On Initializing event handler of form events.
·         Paste it in your event handler class
·         Write body of the method as follows (replace workflow datasource and workflow type)
     /// <summary>
    /// Triggering workflow dynamically
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormEventHandler(formStr(SalesTableListPage), FormEventType::Initializing)]
    public static void SalesTableListPage_OnInitializing(xFormRun sender, FormEventArgs e)
    {
        FormRun                SalesTableListPage         = sender;
        FormBuildDesign SalesTableListPageDesign = SalesTableListPage.form().design();

        SalesTableListPageDesign.workflowEnabled(true);
        SalesTableListPageDesign.workflowDatasource(tableStr(SalesTable));
        SalesTableListPageDesign.workflowType(workflowTypeStr(SalesOrderWFType));
    }
************************************************************************
To enable workflow in SalesTable form, we need to write below code.
[PostHandlerFor(classStr(SalesTableInteraction), methodStr(SalesTableInteraction, enableHeaderActions))]
   public static void SalesTableInteraction_Post_enableHeaderActions(XppPrePostArgs args)
   {
       SalesTable activeRecord;
       SalesTableInteraction        interaction        = args.getThis();
       Page salesTablePage = interaction.page();
       if (salesTablePage.activeRecord(tablestr(SalesTable)))
       {            
           FormRun formrun   = salesTablePage.formRun();
           FormBuildDesign design     = formrun.form().design();
           FormDesign        wfDesign = formrun.design();
           //WF setup
           design.workflowEnabled(true);
           design.workflowDatasource(tableStr(SalesTable));
           design.workflowType(workflowTypeStr(LTSalesOrderWFType));
           wfDesign.workflowEnabled(true);
           wfDesign.workflowDatasource(tableStr(SalesTable));
           wfDesign.workflowType(workflowTypeStr(LTSalesOrderWFType));
   //updating wf controls            
           formrun.updateWorkflowControls();
       }
   }
To  make workflow button visible in SalesTable form, we need to write below code.
[PostHandlerFor(formStr(SalesTable), formMethodStr(SalesTable, canSubmitToWorkflow))]
   public static void SalesTable_Post_canSubmitToWorkflow(XppPrePostArgs args)
   {
       FormRun salesTableDetails = args.getThis();
       formDataSource salesTableDS    = salesTableDetails.dataHelper().FindDataSource(formDataSourceStr(SalesTable, SalesTable));
       SalesTable salesTable    = salesTableDS.cursor();
       boolean ret    = args.getReturnValue();
       if (salesTable.LTWorkFlowStatus == VersioningDocumentState::Draft)
      {
           ret = NoYes::True;
       }
       else
       {
           ret = NoYes::false;
       }
       args.setReturnValue(ret);
       salesTableDetails.design().controlName('WorkflowActionBarButtonGroup').visible(true);
   }
************************************************************************
Example : 2 
Requirement
There is no standard workflow feature in available process ‘Request For Quotations’.There is a requirement of enabling customised workflow in standard process called ”and base table ‘PurchRFQCaseTable’ and form ‘PurchRFQCaseTableListPage’
Issue
In current version of D365/AX7, there is no possible way to use or extend method ‘canSubmitToWorkflow’ in standard table like PurchRFQCaseTable without overlayering.Also there is no event listed in table PurchRFQCaseTable related to ‘canSubmitToWorkflow’.
Sample Code and Instructions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[ExtensionOf(ClassStr(FormDataUtil))]
final class ACXFormDataUtil_Extension
{
public static boolean canSubmitToWorkflow(Common _record, str _workflowType)
{
boolean ret = next canSubmitToWorkflow(_record, _workflowType);
if (_record.TableId == tableNum(PurchRFQCaseTable))
return true;
else
return ret;
}
}

No comments:

Post a Comment

POSTMAN D365

  Postman is useful to test the behavior of different OData class from/to D365FO. In this post we will see the steps to setup Postman with D...