Sunday, August 31, 2025

Get Defaults the reporting currency exchange rate values when CurrencyCode field is modified on the table ledger journaltrans table

ReportingCurrencyExchRate reportingExchangeRate;

ReportingCurrencyExchRate reportingExchangeRateSecondary;

ExchRateSecondTxt exchRateTxt;  

[reportingExchangeRate,reportingExchangeRateSecondary,exchRateTxt] =               LedgerJournalEngine_Server::reportingCurrencyModified(_ledgerJournalTrans);

Create and post sales packing slip [partial quantity] using x++ d365FO

try

    {

        ttsbegin;

        salesFormLetterParmData =                         salesFormLetterParmData::newData(DocumentStatus::PackingSlip,VersioningUpdateType::Initial);

        salesFormLetterParmData.parmOnlyCreateParmUpdate(true);

        salesFormLetterParmData.createData(false);

        salesParmUpdate = salesFormLetterParmData.parmParmUpdate();

        salesParmTable = this.createParmTable("12/08/2025",salesTable, salesParmUpdate.ParmId,"Tracking1",_shipmentNumber);

        this.createSalesParmLine(salesParmTable, _salesId, _shipmentNumber);

        salesFormLetter_PackingSlip = SalesFormLetter::construct(DocumentStatus::PackingSlip);

        salesFormLetter_PackingSlip.transDate('12/08/2025');

        salesFormLetter_PackingSlip.proforma(NoYes::No);

        salesFormLetter_PackingSlip.specQty(salesUpdate::PickingList);

        salesFormLetter_PackingSlip.salesTable(salesTable);

        salesFormLetter_PackingSlip.parmId(salesParmTable.ParmId);

        salesFormLetter_PackingSlip.salesParmUpdate(salesFormLetterParmData.parmParmUpdate());

        salesFormLetter_PackingSlip.runOperation();

        ttscommit;

        this.createSalesParmTrackingTable(salesParmTable,"Test-1,Test2", salesFormLetter_PackingSlip.parmJournalRecord());

}

catch

{

}

 public SalesParmTable createParmTable(TransDate  _packingSlipDate,SalesTable _salesTable, ParmId  _parmId,ShipCarrierTrackingNum  _trackingNumbers, str  _shipmentNumber)

{

    SalesParmTable salesParmTable;

    salesParmTable.TransDate               = _packingSlipDate;

    salesParmTable.Ordering                  = DocumentStatus::PackingSlip;

    salesParmTable.ParmJobStatus         = ParmJobStatus::Waiting;

    salesParmTable.SalesId               = _salesTable.SalesId;

    salesParmTable.SalesName             = _salesTable.SalesName;

    salesParmTable.DeliveryName          = _salesTable.DeliveryName;

    salesParmTable.DeliveryPostalAddress = _salesTable.DeliveryPostalAddress;

    salesParmTable.CustAccount           = _salesTable.CustAccount;

    salesParmTable.CurrencyCode          = _salesTable.CurrencyCode;

    salesParmTable.InvoiceAccount        = _salesTable.InvoiceAccount;

    salesParmTable.ParmId                = _parmId;

    salesParmTable.ReturnPackingSlipId   = _shipmentNumber;

    salesParmTable.insert();

    return salesParmTable;

}

public SalesParmLine createSalesParmLine(SalesParmTable   _salesParmTable,SalesId          _salesId, str _shipmentNumber)

{

    SalesParmLine            salesParmLine;

    SalesParmSubLine         salesParmSubLine;

    SalesLine                salesLine;

    while select sum(SalesQty) from SalesLine group by ItemId  where SalesLine.SalesId        == _salesId

    {

        salesParmLine.clear();

        salesParmLine.initFromSalesLine(salesLine);

        salesParmLine.ParmId     = _salesParmTable.ParmId;

        salesParmLine.TableRefId = _salesParmTable.TableRefId;

        salesParmLine.DeliverNow = 10;

        salesParmLine.setQty(DocumentStatus::PackingSlip, false, true);

        salesParmLine.setInventDeliverNow();

        salesParmLine.setLineAmount(salesLine);

        salesParmLine.Closed = NoYes::No;

        salesParmLine.insert();


        salesParmSubLine.clear();

        salesParmSubLine.initValue();

        salesParmSubLine.initFromSalesParmLine(salesParmLine);

        salesParmSubLine.InventNow  = salesParmLine.InventNow;

        salesParmSubLine.DeliverNow = salesParmLine.DeliverNow;

        salesParmSubLine.insert();

    }

    return salesParmLine;

}

public static void createSalesParmTrackingTable(SalesParmTable _salesParmTable,ShipCarrierTrackingNum _trackingNumbers,CustPackingSlipJour _custPackingSlipJour)

{

    SalesParmPackingSlipTracking       salesParmPackingSlipTracking;

    SalesPackingSlipTrackingInformation salesPackingSlipTrackingInformation;

    SalesParmTable    salesParmTable = SalesParmTable::findSalesId( _salesParmTable.SalesId, _salesParmTable.ParmId);

    container con = str2con(_trackingNumbers, ",");

    for (int i = 1; i <= conLen(con); i++)

    {

        ttsbegin;

        salesParmPackingSlipTracking.clear();

        salesParmPackingSlipTracking.SalesParmId         = salesParmTable.ParmId;

        salesParmPackingSlipTracking.SalesParmTableRefId = salesParmTable.TableRefId;

        salesParmPackingSlipTracking.TrackingNumber      = conPeek(con, i);

        salesParmPackingSlipTracking.insert();


        salesPackingSlipTrackingInformation.clear();

        salesPackingSlipTrackingInformation.SalesId        = _salesParmTable.SalesId;

        salesPackingSlipTrackingInformation.PackingSlipId  = _custPackingSlipJour.PackingSlipId;

        salesPackingSlipTrackingInformation.DeliveryDate   = _salesParmTable.TransDate;

        salesPackingSlipTrackingInformation.TrackingNumber = salesParmPackingSlipTracking.TrackingNumber;

        salesPackingSlipTrackingInformation.TrackingURL    = salesParmPackingSlipTracking.TrackingURL;

        salesPackingSlipTrackingInformation.insert();

        ttscommit;

    }

}




