Skip to content

Statements Workflow

1. Executive Summary

Purpose

The Statements workflow provides the ability to generate, preview, and download PDF financial summary documents for clients, deals, revenue items, and accounts-receivable aging. Statements consolidate payment activity from the worksheet and settlement lifecycle into human-readable documents delivered to clients and their parties. Unlike invoices (which are formal payment requests sent outbound to buyers or clients), statements are informational summaries: they confirm what was received, how it was split, what UTA retained as commission, and what was paid out. The workflow sits downstream of the full cash flow — it can only report on posted payment_item and approved participant_settlement records, meaning all upstream processes (receipt, worksheet, settlement, approval, bank transmission, GL posting) must be complete before the activity appears on a statement.

Scope

Covered:

  • Generating Client (Artist) Statements showing all posted payments received for a client within a date range, with commission breakdown and third-party payout detail
  • Previewing client statement transaction data and selectively excluding individual payment items before generating the PDF
  • Generating Settlement Statements (deal-engagement view) summarizing guarantee, overage, commission, and net amounts per engagement for a client over a date range
  • Generating Deal Statements showing all revenue items and billing item (receivable) details for a single deal with payee allocations
  • Generating Settlement Statements V2 (revenue-item view) showing cash receipts, receivables, and settlement distributions for a specific revenue item within a deal
  • Generating AR Aging Statements for all or a specific client, classifying open receivables into aging buckets as of a given date
  • Generating Invoices for clients (commission invoices) or buyers (total-due invoices) from selected billing items
  • Storing all generated PDF artifacts in object storage with metadata in generated_statement
  • Viewing and re-downloading previously generated statements from the statement history

Not covered (documented separately):

Key Objectives

  • Provide clients, artists, and their representatives with accurate, printable summaries of financial activity
  • Allow cash processors and settlement approvers to generate and review settlement documentation before or after payment transmission
  • Maintain a persistent, downloadable history of all generated PDFs with storage coordinates for retrieval and audit

2. Process Overview

mermaid
flowchart TD
    A[User opens Statement Generator] --> B{Select statement type}
    B --> C[Client Statement]
    B --> D[Settlement Statement\n Engagement view]
    B --> E[Deal Statement]
    B --> F[Settlement Statement V2\n Revenue Item view]
    B --> G[Invoice]
    B --> H[AR Aging Statement]

    C --> C1[Select client,\ndate range, currency]
    C1 --> C2[Preview transactions\nOptionally exclude items]
    C2 --> C3[Generate PDF]

    D --> D1[Select client,\ndate range, currency]
    D1 --> D2[Generate PDF\ndirectly]

    E --> E1[Select deal]
    E1 --> E2[Generate PDF\ndirectly]

    F --> F1[Select deal,\nthen revenue item]
    F1 --> F2[Generate PDF\ndirectly]

    G --> G1[Select invoice type\nClient or Buyer]
    G1 --> G2[Select UTA entity\nUS or UK]
    G2 --> G3[Select party,\ncheck billing items]
    G3 --> G4[Generate PDF]

    H --> H1[Optional client filter\nand as-of date]
    H1 --> H2[Generate PDF]

    C3 --> I[PDF returned to browser]
    D2 --> I
    E2 --> I
    F2 --> I
    G4 --> I
    H2 --> I

    I --> J{Save to storage?}
    J -->|Yes| K[Upload PDF to object storage\nInsert generated_statement record]
    J -->|No| L[Return PDF only]

    K --> M[Statement History updated]
    M --> N[User can re-download\nfrom history tab]

Walkthrough

  1. Select statement type — The user selects one of six statement types on the Generate tab: Client Statement, Settlement Statement (engagement view), Deal Statement, Settlement Statement V2 (revenue-item view), Invoice, or AR Aging Statement. Each type has its own parameter form.

  2. Supply parameters — For client-scoped statements, the user selects a client (party), date range, and currency. For deal-scoped statements, the user selects a deal and optionally a specific revenue item. For invoices, the user selects whether the target is a client or buyer, the UTA entity (US or UK), and the billing items to include.

  3. Preview (Client Statement only) — Before generating a Client Statement, the user can preview the transaction list. The preview shows each posted payment_item record as a row with gross amount, agency commission, and net amount. The user can uncheck individual rows to exclude them from the final PDF. Running totals update in real time to reflect excluded items.

  4. Generate PDF — The user triggers generation. The service queries posted payment and settlement data, aggregates it, renders a PDF using the appropriate template, and returns the result. For all statement types, the PDF is uploaded to object storage and a generated_statement record is inserted.

  5. Download or preview — After generation, the PDF is available for immediate browser preview (opens in a new tab) or download. The generated statement_ref is displayed so the user can track the document.

  6. Statement History — All previously generated and stored statements appear in the History tab. Any stored statement can be re-downloaded by retrieving the PDF from object storage using the stored generated_statement.s3_key.


3. Business Rules

3.1 Client Statement Reports Posted Payment Items Only

Business rule: A Client Statement includes only payment_item records where payment_item.payment_item_posting_status_cd = 'P' (Posted) and payment_item.client_id matches the selected client, within the selected date range (payment_item.posting_dt between date_from and date_to inclusive). Unposted, cancelled, or failed payment items are excluded.

Foundation reference: Get Client Statement Payment Items

Workflow context: If no posted payment items exist for the selected client and date range, the generated PDF contains the message "No transactions found for the selected date range." The "Generate Statement" button in the preview panel is disabled when all transactions have been excluded via checkboxes (zero included items).


