---
id: DOM-ACC-TRX-001
title: Invoice
realises: CON-ACC-TRX-001
product_area: accounting
module: transactions
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-ACC-TRX-transactions
lifecycle: STATE-ACC-TRX-001
custom_fields: none
identity: >-
  Creation assigns a time-ordered identity within the workspace. Issue assigns
  the invoice sequence number, beginning at one million, including for pro
  formas. Each correction document uses its own identity and numbering sequence.
attributes:
  - name: kind
    kind: enum
    required: true
    computed: false
    notes: >-
      Distinguishes an invoice from a quotation that becomes an invoice on
      conversion.
  - name: status
    kind: enum
    required: true
    computed: true
    notes: >-
      Draft and void are explicit lifecycle states; maintained amounts determine
      the other states.
  - name: bill-to
    kind: reference
    required: true
    computed: false
    notes: >-
      Identifies a CRM party and retains the billed name and address on the
      invoice.
  - name: ship-to address
    kind: json
    required: false
    computed: false
    notes: >-
      Optional destination used to determine tax for shipped lines; recognition
      protects it and eligible amendment can replace it.
  - name: business unit and currency
    kind: reference
    required: true
    computed: false
    notes: >-
      Records the issuing unit and an enabled currency; draft replacement
      preserves both.
  - name: 'invoice, accounting and due dates'
    kind: date
    required: true
    computed: false
    notes: >-
      An explicit due date takes precedence over terms, with the invoice date as
      the fallback and earliest permitted due date.
  - name: payment terms
    kind: reference
    required: false
    computed: false
    notes: >-
      Uses the requested terms when supplied, otherwise the customer's saved
      default.
  - name: lines
    kind: collection
    required: true
    computed: false
    notes: >-
      Describes each charge, its price calculation, service period, shipping
      flag, tax classification and originating document.
  - name: line amounts
    kind: money
    required: true
    computed: true
    notes: >-
      The database maintains adjustments and applications and calculates the
      remaining line debt.
  - name: tax lines and exemption
    kind: collection
    required: false
    computed: false
    notes: >-
      Retains the tax zone, class, rate, amount and exemption used at issue
      without resolving posting accounts.
  - name: totals and balance due
    kind: money
    required: true
    computed: true
    notes: >-
      Aggregates the line amounts with database maintenance and consistency
      checks.
  - name: revision
    kind: integer
    required: true
    computed: true
    notes: Identifies successive amendments before posting.
  - name: card-fee policy
    kind: enum
    required: true
    computed: false
    notes: >-
      Records whether card fees are absent, mandatory or optional, using the
      request or unit default.
  - name: card-fee detail
    kind: json
    required: false
    computed: true
    notes: >-
      Explains the fee invoice's connection to its settlement and the
      contributing billed amounts.
  - name: template
    kind: reference
    required: false
    computed: false
    notes: >-
      Selects the invoice rendering design, falling back through the unit
      configuration to the built-in template.
  - name: 'memo, notes and purchase order number'
    kind: text
    required: false
    computed: false
    notes: Carries the editable description of the customer's purchase.
  - name: source and order reference
    kind: text
    required: false
    computed: false
    notes: Connects the bill to its creating workflow and external reference.
  - name: creator metadata
    kind: json
    required: false
    computed: false
    notes: >-
      Preserves size-bounded caller context; the service reads collection
      arrangement and source information from it.
  - name: exchange rate
    kind: decimal
    required: false
    computed: false
    notes: >-
      Retains a supplied rate or selects the inverse of the unit's dated rate
      where available.
  - name: receivable recognised at
    kind: timestamp
    required: false
    computed: true
    notes: >-
      Marks receivable recognition and activates the database's
      commercial-content freeze.
  - name: void reason and instant
    kind: text
    required: false
    computed: false
    notes: Records the explanation and time of final cancellation.
  - name: credit memos · lines
    kind: collection
    required: false
    computed: false
    notes: >-
      Contains numbered reductions of selected charges and their apportioned
      tax, with opposing lines on void.
  - name: debit memos · lines
    kind: collection
    required: false
    computed: false
    notes: >-
      Contains numbered extra charges represented by invoice lines whose initial
      price is zero and debited amount carries the charge.
  - name: write-offs · lines
    kind: collection
    required: false
    computed: false
    notes: >-
      Records debt abandoned by either supported accounting method and a
      separate restoration document when reversed.
  - name: billing reversals
    kind: collection
    required: false
    computed: false
    notes: >-
      Links the cancellation operation to every adjustment, fee, credit,
      application and refund it produced.