Tuesday, August 19, 2025

Make default dimension control element editable false using x++ d365fo

public void init()

{

    DimensionEnumeration          dimensionSetId = DimensionCache::getDimensionAttributeSetForLedger();

    DimensionAttributeSetStorage  dimensionAttributeSetStorage = new DimensionAttributeSetStorage();

    DimensionAttribute            dimensionAttribute;

    DimensionAttributeSetItem     dimAttrSetItem;

    while select dimensionAttribute

        where dimensionAttribute.Name != 'MyDimension'   // Exclude specific dimension (not editable)

        join dimAttrSetItem

            where dimAttrSetItem.DimensionAttribute   == dimensionAttribute.RecId

               && dimAttrSetItem.DimensionAttributeSet == dimensionSetId

    {

        dimensionAttributeSetStorage.addItem(dimensionAttribute.RecId,dimensionAttribute.HashKey, NoYes::Yes);

    }

    DimensionEntryControl.parmEditableDimensionSet(dimensionAttributeSetStorage.save());

}


mark payment with vendor invoice using x++ d365fo

 public boolean markVendInvoicesForSettlement(

    LedgerJournalTrans  _journalTrans,

    VendAccount         _vendAccount,       

    RecId               _settlementRecId,   

    AmountCur           _settlementAmount)  

{

    boolean                     ret;

    InvoiceId                   invoiceId;

    VendTrans                   vendTrans;

    VendTable                   vendTable;

    VendTransOpen               vendTransOpen;

    AmountCur                   settlementAmount;

    CustVendOpenTransManager    settleManager;

    SpecTransManager            specTransManager;

    ret                 = true;

    settleManager       = CustVendOpenTransManager::construct(_journalTrans);

    specTransManager    = settleManager.parmSpecTransManager();

    vendTable           = VendTable::find(_vendAccount);

    vendTrans           = VendTrans::find(_settlementRecId);

    vendTransOpen       = VendTransOpen::findRefId(vendTrans.RecId);

    settlementAmount    = _settlementAmount;

    invoiceId           = vendTrans.Invoice;

    if (vendTransOpen.RecId != 0)

    {

        AmountCur unmarkedAmount = specTransManager.findUnmarkedAmountForRef( vendTransOpen.AmountCur,vendTransOpen.Company(), vendTransOpen.TableId, vendTransOpen.RecId);

        if (!settleManager.checkTransFullyMarkedByOtherSpec(vendTransOpen))

        {

            settleManager.updateTransMarked(vendTransOpen, NoYes::Yes);

            if (abs(settlementAmount) <= abs(unmarkedAmount))

            {

                settleManager.updateSettleAmountPaymCur(vendTransOpen, settlementAmount);

            }

            else

            {

                settleManager.updateSettleAmountPaymCur(vendTransOpen, unmarkedAmount);

            }

            ttsBegin;

            _journalTrans.selectForUpdate(true);

            if (invoiceId)

            {

                _journalTrans.MarkedInvoice = invoiceId;

            }

            else

            {

                _journalTrans.MarkedInvoice = '*';

            }

            _journalTrans.SettleVoucher = SettlementType::SelectedTransact;

            _journalTrans.update();

            ttsCommit;

        }

    }


    return ret;

}


Mark customer payment with invoice using x++ d365fo

public boolean markCustInvoicesForSettlement(

    LedgerJournalTrans  _journalTrans,

    CustAccount         _custAccount,     

    RecId               _settlementRecId,  // custtransrecid

    AmountCur           _settlementAmount) 