3.2 Transaction Exclusion Is a User-Controlled Filter

Business rule: When previewing a Client Statement, any payment items the user unchecks are excluded from the generated PDF only — the underlying payment_item records are not modified. The exclusion is applied in-memory at generation time and recorded in generated_statement.metadata.excludedPaymentItemIds for audit purposes.

Foundation reference: Generate Client Statement

Workflow context: The statement preview table shows a master checkbox in the header that selects or deselects all rows at once. Individual rows can be toggled. The count of excluded items is shown in the card header. The "Generate Statement" button label includes the count of included items, e.g., "Generate Statement (5 items)".


3.3 Settlement Statement Aggregates by Deal Engagement

Business rule: A Settlement Statement (engagement view) groups participant_settlement_item records by payment_item.deal_id to create one engagement row per deal. The query joins participant_settlement_item to payment_item via participant_settlement_item.payment_item_id, filters by participant_settlement_item.payment_party_id = the selected client, and restricts payment_item.posting_dt to the date range. Each engagement accumulates guarantee (payment amount), commission due (from participant_settlement_item.participant_settlement_commission_amt or computed as amount × commission percentage), and deposit received.

Foundation reference: Get Settlement Engagements


3.4 Deal Statement Aggregates Billing Items Across All Revenue Items

Business rule: A Deal Statement is generated for a single deal.deal_id. It retrieves all sales_item (revenue item) records linked to the deal, then all billing_item records under each revenue item, with their REV and PAY billing_item_detail amounts and cash-applied amounts from cash_receipt_application. The statement shows both open (uncollected) and closed (collected) receivables. Payee allocations are derived from deal_party records.

Foundation reference: Get Deal Statement Data


3.5 Settlement Statement V2 Scopes to a Single Revenue Item

Business rule: A Settlement Statement V2 is scoped to a single sales_item.sales_item_id (revenue item), not to a client or date range. It shows all billing_item records under that revenue item, the cash_receipt records applied to them (via cash_receipt_split and cash_receipt_worksheet), and how the PAY portion was distributed among payees via cash_receipt_payout linked to participant_settlement_item. The revenue item is always selected within the context of a deal (user first picks a deal, then a revenue item within it).

Foundation reference: Get Settlement Statement V2 Data


3.6 Invoice Generation Creates an invoice Record and Bridge Rows

Business rule: Generating an invoice from the statements page creates an invoice record (status 'DRAFT') and links the selected billing_item records to it via billing_item_document rows. The invoice_number is generated sequentially per entity per calendar year using the invoice_number_sequence table. Once a billing item is linked to an invoice via billing_item_document, it is excluded from future "available for invoicing" queries for the same document type.

Foundation reference: Generate Invoices from Billing Items

Workflow context: The invoice UI surfaces a simplified form: the user selects whether the invoice is for a client (COMMISSION type, using REV billing item detail amounts) or for a buyer (TOTAL_DUE type, using PAY billing item detail amounts), then selects a party and billing items. Billing items are auto-selected on party selection. A preview below the selection table shows the subtotal, applicable tax (UK VAT at 20% or US NRA withholding at 30%), and total due. These tax previews are display-only calculations in the UI and do not write to any table.

IMPORTANT

The 20% VAT and 30% WHT amounts shown in the Invoice Generator UI are display estimates only. They are not persisted or applied to the invoice record. Production invoice tax handling must be driven by the authoritative tax calculation engine via WithholdingTaxService — see Worksheets Workflow for the production tax flow.


3.7 AR Aging Statement Classifies Open Receivables Into Aging Buckets

Business rule: An AR Aging Statement computes the age of open billing_item records as of a given date. Receivables are classified into standard aging buckets (Current: 0–30 days, 31–60 days, 61–90 days, 91–120 days, Over 120 days) based on billing_item.billing_item_due_dt relative to the as-of date. When the "Open items only" flag is set, only billing_item records without complete cash application are included.

Foundation reference: Get AR Aging Data


3.8 All Generated Statements Are Persisted to Object Storage

Business rule: Every PDF generated through the statements workflow is uploaded to object storage and a generated_statement record is inserted with generation_status_cd = 'COMPLETED'. The s3_bucket and s3_key values are stored so the PDF can be retrieved later via the history tab. The statement_ref is a unique identifier prefixed by type: CS- for client statements, SS- for settlement statements, DS- for deal statements.

Foundation reference: Persist Generated Statement

Workflow context: The history tab queries generated_statement filtering for generation_status_cd = 'COMPLETED' and shows the 50 most recent records ordered by generated_statement.generated_dt descending. Re-download retrieves the file using the stored s3_key.


3.9 Statement History Is Read-Only

Business rule: Previously generated statements in the history tab cannot be deleted, recalled, or regenerated in place. Each generation creates a new record. If a user needs an updated statement, they generate a new one; the old records remain for audit purposes.

Foundation reference: Get Generated Statements


4. Data Access & Operations References

4.1 Queries Used

