Thursday, December 7, 2023

Code to update data for custom fields in SubBillScheduleLine lines which are created from milestone allocation in D365 f&o X++

[Extensionof(tableStr(SubBillScheduleLine))]

internal final class DaxSubBillScheduleLine_Extension

{

   public void recreateMilestoneSubItems(SubBillMilestoneAllocationHeader _milestoneAllocationHeader)

   {

       SubBillScheduleLine milestoneSubLine;

       SubBillMilestoneAllocationLine  allocationLine;

       while select allocationLine

           where allocationLine.SubBillSchedLineRecId == _milestoneAllocationHeader.SubBillSchedLineRecId

       {

           select forupdate milestoneSubLine

               where milestoneSubLine.RecId == allocationLine.SubBillSchedLineRecId;

           ttsbegin;

           milestoneSubLine.DaxEnum = DaxEnum::Advanced; //custom field

           milestoneSubLine.update();

           ttscommit;

       }

       next recreateMilestoneSubItems(_milestoneAllocationHeader);

   }

   public void insert()

   {

       SubBillScheduleLine milestoneSubLine;

       select milestoneSubLine

           where milestoneSubLine.SubBillMilestoneHeaderRecId == this.SubBillMilestoneHeaderRecId;

       this.DaxStatus = milestoneSubLine.DaxStatus; //custom field

       next insert();

   }

}

..............

Subsription billing > All Billing Schedules

Create a header and line and click on Milestone Allocation.




Lines from milestone will be created in SubBillScheduleLines. And custom fields will be updated.







Monday, November 27, 2023

Code to Populate Custom field data from PurchTable to VendInvoiceJour in D365 f&o X++

[ExtensionOf(tableStr(VendInvoiceJour))]

public final class DaxVendInvoiceJour_Extension

{

   public void insert()

   {

       PurchTable      purchTable = PurchTable::find(this.PurchId);

       this.Dax_Remarks = purchTable.Dax_Remarks;

       next insert();

   }

}

...............

OtherWay:

[ExtensionOf(classStr(FormletterService))]

 internal final class DaxFormLetterServiceClass_Extension

 {

    protected void processJournal(Printout _printout)

    {

         VendInvoiceJour         vendInvoiceJourlocal;

         PurchTable              purchTable;

         next processJournal(_printout);

        select forupdate vendInvoiceJourlocal 

            join purchTable

                where vendInvoiceJourlocal.ParmId == parmId

                && vendInvoiceJourlocal.purchId == purchTable.purchId;

        ttsbegin;

        vendInvoiceJourlocal.Dax_Remarks = purchTable.Dax_Remarks; // custom field

        vendInvoiceJourlocal.update();

        ttscommit;

     }

 }

.........................

Other Way :

[ExtensionOf(classStr(PurchFormLetter_Invoice))]

internal final class DaxPurchFormLetter_Invoice_Extension

{

   protected void runRemainUpdates()

   {

       VendInvoiceJour     vendInvoiceJour;

       PurchTable          purchTable;

       str parmid = this.parmId();

       next runRemainUpdates();

       select forupdate vendInvoiceJour

           where vendInvoiceJour.ParmId == parmid;

       purchTable = PurchTable::find(vendInvoiceJour.PurchId);

       ttsbegin;

       vendInvoiceJour.Dax_Remarks = purchTable.Dax_Remarks;

       vendInvoiceJour.update();

       ttscommit;

   }

}

Output :


    





How to make grid empty based on conditions in D365 f&o X++

 I have grid with purchline datasource.

If the location is empty . Then grid should be empty.(no records in gird)

If the location has some range. then range should be applied on grid.


 QueryBuildDataSource            qbdspurch;

 QueryBuildRange                       qbr;

if(this.daxlocation)

{

                 qbdspurch = this.query().dataSourceTable(tableNum(PurchLine));

                    qbr = qbdspurch.addRange(fieldNum(PurchLine, daxlocation));

                    qbr.value(this.daxlocation);

}

else

{

                     qbdspurch = this.query().dataSourceTable(tableNum(PurchLine));

                    qbr = qbdspurch.addRange(fieldNum(PurchLine, PurchId));

                    qbr.value(SysQuery::valueEmptyString()); //makes grid empty

}

reference blog:

https://daxingwitheshant.blogspot.com/2015/04/how-to-filter-gird-based-on-given-input.html

Monday, November 6, 2023

Code to create a Simple BatchJob with Records to include filter in D365F&O X++

/// <summary>

/// The <c>MCRFTCEventProcessBatch</c> class handles processing FTC events in batch.

/// </summary>

class MyBatchJobBatch extends RunBaseBatch implements BatchRetryable

{

   // Packed variables

   int                 dummy;

   // Dialog fields

   QueryRun                            projectQueryRun;

 

   #define.CurrentVersion(2)

   #localmacro.CurrentList

       dummy,

       startDate,

       endDate

   #endmacro

   /// <summary>

   /// Adds the <c>SalesID</c> to the dialog box

   /// allowing the user to run a batch over the selected

   /// <c>SalesID</c>.

   /// </summary>

   /// <returns>

   /// The dialog box box.

   /// </returns>

   public Object dialog()

   {

       DialogRunbase               dialog; 

       //Setup the dialog

       dialog = super();

       dialog.caption("Simple Batch Job");

       return dialog;

   }

   /// <summary>

   /// Retrieves the user entered values from dialog form.

   /// </summary>

   /// <returns>

   /// true if the values are retrieved successfully; otherwise, false.

   /// </returns>

   public boolean getFromDialog()

   {

       boolean ret;

       ret = super();

       return ret;

   }

   protected void initQuery()

   {

       QueryBuildDataSource qbds;

       Query                query = new Query();

 

       query.allowCrossCompany(true);

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

       projectQueryRun = new QueryRun(query);

   }

   protected void new()

   {

       super();

       this.initQuery();

   }

   public container pack()

   {

       return [#CurrentVersion, #CurrentList];

   }

   boolean prompt()

   {

       return super();

   }

   public QueryRun queryRun()

   {

       return projectQueryRun;

   }

   public boolean showQueryValues()

   {

       return true;

   }

   public boolean unpack(container packedClass)

   {

       Version version = runbase::getVersion(packedClass);

       switch (version)

       {

           case #CurrentVersion:

               [version, #CurrentList] = packedClass;

               break;

           default:

               return false;

       }

       return true;

   }

    public static MCRFTCEventProcessBatch construct()

   {

       return new MCRFTCEventProcessBatch();

   }

   public static ClassDescription description()

   {

       return "Simple Batch Job";

   }

   public static void main(Args args)

   {

       MyBatchJobBatch myBatchJobBatch = new myBatchJobBatch();

       myBatchJobBatch.parmInBatch(false);

 

       if (myBatchJobBatch.prompt())

           myBatchJobBatch.runOperation();

   }

 

   /// <summary>

   /// Describes whether the class is designed for execution in a new session.

   /// </summary>

   /// <returns>

   /// false.

   /// </returns>

   protected boolean canRunInNewSession()

   {

       return false;

   }

   /// <summary>

   /// Specifies if the batch task is retryable for transient exceptions or not.

   /// </summary>

   /// <returns>

   /// If true is returned, the batch task is retryable, otherwise it is not.

   /// </returns>

   [Hookable(false)]

   final boolean isRetryable()

   {

       return true;

   }

}

Output :







Tuesday, October 31, 2023

Code to populate data from BillingSchedule to SalesOrder for custom fields in D365 X++

 [Extensionof(classStr(SubBillCreateSalesOrder))]

internal final class DaxSubBillCreateSalesOrder_Extension

{

   public static SalesTable initSalesTable(

       SalesTable _salesTable,

       boolean _isInvoiceCreator,

       NumberSeq _numberSeq,

       SubBillSalesLineConsolidated _salesLineConsolidated,

       ParmId _curParmId)

   {

      

       SubBillScheduleTable    subBillScheduleTable;

 

       next initSalesTable(_salesTable,_isInvoiceCreator,_numberSeq,_salesLineConsolidated,_curParmId);

    

       select subBillScheduleTable

           where subBillScheduleTable.SubBillBillingScheduleNumber == _salesLineConsolidated.SubBillBillingScheduleNumber;

       _salesTable.DaxName = subBillScheduleTable.DaxName;

 

       return _salesTable;

   }

}

.........................

Output :

SB>All Billing Schedules


AR>All sales Orders






Friday, October 20, 2023

Code to create a AP invoice journal in D365F&O X++

public static void main(Args _args)

   {

       MCRLedgerJournal        journalTable;

       LedgerJournalTable      ledgerJournalTable;

       Counter                 recordsInserted;

        ttsbegin;

       //Creates the journal header table

       journalTable = new MCRLedgerJournal_VendInvoiceRegister(LedgerJournalType::VendInvoiceRegister,"APInvoice");

       ledgerJournalTable = journalTable.createLedgerJournalTable();

       journalTable.parmLedgerJournalTable(ledgerJournalTable);

       journalTable.parmMCRCCGeneralLedgerId();

       journalTable.parmCurrencyCode(CompanyInfoHelper::standardCurrency());

 

       // creates a new line in general journal

       journalTable.parmLineNum();

       journalTable.parmLedgerAccountType(LedgerJournalACType::Vend);

       journalTable.parmLedgerAccount(LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber("1001",LedgerJournalACType::Vend)); //You need to use the vendor account as per your environment's data.

       journalTable.parmTransDate(today());

       journalTable.parmTransTxt("Acquisition");

       journalTable.parmInvoice("123");

       journalTable.parmExchRate(0.00);

       journalTable.createLedgerJournalTrans(abs(0),abs(100),LedgerJournalACType::Vend);

       recordsInserted++;

       ttscommit;

       info(strFmt("Journal number %1 is created", ledgerJournalTable.JournalNum));

   }

 ...............


AP>Invoices>Invoice Journal





Friday, October 13, 2023

Code to get vendor Voucher transcations from Mainaccount in D365 X++

 My requirement is to get the vendor for main account transcations if the voucher is available.

        MainAccount                 mainAccount;

       GeneralJournalAccountEntry  generalJournalAccountEntry;

       GeneralJournalEntry         generalJournalEntry,generalJournalEntryloc;

       VendTrans                   vendTrans;

       while select generalJournalAccountEntry

           where generalJournalAccountEntry.MainAccount == mainAccount.RecId // get the current record of main account.

       {

           select generalJournalEntry

               where generalJournalEntry.RecId == generalJournalAccountEntry.GeneralJournalEntry;

 

           select vendTrans

               where vendTrans.Voucher == generalJournalEntry.SubledgerVoucher;

           if(vendTrans)

           {

               update_recordset generalJournalEntryloc

                       setting AccountNum = vendTrans.AccountNum

                   where generalJournalEntryloc.RecId == generalJournalEntry.RecId;

           }

       }

........................................................................................

Other Way :

[ExtensionOf(formDataSourceStr(LedgerTransAccount, GeneralJournalAccountEntry))]

internal final class DaxLedgerTransAccountForm_Extension

{

   public display VendAccount displayVendAccount(GeneralJournalAccountEntry _entry)

   {

       NoYes multipleTransWithinOneVoucher = LedgerParameters::find().AllowMultipleTransactionsWithinOneVoucher;

       VendTable vendorTable = this.findVendTable(_entry);

       VendAccount vendAccounts = vendorTable.AccountNum;

 

       if (multipleTransWithinOneVoucher == NoYes::Yes && vendorTable)

       {

           vendorTable = this.findVendTableWithGeneralJournalEntry(vendAccounts, _entry);

 

           if (vendorTable)

           {

               vendAccounts += "@GeneralLedger:LedgerTransVoucherCustVendMultiple";

           }

        }

       return vendAccounts;

   }

   private VendTable findVendTable(GeneralJournalAccountEntry _entry)

   {

       VendTable vendorTable;

       VendTrans vendTrans;

       GeneralJournalEntry vendGeneralJournalEntry;

       LedgerJournalVoucherChanged ledgerJournalVoucherChanged;

       LedgerJournalVoucherChanged ledgerJournalAndApprovalVoucherChanged;

           select firstonly AccountNum from vendorTable

               exists join vendGeneralJournalEntry

                   where vendGeneralJournalEntry.RecId == _entry.GeneralJournalEntry

               exists join vendTrans

                   where vendTrans.AccountNum == vendorTable.AccountNum

                       && vendGeneralJournalEntry.SubledgerVoucher == vendTrans.Voucher

                       && vendGeneralJournalEntry.SubledgerVoucherDataAreaId == vendTrans.DataAreaId;

 

       if (!vendorTable.AccountNum)

       {

           select firstonly AccountNum from vendorTable

                   exists join vendGeneralJournalEntry

                       where vendGeneralJournalEntry.RecId == _entry.GeneralJournalEntry

                   exists join ledgerJournalVoucherChanged

                       where ledgerJournalVoucherChanged.ToVoucher == vendGeneralJournalEntry.SubledgerVoucher

                           && ledgerJournalVoucherChanged.Todate == vendGeneralJournalEntry.AccountingDate

                   exists join vendTrans

                       where vendTrans.AccountNum == vendorTable.AccountNum

                           && ledgerJournalVoucherChanged.FromVoucher == vendTrans.Voucher

                           && ledgerJournalVoucherChanged.FromDate == vendTrans.TransDate

                           && vendGeneralJournalEntry.SubledgerVoucherDataAreaId == vendTrans.DataAreaId;

       }

       return vendorTable;

   }

   private VendTable findVendTableWithGeneralJournalEntry(VendAccount _vendAccounts, GeneralJournalAccountEntry _entry)

   {

       VendTable vendorTable;

       VendTrans vendTrans;

       GeneralJournalEntry vendGeneralJournalEntry;

           select firstonly AccountNum from vendorTable

                   exists join vendGeneralJournalEntry

                       where vendGeneralJournalEntry.RecId == _entry.GeneralJournalEntry

                   exists join vendTrans

                       where vendTrans.AccountNum == vendorTable.AccountNum

                           && vendGeneralJournalEntry.SubledgerVoucher == vendTrans.Voucher

                           && vendGeneralJournalEntry.SubledgerVoucherDataAreaId == vendTrans.DataAreaId

                           && vendorTable.AccountNum != _vendAccounts;

       return vendorTable;

   }

}


Output :

General Ledger >> Chart of Accounts >> Accounts >> Main Accounts

Click on the transactions

Account number data is from form init method

Vendor Account is from display method.