Contract repository over Subscription Billing with renewal alerts, RPI/CPI indexation, and renewal workflow.

  • Current version: v0.1.1.0
  • AL prefix: SMART
  • Object range: 80800-80899
  • Business Central: 26.0.0.0
  • Publisher: Amplio Solutions

14 — Smart Recurring Contracts & Renewals Manager

A Business Central 26.x extension that adds a customer-contract layer over the standard Subscription Billing module. Manages renewal terms, RPI/CPI/CPIH indexation, alert dispatch, and the renew/amend/churn outcome — all with a full audit trail.

  • Publisher: Amplio Solutions
  • Version: 0.1.1.0
  • Application / Platform: 26.0.0.0
  • Object range: 80800–80899 (AMP prefix, declared as idRanges[0].affix)
  • Country: GB
  • Runtime: 15.0 (BC 26.x)
  • Target: Cloud (works in OnPrem sandboxes too)

What this extension does

Subscription Billing in BC gives you the per-line billing schedule. This extension adds the commercial wrapper around it — the contract document, the renewal lifecycle, and the indexation/alert mechanics that BC doesn't ship out of the box.

Each Contract Header points at one customer; each Contract Line points at a Service Commitment line in Subscription Billing (foreign key, no data duplication). The renewal calculator rolls dates forward; the indexation engine applies a CPI/RPI uplift to the lines' unit prices; the dispatcher fires desktop notifications N days before renewal; the contract manager records the outcome and (optionally) advances the cycle.

Object map

Range Object kind Examples
80800–80804 Tables Contract Header, Contract Line, Indexation Rate, Renewal Action Log, Contracts Setup
80820–80828 Pages Contract List/Card, Contract Lines, Indexation Rates, Action Log, Renewals Dashboard, Setup, Activities cue
80826 Role Centre Renewals Manager (AMP Renewals Role Centre) + matching profile
80850 PageExtensions Customer Card → Contracts navigation
80860–80864 Codeunits Renewal Date Calculator, Indexation Engine, Notification Dispatcher, Contract Mgt, Install
80880–80883 Enums Contract Status, Indexation Type, Renewal Outcome, Renewal Action Type
80890–80891 Permission Sets Full + read-only

Folder layout

14-Smart-Contracts-Renewals/
├── app.json
├── .editorconfig
├── .gitignore
├── README.md
├── .vscode/
│   └── launch.json
└── src/
    ├── Tables/
    ├── Pages/
    ├── PageExtensions/
    ├── Codeunits/
    ├── RoleCentre/
    ├── Enums/
    └── Permissions/

Dependencies

Pinned in app.json:

App Publisher Version Notes
Base Application Microsoft 26.0.0.0
System Application Microsoft 26.0.0.0
Subscription Billing Microsoft 26.0.0.0 App ID written as 8073825b-2cdd-460d-9d9a-fa1fa7c66f59. Verify against your installed symbols — see ship list below.

What's complete

  • AL scaffold compiles against BC 26 symbol sets (Base + System + Subscription Billing).
  • Setup table with sensible defaults populated by the install codeunit (90-day notice, 12-month renewal, 90-day primary alert, 30-day secondary alert).
  • Contract Header / Line model, with the Line's foreign key to Service Commitment."Entry No." so we don't duplicate Subscription Billing's data.
  • Renewal Date Calculator: rolls Start Date + Initial Term forward by Renewal Term until it lands on/after work date; computes Notice By Date.
  • Indexation Engine: header + per-line override, CPI/RPI/CPIH lookup against the rate table, fixed-% mode, cap and floor, batch "run for all due in next 30 days" action.
  • Notification Dispatcher: desktop notifications via the BC Notification API, dedupes per-day, auto-promotes Active → Pending Renewal when the alert fires, and logs the dispatch.
  • Contract Mgt: records Renew/Amend/Churn outcome, writes audit log, and (when Renew + auto-apply enabled) runs indexation and rolls the cycle forward.
  • Renewal Action Log: append-only audit trail, displayed as both a list and a card factbox.
  • Renewals Dashboard with traffic-light styling on the renewal date column.
  • Role Centre with cues for "Due in 30 days", "Due in 90 days", "Notice due in 30 days", "Awaiting outcome", and "Indexation due" — drillable into the dashboard.
  • Customer Card extension with a Contracts navigation action.
  • Two permission sets: full (AMP Contracts Renewals) + read-only.

What Lee needs to ship