OperationFoundation DocPurpose in This Workflow
getClientsForStatementTODO: Document in foundation/queries/invoices-and-statements.mdLoad the client dropdown on page mount. Queries party where active_ind = true, ordered by display_name, limit 100.
getClientStatementPreviewGet Client Statement Payment ItemsFetch the transaction list for the Client Statement preview panel before PDF generation.
getGeneratedStatementsGet Generated StatementsLoad the history tab with metadata for all completed generated_statement records. Joins party for client name.
downloadStatementGet Generated Statement by IDRetrieve s3_key and file_name for a stored statement to initiate a download from object storage.
getDealsForStatementTODO: Document in foundation/queries/invoices-and-statements.mdLoad the deal dropdown for Deal Statement and Settlement Statement V2 cards. Queries deal ordered by deal_id descending, limit 100. Supports optional name/reference search.
getRevenueItemsForStatementTODO: Document in foundation/queries/invoices-and-statements.mdLoad revenue items for a selected deal for Settlement Statement V2. Queries sales_item joined to deal, filtered by deal_id, limit 100.
getPartiesForInvoiceTODO: Document in foundation/queries/invoices-and-statements.mdLoad the client or buyer party dropdown for the Invoice Generator. Queries deal_party joined to party, grouped by party, ordered by deal count descending, limit 100.
getBillingItemsForInvoiceGet Billing Item Details Available for InvoicingLoad billing items for the selected party in the Invoice Generator. Uses REV amounts for CLIENT invoices, PAY amounts for BUYER invoices. Filters out zero-amount items.
getSettlementEngagementsGet Settlement EngagementsAggregate settlement items by deal for the Settlement Statement (engagement view) PDF.
getClientTransactionsGet Client Statement Payment ItemsAggregate posted payment items by posting date and deal for the Client Statement PDF. Groups by posting_dt and deal_id.
getDealStatementDataGet Deal Statement DataRetrieve deal header, revenue items, receivables, cash applications, and payee allocations for the Deal Statement PDF.
getSettlementStatementV2DataGet Settlement Statement V2 DataRetrieve revenue item, cash receipts, receivables, and distribution data for Settlement Statement V2.
getARAgingDataGet AR Aging DataRetrieve open billing items classified into aging buckets for the AR Aging Statement PDF.
getDefaultUTAEntityTODO: Document in foundation/queries/invoices-and-statements.mdFetch the first uta_entity record with address and contact methods for use in PDF statement headers.

4.2 Procedures Used

OperationFoundation DocTrigger in This Workflow
generateClientStatementGenerate Client StatementUser clicks "Generate Statement" after previewing and optionally excluding transactions on the Client Statement card.
generateSettlementStatementGenerate Settlement StatementUser clicks "Generate Settlement Statement" on the Settlement Statement (engagement view) card.
generateDealStatementGenerate Deal StatementUser clicks "Generate Deal Statement" after selecting a deal on the Deal Statement card.
generateSettlementStatementV2Generate Settlement Statement V2User clicks "Generate Settlement Statement" after selecting a deal and revenue item on the Settlement Statement V2 card.
generateInvoiceGenerate Invoices from Billing ItemsUser clicks "Generate Invoice" after selecting party, billing items, and entity type on the Invoice Generator card. Creates invoice, increments invoice_number_sequence, and inserts billing_item_document rows.
generateARAgingStatementGenerate AR Aging StatementUser clicks "Generate AR Aging Statement" on the AR Aging card.
persistGeneratedStatementPersist Generated StatementCalled automatically after every successful PDF generation. Uploads PDF to object storage and inserts generated_statement row with generation_status_cd = 'COMPLETED'.

5. Key User Actions

5.1 Preview Client Statement Transactions

Preconditions:

  • A client (party) must be selected from the dropdown.
  • date_from and date_to must both be populated.
  • Currency must be selected (defaults to 'USD').

Procedure reference: Get Client Statement Payment Items

Steps:

  1. User selects a client, date range, and currency in the Client Statement card.
  2. User clicks "Preview & Edit Transactions".
  3. The service fetches all posted payment_item records for the client within the date range and returns them as a transaction list with gross, commission, and net amounts.
  4. The transaction list appears in the preview panel below the form with per-row amounts and a running summary footer.

Postconditions:

  • Transaction data is loaded into client-side state. No generated_statement record is created.
  • Each transaction row represents one payment_item record, grouped by posting_dt and deal_id, showing payment_item.payment_item_id, posting date, deal reference, project name, memo, gross amount, agency commission, and net amount.

UI trigger: "Preview & Edit Transactions" button. Visible at all times on the Client Statement card. Enabled when a client, date_from, and date_to are all populated.


5.2 Generate Client Statement

Preconditions:

  • A client, date range, and currency must be selected.
  • Preview mode must be active (user has clicked "Preview & Edit Transactions").
  • At least one transaction must remain included (not all unchecked).

Procedure reference: Generate Client Statement

Steps:

  1. User reviews the transaction list in preview mode and optionally unchecks transactions to exclude.
  2. User clicks "Generate Statement (N items)".
  3. The service re-queries the full transaction set, filters out excluded payment_item.payment_item_id values, aggregates totals, renders the PDF using the Client Statement template, uploads the PDF to object storage, and inserts a generated_statement record.
  4. The PDF is returned as a base64-encoded string for immediate browser preview or download.

Postconditions:

  • A generated_statement row is inserted with statement_type_cd = 'CLIENT_STATEMENT', generation_status_cd = 'COMPLETED', client_id set to the selected party, date_from, date_to, currency_cd, s3_bucket, s3_key, file_name, file_size_bytes populated, and metadata containing { totalGross, totalCommission, totalNet, transactionCount, excludedPaymentItemIds }.
  • generated_statement.statement_ref is formatted as CS-{timestamp}-{uuid}.
  • The success panel displays the file name and statement_ref.

UI trigger: "Generate Statement (N items)" button. Visible only in preview mode. Enabled when at least one transaction is included.


5.3 Generate Settlement Statement (Engagement View)

Preconditions:

  • A client, date range, and currency must be selected.

