Billing Items Workflow
1. Executive Summary
Purpose
The billing items workflow manages the receivables that UTA expects to collect from buyers on behalf of clients under active deals. Each billing item represents a single expected payment installment from a buyer, derived from the payment terms negotiated in a deal. The system splits every billing item into two detail lines — REV (UTA's commission) and PAY (the client's payout share) — which become the targets against which cash receipts are applied on worksheets. This workflow is the bridge between the deal/revenue world (where gross amounts and commission rates are established) and the cash processing world (where payments are received, applied, and disbursed).
Scope
Covered:
- Viewing, searching, and filtering revenue items and their billing items
- Managing deductions on billing item REV and PAY detail lines
- In-place deduction management: adding, editing, and removing deductions on existing billing items
- Managing payment terms: updating amount, due date, due date status, and payment party; removing a payment term
- Viewing revenue item recognition schedules
- Revenue item modification via the Modify dialog (delegating to the Deal Engine service)
Not covered (documented separately):
- Cash application against billing item details — see Worksheets Workflow
- Write-off approval of REV billing item details — see Write-Offs Workflow
- Invoice and statement generation from billing items — see Invoicing Workflow
- AR aging reporting from billing items — see AR Aging Workflow
- Deal Engine sales block ingestion that creates revenue items and billing items — see Deals Workflow
- Cash matching (linking cash receipts to receivables before worksheet creation) — see Cash Matching Workflow
Key Objectives
- Provide a unified view of expected revenue (revenue items) alongside the corresponding billing installments (billing items) that cash processors use for cash application
- Enable users to adjust billing item deductions (tax withholding, bank charges, discounts, and other reduction types) directly on existing billing items
- Allow users to correct payment term details (amount, due date, payment party) when deal data needs adjustment, with revenue impact optionally propagated upward
- Surface outstanding receivable balances (REV balance, PAY balance, total balance) to support cash application decisions
2. Process Overview
flowchart TD
A[Deal Engine produces sales item and payment terms] --> B[Revenue sync creates revenue_items and billing_items]
B --> C[Each billing_item gets REV and PAY billing_item_detail records]
C --> D{User opens Revenue page}
D --> E[Browse and search revenue items]
E --> F{Select revenue item?}
F -->|Yes| G[View recognition schedules]
F --> H[Browse billing items in lower panel]
H --> I{Select billing item}
I --> J[Manage Deductions]
I --> K[Manage Payment Term]
I --> L[Modify Revenue Item]
J --> M[Save deductions in-place on billing item]
K --> N[Update or remove deal engine payment term]
N --> O[Revenue sync produces updated billing item]
L --> O
M --> P[Updated billing item available for cash application on worksheets]
O --> P
P --> Q[Cash worksheet applies cash to REV and PAY details]Walkthrough
Revenue sync creates receivables — When the Deal Engine produces a sales block containing a sales item and payment terms, the sync process creates one
revenue_itemsrecord per sales item and onebilling_item(with REV and PAYbilling_item_detailrecords) per payment term. Tax deductions are estimated at creation time and stored asbilling_item_deductionrecords on the PAY detail.User browses the Revenue page — The Revenue page loads an initial set of revenue items (filtered by
current_item_ind = trueandrevenue_item_date_status_cd = 'C'by default) and all current, open billing items. Users can search by free text, filter by current/non-current and confirmed/unconfirmed date status, and export results.User selects a revenue item — Clicking a revenue item row loads the associated
revenue_item_schedulesrecords in a side panel, showing the revenue recognition timeline (date, amount, posting status).User browses billing items — The billing items panel below shows the flattened display view of billing items for the current filter, including REV and PAY breakdown, balance, cash applied, and deduction totals. Selecting a billing item row activates action buttons.
User manages deductions — Selecting a billing item and clicking "Manage Deductions" opens a dialog showing REV and PAY detail sections with the current deductions listed. The user can add, edit, or remove deductions and save. Deductions are saved directly on the existing billing item — no rebill, reversal, or new billing item is created.
User manages a payment term — Selecting a billing item that has a
payment_term_refand clicking "Manage Payment Term" opens a dialog to update the amount, due date, payment party, and date status — or to remove the term entirely. Saving delegates to the Deal Engine service, which triggers a revenue sync, producing updated revenue items and billing items.Updated billing items reach cash processing — After deduction changes or payment term updates, the billing items (with
current_item_ind = true,open_item_ind = true) are available for cash application on worksheets.
3. Business Rules
3.1 Exactly Two Details Per Billing Item
Business rule: Every billing item must have exactly two detail records: one with billing_item_detail_type_cd = 'REV' (UTA's commission) and one with 'PAY' (the client's payout share). No billing item may exist with only one detail or with duplicate types.
Foundation reference: Billing Items Data Model — Structural Invariants
Workflow context: The Manage Deductions dialog always renders both a Commission (REV) section and a Pay Out (PAY) section. If a detail is missing, the section is omitted and no deductions for that type can be saved.
3.2 Collection Style Determines PAY Detail Amounts
Business rule: When a billing item's collection_style_cd = 'CLIENT', UTA collects only its commission directly from the client — the buyer pays the client directly. In this case, the PAY detail's billing_item_detail_gross_amt, billing_item_detail_percent, billing_item_detail_amt, billing_item_detail_tax_amt, and billing_item_detail_total_amt are all zero. When collection_style_cd = 'BUYER', PAY detail amounts are calculated normally as gross × (1 - commission rate).
Foundation reference: Billing Items Data Model — Collection Style Impact on PAY
Workflow context: A billing item with collection_style_cd = 'CLIENT' will show zero PAY amounts in the billing items table and no PAY balance. The Manage Deductions dialog will still show the PAY section but all amounts will be zero.
3.3 Deductions Do Not Modify Detail Base Amounts
Business rule: billing_item_deduction records reduce the effective collectible amount for presentation and worksheet matching purposes, but they do not change billing_item_detail_amt or billing_item_detail_total_amt. The base amounts are always gross_amt × percent. Deductions are tracked separately.
Foundation reference: Billing Items Data Model — Calculated Field Rules
Workflow context: In the Manage Deductions dialog, the "Billing Amt" preview is calculated as net_amt − total_deductions for display only. When the user saves, deductions are updated directly on the existing billing item. Detail base amounts (billing_item_detail_amt) are never modified by deduction changes.
3.4 Deductions Are Managed In-Place
Business rule: Deductions are managed directly on the existing billing item without creating reversals or new billing item versions. The manageBillingItemDeductions procedure creates, updates, and deletes billing_item_deduction records in place.
Foundation reference: Billing Items Procedures — Manage Billing Item Deductions
Workflow context: When the user saves deductions, the changes are persisted directly on the existing billing item. The Revenue page refreshes via path revalidation. Note: the immutability/reversal pattern still applies to billing item header and detail changes triggered by revenue sync — only deduction management is in-place.
3.5 Collection Style Override Survives Revenue Sync
Business rule: If a user has manually overridden collection_style_cd on a billing item (collection_style_override_ind = true), that override is preserved when the Deal Engine sends updated payment terms and the revenue sync creates a new billing item version. The sync copies the override style and party rather than recalculating from the payment party.
Foundation reference: Billing Items Data Model — billing_item.collection_style_override_ind
3.6 Open Item Flag Is Recalculated Automatically
Business rule: billing_item.open_item_ind is true when the billing item has outstanding balance — when the absolute difference between cash applied and billing_item_detail_total_amt is >= 0.01 (epsilon) for either the REV or PAY detail. This flag is recalculated whenever cash applications change or whenever a rebill creates a new billing item version.
Foundation reference: Billing Items Data Model — Calculated Field Rules
Workflow context: The billing items panel has a "Show Closed" checkbox (default: off) that filters by open_item_ind. When unchecked, only items with outstanding balances are shown.
3.7 Tax Deductions Are Estimates at Creation; Authoritative at Worksheet Time
Business rule: Tax deduction records (billing_item_deduction rows with types WH_US_NRA, WH_UK_FEU, VAT_ARTIST, VAT_COMM) are auto-calculated and persisted when a billing item is created or updated via revenue sync. These are estimates for display purposes. The worksheet recalculates tax authoritatively when it loads, using the billing item's client_id (or contracted_party_id) and uta_entity_id. The tax_stale_ind flag on billing_item indicates when underlying tax data has changed.
Foundation reference: Billing Items Data Model — billing_item.tax_stale_ind
3.8 Only REV Details Can Be Written Off
Business rule: Write-offs apply only to REV-type billing item details. PAY details remain write_off_status_cd = 'NOT_WRITTEN_OFF' regardless of a write-off action. The company absorbs the commission loss; the client's payout obligation is unaffected.
Foundation reference: Billing Items Data Model — billing_item_detail.write_off_status_cd
Workflow context: The billing items table shows a "Write-Off" badge (WRITTEN_OFF or RECOVERED) on rows where the REV detail has been written off, with a link to the write-off packet. No write-off action is available from the billing items workflow itself; that action is in the Write-Offs workflow.
3.9 Payment Term Changes Trigger Revenue Sync
Business rule: When a user updates a payment term (amount, due date, payment party) via the Manage Payment Term dialog, the change is applied through the Deal Engine service. If "Adjust Revenue" is checked, the total revenue_item_gross_amt is updated. If unchecked, the amount difference is redistributed across remaining payment terms. After the update, the revenue sync creates updated billing items through the reversal/replacement pattern.
Foundation reference: Billing Items Procedures — Manage Payment Term
Workflow context: The "Manage Payment Term" button is only enabled when the selected billing item has a non-null payment_term_ref. The dialog requires a valid amount, due date, and due date status before the Update action can proceed. The Remove action requires confirmation via a secondary dialog.
3.10 Deduction Management Operates on Current Billing Items
Business rule: Deduction management operates on current_item_ind = true billing items. The Manage Deductions dialog loads the current billing item's details and deductions for editing.
Foundation reference: Billing Items Procedures — Manage Billing Item Deductions
Workflow context: The dialog always operates on the effective current billing item.
4. Data Access & Operations References
4.1 Queries Used
| Operation | Foundation Doc | Purpose in This Workflow |
|---|---|---|
searchRevenueItems | Revenue Items — Search Query | Loads revenue items table on page entry and after each search/filter change |
getSchedulesByItemId | Revenue Item Schedules — Lookup by Revenue Item | Loads the recognition schedule side panel when a revenue item row is selected |
getBillingItemsForDisplay | Billing Items — Flattened Display View | Loads the billing items panel; re-fetched when filters change (current/closed/zero toggles, revenue item selection, search term) |
getBillingItemById | Billing Items — Single Record Lookup | Loads billing item header for the Manage Deductions dialog |
getBillingItemDetailsByBillingItemId | Billing Item Details — Lookup by Billing Item | Loads REV and PAY details for the Manage Deductions dialog |
getBillingItemDeductionsByDetailId | Billing Item Deductions — Lookup by Detail | Loads existing deductions for each detail in the Manage Deductions dialog |
getBillingItemsByRevenueItemId | Billing Items — Lookup by Revenue Item | Resolves the current billing item when a non-current item ID is submitted for rebill |
getPaymentTermByRef | Payment Terms — Lookup by Ref | Loads current payment term data into the Manage Payment Term dialog |
getPaymentPartyOptionsForTerm | TODO: Document in foundation/queries/billing-items.md | Loads party options (deal parties + buyer) to populate the Payment Party dropdown in the Manage Payment Term dialog |
getCodeMasterOptions | Code Master — Lookup by Type | Loads deduction type options and date status options for dropdowns |
4.2 Procedures Used
| Operation | Foundation Doc | Trigger in This Workflow |
|---|---|---|
manageBillingItemDeductions | Billing Items Procedures — Manage Billing Item Deductions | User saves changes in the Manage Deductions dialog |
manageDealEnginePaymentTermAction | Billing Items Procedures — Manage Payment Term | User clicks "Save Changes" or confirms "Remove" in the Manage Payment Term dialog |
modifyRevenueItem (via Modify dialog) | TODO: Document in foundation/procedures/billing-items.md | User clicks "Modify" in the revenue items Actions menu |
5. Key User Actions
5.1 Search and Filter Revenue Items
Preconditions:
- User is on the Revenue page (
/revenue)
Procedure reference: Billing Items Queries — Search Revenue Items
Steps:
- User types a search term in the text field and presses Enter; the system submits the term to the server and replaces the revenue items table with results.
- User toggles "Current Items only" checkbox; this re-fetches results with
current_item_indfilter applied. - User toggles "Confirmed Dates Only" checkbox; this re-fetches results with
revenue_item_date_status_cd = 'C'filter applied. - User clicks the refresh button to re-fetch both revenue items and billing items simultaneously.
- Column-level filters refine the current result set on the client side.
Postconditions:
revenue_itemsrows matching the criteria are displayed; initial load defaults tocurrent_item_ind = trueandrevenue_item_date_status_cd = 'C'.
UI trigger: Search input field — press Enter to submit. Checkboxes — toggle to re-fetch. Refresh button — always visible and enabled.
5.2 View Revenue Item Recognition Schedules
Preconditions:
- At least one revenue item is visible in the table
- Revenue item has
revenue_item_rec_style_cd = 'I'(Immediate) or'M'(Monthly);'C'(Cash) generates no schedules
Procedure reference: Billing Items Queries — Get Schedules by Revenue Item
Steps:
- User clicks a revenue item row.
- The system loads
revenue_item_schedulesfor the selectedrevenue_item_idand displays them in a side panel showing date, amount, posting status, and posting date. - Clicking the same row again or the close button collapses the side panel and deselects the revenue item.
Postconditions:
revenue_item_schedulesrows for the selected item are shown in the side panel.
UI trigger: Revenue item row click. Close (×) button to collapse. Always available on any revenue item row.
5.3 Filter and Browse Billing Items
Preconditions:
- User is on the Revenue page
Procedure reference: Billing Items Queries — Billing Items Display View
Steps:
- The billing items panel loads with all current, open billing items by default.
- Selecting a revenue item row filters the billing items panel to show only billing items under that revenue item.
- User toggles "Show Closed" to include billing items where
open_item_ind = false. - User toggles "Show Zero" to include billing items where both REV and PAY amounts are zero (typically
collection_style_cd = 'CLIENT'items). - User clicks a billing item row to select it, activating the "Manage Deductions" and "Manage Payment Term" buttons.
Postconditions:
- Selected billing item row is highlighted; action buttons become enabled.
UI trigger: "Show Closed" and "Show Zero" checkboxes — toggles above the billing items table. Row click — selects item. Always available.
5.4 Manage Deductions
Preconditions:
- A billing item is selected in the billing items table
- The selected billing item has
current_item_ind = true
Procedure reference: Billing Items Procedures — Manage Billing Item Deductions
Steps:
- User clicks "Manage Deductions"; the system loads the billing item header, its REV and PAY details, and all existing
billing_item_deductionrecords. - The dialog shows two sections (Commission / REV and Pay Out / PAY), each with a header row showing percent, net amount, total deductions, and billing amount.
- User adds, edits, or removes deduction rows (type, amount, "Net" flag, comment) in either section.
- User clicks "Save Changes"; deductions are saved directly on the existing billing item. New deductions are created, existing ones are updated, and removed ones are deleted.
Postconditions:
billing_item_deductionrecords updated in-place on the existing billing item's details.- No new
billing_itemorbilling_item_detailrecords are created. billing_item_detail_amtremains unchanged (deductions do not affect base amounts).- Revenue page revalidated; billing items panel refreshes.
UI trigger: "Manage Deductions" button. Visible always in the action bar below the billing items table. Enabled when a billing item row is selected.
5.5 Manage Payment Term
Preconditions:
- A billing item is selected in the billing items table
- The selected billing item has a non-null
billing_item.payment_term_ref
Procedure reference: Billing Items Procedures — Manage Payment Term
Steps:
- User clicks "Manage Payment Term"; the system loads the current payment term data by
payment_term_refand loads party options for the payment party dropdown. - User edits name, payment party, amount, due date, and due date status.
- User optionally checks "Adjust Revenue?" to control whether the amount change updates
revenue_item_gross_amt(checked) or redistributes the difference to other payment terms (unchecked). - User clicks "Save Changes"; validation checks that amount, due date, and due date status are provided. On success, the Deal Engine service updates the payment term, triggering a revenue sync that produces updated billing items.
- Alternatively, user clicks "Remove" and confirms the removal. The payment term is deleted from the Deal Engine, triggering a revenue sync that deactivates the corresponding billing item.
Postconditions:
- Payment term updated (or removed) in the Deal Engine source tables.
- Revenue sync produces updated
revenue_itemsandbilling_itemrecords; the original billing item is reversed and a new current version is created. - Revenue page revalidated.
UI trigger: "Manage Payment Term" button. Visible always in the action bar. Enabled when a billing item is selected AND that item has a non-null billing_item.payment_term_ref. Remove action requires confirmation in a secondary dialog.
5.6 Modify Revenue Item
Preconditions:
- A revenue item is visible in the revenue items table
Procedure reference: TODO: Document in foundation/procedures/billing-items.md
Steps:
- User clicks the "Actions" dropdown on a revenue item row and selects "Modify."
- The Modify Revenue Item dialog opens, pre-populated with the revenue item's current data from the Deal Engine.
- User edits the applicable fields (amounts, dates, commission, rec style, etc.).
- User saves; the Deal Engine service processes the change, which triggers a revenue sync that produces updated revenue items and billing items.
Postconditions:
- Revenue item and associated billing items updated via revenue sync.
- Revenue page refreshed.
UI trigger: "Actions" dropdown menu on a revenue item row → "Modify" menu item. Always visible for every revenue item row.
6. Permissions & Role-Based Access
**PoC Artifact:** The PoC codebase does not enforce role-based access controls on the billing items / revenue page or its server actions. All authenticated users can perform all operations. The permission table below reflects the intended production role model based on business domain rules.
| Action | CASH_MANAGER | CASH_PROCESSOR | SETTLEMENT_APPROVER | IT |
|---|---|---|---|---|
| View revenue items and billing items | Yes | Yes | Yes | Yes |
| View recognition schedules | Yes | Yes | Yes | Yes |
| Search and filter | Yes | Yes | Yes | Yes |
| Manage deductions | Yes | — | — | Yes |
| Manage payment term (update/remove) | Yes | — | — | Yes |
| Modify revenue item | Yes | — | — | Yes |
Field-level restrictions:
- The Write-Off badge on billing item rows links to the write-off packet. Write-off actions are restricted to the Write-Offs workflow and governed by a separate approval chain; no write-off can be initiated from the billing items workflow.
billing_item_detail_amtandbilling_item_detail_total_amtare computed fields that cannot be directly edited by any user role. Changes to these values require a revenue sync triggered by a payment term update. Deduction changes do not affect these fields.
7. Integration Points
7.1 Upstream
| Source | Data Provided | Mechanism |
|---|---|---|
| Deal Engine (sales block pipeline) | sales_item and payment_term records via sales_block; triggers creation of revenue_items and billing_item / billing_item_detail | Batch ingest: sales_block processed by revenue sync job |
| Deal Engine screen (manual entry) | deal_engine_sales_item and deal_engine_payment_term edited directly by users | Server action manageDealEnginePaymentTermAction; triggers revenue sync |
Tax engine (WithholdingTaxService) | Auto-calculated tax deduction amounts and VAT pass-through metadata at billing item creation time | Service call within BillingService; writes billing_item_deduction records on PAY detail |
7.2 Downstream
| Consumer | Data Consumed | Mechanism |
|---|---|---|
| Worksheets workflow | billing_item_detail.billing_item_detail_id (REV and PAY) as the target for cash_receipt_application | FK lookup: cash_receipt_application.billing_item_detail_id |
| Write-Offs workflow | billing_item_detail REV rows as subjects for write_off_packet / packet_receivable | FK: billing_item_detail.write_off_packet_id and packet_receivable.billing_item_detail_id |
| AR Aging reports | billing_item with current_item_ind = true and open_item_ind = true, aged by billing_item_aging_dt | Batch query in AR aging service |
| Invoicing workflow | billing_item linked to generated invoices and credit memos via billing_item_document bridge table | FK lookup via billing_item_document |
| Cash Matching workflow | billing_item display view with onReferenceClick to add split references by sales_item_ref or payment_term_ref | Shared table component |
| Client detail page (Revenue tab) | billing_item_display filtered by client_id | Service call getBillingItemsDisplayByClientId |
7.3 External Integrations
No external integrations for this workflow. All data flows are internal to the Client Processing system. The Deal Engine is treated as an upstream internal system, not an external API.
8. Functional Screen Requirements
8.1 Revenue Page
Route: /revenue
Data loading:
searchRevenueItems— Revenue Items — Search Query: loads initial revenue items withcurrent_item_ind = trueandrevenue_item_date_status_cd = 'C'; or loads all history ifsalesItemRefURL parameter is presentgetBillingItemsForDisplay— Billing Items — Flattened Display View: loads billing items withcurrent_item_only = trueandopen_item_only = trueon initial entry
Revenue Items Table Region
Displays the searchable list of revenue items. Selecting a row loads the schedules side panel and filters the billing items panel.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| UTA Entity | revenue_items.uta_entity_id → uta_entity name | No | Hidden by default; shown via column visibility toggle |
| Deal Name | revenue_items.deal_id → deal.deal_reference | No | Always visible |
| Client Name | revenue_items.client_id → party.full_name | No | Always visible; links to /clients/{client_id}?tab=revenue |
| Buyer Name | revenue_items.buyer_id → party.full_name | No | Always visible |
| Sales Item Ref | revenue_items.sales_item_ref | No | Hidden by default |
| Revenue Item Name | revenue_items.revenue_item_name | No | Always visible |
| Gross Amt | revenue_items.revenue_item_gross_amt | No | Always visible |
| Commission % | revenue_items.revenue_item_commission_perc | No | Hidden by default |
| Commission Amt | revenue_items.revenue_item_commission_amt | No | Always visible |
| Cash Collected | Computed: sum of cash applied to REV and PAY details under this revenue item | No | Always visible |
| Currency | revenue_items.currency_cd | No | Always visible |
| Start Date | revenue_items.revenue_item_start_dt | No | Always visible |
| End Date | revenue_items.revenue_item_end_dt | No | Always visible |
| Status | revenue_items.revenue_item_status_cd → code master description | No | Hidden by default |
| Date Status | revenue_items.revenue_item_date_status_cd → code master description | No | Always visible |
| Rec Style | revenue_items.revenue_item_rec_style_cd → code master description | No | Hidden by default |
| Current Item | revenue_items.current_item_ind | No | Hidden by default |
| Department Name | revenue_items.department_id → department name | No | Always visible |
| Created Date | revenue_items.created_dt | No | Hidden by default |
| Created By | revenue_items.created_by | No | Hidden by default |
| Updated Date | revenue_items.updated_dt | No | Hidden by default |
| Updated By | revenue_items.updated_by | No | Hidden by default |
| Actions | — | No | Always visible; contains "Modify" menu item |
Grid features:
- Sortable columns: all columns support sort
- Filters: column-level filters (text, select, number, date) per column type; global filter is disabled in favor of server-side search
- Row selection: single row click — loads schedules side panel and filters billing items
- Pagination: yes, default page size
- Export: yes, exports to CSV as "revenue-items"
Conditional display:
- "Current Items only" checkbox — when checked, re-fetches with
current_item_ind = true; default on unlesssalesItemRefURL parameter is present - "Confirmed Dates Only" checkbox — when checked, re-fetches with
revenue_item_date_status_cd = 'C'; default on - Refresh button — always visible and enabled; re-fetches both revenue items and billing items
- Schedules side panel — visible when a revenue item row is selected; collapses to the right of the table as a 400px panel
- "Searching..." overlay — visible while a search request is in flight
Recognition Schedules Side Panel Region
Shows the recognition timeline for the selected revenue item. Only appears when a revenue item row is selected.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Date | revenue_item_schedules.revenue_dt | No | Always visible when panel is open |
| Amt | revenue_item_schedules.revenue_amt | No | Always visible when panel is open |
| Status | revenue_item_schedules.revenue_item_posting_status_cd → code master description | No | Always visible when panel is open |
| Posting Date | revenue_item_schedules.revenue_item_posting_dt | No | Always visible when panel is open |
Grid features:
- Sortable columns: all columns
- Filters: none
- Row selection: none
- Pagination: no
- Export: no
- Initial sort:
revenue_dtascending
Conditional display:
- Panel visible only when a revenue item row is selected
- Close (×) button collapses the panel and deselects the revenue item
- "Loading schedules..." indicator shown while the schedule data is being fetched
Billing Items Table Region
Displays the flattened view of billing items with REV and PAY breakdown, balances, and action buttons.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Billing Item ID | billing_item.billing_item_id | No | Hidden by default |
| Sales Item Ref | billing_item → revenue_items.sales_item_ref | No | Hidden by default |
| Pmt Term Ref | billing_item.payment_term_ref | No | Hidden by default |
| Deal Name | billing_item.deal_id → deal.deal_reference | No | Always visible |
| Buyer Name | billing_item.buyer_id → party.full_name | No | Always visible |
| Client Name | billing_item.client_id → party.full_name | No | Hidden by default |
| UTA Entity | billing_item.uta_entity_id → entity name | No | Hidden by default |
| Department | billing_item.department_id | No | Hidden by default |
| Collection Style | billing_item.collection_style_cd → code master description | No | Always visible |
| Billing Item Name | billing_item.billing_item_name | No | Always visible |
| Billing Gross Amt | billing_item_detail REV billing_item_detail_gross_amt | No | Always visible |
| Commission % | billing_item_detail REV billing_item_detail_percent | No | Always visible; formatted as percentage |
| Total Balance | Computed: REV balance + PAY balance | No | Always visible |
| Revenue Amt | billing_item_detail REV billing_item_detail_amt | No | Always visible |
| Currency | billing_item.currency_cd → code master description | No | Always visible |
| Due Date | billing_item.billing_item_due_dt | No | Always visible |
| Collection Party | billing_item.collection_party_id → party.full_name | No | Hidden by default |
| Revenue Item Name | revenue_items.revenue_item_name | No | Hidden by default |
| Cash Applied | Computed: total cash_receipt_application.cash_receipt_amt_applied for this billing item | No | Hidden by default |
| Total Deductions | Computed: sum of billing_item_deduction.billing_item_deduction_amt | No | Hidden by default |
| Rev Net Amt | billing_item_detail REV billing_item_detail_amt | No | Hidden by default |
| Rev Tax Amt | billing_item_detail REV billing_item_detail_tax_amt | No | Hidden by default |
| Rev Total Amt | billing_item_detail REV billing_item_detail_total_amt | No | Hidden by default |
| Rev Cash | Computed: cash applied to REV detail | No | Hidden by default |
| Rev Balance | Computed: rev_total_amt − rev_deductions − rev_cash | No | Hidden by default |
| Pay Net Amt | billing_item_detail PAY billing_item_detail_amt | No | Hidden by default |
| Pay Amt | billing_item_detail PAY billing_item_detail_amt | No | Hidden by default |
| Pay Tax Amt | billing_item_detail PAY billing_item_detail_tax_amt | No | Hidden by default |
| Pay Total Amt | billing_item_detail PAY billing_item_detail_total_amt | No | Hidden by default |
| Pay Cash | Computed: cash applied to PAY detail | No | Hidden by default |
| Pay Balance | Computed: pay_total_amt − pay_deductions − pay_cash | No | Hidden by default |
| Status | billing_item.billing_item_status_cd → code master description | No | Hidden by default |
| Write-Off | billing_item_detail REV write_off_status_cd | No | Visible only when write_off_status_cd is 'WRITTEN_OFF' or 'RECOVERED'; links to write-off packet |
| Open Item | billing_item.open_item_ind | No | Hidden by default |
| Current Item | billing_item.current_item_ind | No | Hidden by default |
| Created Date | billing_item.created_dt | No | Hidden by default |
| Created By | billing_item.created_by | No | Hidden by default |
| Updated Date | billing_item.updated_dt | No | Hidden by default |
| Updated By | billing_item.updated_by | No | Hidden by default |
Grid features:
- Sortable columns: all columns support sort
- Filters: global text filter and column-level filters
- Row selection: single row click
- Pagination: yes
- Export: yes, exports to CSV as "billing-items"
Conditional display:
- "Show Closed" checkbox — includes billing items where
open_item_ind = false; default off - "Show Zero" checkbox — includes billing items where amounts are zero; default off
- "Manage Deductions" button — visible below the grid; enabled when a billing item row is selected
- "Manage Payment Term" button — visible below the grid; enabled when a billing item is selected AND
billing_item.payment_term_refis not null - Write-Off badge — visible inline in the Write-Off column only when REV detail has
write_off_status_cd = 'WRITTEN_OFF'or'RECOVERED'
8.2 Manage Deductions Dialog
Route: Modal dialog opened from /revenue
Data loading:
getBillingItemDeductionData— loadsbilling_item,billing_item_detail[], andbilling_item_deduction[]for the selected billing itemgetBillingItemDeductionTypeOptions— loadsBILLING_ITEM_DEDUCTION_TYPE_CDoptions from code master
Header Region
Shows a summary of the billing item being edited.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Billing Item Name | billing_item.billing_item_name | No | Always visible |
| Gross Amount | billing_item_detail REV billing_item_detail_gross_amt | No | Always visible |
| Total Net | Computed: rev_gross × rev_percent + pay_gross × pay_percent | No | Always visible |
| Total Deduction | Computed: sum of billing_item_deduction_amt where billing_item_deduction_update_net_ind = true | No | Always visible |
| Total Billing | Computed: total_net − total_deduction | No | Always visible |
| Currency | billing_item.billing_item_currency_cd | No | Always visible |
Commission (REV) Deductions Region
Deduction rows for the REV detail, with per-section summary showing percent, net amount, total deductions, and billing amount.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Type | billing_item_deduction.billing_item_deduction_type_cd | Yes | Always visible; dropdown from BILLING_ITEM_DEDUCTION_TYPE_CD |
| Amount | billing_item_deduction.billing_item_deduction_amt | Yes | Always visible; numeric input |
| Net (checkbox) | billing_item_deduction.billing_item_deduction_update_net_ind | Yes | Always visible; affects billing amount preview calculation |
| Comment | billing_item_deduction.comment | Yes | Always visible |
| Delete row | — | Yes | Trash button on each row; removes row from working set |
| Add row | — | Yes | Plus button on the last row of each section |
Grid features:
- Sortable columns: none (manual row management)
- Filters: none
- Row selection: none
- Pagination: no
Conditional display:
- REV section hidden if billing item has no REV detail (defensive case; should not occur in production)
- Section summary header always shows: percent, net amount (
gross × percent), total deductions (sum of net-affecting deductions), billing amount (net − total_deductions) - "Save Changes" button disabled while loading or saving
Pay Out (PAY) Deductions Region
Identical structure to the Commission (REV) section above, operating on the PAY billing_item_detail record. REV and PAY sections are separated by a horizontal divider.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Type | billing_item_deduction.billing_item_deduction_type_cd | Yes | Always visible |
| Amount | billing_item_deduction.billing_item_deduction_amt | Yes | Always visible |
| Net (checkbox) | billing_item_deduction.billing_item_deduction_update_net_ind | Yes | Always visible |
| Comment | billing_item_deduction.comment | Yes | Always visible |
| Delete row | — | Yes | Trash button on each row |
| Add row | — | Yes | Plus button on last row |
Conditional display:
- PAY section hidden if billing item has no PAY detail (defensive case)
- For
collection_style_cd = 'CLIENT'items, PAY gross and net amounts are zero; deductions can still be entered but will not change the zero net amount
8.3 Manage Payment Term Dialog
Route: Modal dialog opened from /revenue
Data loading:
getPaymentTermByRef— loads the currentdeal_engine_payment_termbypayment_term_refgetPaymentPartyOptionsForTerm— loads party options (deal parties + buyer) for the selected termgetCodeMasterOptions('REVENUE_ITEM_DATE_STATUS_CD')— loads due date status options
Payment Term Edit Region
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Name | deal_engine_payment_term.name | Yes | Always visible |
| Payment Party | deal_engine_payment_term.payment_party_id | Yes | Always visible; dropdown populated from deal parties and buyer |
| Amount | deal_engine_payment_term.gross_amt | Yes | Always visible; numeric input |
| Due Date | deal_engine_payment_term.due_dt | Yes | Always visible; date input |
| Status | deal_engine_payment_term.due_date_status_cd | Yes | Always visible; dropdown from REVENUE_ITEM_DATE_STATUS_CD |
| Adjust Revenue? | — | Yes | Checkbox; when checked, amount change updates revenue_item_gross_amt; when unchecked, difference spread to other terms |
Conditional display:
- "Save Changes" button disabled while loading or saving; requires amount, due date, and due date status
- "Remove" button always visible; triggers a destructive confirmation dialog before executing
- Confirmation dialog body describes the impact on revenue total based on the "Adjust Revenue?" checkbox state
- Loading spinner shown while data is being fetched
9. Additional Diagrams
Billing Item Lifecycle: Current and Non-Current Versions
flowchart LR
A["billing_item v1\ncurrent_item_ind=true\nopen_item_ind=true"] -->|"Deductions changed\n(saved in-place)"| A1["billing_item v1\ncurrent_item_ind=true\nbilling_item_deduction records updated"]
A -->|"Revenue sync\n(rebill triggered)"| B["Reversal Item\ncurrent_item_ind=false\nopen_item_ind=false\nAll amounts negated"]
A -->|"Deactivated"| A2["billing_item v1\ncurrent_item_ind=false"]
B -.-> A2
A2 --> C["billing_item v2\ncurrent_item_ind=true\nopen_item_ind=recalculated\nDeductions copied forward"]
C --> D["cash_receipt_application\npoints to new billing_item_detail_id"]Deduction Save Flow
flowchart TD
A[User saves Manage Deductions dialog] --> B[Collect non-empty deduction rows]
B --> C[Call manageBillingItemDeductions]
C --> D[Fetch existing deductions\nfor all details]
D --> E[Delete removed deductions\nUpdate changed deductions\nCreate new deductions]
E --> F[Revalidate Revenue page]10. Cross-References
| Document | Relationship |
|---|---|
| Billing Items Data Model | Defines billing_item, billing_item_detail, billing_item_deduction, revenue_items, and revenue_item_schedules tables used throughout this workflow |
| Billing Items Queries | Specifies all data retrieval operations: search, display view, detail lookups, schedule retrieval |
| Billing Items Procedures | Specifies deduction management, revenue sync, and payment term management mutations |
| Deals, Sales Items & Payment Terms Data Model | Defines deal, deal_party, sales_item, payment_term — the upstream sources that produce revenue items and billing items |
| Worksheets Workflow | Downstream: billing item details are the targets for cash receipt applications on worksheets |
| Write-Offs Workflow | Downstream: REV billing item details can be written off through a separate approval workflow; write-off badge displayed in billing items table |
| AR Aging Workflow | Downstream: billing items with current_item_ind = true and open_item_ind = true are aged by billing_item_aging_dt for AR reporting |
| Invoicing Workflow | Downstream: billing items are linked to invoices and credit memos via the billing_item_document bridge table |
| Cash Matching Workflow | The billing items table component is reused in cash matching to display receivables alongside cash receipt references |
| Deals Workflow | Upstream: the Deal Engine produces sales blocks that drive revenue sync and billing item creation |
11. Gherkin Scenarios
Feature: Billing Items - Revenue Item and Billing Item Browsing
Scenario: Default page load shows current confirmed revenue items and open billing items
Given the Revenue page is loaded with no URL parameters
When the page data is fetched from the server
Then revenue items where "revenue_items.current_item_ind = true" and "revenue_items.revenue_item_date_status_cd = 'C'" are displayed
And billing items where "billing_item.current_item_ind = true" and "billing_item.open_item_ind = true" are displayed in the billing items panel
And the "Current Items only" checkbox is checked by default
And the "Confirmed Dates Only" checkbox is checked by default
Scenario: Selecting a revenue item loads recognition schedules and filters billing items
Given the revenue item "Adele - Netflix Special" with "revenue_item_id = 1001" is visible
And three "revenue_item_schedules" records exist for "revenue_item_id = 1001"
When the user clicks the "Adele - Netflix Special" row
Then the recognition schedules side panel opens with three rows
And each row shows "revenue_item_schedules.revenue_dt", "revenue_amt", and "revenue_item_posting_status_cd"
And the billing items panel re-fetches filtered to "billing_item.revenue_item_id = 1001"
Scenario: Show Closed toggle includes fully applied billing items
Given the billing items panel shows only open items by default
And one billing item with "billing_item_id = 2042" has "billing_item.open_item_ind = false"
When the user checks the "Show Closed" checkbox
Then the billing items panel re-fetches with "open_item_only = false"
And billing item "billing_item_id = 2042" appears in the results
Scenario: Manage Payment Term button disabled when billing item has no payment term ref
Given the billing item with "billing_item_id = 3001" has "billing_item.payment_term_ref = null"
When the user clicks the billing item row
Then the "Manage Deductions" button is enabled
And the "Manage Payment Term" button is disabledFeature: Billing Items - Manage Deductions (In-Place)
Scenario: User adds a bank charge deduction to the PAY detail and saves
Given the billing item "Studio Fee — Warner Bros" with "billing_item_id = 4010" is selected
And "billing_item_detail" REV has "billing_item_detail_gross_amt = 50000.00" and "billing_item_detail_percent = 0.1000"
And "billing_item_detail" PAY has "billing_item_detail_amt = 45000.00"
And no existing "billing_item_deduction" records for this billing item
When the user opens "Manage Deductions"
And adds a deduction row to the Pay Out section with "billing_item_deduction_type_cd = 'B'", "billing_item_deduction_amt = 250.00", "billing_item_deduction_update_net_ind = true"
And clicks "Save Changes"
Then "manageBillingItemDeductions" is invoked for "billing_item_id = 4010"
And no new "billing_item" is created (deductions saved in-place)
And "billing_item.current_item_ind" for item 4010 remains true
And one "billing_item_deduction" record is created with "billing_item_deduction_type_cd = 'B'" and "billing_item_deduction_amt = 250.00"
And PAY "billing_item_detail_amt" remains "45000.00" (unchanged by deduction)
Scenario: No-op when user saves without making changes
Given the billing item with "billing_item_id = 4011" has two existing "billing_item_deduction" records
When the user opens "Manage Deductions" and makes no changes
And clicks "Save Changes"
Then "manageBillingItemDeductions" is invoked with the same deduction set
And no deduction records are changed
And the dialog closes
Scenario: Deductions do not change billing_item_detail_amt
Given the billing item with "billing_item_id = 6001" has "billing_item_detail" REV "billing_item_detail_amt = 5000.00"
When the user adds a deduction to the Commission section with "billing_item_deduction_amt = 100.00"
And saves
Then "billing_item_detail" REV "billing_item_detail_amt" is still "5000.00"
And a "billing_item_deduction" record exists with "billing_item_deduction_amt = 100.00"Feature: Billing Items - Manage Payment Term
Scenario: User updates a payment term amount with Adjust Revenue checked
Given the billing item "Appearance Fee — Jan 2025" with "billing_item_id = 7001" is selected
And "billing_item.payment_term_ref = 'PT-2025-01'"
And "deal_engine_payment_term.gross_amt = 100000.00" and "deal_engine_payment_term.due_dt = '2025-01-15'"
When the user opens "Manage Payment Term"
And sets "Amount" to "120000.00"
And checks "Adjust Revenue?"
And clicks "Save Changes"
Then "deal_engine_payment_term.gross_amt" is updated to "120000.00"
And the revenue item's "revenue_items.revenue_item_gross_amt" is increased by "20000.00"
And a new "billing_item" with updated amounts is created with "current_item_ind = true"
And the original "billing_item_id = 7001" is deactivated with "current_item_ind = false"
Scenario: User removes a payment term
Given the billing item with "billing_item_id = 7002" is selected
And "billing_item.payment_term_ref = 'PT-2025-02'"
When the user opens "Manage Payment Term" and clicks "Remove"
And confirms the removal in the confirmation dialog
Then the "deal_engine_payment_term" with "payment_term_ref = 'PT-2025-02'" is deleted
And the corresponding "billing_item.current_item_ind" is set to "false" via revenue sync
And the Revenue page re-fetches without that billing item in the current view
Scenario: Save validation rejects missing due date
Given the Manage Payment Term dialog is open for "payment_term_ref = 'PT-2025-03'"
When the user clears the "Due Date" field and clicks "Save Changes"
Then a validation error "Due date is required" is shown
And no database writes occurFeature: Billing Items - Write-Off Display and Collection Style
Scenario: Written-off REV detail shows badge linking to write-off packet
Given the billing item with "billing_item_id = 9001" has "billing_item_detail" REV "write_off_status_cd = 'WRITTEN_OFF'"
And "billing_item_detail.write_off_packet_id = 'a1b2c3d4-...'"
When the billing items table is displayed
Then the row shows a "Written Off" badge in the Write-Off column
And clicking the badge opens the path "/write-offs/packets/a1b2c3d4-..." in a new tab
Scenario: PAY detail write-off status is always NOT_WRITTEN_OFF
Given the billing item with "billing_item_id = 9002" has REV "write_off_status_cd = 'WRITTEN_OFF'"
Then "billing_item_detail" PAY "write_off_status_cd = 'NOT_WRITTEN_OFF'"
And no write-off badge appears for the PAY detail
Scenario: Collection style CLIENT produces zero PAY amounts in billing items table
Given the billing item with "billing_item_id = 10001" has "billing_item.collection_style_cd = 'CLIENT'"
When the billing items table is displayed
Then "billing_item_detail" PAY "billing_item_detail_total_amt = 0.00"
And the "Pay Balance" column shows "0.00"
And "Total Balance" equals only the REV detail balance