Wednesday, June 9, 2021

How to add reference fields in forms that don't have a data source

 

Create a temp table with reference fields you wanted 


Add the Temp table as a data source in the required from without any join source


To initialize values when opening form

    [FormDataSourceEventHandler(formDataSourceStr(PdsResetVendorBatchDetails, PdsVendBatchInfo), FormDataSourceEventType::Initialized)]
    public static void PdsVendBatchInfo_OnInitialized(FormDataSource sender, FormDataSourceEventArgs e)
    {
            FormRun formRun = sender.formRun() as FormRun;

            switch (formRun.args().dataset())
            {
                case tableNum(InventBatch) :

                    InventBatch  inventBatch = formRun.args().record() as InventBatch;

                    PdsVendBatchInfoTMP PdsVendBatchInfo1 = sender.cursor();


                    FormReferenceControl Manufact = formRun.design().controlName(formControlStr(PdsResetVendorBatchDetails, PdsVendBatchInfo_Manufact)) as FormReferenceControl;
                    FormReferenceControl ManufactSite = formRun.design().controlName(formControlStr(PdsResetVendorBatchDetails, PdsVendBatchInfo_ManufactSite)) as FormReferenceControl;
                
                    PdsVendBatchInfo1.Manufact = inventBatch.Manufact;
                    PdsVendBatchInfo1.ManufactSite = inventBatch.ManufactSite;

                    PdsVendBatchInfo1.doInsert();
                
                    sender.setRecord(PdsVendBatchInfo1);

                    Manufact.value(inventBatch.Manufact);
                    ManufactSite.value(inventBatch.ManufactSite);
                    break;
            }
    }

 

Lookup

public static void dirPartyLocationLookup(FormReferenceGroupControl _ctrl, DirPartyRecId _party)
    {
        container               conLocationRoles;
        LogisticsLocationRole   logisticsLocationRole;
        QueryBuildDataSource    qbdsDirPartyLocation, qbdsDirPartyLocationRole;

        Query   query = new Query();
        SysReferenceTableLookup sysTableLookup = SysReferenceTableLookup::newParameters(tablenum(DirPartyLocation), _ctrl);

        while select RecId from LogisticsLocationRole
            where LogisticsLocationRole.IsManufactSite
        {
            conLocationRoles += LogisticsLocationRole.RecId;
        }

        sysTableLookup.addLookupfield(fieldNum(DirPartyLocation, Location));
        sysTableLookup.addLookupfield(fieldNum(DirPartyLocation, Party));
        
        qbdsDirPartyLocation = query.addDataSource(tablenum(DirPartyLocation));
        
        qbdsDirPartyLocationRole = qbdsDirPartyLocation.addDataSource(tablenum(DirPartyLocationRole));
        qbdsDirPartyLocationRole.joinMode(JoinMode::ExistsJoin);
        qbdsDirPartyLocationRole.relations(true);

        qbdsDirPartyLocationRole.addRange(fieldNum(DirPartyLocationRole, LocationRole)).value(con2Str(conLocationRoles));
       
        if(_party)
        {
            qbdsDirPartyLocation.addRange(fieldNum(DirPartyLocation, Party)).value(queryValue(_party));

            qbdsDirPartyLocation.addRange(fieldNum(DirPartyLocation, Location)).value(SysQuery::valueNot(0));
        }
        else
        {
            qbdsDirPartyLocation.addRange(fieldNum(DirPartyLocation, Party)).value(SysQuery::valueEmptyString());
        }

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

    public static void DirPartyIdLookup(FormControl _ctrl)
    {
        Query   query = new Query();

        SysReferenceTableLookup sysTableLookup = SysReferenceTableLookup::newParameters(tablenum(DirPartyTable), _ctrl);

        sysTableLookup.addLookupfield(fieldNum(DirPartyTable, PartyNumber));
        sysTableLookup.addLookupfield(fieldNum(DirPartyTable, Name));

        query.addDataSource(tablenum(DirPartyTable));
        
        sysTableLookup.parmQuery(query);
        sysTableLookup.performFormLookup();
    }

Tuesday, May 25, 2021

Set Financial Dimensions by X++ code in AX 2012/Setting one Dimension value in the combination

    /// <summary>
    /// replace specific financial dimension value in DefaultDimension based on the LedgerParameters setup
    /// </summary>
    /// <param name = "_defaultDimensionFrom">DefaultDimension recId the value should be taken from</param>
    /// <param name = "_defaultDimensionTo">DefaultDimension recId the value should be assigned to</param>
    /// <returns>returns new DefaultDimension recId if conditions are met</returns>
    public static DimensionDefault replaceDefaultDim(DimensionDefault _defaultDimensionFrom, DimensionDefault _defaultDimensionTo)
    {
        if(!_defaultDimensionFrom)
        {
            return _defaultDimensionTo;
        }

        LedgerParameters ledgerParameters = LedgerParameters::find();

        if (ledgerParameters.DepartmentSetFinancialDimension &&
            ledgerParameters.DepartmentDimensionAttribute)
        {
            DimensionAttribute                  dimAttr;
            DimensionAttributeValue             dimAttrValue;
            DimensionAttributeValueSetStorage   davss;

            davss = DimensionAttributeValueSetStorage::find(_defaultDimensionTo);

            dimAttr = DimensionAttribute::find(ledgerParameters.DepartmentDimensionAttribute);

            DimensionAttributeValueSetStorage dimStorage = DimensionAttributeValueSetStorage::find(_defaultDimensionFrom);
            DimensionValue dimValue = dimStorage.getDisplayValueByDimensionAttribute(dimAttr.RecId);

            dimAttrValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttr, dimValue);

            if(dimAttrValue && !davss.containsDimensionAttributeValue(dimAttrValue.RecId))
            {
                davss.addItem(dimAttrValue);

                return davss.save();
            }
        }

        return _defaultDimensionTo;
    }

Friday, April 30, 2021

Conversion from UTCDateTime to Date or Time in AX

