Thursday, 3 July 2025

Create sales order workflow in d365 FO

 https://axraja.blogspot.com/2020/03/d365ax7-extend-cansubmittoworkflow-in.html

/// <summary>

/// This class is an event handler for formDataUtil

/// </summary>

class PNG_FormDataUtilEventHandler

{

    /// <summary>

    /// Can submit to workflow

    /// </summary>

    /// <param name="args">XppPrePostArgs</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::averageDiscountPctCaCheData(salesTable) && !salesTable.InterCompanyOrder && salesTable.RecId

                && salesTable.PNGDocumentState == PNG_VersioningDocumentState::Draft)

            {

                ret = boolean::true;

            }

            else

            {

                ret = boolean::false;

            }

        }

        args.setReturnValue(ret);

    }


    /// <summary>

    /// Triggering workflow dynamically

    /// </summary>

    /// <param name="sender">xFormRun</param>

    /// <param name="e">FormEventArgs</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(PNG_SalesTableWorkflowType));

    }


    /// <summary>

    /// This method is used to enableHeaderActions

    /// </summary>

    /// <param name = "args">XppPrePostArgs</param>

    [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(PNG_SalesTableWorkflowType));

            wfDesign.workflowEnabled(true);

            wfDesign.workflowDatasource(tableStr(SalesTable));

            wfDesign.workflowType(workflowTypeStr(PNG_SalesTableWorkflowType));

            //updating wf controls

            formrun.updateWorkflowControls();

        }

    }


    /// <summary>

    /// This method is used to enable can submit to workflow button

    /// </summary>

    /// <param name = "args">XppPrePostArgs</param>

    [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::averageDiscountPctCaCheData(salesTable) && !salesTable.InterCompanyOrder && salesTable.RecId

            && salesTable.PNGDocumentState == PNG_VersioningDocumentState::Draft)

        {

            ret = boolean::True;

        }

        else

        {

            ret = boolean::false;

        }


        args.setReturnValue(ret);


        if (salesTable::averageDiscountPctCaCheData(salesTable) && !salesTable.InterCompanyOrder && salesTable.RecId)

            

        {

            salesTableDetails.design().controlName('WorkflowActionBarButtonGroup').visible(true);

        }

        else 

        {

            salesTableDetails.design().controlName('WorkflowActionBarButtonGroup').visible(false);

        }

    }

}
-------------------------------------

/// <summary>

/// This class is used to trigger requst change button on approved and confirmed case

/// </summary>

class PNG_SalesButtonRequestChange

{

    /// <summary>

    /// This method is to call the main logic of the class 

    /// </summary>

    /// <param name = "_args">Args</param>

    static void main(Args _args)

    {

        SalesTable       salesTable;

        FormDataSource   fds;



        if (!_args)

            throw error("@SYS25407");


        salesTable = _args.record();


        if (salesTable.RecId &&  

            (salesTable.PNGDocumentState ==  PNG_VersioningDocumentState::Approved || 

            salesTable.PNGDocumentState ==  PNG_VersioningDocumentState::Confirmed))

        {

            ttsbegin;

            salesTable.selectForUpdate(true);

            salesTable.PNGDocumentState =  PNG_VersioningDocumentState::Draft;

            salesTable.doupdate();

            ttscommit;          

        }

        else if (salesTable.RecId && (salesTable.PNGDocumentState == PNG_VersioningDocumentState::Rejected))

        {

            PNG_SalesbuttonRequestChange::cancelAssociatedWorkflows(salesTable.TableId, salesTable.RecId);

        }


        if(_args &&

           _args.record() &&

           _args.record().isFormDataSource())

        {

            fds = _args.record().dataSource();

            fds.selectionChanged();

            fds.research(true);

        }


        Info("@SYS119229");


    }


    static void cancelAssociatedWorkflows(RefTableId _tableId, RefRecId _recId, WorkflowComment _workflowComment = 'The document referenced in the workflow was removed.')

    {

        Set workflowsToCancel = PNG_SalesButtonRequestChange::getPendingWorkflows(_tableId, _recId);

        SetEnumerator setEnumerator = workflowsToCancel.getEnumerator();


        while (setEnumerator.moveNext())

        {

            if (PNG_SalesButtonRequestChange::isValidToCancelWorkflow(setEnumerator.current()))

            {

                UserConnection connection = new UserConnection();


                try

                {

                    connection.ttsbegin();

                    Workflow::cancelWorkflow(setEnumerator.current(), _workflowComment);

                    connection.ttscommit();

                }

                finally

                {

                    connection.finalize();

                }

            }

        }

    }


    static boolean isValidToCancelWorkflow(WorkflowCorrelationId _workflowCorrelationId)