Procedure reference: Generate Settlement Statement

Steps:

  1. User selects a client, date range, and currency in the Settlement Statement card.
  2. User clicks "Generate Settlement Statement".
  3. The service queries participant_settlement_item records where payment_party_id = the client and payment_item.posting_dt falls within the date range, groups by deal, calculates per-engagement totals (guarantee, commission, deposit), renders the Settlement Statement PDF in landscape orientation, uploads to storage, and inserts a generated_statement record.
  4. The PDF is returned for immediate browser preview or download.

Postconditions:

  • A generated_statement row is inserted with statement_type_cd = 'SETTLEMENT_STATEMENT', statement_ref formatted as SS-{timestamp}-{uuid}, and metadata containing { totalGuarantee, totalNetGross, totalCommissionDue, netAmount, engagementCount }.

UI trigger: "Generate Settlement Statement" button on the Settlement Statement card. Enabled when a client, date_from, and date_to are populated.


5.4 Generate Deal Statement

Preconditions:

  • A deal must be selected from the deal dropdown.

Procedure reference: Generate Deal Statement

Steps:

  1. User selects a deal from the Deal Statement card. An info panel shows the deal name, reference, and active/inactive status.
  2. User clicks "Generate Deal Statement".
  3. The service retrieves the full deal structure: deal header, payees from deal_party, revenue items from sales_item, billing items with REV/PAY detail amounts and cash-applied amounts from cash_receipt_application. Renders a landscape legal-size PDF, saves to storage, and returns the result.

Postconditions:

  • A generated_statement row is inserted with statement_type_cd = 'SETTLEMENT_STATEMENT' (deal variant), statement_ref formatted as DS-{timestamp}-{uuid}, and metadata containing deal totals (total gross, commission, cash applied, payable, payee allocations).

UI trigger: "Generate Deal Statement" button. Enabled when a deal is selected.


5.5 Generate Settlement Statement V2 (Revenue Item View)

Preconditions:

  • A deal must be selected.
  • A revenue item (sales_item) within the selected deal must be selected.

Procedure reference: Generate Settlement Statement V2

Steps:

  1. User selects a deal. Revenue items for that deal load automatically into the revenue item dropdown.
  2. User selects a revenue item. An info panel shows the item name, reference, deal name, and gross amount.
  3. User clicks "Generate Settlement Statement".
  4. The service queries cash receipts applied to billing items under the selected revenue item, retrieves cash_receipt_payout and participant_settlement_item records to show how PAY was distributed, renders the PDF, saves to storage, and returns the result.

Postconditions:

  • A generated_statement row is inserted with statement_type_cd = 'SETTLEMENT_STATEMENT' (V2 variant) and metadata containing settlement distribution totals.

UI trigger: "Generate Settlement Statement" button on the Settlement Statement V2 card. Enabled when a revenue item is selected. Revenue item dropdown is disabled until a deal is selected.


5.6 Generate Invoice

Preconditions:

  • Invoice target type must be selected ('CLIENT' or 'BUYER').
  • UTA entity must be selected ('US' or 'UK').
  • A party (client or buyer) must be selected.
  • At least one billing item must be selected.

Procedure reference: Generate Invoices from Billing Items

Steps:

  1. User selects invoice target type (CLIENT or BUYER). The party dropdown reloads with parties of that role from deal_party.
  2. User selects a UTA entity. The UK flag affects invoice grouping logic and tax display.
  3. User selects a party. Billing items for the party load automatically and all are pre-selected.
  4. User reviews the billing item table, toggling checkboxes to include or exclude items. A totals panel shows subtotal, tax estimate, and total due.
  5. User clicks "Generate Invoice (N items)".
  6. The service validates item types, groups items into invoice batches by entity/currency/recipient rules (one client per invoice for UK entity), generates sequential invoice numbers, inserts invoice records with status_cd = 'DRAFT', inserts billing_item_document rows, renders the invoice PDF, and returns the result.

Postconditions:

  • One or more invoice records are created with status_cd = 'DRAFT' and invoice_number formatted as {prefix}-{year}-{sequence}.
  • billing_item_document rows are inserted: document_type_cd = 'CI' for COMMISSION invoices, 'BI' for TOTAL_DUE invoices.
  • invoice_number_sequence.current_sequence is incremented for each entity + calendar year combination used.
  • The success panel displays the file name and invoice number.

UI trigger: "Generate Invoice (N items)" button on the Invoice Generator card. Enabled when a party is selected and at least one billing item is checked.


5.7 Generate AR Aging Statement

Preconditions:

  • No required parameters. Client filter and as-of date are optional.

Procedure reference: Generate AR Aging Statement

Steps:

  1. User optionally selects a client and/or as-of date on the AR Aging card. The "Open Items Only" toggle defaults to enabled.
  2. User clicks "Generate AR Aging Statement".
  3. The service queries billing_item records, computes age relative to the as-of date using billing_item.billing_item_due_dt, classifies into aging buckets, renders the PDF, saves to storage, and returns the result.

Postconditions:

  • A generated_statement row is inserted with statement_type_cd = 'AR_STATEMENT'.

UI trigger: "Generate AR Aging Statement" button on the AR Aging card. Always enabled.


5.8 Re-Download Statement from History

Preconditions:

  • A generated_statement record with generation_status_cd = 'COMPLETED' and a populated s3_key must exist.

Procedure reference: Get Generated Statement by ID