{

    boolean                     ret;

    InvoiceId                   invoiceId;

    CustTrans                   custTrans;

    CustTable                   custTable;

    CustTransOpen               custTransOpen;

    AmountCur                   settlementAmount;

    CustVendOpenTransManager    settleManager;

    SpecTransManager            specTransManager;


    ret                 = true;

    settleManager       = CustVendOpenTransManager::construct(_journalTrans);

    specTransManager    = settleManager.parmSpecTransManager();


    custTable           = CustTable::find(_custAccount);

    custTrans           = CustTrans::find(_settlementRecId);

    custTransOpen       = CustTransOpen::findRefId(custTrans.RecId);


    settlementAmount    = _settlementAmount;

    invoiceId           = custTrans.Invoice;

    if (custTransOpen.RecId != 0)

    {

        AmountCur unmarkedAmount = specTransManager.findUnmarkedAmountForRef( custTransOpen.AmountCur,  custTransOpen.Company(), 

custTransOpen.TableId,  custTransOpen.RecId);

        if (!settleManager.checkTransFullyMarkedByOtherSpec(custTransOpen))

        {

            settleManager.updateTransMarked(custTransOpen, NoYes::Yes);

            if (abs(settlementAmount) <= abs(unmarkedAmount))

            {

                settleManager.updateSettleAmountPaymCur(custTransOpen, settlementAmount);

            }

            else

            {

                settleManager.updateSettleAmountPaymCur(custTransOpen, unmarkedAmount);

            }

            ttsbegin;

            _journalTrans.selectForUpdate(true);

            if (invoiceId)

            {

                _journalTrans.MarkedInvoice = invoiceId;

            }

            else

            {

                _journalTrans.MarkedInvoice = '*';

            }


            _journalTrans.SettleVoucher = SettlementType::SelectedTransact;

            _journalTrans.update();

            ttscommit;

                TaxWithhold taxWithhold = TaxWithhold::construct(_journalTrans);

                taxWithhold.createAllTaxWithholdTrans();

                TaxWithholdTrans taxWithholdTrans = TaxWithholdTrans::find( _journalTrans.DataAreaId,

                                                        _journalTrans.Voucher,  _journalTrans.TransDate);

                if (taxWithholdTrans.RecId)

                {

                    taxWithholdTrans.selectForUpdate(true);

                    taxWithholdTrans.InvoiceTaxWithholdAmount = abs(20) * -1;

                    taxWithholdTrans.TaxWithholdAmount        = abs(20) * -1;

                    taxWithholdTrans.doUpdate();

                }

        }

    }

    return ret;

}


Create ledger dimension with main account and default dimension using x++ d365fo

public DimensionDynamicAccount generateLedgerDimension(str _mainAccount, container _conData)

{

    int                                 i;

    LedgerRecId                         ledgerRecId;

    DimensionAttribute                  dimensionAttribute;

    DimensionAttributeValue             dimensionAttributeValue;

    DimensionStorage                    dimStorage;

    LedgerAccountContract               ledgerAccountContract = new LedgerAccountContract();

    DimensionAttributeValueContract     valueContract;

    List                                valueContracts = new List(Types::Class);

    DimensionAttributeValueCombination  dimensionAttributeValueCombination;

    container conAttr = ["EntityName","CentreName","departmentName"];

    for (i = 1; i <= conLen(conAttr); i++)

    {

        dimensionAttribute = DimensionAttribute::findByName(conPeek(conAttr, i));

        if (dimensionAttribute.RecId == 0)

        {

            continue;

        }


        if (dimensionAttribute)

        {

            dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,

                          conPeek(_conData, i));

            if (dimensionAttributeValue)

            {

                valueContract = new DimensionAttributeValueContract();

                valueContract.parmName(dimensionAttribute.Name);

                valueContract.parmValue(dimensionAttributeValue.CachedDisplayValue);

                valueContracts.addEnd(valueContract);

            }

        }

    }

    ledgerAccountContract.parmMainAccount(_mainAccount);

    ledgerAccountContract.parmValues(valueContracts);

    dimStorage = DimensionServiceProvider::buildDimensionStorageForLedgerAccount(ledgerAccountContract);

    dimensionAttributeValueCombination = DimensionAttributeValueCombination::find(dimStorage.save());

    ledgerRecId = dimensionAttributeValueCombination.RecId;

    return ledgerRecId;

}


Create customer bank account using x++ d365fo

CustName                 name;

DirParty                 dirParty; 

CustTable                custTable;

CustBankAccount          custBankAccount;

ttsBegin;

custBankAccount.clear();

custBankAccount.initValue();

custBankAccount.CustAccount     = 'CUST-000123';

custBankAccount.AccountID       = 'BANK-ACCT-001';

custBankAccount.Name            = 'Wells Fargo Bank';

custBankAccount.AccountNum      = '9876543210';

custBankAccount.BankGroupId     = 'CORP-BANK';

custBankAccount.RegistrationNum = 'REG-998877';

custBankAccount.BankCodeType    = 'RoutingNumber';

custBankAccount.SWIFTNo         = 'WFBIUS6S';

custBankAccount.BankIBAN        = 'US64SVBKUS6S1234567890';

custBankAccount.CurrencyCode    = 'USD';


LogisticsPostalAddress          logisticsPostalAddress;         

LogisticsLocation               logisticsLocation;

LogisticsAddressStreet          street;


street = '123 Market Street' + '\n' + 'Suite 45B' + '\n' + 'Business Plaza';

logisticsLocation = LogisticsLocation::find(custBankAccount.Location, true);

if (!logisticsLocation.RecId)

{

    logisticsLocation.clear();

}

logisticsLocation.IsPostalAddress = NoYes::Yes;

logisticsLocation.Description     = 'Primary Bank Address';

logisticsLocation.write();

logisticsPostalAddress = LogisticsPostalAddress::findByLocation(logisticsLocation.RecId, true);

if (!logisticsPostalAddress.RecId)

{

    logisticsPostalAddress.clear();

}

logisticsPostalAddress.CountryRegionId  = 'US';

logisticsPostalAddress.State            = 'CA';

logisticsPostalAddress.County           = 'Santa Clara';

logisticsPostalAddress.City             = 'San Jose';

logisticsPostalAddress.ZipCode          = '95113';

logisticsPostalAddress.DistrictName     = 'Downtown';

logisticsPostalAddress.Street           = street;

logisticsPostalAddress.Location         = logisticsLocation.RecId;

if (logisticsPostalAddress.RecId)

{

    logisticsPostalAddress.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);

}

logisticsPostalAddress.formatAddressInstance();

logisticsPostalAddress.write();

custBankAccount.Location = logisticsLocation.RecId;

custBankAccount.defaultRow();

// Validate and Insert