    {

        SysWorkflowTable workflowTable = SysWorkflowTable::find(_workflowCorrelationId);


        return SysWorkflowTable::exist(workflowTable.RootCorrelationId);

    }


    static Set getPendingWorkflows(RefTableId _tableId, RefRecId _recId)

    {

        var workflows = new Set(Types::Guid);

        

        WorkflowWorkItemTable workflowWorkItemTable;


        while select CorrelationId from workflowWorkItemTable

            where workflowWorkItemTable.Status == WorkflowWorkItemStatus::Pending

               && workflowWorkItemTable.RefRecId == _recId

               && workflowWorkItemTable.RefTableId == _tableId

        {

            workflows.add(workflowWorkItemTable.CorrelationId);

        }


        WorkflowTrackingStatusTable workflowTrackingStatusTable;


        while select CorrelationId from workflowTrackingStatusTable

            where workflowTrackingStatusTable.ContextTableId == _tableId

               && workflowTrackingStatusTable.ContextRecId == _recId

               && workflowTrackingStatusTable.TrackingStatus == WorkflowTrackingStatus::Pending

        {

            workflows.add(workflowTrackingStatusTable.CorrelationId);

        }


        return workflows;

    }

}
---------------------------------------------------

//<summary>

 //Bundle extension of the <c>SalesConfirmJournalPost</c> class.

 //</summary>

[ExtensionOf(classStr(SalesConfirmJournalPost))]

public final class PNG_SalesConfirmJournalPost_C_Extension

{

    /// <summary>

    /// This method is called with end of the post confirmation

    /// </summary>

    protected void endUpdate()

    {

        SalesTable salesTable;


        next endUpdate();


        if (this.documentStatus() == DocumentStatus::Confirmation)

        {

            CustConfirmJour custConfirmJourLoc = this.parmJournalTable() as CustConfirmJour;

            

            if (salesTable::averageDiscountPctCaCheData(salesTable::find(custConfirmJourLoc.SalesId)))

            {

                update_recordset salesTable 

                    Setting PNGDocumentState = PNG_VersioningDocumentState::Confirmed

                    where salesTable.SalesId == custConfirmJourLoc.SalesId

                        && salesTable.PNGDocumentState == PNG_VersioningDocumentState::Approved;

            }

            else

            {

                salesTable   salesTableLocal = salesTable::find(custConfirmJourLoc.SalesId);


                if (salesTableLocal.PNGDocumentState == PNG_VersioningDocumentState::Draft)

                {

                    update_recordset salesTable

                        Setting PNGDocumentState = PNG_VersioningDocumentState::Approved

                            where salesTable.SalesId == custConfirmJourLoc.SalesId

                               && salesTable.PNGDocumentState == PNG_VersioningDocumentState::Draft;

                }

            }

        }

    }

}
-------------------------------------------------

/// <summary>

/// This class is an extension of formDatasource SalesLine

/// </summary>

[ExtensionOf(formDataSourceStr(SalesTable, SalesLine))]

final class PNG_SalesLine_DS_Extension

{

   

    /// <summary>

    /// Init method is used to initilise the values

    /// </summary>

    public void init()

    {

        next init();


        this.enableSalesOrderUnitPrice();

    }


    /// <summary>

    /// this method is used to enable disable button on record

    /// </summary>

    /// <returns>int</returns>

    public int active()

    {

        int ret;


        ret = next active();


        this.enableSalesOrderUnitPrice();


        return ret;

    }


    /// <summary>

    /// This method is used to enable sales order unitPrice

    /// </summary>

    public void enableSalesOrderUnitPrice()

