For the complete documentation index, see llms.txt. This page is also available as Markdown.

Billing Engine Architecture

The residential billing engine is the scheduled process that turns each resident's configured fees into invoices, statements, and accommodation drawdowns every day, without manual intervention. It is implemented as the RAC_BillingEngine Apex class and is the heart of residential aged care billing in Maica.

This article explains how the engine is structured: what it processes, the services it orchestrates, and the lifecycle of a single billing run. The rules it applies are covered in the companion articles on Next Billing Date and Catch-Up Chains and Fee Type Processing Rules.

What the engine does

The engine is a daily, scheduled, batched orchestrator. On each run it walks every active residential Agreement Item that is due, derives the period to bill, evaluates caps and leave, creates the resulting invoice line items, rolls them up into invoices and monthly statements, performs automatic accommodation drawdown where eligible, and advances each item's billing cursor.

Technically, RAC_BillingEngine is a Salesforce Batchable, Schedulable, and Stateful class. A few properties follow from that design:

  • Scheduled and batched. A daily scheduled run starts a fresh batch. The batch processes Agreement Items in chunks of 20 at a time, each chunk with its own governor limits.

  • Callout-free. The engine never calls Services Australia. Fee rate callouts are separate scheduled job (see Fee Detection and Rate Updates).

  • Stateful counters. The engine keeps running totals (items completed, items failed, statements touched, chain depth) across all chunks so the run can report a tidy summary at the end.

Only Agreement Items whose Funding has a Funding Source of Residential Aged Care are in scope. The engine does not touch Home Care Package or NDIS funding.

The Agreement Item processor

The engine is a general-purpose Agreement Item processor: it does not contain fee-specific code paths for each fee type baked into the run loop. Instead it reads the configuration on each Agreement Item and its linked Support Item, then delegates the specialised work to a small set of focused services.

Agreement Item structure

Each Agreement Item carries the fields the engine needs to bill it:

Field
Role in billing

Rate and Quantity

The base inputs to the charge amount.

Billing Method

In Advance or In Arrears. Drives when a period becomes billable.

Service Frequency

Day, Week, Month, or One (one-off). Drives the length of each billing period.

Start Date and End Date

The lifecycle window. Periods are clamped so they never fall outside this window.

Next Billing Date

The cursor that determines when the item is next due.

Last Billed Period End

The last day already billed. Prevents re-billing the same days.

Cumulative Amount (FY)

The running total used for annual cap evaluation.

Cap Reached

Set when a cap is engaged. A capped item drops out of the engine's scope.

Active Item

A formula that is true when today falls within the item's dates and the parent agreement is active.

Automatic RAD Drawdown

Whether eligible charges trigger a drawdown against the lump sum.

Billing Status

Initialised, Complete, or Failed.

Fee Type (on the linked Support Item)

Tells the engine which processing rules apply.

Orchestrated services

The run loop delegates to four focused services:

  • Billing Period Calculator derives the period to bill and adjusts chargeable days for leave.

  • Cap Service evaluates the regulatory caps for capped fee types.

  • Retention Service calculates retention deductions from the lump sum.

  • Drawdown Service performs automatic accommodation drawdown after billing.

The lifecycle of a run

A run moves through three stages, with the heavy lifting happening per item.

Selecting what is due

The run starts by selecting active, in-scope Agreement Items that are due: the item must be active, not already at a cap, have a Next Billing Date on or before today, not be in a Failed state, and belong to an active residential agreement. Items are processed grouped by Service Agreement so each monthly statement is built once per agreement per period.

Processing each item

Each item is processed end to end inside its own try block, so a failure on one item never stops the others. The per-item pipeline runs in this order:

  1. Derive the billing period.

  2. Skip empty periods, and flag a guardrail breach for logging.

  3. Compute the proposed charge amount.

  4. Apply the fee type rules: route capped fees through the Cap Service, retention through the Retention Service, and bill pass-through fees at their raw amount.

  5. Get or create the monthly Service Agreement Statement for the period.

  6. Get or create the invoice header for the period.

  7. Stage the invoice line item.

  8. Stage the Funding cumulative updates.

  9. Stage the Agreement Item update (advance the billing cursor, set Billing Status to Complete).

  10. Queue an accommodation drawdown where eligible.

All database writes are staged and committed once per chunk as bulk operations, which keeps the run efficient and within platform limits.

Outputs of a run

A successful run produces:

  • Invoice line items, each stamped with a line item source of Billing Engine.

  • Invoices that roll up the line items for the period.

  • Service Agreement Statements of type Residential Aged Care - Monthly with a status of Generated, one per agreement per period.

  • Updated Funding cumulatives that feed cap evaluation.

  • Retention and accommodation drawdown records where applicable.

Automatic and manual runs

The engine normally runs on its daily schedule. An administrator can also trigger an ad-hoc run from the Maica Settings area. Either way, the same pipeline executes; the only difference is what starts it. For scheduling and manual rate changes, see Scheduling and Manual Rate Changes.

Last updated

Was this helpful?