if (custBankAccount.validateWrite())

{

    custBankAccount.insert();

    custTable = CustTable::find(custBankAccount.CustAccount, true);

    if (custTable.RecId && custTable.BankAccount != custBankAccount.AccountID)

    {

        ttsBegin;

        custTable.BankAccount = custBankAccount.AccountID;  

        custTable.update();

        ttsCommit;

    }  

}

ttsCommit;


Create customer address using x++ d365fo

DirParty                        dirParty;

LogisticsPostalAddress          logisticsPostalAddress;

DirPartyPostalAddressView       partyPostalAddressView;

ttsBegin;

DirPartyPostalAddressView       dirPartyPostalAddressView;

LogisticsAddressStreet          street;

street = 'test';

dirParty = DirParty::constructFromCommon(custTable::find('test001'));

logisticsLocation.clear();

logisticsLocation.Description      = 'Primary Business Address';

logisticsLocation.IsPostalAddress  = true;

logisticsLocation.LocationId       = 'LOC-1001';

logisticsLocation.insert();

logisticsPostalAddress = LogisticsPostalAddress::findByLocation(logisticsLocation.RecId, true);

if (!logisticsPostalAddress.RecId)

{

    logisticsPostalAddress.clear();

}

logisticsPostalAddress.CountryRegionId  = 'US';

logisticsPostalAddress.State            = 'CA';

logisticsPostalAddress.County           = 'Santa Clara';

logisticsPostalAddress.City             = 'San Jose';

logisticsPostalAddress.ZipCode          = '95112';

logisticsPostalAddress.DistrictName     = 'Downtown';

logisticsPostalAddress.Street           = '1234 Market Street';

logisticsPostalAddress.Location         = logisticsLocation.RecId;


dirPartyPostalAddressView.initFromPostalAddress(logisticsPostalAddress);

dirPartyPostalAddressView.LocationName  = 'Headquarters Address';

dirPartyPostalAddressView.Party         = custTable.Party;

dirPartyPostalAddressView.IsPrimary     = NoYes::Yes;

dirPartyPostalAddressView.ProArIsCreatedByIntegration = true;

container roles;

roles = [LogisticsLocationRole::findByName('Business').RecId];

partyPostalAddressView = DirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView, roles);

ttsCommit;


Create customer using x++ d365fo

CustName     name;

DirParty     dirParty;

ttsbegin;

custTable.clear();

custTable.initValue();

custTable.AccountNum                    = 'CUST-001';

name                                                 = 'Contoso Retailer';

custTable.InvoiceAccount                = 'CUST-INV-001';

custTable.CustGroup                     = 'CUSTGROUP1';

custTable.PartyCountry                  = 'US';

custTable.Currency                      = 'USD';

custTable.CustClassificationId          = 'CLASS-001';

custTable.TaxGroup                      = 'TAXGRP01';

custTable.TaxWithholdCalculate_TH       = NoYes::Yes;

custTable.TaxWithholdGroup_TH           = 'WITHHOLD-GRP1';

custTable.PaymTermId                    = 'NET30';

custTable.PaymMode                      = 'BANK';

custTable.InclTax                       = NoYes::No;

custTable.CredManAccountStatusId        = 'ACTIVE';

custTable.Blocked                       = CustVendorBlocked::No;

custTable.DefaultDimension              = 878468543576;

if(custTable.validateWrite())

{

    DirPartyTable dirPartyTable; 

    if (!custTable.Party)

    {

    // Create a Party entry for customer

    dirPartyTable = DirPartyTable::createNew(DirPartyType::Organization, name);

    custTable.Party = dirPartyTable.RecId;

   }

   custTable.insert();

   dirParty = DirParty::constructFromCommon(custTable);

   dirParty.parmLanguageId('US-EN');

  if(dirParty)

 {

    dirParty.update();

 }

}

ttscommit;

Create contact person using x++ d365fo


    NumberSeq               numberSeq;

    ContactPersonSyncEntity contactPersonEntity;

    container               roleContainer;

    // Generate new Contact Person ID

    ttsbegin;

    numberSeq                        = NumberSeq::newGetNum(ContactPerson::numRefContactPersonId());

    contactPerson.ContactPersonId    = numberSeq.num();

    numberSeq.used();

    ttscommit;

    // Create Contact Person record

    ttsbegin;

    contactPerson.CustAccount        = 'Test001';

    contactPersonEntity              = ContactPersonSyncEntity::construct(contactPerson);

    contactPersonEntity.parmContactPersonId(contactPerson.ContactPersonId);

    contactPersonEntity.parmFirstName("FirstName");

    contactPersonEntity.parmLastName('Last name');

    contactPersonEntity.parmLanguageId('US-EN');

    contactPersonEntity.write();

    ttscommit;

//  create postal address for contact person

DirPartyPostalAddressView       postalAddressView;

LogisticsPostalAddress          logisticsPostalAddress;

LogisticsLocation               logisticsLocation;

LogisticsAddressStreet          street;

DirParty                        dirParty = DirParty::constructFromCommon(contactPerson);

DirPartyLocation                dirPartyLocation;

boolean                         ret = true;

DirPartyPostalAddressView       partyPostalAddressView;

ttsbegin;

logisticsLocation.clear();

logisticsLocation.Description = 'test desc';

logisticsLocation.IsPostalAddress = true;

logisticsLocation.LocationId = '001234';

logisticsLocation.insert();

logisticsPostalAddress =  LogisticsPostalAddress::findByLocation(logisticsLocation.RecId, true);