    {

        FormDataSource  salesLine_Ds = this.formrun().datasource(FormDataSourceStr(SalesTable, SalesLine)) as FormDataSource;

        SalesLine       salesLine = SalesLine_Ds.cursor();


        InterCompanyEndpointActionPolicy    interCompanyEndpointActionPolicy    = SalesLine.salesTable().interCompanyEndpointActionPolicy();

        boolean                             isICPOLineInvoiceMatched            = salesLine.isInterCompanyOrderLineInvoiceMatched();


        if (!SalesTable::find(SalesLine.SalesId).InterCompanyOrder && SalesLine.SalesId)

        {

            if (CustParameters::find().PNGDisableUnitPrice)

            {

                if (InventTable::find(SalesLine.ItemId).PNGEnableUnitPriceOverride)

                {

                    SalesLine_DS.object(fieldNum(SalesLine, SalesPrice)).enabled(false);

                    SalesLine_DS.object(fieldNum(SalesLine, LineAmount)).enabled(false);

                }

                else

                {

                    SalesLine_DS.object(fieldNum(SalesLine, SalesPrice)).enabled(true);

                    SalesLine_DS.object(fieldNum(SalesLine, LineAmount)).enabled(true);

                }

            }

            else if ((!CustParameters::find().PNGDisableUnitPrice) && (InventTable::find(SalesLine.ItemId).PNGEnableUnitPriceOverride))

            {

                SalesLine_DS.object(fieldNum(SalesLine, SalesPrice)).enabled(false);

                SalesLine_DS.object(fieldNum(SalesLine, LineAmount)).enabled(false);

            }

            else

            {

                SalesLine_DS.object(fieldNum(SalesLine, SalesPrice)).enabled(true);

                SalesLine_DS.object(fieldNum(SalesLine, LineAmount)).enabled(true);

            }

        }

        else if ((SalesTable::find(SalesLine.SalesId).InterCompanyOrder)  && SalesLine.SalesId)

        {

            SalesLine_DS.object(fieldNum(SalesLine, SalesPrice)).enabled(interCompanyEndpointActionPolicy.EditPrice    && !isICPOLineInvoiceMatched);

            SalesLine_DS.object(fieldNum(SalesLine, LineAmount)).enabled(interCompanyEndpointActionPolicy.EditPrice    && !isICPOLineInvoiceMatched);

        }

    }

}
-------------------------------------------------------------

/// <summary>

/// This class is an extension of SalesTable form datasource

/// </summary>

[ExtensionOf(formDataSourceStr(SalesTable, SalesTable))]

final class PNG_SalesTable_DS_Extension

{

    /// <summary>

    /// This method is used when datasource is initialised 

    /// </summary>

    public void init()

    {

        next init();


        this.enableViewButton();

    }


    /// <summary>

    /// This method is used to for active records

    /// </summary>

    /// <returns>INT</returns>

    public int active()

    {

        int ret;


        ret = next active();


        this.enableViewButton();


        return ret;

    }


    /// <summary>

    /// This method is used to enable and view the buttons

    /// </summary>

    public void enableViewButton()

    {

        FormDataSource salesTable_Ds = this.formrun().datasource(FormDataSourceStr(SalesTable, SalesTable)) as FormDataSource;

        FormControl    FormControl   = this.formRun().design().controlName(formControlStr(SalesTable, buttonRequestChange));


        SalesTable  salesTable = salesTable_Ds.cursor();


        if (salesTable.PNGDocumentState == PNG_VersioningDocumentState::InReview ||

            salesTable.PNGDocumentState == PNG_VersioningDocumentState::Approved ||

            salestable.PNGDocumentState == PNG_VersioningDocumentState::Rejected ||

            salesTable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed)

        {

            this.formRun().design().viewEditMode(ViewEditMode::View);

        }


        boolean buttonRequestChange = (salestable.PNGDocumentState == PNG_VersioningDocumentState::Rejected ||

                                       salestable.PNGDocumentState == PNG_VersioningDocumentState::Approved ||

                                       salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed);


        if (buttonRequestChange)

        {

            FormControl.enabled(true);

        }

        else

        {

            FormControl.enabled(false);

        }

        

    }

}
------------------------------------------------------------------

/// <summary>

/// This class is an extension of SalesTable

/// </summary>

[ExtensionOf(tableStr(SalesTable))]

final class PNG_SalesTable_Extension

{

    /// <summary>

    /// This method is used to update workflow status 

    /// </summary>

    /// <param name = "_salesTableRecId">RecId</param>

    /// <param name = "_status">PNG_VersioningDocumentState</param>

    public static void updateWorkflowStatus(RecId _salesTableRecId, PNG_VersioningDocumentState _status)

    {

        SalesTable salesTable;


        ttsbegin;

        update_recordset salesTable

            setting PNGDocumentState = _status

                where salesTable.RecId   == _salesTableRecId;

        ttscommit;


    }


    /// <summary>

    /// This method is used to total gross amount cache data

    /// </summary>

    /// <param name = "_salesTable">SalesTable</param>

    /// <returns>PNG_TotalGrossAmount</returns>

    [SysClientCacheDataMethodAttribute(true)]

    public static display PNG_TotalGrossAmount totalGrossAmountCaCheData(SalesTable _salesTable)

    {

        SalesLine               salesLine;

        PNG_TotalGrossAmount    amountCur = 0;


        while select salesLine

                index hint SalesLineIdx

                where salesLine.SalesId == _salesTable.salesid

        {

            amountCur += (salesLine.SalesQty * salesLine.SalesPrice);

        }


        return amountCur;

    }


    /// <summary>

    /// This method is used to total discount amount cache data

    /// </summary>

    /// <param name = "_salesTable">SalesTable</param>

    /// <returns>PNG_totalDiscountAmount</returns>

    [SysClientCacheDataMethodAttribute(true)]