Steps:

  1. User opens the Statement History tab. History loads automatically, showing the 50 most recent completed statements.
  2. User locates the statement in the history table and clicks the download icon.
  3. The service retrieves generated_statement.s3_key and fetches the PDF buffer from object storage using the S3 download API.
  4. The PDF is returned as base64 and triggered as a browser file download.

Postconditions:

  • No database records are created or updated. The PDF file in object storage is accessed read-only.

UI trigger: Download icon button in the Actions column of the history table. Always visible for completed statements.


6. Permissions & Role-Based Access

NOTE

The PoC statements page does not enforce role-based access. The page is accessible to any authenticated user. Production must restrict invoice generation to appropriate approver roles as described below.

ActionCASH_MANAGERCASH_PROCESSORSETTLEMENT_APPROVERIT
Preview Client Statement transactionsYesYesYesYes
Generate Client StatementYesYesYesYes
Generate Settlement Statement (engagement view)YesYesYesYes
Generate Deal StatementYesYesYesYes
Generate Settlement Statement V2YesYesYesYes
Generate InvoiceYesYes
Generate AR Aging StatementYesYesYesYes
View Statement HistoryYesYesYesYes
Re-download from HistoryYesYesYesYes

Field-level restrictions:

  • The Invoice Generator UI exposes a UK entity toggle that affects invoice grouping and tax display. Production should derive the entity from billing_item.uta_entity_id rather than relying on a user-supplied toggle.
  • generated_statement.generated_by should be populated with the authenticated user's identity. In the PoC, this field defaults to 'system' because session resolution is not yet implemented.

7. Integration Points

7.1 Upstream

SourceData ProvidedMechanism
Worksheets workflowPosted payment_item records with payment_item_posting_status_cd = 'P' and payment_item.posting_dtFK lookup — payment_item.client_id and payment_item.posting_dt used for client statement transaction queries
Settlements workflowparticipant_settlement and participant_settlement_item records with commission amounts and payee allocationsFK lookup — participant_settlement_item.payment_party_id and participant_settlement_item.payment_item_id used for settlement engagement queries
Billing Items workflowbilling_item, billing_item_detail, and sales_item records with gross amounts, due dates, and detail type codesFK lookup — billing items scoped by deal, revenue item, or party for invoice generation and deal/settlement statement queries
Cash Receipts workflowcash_receipt, cash_receipt_split, cash_receipt_worksheet, cash_receipt_application, and cash_receipt_payout recordsFK lookup — cash receipt application and payout amounts used in Settlement Statement V2 to show cash applied vs. receivables

7.2 Downstream

ConsumerData ConsumedMechanism
External clients and their partiesGenerated PDF statement documentsBrowser download triggered by user; PDF delivered as file attachment
Invoice lifecycleinvoice record created with status_cd = 'DRAFT'INSERT into invoice; downstream invoice workflow (issue, void, mark paid) consumes the created record — see Invoicing Workflow
Audit trailgenerated_statement records with storage coordinates and metadataFK reference persisted in generated_statement; retrievable by administrators and auditors

7.3 External Integrations

SystemDirectionProtocolNotes
Object Storage (S3-compatible)Outbound (upload) and Inbound (download)S3 API (PutObject / GetObject)Generated PDFs are uploaded via s3Service.uploadPdf() using a structured key pattern: {type}/{clientId}/{dateRange}. Re-downloads use s3Service.downloadPdf(). In the PoC development environment, a local file_path may be used instead of S3 when S3 is not configured.

8. Functional Screen Requirements

8.1 Statement Generator Page

Route: /statements

Data loading:

  • getClientsForStatement — queries active party records on page mount to populate client dropdown; limit 100, ordered by party.display_name

Generate Tab

The Generate tab hosts all PDF generation forms presented as separate expandable cards, one per statement type. All cards appear on the same tab simultaneously.

Conditional display:

  • All six statement type cards are always visible on the Generate tab.
  • Each card operates independently; selecting parameters in one card does not affect others.

Client Statement Sub-section

The Client Statement card generates a per-client payment activity summary for a date range.

Field / ColumnSourceEditable?Condition
Clientparty.party_id, party.display_nameYesAlways; populated from getClientsForStatement
From DateUser inputYesAlways; pre-set to 2024-01-01 on load
To DateUser inputYesAlways; pre-set to 2024-12-31 on load
CurrencyUser inputYesAlways; defaults to 'USD'; options: USD, EUR, GBP, CAD

Conditional display:

  • "Preview & Edit Transactions" button enabled when client, date_from, and date_to are all populated.
  • Transaction preview panel replaces the button after a successful preview fetch.
  • "Cancel" button in preview panel returns the card to the input form and clears the transaction list.
  • "Generate Statement (N items)" button appears in preview mode; label reflects the number of included (non-excluded) transactions.
  • Button is disabled when all transactions are excluded (0 included items).
  • Success panel appears after generation; it shows file name, statement_ref, and "Preview" / "Download" buttons.
  • Error message appears if the server action returns an error.

Transaction Preview Table (inside Client Statement card)

Shows posted payment items returned by the preview query, one row per payment_item grouped by posting date and deal.

Field / ColumnSourceEditable?Condition
Include checkboxClient state (excludedIds set)YesAlways in preview mode
Datepayment_item.posting_dtNoAlways
Deal/Projectdeal.deal_reference, deal.deal_nameNoAlways; "-" when deal reference is null
Memopayment_item.payment_item_nameNoAlways; "-" when null
GrossComputed: sum of payment_item_amt for the grouped transactionNoAlways
CommissionComputed: sum of amounts for payment_item_type_cd = 'S' itemsNoAlways
NetComputed: gross − commission − third-party payout amountsNoAlways