if(!logisticsPostalAddress.RecId)

{

    logisticsPostalAddress.clear();

}

        

logisticsPostalAddress.CountryRegionId  = 'US';

logisticsPostalAddress.State            = 'Test state';

logisticsPostalAddress.County           = 'US';

logisticsPostalAddress.City             = 'test city';

logisticsPostalAddress.ZipCode          = '989238';

logisticsPostalAddress.Street           = 'test street';

logisticsPostalAddress.Location         = logisticsLocation.RecId;


postalAddressView.initFromPostalAddress(logisticsPostalAddress);

postalAddressView.LocationName  = 'Business';

postalAddressView.Party         = contactPerson.Party;

postalAddressView.IsPrimary     = true;

postalAddressView.ProArIsCreatedByIntegration = true;

partyPostalAddressView = DirParty.createOrUpdatePostalAddress(postalAddressView,LogisticsLocationRole::findByName('Business').RecId);

ttscommit;



Monday, August 18, 2025

Mark invoice transaction to ledger journal transaction using x++ D365fo

public void markTransaction(LedgerJournalTrans _journalTrans)

{

    CustTransOpen                          custTransOpen;

    CustTrans                                   custTrans;

    CustVendOpenTransManager     manager          = CustVendOpenTransManager::construct(_journalTrans);

    SpecTransManager                     specTransManager = manager.parmSpecTransManager();

    AmountCur                                unmarkedAmount;

    // 🔹 Find the matching CustTrans record

    select firstonly custTrans

        where custTrans.Invoice    == _journalTrans.MarkedInvoice  // Probably should map to invoice reference

              && custTrans.AccountNum == 'Test001';        // Replace hardcode with _journalTrans.CustomerAccount if possible

    // 🔹 Find the open transaction for settlement

    custTransOpen = CustTransOpen::findRefId(custTrans.RecId);

    // 🔹 Check unmarked amount for this transaction

    unmarkedAmount = specTransManager.findUnmarkedAmountForRef(custTransOpen.AmountCur,

                        custTransOpen.company(),custTransOpen.TableId,custTransOpen.RecId);

    if (unmarkedAmount <= 0)

    {

        warning("Nothing left to settle for this transaction.");

    }

    // 🔹 Ensure not already marked by another specTrans

    if (!manager.checkTransFullyMarkedByOtherSpec(custTransOpen))

    {

        manager.updateTransMarked(custTransOpen, NoYes::Yes);

        manager.updateSettleAmountPaymCur(custTransOpen, custTransOpen.AmountCur);

    }

    ttsbegin;

    _journalTrans.selectForUpdate(true);

    _journalTrans.MarkedInvoice = custTrans.Invoice;

    _journalTrans.SettleVoucher = SettlementType::SelectedTransact;

    _journalTrans.doUpdate();

    ttscommit;

}


Create customer payment journal using x++ d365fo

// Table buffers

LedgerJournalTable   journalTable;

LedgerJournalName    journalName  = LedgerJournalName::find("custPaym");

CustTable            custTable    = CustTable::find('Test001');

CustPaymModeTable    paymModeTable = CustPaymModeTable::find('Test');

LedgerJournalTrans   journalTrans;

NumberSeq            numberSeq;

DimensionDefault     defDimension  = 0;

ExchangeRateHelper   exchangeRateHelper;

LedgerRecId          ledgerRecIdLocal;

ExchangeRateHelper   exchangeRateHelperRep;


// Generate Journal ID

JournalNum journalNum = JournalTableData::newTable(journalTable).nextJournalId();

// Initialize Journal header

journalTable.clear();

journalTable.JournalNum  = journalNum;

journalTable.JournalName = "custPaym";

// Populate from journal name setup

journalTable.initFromLedgerJournalName(journalTable.JournalName);

journalTable.Name = journalName.Name;

// Insert Journal header

if (journalTable.validateWrite())

{

    journalTable.doInsert();

}

// Prepare NumberSeq for voucher

numberSeq = NumberSeq::newGetVoucherFromId(journalName.NumberSequenceTable);

// Initialize Journal line

journalTrans.initValue();

journalTrans.initFromLedgerJournalTable_LT(journalTable);

journalTrans.JournalNum   = journalTable.JournalNum;

journalTrans.Voucher      = numberSeq.voucher();

numberSeq.used();

journalTrans.AccountType      = LedgerJournalACType::Cust;

journalTrans.TransactionType  = LedgerTransType::Payment;

// Customer dynamic account (ledger dimension)

DimensionDynamicAccount dynAccount = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(

                                        custTable.AccountNum,

                                        journalTrans.AccountType);

journalTrans.LedgerDimension  = DimensionAttributeValueCombination::find(dynAccount).RecId;

journalTrans.initFromCustTable(custTable, false);

// Default dimensions merge

journalTrans.DefaultDimension = DimensionDefaultFacade::serviceMergeDefaultDimensions(

                                    defDimension,

                                    custTable.DefaultDimension);

// Dates

journalTrans.TransDate     = str2Date('09/01/2025', 123);   // Date in system format

journalTrans.DocumentDate  = str2Date('09/01/2025', 123);

journalTrans.Due           = journalTrans.TransDate;

// Document details

journalTrans.DocumentNum   = 'Test1';

journalTrans.AmountCurCredit = 200;

journalTrans.AmountCurDebit  = 0;

journalTrans.CurrencyCode    = 'USD';

journalTrans.Company         = 'USMF';

journalTrans.Txt             = "testing01";

// Approval details