Here is an example of correct conversion between UTCDateTime value and Date and Time value which is associated with user preferred time zone:
public static void testDateTimeConversion()
{
    utcDateTime dateTime;
    date dateInUserTimeZone;
    TimeOfDay timeInUserTimeZone;

    dateTime = DateTimeUtil::utcNow();

    dateInUserTimeZone = DateTimeUtil::date(DateTimeUtil::applyTimeZoneOffset(dateTime, DateTimeUtil::getUserPreferredTimeZone()));
    timeInUserTimeZone = DateTimeUtil::time(DateTimeUtil::applyTimeZoneOffset(dateTime, DateTimeUtil::getUserPreferredTimeZone()));

    dateTime = DateTimeUtil::newDateTime(dateInUserTimeZone, timeInUserTimeZone, DateTimeUtil::getUserPreferredTimeZone());
}

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;
}

Saturday, April 24, 2021

Query with join with multiple data sources in AX (Inner join, not exists join)

    public void initializeQueryDS()
    {
        query = new Query();
        QueryBuildDataSource qbds;
        QueryBuildDataSource qbdsSessionLine;

        switch(routing)
        {
            case Routing::Sales:
                qbds = query.addDataSource(tableNum(SalesLine));

                qbdsSessionLine = qbds.addDataSource(tableNum(WorkbenchSessionLine));
                qbdsSessionLine.joinMode(JoinMode::NoExistsJoin);
                qbdsSessionLine.relations(true);
                qbdsSessionLine.fetchMode(QueryFetchMode::One2One);

                TblNum = tableNum(SalesLine);
                break;
            case Routing::Return:
                qbds = query.addDataSource(tableNum(SalesLine));
                TblNum = tableNum(SalesLine);
                break;
        }
    }

    public void initializeQueryRange()
    {
        if(inventLocationId != strMin())
        {  
            QueryBuildDataSource qbdsSalesLine,qbdsInventDim;

            qbdsSalesLine = query.dataSourceTable(tableNum(SalesLine));
            qbdsInventDim = qbdsSalesLine.addDataSource(tableNum(InventDim));
            qbdsInventDim.joinMode(JoinMode::InnerJoin);
            qbdsInventDim.relations(true);
            qbdsInventDim.fetchMode(QueryFetchMode::One2One);
            qbdsInventDim.addRange(fieldNum(InventDim, InventLocationId)).value(inventLocationId);
        }

        if(shipDate != dateNull())
        {
            QueryBuildDataSource qbds;

            qbds = query.dataSourceTable(tableNum(SalesLine));
            qbds.addRange(fieldNum(SalesLine, ShippingDateConfirmed)).value(SysQuery::value(shipDate));
        }

        if(dlvModeFrom.elements())
        {
            container   conMOD;
            Enumerator  enumerator  =   dlvModeFrom.getEnumerator();

            while (enumerator.moveNext())
            {
                conMOD += enumerator.current();
            }

            QueryBuildDataSource qbds;
            qbds = query.dataSourceTable(tableNum(SalesLine));

            qbds.addRange(fieldNum(SalesLine, DlvMode)).value(con2Str(conMOD));
        }

    }

    public WorkbenchSessionLine initFromCommon(Common _callerTable)
    {
        WorkbenchSessionLine line;

        switch (_callerTable.TableId)
        {
            case tableNum(SalesLine):
                line.RefRecId    = _callerTable.(fieldNum(SalesLine, RecId));
                line.RefTableId    = _callerTable.TableId;

                line.InventTransId    = _callerTable.(fieldNum(SalesLine, InventTransId));

                if(routing == Routing::Sales)
                {
                    line.ReferenceType = RefType::SalesOrder;
                }
                else if(routing == Routing::Return)
                {
                    line.ReferenceType = RefType::ReturnOrder;
                }
                break;

            default:
                break;
        }

        return line;
    }

    public void createWorkbenchSession(WorkbenchSessionContract _contract)
    {
        WorkbenchSessionTable header;
        WorkbenchSessionLine line;

        RecordInsertList lineRecordList = new RecordInsertList(tableNum(WorkbenchSessionLine), true, true, true, false, true, line);

        contract = _contract;
       
        this.initializeParameters();
        this.initializeQueryDS();
        this.initializeQueryRange();

        try
        {
            ttsbegin;

            NumberSeq numberSeq = NumberSeq::newGetNum(TMSParameters::numRefInternalSessionID());

            header.initValue();

            header.DynamicsInternalSessionID = numberSeq.num();

            numberSeq.used();

            header.SessionStatus = SessionStatus::Open;

            header.LE_ID = curExt();

            if (routing == Routing::Sales || routing == Routing::Return)
            {
                header.CombineOrders = true;
            }
           
            header.insert();

            queryRun = new QueryRun(query);

            while(queryRun.next())
            {
                Common common = queryRun.get(TblNum);

                line = this.initFromCommon(common);

                line.WorkbenchSessionTable = header.RecId;

                lineRecordList.add(line);
            }

            lineRecordList.insertDatabase();

            ttscommit;
            
            this.openWorkbenchSessionForm(header);
        }
        catch
        {

        }
    }

Sysoperations frameworks Tips and tricks in AX

    protected ClassDescription defaultCaption()
    {
        return "@CashManagement:CashFlowTimeSeriesInitializeControllerCaption";
    }

    public ClassDescription caption()
    {
        return this.defaultCaption();
    }

    /// <summary>
    /// Indicates if the class must run in batch or not.
    /// </summary>
    /// <returns>
    /// Always returns false.
    /// </returns>
    /// <remarks>
    /// This method must be in this class because it is called from the <c>dialogRunbase</c> class.
    /// </remarks>
    public boolean mustGoBatch()
    {
        return false;
    }

    /// <summary>
    /// Determines whether the job can be executed in batch.
    /// </summary>
    /// <returns>
    /// false if the job cannot be executed in batch; otherwise, true.
    /// </returns>
    public boolean canGoBatch()
    {
        return false;
    }

    /// <summary>
    /// Sets whether to show the batch tab or not.
    /// </summary>
    /// <param name = "_showBatchTab">Flag to identify whether to show the batch tab or not.</param>
    /// <returns>False for batch tab to be invisible</returns>
    public boolean showBatchTab(boolean _showBatchTab = showBatchTab)
    {
        return false;
    }
	
	public boolean showBatchRecurrenceButton(boolean _showBatchRecurrenceButton = showBatchRecurrenceButton)
    {
        return false;
    }

Thursday, April 22, 2021

How to get the number of elements in the list in AX

{ 
    List il = new List(Types::Integer); 
 
    il.addStart(1); 
    il.addStart(2); 
    il.addStart(3); 
    if (il.elements() != 3) 
    { 
        print "Something is wrong..."; 
    } 
}

