SalesFormLetter salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice);
SalesParmLine parmLine;
SalesParmUpdate salesParmUpdate;
//A SalesTable that already exists with one line unposted
salesFormLetter.salesTable(initialSalesTable);
salesFormLetter.transDate(invoiceDate);
salesFormLetter.specQty(SalesUpdate::All);
salesFormLetter.proforma(false);
salesFormLetter.printFormLetter(false);
salesParmUpdate = salesFormLetter.salesParmUpdate();
//Passing a NumberSequenceGroup string to a Custom field in order to allocate Invoice and Voucher num from this later
salesParmUpdate.CustomNumberSequenceGroupId = numberSequenceGroup;
salesFormLetter.createParmUpdateFromParmUpdateRecord(salesParmUpdate);
salesFormLetter.initParmSalesTable(initialSalesTable);
salesFormLetter.initParameters(salesParmUpdate, Printout::After);
salesFormLetter.initLinesQuery();
//Remove lines of Sales Order that don't belong to this process
while select parmLine where parmLine.ParmId == salesFormLetter.parmId()
{
if(!someMap.exists(parmLine.SalesLineRecId))
{
parmLine.selectForUpdate(true);
parmLine.delete();
}
}
salesFormLetter.run();
Hi @Vasileios,
Thanks for sharing the detailed context — really helpful in understanding the issue.
Since the same logic works when triggered from the UI but fails in code, and given your suspicion about SalesParmUpdate
inconsistencies, a few things to consider:
CustomNumberSequenceGroupId
— try moving that assignment after initParameters()
and just before run()
to ensure it doesn’t get overwritten or ignored during parameter initialization.run()
, add a quick info()
or debug
log for salesFormLetter.salesParmUpdate().CustomNumberSequenceGroupId
to confirm the value is still correct at execution time.SalesParmUpdate
, SalesParmLine
, and related tables manually if you suspect corruption that the standard cleanup job didn’t catch.Also, I highly recommend checking out this article by Gaurav Gulati:
🔗 How to debug sandbox/UAT environment in D365FO
It walks you through how to attach a debugger to a sandbox/UAT environment — super helpful in scenarios like this when code behaves differently in non-dev tiers.
Let us know how it goes once you try these steps.
Martin Dráb
439
Most Valuable Professional
Abhilash Warrier
305
Saalim Ansari
261