[Bug][Subscription Billing] Supplier charge period is ignored when crediting usage-based vendor subscription lines
Nobody has claimed this yet.
- Dominant language
- AL
- Stars
- 683
- Forks
- 459
- Avg merge
- 3d 26m
- Merged PRs (30d)
- 633
Description
Describe the issue
A subscription is billed on the basis of usage data and has both a customer line and a vendor line. It is invoiced a year in advance, 1 January to 31 December. The customer cancels as of 1 October, so usage data for the remaining three months is delivered with a negative quantity in order to credit the unused part of the year.
Two things go wrong:
-
While the usage data is processed, the user is told that the quantity must not be negative, even though the credited quantity is fully covered by the quantity that is currently subscribed. The message is misleading — nothing is actually wrong, and the data is processed anyway — but it makes users doubt whether the credit was created correctly.
-
The resulting vendor credit memo credits the whole year instead of the three cancelled months. The customer side gets this right: there the credit is limited to the period the usage data actually covers. On the vendor side the charge start and end dates of the delivered usage data are not taken into account at all, so the amount comes out roughly four times too high. Since this ends up in a posted purchase credit memo, the vendor account and the contract margin are both wrong, and the error is only found when someone reconciles the vendor invoice by hand.
Affected objects:
src/Apps/W1/Subscription Billing/App/Usage Based Billing/Codeunits/ProcessUsageDataBilling.Codeunit.alsrc/Apps/W1/Subscription Billing/App/Usage Based Billing/Tables/UsageDataBilling.Table.alsrc/Apps/W1/Subscription Billing/App/Billing/Codeunits/BillingProposal.Codeunit.alsrc/Apps/W1/Subscription Billing/App/Service Objects/Tables/SubscriptionHeader.Table.al
Expected behavior
1 — Negative quantity warning
The warning should only appear when the negative quantity delivered is larger in absolute terms than the quantity currently subscribed on the Subscription Line (a quantity of -2 is legitimate for a subscription with quantity 3; -5 is not).
Today the message originates from QtyNegativeErr in Subscription Header, raised via Process Usage Data Billing.UpdateServiceObjectQuantity() when the recalculated total quantity is validated. The check should compare the incoming negative quantity against the currently subscribed quantity before raising anything, and stay silent when the credit is covered by it. If a message is still warranted, it should also be raised consistently — either it blocks processing or it does not; right now it is shown and the record is processed regardless.
2 — Supplier charge period on the vendor side
Charge Start Date / Charge End Date of the usage data (and the Supplier Charge Start Date / Supplier Charge End Date mirrored into Usage Data Billing Metadata) must be honoured for vendor Subscription Lines exactly as they are for customer lines, so the vendor credit memo covers only 01.10.2026–31.12.2026.
Where it currently breaks:
Process Usage Data Billing.Code()restricts the repricing loop toPartner::Customer, andCalculateCustomerUsageDataBillingPrice()exits immediately for any other partner. The period-aware calculation —CalculateUsageDataPrices()→Subscription Line.UnitPriceForPeriod("Charge Start Date", "Charge End Date")— therefore never runs for vendor lines.- As a result the vendor
Unit Cost/Cost Amountstay at the raw importedUnit Cost × Quantityproduced byUsage Data Billing.CalculateAmounts(), which does not consider the charge period at all. Billing Proposal.SetBillingLineUnitPriceAndServiceAmountsFromUsageDataBilling()then takesUsage Data Billing."Cost Amount"as the base amount forPartner::Vendor, so the un-prorated full-year amount lands on the billing line and on the purchase credit memo.
Proposed fix: apply the same period-based cost calculation to vendor Subscription Lines — i.e. give vendor lines a counterpart to CalculateCustomerUsageDataBillingPrice that derives Unit Cost / Cost Amount from the charge period via UnitPriceAndCostForPeriod (or extend the existing routine to run for both partners, using Unit Cost/Cost Amount instead of Unit Price/Amount for vendors), keeping Unit Cost from Import-style supplier settings respected. Usage Data Billing Metadata is already written for both partners, so no new data is needed.
Steps to reproduce
- Create a Subscription with a customer Subscription Line and a vendor Subscription Line, both with Usage Based Billing enabled and a yearly billing rhythm.
- Import usage data for that subscription with Charge Start Date = 01.01.2026, Charge End Date = 31.12.2026, Quantity = 10, Unit Cost = 1200, and process the import.
- Create and post the billing documents from both the customer subscription contract and the vendor subscription contract — the customer invoice and the purchase invoice cover the full year.
- Import a second usage data file for the same subscription with Charge Start Date = 01.10.2026, Charge End Date = 31.12.2026, Quantity = -10, Unit Cost = 1200 (the cancellation as of 1 October).
- Process the usage data.
→ A message appears saying the quantity must not be negative, although the subscription currently has quantity 10 and only 10 is being credited. The lines are processed regardless. (Defect 1) - Open the vendor subscription contract, create the billing proposal and the credit memo.
→ Expected credited amount: 3,600 (01.10.2026–31.12.2026). Actual credited amount: 12,000 (full year). (Defect 2) - Repeat step 6 on the customer subscription contract — there the credit is limited to the cancelled period, which shows the two sides behave differently.
Additional context
No response
I will provide a fix for a bug
- I will provide a fix for a bug
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ProcessUsageDataBilling.Codeunit.al, especially UpdateServiceObjectQuantity() and the customer-only repricing path, then trace BillingProposal.Codeunit.al and UsageDataBilling.Table.al. Compare the customer period calculation with vendor handling and review SubscriptionHeader.Table.al for QtyNegativeErr. Done means covered negative quantities no longer warn incorrectly and vendor credits use the delivered charge period, with the affected billing flow verified.
Written by the indexing model from the issue text.
Assessment
- Domain
- backend, payments
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100