    public static display PNG_totalDiscountAmount totalDiscountAmountCaCheData(SalesTable _salesTable)

    {

        salesTotals                 salesTotals;   

        PNG_totalDiscountAmount     totaldiscount =0;


        salesTable salesTable = SalesTable::find(_salesTable.SalesId);

        if (salesTable.recid)

        {

            salesTotals = SalesTotals::construct(salesTable, SalesUpdate::All);

            salesTotals.calc();

            totaldiscount = salesTotals.totalLineDisc();

        }


        return totaldiscount;

    }


    /// <summary>

    /// This method is used to calculate the average discount pct cache data

    /// </summary>

    /// <param name = "_salesTable">SalesTable</param>

    /// <returns>PNG_AverageDiscountPct</returns>

    [SysClientCacheDataMethodAttribute(true)]

    public static display PNG_AverageDiscountPct averageDiscountPctCaCheData(SalesTable _salesTable)

    {

        SalesLine               salesLine;

        PNG_AverageDiscountPct  amountCur = 0, amountCurGrossAmount = 0, amountCurDisAmount;

        int                     counter;


        while select salesLine

                index hint SalesLineIdx

                where salesLine.SalesId == _salesTable.salesid

        {

            amountCurGrossAmount += (salesLine.SalesQty * salesLine.SalesPrice);

            counter++;

        }


        salesTotals                 salesTotals;


        salesTable salesTable = SalesTable::find(_salesTable.SalesId);

        if (salesTable.recid)

        {

            salesTotals = SalesTotals::construct(salesTable, SalesUpdate::All);

            salesTotals.calc();

            amountCurDisAmount = salesTotals.totalLineDisc();


            if (counter>0 && amountCurGrossAmount!=0 && amountCurDisAmount!=0)

            {

                amountCur = (amountCurDisAmount/amountCurGrossAmount)*100;

            }

            else if (counter>0 && amountCurGrossAmount!=0)

            {

                amountCur = (amountCurDisAmount/amountCurGrossAmount)*100;

            }

        }


        return amountCur;

    }

}
--------------------------------------------------------------

/// <summary>

/// This method is used to when modify the item id 

/// </summary>

[ExtensionOf(formDataFieldStr(SalesTable, SalesLine, ItemId))]

final class PNG_SalesTable_SalesLineItemId_Extension

{

    /// <summary>

    /// This method is used to modify the data

    /// </summary>

    public void modified()

    {

        FormDataObject formDataObject = any2Object(this) as FormDataObject;

        FormDataSource formDataSource = formDataObject.datasource();

        SalesLine      salesLine;


        next modified();


        salesLine = formDataSource.cursor();


        InterCompanyEndpointActionPolicy    interCompanyEndpointActionPolicy    = SalesLine.salesTable().interCompanyEndpointActionPolicy();

        boolean                             isICPOLineInvoiceMatched            = salesLine.isInterCompanyOrderLineInvoiceMatched();



        if (!SalesTable::find(SalesLine.SalesId).InterCompanyOrder && salesLine.SalesId)

        {

            if (CustParameters::find().PNGDisableUnitPrice)

            {

                if (InventTable::find(SalesLine.ItemId).PNGEnableUnitPriceOverride)

                {

                    formDataSource.object(fieldNum(SalesLine, SalesPrice)).enabled(false);

                    formDataSource.object(fieldNum(SalesLine, LineAmount)).enabled(false);

                }

                else

                {

                    formDataSource.object(fieldNum(SalesLine, SalesPrice)).enabled(true);

                    formDataSource.object(fieldNum(SalesLine, LineAmount)).enabled(true);

                }

            }

            else if ((!CustParameters::find().PNGDisableUnitPrice) && (InventTable::find(SalesLine.ItemId).PNGEnableUnitPriceOverride))

            {

                formDataSource.object(fieldNum(SalesLine, SalesPrice)).enabled(false);

                formDataSource.object(fieldNum(SalesLine, LineAmount)).enabled(false);

            }

            else

            {

                formDataSource.object(fieldNum(SalesLine, SalesPrice)).enabled(true);

                formDataSource.object(fieldNum(SalesLine, LineAmount)).enabled(true);

            }

        }  

        else if ((SalesTable::find(SalesLine.SalesId).InterCompanyOrder)  && SalesLine.SalesId)

        {

            formDataSource.object(fieldNum(SalesLine, SalesPrice)).enabled(interCompanyEndpointActionPolicy.EditPrice    && !isICPOLineInvoiceMatched);

            formDataSource.object(fieldNum(SalesLine, LineAmount)).enabled(interCompanyEndpointActionPolicy.EditPrice    && !isICPOLineInvoiceMatched);

        }

    }

}
------------------------------------------------

/// <summary>

