Describe the issue
Exploding a BOM (Codeunit "Sales-Explode BOM") on a sales line for a customer that invoices in a foreign currency fails with a Sales Line "does not exist" runtime error.
Table 8068 "Sales Subscription Line" caches the originating sales line in the global variable SalesLine (set via SetSalesLine before the sales line itself is inserted, during BOM explosion in Codeunit 8069 "Sales Subscription Line Mgmt."). However, local procedure GetDate(): Date performed a hard SalesLine.Get(Rec."Document Type", Rec."Document No.", Rec."Document Line No.") instead of reusing the existing GetSalesLine(var SalesLine2: Record "Sales Line") caching helper (which falls back to Get() only when the cached line doesn't match).
GetDate() is invoked from the Unit Cost (LCY) field's OnValidate trigger, which fires while the sales line still only exists in memory (not yet inserted). For FCY customers this validation path is triggered, so the hard Get() fails. Non-FCY customers don't hit this code path, which is why the defect only reproduces with a foreign currency.
Expected behavior
BOM explosion on a sales line for a foreign-currency customer should succeed and create the corresponding "Sales Subscription Line" records without errors, the same as it does for LCY customers.
Steps to reproduce
- Create a customer with a foreign currency (
Currency Code <> '').
- Create an item with
Replenishment System = Assembly (BOM), where the BOM component has a Subscription Package/Service Commitment assigned.
- Create a sales order line for that customer/item.
- Run
Codeunit::"Sales-Explode BOM" on the sales line (for example, via the Explode BOM action, or programmatically).
- Observe the error:
Sales Line does not exist.
Additional context
Root cause: Table 8068 "Sales Subscription Line" → local procedure GetDate(): Date called SalesLine.Get(Rec."Document Type", Rec."Document No.", Rec."Document Line No.") directly instead of GetSalesLine(SalesLine).
Fix: replace the direct Get() call in GetDate() with GetSalesLine(SalesLine), which reuses the in-memory cached sales line set via SetSalesLine during BOM explosion when it matches, and only falls back to Get() otherwise. This is consistent with every other call site in this table (CalculateUnitCost, CalculateServiceAmount, CalculateCalculationBaseAmount, CreateVATAmountLineForSalesSubscriptionLine).
I will provide a fix for a bug
Describe the issue
Exploding a BOM (Codeunit
"Sales-Explode BOM") on a sales line for a customer that invoices in a foreign currency fails with a Sales Line"does not exist"runtime error.Table 8068
"Sales Subscription Line"caches the originating sales line in the global variableSalesLine(set viaSetSalesLinebefore the sales line itself is inserted, during BOM explosion in Codeunit 8069"Sales Subscription Line Mgmt."). However, local procedureGetDate(): Dateperformed a hardSalesLine.Get(Rec."Document Type", Rec."Document No.", Rec."Document Line No.")instead of reusing the existingGetSalesLine(var SalesLine2: Record "Sales Line")caching helper (which falls back toGet()only when the cached line doesn't match).GetDate()is invoked from theUnit Cost (LCY)field'sOnValidatetrigger, which fires while the sales line still only exists in memory (not yet inserted). For FCY customers this validation path is triggered, so the hardGet()fails. Non-FCY customers don't hit this code path, which is why the defect only reproduces with a foreign currency.Expected behavior
BOM explosion on a sales line for a foreign-currency customer should succeed and create the corresponding
"Sales Subscription Line"records without errors, the same as it does for LCY customers.Steps to reproduce
Currency Code <> '').Replenishment System = Assembly (BOM), where the BOM component has a Subscription Package/Service Commitment assigned.Codeunit::"Sales-Explode BOM"on the sales line (for example, via theExplode BOMaction, or programmatically).Sales Line does not exist.Additional context
Root cause: Table 8068
"Sales Subscription Line"→ local procedureGetDate(): DatecalledSalesLine.Get(Rec."Document Type", Rec."Document No.", Rec."Document Line No.")directly instead ofGetSalesLine(SalesLine).Fix: replace the direct
Get()call inGetDate()withGetSalesLine(SalesLine), which reuses the in-memory cached sales line set viaSetSalesLineduring BOM explosion when it matches, and only falls back toGet()otherwise. This is consistent with every other call site in this table (CalculateUnitCost,CalculateServiceAmount,CalculateCalculationBaseAmount,CreateVATAmountLineForSalesSubscriptionLine).I will provide a fix for a bug