Skip to content

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):

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

mermaid
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

  1. 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_items record per sales item and one billing_item (with REV and PAY billing_item_detail records) per payment term. Tax deductions are estimated at creation time and stored as billing_item_deduction records on the PAY detail.

  2. User browses the Revenue page — The Revenue page loads an initial set of revenue items (filtered by current_item_ind = true and revenue_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.

  3. User selects a revenue item — Clicking a revenue item row loads the associated revenue_item_schedules records in a side panel, showing the revenue recognition timeline (date, amount, posting status).

  4. 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.

  5. 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.

  6. User manages a payment term — Selecting a billing item that has a payment_term_ref and 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.

  7. 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

OperationFoundation DocPurpose in This Workflow
searchRevenueItemsRevenue Items — Search QueryLoads revenue items table on page entry and after each search/filter change
getSchedulesByItemIdRevenue Item Schedules — Lookup by Revenue ItemLoads the recognition schedule side panel when a revenue item row is selected
getBillingItemsForDisplayBilling Items — Flattened Display ViewLoads the billing items panel; re-fetched when filters change (current/closed/zero toggles, revenue item selection, search term)
getBillingItemByIdBilling Items — Single Record LookupLoads billing item header for the Manage Deductions dialog
getBillingItemDetailsByBillingItemIdBilling Item Details — Lookup by Billing ItemLoads REV and PAY details for the Manage Deductions dialog
getBillingItemDeductionsByDetailIdBilling Item Deductions — Lookup by DetailLoads existing deductions for each detail in the Manage Deductions dialog
getBillingItemsByRevenueItemIdBilling Items — Lookup by Revenue ItemResolves the current billing item when a non-current item ID is submitted for rebill
getPaymentTermByRefPayment Terms — Lookup by RefLoads current payment term data into the Manage Payment Term dialog
getPaymentPartyOptionsForTermTODO: Document in foundation/queries/billing-items.mdLoads party options (deal parties + buyer) to populate the Payment Party dropdown in the Manage Payment Term dialog
getCodeMasterOptionsCode Master — Lookup by TypeLoads deduction type options and date status options for dropdowns

4.2 Procedures Used

OperationFoundation DocTrigger in This Workflow
manageBillingItemDeductionsBilling Items Procedures — Manage Billing Item DeductionsUser saves changes in the Manage Deductions dialog
manageDealEnginePaymentTermActionBilling Items Procedures — Manage Payment TermUser clicks "Save Changes" or confirms "Remove" in the Manage Payment Term dialog
modifyRevenueItem (via Modify dialog)TODO: Document in foundation/procedures/billing-items.mdUser 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:

  1. 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.
  2. User toggles "Current Items only" checkbox; this re-fetches results with current_item_ind filter applied.
  3. User toggles "Confirmed Dates Only" checkbox; this re-fetches results with revenue_item_date_status_cd = 'C' filter applied.
  4. User clicks the refresh button to re-fetch both revenue items and billing items simultaneously.
  5. Column-level filters refine the current result set on the client side.

Postconditions:

  • revenue_items rows matching the criteria are displayed; initial load defaults to current_item_ind = true and revenue_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:

  1. User clicks a revenue item row.
  2. The system loads revenue_item_schedules for the selected revenue_item_id and displays them in a side panel showing date, amount, posting status, and posting date.
  3. Clicking the same row again or the close button collapses the side panel and deselects the revenue item.

Postconditions:

  • revenue_item_schedules rows 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:

  1. The billing items panel loads with all current, open billing items by default.
  2. Selecting a revenue item row filters the billing items panel to show only billing items under that revenue item.
  3. User toggles "Show Closed" to include billing items where open_item_ind = false.
  4. User toggles "Show Zero" to include billing items where both REV and PAY amounts are zero (typically collection_style_cd = 'CLIENT' items).
  5. 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:

  1. User clicks "Manage Deductions"; the system loads the billing item header, its REV and PAY details, and all existing billing_item_deduction records.
  2. 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.
  3. User adds, edits, or removes deduction rows (type, amount, "Net" flag, comment) in either section.
  4. 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_deduction records updated in-place on the existing billing item's details.
  • No new billing_item or billing_item_detail records are created.
  • billing_item_detail_amt remains 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:

  1. User clicks "Manage Payment Term"; the system loads the current payment term data by payment_term_ref and loads party options for the payment party dropdown.
  2. User edits name, payment party, amount, due date, and due date status.
  3. 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).
  4. 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.
  5. 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_items and billing_item records; 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:

  1. User clicks the "Actions" dropdown on a revenue item row and selects "Modify."
  2. The Modify Revenue Item dialog opens, pre-populated with the revenue item's current data from the Deal Engine.
  3. User edits the applicable fields (amounts, dates, commission, rec style, etc.).
  4. 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.