/// This class is an extension of sales table list page

/// </summary>

[ExtensionOf(classStr(SalesTableListPageInteraction))]

internal final class PNG_SalesTableListPageInteraction_C_Extension

{

    /// <summary>

    /// List page interaction initialized.

    /// </summary>

    public void initialized()

    {

        next initialized();


        this.getEnableDisable();

    }


    /// <summary>

    /// This method is used to selection of changes

    /// </summary>

    public void selectionChanged()

    {

        next selectionChanged();


        this.getEnableDisable();

    }


    /// <summary>

    /// This method is used to set button enable and disable

    /// </summary>

    protected void setButtonSell()

    {

        SalesTable salestable = this.currentSalesTable();


        next setButtonSell();


        if(!salestable.InterCompanyOrder && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            boolean enableConfirm = salestable.PNGDocumentState == PNG_VersioningDocumentState::Approved && canConfirmationBeUpdated;


            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdateConfirmation), enableConfirm);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonProformaConfirmation), enableConfirm);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdateConfirm), enableConfirm);

        }

       

    }


    /// <summary>

    /// This method is used to set button enable and disable

    /// </summary>

    protected void setButtonPickAndPack()

    {

        next setButtonPickAndPack();


        SalesTable salestable = this.currentSalesTable();

        if(!salestable.InterCompanyOrder && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            boolean enablePickinglist = salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed && canPickingListBeUpdated;

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdatePickingList), enablePickinglist);

            

            boolean enablePickinglistReg = salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed && canPickingListBeRegistrated;

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdatePickingListRegistrate), enablePickinglistReg);

            

            boolean enablePackingSlip = salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed && canPackingSlipBeUpdated;


            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdatePackingSlip), enablePackingSlip);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonProformaPackingSlip), enablePackingSlip);


        }

    }


    /// <summary>

    /// This method is used to set button enable and disable

    /// </summary>

    protected void setButtonInvoice()

    {

        next setButtonInvoice();


        SalesTable salestable = this.currentSalesTable();

        if(!salestable.InterCompanyOrder && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            boolean enableInvoice = salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed && canInvoiceBeUpdated;


            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdateInvoice), enableInvoice);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonProformaInvoice), enableInvoice);

        }

    }


    /// <summary>

    /// This method is used to set button enable and disable

    /// </summary>

    public void getEnableDisable()

    {

        SalesTable salestable = this.currentSalesTable();


        if(!salestable.InterCompanyOrder && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            boolean enableConfirm = salestable.PNGDocumentState == PNG_VersioningDocumentState::Approved && canConfirmationBeUpdated;


            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdateConfirmation), enableConfirm);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonProformaConfirmation), enableConfirm);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdateConfirm), enableConfirm);


            

            boolean enablePickinglist = salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed && canPickingListBeUpdated;

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdatePickingList), enablePickinglist);

            

            boolean enablePickinglistReg = salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed && canPickingListBeRegistrated;

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdatePickingListRegistrate), enablePickinglistReg);

            

            boolean enablePackingSlip = salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed && canPackingSlipBeUpdated;


            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdatePackingSlip), enablePackingSlip);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonProformaPackingSlip), enablePackingSlip);


            

            boolean enableInvoice = salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed && canInvoiceBeUpdated;

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonUpdateInvoice), enableInvoice);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonProformaInvoice), enableInvoice);


            boolean buttonRequestChange = (salestable.PNGDocumentState == PNG_VersioningDocumentState::Approved ||

                                           salestable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed);

            this.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, buttonRequestChange), buttonRequestChange);

        }

    }

}
--------------------------------------------------------

/// <summary>

/// Extension for <c>SalesTableType</c>

/// </summary>

[ExtensionOf(classStr(SalesTableType))]

public final class PNG_SalesTableType_C_Extension

{

    /// <summary>

    /// This method is an extension of mayConfirmationBeUpdated

    /// </summary>

    /// <returns>boolean</returns>

    boolean mayConfirmationBeUpdated()

    {

        boolean ret = next mayConfirmationBeUpdated();


        if (!salesTable.InterCompanyOrder && ret && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            ret = (salesTable.PNGDocumentState == PNG_VersioningDocumentState::Approved)? true : false;

        }


        return ret;

    }


    /// <summary>

    /// This method is an extension of mayPickingListBeUpdated

    /// </summary>

    /// <returns>boolean</returns>

    boolean mayPickingListBeUpdated()

    {

        boolean ret = next mayPickingListBeUpdated();


        if (!salesTable.InterCompanyOrder && ret && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            ret = (salesTable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed) ? true : false;

        }


        return ret;

    }


    /// <summary>

    /// This method is an extension of mayPickingListBeRegistered

