Friday 17 September 2021

Batch class with lookup on dialog using Sys Operation Framework in D365 FSCM

We need to create 4 classes 

  • Controller class - This class works as the entry point for the process.
  • Service class - This class does the actual job.
  • Contract class - Handles the data values.
  • UI Builder class (optional) - This class is used to do modifications on the dialog (Like - 01) To provide lookup on the field, 02) To make any field mandatory or disabled).

  • Controller class

 /// <summary>
/// Controller class to generate the ER business document for customer invoices.
/// </summary>
class SalesContractCustCommunicationController extends SysOperationServiceController
{
    /// <summary>
    /// New method for GenerateSalesOrderController class.
    /// </summary>
    protected void new()
    {
        super();
        this.parmClassName(classStr(SalesContractCustCommunicationService));
        this.parmMethodName(methodStr(SalesContractCustCommunicationService, processOperation));
     
        this.parmDialogCaption("Your dialog caption");
    }
    /// <summary>
    /// Caption for batch dialogue.
    /// </summary>
    /// <returns>
    /// caption
    /// </returns>
    public ClassDescription caption()
    {
        return "Your class description";
    }
    /// <summary>
    /// Main method for controller class.
    /// </summary>
    /// <param name = "args">
    /// Args
    /// </param>
    public static void main(Args args)
    {
        SalesContractCustCommunicationController controller = new SalesContractCustCommunicationController();
     
        controller.startOperation();
    }



  • Service class

 /// <summary>

/// Service class to generate the ER business document for customer invoices.

/// </summary>


class SalesContractCustCommunicationService extends SysOperationServiceBase

{

    /// <summary>

    /// Process the actual operation for the class.

    /// </summary>

    /// <param name = "_datacontract">

    /// SalesContractCustCommunicationDataContract object

    /// </param>

    public Void processOperation(SalesContractCustCommunicationDataContract _datacontract)

    {

        #OCCRetryCount

        try

        {

            CustInvoiceJour custInvoiceJour;

            Args args = new Args();


//Note here SalesSubContractID is a custom field.

            select custInvoiceJour

                where custInvoiceJour.SalesSubContractId == _datacontract.parmSalesSubContractId();


            

            if (custInvoiceJour.RecId)

            {

                args.parmEnumType(enumnum(PrintCopyOriginal));

                args.parmEnum(1);

                args.record(custInvoiceJour);


                new MenuFunction(menuitemOutputStr(SalesInvoiceOriginal), MenuItemType::Output).run(args);

            }

        }

       

        catch (Exception::Deadlock)

        {

            // retry on deadlock

            retry;

        }

        catch (Exception::UpdateConflict)

        {

            // try to resolve update conflict

            if (appl.ttsLevel() == 0)

            {

                if (xSession::currentRetryCount() >= #RetryNum)

                {

                    throw Exception::UpdateConflictNotRecovered;

                }

                else

                {

                    retry;

                }

            }

            else

            {

                throw Exception::UpdateConflict;

            }

        }

        catch(Exception::DuplicateKeyException)

        {

            // retry in case of an duplicate key conflict

            if (appl.ttsLevel() == 0)

            {

                if (xSession::currentRetryCount() >= #RetryNum)

                {

                    throw Exception::DuplicateKeyExceptionNotRecovered;

                }

                else

                {

                    retry;

                }

            }

            else

            {

                throw Exception::DuplicateKeyException;

            }

        }

    }





  • Data Contract class

 /// <summary>

/// Contract class to generate the ER business document for customer invoices.

/// </summary>

[DataContractAttribute,

SysOperationContractProcessingAttribute(classStr(SalesContractCustCommunicationUIBuilder))]

class SalesContractCustCommunicationDataContract

{

  // Note, here SalesSubContractId is a custom field

    SalesSubContractId  salesSubContractId;

    

    /// <summary>

    /// sub framwork parameter for Release batch job.

    /// </summary>

    /// <param name = "_salesSubContractId">

    /// Sales sub contract Id

    /// </param>

    /// <returns>

    /// Sales sub contract Id value

    /// </returns>

    [DataMemberAttribute,

    SysOperationLabelAttribute("Your Label Attribute Value"),

    SysOperationHelpTextAttribute("Your Help Text Attribute Value"),

    SysOperationDisplayOrderAttribute('1')]

    public SalesSubContractId parmSalesSubContractId(SalesSubContractId _salesSubContractId = salesSubContractId)

    {

        salesSubContractId = _salesSubContractId;

        return salesSubContractId;

    }


}



  • UI Builder class

 /// <summary>

/// UI Builder class to generate the ER business document for customer invoices.

/// </summary>


class SalesContractCustCommunicationUIBuilder extends SysOperationAutomaticUIBuilder

{

    /// <summary>

    ///    Implements a custom lookup for dimension attribute.

    /// </summary>

    /// <param name="_control">

    ///    The <c>FormStringControl</c> for which the lookup fields must be associated.

    /// </param>

    /// <remarks>

    ///    It uses the <c>SalesContractSubFCTable</c> table for lookup.

    /// </remarks>

    public void lookupSubContractId(FormStringControl _control)

    {

        Query                   query = new Query();

        QueryBuildDataSource    qbds;

        SysTableLookup          sysTableLookup;


        if (_control != null)

        {

            // NOTE: here "SalesContractSubFCTable" is a custom table

            sysTableLookup = SysTableLookup::newParameters(tablenum(SalesContractSubFCTable), _control);

            qbds = query.addDataSource(tableNum(SalesContractSubFCTable));

            SysTableLookup.addLookupfield(fieldNum(SalesContractSubFCTable, SalesSubContractId), true);

            SysTableLookup.addLookupfield(fieldNum(SalesContractSubFCTable, SalesContractId), false);

            sysTableLookup.parmQuery(query);

            sysTableLookup.performFormLookup();

        }

    }


    /// <summary>

    /// Post build method for UI Builder class

    /// </summary>

    public void postBuild()

    {

        super();


        // get datacontract

        SalesContractCustCommunicationDataContract salesContractCustCommunicationDataContract = this.dataContractObject();


        // get dialog fields

        DialogField dialogField = this.bindInfo().getDialogField(salesContractCustCommunicationDataContract, methodstr(SalesContractCustCommunicationDataContract, parmSalesSubContractId));


        dialogField.fieldControl().mandatory(true);


        // register override methods

        dialogField.registerOverrideMethod(

            methodStr(FormStringControl, lookup),

            methodStr(SalesContractCustCommunicationUIBuilder, lookupSubContractId),

            this);


    }


}


  • Now create a menu item of type Action and provide the controller class object in it.

=================================================================



No comments:

Post a Comment

Insert/Update or remove the default dimension value in D365 FSCM via x++

Use below method to insert/update the dimension values, just pass the parameter values to the method and it will return the updated value: p...