Grid features:

  • Sortable columns: None (ordered by payment_item.posting_dt descending)
  • Filters: None
  • Row selection: Checkbox per row (multi-select); checked = included in PDF, unchecked = excluded
  • Pagination: No; all results returned

Conditional display:

  • Master checkbox in table header toggles all rows selected or deselected.
  • Excluded rows render at reduced opacity.
  • "N item(s) excluded" badge shown in card header when excludedIds.size > 0.
  • Totals summary panel below the table updates live as checkboxes change, showing Total Gross, Total Commission, Total Net for included items.

Settlement Statement (Engagement View) Sub-section
Field / ColumnSourceEditable?Condition
Clientparty.party_id, party.display_nameYesAlways; shared client list from page-level state
From DateUser inputYesAlways
To DateUser inputYesAlways
CurrencyUser inputYesAlways; defaults to 'USD'

Conditional display:

  • "Generate Settlement Statement" button enabled when client, date_from, and date_to are populated.

Deal Statement Sub-section
Field / ColumnSourceEditable?Condition
Dealdeal.deal_id, deal.deal_name, deal.deal_reference, deal.active_indYesAlways; loaded from getDealsForStatement
Deal info paneldeal.deal_name, deal.deal_reference, deal.active_indNoVisible when a deal is selected

Conditional display:

  • Deal dropdown is disabled when no deals are available or while loading.
  • Info panel shows deal name, reference, and "Active" / "Inactive" status when a deal is selected.
  • "Generate Deal Statement" button enabled when a deal is selected.

Settlement Statement V2 Sub-section
Field / ColumnSourceEditable?Condition
Dealdeal.deal_id, deal.deal_name, deal.deal_reference, deal.active_indYesAlways
Revenue Itemsales_item.sales_item_id, sales_item.name, sales_item.sales_item_ref, sales_item.gross_amtYesEnabled after a deal is selected; reloads when deal changes
Revenue item info panelsales_item.name, sales_item.sales_item_ref, deal.deal_name, sales_item.gross_amtNoVisible when a revenue item is selected

Conditional display:

  • Revenue item dropdown shows "Select a deal first" placeholder until a deal is chosen.
  • Revenue item dropdown disabled while loading or when no revenue items exist for the selected deal.
  • "Generate Settlement Statement" button enabled when a revenue item is selected.

Invoice Generator Sub-section
Field / ColumnSourceEditable?Condition
Invoice ForUser input: 'CLIENT' or 'BUYER'YesAlways; defaults to 'CLIENT'
UTA EntityUser input: 'US' or 'UK'YesAlways; defaults to 'US'
Partyparty.party_id, party.display_name, deal countYesReloads when Invoice For changes
Billing Items table (checkbox)billing_item.billing_item_id stateYesVisible after party is selected
Billing item descriptiondeal.deal_name, sales_item.sales_item_idNoAlways in billing items table
Due Datebilling_item.billing_item_due_dtNoAlways in billing items table; "-" when null
Amountbilling_item_detail.billing_item_detail_amt (REV for CLIENT, PAY for BUYER)NoAlways in billing items table
SubtotalComputed: sum of selected itemsNoVisible when billing items are selected
VAT @ 20%Computed: subtotal × 0.20NoVisible when isUKEntity = true
WHT @ 30%Computed: subtotal × 0.30NoVisible when US entity and targetType = 'BUYER'
Total DueComputed: subtotal ± taxNoVisible when billing items are selected

Grid features:

  • Sortable columns: None
  • Filters: None
  • Row selection: Checkbox per row; all rows auto-selected on party load; toggle to include/exclude
  • Pagination: No; limited to 100 items with overflow-y-auto scroll

Conditional display:

  • Billing items table is hidden until a party is selected.
  • "Generate Invoice (N items)" button label reflects current selection count.
  • Button disabled when no billing items are selected.

AR Aging Statement Sub-section
Field / ColumnSourceEditable?Condition
Client filterparty.party_id, party.display_nameYesOptional; when blank, all clients are included
As-of DateUser inputYesOptional; defaults to today (new Date())
Open Items OnlyBooleanYesAlways; defaults to true

Conditional display:

  • "Generate AR Aging Statement" button is always enabled (no required fields).

History Tab

Shows the 50 most recent completed generated_statement records, ordered by generated_dt descending.

Field / ColumnSourceEditable?Condition
Statement Refgenerated_statement.statement_refNoAlways
Clientparty.display_name joined via generated_statement.client_idNoAlways; "Unknown" when party not found or client_id is null
Typegenerated_statement.statement_type_cdNoAlways; underscores replaced with spaces for display
Date Rangegenerated_statement.date_from + generated_statement.date_toNoVisible when both fields are populated; "-" otherwise
Generatedgenerated_statement.generated_dtNoAlways; "-" when null
Sizegenerated_statement.file_size_bytesNoAlways; formatted as B / KB / MB; "-" when null
Download buttonN/AN/AAlways visible for each row

Grid features:

  • Sortable columns: None (fixed order by generated_dt descending)
  • Filters: None exposed in UI (server action supports client_id and statement_type filter parameters)
  • Row selection: None
  • Pagination: No; 50 records shown

Conditional display:

  • "Refresh" button in card header reloads history on demand.
  • Loading spinner shown while history is fetching.
  • "No statements have been generated yet." message shown when the result set is empty.

9. Additional Diagrams