    /// </summary>

    /// <returns>boolean</returns>

    boolean  mayPickingListBeRegistered()

    {

        boolean ret = next mayPickingListBeRegistered();


        if (!salesTable.InterCompanyOrder && ret && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            ret = (salesTable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed) ? true : false;

        }


        return ret;

    }


    /// <summary>

    /// This method is an extension of mayPackingSlipBeUpdated

    /// </summary>

    /// <returns>boolean</returns>

    boolean mayPackingSlipBeUpdated()

    {

        boolean ret = next mayPackingSlipBeUpdated();


        if (!salesTable.InterCompanyOrder && ret && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            ret = (salesTable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed) ? true : false;

        }


        return ret;

    }


    /// <summary>

    /// This method is an extension of mayInvoiceBeUpdated

    /// </summary>

    /// <returns>boolean</returns>

    boolean mayInvoiceBeUpdated()

    {

        boolean ret = next mayInvoiceBeUpdated();


        if (!salesTable.InterCompanyOrder && ret && salesTable::averageDiscountPctCaCheData(salesTable))

        {

            ret = (salesTable.PNGDocumentState == PNG_VersioningDocumentState::Confirmed) ? true : false;

        }


        return ret;

    }

}
------------------------------------------------------

/// <summary>

/// The PNG_SalesTableWorkflowApprovalEventHandler workflow outcome event handler.

/// </summary>

public final class PNG_SalesTableWorkflowApprovalEventHandler implements

WorkflowElemChangeRequestedEventHandler,

WorkflowElementCompletedEventHandler,

WorkflowElementReturnedEventHandler

{

    /// <summary>

    /// This method is used to approve the workflow

    /// </summary>

    /// <param name = "_workflowElementEventArgs">WorkflowElementEventArgs</param>

    public void completed(WorkflowElementEventArgs _workflowElementEventArgs)

{

        RecId salesTableRecId = _workflowElementEventArgs.parmWorkflowContext().parmRecId();


        SalesTable::updateWorkflowStatus(salesTableRecId, PNG_VersioningDocumentState::Approved);

}


    /// <summary>

    /// This method is called on change request

    /// </summary>

    /// <param name = "_workflowElementEventArgs">WorkflowElementEventArgs</param>

    public void changeRequested(WorkflowElementEventArgs _workflowElementEventArgs)

{

        RecId salesTableRecId = _workflowElementEventArgs.parmWorkflowContext().parmRecId();


        SalesTable::updateWorkflowStatus(salesTableRecId, PNG_VersioningDocumentState::ChangeRequest);

}


    /// <summary>

    /// This method is used to call when return the workflow

    /// </summary>

    /// <param name = "_workflowElementEventArgs">WorkflowElementEventArgs</param>

    public void returned(WorkflowElementEventArgs _workflowElementEventArgs)

{

        RecId salesTableRecId = _workflowElementEventArgs.parmWorkflowContext().parmRecId();


        SalesTable::updateWorkflowStatus(salesTableRecId, PNG_VersioningDocumentState::Rejected);

}

}
---------------------------------------------------------------

/// <summary>

/// The PNG_SalesTableWorkflowApprovalResubmitActionMgr menu item action event handler.

/// </summary>

public class PNG_SalesTableWorkflowApprovalResubmitActionMgr 

{

    /// <summary>

    /// This method is main method of the class

    /// </summary>

    /// <param name = "_args">Args</param>

    public static void main(Args _args)

    {

        SalesTable              salesTable;


        salesTable = _args.record();

        if (salesTable::averageDiscountPctCaCheData(salesTable) && salesTable.RecId)

        {

            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();


                    PNG_SalesTableWorkflowTypeSubmitManager SubmitManager=new PNG_SalesTableWorkflowTypeSubmitManager();

                    

                    if (SubmitManager.validateLedgerDimension(salesTable))

                    {

                        if (dialog.parmIsClosedOK())

                        {

                            workItem = _args.caller().getActiveWorkflowWorkItem();

                            WorkflowWorkItemActionManager::dispatchWorkItemAction(workItem, dialog.parmWorkflowComment(), dialog.parmTargetUser(), WorkflowWorkItemActionType::Resubmit, _args.menuItemName());


                            ttsbegin;

                            salesTable.selectForUpdate(true);

                            salesTable.PNGDocumentState = PNG_VersioningDocumentState::InReview;

                            salesTable.update();

                            ttscommit;

                        }

                    }

                }

                catch(exception::Error)

                {

                    error("Error on workflow activation.");

                }

            }


            // make sure changes in status are reflected on the caller

            FormDataSource callerDS = _args.record().dataSource();

            callerDS.reread();

            callerDS.refresh();