ActionCASH_MANAGERCASH_PROCESSORSETTLEMENT_APPROVERIT
View revenue items and billing itemsYesYesYesYes
View recognition schedulesYesYesYesYes
Search and filterYesYesYesYes
Manage deductionsYesYes
Manage payment term (update/remove)YesYes
Modify revenue itemYesYes

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_amt and billing_item_detail_total_amt are 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

SourceData ProvidedMechanism
Deal Engine (sales block pipeline)sales_item and payment_term records via sales_block; triggers creation of revenue_items and billing_item / billing_item_detailBatch 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 usersServer action manageDealEnginePaymentTermAction; triggers revenue sync
Tax engine (WithholdingTaxService)Auto-calculated tax deduction amounts and VAT pass-through metadata at billing item creation timeService call within BillingService; writes billing_item_deduction records on PAY detail

7.2 Downstream

ConsumerData ConsumedMechanism
Worksheets workflowbilling_item_detail.billing_item_detail_id (REV and PAY) as the target for cash_receipt_applicationFK lookup: cash_receipt_application.billing_item_detail_id
Write-Offs workflowbilling_item_detail REV rows as subjects for write_off_packet / packet_receivableFK: billing_item_detail.write_off_packet_id and packet_receivable.billing_item_detail_id
AR Aging reportsbilling_item with current_item_ind = true and open_item_ind = true, aged by billing_item_aging_dtBatch query in AR aging service
Invoicing workflowbilling_item linked to generated invoices and credit memos via billing_item_document bridge tableFK lookup via billing_item_document
Cash Matching workflowbilling_item display view with onReferenceClick to add split references by sales_item_ref or payment_term_refShared table component
Client detail page (Revenue tab)billing_item_display filtered by client_idService 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:

  • searchRevenueItemsRevenue Items — Search Query: loads initial revenue items with current_item_ind = true and revenue_item_date_status_cd = 'C'; or loads all history if salesItemRef URL parameter is present
  • getBillingItemsForDisplayBilling Items — Flattened Display View: loads billing items with current_item_only = true and open_item_only = true on 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 / ColumnSourceEditable?Condition
UTA Entityrevenue_items.uta_entity_iduta_entity nameNoHidden by default; shown via column visibility toggle
Deal Namerevenue_items.deal_iddeal.deal_referenceNoAlways visible
Client Namerevenue_items.client_idparty.full_nameNoAlways visible; links to /clients/{client_id}?tab=revenue
Buyer Namerevenue_items.buyer_idparty.full_nameNoAlways visible
Sales Item Refrevenue_items.sales_item_refNoHidden by default
Revenue Item Namerevenue_items.revenue_item_nameNoAlways visible
Gross Amtrevenue_items.revenue_item_gross_amtNoAlways visible
Commission %revenue_items.revenue_item_commission_percNoHidden by default
Commission Amtrevenue_items.revenue_item_commission_amtNoAlways visible
Cash CollectedComputed: sum of cash applied to REV and PAY details under this revenue itemNoAlways visible
Currencyrevenue_items.currency_cdNoAlways visible
Start Daterevenue_items.revenue_item_start_dtNoAlways visible
End Daterevenue_items.revenue_item_end_dtNoAlways visible
Statusrevenue_items.revenue_item_status_cd → code master descriptionNoHidden by default
Date Statusrevenue_items.revenue_item_date_status_cd → code master descriptionNoAlways visible
Rec Stylerevenue_items.revenue_item_rec_style_cd → code master descriptionNoHidden by default
Current Itemrevenue_items.current_item_indNoHidden by default
Department Namerevenue_items.department_id → department nameNoAlways visible
Created Daterevenue_items.created_dtNoHidden by default
Created Byrevenue_items.created_byNoHidden by default
Updated Daterevenue_items.updated_dtNoHidden by default
Updated Byrevenue_items.updated_byNoHidden by default
ActionsNoAlways 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 unless salesItemRef URL 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 / ColumnSourceEditable?Condition
Daterevenue_item_schedules.revenue_dtNoAlways visible when panel is open
Amtrevenue_item_schedules.revenue_amtNoAlways visible when panel is open
Statusrevenue_item_schedules.revenue_item_posting_status_cd → code master descriptionNoAlways visible when panel is open
Posting Daterevenue_item_schedules.revenue_item_posting_dtNoAlways visible when panel is open

