Showing posts with label CoC. Show all posts
Showing posts with label CoC. Show all posts

Monday, April 26, 2021

UserConnection in D365fo

Its used when we need to commit our transaction wehen standared code doesn't Commit.
example :SalesQuotationEditLinesForm_Sales_Send > checkSales() , COC and try to write 
custom insert or update operation here while validation is failed our transactions doesn't commit

static void KlForRecordInserted(Args _args)
{
    UserConnection userConnection;
    CustTable custTable;
    ;
   
    ttsbegin;
   
    userConnection = new userConnection();
   
    custTable.clear();
    custTable.initValue();
    custTable.AccountNum = "000020";
    custTable.Name = "My Test Customer";
    custTable.setConnection(userConnection); // set userconnection
    custTable.insert();
   
    throw error("An error that causes a rollback");
    ttscommit;
}

Monday, April 12, 2021

Register override lookup in D365fo from form datasource

/// <summary>
/// Extension of the form 'SalesTable' data source 'SalesLine'.
/// </summary>
[ExtensionOf(formDataSourceStr(SalesTable, SalesLine))]
final class Sales_SalesTableForm_SalesLineDS_Extension
{
    /// <summary>
    /// COC construct to handle standard datasource init method
    /// </summary>
    /// <remarks>
    /// Method overriden to add custom logic
    /// </remarks>
    void init()
    {
        next init();

        this.m_Init();
    }

    /// <summary>
    /// COC Implementation for additional logic on init method
    /// </summary>
    void m_Init()
    {
        this.sm_ReasonCodeLookupRegisterOverride();
    }

    /// <summary>
    /// SM reason code lookup override method
    /// </summary>
    public void m_ReasonCodeLookupRegisterOverride()
    {
        FormDataSource salesLineDataSource = element.dataSource(formDataSourceStr(SalesTable, SalesLine)) as FormDataSource;
        SM_Sales_SalesTableFormRegisterMethods formRegisterMethods = new SM_Sales_SalesTableFormRegisterMethods();

        salesLineDataSource.object(fieldNum(SalesLine, SM_ReasonCode)).registerOverrideMethod(methodStr(FormDataObject, lookup),
                                methodStr(M_Sales_SalesTableFormRegisterMethods, lookupReasoncode ),
                                formRegisterMethods);
              
    }

}

/// <summary>
/// Form 'SalesTable', data source 'SalesLine' register override method implementation
/// </summary>
class Sales_SalesTableFormRegisterMethods
{
    /// <summary>
    /// Overrides <c>SM_Reasoncode</c> field lookup
    /// </summary>
    /// <param name = "_formStringControl">The control that is bound to the <c>SM_Reasoncode</c> field.</param>
    public void lookupReasoncode(FormStringControl _formStringControl)
    {
        FormRun formRun = _formStringControl.formRun();

        SalesTable salesTableLoc = formRun.dataSource(formDataSourceStr(SalesTable, SalesTable)).cursor() as SalesTable;

        SalesLine::m_lookupReasoncode(_formStringControl, salesTableLoc.DlvReason);
    }

}

/// <summary>
    /// Overrides <c>SM_Reasoncode</c> field lookup
    /// </summary>
    /// <param name = "_formStringControl">The control that is bound to the <c>SM_Reasoncode</c> field.</param>
    public static void lookupReasoncode(FormStringControl _formStringControl, DlvReasonId _dlvReason)
    {
        Query query = new Query();

        QueryBuildDataSource queryBuildDataSource = query.addDataSource(tableNum(ReasonTable));
        queryBuildDataSource.addSelectionField(fieldnum(ReasonTable, Reason));

        if (SM_CustParameters::find().ActivateReasonCode)
        {
            container conReasoncode;
            ReasonTable reasonTable;
            SM_DeliveryReasonReasonCodeCombination deliveryReasonReasonCodeCombination;

            while select ReasonCode from deliveryReasonReasonCodeCombination
                exists join reasonTable
                where reasonTable.Reason == deliveryReasonReasonCodeCombination.ReasonCode
                && deliveryReasonReasonCodeCombination.DlvReasonId == _dlvReason
                && reasonTable.SM_ActivateReasonCode == NoYes::Yes
            {
                conReasoncode += deliveryReasonReasonCodeCombination.ReasonCode;
            }

            str reasoncodes = conReasoncode != conNull() ? con2Str(conReasoncode) : SysQuery::valueEmptyString();

            queryBuildDataSource.addRange(fieldnum(ReasonTable, Reason)).value(reasoncodes);
        }
       
        SysTableLookup lookup = SysTableLookup::newParameters(tablenum(ReasonTable), _formStringControl);

        lookup.addLookupfield(fieldnum(ReasonTable, Reason));
        lookup.addLookupfield(fieldnum(ReasonTable, Description));

        lookup.parmQuery(query);
        lookup.performFormLookup();
    }