Below are the things that need attention before this can go to a real tenant. Most are configuration; a couple are code TODOs flagged inline.

Verify before publish

  1. Subscription Billing dependency ID. The 8073825b-... GUID in app.json is the value commonly returned for the Microsoft Subscription Billing app, but Microsoft has been known to re-key apps between major waves. Before first publish, run Get-NAVAppInfo (or the cloud-equivalent app inspector) on your target environment, and replace the GUID and version in app.json if they differ.
  2. Service Commitment / Service Object table names. The Contract Line's TableRelation references Service Object and Service Commitment.Entry No.. If the symbols on your tenant expose those tables under different object names (Microsoft has used "Customer Subscription Contract", "Service Commitment", and "Subscription Line" at various points), update AMPContractLine.Table.al accordingly. The FetchCommitmentSnapshot() helper assumes fields Description, Quantity, Price on Service Commitment — confirm and adjust.
  3. No. Series. Pick a series code in Contracts Setup → Numbering. There is no auto-created series; pick an existing one (CONT etc.) or create one before publishing.

Configuration / data seeding

  1. RPI / CPI / CPIH rate seeding from ONS. The AMP Indexation Rate table is empty on install. You need a feed. Two reasonable paths:
    • Manual: monthly XLSX upload via the standard "Edit in Excel" against page 80823.
    • Automated: add a small helper codeunit that calls the ONS time-series API. The relevant ONS time-series IDs are CHAW (RPI all items, annual % change), D7G7 (CPI all items, annual % change), and L55O (CPIH all items, annual % change). API base: https://api.ons.gov.uk/timeseries/{id}/data. This is the right v2 work item.
  2. Alert lead-time defaults. Install seeds 90/30 days. Confirm with the commercial team whether you want a 180-day "early warning" cue too, and add a third lead-time to AMP Contracts Setup if so.
  3. Notification Recipient. Setup currently accepts a single User ID + a fallback email. The Notification API only fires desktop alerts to the currently signed-in user, so for a true asynchronous alert (email, Teams) you'll need to add an email-sending codeunit using Email::Send() and the standard Email Account. That's the right v1.1 enhancement.
  4. Role Centre permissions. The AMP Renewals Manager profile is enabled but the user that needs to land on it must (a) have the AMP Contracts Renewals permission set assigned, and (b) be told to switch profile via My Settings → Role. Add it to your standard onboarding checklist or assign via user-group at provisioning.
  5. Job Queue. None of the codeunits are wired to a Job Queue Entry. To run alerts daily and indexation monthly, create two Job Queue Entries pointing at:
    • Codeunit 80862 (AMP Notification Dispatcher) → daily 07:00, no parameters.
    • Codeunit 80861 (AMP Indexation Engine) calling RunForAllDuebut the codeunit's OnRun isn't currently the entry point for that procedure; you'll need a thin scheduler codeunit (one new file) or change the engine's OnRun to invoke RunForAllDue.

Deferred to v2

  • eSignature integration (DocuSign / Adobe Sign) for renewal letters — explicitly out of MVP scope.
  • Renewal letter templates / email body composition beyond the generic notification.
  • Forecast revenue from indexation — projected ARR uplift over a period.
  • Contract amendments as first-class entities (today the Amend outcome only flips status; an amendment record + diff would be the right v2 model).

Build & deploy

From VS Code with the AL Language extension:

  1. Place this folder anywhere on your machine.
  2. AL: Download symbols against your sandbox.
  3. F5 runs the BC: Cloud Sandbox launch profile (edit environmentName in .vscode/launch.json) or BC: Local Sandbox (Docker) for OnPrem.
  4. The Renewals Manager role centre (page 80826) opens by default.

Smoke test path (manual)

  1. Open Contracts Setup, pick a No. Series, set defaults, save.
  2. Open the Customer Card for any customer, click Contracts → Contracts, then +New.
  3. Fill Start Date, Initial Term 12, Renewal Term 12, Notice 90, Indexation Type CPI.
  4. Add a line; pick a Service Commitment from Subscription Billing.
  5. Click Recalculate Renewal Date — you should see Next Renewal and Notice By populate.
  6. Seed at least one row in Indexation Rates (e.g. CPI 2025-12 = 3.20).
  7. Click Run Indexation — line price uplifts; one log entry written.
  8. Click Send Renewal Alerts — if any contract is inside the lead window you'll see a desktop notification.
  9. Click Record Outcome: Renew — status flips, cycle rolls forward, audit entry written.