Grid features:

  • Sortable columns: all columns
  • Filters: none
  • Row selection: none
  • Pagination: no
  • Export: no
  • Initial sort: revenue_dt ascending

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 / ColumnSourceEditable?Condition
Billing Item IDbilling_item.billing_item_idNoHidden by default
Sales Item Refbilling_itemrevenue_items.sales_item_refNoHidden by default
Pmt Term Refbilling_item.payment_term_refNoHidden by default
Deal Namebilling_item.deal_iddeal.deal_referenceNoAlways visible
Buyer Namebilling_item.buyer_idparty.full_nameNoAlways visible
Client Namebilling_item.client_idparty.full_nameNoHidden by default
UTA Entitybilling_item.uta_entity_id → entity nameNoHidden by default
Departmentbilling_item.department_idNoHidden by default
Collection Stylebilling_item.collection_style_cd → code master descriptionNoAlways visible
Billing Item Namebilling_item.billing_item_nameNoAlways visible
Billing Gross Amtbilling_item_detail REV billing_item_detail_gross_amtNoAlways visible
Commission %billing_item_detail REV billing_item_detail_percentNoAlways visible; formatted as percentage
Total BalanceComputed: REV balance + PAY balanceNoAlways visible
Revenue Amtbilling_item_detail REV billing_item_detail_amtNoAlways visible
Currencybilling_item.currency_cd → code master descriptionNoAlways visible
Due Datebilling_item.billing_item_due_dtNoAlways visible
Collection Partybilling_item.collection_party_idparty.full_nameNoHidden by default
Revenue Item Namerevenue_items.revenue_item_nameNoHidden by default
Cash AppliedComputed: total cash_receipt_application.cash_receipt_amt_applied for this billing itemNoHidden by default
Total DeductionsComputed: sum of billing_item_deduction.billing_item_deduction_amtNoHidden by default
Rev Net Amtbilling_item_detail REV billing_item_detail_amtNoHidden by default
Rev Tax Amtbilling_item_detail REV billing_item_detail_tax_amtNoHidden by default
Rev Total Amtbilling_item_detail REV billing_item_detail_total_amtNoHidden by default
Rev CashComputed: cash applied to REV detailNoHidden by default
Rev BalanceComputed: rev_total_amt − rev_deductions − rev_cashNoHidden by default
Pay Net Amtbilling_item_detail PAY billing_item_detail_amtNoHidden by default
Pay Amtbilling_item_detail PAY billing_item_detail_amtNoHidden by default
Pay Tax Amtbilling_item_detail PAY billing_item_detail_tax_amtNoHidden by default
Pay Total Amtbilling_item_detail PAY billing_item_detail_total_amtNoHidden by default
Pay CashComputed: cash applied to PAY detailNoHidden by default
Pay BalanceComputed: pay_total_amt − pay_deductions − pay_cashNoHidden by default
Statusbilling_item.billing_item_status_cd → code master descriptionNoHidden by default
Write-Offbilling_item_detail REV write_off_status_cdNoVisible only when write_off_status_cd is 'WRITTEN_OFF' or 'RECOVERED'; links to write-off packet
Open Itembilling_item.open_item_indNoHidden by default
Current Itembilling_item.current_item_indNoHidden by default
Created Datebilling_item.created_dtNoHidden by default
Created Bybilling_item.created_byNoHidden by default
Updated Datebilling_item.updated_dtNoHidden by default
Updated Bybilling_item.updated_byNoHidden 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_ref is 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 — loads billing_item, billing_item_detail[], and billing_item_deduction[] for the selected billing item
  • getBillingItemDeductionTypeOptions — loads BILLING_ITEM_DEDUCTION_TYPE_CD options from code master