Sunday, April 11, 2021

Access public variables in extension class using chain of command

When you wrap a method, you can also access public and protected methods
and variables of the base class.
CustInvoiceJour is a base class variable hence you will be able to access it. Eg.

[ExtensionOf(classStr(SalesConfirmJournalCreate))]
Final class SalesConfirmJournalCreate_Extension
{
protected void createJournalHeader()
{
next createJournalHeader();
//It's as simple as this:
custConfirmJour.SalesBalance = 0;
}
if gets an error, It's an old bug with variable names. Declare new one and use it:
protected void createJournalHeader()
{
next createJournalHeader();
CustConfirmJour custConfirmJourLocal =
custConfirmJour;
custConfirmJourLocal.MyField = 'blah-blah';
}
}

Add new fields in sysoperation dialog and get the values in controller class in AX

UIBuilder class

[ExtensionOf(classstr(ExchangeRateImportUIBuilder))]
final class PDPExchangeRateImportUIBuilder_Extension
{
    public FormBuildIntControl      intCtrl;
    public FormBuildCheckBoxControl booleanCtrl;

    public void build()
    {
        next build();

        DialogField                 dialogField;
        DialogField                 dialogFieldNoYesId;
        ExchangeRateImportRequest   dataContract1;
        FormBuildCheckBoxControl    exchangeRateFromPreviousDayControl;

        dataContract1    = this.dataContractObject();

       //  creating this field if standared code skips it to avoid type cast error in contoller at runtime
        if(exchangeRateFromPreviousDayControl == null)
        {
            dialogField = dialog.addField(extendedtypestr(ExchangeRateFromPreviousDay));
            exchangeRateFromPreviousDayControl = dialogField.control();
            exchangeRateFromPreviousDayControl.value(dataContract1.parmExchangeRateFromPreviousDay());
            exchangeRateFromPreviousDayControl.allowEdit(false);
            exchangeRateFromPreviousDayControl.visible(false);
        }

        dialogField     = dialog.addField(extendedtypestr(NumberOf),"integer","integer");
        intCtrl         = dialogField.control();
        intCtrl.value(dataContract1.parmInteg());

        dialogField     = dialog.addField(extendedtypestr(NoYesId),"boolean","boolean");
        booleanCtrl     = dialogField.control();
        booleanCtrl.value(dataContract1.parmNoYesId());
    }

}

Contract class

[ExtensionOf(ClassStr(ExchangeRateImportRequest))]
[DataContractAttribute]
final class PDPExchangeRateImportRequest_Extension
{
    public int     integ;
    public NoYesId noYesValue;

    /// <summary>
    /// data memeber attribute of Integ field
    /// </summary>
    /// <param name = "_integ">integ</param>
    /// <returns>int</returns>
    [DataMemberAttribute]
    public int parmInteg(int _integ = 0)
    {
        if (!_integ)
        {
            integ = _integ;
        }

        return integ;
    }

    /// <summary>
    /// NoyesId field
    /// </summary>
    /// <param name = "_noYesValue">NoYesValue</param>
    /// <returns>boolean</returns>
    [DataMemberAttribute]
    public NoYesId parmNoYesId(NoYesId _noYesValue = NoYes::No)
    {
        if (!_noYesValue)
        {
            noYesValue = _noYesValue;
        }

        return _noYesValue;
    }

}

Controller class

[ExtensionOf(ClassStr(ExchangeRateImportController))]
final class PDPExchangeRateImportController_Extension
{
    public const str numberof = 'Fld11_1';
    public const str noYesValue = 'Fld12_1';


    public void getFromDialog()
    {
        next getFromDialog();

        FormRun                             theDialogForm;
        ExchangeRateImportRequest           exchangeRateImportRequest;
        ExchangeRateProviderFactory         factory;

        FormIntControl intCtrl;
        FormCheckBoxControl booleanCtrl;
        FormCheckBoxControl exchangeRateFromPreviousDayControl;
       
        exchangeRateImportRequest = this.getDataContractObject(classStr(ExchangeRateImportRequest));
        theDialogForm = this.dialog().formRun();

        intCtrl = theDialogForm.control(theDialogForm.controlId(numberof));

        booleanCtrl = theDialogForm.control(theDialogForm.controlId(noYesValue));

        exchangeRateImportRequest.parmInteg(intCtrl.value());

        exchangeRateImportRequest.parmExchangeRateTypeRecId(booleanCtrl.value());

        Info(strFmt("%1--%2",intCtrl.value(), booleanCtrl.value()));

    }

}

Table browser URL in D365FO

Critical Thinking icon icon by Icons8