relationships:
  - to: DOM-ACC-TRX-003
    cardinality: many-to-many through allocations
    ownership: >-
      Allocation records belong to the payment and contribute to the invoice
      line's paid amount.
    cross_service: false
  - to: DOM-ACC-TRX-004
    cardinality: many-to-many through credit applications
    ownership: >-
      Application records belong to the credit and also contribute to the line's
      paid amount.
    cross_service: false
  - to: DOM-ACC-TRX-005
    cardinality: many-to-one
    ownership: The account reads the invoice's financial effects without owning the bill.
    cross_service: false
  - to: DOM-ACC-TRX-006
    cardinality: one-to-one
    ownership: >-
      The invoice and its correction documents share the transaction-record
      shape for identity, batching and history.
    cross_service: false
invariants:
  - id: INV-DOM-ACC-TRX-001-01
    statement: >-
      Replacing a draft requires its current version and rejects stale
      replacements without effects.
    enforced_at:
      - api
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/update-draft.integration.spec.js#it
      refuses an update at a version the draft has moved past (stale)
  - id: INV-DOM-ACC-TRX-001-02
    statement: Draft replacement preserves the existing business unit and currency.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/update-draft.integration.spec.js#it
      refuses a change of business unit: a draft keeps its unit
      (business_unit_mismatch)
  - id: INV-DOM-ACC-TRX-001-03
    statement: >-
      Each extension rounds half away from zero to minor units before the
      invoice sums the resulting line amounts.
    enforced_at:
      - api
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/rounding.integration.spec.js#it
      totals the rounded lines (3422), not a rounding of the unrounded sum
      (3421)
  - id: INV-DOM-ACC-TRX-001-04
    statement: >-
      A real invoice needs lines, an open period and an eligible batch, while a
      pro forma needs lines without a batch; failures before numbering leave the
      sequence unchanged.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/issue.integration.spec.js#it
      refuses the issue when the unit has no assignment rules (batch_required),
      the draft unchanged
  - id: INV-DOM-ACC-TRX-001-05
    statement: >-
      The workspace invoice sequence begins at one million and permits skipped
      numbers without duplicates.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/issue.integration.spec.js#it
      numbers the tenant’s first invoice 1,000,000
  - id: INV-DOM-ACC-TRX-001-06
    statement: >-
      Once recognised, ordinary database writes preserve commercial content
      while allowing designated lifecycle, description and maintained-amount
      changes.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/db/invoices.table.integration.spec.js#it
      refuses a change of an issued line’s amounts (RHA04)
  - id: INV-DOM-ACC-TRX-001-07
    statement: >-
      Maintained amounts determine invoice status, including paid for a newly
      issued zero-value invoice.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/issue.integration.spec.js#it
      is paid at once, its line with it
  - id: INV-DOM-ACC-TRX-001-08
    statement: >-
      An unconverted pro forma has no batch, receivable facts or allocations and
      supports complete deletion.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/issue.integration.spec.js#it
      gives it no batch, no accounting date and no recognition (FC-06)
  - id: INV-DOM-ACC-TRX-001-09
    statement: >-
      Line debt is total plus debits minus payments, credits and write-offs,
      bounded from zero to total plus debits, with header amounts summing the
      lines.
    enforced_at:
      - database
    provenance: documented
    source: >-
      services-accounting:docs/architecture/accounting-2.0/06-integrity-model.md#2.
      Generated balances with CHECK bounds
  - id: INV-DOM-ACC-TRX-001-10
    statement: >-
      Amendment increments revision and preserves any line carrying an
      application or adjustment.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/document-edits/reassign-and-edit.integration.spec.js#it
      removes a line with nothing applied at the next revision, and refuses
      removing or repricing the paid line
  - id: INV-DOM-ACC-TRX-001-11
    statement: >-
      A posting, posted or downloaded batch prevents amendment, document or
      accounting date correction and voiding, while terms, due dates and
      descriptions use separate edit guards.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/invoices/invoice-changes.ts:changeHeader
  - id: INV-DOM-ACC-TRX-001-12
    statement: >-
      Void requires a reason and an invoice without applications or adjustments,
      retaining amounts while cancelling a recognised receivable on the void
      date.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/void.integration.spec.js#it
      is refused invoice_has_money_applied, the invoice unchanged
  - id: INV-DOM-ACC-TRX-001-13
    statement: >-
      A credit memo is limited to outstanding debt plus releasable paid value
      and leaves no effects when it exceeds that limit.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/change-memos/credit-memos.integration.spec.js#it
      writes nothing: no memo, no ledger line, no fact, no event
  - id: INV-DOM-ACC-TRX-001-14
    statement: >-
      Voiding a memo appends dated opposite lines once and retains the original
      document.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/change-memos/credit-memos.integration.spec.js#it
      returns the invoice’s balances to what they were before the memo
  - id: INV-DOM-ACC-TRX-001-15
    statement: >-
      Restoring a write-off creates a separately numbered opposite document and
      neither member of that pair supports another reversal.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/write-offs/write-offs.integration.spec.js#it
      answers the reversal: a second write-off, numbered next, its lines
      negating the first’s
  - id: INV-DOM-ACC-TRX-001-16
    statement: >-
      Issue retains tax lines by rate without posting accounts and later
      reductions use that recorded determination.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/issue-tax.integration.spec.js#it
      writes one tax line per rate on the dues line, naming the zone and the
      rate and no account
  - id: INV-DOM-ACC-TRX-001-17
    statement: >-
      Creation selects the card-fee policy and receivable recognition protects
      it from ordinary changes; pro forma issue alone does not activate that
      freeze.
    enforced_at:
      - api
      - service
      - database
    provenance: observed
    source: >-
      services-accounting:db/migrations/20261019013149_invoice_ship_to_address.sql:refuse_frozen_invoice_changes;
      services-accounting:modules/transactions/services/invoices/invoice-drafts.ts
  - id: INV-DOM-ACC-TRX-001-18
    statement: >-
      Billing-reversal preparation commits its financial steps together or rolls
      them all back.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      refuses a reversal dated in no open period (period_not_open), writing
      nothing
  - id: INV-DOM-ACC-TRX-001-19
    statement: >-
      Invoice and correction records contain no custom-field storage and the
      module registration supplies no custom-field capability declaration.
    enforced_at:
      - api
      - service
    provenance: documented
    source: >-
      services-accounting:docs/milestones/plans/ACCT-M2-plan.md#7a. Entity
      capabilities (R2-ARCH-001)