mermaid
stateDiagram-v2
    [*] --> PENDING : generated_statement INSERT
    PENDING --> GENERATING : Generation process starts
    GENERATING --> COMPLETED : PDF stored in object storage
    GENERATING --> FAILED : Error during generation or upload

The generated_statement.generation_status_cd state machine above is fully described in Invoices and Statements Data Model — Section 3.2.

**PoC Artifact:** In the PoC, generation is synchronous. The `PENDING` and `GENERATING` states are never persisted — records are written directly with `generation_status_cd = 'COMPLETED'` after a successful generation and upload. Production may introduce asynchronous job-based PDF generation that passes through each intermediate state.

mermaid
sequenceDiagram
    participant U as User
    participant S as Statements Page
    participant A as Server Actions
    participant SVC as StatementService
    participant PDF as PDF Generator
    participant ST as Object Storage
    participant DB as Database

    U->>S: Select client, date range, currency
    U->>S: Click "Preview & Edit Transactions"
    S->>A: getClientStatementPreviewAction(clientId, dateFrom, dateTo)
    A->>SVC: getClientStatementPreview()
    SVC->>DB: Query posted payment_item records
    DB-->>SVC: Transaction rows
    SVC-->>A: { client, transactions, totals }
    A-->>S: Preview data
    S->>U: Display transaction table

    U->>S: Uncheck some transactions
    U->>S: Click "Generate Statement (N items)"
    S->>A: generateClientStatementAction(clientId, ..., excludedIds)
    A->>SVC: generateClientStatement(..., excludedIds)
    SVC->>DB: Re-query payment_item (filter excluded IDs)
    DB-->>SVC: Filtered transactions
    SVC->>PDF: generateClientStatement(statementData)
    PDF-->>SVC: PDF buffer
    SVC->>ST: uploadPdf(s3Key, buffer)
    ST-->>SVC: { bucket, key }
    SVC->>DB: INSERT generated_statement (generation_status_cd = 'COMPLETED')
    DB-->>SVC: generated_statement_id
    SVC-->>A: { success, buffer, fileName, statementRef }
    A-->>S: { pdfBase64, fileName, statementRef }
    S->>U: Show success panel with download / preview buttons

10. Cross-References

DocumentRelationship
Invoices and Statements Data ModelDefines generated_statement, invoice, invoice_number_sequence, invoice_bank_details, and billing_item_document tables used throughout this workflow
Invoices and Statements QueriesSpecifies all data retrieval operations for client transactions, settlement engagements, deal statements, AR aging, and generated statement history
Invoices and Statements ProceduresSpecifies all data mutation operations: invoice creation (with number generation and bridge-table linking), statement PDF generation, and persistence to object storage
Invoicing WorkflowDownstream: invoices generated here have status_cd = 'DRAFT'; the invoicing workflow manages the issue, void, and paid status transitions
Worksheets WorkflowUpstream: worksheet apply and approve create posted payment_item records that appear on client statements; also the source of production tax calculations
Settlements WorkflowUpstream: participant_settlement_item records created during settlement drive the engagement-view Settlement Statement
Payments WorkflowUpstream: bank-sent and GL-posted payment items satisfy the payment_item_posting_status_cd = 'P' requirement for client statements
Billing Items WorkflowUpstream: billing_item and billing_item_detail records created via the billing items workflow are queried for invoice generation and deal statements
AR Aging WorkflowRelated: the AR Aging Statement produced here is a PDF export of the same aging data displayed interactively in the AR Aging report screen

11. Gherkin Scenarios

gherkin
Feature: Statements - Client Statement Generation

  Scenario: Generate a client statement for a client with posted payments in the period
    Given party "Taylor Swift" has party_id = 42 and active_ind = true
    And payment_item records exist for client_id = 42 with posting_dt between 2024-01-01 and 2024-12-31
    And payment_item.payment_item_posting_status_cd = 'P' for all those records
    When the user selects client "Taylor Swift", date_from = 2024-01-01, date_to = 2024-12-31, currency = 'USD'
    And clicks "Preview & Edit Transactions"
    Then the transaction preview table shows all posted payment_item rows for client_id = 42 in that period
    And the totals panel shows the aggregate gross, commission, and net amounts

  Scenario: Exclude transactions from a client statement before generation
    Given a client statement preview is loaded with 5 transactions for client_id = 42
    And payment_item with payment_item_id = 1001 has payment_item_amt = 5000.00 and payment_item_type_cd = 'S'
    When the user unchecks the row for payment_item_id = 1001
    Then the "1 item(s) excluded" indicator appears in the card header
    And the totals panel decreases by 5000.00 for both Gross and Commission
    And the "Generate Statement (4 items)" button reflects 4 included items

  Scenario: Generate statement creates generated_statement record with exclusion metadata
    Given the user has excluded payment_item_id = 1001 and 4 transactions remain included
    When the user clicks "Generate Statement (4 items)"
    Then a generated_statement row is inserted with statement_type_cd = 'CLIENT_STATEMENT'
    And generated_statement.generation_status_cd = 'COMPLETED'
    And generated_statement.client_id = 42
    And generated_statement.metadata.excludedPaymentItemIds = [1001]
    And generated_statement.metadata.transactionCount = 4
    And generated_statement.statement_ref begins with 'CS-'
    And the success panel shows the file name and statement_ref

  Scenario: Client with no posted payments in the period sees an empty statement message
    Given party "New Artist" has party_id = 99
    And no payment_item records exist for client_id = 99 with posting_dt in 2024
    When the user selects party 99, date_from = 2024-01-01, date_to = 2024-12-31, and previews
    Then the preview panel shows "No transactions found for the selected date range."
    And the "Generate Statement (0 items)" button is disabled