            _args.caller().updateWorkflowControls();

        }

        else 

        {

            throw warning('Average discount percent does not exists.');

        }

    }

}
--------------------------------------------------------------------

/// <summary>

/// The PNG_SalesTableWorkflowTypeDocument workflow document class.

/// </summary>

class PNG_SalesTableWorkflowTypeDocument extends WorkflowDocument

{

    /// <summary>

/// Returns query name for the workflow document.

/// </summary>

/// <returns>

/// Name of the query <c>PNG_SalesTableQuery</c>.

/// </returns>

public queryName getQueryName()

{

return querystr(PNG_SalesTableQuery);

}


    /// <summary>

    /// This method is called in workflow configuration for total Gross amount

    /// </summary>

    /// <param name = "_companyId">CompanyId</param>

    /// <param name = "_tableId">TableId</param>

    /// <param name = "_recId">RecId</param>

    /// <returns>PNG_TotalGrossAmount</returns>

    public PNG_TotalGrossAmount parmtotalGrossAmount(CompanyId _companyId, TableId _tableId, RecId _recId)

    {

        SalesTable salesTable;


        select firstonly salesTable

            where salesTable.recid == _recId;


        return SalesTable::totalGrossAmountCaCheData(salesTable);

    }


    /// <summary>

    /// This method is called in workflow configuration for total discount amount

    /// </summary>

    /// <param name = "_companyId">CompanyId</param>

    /// <param name = "_tableId">TableId</param>

    /// <param name = "_recId">RecId</param>

    /// <returns>PNG_TotalDiscountAmount</returns>

    public PNG_TotalDiscountAmount parmtotalDiscountAmount(CompanyId _companyId, TableId _tableId, RecId _recId)

    {

        SalesTable salesTable;


        select firstonly salesTable 

            where salesTable.recid == _recId;


        return SalesTable::totalDiscountAmountCaCheData(salesTable);

    }


    /// <summary>

    /// This method is called in workflow configuration for Average discount percentage

    /// </summary>

    /// <param name = "_companyId">CompanyId</param>

    /// <param name = "_tableId">TableId</param>

    /// <param name = "_recId">RecId</param>

    /// <returns>PNG_AverageDiscountPct</returns>

    public PNG_AverageDiscountPct parmAverageDiscountPct(CompanyId _companyId, TableId _tableId, RecId _recId)

    {

        SalesTable SalesTable;


        select firstonly salesTable 

            where SalesTable.recid == _recId;


        return SalesTable::averageDiscountPctCaCheData(salesTable);

    }

}
------------------------------------------------------

/// <summary>

/// The PNG_SalesTableWorkflowTypeEventHandler workflow event handler.

/// </summary>

public class  PNG_SalesTableWorkflowTypeEventHandler implements WorkflowCanceledEventHandler,  

WorkflowCompletedEventHandler,

WorkflowStartedEventHandler

{

    /// <summary>

    /// This method is used when workflow inital start process

    /// </summary>

    /// <param name = "_workflowEventArgs">WorkflowEventArgs</param>

    public void started(WorkflowEventArgs _workflowEventArgs)

{

        RecId salesTableRecId = _workflowEventArgs.parmWorkflowContext().parmRecId();


        SalesTable::updateWorkflowStatus(salesTableRecId, PNG_VersioningDocumentState::InReview);

}


    /// <summary>

    /// This method is need to call when it's canceled 

    /// </summary>

    /// <param name = "_workflowEventArgs">WorkflowEventArgs</param>

    public void canceled(WorkflowEventArgs _workflowEventArgs)

{

        RecId salesTableRecId = _workflowEventArgs.parmWorkflowContext().parmRecId();


        SalesTable::updateWorkflowStatus(salesTableRecId, PNG_VersioningDocumentState::Draft);

}


    /// <summary>

    /// This method is called with approved the workflow 

    /// </summary>

    /// <param name = "_workflowEventArgs">WorkflowEventArgs</param>

    public void completed(WorkflowEventArgs _workflowEventArgs)

{

        RecId salesTableRecId = _workflowEventArgs.parmWorkflowContext().parmRecId();


        SalesTable::updateWorkflowStatus(salesTableRecId, PNG_VersioningDocumentState::Approved);

}

}
--------------------------------------------------------

/// <summary>

/// The PNG_SalesTableWorkflowTypeSubmitManager menu item action event handler.

/// </summary>

public class PNG_SalesTableWorkflowTypeSubmitManager 

{

    /// <summary>

    /// This method by the system when the class is run directly from a menu item and it takes a parameter of type args.

    /// </summary>

    /// <param name = "args">Args</param>

    public static void main(Args args)

