Skip to main content

Invoices

An invoice is the billing document for a single completed work order. It's created from the work order itself — the work order is the unit of billable work, and the invoice is its receipt — and it's pushed to your connected billing system in the same step.

Invoices are optional

The invoices feature is gated by a tenant setting (feature_flag_invoices_enabled). Some operations bill outside TuffOps (in QuickBooks directly, or in a separate accounting tool) and never use TuffOps invoices. Other operations want everything in one place.

When the flag is off:

  • The Invoices menu, list, and create form are hidden.
  • The Create Invoice button on the work order is hidden.
  • The Invoices controller refuses requests (404) even if you navigate directly.

When the flag is on:

  • Completed work orders show a Create Invoice button.
  • The Invoices menu and list appear in the top navigation.
  • Cancellation flows through to your billing system in real time.

The flag isn't a one-way door — you can turn invoices on or off and the existing data stays intact, only the surface area changes.

The three invoice statuses

StatusWhat it means
sentInvoice has been issued. (TuffOps creates invoices in this state — there's no draft.)
paidPayment has been recorded (typically by an upstream sync from your billing system).
cancelledInvoice was withdrawn before payment was recorded.

The act of creating an invoice in TuffOps is the act of sending it to the connected billing system. There's no "draft" state — if you need an internal-only working copy, that's a quotation, not an invoice.

One invoice per work order

The work order ↔ invoice relationship is one-to-one:

  • An invoice is always created from a single work order. You can't bundle multiple work orders onto one invoice.
  • A work order can have at most one active (sent or paid) invoice at a time. Cancelled invoices stay on the record for the audit trail but don't block creating a new one.

If you need to bill a customer for several jobs on a single document, that's a feature of your billing system (consolidated statements, monthly summaries, etc.) — not the TuffOps invoice itself.

How an invoice is structured

When an invoice is created, TuffOps snapshots two subtotals from the source work order:

  • Unit subtotal — the device model's cost, copied at invoice time. The user can opt out of this with the Include unit price toggle (off → unit subtotal is 0).
  • Items subtotal — the sum of quantity × price for every line item the technician added on the work order.

The invoice also stores a tax rate, defaulting to the tenant's default rate, and applies it to both subtotals to produce the Grand Total. None of this re-derives from the work order after the invoice is created — later edits to the work order's items don't change the invoice. That's the point of an invoice: it has to be stable once it leaves TuffOps.

The invoice number (invoice_id) is generated automatically: tenant prefix from the invoice_prefix setting (default TFT) plus a sequential number.

What cancellation does (and doesn't do)

Cancelling an invoice:

  • Sets the invoice status to cancelled and records cancelled_at.
  • Calls the connected billing system to cancel the corresponding record there. If that call fails, TuffOps does not cancel locally either — the two systems stay in sync.
  • Removes the duplicate-invoice block on the work order, so a fresh invoice can be created with corrected numbers.

What cancellation does not do:

  • It does not change the work order's status. If the work order was billed, it stays billed. If it was completed, it stays completed. The work order is decoupled from the invoice's lifecycle on purpose.
  • It does not delete the invoice — cancelled invoices remain visible in the Invoices list (greyed out) for audit purposes.

A paid invoice cannot be cancelled — payments must be reversed first (in your accounting system) and then the credit/refund is recorded outside the TuffOps cancellation flow.

External billing integration

TuffOps is built to feed an external billing system (currently CaribeEats) as the system of record for finance. The runtime pattern:

  1. Office user clicks Create Invoice on a completed work order.
  2. TuffOps creates the invoice locally and pushes it to the external system in the same request. If the external call fails, the invoice is still created locally (so the office can retry or contact support), but a warning is logged.
  3. Cancellation goes the other way: TuffOps requires a successful external cancellation before flipping the local status, so the two systems can't drift.
  4. Payment is recorded in the external system; sync-back to mark TuffOps invoices as paid happens out-of-band.

This pattern keeps TuffOps as the operational record and the external system as the financial record, without double-entry.

Why invoices snapshot

When an invoice is created, the unit cost, item subtotal, and tax rate are copied from their sources, not referenced. This is the same reason quotations lock after submission: the document the customer pays against has to be stable. If you discover a mistake later, you cancel the invoice and create a new one. The old one stays intact for the record.