Header Region

Shows a summary of the billing item being edited.

Field / ColumnSourceEditable?Condition
Billing Item Namebilling_item.billing_item_nameNoAlways visible
Gross Amountbilling_item_detail REV billing_item_detail_gross_amtNoAlways visible
Total NetComputed: rev_gross × rev_percent + pay_gross × pay_percentNoAlways visible
Total DeductionComputed: sum of billing_item_deduction_amt where billing_item_deduction_update_net_ind = trueNoAlways visible
Total BillingComputed: total_net − total_deductionNoAlways visible
Currencybilling_item.billing_item_currency_cdNoAlways 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 / ColumnSourceEditable?Condition
Typebilling_item_deduction.billing_item_deduction_type_cdYesAlways visible; dropdown from BILLING_ITEM_DEDUCTION_TYPE_CD
Amountbilling_item_deduction.billing_item_deduction_amtYesAlways visible; numeric input
Net (checkbox)billing_item_deduction.billing_item_deduction_update_net_indYesAlways visible; affects billing amount preview calculation
Commentbilling_item_deduction.commentYesAlways visible
Delete rowYesTrash button on each row; removes row from working set
Add rowYesPlus 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 / ColumnSourceEditable?Condition
Typebilling_item_deduction.billing_item_deduction_type_cdYesAlways visible
Amountbilling_item_deduction.billing_item_deduction_amtYesAlways visible
Net (checkbox)billing_item_deduction.billing_item_deduction_update_net_indYesAlways visible
Commentbilling_item_deduction.commentYesAlways visible
Delete rowYesTrash button on each row
Add rowYesPlus 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 current deal_engine_payment_term by payment_term_ref
  • getPaymentPartyOptionsForTerm — loads party options (deal parties + buyer) for the selected term
  • getCodeMasterOptions('REVENUE_ITEM_DATE_STATUS_CD') — loads due date status options

Payment Term Edit Region

Field / ColumnSourceEditable?Condition
Namedeal_engine_payment_term.nameYesAlways visible
Payment Partydeal_engine_payment_term.payment_party_idYesAlways visible; dropdown populated from deal parties and buyer
Amountdeal_engine_payment_term.gross_amtYesAlways visible; numeric input
Due Datedeal_engine_payment_term.due_dtYesAlways visible; date input
Statusdeal_engine_payment_term.due_date_status_cdYesAlways visible; dropdown from REVENUE_ITEM_DATE_STATUS_CD
Adjust Revenue?YesCheckbox; 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

mermaid
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

mermaid
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

DocumentRelationship
Billing Items Data ModelDefines billing_item, billing_item_detail, billing_item_deduction, revenue_items, and revenue_item_schedules tables used throughout this workflow
Billing Items QueriesSpecifies all data retrieval operations: search, display view, detail lookups, schedule retrieval
Billing Items ProceduresSpecifies deduction management, revenue sync, and payment term management mutations
Deals, Sales Items & Payment Terms Data ModelDefines deal, deal_party, sales_item, payment_term — the upstream sources that produce revenue items and billing items
Worksheets WorkflowDownstream: billing item details are the targets for cash receipt applications on worksheets
Write-Offs WorkflowDownstream: REV billing item details can be written off through a separate approval workflow; write-off badge displayed in billing items table
AR Aging WorkflowDownstream: billing items with current_item_ind = true and open_item_ind = true are aged by billing_item_aging_dt for AR reporting
Invoicing WorkflowDownstream: billing items are linked to invoices and credit memos via the billing_item_document bridge table
Cash Matching WorkflowThe billing items table component is reused in cash matching to display receivables alongside cash receipt references
Deals WorkflowUpstream: the Deal Engine produces sales blocks that drive revenue sync and billing item creation

11. Gherkin Scenarios

gherkin
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 disabled
gherkin
Feature: 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"
gherkin
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 occur
gherkin
Feature: 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

Confidential. For internal use only.