Friday, April 16, 2021

Data entities method calling sequence in D365FO

 
EXPORT:
       Entity- postLoad()
       staging - insert()
       Entity- postLoad() - depends on records

IMPORT:
       staging - postLoad()
       Entity - postLoad()
       Entity - initValue()
       Entity - validateField() - depends on no of fields
       Entity - validateWrite()
       Entity - insert() / update()
       Entity - persistEntity()
       Entity - initializeEntityDataSource()
       Entity - mapEntityToDataSource()
       Entity - insertEntityDataSource() / updateEntityDataSource()
       Entity - mapDataSourceToEntity()
       staging - postLoad()

Tuesday, April 13, 2021

How to create a collapsible section in Blogger

Add CSS

Add a unique name for each new post eg: collapsible1 or collapsible2 etc
add at the start of the HTML code after <HTML> tag
<style>
.collapsible {
  background-color: #777;
  color: white;
  cursor: pointer;
  padding: 18px;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}

.active, .collapsible:hover {
  background-color: #555;
}

.content1 {
  padding: 0 18px;
  display: none;
  overflow: hidden;
  background-color: #f1f1f1;
}
</style>

Apply CSS to div and Paragragh

add these classes in the paragrah and the div at the start of the tag
<p title="UIBuilder" class="collapsible">UIBuilder class</p>
<div class="content1"></div>

Javascript

add at the end of the HTML code before </HTML> tag
<script>
var coll = document.getElementsByClassName("collapsible");
var i;

for (i = 0; i < coll.length; i++) {
  coll[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var content = this.nextElementSibling;
    if (content.style.display === "block") {
      content.style.display = "none";
    } else {
      content.style.display = "block";
    }
  });
}
</script>

How to use RecordInsertList in AX

/// <summary>
/// The <c>BankCheckStubDP</c> class declares the variables and tables that are required for the
/// <c>BankCheckStub</c> report.
/// </summary>
[
    SRSReportParameterAttribute(classStr(BankCheckStubContract))
]
public class BankCheckStubDP extends SRSReportDataProviderBase
{
    BankCheckStubTmp  BankCheckStubTmp;
    /// <summary>
    ///    Fetches the <c>BankCheckStubTmp</c> temporary table.
    /// </summary>
    /// <returns>
    ///    The <c>BankCheckStubTmp</c> temporary table.
    /// </returns>
    [
        SRSReportDataSetAttribute(tablestr(BankCheckStubTmp))
    ]
    public BankCheckStubTmp getBankCheckStubTmp()
    {
        select  BankCheckStubTmp;
    
        return  BankCheckStubTmp;
    }

    /// <summary>
    ///    Fetches the required data for the <c>BankCheckStub</c> report.
    /// </summary>
    public void processReport()
    {
        RecordInsertList            tmpTableRecordList;
        BankTrans             BankTrans;
        BankChequeTable             bankChequeTable;
        CompanyBankAccountId        curBankAccountIdGroup;
        BankChequeNum               curChequeNumGroup;
        int                         lineNumInCheck;
        RefRecId                    SSNType;
        HcmIdentificationNumber     BankSSN;
    
        BankCheckStubContract contract        = this.parmDataContract() as BankCheckStubContract;
        BankChequeNum               chequeNum       = contract.parmChequeNum();
        TransDate                   transDate       = contract.parmChequeDate();
        CompanyBankAccountId        bankAccountId   = contract.parmBankAccountId();
        ShowSSN                  showSSN         = contract.parmShowSSN();
    
        tmpTableRecordList = new RecordInsertList(tableNum(BankCheckStubTmp), true, true, true, false, true, BankCheckStubTmp);
    
        SSNType = BankAccountingParameters::find().SSNIdentificationType;
        if (!Global::hasTableAccess(tableNum(HcmPersonIdentificationNumber))
        ||  !Global::hasFieldAccess(tableNum(HcmPersonIdentificationNumber), fieldNum(HcmPersonIdentificationNumber, IdentificationNumber)))
        {
            showSSN = false;
        }
    
        while select BankTrans order by BankAccountId, BankChequeNum
            where (BankTrans.JournalEntryType == JournalEntryType::Refund
              ||   BankTrans.JournalEntryType == JournalEntryType::Stipend
              ||   BankTrans.JournalEntryType == JournalEntryType::SubsidiaryRefund)
              &&   BankTrans.SISPaymentType   == SISPaymentType::Check
              &&   BankTrans.BankChequeNum
              &&  (!chequeNum     || (chequeNum     && BankTrans.BankChequeNum  == chequeNum))
              &&  (!bankAccountId || (bankAccountId && BankTrans.BankAccountId  == bankAccountId))
            join TransDate from bankChequeTable
                where bankChequeTable.AccountID     == BankTrans.BankAccountId
                  &&  bankChequeTable.ChequeNum     == BankTrans.BankChequeNum
                  && (!transDate  || (transDate     && bankChequeTable.TransDate == transDate))
        {
            if (curBankAccountIdGroup != BankTrans.BankAccountId || curChequeNumGroup != BankTrans.BankChequeNum)
            {
                curBankAccountIdGroup = BankTrans.BankAccountId;
                curChequeNumGroup     = BankTrans.BankChequeNum;
                lineNumInCheck        = 1;
            }
    
            BankSSN  = "";
            if (showSSN)
            {
                BankSSN  = HcmPersonIdentificationNumber::findByPersonAndType(Bank::find(BankTrans.Bank).Person, SSNType).IdentificationNumber;
            }
    
            BankCheckStubTmp.BankAccountId   = BankTrans.BankAccountId;
            BankCheckStubTmp.ChequeNum       = BankTrans.BankChequeNum;
            BankCheckStubTmp.ChequeDate      = bankChequeTable.TransDate;
            BankCheckStubTmp.LineNum         = strFmt('%1', lineNumInCheck);
            BankCheckStubTmp.BankId       = strFmt('%1', BankTrans.BankIdInSIS);
            BankCheckStubTmp.BankName     = BankTrans.BankName();
            BankCheckStubTmp.BankSSN      = BankSSN;
            BankCheckStubTmp.FundSource      = FundSource::findByRecId(BankTrans.FundSource).Description;
            BankCheckStubTmp.Amount          = BankTrans.AmountCur;
    
            tmpTableRecordList.add(BankCheckStubTmp);
            lineNumInCheck++;
        }
    
        tmpTableRecordList.insertDatabase();
    }
}

