Honour a deliberate 0% discount on Amount Type = Discount price list lines - #11070
Draft
attilatoury wants to merge 1 commit into
Draft
Honour a deliberate 0% discount on Amount Type = Discount price list lines#11070attilatoury wants to merge 1 commit into
attilatoury wants to merge 1 commit into
Conversation
…lines A variant- or currency-specific line with Line Discount % = 0 could never displace a less specific line, because the specificity reset was gated on the value being > 0. Gate it on the line declaring a discount instead, and let a declaring line take over a cleared best line so selection is order-independent. Fixes AB#649151
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
A variant- or currency-specific price list line with
Line Discount % = 0could never win over a less specific line, so there was no way to configure "no discount for this variant".In
PickBestLine, the specificity reset was gated on(AmountType <> AmountType::Discount) or (PriceListLine."Line Discount %" > 0). During discount calculationAmountTypeis always::Discount(passed as a literal fromCalcBestAmountviaApplyDiscount), so the effective gate was just"Line Discount %" > 0— a 0% line could never displace the generic one.The gate now asks whether the line declares a discount rather than whether the value is positive: an explicit
Amount Type = Discountline means the 0 was deliberate, while on anAmount Type = Anyline a 0 is indistinguishable from an unset field and is still ignored. That keeps #582311 working (anAnyline carrying a price with an untouched 0% discount must not wipe out a real discount).A second change lets a declaring line take over a cleared best line, so selection is order-independent. Without it the fix only worked when the generic line happened to be iterated first.
Blast radius is provably narrow.
DiscountIsDeclareddiffers from the old> 0test only whenAmount Type = Discountand the discount is0, and the new take-over clause can only fire whenIsBetterLineis false and the best line isn't real — which for discounts also means0. ForAmountType = Pricethe first clause of the gate is always true and the new clause always false, so the price path is unchanged.Old pricing (V15) already behaves correctly here —
PurchPriceCalcMgt.CalcBestLineDiscgives a specific line an unconditional win — so this also closes a V15 → V16 parity gap.Linked work
Fixes #
AB#649151
How I validated this
What I tested and the outcome
alcagainst a v30 dev instance: 0 errors, 635 warnings — all pre-existingAL0432/AL0684, none referencingPriceCalculationV16.30.0.54275.1), 257/257 apps installed cleanly.Discountline at 30% and a variant-specificDiscountline at 0%; a purchase line with that variant should show 0%, and switching the variant line toPrice & Discountshould return it to 30%.Four tests added to
TestPriceCalculationV16.Codeunit.al:PurchVariantZeroPctDiscountLineWinsOverGenericDiscountPurchVariantZeroPctDiscountLineWinsWhenAddedBeforeGenericDiscountSalesVariantZeroPctDiscountLineWinsOverGenericDiscountPurchCurrencyZeroPctDiscountLineWinsOverGenericDiscountCurrency Codespecificity, which shares the code pathThe three existing tests that pin the current behaviour were traced by hand against both iteration orders and remain satisfied, because all three use
"Price Amount Type"::Anyfor their spurious 0% line:DiscountPreservedWhenSpuriousZeroPctVariantLineExists,VariantSpecificDiscountOverridesHigherGenericDiscount,VariantDiscountSelectedWhenSpuriousZeroPctAndRealVariantDiscountExist.Risk & compatibility
Amount Type = Discountline sitting at 0% will see it start taking effect; today such lines are inert. This is not measurable from telemetry. Mitigating factor: the V15 → V16 data conversion inCopyFromToPriceListLinewrites migrated discount records asAmount Type = Discountwith the variant preserved, so most affected lines are migrated configurations this change restores rather than breaks.Amount Type = Price & Discount; they must change the variant line toDiscount. Support needs to communicate this.Currency Codeand is fixed by the same code path.