journalTrans.AcknowledgementDate = DateTimeUtil::date(DateTimeUtil::getSystemDateTime());

journalTrans.PaymMode            = paymModeTable.PaymMode;

journalTrans.PaymReference       = 'Test123';

journalTrans.Approved            = NoYes::Yes;

journalTrans.Approver            = HcmWorker::userId2Worker(curUserId());

// Offset account

journalTrans.OffsetAccountType     = LedgerJournalACType::Ledger;

journalTrans.OffsetLedgerDimension = LedgerDimensionFacade::serviceCreateLedgerDimension(

                                         paymModeTable.PaymentLedgerDimension,

                                         journalTrans.DefaultDimension);

// Line number

journalTrans.LineNum = LedgerJournalTrans::lastLineNum(journalTrans.JournalNum) + 1;

// Exchange rate

exchangeRateHelper = ExchangeRateHelper::newCurrency(

                         Ledger::primaryLedger(CompanyInfo::findDataArea(journalTrans.Company).RecId),

                         journalTrans.CurrencyCode);

journalTrans.ExchRate = ExchangeRateHelper::exchRate(

                            journalTrans.CurrencyCode,

                            journalTrans.TransDate);

// Ledger dimension name

journalTrans.LedgerDimensionName = LedgerJournalTransLedgerDimensionNameHelper::findName(

                                       journalTrans.Company,

                                       journalTrans.AccountType,

                                       journalTrans.LedgerDimension);

// Tax withholding check

if (TaxThaiGovCertificationFeatureChecker::isTaxWithholdEnabled())

{

    journalTrans.TaxWithholdGroup = custTable.getTaxWithholdGroup();

}

else

{

    journalTrans.TaxWithholdGroup = custTable.TaxWithholdGroup_TH;

}

journalTrans.TaxWithholdCalculate_TH = custTable.TaxWithholdCalculate_TH;

// Reporting currency exchange rate

ledgerRecIdLocal = Ledger::primaryLedger(CompanyInfo::findDataArea(journalTrans.company()).RecId);

exchangeRateHelperRep = ExchangeRateHelper::newExchangeDate(

                            ledgerRecIdLocal,

                            journalTrans.CurrencyCode,

                            journalTrans.TransDate);

exchangeRateHelperRep.parmToCurrency(Ledger::reportingCurrency());

exchangeRateHelperRep.parmExchangeRateTypeRecId(Ledger::reportingCurrencyExchangeRateType());

journalTrans.ReportingCurrencyExchRate          = exchangeRateHelperRep.getExchangeRate1();

journalTrans.ReportingCurrencyExchRateSecondary = exchangeRateHelperRep.getExchangeRate2();

// Final insert

if (journalTrans.validateWrite())

{

    journalTrans.doInsert();

}


Get dynamic account number for customer or vendor account using x++ d365fo

 DimensionDynamicAccount dynAccount      = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber("Test001",LedgerJournalACType::Cust/LedgerJournalACType::Vend);

Recid ledgerDimension = DimensionAttributeValueCombination::find(dynAccount).RecId;



Create customer group using x++ d365fo

custGroup CustGroup ;

custGroup .initValue();

custGroup.CustGroup = 'TestGroup';        

custGroup.Name      = 'Test'; 

if(custGroup.validateWrite())

{

  custGroup.insert();

}

Create SalesTable (Header) and SalesLine (Line) in X++ D365FO

SalesTable   salesTable;

SalesLine    salesLine;

CustTable    custTable=  custTable::find("Test123"); // assume populated earlier

InventTable  inventTable; // assume populated earlier


// Generate SalesId using number sequence

NumberSeq num      = NumberSeq::newGetNum(NumberSeqReference::findReference(extendedTypeNum(ProArSalesId)));

SalesId   salesId  = num.num();


salesTable.initValue();

salesTable.SalesId      = salesId;  // Assign generated SalesId

num.used();                         // Mark number sequence as consumed


// Initialize header values from customer

salesTable.CustAccount  = custTable.AccountNum;

salesTable.initFromCustTable();


// Payment and currency settings

salesTable.PaymMode     = CustPaymModeTable::find("Test").PaymMode;

salesTable.CurrencyCode = 'USD';

salesTable.LanguageId   = '';


// Dates

salesTable.ShippingDateRequested = today();

salesTable.ReceiptDateRequested  = today();

salesTable.DeliveryDate          = salesTable.ShippingDateRequested;


// Intercompany fields

salesTable.InterCompanyOrder                 = NoYes::No;

salesTable.InterCompanyCompanyId             = '';

salesTable.InterCompanyAutoCreateOrders      = NoYes::No;

salesTable.InterCompanyDirectDelivery        = NoYes::No;

salesTable.InterCompanyAllowIndirectCreation = NoYes::No;


// Dimensions

salesTable.DefaultDimension = DimensionDefaultFacade::serviceMergeDefaultDimensions( 34556578437,custTable.DefaultDimension);

// Taxes

salesTable.TaxGroup = "";

// Source document header

SourceDocumentHeader sourceDocumentHeader;

sourceDocumentHeader.TypeEnumName     = enumStr(SourceDocument_ProductSale);

sourceDocumentHeader.TypeEnumValue    = SourceDocument_ProductSale::SalesOrder;

sourceDocumentHeader.AccountingStatus = SourceDocumentAccountingStatus::InProcess;

salesTable.SourceDocumentHeader = SourceDocumentHeader::createSourceDocumentHeader(tableNum(SalesTable),

                                      sourceDocumentHeader);