    {

        SalesTable              salesTable;

        WorkflowComment         note = "";

        WorkflowSubmitDialog    workflowSubmitDialog;

        WorkflowCorrelationId   workflowCorrelationId;

        PNG_SalesTableWorkflowTypeSubmitManager SubmitManager=new PNG_SalesTableWorkflowTypeSubmitManager();


        salesTable = args.record();

        if (salesTable::averageDiscountPctCaCheData(salesTable)&& salesTable.RecId)

        {


            WorkflowTypeName        workflowTypeName = workFlowTypeStr('PNG_SalesTableWorkflowType');

            workflowversionTable    versionTable     = args.caller().getActiveWorkflowConfiguration();

            if (!versionTable)

            {

                versionTable = SubmitManager.findWorkFlowVersionTable();

            }


            workflowSubmitDialog =    WorkflowSubmitDialog::construct(versionTable);

            workflowSubmitDialog.run();


            if (workflowSubmitDialog.parmIsClosedOK())

            {

                

                note = workflowSubmitDialog.parmWorkflowComment();


                if (SubmitManager.validateLedgerDimension(salesTable))

                {

                    try

                    {

                        ttsbegin;

                        workflowCorrelationId = Workflow::activateFromWorkflowType(workflowTypeName, salesTable.RecId, note, NoYes::No);

                        salesTable.selectForUpdate(true);

                        salesTable.PNGDocumentState = PNG_VersioningDocumentState::InReview;

                        salesTable.update();

                        ttscommit;

                    }

                    catch (Exception::Error)

                    {

                        error("Error on workflow activation.");

                    }

                }

            }

            args.caller().updateWorkFlowControls();

        }

        else 

        {

            throw warning('Average discount percent does not exists.');

        }

    }


    /// <summary>

    /// This method is used to validate the ledger dimension

    /// </summary>

    /// <param name = "_salesTable">SalesTable</param>

    /// <returns>boolean</returns>

    public boolean validateLedgerDimension(SalesTable _salesTable)

    {

        SalesLine   salesLinelocal;

        boolean     ret;

        LedgerDimensionAccount ledgerDimension, headerledgerDimension ;

        PNG_CheckFullyDistributedAndQualified   accountingDisqualified=new  PNG_CheckFullyDistributedAndQualified();


        headerledgerDimension  = LedgerDimensionFacade::serviceCreateLedgerDimension(CustLedgerAccounts::summaryLedgerDimension(_salesTable.InvoiceAccount, _salesTable.PostingProfile),_salesTable.DefaultDimension);

        ret = accountingDisqualified.validateLedgerDimensionLE(CompanyInfo::findDataArea(curExt()).RecId ,headerledgerDimension, _salesTable.createDate());


        if (ret == false)

        {

            throw Exception::Error;

        }


        while select salesLinelocal

            where salesLinelocal.SalesId == _salesTable.SalesId

        {

            if (!MainAccount::find(salesLinelocal.ledgerDimensionSales()).RecId)

            {

                DimensionDefault  dimensionDefault = LedgerDimensionDefaultFacade::serviceMergeDefaultDimensions(salesLinelocal.ledgerDimensionSales(), salesLinelocal.DefaultDimension);

                ledgerDimension  = LedgerDimensionFacade::serviceCreateLedgerDimension(salesLinelocal.ledgerDimensionSales(), dimensionDefault);

            }

            else

            {        

                ledgerDimension  = LedgerDimensionFacade::serviceCreateLedgerDimension(salesLinelocal.ledgerDimensionSales(), salesLinelocal.DefaultDimension);

            }


            ret = accountingDisqualified.validateLedgerDimensionLE(CompanyInfo::findDataArea(curExt()).RecId ,ledgerDimension, _salesTable.createDate());


            if (ret == false)

            {

                throw Exception::Error;

            }

    

        }

        return true;

    }


    /// <summary

    /// find the WorkflowVersionTable

    /// </summary>

    /// <returns>WorkflowVersionTable</returns>

    public WorkflowVersionTable findWorkFlowVersionTable()

    {

        WorkflowVersionTable workflowVersionTblBfr;

        WorkflowTable        workflowTblBfr;


        select  firstonly * from workflowVersionTblBfr

            join workflowTblBfr

            where workflowVersionTblBfr.WorkflowTable  == workflowTblBfr.RecId

            && workflowVersionTblBfr.Enabled           == NoYes::Yes

            && workflowTblBfr.TemplateName             == 'PNG_SalesTableWorkflowType' 

            && workflowTblBfr.DATAAREA == curExt();

        return workflowVersionTblBfr;

    }

}

No comments:

Post a Comment

validate offsetLedgerDimension in d365 FO

 /// <summary> /// This class is used to validate offsetLedgerDimension /// </summary> class PNG_InventMovValidateOffsetLedgerDi...