Skip to content

[Bug][Subscription Billing] Price Update Template filters on Subscription Lines are overwritten by the proposal's own default filters #10358

Description

Describe the issue

The filters defined on a Price Update Template are not honoured when the price update proposal is created. A template that restricts the subscription lines — for example to a specific "Next Price Update" date — produces a proposal that contains lines outside that filter, so a targeted price adjustment cannot be carried out in practice.

The user's intent is precisely the opposite of what happens: the template is the place where the selection is defined, but the proposal quietly replaces part of that selection with its own broader defaults. Users then have to delete the surplus proposal lines by hand, or discover after the fact that prices were updated on contracts that were never meant to be included.

Affected objects:

  • src/Apps/W1/Subscription Billing/App/Contract Price Update/Codeunits/PriceUpdateManagement.Codeunit.al
  • src/Apps/W1/Subscription Billing/App/Contract Price Update/Tables/PriceUpdateTemplate.Table.al
  • src/Apps/W1/Subscription Billing/App/Contract Price Update/Codeunits/CalculationBaseByPerc.Codeunit.al
  • src/Apps/W1/Subscription Billing/App/Contract Price Update/Codeunits/PriceByPercent.Codeunit.al

Expected behavior

The proposal must contain only subscription lines that satisfy both the template's own filters and the mandatory defaults. With a Subscription Line Filter of "Next Price Update" = 08/01/25, only lines whose Next Price Update is 08/01/25 may appear in the proposal.

Root cause

PriceUpdateManagement.Codeunit.al, GetAndApplyFiltersOnServiceCommitment:

if ServiceCommitmentFilterText <> '' then begin
    ServiceCommitment.SetView(ServiceCommitmentFilterText);
    ApplyDefaultFiltering(ServiceCommitment, PriceUpdateTemplate, IncludeServiceCommitmentUpToDate);
    FindAndMarkMatchedAndDeleteUnmarkedServiceCommitment(ServiceCommitment, TempServiceCommitment);
end;

SetView applies the template's stored filters, and ApplyDefaultFiltering is then called on the same record variable:

local procedure ApplyDefaultFiltering(...)
begin
    ServiceCommitment.SetRange(Partner, PriceUpdateTemplate.Partner);
    ServiceCommitment.SetRange("Exclude from Price Update", false);
    ServiceCommitment.SetRange("Invoicing via", Enum::"Invoicing Via"::Contract);
    ServiceCommitment.SetFilter("Next Price Update", '<=%1|%2', IncludeServiceCommitmentUpToDate, 0D);
    ServiceCommitment.SetRange("Planned Sub. Line exists", false);
    ServiceCommitment.SetRange("Usage Based Billing", false);
    ServiceCommitment.SetRange(Closed, false);
end;

SetRange / SetFilter replace the filter on a field rather than intersect with it. Every field touched by ApplyDefaultFiltering therefore loses whatever the template specified for it. In the reported scenario the template's "Next Price Update" = 08/01/25 is replaced by <=IncludeContractLinesUpToDate|0D, which also lets through every line with a blank Next Price Update — hence the proposal "ignores" the filter.

The same collision applies to Partner, "Exclude from Price Update", "Invoicing via", "Planned Sub. Line exists", "Usage Based Billing" and Closed, and it is reached from every path that calls ApplyDefaultFiltering, including FilterAndMarkServiceCommitmentOnServiceObject and ApplyContractFilterAndMarkServiceCommitment.

Proposed fix

Apply the mandatory defaults in a separate filter group so that they intersect with the template's view instead of overwriting it — set FilterGroup(2) (or another unused group) around the body of ApplyDefaultFiltering and restore FilterGroup(0) afterwards, leaving the template's SetView filters untouched in the user filter group.

Where the default and the template genuinely conflict — the template asks for a Next Price Update later than "Include Contract Lines up to Date" — the intersection correctly yields nothing, which is the honest answer and better than silently widening the selection.

Steps to reproduce

  1. Open a customer subscription contract and set Next Price Update on one contract line to 08/01/25. Leave other lines with a different or blank Next Price Update.
  2. Open Price Update Templates and create a template (any Price Update Method, Partner = Customer).
  3. On the template, open the Subscription Line Filter and set a filter Next Price Update = 08/01/25. Save the filter.
  4. Open Subscription Contract Price Update, select the template, and set Perform Update on and Include Contract Lines up to Date both to today (a date later than 08/01/25).
  5. Choose Create Proposal.
  6. The proposal contains subscription lines whose Next Price Update is not 08/01/25 — including lines with a blank Next Price Update — instead of only the line from step 1.

I will provide a fix for a bug

  • I will provide a fix for a bug

Metadata

Metadata

Assignees

No one assigned

    Labels

    FinanceGitHub request for Finance area

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions