Arc Forge Labs Docs v2026.10.53

Invoicing rules

Flow drafts the invoice of each billable job that is ready to invoice, by rules, and sends checked invoices to the accounting system (Xero) in one of two ways. Invoicing is part of Flow and needs no integration. With no accounting system connected, Flow's own records are the only check: each job gets at most one invoice. The send mode is on the Xero integration page. This page describes the rules and the send modes. The code is in server/core/invoicing-rules.js. The settings are in Flow under Settings, Rules, and at /api/invoicing/settings.

From job to customer

flowchart LR
  work[Job in work] -- a person, or the work system's ready statuses --> job[Ready to invoice]
  job --> rules{Does an invoice rule match?}
  rules -- yes --> wait[Waits: the job lists the rules]
  rules -- no --> draft[Flow draft invoice]
  draft --> check[A person checks it in Flow]
  check --> mode{Send mode}
  mode -- accounting_draft --> xdraft[Xero draft]
  xdraft --> xapprove[A person approves and sends it in Xero]
  mode -- approve_and_email --> xauth[Xero approved invoice]
  xauth --> xemail[Xero emails it to the customer]
  xapprove --> back[The mirror reads it back to Flow]
  xemail --> back
  1. Ready. A job is in work until it is ready to invoice. Ready is Flow's own stage, not a work system status. A person marks a job ready on the Jobs board, or an automation does it from the work system's status (docs/AUTOMATIONS.md).
  2. Draft. The pipeline (docs/JOB_INVOICE_LINKS.md) runs every two minutes. The automation "Draft when ready" drafts the invoice of each ready job that has no invoice and that no invoice rule stops. The draft waits in Flow. Nothing goes to Xero by itself.
  3. Check. A person checks the draft in Flow and issues it. Issuing gives it its number and keeps the document as sent.
  4. Send. A person sends the issued invoice to Xero. The customer's send mode decides what Xero gets (below).
  5. Read back. The mirror (docs/XERO.md, "The mirror") copies Xero's status. The matcher links the Xero invoice to the job by the Flow invoice that made it (flow_invoice). Approval, payment, void and credit notes then show on the job.

Reference

The Reference is the text the customer reads on the invoice, next to its number. The lab writes it as a rule under Settings, Rules, Reference (referenceTemplate), from tokens:

Token Value
{practitioner} The job's practitioner.
{patient} The patient name. The work system gives it only when its integration keeps patient names (Seazona: Settings, Integrations, Seazona, Keep patient names).

The default rule is {practitioner} - {patient}. Text between two tokens shows only when both have a value: with no patient name, the Reference is the practitioner alone. An empty rule gives no Reference; the accounting system then shows the invoice number. Flow never puts a work system's ids in the Reference. The code is in server/core/references.js.

The automation "Reference from the rule" keeps the Reference of each draft made from a job up to date as the rule or the job's fields change. It never changes a Reference a person typed, and it does not change the draft's status. A job read before patient names were kept gets its name from one more read of the work system, at most 10 jobs each run.

The rules

The ledger's own checks guard every draft (server/core/ledger.js): the job is not held, every line maps to a price item, it has a customer, the accounting copy holds no invoice for it, and the work system's report is less than a day old. Then the job must be marked ready to invoice.

Every other check is an invoice rule that the lab builds: When, If, Then (docs/INVOICE_RULES.md). Flow makes starter rules from the earlier settings once, for each organisation:

Starter rule If Then From the setting
Customer not billable Customer is billable is no Never draft customer billable
No amount Job total is at most 0 Wait for a person
Old job Job age (days) is more than 90 Wait for a person staleDays
Practitioner required Practitioner is empty Wait for a person (off until turned on) requirePractitioner
Rush charge share Rush line share is not 20% Wait for a person rushItemCode, rushPercent (only when a code is set)

The earlier lab app held these checks in its code. In Flow they are rows the lab edits under Settings, Rules, Invoices. GET /api/invoicing/jobs lists the rules each job without an invoice waits on (waitingFor).

staleDays still sets the matcher's hold on an old job that has no accounting invoice (docs/JOB_INVOICE_LINKS.md). The settings requirePractitioner, rushItemCode and rushPercent only seed the starter rules.

A draft gets the invoice date when it is issued, and a due date paymentTermsDays after the day Flow drafted it (default 30).

The automation "Draft when ready" turns the drafts on or off. It is on by default. A customer's autoDraft turns them off for that customer. It runs with or without an accounting integration. With no integrations on at all, the pipeline does not run, and a person drafts from the Jobs board.

The duplicate check

The earlier app asked Xero for each job before it drafted. Flow does not. It drafts only when its own copy of Xero is complete, was read in the last day, and changed no later than the matcher's last check of the job, and holds no invoice with the job's own invoice number. When Flow sends an invoice it drafted that way, it skips Xero's live reference check too. An invoice a person made by hand in Flow still gets the live check.

Send modes

Mode In Flow In Xero Xero emails the customer
accounting_draft (default) A person checks and sends A draft. A person approves and sends it When the person sends it in Xero
approve_and_email A person approves (issues) and sends Approved (AUTHORISED) Yes, at once, with the Xero template

approve_and_email needs an email address on the Xero contact. The preview says so when it has none.

Xero's email action is not idempotent: a repeat sends a second email. Flow records the email as sending before it calls. It records sent, failed (Xero refused) or unknown (no clear answer). Sending the invoice again retries a failed email only. After unknown a person checks the invoice in Xero.

Customer settings

Each customer can override some settings at /api/invoicing/contacts/:id/billing. A null value takes the organisation's setting.

Setting Meaning
billable Rules never draft an invoice for a customer that is not billable
defaultPractitioner The practitioner for jobs that name none
autoDraft Drafts on or off for this customer
sendMode The send mode for this customer
paymentTermsDays The customer's payment terms