---
id: CAP-ACC-TRX-001
title: Issue customer bills and numbered quotes
feature: FEAT-ACC-TRX-01
product_area: accounting
module: transactions
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes:
  - CAP-ACC-INV-001
  - CAP-ACC-INV-002
  - CAP-ACC-INV-003
  - CAP-ACC-INV-004
  - CAP-ACC-INV-005
  - CAP-ACC-INV-014
  - CAP-ACC-INV-019
  - CAP-ACC-INV-022
  - CAP-ACC-INV-026
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D3'
  - 'services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D12'
  - 'services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D14'
  - 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#M1-1'
  - 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#A-1'
  - 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#A-17'
  - 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#D-01'
purpose: Staff and Commerce turn proposed charges into documents customers can settle.
outcomes:
  - Staff and Commerce turn proposed charges into documents customers can settle.
  - >-
    A quote follows the pro forma path until conversion recognizes its receivable. Tax ownership for
    staff-created charges remains a Product decision.
concepts:
  - CON-ACC-TRX-001
  - CON-ACC-TRX-006
actors:
  - ACT-ACC-012
  - ACT-ACC-021
surfaces:
  - console
  - api
preconditions:
  - 'Books and Products provide the business unit, supported currencies, products and fiscal calendar.'
postconditions:
  - Issue recognizes invoice debt in a batch awaiting posting.
permissions:
  - key: accounting.invoices.create
    where_checked: api
    scope: tenant
  - key: accounting.invoices.adjust
    where_checked: api
    scope: tenant
  - key: accounting.invoices.delete
    where_checked: api
    scope: tenant
  - key: accounting.invoices.read
    where_checked: api
    scope: tenant
  - key: accounting.tax.calculate
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-ACC-TRX-001-01
    proved_by: [ATS-ACC-TRX-001-01, ATS-ACC-TRX-001-17, TST-ACC-TRX-065]
    statement: >-
      A draft replacement requires the version last read and replaces the document as a whole; a stale version
      leaves it unchanged.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    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)
    origin: 'services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D3'
  - id: BR-CAP-ACC-TRX-001-02
    proved_by: [ATS-ACC-TRX-001-02, TST-ACC-TRX-065]
    statement: Changing a draft’s business unit or currency requires creating another draft.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    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)
    origin: 'services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D12'
  - id: BR-CAP-ACC-TRX-001-03
    proved_by: [ATS-ACC-TRX-001-03, TST-ACC-TRX-046, TST-ACC-TRX-222]
    statement: >-
      Invoice lines require active sellable products from the invoice’s unit, prices in its currency, and a
      currency supported by that unit; invalid input creates no draft.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/create-draft.integration.spec.js#it
      refuses an inactive product (product_not_sellable)
    origin: 'services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D3'
    examples:
      positive: USD dues using the unit’s active product can be billed in USD.
      negative: A product belonging to a different unit fails the unit check.
  - id: BR-CAP-ACC-TRX-001-04
    proved_by: [ATS-ACC-TRX-001-04, TST-ACC-TRX-010, TST-ACC-TRX-046, TST-ACC-TRX-061]
    statement: >-
      Amounts use whole currency minor units, line extensions round once half away from zero, totals sum those
      rounded lines, and discounts cannot exceed extensions.
    kind: calculation
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    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)
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#D-04'
    examples:
      positive: An extension of 832.5 yen becomes 833 yen.
      negative: Discounting beyond the extended charge rejects the draft.
  - id: BR-CAP-ACC-TRX-001-05
    proved_by: [ATS-ACC-TRX-001-05, ATS-ACC-TRX-019-08, TST-ACC-TRX-046, TST-ACC-TRX-047]
    statement: >-
      An explicit due date takes precedence over requested or customer-default terms, otherwise the invoice
      date applies; the due date cannot precede the invoice date.
    kind: calculation
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/customer-terms-precedence.integration.spec.js#it
      takes the bill-to’s default terms when the request names none, the due date 45 days after the invoice
      date
    origin: 'services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D3'
  - id: BR-CAP-ACC-TRX-001-06
    proved_by: [ATS-ACC-TRX-001-06, TST-ACC-TRX-062]
    statement: 'A supplied service period includes both dates, with its end on or after its start.'
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/service-period-order.integration.spec.js#it
      refuses a period ending before it starts with a 400 naming the service period
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-001-07
    proved_by: [ATS-ACC-TRX-001-07, ATS-ACC-TRX-001-17, ATS-ACC-TRX-020-09, TST-ACC-TRX-056]
    statement: >-
      Issue requires at least one line, an open fiscal period and an eligible batch selected explicitly or by
      assignment rules; refusal leaves the draft unnumbered.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    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
    origin: 'services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D12'
  - id: BR-CAP-ACC-TRX-001-08
    proved_by: [ATS-ACC-TRX-001-08, ATS-ACC-TRX-001-18, TST-ACC-TRX-052, TST-ACC-TRX-056]
    statement: >-
      Invoice numbering begins at one million within the workspace and permits gaps while preventing
      duplicates.
    kind: policy
    enforced_at:
      - service
      - database
    must_prove: true
    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
    origin: none
    note: >-
      The cited build recommendation does not establish Product approval; the authority gap remains open in
      FND-ACC-TRX-035.
  - id: BR-CAP-ACC-TRX-001-09
    proved_by: [ATS-ACC-TRX-001-09, TST-ACC-TRX-056, TST-ACC-TRX-231]
    statement: >-
      General ledger accounts are selected and frozen at posting, so missing account setup does not prevent
      issue.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/issue.integration.spec.js#it
      resolves no account on a line of a product with no setup either (the unit’s defaults are the posting’s
      to read)
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#A-1'
  - id: BR-CAP-ACC-TRX-001-10
    proved_by: [ATS-ACC-TRX-001-10, ATS-ACC-TRX-001-17, TST-ACC-TRX-022]
    statement: >-
      Ordinary writes cannot change issued commercial content or delete an issued real invoice; the supported
      amendment path remains available for eligible unposted lines.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    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)
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#D-01'
  - id: BR-CAP-ACC-TRX-001-11
    proved_by: [ATS-ACC-TRX-001-11, TST-ACC-TRX-056, TST-ACC-TRX-063, TST-ACC-TRX-236]
    statement: >-
      Invoice status follows its monetary position, with an outstanding amount keeping it open and a
      zero-total invoice becoming paid immediately.
    kind: calculation
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/invoices/issue.integration.spec.js#it
      is paid at once, its line with it
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#M1-1'
  - id: BR-CAP-ACC-TRX-001-12
    proved_by: [ATS-ACC-TRX-001-12, ATS-ACC-TRX-001-17, ATS-ACC-TRX-020-09, TST-ACC-TRX-048, TST-ACC-TRX-056, TST-ACC-TRX-220]
    statement: >-
      A pro forma receives an invoice number without a batch or receivable, converts once while retaining that
      number, and can be deleted only before conversion; drafts can also be deleted.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    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)
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#D-01'
  - id: BR-CAP-ACC-TRX-001-13
    proved_by: [ATS-ACC-TRX-001-13, TST-ACC-TRX-054, TST-ACC-TRX-055, TST-ACC-TRX-232]
    statement: >-
      Issue freezes tax calculated from the line’s class and applicable billing or shipping address, exempts
      eligible organizations, and refuses taxable staff invoices lacking an address.
    kind: calculation
    enforced_at:
      - service
      - database
    must_prove: true
    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
    origin: OQ-ACC-TRX-001
  - id: BR-CAP-ACC-TRX-001-14
    proved_by: [ATS-ACC-TRX-001-14, TST-ACC-TRX-002]
    statement: >-
      Creation selects the requested card-fee policy or the unit default, and issue freezes the choice of
      none, required or optional.
    kind: policy
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/e2e/card-fees.e2e.spec.js#it stamps the body’s policy on
      the invoice, and the unit’s default (optional) when the body names none
    origin: 'services-accounting:docs/architecture/accounting-2.0/02-decisions.md#A-17'
  - id: BR-CAP-ACC-TRX-001-15
    proved_by: [ATS-ACC-TRX-001-15]
    statement: >-
      With mandatory service periods enabled, an automatically deferred line lacking its period prevents issue
      before a number is allocated.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-accounting:modules/transactions/services/invoices/invoice-service-periods.ts:requireServicePeriods
    origin: none
  - id: BR-CAP-ACC-TRX-001-16
    proved_by: [ATS-ACC-TRX-001-16]
    statement: >-
      Issue preserves a stored exchange rate, otherwise selects the inverse dated unit rate, and keeps no rate
      when neither is available.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-accounting:modules/transactions/services/invoices/invoice-issue.ts:exchangeRateOf'
    origin: none
scenarios:
  - id: SC-CAP-ACC-TRX-001-01
    given: The member has a New York billing address and the unit has an eligible batch.
    when: 'Prepare dues and gala charges, save and revise the draft, then issue it.'
    then: The open numbered invoice joins the batch with charge-level receivables and applicable New York tax.
    provenance: test
    source: 'react-console:acceptance/accounting/playwright/journeys/invoices/ACT-ACC-0180.spec.ts#ACT-ACC-0180'
  - id: SC-CAP-ACC-TRX-001-02
    given: An event quote has already been issued as pro forma.
    when: 'Update its terms, attempt a memo, then convert the quote.'
    then: Memo creation fails; conversion recognizes the same numbered document as debt.
    provenance: test
    source: 'react-console:acceptance/accounting/playwright/journeys/invoices/ACT-ACC-0182.spec.ts#ACT-ACC-0182'
  - id: SC-CAP-ACC-TRX-001-03
    given: No assignment rule exists for the business unit.
    when: Issue a draft without selecting a batch.
    then: Refusal preserves the draft and leaves numbering untouched.
    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
edge_cases: []
constraints:
  - An invoice contains no more than five hundred lines.
depends_on:
  - CAP-ACC-TRX-019
related:
  - CAP-ACC-TRX-002
  - CAP-ACC-TRX-005
  - CAP-ACC-TRX-016
  - CAP-ACC-TRX-020
journeys:
  - JNY-ACC-TRX-001
  - JNY-ACC-TRX-006
open_questions:
  - OQ-ACC-TRX-001
evidence:
  - >-
    services-accounting at f47cb263875bbc0c5640fba7dae6785ec32695f8:
    modules/transactions/aws/api/invoices.routes.ts (createInvoiceDraft, updateInvoiceDraft,
    deleteInvoiceDraft, issueInvoice, convertProFormaInvoice), service-periods.routes.ts (listServicePeriods),
    tax.routes.ts (calculateTax), transaction-actions.routes.ts; services/invoices/invoice-drafts.ts,
    invoice-issue.ts, invoice-tax.ts, invoice-amounts.ts, invoice-service-periods.ts;
    services/tax/tax-calculation.ts, tax-quotes.ts; db/invoices.table.ts, invoice-lines.table.ts,
    invoice-tax-lines.table.ts; docs/accounting/invoices.md, tax.md; tests e2e/invoices.e2e.spec.js,
    invoices-issue-at-once.e2e.spec.js, tax.e2e.spec.js, card-fees.e2e.spec.js;
    integration/services/invoices/create-draft, update-draft, delete-draft, issue, issue-tax,
    issue-tax-ship-to, rounding, service-period-order, customer-terms-precedence;
    integration/db/invoices.table.
  - >-
    react-console at baf6dae382d6f41dce976c7f848667ccc37e076f:
    app/(console)/console/[tenantId]/accounting/invoices/new, [invoiceId]/edit;
    components/accounting/invoices/invoice-editor-screen.tsx; acceptance journeys ACT-ACC-0180, 0182, 0184,
    0186, 0200, 0214 and their Playwright specs; inventory rules RUL-ACC-INV-001 to 012, 019, 044, 046, 048,
    049.
controls: [TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002]
exercised_by: [FAS-ACC-TRX-01-01, FAS-ACC-TRX-01-03, FAS-ACC-TRX-01-04, FAS-ACC-TRX-01-05]
suites: [TST-ACC-TRX-002, TST-ACC-TRX-010, TST-ACC-TRX-022, TST-ACC-TRX-046, TST-ACC-TRX-047, TST-ACC-TRX-048, TST-ACC-TRX-052, TST-ACC-TRX-054, TST-ACC-TRX-055, TST-ACC-TRX-056, TST-ACC-TRX-061, TST-ACC-TRX-062, TST-ACC-TRX-063, TST-ACC-TRX-065, TST-ACC-TRX-220, TST-ACC-TRX-222, TST-ACC-TRX-231, TST-ACC-TRX-232, TST-ACC-TRX-236]
---

# Issue customer bills and numbered quotes

## Purpose

Staff and Commerce turn proposed charges into documents customers can settle.

## How It Works

Staff select the customer, business unit and currency before preparing product lines. Saving creates an unnumbered working document. Another editor’s saved changes prevent an obsolete replacement from overwriting it. Issue checks the dates, line eligibility and available batch before recognizing debt. Accounting retains the numbered document and tracks later settlement through its line balances. A quote follows the pro forma path until conversion recognizes its receivable. Tax ownership for staff-created charges remains a Product decision.

## Relationships

- Maintain customer-specific collection choices supplies or continues the related financial work.
- Correct issued bills before posting supplies or continues the related financial work.
- Prepare and deliver invoice documents supplies or continues the related financial work.
- Find money records and understand available work supplies or continues the related financial work.
- Coordinate financial commands across applications supplies or continues the related financial work.