physical:
  - invoices
  - invoice_lines
  - invoice_tax_lines
  - credit_memos
  - credit_memo_lines
  - credit_memo_tax_lines
  - debit_memos
  - debit_memo_lines
  - debit_memo_tax_lines
  - write_offs
  - write_off_lines
  - reversals
  - invoices_v
  - credit_memos_v
  - debit_memos_v
  - write_offs_v
evidence:
  - >-
    services-accounting at f47cb263: modules/transactions/db/invoices.table.ts,
    invoice-lines.table.ts, invoice-tax-lines.table.ts, credit-memos.table.ts,
    credit-memo-lines.table.ts, memo-tax-lines.table.ts, debit-memos.table.ts,
    debit-memo-lines.table.ts, write-offs.table.ts, write-off-lines.table.ts,
    reversals.table.ts, document-vocabularies.ts; services/invoices/*,
    change-memos/*, write-offs/*, reversals/*; aws/api/invoices.schemas.ts
    (creator metadata).
  - >-
    services-accounting at f47cb263:
    docs/architecture/accounting-2.0/02-decisions.md (M1-1, M1-4 to M1-6, A-1,
    A-4, A-14, A-17, R-1, C-10), 05-lifecycles.md §1, 06-integrity-model.md §2
    to §4.
  - >-
    The superseded invoice adjustment concept’s facets (memos, freed money,
    write-offs, negating documents, billing reversals) are designed here.
  - >-
    services-accounting:db/migrations/20261019013149_invoice_ship_to_address.sql
    (shipping address, line ships flag and recognition-based protection)
---
# Invoice

## What It Models

Invoice covers customer billing and the documents that adjust that billing. Credit and debit memos, write-offs and billing reversals remain distinct records within this concept. A pro forma represents a quotation before receivable recognition.

## Identity and Attributes

The attributes describe the billed party, commercial terms, charges and financial position. Recognition separates editable preparation from protected commercial content; posting account selection belongs to batch management.

## Relationships

Allocations and credit applications connect receipts and customer credit to invoice lines. CRM supplies customer context, Books supplies configuration, and batch management supplies the posting boundary.

## Invariants

The invariant rows distinguish database protections from command eligibility checks. Their cited evidence identifies which conditions are tested and which are read from implementation or recorded architecture.

## How It Is Stored and Shared

Transactions owns billing and correction storage. Authorized console reads, service-function calls and dataset queries provide distinct access surfaces. Receivable change events provide the financial integration surface for Commerce.

## Open Design Questions

Staff billing without an order still needs a tax-ownership decision. The approved amendment direction lacks a working console connection, and memo editors assume draft behavior that the commands do not implement. Recognition-based protection also requires clearer treatment of issued pro formas.