How to create RunBaseBatch class in AX : Sample code

See the code

/// <summary>
///    The <c>LedgerJournalEntryPost</c> class creates and posts to general ledger transactions specified in
///    the <c>LedgerJournalEntryContract</c> contract class.
/// </summary>
class LedgerJournalEntryPost extends RunBaseBatch
{
    LedgerJournalEntryContract           ledgerJournalEntryContract;
    LedgerJournalEntryPostStatusContract ledgerJournalEntryPostStatusContract;
    Set                                     studentTransRecIdPostedSet;

    #IntegrationServiceFaults
    /// <summary>
    ///     Checks if the Ledger journal can be posted or not.
    /// </summary>
    /// <param name="_ledgerJournalTable">
    ///     Record of the <c>LedgerJournalTable</c> table to verify.
    /// </param>
    /// <returns>
    ///     True if Ledger journal can be posted; otherwise, false.
    /// </returns>
    protected boolean canPostLedgerJournal(LedgerJournalTable  _ledgerJournalTable)
    {
        LedgerJournalTrans  ledgerJournalTrans;
        VendPaymModeTable   vendPaymModeTable;
    
        select firstOnly RecId from ledgerJournalTrans
            where ledgerJournalTrans.JournalNum == _ledgerJournalTable.JournalNum;
    
        if (!ledgerJournalTrans.RecId)
        {
            return false;
        }
    
        if (_ledgerJournalTable.JournalType == LedgerJournalType::Payment)
        {
            select firstOnly RecId from ledgerJournalTrans
                where ledgerJournalTrans.JournalNum        == _ledgerJournalTable.JournalNum
                 &&   ledgerJournalTrans.AccountType       == LedgerJournalACType::Vend
                 &&   ledgerJournalTrans.OffsetAccountType == LedgerJournalACType::Bank
                 &&  (!ledgerJournalTrans.BankChequeNum
                 ||  ledgerJournalTrans.PaymentStatus      != CustVendPaymStatus::Sent)
            exists join vendPaymModeTable
                where vendPaymModeTable.PaymMode        == ledgerJournalTrans.PaymMode
                   && vendPaymModeTable.PaymentType     == PaymentType::Check;
    
            if(ledgerJournalTrans.RecId)
            {
                return false;
            }
        }
    
        return true;
    }

    /// <summary>
    ///     Creates a ledger journal for the specified ledger journal entry.
    /// </summary>
    /// <param name="_ledgerJourEntryLines">
    ///     List of <c>LedgerJournalEntryLineContract</c> contract classes.
    /// </param>
    /// <param name="_journalEntryType">
    ///     The type of the journal to create.
    /// </param>
    /// <returns>
    ///     Created <c>LedgerJournalTable</c> table.
    /// </returns>
    protected LedgerJournalTable createJournal(List                 _ledgerJourEntryLines,
                                               JournalEntryType  _journalEntryType)
    {
        LedgerJournalTable              ledgerJournalTable;
        LedgerJournalCreate          ledgerJournalCreate;
        LedgerJournalEntryContract   entryContract;
    
        entryContract = new LedgerJournalEntryContract();
        entryContract.parmLedgerJourEntryLines(_ledgerJourEntryLines);
    
        ledgerJournalCreate = LedgerJournalCreate::construct(entryContract, _journalEntryType);
        ledgerJournalCreate.run();
    
        ledgerJournalTable = ledgerJournalCreate.parmLedgerJournalTable();
    
        return  ledgerJournalTable;
    }

    /// <summary>
    ///     Finds or creates a ledger journal for the specified ledger journal entry.
    /// </summary>
    /// <param name="_ledgerJourEntryLines">
    ///     List of <c>LedgerJournalEntryLineContract</c> contract classes.
    /// </param>
    /// <param name="_journalEntryType">
    ///     The type of the journal entry.
    /// </param>
    /// <param name="_paymentType">
    ///     The payment type of the journal entry.
    /// </param>
    /// <returns>
    ///     Found or created <c>LedgerJournalTable</c> table.
    /// </returns>
    protected LedgerJournalTable findOrCreateJournal(List                 _ledgerJourEntryLines,
                                                     JournalEntryType  _journalEntryType,
                                                     SISPaymentType    _paymentType)
    {
        LedgerJournalTable  ledgerJournalTable;
    
        ledgerJournalTable = this.findRelatedJournal(_ledgerJourEntryLines, _journalEntryType, _paymentType);
    
        if (!ledgerJournalTable)
        {
            ledgerJournalTable = this.createJournal(_ledgerJourEntryLines, _journalEntryType);
        }
    
        return  ledgerJournalTable;
    }

    /// <summary>
    ///     Finds the ledger journal for the specified ledger journal entry.
    /// </summary>
    /// <param name="_ledgerJourEntryLines">
    ///     List of <c>LedgerJournalEntryLineContract</c> contract classes.
    /// </param>
    /// <param name="_journalEntryType">
    ///     The type of the journal entry.
    /// </param>
    /// <param name="_paymentType">
    ///     The payment type of the journal entry.
    /// </param>
    /// <returns>
    ///     Found <c>LedgerJournalTable</c> table.
    /// </returns>
    protected LedgerJournalTable findRelatedJournal(List                 _ledgerJourEntryLines,
                                                    JournalEntryType  _journalEntryType,
                                                    SISPaymentType    _paymentType)
    {
        LedgerJournalEntryLineContract   ledgerJournalEntryLineContract;
        ListEnumerator                      ledgerJourEntryLinesEnum;
        LedgerJournalTable                  ledgerJournalTable;
    
        if (StudentTrans::isBankChequeProcess(_journalEntryType, _paymentType))
        {
            ledgerJourEntryLinesEnum = _ledgerJourEntryLines.getEnumerator();
    
            while (ledgerJourEntryLinesEnum.moveNext())
            {
                ledgerJournalEntryLineContract = ledgerJourEntryLinesEnum.current();
    
                //if (ledgerJournalEntryLineContract.parmBankChequeNum())
                //{
                ledgerJournalTable = ledgerJournalTable.FindByStudentTransIdInSIS(ledgerJournalEntryLineContract.parmTransIdInSIS(),
                                                                                        ledgerJournalEntryLineContract.parmJournalEntryType());
                if (ledgerJournalTable)
                {
                    return  ledgerJournalTable;
                }
                //}
            }
        }
    
        return  ledgerJournalTable;
    }