// Validate and insert SalesTable

if (salesTable.validateWrite())

{

    salesTable.insert();

}

// ----------------------------------------------------------------------

// Create SalesLine

// ----------------------------------------------------------------------


InventDim               inventDim, inventDimSales;

InventTableModule       salesTableModule        = InventTableModule::find(inventTable.ItemId, ModuleInventPurchSales::Sales);

InventItemOrderSetupMap inventItemOrderSetupMap = InventItemOrderSetupMap::findDefault(

                                                      inventTable.ItemId,

                                                      InventItemOrderSetupMap::module2SetupType(ModuleInventPurchSales::Sales));


// Build inventDim

inventDim.InventSiteId     = salesTableModule.inventSiteId()     ? salesTableModule.inventSiteId()     : inventItemOrderSetupMap.inventSiteId();

inventDim.InventLocationId = salesTableModule.inventLocationId() ? salesTableModule.inventLocationId() : inventItemOrderSetupMap.inventLocationId();

inventDimSales = InventDim::findOrCreate(inventDim);

salesLine.clear();

salesLine.initValue(salesTable.SalesType);

salesLine.initFromSalesTable(salesTable);


// Line-specific details

salesLine.TaxWithholdGroup = TaxWithholdGroupHeading::find("");

salesLine.ItemId           = inventTable.ItemId;

salesLine.Name             = InventTable::name(inventTable.ItemId);

salesLine.TaxItemGroup     = salesTableModule.TaxItemGroupId;


// Line number

salesLine.LineNum                    = SalesLine::lastLineNum(salesLine.SalesId) + 1.0;

salesLine.LineCreationSequenceNumber = real2int(salesLine.LineNum);


// InventTransId from number sequence

salesLine.InventTransId              = NumberSeq::newGetNum(InventParameters::numRefInventTransId()).num();


// Dimensions

salesLine.TaxWithholdItemGroupHeading_ = salesTableModule.TaxWithholdItemGroupHeading_TH;

salesLine.InventDimId                  = inventDimSales.InventDimId;

salesLine.SalesUnit                    = salesTableModule.UnitId;


// Barcode lookup

InventItemBarcode inventItemBarcode = InventItemBarcode::findSalesBarcodeDimension( salesLine.ItemId,

                                          salesLine.inventDim(), '',salesLine.SalesUnit);

if (inventItemBarcode.RecId)

{

    salesLine.BarCode     = inventItemBarcode.ItemBarCode;

    salesLine.BarCodeType = inventItemBarcode.BarcodeSetupId;

}

// Pricing and quantities

salesLine.PriceUnit         = salesTableModule.PriceUnit;

salesLine.SalesPrice        = 90;

salesLine.SalesQty          = 5;

salesLine.DefaultDimension  = DimensionDefaultFacade::serviceMergeDefaultDimensions(3466899223,

                                  custTable.DefaultDimension,inventTable.DefaultDimension);

salesLine.RemainSalesPhysical = salesLine.SalesQty;

salesLine.LineAmount          = salesLine.calcLineAmount();

salesLine.RevRecContractStartDate = today();

salesLine.TaxGroup            = '';

// Source document line

SourceDocumentLine sourceDocumentLine;

sourceDocumentLine.SourceDocumentHeader = salesLine.salesTable().SourceDocumentHeader;

sourceDocumentLine.TypeEnumName         = enumStr(SourceDocumentLine_ProductSale);

sourceDocumentLine.TypeEnumValue        = SourceDocumentLine_ProductSale::SalesOrderLine;

sourceDocumentLine.AccountingStatus     = SourceDocumentLineAccountingStatus::Draft;


// Insert SalesLine

ttsBegin;

salesLine.SourceDocumentLine = SourceDocumentLine::createSourceDocumentLine(tableNum(SalesLine),  sourceDocumentLine);

salesLine.doInsert();

ttsCommit;



Post sales order invoice using x++ D365fo


    SalesFormLetter salesFormLetter;

   SalesTable salesTable = SalesTable ::Find('Test001');

    salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice);

    salesFormLetter.reArrangeNow(false);

    salesFormLetter.transDate(today());

    salesFormLetter.proforma(false);

    salesFormLetter.specQty(salesUpdate::All);

    salesFormLetter.salesTable(salesTable);

    salesFormLetter.run();


Sunday, August 17, 2025

Confirm sales order using x++ d365fo

SalesFormLetter salesFormLetter;

SysQueryRun     queryRun;

Query           query;

salesFormLetter = SalesFormLetter::construct(DocumentStatus::Confirmation);

salesFormLetter.reArrangeNow(false);

query = new Query(QueryStr(SalesUpdate));

query.dataSourceTable(tableNum(SalesTable)).addRange(fieldNum(SalesTable, SalesId)).value(queryValue("Test001"));

queryRun = new SysQueryRun(query);

salesFormLetter.chooseLinesQuery(queryRun);

salesFormLetter.transDate(today());

salesFormLetter.specQty(SalesUpdate::All);

salesFormLetter.printFormLetter(false);

salesFormLetter.chooseLines();

salesFormLetter.run();


Wednesday, August 13, 2025

create multi select look up on vendor parameter form control using x++ d365fo

[ExtensionOf(formStr(VendParameters))]

final class VendParameters_Extension

{

    public SysLookupMultiSelectCtrl msCtrl;

    public void init()

    {

        FormStringControl formStringControl;

        formStringControl = this.design().controlName(formControlStr(VendParameters, VendParameters_multiselect) );

        this.multiselectLookup(formStringControl);

    }

