Skip to content

[Bug][Subscription Billing] "Delete Invoiced Sales Orders" leaves orphaned Sales Subscription Lines behind #10175

Description

Describe the issue

When a fully invoiced sales order is removed with the standard Delete Invoiced Sales Orders batch job, the Subscription Billing data attached to that order is not removed with it. The order and its lines disappear, but the Sales Subscription Lines that belonged to those order lines stay in the database and become orphaned records: they still point to a document number that no longer exists.

Users notice this on the Sales Subscription Lines list, which keeps growing with entries for orders nobody can open any more. Nothing in the UI can clean them up, because the document they belong to is gone — the only way to get rid of them is a data fix.

The same cleanup works correctly when an order is deleted manually from the Sales Orders list, or when a quote is converted into an order, so the leftovers only appear for orders that were removed by this batch job. That makes the problem easy to miss and it accumulates silently over time.

Expected behavior

Deleting a sales order through report 299 "Delete Invoiced Sales Orders" should delete the related records in table 8068 "Sales Subscription Line", exactly as every other deletion path already does. No record in table 8068 should survive the document it belongs to.

Cause

Subscription Billing cleans up table 8068 in the OnDelete() trigger of tableextension 8054 "Sales Line" (DeleteSalesServiceCommitment()). Report 299 deletes the order lines and the header without running triggers:

SalesOrderLine.Delete();          // Base Application, report 299, line ~103
...
Delete();                         // the Sales Header, line ~137

Because Delete() defaults to RunTrigger = false, the table extension trigger never fires and the Sales Subscription Lines are left behind.

The app already handles the other trigger-less deletion paths with subscribers in codeunit "Sales Subscription Line Mgmt.":

  • Codeunit::"Sales-Post", OnBeforeSalesLineDeleteAllDeleteSalesServiceCommitmentOnBeforeSalesLineDeleteAll
  • Codeunit::"Sales-Quote to Order", OnRunOnAfterSalesQuoteLineDeleteAllDeleteSalesServiceCommitmentOnAfterSalesQuoteLineDeleteAll

Report 299 is the one that is missing.

Proposed fix

Report 299 already raises a suitable integration event after each deleted line, so no base application change is needed. Add a subscriber to codeunit "Sales Subscription Line Mgmt.":

[EventSubscriber(ObjectType::Report, Report::"Delete Invoiced Sales Orders", OnAfterDeleteSalesLine, '', false, false)]
local procedure DeleteSalesSubscriptionLinesOnAfterDeleteSalesLine(var SalesLine: Record "Sales Line")
begin
    SalesLine.DeleteSalesServiceCommitment();
end;

DeleteSalesServiceCommitment() already guards against temporary records and against document types that cannot carry subscription lines, so it is safe to call for every deleted line.

An alternative, broader fix is a subscriber to Database::"Sales Line", OnAfterDeleteEvent guarded with if RunTrigger then exit;, which would also catch any other caller that deletes sales lines without triggers. The narrow, report-specific subscriber is preferred because it keeps the existing per-path pattern of the app and cannot change behaviour of unrelated deletion paths.

Archiving is not affected: the report archives the document before deleting it, so the "Sales Subscription Line Archive" entries are written correctly. Only the live table 8068 leaks.

There is currently no test covering report 299 in the Subscription Billing test app; the fix should come with a test that runs the report on a fully invoiced order and asserts that no "Sales Subscription Line" remains for that document.

Steps to reproduce

  1. Create an item and set Subscription Option = Service Commitment Item, then assign a subscription package to it.
  2. Create a sales order for a customer and add one line with that item. On the line, choose Line > Subscription Lines and confirm that Sales Subscription Lines were created for it.
  3. Post the order with Ship and Invoice. The order is fully shipped and invoiced but stays in the Sales Orders list.
  4. Search for Delete Invoiced Sales Orders, filter on the order number from step 2 and run the batch job.
  5. Confirm the order is gone from the Sales Orders list.
  6. Search for Sales Subscription Lines and filter Document No. on the deleted order number.

Result: the Sales Subscription Lines of the deleted order are still there and can no longer be reached from any document.

Expected: the list is empty — the subscription lines were deleted together with the order.

Additional context

No response

I will provide a fix for a bug

  • I will provide a fix for a bug

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ApprovedThe issue is approvedOwnership: ManualPreserve the manually selected team ownershipTeam: FinanceGitHub request for Finance area

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions