Invoices and Statements Data Model
1. Executive Summary
Purpose
The Invoices and Statements domain manages the generation, tracking, and storage of two categories of outbound financial documents: invoices and statements. Invoices are formal payment requests produced from billing items and transmitted to buyers or clients. Statements are summary PDF documents that consolidate financial activity for a client, settlement, or accounts-receivable aging view over a date range. Both document types produce PDF artifacts stored externally (object storage), with metadata retained in the database for retrieval, audit, and lifecycle management. This domain sits downstream of billing and upstream of cash collection: once billing items exist with confirmed amounts, invoices are generated; once payments flow through worksheets and settlements, statements are produced.
Scope
Covered:
invoice— Header record for a generated invoice, linking a set of billing items to a recipient, currency, and UTA entity.invoice_number_sequence— Per-entity, per-year sequential counter used to generate unique invoice numbers.invoice_bank_details— Payment instructions (wire, ACH, BACS, IBAN) displayed on invoice PDFs, keyed by UTA entity and currency.generated_statement— Metadata and storage coordinates for generated PDF statements of any type.
Not covered (documented separately):
billing_item,billing_item_detail— The receivables that invoices are generated from. See Billing Items Data Model.billing_item_document— The bridge table linking billing items to invoices. Documented in Billing Items Data Model (that document owns the bridge table).participant_settlement,payment_item— Settlement and payment records that settlement statements summarize. See Settlements Data Model.party,address— Recipient and bank address records. See Parties Data Model.
2. Data Model
2.1 Entity-Relationship Diagram
erDiagram
invoice ||--o{ billing_item_document : "referenced via document_id (polymorphic)"
invoice }o--|| uta_entity : "issued by"
invoice }o--|| party : "recipient_party_id"
invoice }o--o| party : "contracted_party_id"
invoice_number_sequence }o--|| uta_entity : "sequence per entity"
invoice_bank_details }o--|| uta_entity : "bank details per entity"
invoice_bank_details }o--o| address : "bank_address_id"
generated_statement }o--o| party : "client_id"
billing_item_document }o--|| billing_item : "billing_item_id"
invoice {
serial invoice_id PK
varchar invoice_number UK
integer uta_entity_id FK
date issue_date
date due_date
varchar billing_terms_cd
varchar invoice_type_cd
varchar invoice_recipient_cd
boolean multi_client_ind
varchar currency_cd
integer recipient_party_id FK
varchar recipient_address_id
integer contracted_party_id FK
varchar contracted_address_id
decimal total_gross_amt
decimal total_commission_amt
varchar status_cd
}
invoice_number_sequence {
serial invoice_number_sequence_id PK
integer uta_entity_id FK
integer current_year
integer current_sequence
varchar prefix
}
invoice_bank_details {
serial invoice_bank_details_id PK
integer uta_entity_id FK
varchar currency_cd
varchar bank_name
integer bank_address_id FK
varchar account_number
varchar account_name
varchar aba_routing_number
varchar swift_code
varchar iban
varchar sort_code
boolean is_active
}
generated_statement {
serial generated_statement_id PK
varchar statement_type_cd
varchar statement_ref
integer client_id FK
date date_from
date date_to
varchar currency_cd
varchar s3_bucket
varchar s3_key
varchar file_path
varchar file_name
integer file_size_bytes
varchar generation_status_cd
text error_message
jsonb metadata
}
billing_item_document {
serial billing_item_document_id PK
integer billing_item_id FK
varchar document_type_cd
integer document_id
varchar payment_term_ref
}
uta_entity {
serial uta_entity_id PK
}
party {
serial party_id PK
}
address {
serial address_id PK
}
billing_item {
serial billing_item_id PK
}2.2 invoice
Represents a generated invoice document. Each invoice belongs to exactly one UTA entity, one currency, and one recipient party. Invoices are created from selected billing item details and can be either Commission invoices (sent to clients for UTA's revenue share) or Total Due invoices (sent to buyers for the full amount owed).
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
invoice_id | serial | Yes | Auto | Primary key. Referenced by billing_item_document.document_id for invoice types CI and BI. |
invoice_number | varchar(50) | Yes | — | Human-readable invoice number. Format: {prefix}-{year}-{sequence}, e.g., UTA_US-2026-000001. Globally unique via uq_invoice_number constraint. |
uta_entity_id | integer | Yes | — | FK to uta_entity. The UTA legal entity issuing this invoice. All billing items on the invoice must share this entity. |
issue_date | date | Yes | — | Date the invoice was generated. |
due_date | date | Yes | — | Payment deadline, calculated from billing_terms_cd offset applied to issue_date. |
billing_terms_cd | varchar(20) | No | 'DUE_RECEIPT' | Payment terms code (BILLING_TERMS_CD). Determines how many days after issue_date payment is due. See Section 5. |
invoice_type_cd | varchar(20) | Yes | — | Type of invoice (INVOICE_TYPE_CD). COMMISSION invoices cover REV billing item details; TOTAL_DUE invoices cover PAY billing item details. See Section 5. |
invoice_recipient_cd | varchar(20) | Yes | — | Who the invoice is addressed to (INVOICE_RECIPIENT_CD). See Section 5. |
multi_client_ind | boolean | No | false | true when the invoice combines billing items from multiple clients. Only permitted for US entities with invoice_recipient_cd = 'BUYER'. UK entities always have false. |
currency_cd | varchar(10) | Yes | — | Currency of the invoice (CURRENCY_CD). All billing items on the invoice must share this currency. |
recipient_party_id | integer | Yes | — | FK to party. The bill-to party (client or buyer depending on invoice_recipient_cd). |
recipient_address_id | varchar(100) | No | — | auth_address_id from the party addresses system, identifying the recipient's mailing address for the PDF. |
contracted_party_id | integer | No | — | FK to party. The talent or artist for UK Total Due invoices where the contracted party differs from the recipient. |
contracted_address_id | varchar(100) | No | — | auth_address_id for the contracted party's address, used on UK Total Due invoice PDFs. |
total_gross_amt | decimal(15,2) | Yes | — | Total invoice amount. Sum of the billing_item_detail.gross_amt values for all billing item details on this invoice. Transmitted as string to preserve precision. |
total_commission_amt | decimal(15,2) | No | — | UTA commission total. Populated for COMMISSION invoices only; null for TOTAL_DUE invoices. Transmitted as string to preserve precision. |
status_cd | varchar(20) | Yes | 'DRAFT' | Invoice lifecycle status (INVOICE_STATUS_CD). See Section 3. |
NOTE
Pure audit columns (created_by, created_dt, updated_by, updated_dt) are omitted from this table unless they carry business meaning.
2.3 invoice_number_sequence
Tracks sequential invoice numbers per UTA entity per calendar year. Each entity has its own number series with a configurable prefix. The sequence counter increments atomically on each invoice creation and resets to zero at the start of each new year.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
invoice_number_sequence_id | serial | Yes | Auto | Primary key. |
uta_entity_id | integer | Yes | — | FK to uta_entity. The entity this sequence belongs to. |
current_year | integer | Yes | — | Calendar year for this sequence counter. Unique per entity via uq_invoice_seq_entity_year. |
current_sequence | integer | Yes | 0 | Last-used sequence number for this entity and year. Incremented atomically when a new invoice is created. |
prefix | varchar(10) | Yes | — | Invoice number prefix for this entity. Examples: UTA_US, UTA_UK, ML, UTA_S, RC. Derived from uta_entity.invoice_prefix. |
NOTE
Pure audit columns (created_by, created_dt, updated_by, updated_dt) are omitted from this table unless they carry business meaning.
2.4 invoice_bank_details
Stores bank payment instructions printed on invoice PDFs. Each record represents the bank details for a specific UTA entity and currency combination. This table is distinct from bank_account records used for cash receipt and outbound payment processing — invoice_bank_details exists solely for document presentation.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
invoice_bank_details_id | serial | Yes | Auto | Primary key. |
uta_entity_id | integer | Yes | — | FK to uta_entity. The entity these bank details belong to. Unique per entity + currency via uq_invoice_bank_entity_currency. |
currency_cd | varchar(10) | Yes | — | Currency these bank details apply to (CURRENCY_CD). |
bank_name | varchar(200) | Yes | — | Name of the bank as it appears on the invoice PDF. |
bank_address_id | integer | No | — | FK to address. Physical address of the bank branch. Joined fields appear on the PDF as the bank's mailing address. |
account_number | varchar(50) | Yes | — | Bank account number. |
account_name | varchar(200) | No | — | Account holder name displayed on the invoice. |
aba_routing_number | varchar(20) | No | — | US domestic routing number (9 digits). Used for USD wire/ACH instructions. |
swift_code | varchar(20) | No | — | SWIFT/BIC code (8–11 characters). Used for international wire instructions. |
iban | varchar(50) | No | — | International Bank Account Number (up to 34 characters). Used for European payment instructions. |
sort_code | varchar(10) | No | — | UK sort code (6 digits, formatted XX-XX-XX). Used for BACS payment instructions. |
is_active | boolean | Yes | true | Whether these bank details are currently in use. Inactive records are retained for historical PDFs. |
NOTE
Pure audit columns (created_by, created_dt, updated_by, updated_dt) are omitted from this table unless they carry business meaning.
2.5 generated_statement
Tracks all generated PDF statement documents with metadata for retrieval and audit. The actual PDF file is stored externally (object storage or local file system); this table holds the storage coordinates, generation status, and generation parameters.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
generated_statement_id | serial | Yes | Auto | Primary key. |
statement_type_cd | varchar(50) | Yes | — | Type of statement (STATEMENT_TYPE_CD). See Section 5. |
statement_ref | varchar(100) | Yes | — | Unique reference identifier displayed on the PDF. Format varies by type: CS-{timestamp}-{uuid} for client statements, SS-{timestamp}-{uuid} for settlement statements. Uniqueness enforced at application layer. |
client_id | integer | No | — | FK to party. The client or party this statement is generated for. null for AR statements not tied to a specific client. |
date_from | date | No | — | Start of the date range covered by the statement. |
date_to | date | No | — | End of the date range covered by the statement. |
currency_cd | varchar(10) | No | — | Currency of the statement (CURRENCY_CD). |
s3_bucket | varchar(255) | No | — | Object storage bucket name where the PDF is stored. |
s3_key | varchar(500) | No | — | Object storage key (path) for the PDF file. Used by the download operation to retrieve the file. |
file_path | varchar(500) | No | — | Local or temporary file system path. Used during development or before upload to object storage. |
file_name | varchar(255) | No | — | Name of the generated PDF file. |
file_size_bytes | integer | No | — | Size of the generated file in bytes. |
generation_status_cd | varchar(20) | No | 'PENDING' | Generation lifecycle status. See Section 3. |
error_message | text | No | — | Error details if generation_status_cd = 'FAILED'. |
metadata | jsonb | No | — | Flexible generation parameters and summary totals specific to the statement type. For client statements: { totalGross, totalCommission, totalNet, transactionCount, excludedPaymentItemIds }. For settlement statements: { totalGuarantee, totalNetGross, totalCommissionDue, netAmount, engagementCount }. |
generated_by | varchar(100) | No | — | User or system process that initiated generation. |
generated_dt | timestamp | No | now() | Timestamp when generation was initiated. |
NOTE
Pure audit columns (created_by, created_dt, updated_by, updated_dt) are omitted from this table unless they carry business meaning.
3. Status Lifecycle
3.1 Invoice Status (INVOICE_STATUS_CD)
| Status | Code | Description | Allowed Transitions |
|---|---|---|---|
| Draft | DRAFT | Invoice has been created but not yet finalized or sent to the recipient. Amounts and line items can be modified. | → Issued (ISSUED), → Void (VOID) |
| Issued | ISSUED | Invoice has been finalized and transmitted to the recipient. No further edits to amounts or line items are permitted. | → Paid (PAID), → Void (VOID) |
| Paid | PAID | Payment has been received and matched against this invoice. Terminal state. | — |
| Void | VOID | Invoice has been cancelled. Can be voided from DRAFT or ISSUED. Terminal state. | — |
stateDiagram-v2
[*] --> DRAFT : Invoice created
DRAFT --> ISSUED : Finalize and issue
DRAFT --> VOID : Cancel
ISSUED --> PAID : Payment received
ISSUED --> VOID : CancelTransition: DRAFT → ISSUED
- Trigger: User finalizes and issues the invoice to the recipient.
- Preconditions: Invoice must have at least one billing item linked via
billing_item_document.invoice.status_cdmust be'DRAFT'. - Side-effects:
invoice.status_cdset to'ISSUED'.invoice.updated_byandinvoice.updated_dtrecorded.
Transition: DRAFT → VOID
- Trigger: User cancels the invoice before it has been sent.
- Preconditions:
invoice.status_cdmust be'DRAFT'. - Side-effects:
invoice.status_cdset to'VOID'.billing_item_documentlinks are not removed — they serve as historical record.
Transition: ISSUED → PAID
- Trigger: Cash receipt is applied against this invoice and matched by the user.
- Preconditions:
invoice.status_cdmust be'ISSUED'. - Side-effects:
invoice.status_cdset to'PAID'.
Transition: ISSUED → VOID
- Trigger: User cancels an already-issued invoice (e.g., issued in error).
- Preconditions:
invoice.status_cdmust be'ISSUED'. - Side-effects:
invoice.status_cdset to'VOID'.
IMPORTANT
PAID and VOID are terminal states. No transition out of either is supported.
3.2 Statement Generation Status (generation_status_cd)
| Status | Code | Description | Allowed Transitions |
|---|---|---|---|
| Pending | PENDING | Statement generation has been requested but not yet started. | → Generating (GENERATING) |
| Generating | GENERATING | PDF generation is in progress. | → Completed (COMPLETED), → Failed (FAILED) |
| Completed | COMPLETED | PDF has been generated and stored. s3_bucket/s3_key or file_path are populated. | — |
| Failed | FAILED | Generation encountered an error. error_message contains details. | — |
stateDiagram-v2
[*] --> PENDING : Statement requested
PENDING --> GENERATING : Generation starts
GENERATING --> COMPLETED : PDF stored successfully
GENERATING --> FAILED : Error during generationTransition: PENDING → GENERATING
- Trigger: The generation process picks up the statement record and begins PDF creation.
- Preconditions:
generation_status_cdmust be'PENDING'. - Side-effects:
generation_status_cdset to'GENERATING'.
Transition: GENERATING → COMPLETED
- Trigger: PDF file successfully generated and stored in object storage.
- Preconditions:
generation_status_cdmust be'GENERATING'. PDF buffer is non-empty. - Side-effects:
generation_status_cdset to'COMPLETED'.s3_bucket,s3_key,file_name,file_size_bytes, andmetadatapopulated with storage coordinates and summary data.
Transition: GENERATING → FAILED
- Trigger: An error is thrown during PDF generation or storage upload.
- Preconditions:
generation_status_cdmust be'GENERATING'. - Side-effects:
generation_status_cdset to'FAILED'.error_messagepopulated with the error detail.
4. Validation & Database Constraints
Unique Constraints
| Table | Constraint | Columns | Business Rule |
|---|---|---|---|
invoice | uq_invoice_number | (invoice_number) | Each invoice number must be globally unique across all entities and years. Atomic sequence increment prevents duplicates under concurrent creation. |
invoice_number_sequence | uq_invoice_seq_entity_year | (uta_entity_id, current_year) | One sequence record per entity per calendar year. Prevents duplicate counters for the same entity and year. |
invoice_bank_details | uq_invoice_bank_entity_currency | (uta_entity_id, currency_cd) | One bank detail record per entity per currency. The system automatically selects the matching record when generating invoice PDFs. |
billing_item_document | uq_billing_item_document_item_type_doc | (billing_item_id, document_type_cd, document_id) | Prevents duplicate links between the same billing item and the same document. |
Business Validation
- Single entity per invoice: All billing item details on an invoice must share the same
uta_entity_id. This is enforced during the grouping step of invoice generation, before any records are written. - Single currency per invoice: All billing item details on an invoice must share the same
currency_cd. Enforced during the same grouping step. - UK entity: one client per invoice: When
uta_entity_idcorresponds to the UK entity,multi_client_indmust befalse. UK invoices always group by client in addition to entity and currency, regardless of themulti_client_indflag on the request. - US entity multi-client restriction: US entities may combine multiple clients on a single invoice only when
invoice_recipient_cd = 'BUYER'and themultiClientInvoiceflag is explicitly settrueon the create request. - Invoice type must match detail type:
COMMISSIONinvoices require REV-type billing item details (billing_item_detail.billing_item_detail_type_cd = 'REV').TOTAL_DUEinvoices require PAY-type details. Mixing types within a single invoice is not permitted. due_datederived frombilling_terms_cd:due_dateis always calculated asissue_date + offset(billing_terms_cd). The offset is0days forDUE_RECEIPT,7forNET_7,14forNET_14,30forNET_30,45forNET_45, and60forNET_60. The field is never set independently.statement_refuniqueness: Uniqueness ofstatement_refingenerated_statementis enforced at the application layer during generation (not by a database constraint). The reference is prefixed by statement type (CS-,SS-) and includes a timestamp and UUID segment to minimize collision risk.- Bank details selection is automatic: When generating an invoice PDF, the system matches
invoice.uta_entity_id+invoice.currency_cdtoinvoice_bank_details.(uta_entity_id, currency_cd)to resolve the correct payment instructions. If no matching active record exists, the PDF is generated without payment instructions.
NOTE
PoC Artifact: In the PoC, invoice status transitions (Draft → Issued → Paid → Void) are not enforced by explicit state-machine guards in the service layer. updateInvoiceStatus accepts any target status. Production should enforce the allowed-transitions table in Section 3.1 as preconditions.
5. Code Master Values
5.1 INVOICE_STATUS_CD
Used by invoice.status_cd.
| Code | Description | Behavior / When Used |
|---|---|---|
DRAFT | Invoice created, not yet finalized. | Default on creation. Invoice is editable. |
ISSUED | Invoice finalized and sent to recipient. | Set when user issues the invoice. Amounts are locked. |
PAID | Payment received against this invoice. | Terminal state. Set when cash is matched to this invoice. |
VOID | Invoice cancelled. | Terminal state. Can be set from DRAFT or ISSUED. |
Default on creation: DRAFT
5.2 INVOICE_TYPE_CD
Used by invoice.invoice_type_cd.
| Code | Description | Behavior / When Used |
|---|---|---|
COMMISSION | Commission invoice sent to the client for UTA's revenue (REV) share. | Requires REV-type billing item details (billing_item_detail_type_cd = 'REV'). Populates total_commission_amt. |
TOTAL_DUE | Full-amount invoice sent to the buyer for the total owed under the deal. | Requires PAY-type billing item details (billing_item_detail_type_cd = 'PAY'). total_commission_amt is not populated. |
Default on creation: Set from the create request; no system default.
5.3 INVOICE_RECIPIENT_CD
Used by invoice.invoice_recipient_cd.
| Code | Description | Behavior / When Used |
|---|---|---|
CLIENT | Invoice is addressed to the client (talent/artist). | recipient_party_id is set to the client's party_id. Always results in one invoice per client. |
BUYER | Invoice is addressed to the buyer (studio, brand, network, platform). | recipient_party_id is set to the buyer's party_id. US entities may optionally combine multiple clients into one invoice (multi_client_ind = true). |
Default on creation: Set from the create request; no system default.
5.4 BILLING_TERMS_CD
Used by invoice.billing_terms_cd. Determines the due_date offset from issue_date.
| Code | Description | Behavior / When Used |
|---|---|---|
DUE_RECEIPT | Due upon receipt. | due_date = issue_date (0 days offset). |
NET_7 | Net 7 days. | due_date = issue_date + 7 days. |
NET_14 | Net 14 days. | due_date = issue_date + 14 days. |
NET_30 | Net 30 days. | due_date = issue_date + 30 days. |
NET_45 | Net 45 days. | due_date = issue_date + 45 days. |
NET_60 | Net 60 days. | due_date = issue_date + 60 days. |
Default on creation: DUE_RECEIPT (applied when no override is provided on the create request).
5.5 DOCUMENT_TYPE_CD (on billing_item_document)
Used by billing_item_document.document_type_cd. Discriminates which document type the document_id references and which billing item detail type is relevant.
| Code | Description | Behavior / When Used |
|---|---|---|
CI | Commission Invoice | Created when a COMMISSION invoice is generated. Links REV billing item details to the invoice. document_id = invoice.invoice_id. |
BI | Buyer Invoice | Created when a TOTAL_DUE invoice is generated. Links PAY billing item details to the invoice. document_id = invoice.invoice_id. |
CM | Credit Memo | Reserved for future use. Represents credit memo adjustments. |
CL | Client Letter | Reserved for future use. Represents client correspondence. |
Default on creation: Set from invoice type at the time of creation; no system default.
5.6 STATEMENT_TYPE_CD
Used by generated_statement.statement_type_cd.
| Code | Description | Behavior / When Used |
|---|---|---|
CLIENT_STATEMENT | Activity summary for a client over a date range. | Generated from posted payment_item records for the client in the given period. statement_ref prefixed CS-. |
SETTLEMENT_STATEMENT | Settlement breakdown accompanying a payment to a client's party. | Generated from participant_settlement_item and payment_item records for the client in the given period. statement_ref prefixed SS-. |
AR_STATEMENT | Accounts receivable aging summary. | Reserved for AR aging exports. Not tied to a specific client. |
INVOICE | Invoice document stored as a generated statement record. | Used when invoice PDFs are persisted via the statement storage path rather than directly. |
Default on creation: Set from the generation request; no system default.
5.7 generation_status_cd
Used by generated_statement.generation_status_cd.
| Code | Description | Behavior / When Used |
|---|---|---|
PENDING | Generation requested, not yet started. | Default on creation. Record created before PDF generation begins. |
GENERATING | PDF generation in progress. | Set when the generation process begins. |
COMPLETED | PDF generated and stored successfully. | Set after successful upload. s3_bucket, s3_key, file_name, and file_size_bytes are populated. |
FAILED | Generation failed. | Set on exception. error_message field contains details. |
Default on creation: PENDING
6. Cross-References
| Document | Relationship |
|---|---|
| Billing Items Data Model | invoice is linked to billing items through the billing_item_document bridge table (owned by the Billing Items area). Each billing_item_document row ties a billing_item_id to a document_id (which is an invoice_id for types CI and BI). The document_type_cd discriminates whether the invoice covers REV details (CI) or PAY details (BI). A billing item detail is considered "already invoiced" when a matching billing_item_document row exists for its parent billing_item_id and the relevant document type. |
| Settlements Data Model | generated_statement with statement_type_cd = 'SETTLEMENT_STATEMENT' is populated from participant_settlement_item and payment_item records. Settlement statements summarize how PAY was divided among the client's party over a period. |
| Parties Data Model | invoice.recipient_party_id and invoice.contracted_party_id reference party. generated_statement.client_id references party. Recipient and contracted party addresses are resolved from the party addresses system using auth_address_id values stored in invoice.recipient_address_id and invoice.contracted_address_id. |
| Deals, Sales Items & Payment Terms Data Model | Settlement statements join deal to group payment activity by engagement. payment_item.deal_id links posted payments back to their originating deal for statement grouping. |