gherkin
Feature: Statements - Settlement Statement (Engagement View)

  Scenario: Generate a settlement statement showing engagements for a client
    Given participant_settlement_item records exist with payment_party_id = 42
    And those items are joined to payment_item records with posting_dt between 2024-01-01 and 2024-12-31
    And the payment_item records are linked to deal records
    When the user selects client "Taylor Swift" (party_id = 42), date range 2024-01-01 to 2024-12-31
    And clicks "Generate Settlement Statement" on the Settlement Statement card
    Then a PDF is generated with one engagement row per distinct deal.deal_id
    And each row shows guarantee, commission_due, and deposit_received aggregated from participant_settlement_item
    And a generated_statement row is inserted with statement_type_cd = 'SETTLEMENT_STATEMENT'
    And generated_statement.statement_ref begins with 'SS-'

  Scenario: Settlement statement for a client with no settlement items in period
    Given party_id = 99 has no participant_settlement_item records with posting_dt in 2024
    When the user generates a settlement statement for party 99 for date range 2024
    Then the PDF renders with the engagement table showing "No engagements found for the selected date range."
    And a generated_statement row is inserted (empty statements are valid and stored)
gherkin
Feature: Statements - Deal Statement Generation

  Scenario: Generate a deal statement for an active deal with revenue items and receivables
    Given deal with deal_id = 10 and deal_name = "World Tour 2024" has active_ind = true
    And sales_item records with sales_item_id = 101 and 102 exist under deal_id = 10
    And billing_item records exist under each sales_item with billing_item_detail records for REV and PAY
    When the user selects deal "World Tour 2024" and clicks "Generate Deal Statement"
    Then the PDF shows a deal header with deal_name = "World Tour 2024" and deal.deal_reference
    And revenue items 101 and 102 each have a section showing their receivable rows
    And each receivable row shows billing_item_detail.billing_item_detail_amt for REV (commission) and PAY (payable)
    And a generated_statement row is inserted with statement_ref beginning with 'DS-'

  Scenario: Deal statement for an inactive deal still generates successfully
    Given deal with deal_id = 20 has active_ind = false
    When the user selects the inactive deal and generates a deal statement
    Then the PDF generates without error
    And the deal details block on the PDF shows the "Inactive" status indicator
    And a generated_statement row is inserted
gherkin
Feature: Statements - Invoice Generation

  Scenario: Generate a commission invoice for a client using US entity rules
    Given party "Live Nation" (party_id = 55) exists with partyRoleTypeCd = 'CLIENT' in 3 deal_party rows
    And billing_item records exist for that client with billing_item_detail_type_cd = 'REV'
    And no billing_item_document rows exist for those billing items with document_type_cd = 'CI'
    When the user selects "Client (Commission Invoice)", "US" entity, party "Live Nation"
    And all 3 billing items are auto-selected
    And clicks "Generate Invoice (3 items)"
    Then an invoice record is inserted with invoice_type_cd = 'COMMISSION' and status_cd = 'DRAFT'
    And invoice.invoice_number is formatted as 'UTA_US-{current_year}-{6-digit-sequence}'
    And invoice_number_sequence.current_sequence is incremented for the US entity + current year
    And 3 billing_item_document rows are inserted with document_type_cd = 'CI'
    And the success panel shows the generated invoice_number

  Scenario: UK entity invoice enforces one-client-per-invoice grouping
    Given the user selects "UK" entity and selects billing items from 2 different clients
    When the user clicks "Generate Invoice"
    Then 2 separate invoice records are created: one per client
    And both invoices have multi_client_ind = false
    And both have the UK entity's invoice_number prefix

  Scenario: Billing items already linked to an invoice are not available for re-invoicing
    Given billing_item_id = 500 already has a billing_item_document row with document_type_cd = 'CI'
    When the user loads billing items for a CLIENT invoice for the same client
    Then billing_item_id = 500 does not appear in the billing items table
gherkin
Feature: Statements - Statement History and Re-download

  Scenario: Re-download a previously generated statement from the history tab
    Given a generated_statement row exists with generated_statement_id = 77
    And generated_statement.generation_status_cd = 'COMPLETED'
    And generated_statement.s3_key = 'CLIENT_STATEMENT/42/2024-01-01_2024-12-31.pdf'
    And generated_statement.file_name = 'CS-1710000000-ABCD1234.pdf'
    When the user opens the Statement History tab
    And clicks the download icon for generated_statement_id = 77
    Then the PDF is retrieved from object storage using s3_key = 'CLIENT_STATEMENT/42/2024-01-01_2024-12-31.pdf'
    And the file downloads to the browser as 'CS-1710000000-ABCD1234.pdf'
    And no generated_statement record is created or modified

  Scenario: History tab shows only completed statements
    Given generated_statement rows exist with generation_status_cd values 'COMPLETED', 'FAILED', and 'PENDING'
    When the user opens the Statement History tab
    Then only the row with generation_status_cd = 'COMPLETED' appears in the history table
    And rows with 'FAILED' and 'PENDING' are excluded

  Scenario: History tab loads the 50 most recent completed statements
    Given 60 completed generated_statement rows exist ordered by generated_dt
    When the user opens the Statement History tab
    Then the table shows 50 rows
    And they are ordered by generated_statement.generated_dt descending
    And the 10 oldest records do not appear

Confidential. For internal use only.