    /// <summary>
    ///     Initializes the map of transaction types and transactions from
    ///     the <c>LedgerJournalEntryContract</c> contract class.
    /// </summary>
    /// <returns>
    ///     An instance of the map of transaction types and transactions.
    /// </returns>
    public Map getJournalEntryLinesMap()
    {
        List                              entryLineList;
        ListEnumerator                    ledgerJournalEntryLinesEnum;
        LedgerJournalEntryLineContract entryLineContract;
        container                         entryTypeKeyCon;
        int                               transGroupCounter;
        Map                               entryLinesMap = new Map(Types::Container, Types::Class);
    
        #define.TransGroupUniqueIdentifier("TransGroupUniqueIdentifier")
    
        ledgerJournalEntryLinesEnum     = ledgerJournalEntryContract.parmLedgerJourEntryLines().getEnumerator();
    
        while (ledgerJournalEntryLinesEnum.moveNext())
        {
            entryLineContract = ledgerJournalEntryLinesEnum.current();
    
            if (StudentTrans::isBankChequeProcess(entryLineContract.parmJournalEntryType(), entryLineContract.parmSISPaymentType())
             && entryLineContract.parmMasterChequeGroup())
            {
                entryTypeKeyCon = [entryLineContract.parmJournalEntryType(), entryLineContract.parmSISPaymentType(), entryLineContract.parmMasterChequeGroup()];
            }
            else
            {
                transGroupCounter++;
                entryTypeKeyCon = [entryLineContract.parmJournalEntryType(), entryLineContract.parmSISPaymentType(), strFmt("%1%2", #TransGroupUniqueIdentifier, transGroupCounter)];
            }
    
            if (!entryLinesMap.exists(entryTypeKeyCon))
            {
                entryLineList = new List(Types::Class);
                entryLineList.addEnd(entryLineContract);
    
                entryLinesMap.insert(entryTypeKeyCon, entryLineList);
            }
            else
            {
                entryLineList = entryLinesMap.lookup(entryTypeKeyCon);
                entryLineList.addEnd(entryLineContract);
    
                entryLinesMap.insert(entryTypeKeyCon, entryLineList);
            }
        }
    
        return entryLinesMap;
    }

    /// <summary>
    ///    Gets student transaction SIS Ids.
    /// </summary>
    /// <param name="_ledgerJourEntryLines">
    ///     List of <c>LedgerJournalEntryLineContract</c> contract classes.
    /// </param>
    /// <returns>
    ///     Container of student transaction SIS Ids.
    /// </returns>
    protected container getStudentTransIds(List _ledgerJourEntryLines)
    {
        LedgerJournalEntryLineContract   ledgerJournalEntryLineContract;
        container                           ret;
        ListEnumerator                      ledgerJournalEntryLinesEnum = _ledgerJourEntryLines.getEnumerator();
    
        while (ledgerJournalEntryLinesEnum.moveNext())
        {
            ledgerJournalEntryLineContract = ledgerJournalEntryLinesEnum.current();
    
            ret += ledgerJournalEntryLineContract.parmTransIdInSIS();
        }
    
        return  ret;
    }

    /// <summary>
    ///     Initializes <c>LedgerJournalEntryPostStatusContract</c> contract class.
    /// </summary>
    protected void initEntryPostStatusContract()
    {
        ledgerJournalEntryPostStatusContract = new LedgerJournalEntryPostStatusContract();
        ledgerJournalEntryPostStatusContract.parmPostedJournals(new List(Types::String));
        ledgerJournalEntryPostStatusContract.initializeMessages();
    }

    public static void markPostedTrans(Map _postedTransMap)
    {
        new SISIntegrationServiceAdapter().sendPostedStudentTrans(_postedTransMap);
    }

    public void new()
    {
        super();
    
        studentTransRecIdPostedSet = new Set(Types::Int64);
    }

    /// <summary>
    ///     Gets or sets the value of the <c>LedgerJournalEntryContract</c> class parameter.
    /// </summary>
    /// <param name="_ledgerJournalEntryContract">
    ///     The new value of the <c>LedgerJournalEntryContract</c> class parameter; optional.
    /// </param>
    /// <returns>
    ///     The current value of the <c>LedgerJournalEntryContract</c> class parameter.
    /// </returns>
    public LedgerJournalEntryContract parmLedgerJournalEntryContract(LedgerJournalEntryContract _ledgerJournalEntryContract = ledgerJournalEntryContract)
    {
        ledgerJournalEntryContract = _ledgerJournalEntryContract;
        return ledgerJournalEntryContract;
    }

    /// <summary>
    ///     Gets or sets the value of the <c>LedgerJournalEntryPostStatusContract</c> class parameter.
    /// </summary>
    /// <param name="_ledgerJournalEntryPostStatusContract">
    ///     The new value of the <c>LedgerJournalEntryPostStatusContract</c> class parameter; optional.
    /// </param>
    /// <returns>
    ///     The current value of the <c>LedgerJournalEntryPostStatusContract</c> class parameter.
    /// </returns>
    public LedgerJournalEntryPostStatusContract parmLedgerJournalEntryPostStatusContract(LedgerJournalEntryPostStatusContract _ledgerJournalEntryPostStatusContract = ledgerJournalEntryPostStatusContract)
    {
        ledgerJournalEntryPostStatusContract = _ledgerJournalEntryPostStatusContract;
        return  ledgerJournalEntryPostStatusContract;
    }

    /// <summary>
    ///     Gets or sets the value of the <c>studentTransRecIdPostedSet</c> parameter.
    /// </summary>
    /// <param name="_studentTransRecIdPostedSet">
    ///     The new value of the <c>studentTransRecIdPostedSet</c> parameter; optional.
    /// </param>
    /// <returns>
    ///     The current value of the <c>studentTransRecIdPostedSet</c> parameter.
    /// </returns>
    public Set parmStudentTransRecIdPostedSet(Set _studentTransRecIdPostedSet = studentTransRecIdPostedSet)
    {
        studentTransRecIdPostedSet = _studentTransRecIdPostedSet;
        return studentTransRecIdPostedSet;
    }

    /// <summary>
    ///     Posts the ledger journal.
    /// </summary>
    /// <param name="_ledgerJournalTable">
    ///     Ledger journal to post.
    /// </param>
    protected void postJournal(LedgerJournalTable   _ledgerJournalTable)
    {
        LedgerJournalCheckPost  ledgerJournalCheckPost;
        LedgerJournalTable      ledgerJournalTable;
    
        if (!_ledgerJournalTable)
        {
            throw error("@1401");
        }
    
        ledgerJournalCheckPost = LedgerJournalCheckPost::newLedgerJournalTable(_ledgerJournalTable, NoYes::Yes);
    
        if (this.canPostLedgerJournal(_ledgerJournalTable))
        {
            ledgerJournalCheckPost.parmSkipBlockedForManualEntryCheck(true);
            ledgerJournalCheckPost.runOperation();
        }
    
        ledgerJournalTable = ledgerJournalTable::find(_ledgerJournalTable.JournalNum);
    
        if (!ledgerJournalTable.Posted)
        {
            throw error("@1402");
        }
    }

    /// <summary>
    ///    Posts student transactions.
    /// </summary>
    /// <param name="_journalNum">
    ///     Ledger journal Id.
    /// </param>
    /// <param name="_ledgerJourEntryLines">
    ///     List of <c>LedgerJournalEntryLineContract</c> contract classes.
    /// </param>
    protected void postStudentTrans(LedgerJournalId   _journalNum,
                                    List              _ledgerJourEntryLines)
    {
        LedgerJournalEntryLineContract   ledgerJournalEntryLineContract;
        StudentTrans                     studentTrans;
        container                           mapKey;
        ListEnumerator                      ledgerJournalEntryLinesEnum = _ledgerJourEntryLines.getEnumerator();
        Map                                 transLedgerJournalIdMap     = new Map(Types::Container, Types::Class);
        Set                                 journalNumSet               = new Set(Types::String);
    
        journalNumSet.add(_journalNum);
    
        while (ledgerJournalEntryLinesEnum.moveNext())
        {
            ledgerJournalEntryLineContract = ledgerJournalEntryLinesEnum.current();
    
            mapKey = [ledgerJournalEntryLineContract.parmTransIdInSIS(), ledgerJournalEntryLineContract.parmJournalEntryType()];
    
            transLedgerJournalIdMap.insert(mapKey, journalNumSet);
    
            studentTrans        = StudentTrans::find(ledgerJournalEntryLineContract.parmTransIdInSIS(),
                                                        ledgerJournalEntryLineContract.parmJournalEntryType(),
                                                        true);
            studentTrans.Posted = true;
            if(studentTrans.SISPaymentType == SISPaymentType::Check)
                studentTrans.PendingChequeInSIS = false;
    
            if (!studentTrans.validateWrite())
            {
                throw error("@SYS18447");
            }
    
            studentTrans.updateSkipDatabaseLog(true);
    
            if (studentTrans.isValidForFundSourceTrans())
            {
                if (FundSourceTrans::findByStudentTrans(studentTrans.RecId))
                {
                    FundSourceTrans::updateExist(studentTrans);
                }
                else
                {
                    FundSourceTrans::create(studentTrans);
                }
            }
    
            if (StudentAccountingParameters::isCampusNexusMode())
            {
                LedgerJournalEntryPost::markPostedTrans(transLedgerJournalIdMap);
            }
    
            studentTransRecIdPostedSet.add(studentTrans.RecId);
        }
    }

    /// <summary>
    ///     Executes business logic of the class.
    /// </summary>
    public void run()
    {
        LedgerJournalTable      ledgerJournalTable;
        JournalEntryType     journalEntryType;
        SISPaymentType       paymentType;
        AifInfoLog              aifInfoLog;
        List                    ledgerJourEntryLines;
        Name                    groupName;
        boolean                 exceptionThrown;
        MapEnumerator           entryLinesMapEnum;
    
        this.initEntryPostStatusContract();
    
        entryLinesMapEnum = this.getJournalEntryLinesMap().getEnumerator();
    
        while (entryLinesMapEnum.moveNext())
        {
            [journalEntryType, paymentType, groupName]  = entryLinesMapEnum.currentKey();
            ledgerJourEntryLines                        = entryLinesMapEnum.currentValue();
            aifInfoLog                                  = new AifInfoLog();
    
            try
            {
                ttsBegin;
    
                this.validateLedgerJourEntryLines(ledgerJourEntryLines);
    
                ledgerJournalTable = this.findOrCreateJournal(ledgerJourEntryLines, journalEntryType, paymentType);
    
                this.postJournal(ledgerJournalTable);
                this.postStudentTrans(ledgerJournalTable.JournalNum, ledgerJourEntryLines);
    
                ttsCommit;
    
                if (ledgerJournalTable.Posted)
                {
                    ledgerJournalEntryPostStatusContract.parmPostedJournals().addEnd(ledgerJournalTable.JournalNum);
                }
            }
            catch (Exception::Error)
            {
                exceptionThrown = true;
                this.updateEntryPostStatus(aifInfoLog, LedgerJournalCreatePostStatus::Error, this.getStudentTransIds(ledgerJourEntryLines));
            }
            catch (Exception::CLRError)
            {
                exceptionThrown = true;
                error(AifUtil::getClrErrorMessage());
                this.updateEntryPostStatus(aifInfoLog, LedgerJournalCreatePostStatus::Error, this.getStudentTransIds(ledgerJourEntryLines));
            }
            catch
            {
                exceptionThrown = true;
                this.updateEntryPostStatus(aifInfoLog, LedgerJournalCreatePostStatus::Error, this.getStudentTransIds(ledgerJourEntryLines));
            }
        }
    
        if (!exceptionThrown && !ledgerJournalEntryPostStatusContract.parmPostedJournals().empty())
        {
            ledgerJournalEntryPostStatusContract.parmStatus(LedgerJournalCreatePostStatus::Posted);
        }
    }

    /// <summary>
    ///     Updates <c>LedgerJournalEntryPostStatusContract</c> contract class.
    /// </summary>
    /// <param name="_aifInfoLog">
    ///     An object of <c>AifInfoLog</c> class.
    /// </param>
    /// <param name="_postStatus">
    ///     Operation status.
    /// </param>
    /// <param name="_studentTransIdCon">
    ///     Container of student transaction SIS Ids.
    /// </param>
    protected void updateEntryPostStatus(AifInfoLog                         _aifInfoLog,
                                         LedgerJournalCreatePostStatus   _postStatus,
                                         container                          _studentTransIdCon)
    {
        SysInfologEnumerator infologEnum;
    
        if (!ledgerJournalEntryPostStatusContract)
        {
            this.initEntryPostStatusContract();
        }
    
        ledgerJournalEntryPostStatusContract.parmStatus(_postStatus);
    
        AifFault::fault(strFmt("@1403", "@141", con2str(_studentTransIdCon, ', ')), #LedgerJournalTableCreationFailed);
    
        infologEnum = SysInfologEnumerator::newData(_aifInfoLog.getInfoLogData());
    
        while (infologEnum.moveNext())
        {
            ledgerJournalEntryPostStatusContract.addMessage(IntegrationServiceProvider::trimLeadingTabs(infologEnum.currentMessage()));
        }
    }

    /// <summary>
    ///     Validates ledger journal entry lines.
    /// </summary>
    /// <param name="_ledgerJourEntryLines">
    ///     List of <c>LedgerJournalEntryLineContract</c> contract classes.
    /// </param>
    protected void validateLedgerJourEntryLines(List    _ledgerJourEntryLines)
    {
        LedgerJournalEntryLineContract ledgerJournalEntryLineContract;
        StudentTrans                   studentTrans;
        ListEnumerator                    ledgerJournalEntryLinesEnum = _ledgerJourEntryLines.getEnumerator();
    
        while (ledgerJournalEntryLinesEnum.moveNext())
        {
            ledgerJournalEntryLineContract = ledgerJournalEntryLinesEnum.current();
            studentTrans                    = StudentTrans::find(ledgerJournalEntryLineContract.parmTransIdInSIS(), ledgerJournalEntryLineContract.parmJournalEntryType());
    
            if (studentTrans.Posted)
            {
                throw error(strfmt("@1399", studentTrans.description()));
            }
    
            if (StudentTrans::isBankChequeProcess(studentTrans.JournalEntryType, studentTrans.SISPaymentType)
             && !studentTrans.BankChequeNum)
            {
                throw error(strFmt("@1400", studentTrans.description()));
            }
        }
    }

    /// <summary>
    ///     Creates a new instance of the <c>LedgerJournalEntryPost</c> class.
    /// </summary>
    /// <param name="_ledgerJournalEntryContract">
    ///     Value of the <c>LedgerJournalEntryContract</c> contract class.
    /// </param>
    /// <returns>
    ///    Created instance of the <c>LedgerJournalEntryPost</c> class.
    /// </returns>
    public static server LedgerJournalEntryPost construct(LedgerJournalEntryContract _ledgerJournalEntryContract)
    {
        LedgerJournalEntryPost   ledgerJournalEntryPost = new LedgerJournalEntryPost();
    
        ledgerJournalEntryPost.parmLedgerJournalEntryContract(_ledgerJournalEntryContract);
    
        return  ledgerJournalEntryPost;
    }

    /// <summary>
    ///     Creates an object of <c>LedgerJournalEntryContract</c> contract class.
    /// </summary>
    /// <param name="_studentTransRecIdPacked">
    ///     Packed set of <c>StudentTrans</c> record Ids.
    /// </param>
    /// <returns>
    ///     An object of <c>LedgerJournalEntryContract</c> contract class.
    /// </returns>
    public static server LedgerJournalEntryContract createJournalEntryContractList(container   _studentTransRecIdPacked)
    {
        StudentTrans                 studentTrans;
        StudentTrans                 studentTransMasterCheque;
        LedgerJournalEntryContract   ledgerJournalEntryContract  = new LedgerJournalEntryContract();
        Set                             masterChequeGroup           = new Set(Types::String);
        Set                             studentTransRecIdSet        = Set::create(_studentTransRecIdPacked);
        SetEnumerator                   se                          = studentTransRecIdSet.getEnumerator();
    
        ledgerJournalEntryContract.parmLedgerJourEntryLines(new List(Types::Class));
    
        while (se.moveNext())
        {
            studentTrans = StudentTrans::findRecId(se.current());
    
            if (studentTrans.MasterChequeGroup && !masterChequeGroup.in(studentTrans.MasterChequeGroup))
            {
                masterChequeGroup.add(studentTrans.MasterChequeGroup);
    
                while select studentTransMasterCheque
                    where studentTransMasterCheque.MasterChequeGroup == studentTrans.MasterChequeGroup
                {
                    ledgerJournalEntryContract.parmLedgerJourEntryLines().addEnd(studentTransMasterCheque.ledgerJournalEntryLineContract());
                }
            }
            else if (!studentTrans.MasterChequeGroup)
            {
                ledgerJournalEntryContract.parmLedgerJourEntryLines().addEnd(studentTrans.ledgerJournalEntryLineContract());
            }
        }
    
        return  ledgerJournalEntryContract;
    }

    /// <summary>
    ///     Performs transaction posting from user interface.
    /// </summary>
    /// <param name="_args">
    ///     Parameters object.
    /// </param>
    public static void main(Args _args)
    {
        LedgerJournalEntryPost   ledgerJournalEntryPost;
        StudentTrans             studentTrans;
        FormDataSource              ds;
        Set                         studentTransRecIdSet = new Set(Types::Int64);
    
        if (!_args || !_args.dataset())
        {
            throw Error(Error::wrongUseOfFunction(funcName()));
        }
    
        if (FormDataUtil::isFormDataSource(_args.record()))
        {
            ds              = FormDataUtil::getFormDataSource(_args.record());
            studentTrans    = ds.getFirst(true) ? ds.getFirst(true) : ds.cursor();
    
            while (studentTrans)
            {
                studentTransRecIdSet.add(studentTrans.RecId);
                studentTrans = ds.getNext();
            }
        }
        else
        {
            studentTrans = _args.record();
            studentTransRecIdSet.add(studentTrans.RecId);
        }
    
        ledgerJournalEntryPost = LedgerJournalEntryPost::newFromLedgerJournalEntryContract(LedgerJournalEntryPost::createJournalEntryContractList(studentTransRecIdSet.pack()));
        ledgerJournalEntryPost.runOperation();
    
        info(strFmt("@561", ledgerJournalEntryPost.parmStudentTransRecIdPostedSet().elements()));
    
        if (ds)
        {
            ds.research(true);
        }
    }

    /// <summary>
    ///     Creates a new instance of the <c>LedgerJournalEntryPost</c> class and initilizes its parameters.
    /// </summary>
    /// <param name="_ledgerJournalEntryContract">
    ///     Value of the <c>LedgerJournalEntryContract</c> contract class.
    /// </param>
    /// <returns>
    ///    Created instance of the <c>LedgerJournalEntryPost</c> class.
    /// </returns>
    public static server LedgerJournalEntryPost newFromLedgerJournalEntryContract(LedgerJournalEntryContract _ledgerJournalEntryContract)
    {
        LedgerJournalEntryPost ledgerJournalEntryPost = new LedgerJournalEntryPost();
    
        LedgerJournalEntryPost::validateLedgerJournalEntryContract(_ledgerJournalEntryContract);
    
        ledgerJournalEntryPost.parmLedgerJournalEntryContract(_ledgerJournalEntryContract);
    
        return ledgerJournalEntryPost;
    }

    /// <summary>
    ///     Validates the <c>LedgerJournalEntryContract</c> contract class.
    /// </summary>
    /// <param name="_ledgerJournalEntryContract">
    ///     An instance of the <c>LedgerJournalEntryContract</c> contract class.
    /// </param>
    public static void validateLedgerJournalEntryContract(LedgerJournalEntryContract _ledgerJournalEntryContract)
    {
        if (!_ledgerJournalEntryContract)
        {
            throw error(strFmt("@35", classStr(LedgerJournalEntryContract)));
        }
    
        if (!_ledgerJournalEntryContract.parmLedgerJourEntryLines()
         || _ledgerJournalEntryContract.parmLedgerJourEntryLines().empty())
        {
            throw error("@36");
        }
    }

    protected boolean canRunInNewSession()
    {
        return false;
    }

}

How to pass marked records from grid to sysoperations framework in AX

Controller class

/// <summary>
/// 
/// </summary>
class Sales_UpdateMoDSalesOrderController extends SysOperationServiceController
{
    public static Sales_UpdateMoDSalesOrderController construct(Args _args)
    {
        Sales_UpdateMoDSalesOrderController  controller = new Sales_UpdateMoDSalesOrderController(classStr( Sales_UpdateMoDSalesOrderService ),
                                                                                                        methodStr( Sales_UpdateMoDSalesOrderService, updateMoDSalesOrder ),
            SysOperationExecutionMode::Synchronous);

        controller.parmArgs( _args );

        return controller;
    }

    public static void main(Args _args)
    {
        Set                                     recordSet;
        SalesTable                              salesTable;
        MultiSelectionHelper                    multiselectionHelper;
        Sales_UpdateMoDSalesOrderContract    dataContract;
        Sales_UpdateMoDSalesOrderController  controller;

        controller = Sales_UpdateMoDSalesOrderController::construct( _args );

        // Get marked records from calling form
        if (_args && _args.caller() is FormRun)
        {
            recordSet = new Set(Types::Record);
            multiselectionHelper = MultiSelectionHelper::createFromCaller(_args.caller());
        
            salesTable = multiselectionHelper.getFirst();

            while (salesTable)
            {
                recordSet.add(salesTable);
            
                salesTable = multiselectionHelper.getNext();
            }
        }

        // Put records from calling datasource into dataContract
        dataContract = controller.getDataContractObject();

        if (dataContract is Sales_UpdateMoDSalesOrderContract)
        {
            dataContract.parmRecordCon(recordSet.pack());
        }

        controller.startOperation();
    }
}

Contract class

/// <summary>
/// The data contract for Intercompany update of Mode of delivery
/// </summary>
[
    DataContract,
    SysOperationGroup('GeneralGroup',"@SYS81043",'1',FormArrangeMethod::Vertical)
]
class Sales_UpdateMoDSalesOrderContract implements SysOperationInitializable, SysOperationValidatable
{
    UpsModeOfDelivery upsModeOfDelivery;
    container            recordCon;

    /// <summary>
    /// Indicates whether the contract is valid.
    /// </summary>
    /// <returns>
    /// A Boolean value that indicates whether the contract is valid.
    /// </returns>
    public boolean validate()
    {
        boolean isValid = true;
        return isValid;
    }

    /// <summary>
    /// Initailizes the default values to parameters.
    /// </summary>
    public void initialize()
    {
    }

    /// <summary>
    /// Method used to specify the data memmber attribute
    /// </summary>
    /// <param>
    /// <name>parmShipmentDate</name>is used to set and get the shipmentDate
    /// </param>
    [
         DataMember,
         SysOperationGroupMember('GeneralGroup'),
         SysOperationDisplayOrder('1'),
         SysOperationLabelAttribute(literalstr("@Warehouse:UpsModeOfDelivery"))
    ]
    public UpsModeOfDelivery parmUpsModeOfDelivery( UpsModeOfDelivery _upsModeOfDelivery = upsModeOfDelivery )
    {
        upsModeOfDelivery  =  _upsModeOfDelivery;

        return upsModeOfDelivery;
    }

    /// <summary>
    /// Method used to specify the data memmber attribute
    /// </summary>
    /// <param name = "_recordCon"></param>
    /// <returns></returns>
    [DataMemberAttribute, SysOperationControlVisibilityAttribute(false)]
    public container parmRecordCon(container _recordCon = recordCon)
    {
        recordCon = _recordCon;

        return recordCon;
    }

}

Service class

class Sales_UpdateMoDSalesOrderService
{
    /// <summary>
    /// Creates transfer order for from and to wareshouse combination
    /// </summary>
    /// <param name = "_contract">TransferOrderCreateContract from dialog</param>
    public void updateMoDSalesOrder(Sales_UpdateMoDSalesOrderContract _contract)
    {
        Set                     recordSet;
        Common                  record;
        SalesTable              salesTable;
        SetEnumerator           se;
        ModeOfDeliverySetup  smModeOfDeliverySetup;

        // Process records
        if (conLen(_contract.parmRecordCon()) > 0)
        {
            recordSet = Set::create(_contract.parmRecordCon());
            se = recordSet.getEnumerator();
            while (se.moveNext())
            {
                record = se.current();

                switch (record.TableId)
                {
                    case tableNum(SalesTable):
                        salesTable = record;
                        salesTable.DlvMode = _contract.parmUpsModeOfDelivery();

                        info(strFmt("%1 %2", salesTable.SalesId, salesTable.DlvMode));
                        break;

                    default:
                        break;
                }
            }
        }
    }

}

Table browser URL in D365FO

Critical Thinking icon icon by Icons8