[Bug][SubscriptionBilling] Assign Subscription Lines dialog does not identify the sales line it was opened for - #10156
Conversation
…tion Lines and offer packages once per BOM component The Assign Subscription Lines page gave the user no way to tell which sales line it was opened for. With bundles the dialog appears several times in a row, so it is not clear which component the Subscription Packages are being offered for. Two separate causes: - Page 8065 declared no DataCaptionExpression, so the caption fell back to the Subscription Package code. It now shows the sales line "No." and Description, and raises OnAfterGetAssignSubscriptionLinesCaption so that extensions can supply their own context. When the page is opened from a Subscription Header the previous caption is kept unchanged. - During Sales-Explode BOM, AddSalesServiceCommitmentsForSalesLine ran twice per component: once from the Sales Line "No." validation trigger and once from OnExplodeBOMCompLinesOnAfterToSalesLineInsert. Two components therefore opened the dialog four times. The validation path is now skipped for the line that is currently being exploded, which the codeunit tracks by document type, document number and line number rather than by a plain flag, so that an error between the two events cannot suppress package assignment for every other sales line of the session. Consolidating onto the post-insert subscriber also removes a latent defect: the validation path inserted and committed Sales Subscription Lines against a Document Line No. whose sales line had not been inserted yet. Fixes microsoft#9965 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Agentic PR Review - Round 1Recommendation: AcceptWhat this PR doesThis PR makes page 8065 identify the sales line when subscription packages are assigned from a sales line. It also moves the BOM-explosion package offer to the post-insert event so each exploded component offers packages once, after the component line has its quantity. The fix matches the reported issue. DataCaptionExpression = GetCaption() uses the sales line number and description only when OpenedFromSalesLine is true, so the Subscription Header path falls back to the package code. The BOM change records the component line before "No." validation, skips the early validation path only for that exact line, clears the state at the post-insert subscriber, and then creates the subscription lines from the inserted sales line. The BaseApp publishers exist and fire in the expected order: OnExplodeBOMCompLinesOnAfterAssignType before "No." validation, and OnExplodeBOMCompLinesOnAfterToSalesLineInsert immediately after Insert(). SuggestionsNone. Risk assessment and necessityRisk: The changed area is sales document line creation for Subscription Billing, so a bad change could miss subscription lines or offer extra packages during BOM explosion. The new subscriber still runs before later BaseApp work such as auto-reservation and dimension copy, but the code uses the same existing modal path and now works from an inserted line with quantity set. The new integration event is additive and does not change existing public signatures. Necessity: The linked issue describes a real usability problem: several identical package dialogs can appear for BOM components with no item or description in the caption. The scope is targeted to page captioning and the duplicate BOM path, and the PR adds tests for caption behavior, one-off component dialogs, and creating another subscription line after BOM explosion.
|
Pull request was closed
What & why
The Assign Subscription Lines page gave the user no way to tell which sales line it was opened for. With bundles the dialog appears several times in a row, so it is not clear which component the Subscription Packages are being offered for.
Two separate causes:
Page 8065 declared no DataCaptionExpression, so the caption fell back to the Subscription Package code. It now shows the sales line "No." and Description, and raises OnAfterGetAssignSubscriptionLinesCaption so that extensions can supply their own context. When the page is opened from a Subscription Header the previous caption is kept unchanged.
During Sales-Explode BOM, AddSalesServiceCommitmentsForSalesLine ran twice per component: once from the Sales Line "No." validation trigger and once from OnExplodeBOMCompLinesOnAfterToSalesLineInsert. Two components therefore opened the dialog four times. The validation path is now skipped for the line that is currently being exploded, which the codeunit tracks by document type, document number and line number rather than by a plain flag, so that an error between the two events cannot suppress package assignment for every other sales line of the session.
Consolidating onto the post-insert subscriber also removes a latent defect: the validation path inserted and committed Sales Subscription Lines against a Document Line No. whose sales line had not been inserted yet.
Linked work
Fixes #9965
AB#650454
How I validated this
What I tested and the outcome (required — be specific: scenarios, commands, screenshots for UI changes)
Created two items and assigned a Subscription Package to each of them.
Created a BOM item and add both items to its BOM.
Created a sales order and add the bundle item on a sales line.
Run Functions > Explode BOM on that line, so the two component lines are inserted.
The Assign Subscription Lines dialog (page 8065 "Assign Service Commitments") opens twice, once per exploded component line.
Observed that both dialogs are distinguishable.
Risk & compatibility
Risk & compatibility
No schema, upgrade or permission impact. No tables, fields or keys were added or changed; nothing to migrate.
Behaviour changes reviewers should watch for:
Insert(), with the quantity set. Calculation base amounts are therefore derived from a complete sales line, where the first (pre-insert) offer saw a line without a quantity.Extensibility surface:
OnAfterGetAssignSubscriptionLinesCaption. Once shipped, its signature is a compatibility contract, so it is worth agreeing on the parameter set now. TheSubscriptionHeaderparameter is deliberate: it is the only context available on the path where the page is opened from a Subscription Header rather than a sales line.IsSalesLineBeingExplodedis new andinternal.Residual risk:
OnExplodeBOMCompLinesOnAfterAssignTypeandOnExplodeBOMCompLinesOnAfterToSalesLineInsert, the stored identity survives until the next explosion resets it onOnBeforeOnRun. To be affected, a subsequently created line would have to match that exact document and line number — explosion uses line numbers between existing lines, while new lines are appended.