    public SysLookupMultiSelectCtrl parmMultiselect(SysLookupMultiSelectCtrl _msCtrl = msCtrl)

    {

        msCtrl = _msCtrl;

        return msCtrl;

    }

    public void multiselectLookup(FormStringControl _multiselectControl)

    {

        Query query = new Query();

        QueryBuildDataSource qbds;


        query.allowCrossCompany(true);

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

        qbds.fields().addField(fieldNum(JournalName, Name));

        qbds.orderMode(OrderMode::GroupBy);

        qbds.addSortField(fieldNum(JournalName, Name));


        msCtrl = SysLookupMultiSelectCtrl::constructWithQuery(this,  _multiselectControl, query );

        this.parmMultiselect(msCtrl);

    }

}

public class VendParametersFormDSEventHandler

{

    [FormDataFieldEventHandler( formDataFieldStr(VendParameters, VendParameters, VendParameters_multiselect),

        FormDataFieldEventType::Modified )]

    public static void VendParameters_multiselect_OnModified(FormDataObject sender, FormDataFieldEventArgs e)

    {

        FormRun formRun = sender.dataSource().formRun();

        SysLookupMultiSelectCtrl msCtrl = formRun.parmMultiselect();

        VendParameters vendParameters = formRun.dataSource(formDataSourceStr(VendParameters, VendParameters)).cursor();

        vendParameters.multiselect = con2Str(msCtrl.getSelectedFieldValues(), ";");

    }

}


Create general journal using x++ D365FO

 LedgerJournalTable ledgerJournalTable ;

LedgerJournalTrans ledgerJournalTrans;

ledgerJournalTable .JournalName = "WriteOff";

ledgerJournalTable .defaultRow();

if (ledgerJournalTable .validateWrite())

{

    ledgerJournalTable .insert();

}

LedgerJournalEngine ledgerJournalEngine = LedgerJournalEngine_Daily::construct();

ledgerJournalEngine.ledgerJournalTable(ledgerJournalTable );

ledgerJournalEngine.newJournalActive(ledgerJournalTable );

ledgerJournalTrans.clear();

ledgerJournalEngine.preCreate(ledgerJournalTrans);

ledgerJournalTrans.initValue();

ledgerJournalEngine.initValue(ledgerJournalTrans);

ledgerJournalTrans.LineNum = 0;

ledgerJournalTrans.TransactionType   = LedgerTransType::WriteOff;

ledgerJournalTrans.TransDate         = DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());

ledgerJournalTrans.AccountType       = LedgerJournalACType::Ledger;

ledgerJournalTrans.LedgerDimension   = 0;

ledgerJournalTrans.DefaultDimension  = 0;

ledgerJournalEngine.accountModified(ledgerJournalTrans);

ledgerJournalTrans.CurrencyCode = 'USD';

ledgerJournalEngine.currencyModified(ledgerJournalTrans);

ledgerJournalTrans.amountCur2DebCred(200);

reasonTable = ReasonTable::find("Test");

ledgerJournalTrans.ReasonRefRecID = ReasonTableRef::createReasonTableRef(reasonTable.Reason, reasonTable.Description);

ledgerJournalTrans.Txt = "Test"; 

ledgerJournalTrans.SkipBlockedForManualEntryCheck = NoYes::Yes;

// Set the offset account type

ledgerJournalTrans.OffsetAccountType     = LedgerJournalACType::Ledger;

ledgerJournalTrans.OffsetLedgerDimension = 0;

ledgerJournalTrans.OffsetDefaultDimension = ledgerJournalTrans.DefaultDimension;

ledgerJournalEngine.offsetAccountModified(ledgerJournalTrans);

ledgerJournalTrans.TaxGroup       = '';

ledgerJournalTrans.TaxItemGroup   = '';

ledgerJournalTrans.PaymMode       = '';

ledgerJournalTrans.PaymSpec       = '';

ledgerJournalTrans.Prepayment     = 0;

ledgerJournalTrans.BankTransType  = '';

ledgerJournalTrans.TransactionType         = LedgerTransType::GeneralJournal;

ledgerJournalTrans.insert();

ledgerJournalEngine.voucherTotals(ledgerJournalTrans, true);

// post journal

LedgerJournalCheckPost ledgerJournalCheckPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJournalTable, NoYes::Yes,NoYes::Yes );

ledgerJournalCheckPost.run();


get current global error text using x++ D365fo

 public static str getError()

{

    SysInfologEnumerator      sysInfologEnumerator;

    SysInfologMessageStruct   infoMessageStruct;

    str                       logMessage;

    str                       logString;

    int                       i;

    #Define.NewLine('\n')

    sysInfologEnumerator = SysInfologEnumerator::newData(infolog.infologData());

    while (sysInfologEnumerator.moveNext())

    {

        i = 1;

        if (logMessage)

        {

            logMessage += #NewLine;

        }

        infoMessageStruct = SysInfologMessageStruct::construct(sysInfologEnumerator.currentMessage());

        while (i <= infoMessageStruct.prefixDepth())

        {

            logString += infoMessageStruct.preFixTextElement(i) + '. ';

            i++;

        }

        logString += infoMessageStruct.message();

        logMessage += infoMessageStruct.message();

    }

    infolog().clear();

    return logMessage;

}


Call API using x++ D365FO

 System.Net.HttpWebRequest    request; System.Net.HttpWebResponse   response; System.IO.Stream             dataStream; System.IO.StreamReade...