Deals Workflow
1. Executive Summary
Purpose
The Deals workflow is the entry point for all financial operations in Client Processing. A deal represents the commercial agreement between UTA and a buyer on behalf of a client (artist, talent, or creator). Every downstream financial operation — billing items, cash receipts, worksheets, settlements, and outbound payments — traces back to a deal. Users create and manage deals through deal master management (reference and party setup) and manage sales items and payment terms through the sales pipeline. The result is revenue items and billing items that the cash management workflow applies payments against.
Scope
Covered:
- Creating and editing deal master records (
deal,deal_party) - Managing deal parties and their commission structures
- Managing sales pipeline items (
sales_block,sales_item,payment_term) from the Sales screen (create, update, split, process) - Processing sales blocks into revenue items and billing items via
processRevenueUpdate - Searching, filtering, and viewing deal data
Not covered (documented separately):
- Billing items and revenue items (downstream of this workflow) — see Billing Items Workflow
- Cash receipts and worksheets — see Cash Receipts Workflow and Worksheets Workflow
- Invoicing from billing items — see Invoicing Workflow
Key Objectives
- Capture the commercial agreement (deal) and the parties involved, including commission structures and payment routing.
- Produce payment terms that define the expected billing schedule (who pays, how much, and when).
- Generate billing items that drive the receivables used in the cash management workflow.
- Maintain versioned history of sales data as terms evolve over time.
2. Process Overview
flowchart TD
A[User selects client] --> B[Create or edit Deal]
B --> C[Assign Deal Parties with commission]
C --> F[Sales Item arrives in Sales Block]
F --> K{Validate sales block}
K -->|Pass| M[Process Revenue Update]
K -->|Fail| N[Block set to Failed status]
N --> O[User corrects data and retries]
O --> K
M --> P[Revenue Items created/updated]
P --> Q[Billing Items created/updated]
Q --> R[Cash management workflow begins]Walkthrough
- Create or edit deal — The user creates a new deal record with a name, reference, date range, and active status, then assigns parties (client, buyer, agent, attorney, etc.) with commission terms and bank routing.
- Sales items enter the pipeline — Sales items and payment terms are created in the sales pipeline (
sales_block,sales_item,payment_term). Each sales block groups one sales item with its associated payment terms. - Process revenue update — The user (from the Sales screen) runs
processRevenueUpdatefor the sales block. This validates the block through three layers (data, consistency, referential) and creates or updatesrevenue_itemsandbilling_item/billing_item_detailrecords. - Billing items available — The resulting billing items (each with one REV detail and one PAY detail) are now available to the cash management workflow for applying receipts.
3. Business Rules
3.1 Sales Item Gross Must Equal Payment Term Sum
Business rule: The sum of all payment_term.gross_amt values for a sales item must equal sales_item.gross_amt within a $0.01 tolerance. Revenue processing is rejected if this check fails.
Foundation reference: Process Revenue Update — Step 2: Run Three-Layer Validation
Workflow context: The data validation layer checks this constraint before allowing revenue processing to proceed.
3.2 Deal Reference Auto-Generation
Business rule: If no deal.deal_reference is provided when creating a deal, the system generates one automatically using the pattern DEAL-{random_alphanumeric}.
Foundation reference: Create Deal — Step 1: Resolve Deal Reference
3.3 Party List Is Authoritative on Upsert
Business rule: When saving a deal with a party list, the submitted list is treated as authoritative. Any existing deal_party row not represented in the submitted list (or explicitly marked isDeleted) is deleted. This ensures the deal's party composition exactly matches the submitted list.
Foundation reference: Upsert Deal with Parties
Workflow context: The deal party management dialog submits the full list of parties on save. Removing a party row from the UI and saving will delete the corresponding deal_party record.
3.4 Commission Sanitization
Business rule: Blank or null values for deal_party.deal_party_commission_perc and deal_party.deal_party_commission_amt are defaulted to '0' during upsert. The system does not accept blank strings for numeric commission fields.
Foundation reference: Upsert Deal with Parties — Step 3: Process the Provided Party List
3.5 Three-Layer Validation Before Revenue Processing
Business rule: Before a sales_block is processed into revenue and billing items, the system runs three validation layers in order: (1) data validation — required fields present, amounts non-negative, payment term sum matches gross within $0.01; (2) consistency validation — immutable fields on existing revenue_items match the incoming data; (3) referential validation — all foreign key references and code master values exist. A single failure at any layer sets sales_block.process_status_cd to 'F' and populates sales_block.error_description.
Foundation reference: Process Revenue Update — Step 2: Run Three-Layer Validation
3.6 Sales Block Creates New Pipeline Rows on Every Version
Business rule: Every time a sales item is updated, a new sales_block is created along with new sales_item and payment_term rows in the pipeline tables. The shared sales_item_ref and payment_term_ref values link records across all versions.
IMPORTANT
The pipeline tables accumulate new rows for every save. The current version of a sales item is identified by following the sales_item_ref to the most recently processed sales_block (i.e., the one with process_status_cd = 'P'). Downstream billing_item records link to payment terms by payment_term_ref value.
3.7 Sales Item Split Requires Exactly One Payment Term
Business rule: The split operation is only permitted when the source item has exactly one payment term. The split carves off a specified amount into a new item, each retaining a single payment term.
Foundation reference: Split Sales Item Pipeline — Step 2: Validate Single Payment Term
3.8 Commission Percentage Precision Differs by Level
Business rule: deal_party.deal_party_commission_perc uses decimal(7,4) (max 999.9999%), while sales_item_party.sales_item_party_commission_perc uses decimal(5,4) (max 9.9999%). The wider precision at the deal-party level is intentional and supports override scenarios.
Foundation reference: Deals Sales Items Payment Terms Data Model — Section 2.3 deal_party
4. Data Access & Operations References
4.1 Queries Used
| Operation | Foundation Doc | Purpose in This Workflow |
|---|---|---|
getDealById | Get Deal by ID | Loads deal header and party details when a row is clicked in the Deals search results, and on the Deal Detail screen |
getAllDeals | List All Deals | Populates deal selector dropdowns |
searchDeals | Search Deals | Executes user-initiated search on the Deals search screen by reference, name, date range, and active status |
getDealsByClient | Get Deals by Client | Loads the deal list for a selected client with aggregate financial summaries |
getSalesItems | Get Sales Items | Loads all sales_item rows from the sales pipeline for the Sales management screen |
getPaymentTerms | Get Payment Terms | Loads payment_term rows for a selected sales_item on the Sales screen |
4.2 Procedures Used
| Operation | Foundation Doc | Trigger in This Workflow |
|---|---|---|
createDeal | Create Deal | User submits the Create Deal dialog |
updateDeal | Update Deal Details | User edits and saves a deal from the Deal Management dialog |
upsertDealWithParties | Upsert Deal with Parties | User saves the deal form including the full party list |
createDealParty | Create Deal Party | User adds a new party to an existing deal |
updateDealParty | Update Deal Party | User edits an existing party entry on a deal |
deleteDealParty | Delete Deal Party | User removes a party row from a deal, or a resubmitted party list omits the party |
processRevenueUpdate | Process Revenue Update | Triggered manually by user from the Sales screen |
splitSalesItemPipeline | Split Sales Item Pipeline | User initiates a split on a sales_item from the Sales management screen |
updateSalesItemPipeline | Update Sales Item Pipeline | User edits a sales_item record from the Sales management screen |
createSalesItemPipeline | Create Sales Item Pipeline | User creates a new sales item from the Sales management screen |
5. Key User Actions
5.1 Create Deal
Preconditions:
- User has navigated to the Deals screen.
- User has clicked "Add New Deal."
Procedure reference: Create Deal
Steps:
- User enters the deal name (required) and optionally a reference, start date, end date, and active status.
- User adds parties: selects a party by lookup, assigns a role (
PARTY_ROLE_TYPE_CD), enters commission percentage or flat amount, and optionally selects a bank account. - User submits. If no
deal_referenceis provided, the system generates one with the patternDEAL-{random_alphanumeric}. - The system inserts the
dealrow and synchronizes thedeal_partyrows.
Postconditions:
- One new
dealrow exists with an auto-generated or user-provideddeal.deal_reference. deal_partyrows exist for all submitted parties, with blank commission values defaulted to'0'.
UI trigger: "Add New Deal" button. Visible when on the Deals screen. Always enabled.
5.2 Edit Deal
Preconditions:
- A deal exists.
- User has clicked the edit icon on a deal row.
Procedure reference: Upsert Deal with Parties
Steps:
- The Deal Management dialog opens pre-populated with the existing deal fields and party list.
- User edits any combination of name, reference, dates, active status, and parties (add, update, or remove rows).
- User submits. The system updates the
dealrow and reconcilesdeal_partyrows to exactly match the submitted list.
Postconditions:
dealrow reflects updated field values.deal_partyrows exactly match the submitted list (new parties inserted, removed parties deleted, updated parties modified).
UI trigger: Edit icon on a deal row. Visible for all deal rows. Always enabled.
5.3 Process Revenue Update (Sales Screen)
Preconditions:
- One or more
sales_itemrows exist in the Sales pipeline withsales_block.process_status_cd='U'(Unprocessed) or'F'(Failed). - User has selected one or more rows using checkboxes on the Sales screen.
Procedure reference: Process Revenue Update
Steps:
- User selects one or more sales pipeline item rows and clicks "Process Revenue Update."
- For each selected item's
sales_block, the system runs three-layer validation in order. - On success: revenue items and billing items are created or updated;
sales_block.process_status_cdset to'P'. - On failure:
sales_block.process_status_cdset to'F';sales_block.error_descriptionpopulated; a toast error is shown.
Postconditions:
sales_block.process_status_cd='P'for successfully processed blocks.- Revenue items and billing items exist for all successfully processed blocks.
UI trigger: "Process Revenue Update" button at the top of the Sales Items grid. Visible always. Enabled only when at least one row checkbox is selected. Label shows "Processing... (N)" during the operation.
5.4 Edit Sales Item (Sales Pipeline Screen)
Preconditions:
- A
sales_itemrow exists in the sales pipeline. - User has clicked the "Edit" button on the row.
Procedure reference: Update Sales Item Pipeline
Steps:
- The Sales Item Management dialog opens pre-populated with the current
sales_itemfield values. - User edits fields. Metadata-only changes (name,
sales_item_status_cd,revenue_date_status_cd) copy existing payment terms with incremented versions. Financial or schedule changes regenerate payment terms from scratch. - On save, the system creates a new
sales_blockwith a newsales_itemrow at an incrementedsales_item_ver.
Postconditions:
- A new
sales_blockandsales_itemrow exist in the pipeline. - Payment terms regenerated (financial/schedule change) or copied with incremented
payment_term_ver(metadata-only change).
UI trigger: "Edit" button on each row of the Sales Items grid. Always visible. Always enabled.
5.5 Split Payment Item (Sales Pipeline Screen)
Preconditions:
- A
sales_itemrow is selected in the Sales grid (payment terms panel is open). - Exactly one
payment_termrow is selected via checkbox in the payment terms panel.
Procedure reference: Split Sales Item Pipeline
Steps:
- User selects a payment term and clicks "Split Payment Item."
- The Split dialog opens. User enters the Revenue Item ID, split amount, and new item due date.
- The system validates the inputs and executes the split, creating a new
sales_itemfor the split portion.
Postconditions:
- The original
payment_term.gross_amtis reduced by the split amount. - A new
sales_itemandpayment_termexist for the split portion. - Downstream revenue and billing items updated.
UI trigger: "Split Payment Item" button in the Payment Terms panel. Visible when payment terms are loaded. Enabled only when exactly one payment term checkbox is selected.
5.6 Create Sales Item (Sales Pipeline Screen)
Preconditions:
- User is on the Sales Management screen.
- User has clicked "Create Sales Item."
Procedure reference: Create Sales Item Pipeline
Steps:
- User selects the deal, UTA entity, client, contracted party, buyer, department, and currency.
- User enters gross amount, commission type and percentage/amount, revenue dates, and recognition style.
- User adds payment terms with amounts and due dates.
- User submits. The system creates a new
sales_blockwithsales_itemandpayment_termrows.
Postconditions:
- A new
sales_block,sales_item, and Npayment_termrows exist in the pipeline. - The sales block is ready for revenue processing.
UI trigger: "Create Sales Item" button on the Sales Management screen. Always visible. Always enabled.
5.7 Search Deals
Preconditions:
- User is on the Deals search screen.
Procedure reference: Search Deals
Steps:
- User enters one or more search criteria: deal reference (partial), deal name (partial), start date range, end date range, and optionally restricts to active deals only.
- User clicks Search. The system executes
searchDealswith all provided criteria combined as AND conditions. - Results appear in the deals grid. Clicking a row loads the deal party detail panel.
Postconditions:
dealrows matching all provided criteria are displayed in the results grid.- Clicking a row loads
deal_partydata for the selected deal viagetDealById.
UI trigger: "Search" button in the Search Deals collapsible panel. The results grid is not populated until the user executes a search.
6. Permissions & Role-Based Access
**PoC Artifact:**
The current PoC does not enforce role-based access on deal management screens. All mutations use 'SYSTEM' as the actor identifier. The table below describes the intended production model. Cash management roles (CASH_MANAGER, CASH_PROCESSOR, SETTLEMENT_APPROVER) should be read-only on deals data.
| Action | CASH_MANAGER | CASH_PROCESSOR | SETTLEMENT_APPROVER | IT |
|---|---|---|---|---|
| Search and view deals | Yes | Yes | Yes | Yes |
| View deal party details | Yes | Yes | Yes | Yes |
| View sales items and payment terms | Yes | Yes | Yes | Yes |
| Create / edit deal | — | — | — | Yes |
| Manage deal parties (add, update, remove) | — | — | — | Yes |
| Create / edit sales pipeline item (Sales screen) | — | — | — | Yes |
| Split sales item (Sales screen) | — | — | — | Yes |
| Process revenue update (Sales screen) | — | — | — | Yes |
Field-level restrictions:
deal.deal_reference, party commission fields (deal_party_commission_perc,deal_party_commission_amt), and allsales_itemfinancial fields are editable only by IT in the current PoC.- All users can view deal summary data, navigate to
/deals/[id], and follow the link to related revenue items.
7. Integration Points
7.1 Upstream
| Source | Data Provided | Mechanism |
|---|---|---|
| Party master data | party.party_id, party.display_name, party.first_name, party.last_name, party.company_name for party assignment on deals and sales items | FK lookup via party table |
| UTA Entity master | uta_entity.uta_entity_id, uta_entity.uta_entity_name for billing entity selection on sales items | FK lookup via uta_entity table |
| Department master | department.department_id, department.department_name for department assignment on sales items | FK lookup via department table |
| Code master | Commission type (COMMISSION_TYPE_CD), revenue recognition style (REVENUE_ITEM_REC_STYLE_CD), revenue date status (REVENUE_ITEM_DATE_STATUS_CD), sales item status (REVENUE_ITEM_STATUS_CD), currency (CURRENCY_CD), party role type (PARTY_ROLE_TYPE_CD) | code_master table lookups |
7.2 Downstream
| Consumer | Data Consumed | Mechanism |
|---|---|---|
| Billing Items workflow | billing_item and billing_item_detail (REV and PAY) rows created by processRevenueUpdate; billing_item.payment_term_ref soft-joins to payment_term.payment_term_ref | Pipeline processing writes billing_item rows from payment_term records |
| Revenue Items workflow | revenue_items and revenue_item_schedules created or updated by processRevenueUpdate; soft-joined by sales_item_ref | Pipeline processing writes revenue_items rows from sales_item records |
| Worksheets workflow | billing_item_detail rows (REV and PAY) are the receivables applied when cash is received | FK via cash_receipt_application.billing_item_detail_id |
| Tax and Withholding | sales_item.service_country_cd and service_state_cd drive tax jurisdiction determination at worksheet apply time | Read by WithholdingTaxService via billing_item → sales_item_ref → sales_item |
| Assignments workflow | deal.deal_id is the top level of the responsibility assignment hierarchy (Deal → Client → Department) | FK via assignment.deal_id; hierarchy walks up if no deal-level owner found |
7.3 External Integrations
No external integrations for this workflow. Deal and sales item data is entered and managed entirely within the application. Bank adapters and outbound payment execution are downstream of billing items, not deals.
8. Functional Screen Requirements
8.1 Deals Search Screen
Route: /deals
Data loading:
- No data loaded on page entry. Results are populated only after the user executes a search.
searchDeals— Search Deals — executed on Search button clickgetDealById— Get Deal by ID — loaded when a deal row is clicked
Search Panel Region
Collapsible panel containing all search filter fields. Expanded by default when no search has been performed.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Deal Reference | User input → filter on deal.deal_reference (partial match) | Yes | Always visible |
| Deal Name | User input → filter on deal.deal_name (partial match) | Yes | Always visible |
| Start Date From | User input → lower bound on deal.deal_start_dt | Yes | Always visible |
| Start Date To | User input → upper bound on deal.deal_start_dt | Yes | Always visible |
| End Date From | User input → lower bound on deal.deal_end_dt | Yes | Always visible |
| End Date To | User input → upper bound on deal.deal_end_dt | Yes | Always visible |
| Active Only (checkbox) | User input → filter deal.active_ind = true | Yes | Always visible |
Grid features:
- Sortable columns: N/A (search panel, not a grid)
- Filters: N/A (this region IS the filter panel)
- Row selection: N/A
- Pagination: N/A
Conditional display:
- Search panel is expanded by default when no search has been performed.
- "No Search Performed" empty state shown below the panel until the user clicks Search.
- Saved search controls (Save, Load, Delete) visible after at least one search has been performed.
Results Grid Region
Displays deals matching the search criteria after the user executes a search.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Deal ID | deal.deal_id | No | Always visible |
| Reference | deal.deal_reference | No | Always visible |
| Name | deal.deal_name | No | Always visible |
| Start Date | deal.deal_start_dt | No | Always visible |
| End Date | deal.deal_end_dt | No | Always visible |
| Active | deal.active_ind rendered as "Yes" / "No" | No | Always visible |
Grid features:
- Sortable columns: All columns
- Filters: Global text filter
- Row selection: Single-click loads the Deal Parties panel; checkbox for multi-select
- Pagination: Yes
Conditional display:
- Results grid visible only after a search has been executed.
- Clicking a deal row loads the Deal Parties panel below.
- Deep-linking via
?dealId={id}URL parameter auto-selects the deal on page load.
Deal Parties Detail Panel Region
Appears below the results grid when a deal row is selected.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Party ID | deal_party.party_id | No | Always visible |
| First Name | party.first_name | No | Always visible |
| Last Name | party.last_name | No | Always visible |
| Company Name | party.company_name | No | Always visible |
| Commission % | deal_party.deal_party_commission_perc | No | Always visible |
| Commission Amt | deal_party.deal_party_commission_amt | No | Always visible |
Grid features:
- Sortable columns: All columns
- Filters: Global text filter
- Row selection: Checkbox multi-select
- Pagination: Yes
Conditional display:
- Panel visible only when a deal row is selected.
- "Loading details..." shown while
getDealByIdis in progress. - "No parties found for this deal" shown when the deal has zero
deal_partyrows. - "Failed to load details" shown on error.
- Panel heading shows the deal reference (or deal ID if reference is absent).
8.2 Deal Detail Screen
Route: /deals/[id]
Data loading:
getDealById— Get Deal by ID — loaded on page entry; renders 404 if deal not found
Information Region
Displays core deal header fields.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| ID | deal.deal_id | No | Always visible |
| Reference | deal.deal_reference | No | Always visible |
| Name | deal.deal_name | No | Always visible |
| Start Date | deal.deal_start_dt | No | Always visible |
| End Date | deal.deal_end_dt | No | Always visible |
| Active | deal.active_ind rendered as "Yes" / "No" | No | Always visible |
Deal Parties Region
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Party ID | deal_party.party_id | No | Always visible |
| Commission % | deal_party.deal_party_commission_perc | No | Always visible |
| Commission Amt | deal_party.deal_party_commission_amt | No | Always visible |
Grid features:
- Sortable columns: Party ID, Commission %
- Filters: None
- Row selection: None
- Pagination: No
Related Revenue Items Region
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Revenue Items link | Navigation link: /revenue?dealId={deal.deal_id} | No | Always visible |
Conditional display:
- "Back to Deals" button navigates to
/deals. - Revenue items link always visible.
8.3 Sales Management Screen
Route: /sales
Data loading:
getSalesItems— Get Sales Items — loads allsales_itemrows from the pipeline on page entry
Sales Items Grid Region
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Sales Item ID | sales_item.sales_item_id | No | Hidden by default |
| Sales Block ID | sales_item.sales_block_id | No | Hidden by default |
| Ref | sales_item.sales_item_ref | No | Always visible |
| Ver | sales_item.sales_item_ver | No | Always visible |
| Block Status | sales_block.process_status_cd rendered as Unprocessed / Processed / Failed / Skipped | No | Always visible |
| Deal | deal.deal_name resolved from sales_item.deal_id | No | Always visible |
| Name | sales_item.name | No | Always visible |
| Client | Resolved from sales_item.client_entity_id → party name | No | Always visible |
| Gross Amt | sales_item.gross_amt | No | Always visible |
| Comm Type | sales_item.uta_commission_type | No | Hidden by default |
| Comm % | sales_item.uta_commission_perc | No | Always visible |
| Comm Amt | sales_item.uta_commission_amt | No | Always visible |
| Start Date | sales_item.revenue_start_dt | No | Always visible |
| End Date | sales_item.revenue_end_dt | No | Always visible |
| Rev Style | Resolved sales_item.rev_rec_style_cd description | No | Always visible |
| Date Status | Resolved sales_item.revenue_date_status_cd description | No | Always visible |
| Item Status | Resolved sales_item.sales_item_status_cd description | No | Always visible |
| Created By | sales_item.created_by | No | Hidden by default |
| Created Date | sales_item.created_dt | No | Hidden by default |
| Updated By | sales_item.updated_by | No | Hidden by default |
| Updated Date | sales_item.updated_dt | No | Hidden by default |
Grid features:
- Sortable columns: All visible columns
- Filters: Global text filter
- Row selection: Checkbox multi-select for batch "Process Revenue Update"; single-click expands the payment terms panel below
- Pagination: Yes
Conditional display:
- "Process Revenue Update" button visible always. Enabled when at least one row checkbox is selected. Shows "Processing... (N)" during operation.
- Block Status badge: Unprocessed (yellow), Processed (green), Failed (red), Skipped (grey). Failed rows show
sales_block.error_descriptionas tooltip hover. - "Edit" button on each row always visible and enabled.
- "Create Sales Item" button always visible and enabled.
Payment Terms Panel Region
Appears below the grid when a sales item row is single-clicked.
| Field / Column | Source | Editable? | Condition |
|---|---|---|---|
| Name | payment_term.name | No | Always visible |
| Amount | payment_term.gross_amt | No | Always visible |
| Due Date | payment_term.due_dt | No | Always visible |
| Ref | payment_term.payment_term_ref | No | Always visible |
| Ver | payment_term.payment_term_ver | No | Always visible |
Grid features:
- Sortable columns: Name, Amount, Due Date, Ref, Ver
- Filters: None
- Row selection: Checkbox single-select (required for Split Payment Item)
- Pagination: No
Conditional display:
- "Split Payment Item" button visible. Enabled only when exactly one payment term checkbox is selected.
- Close button (✕) in the top-right dismisses the panel and deselects the active row.
9. Additional Diagrams
Revenue Processing Validation Flow
flowchart TD
SB["sales_block\nprocess_status_cd = 'U'"] --> L1{"Layer 1\nData Validation"}
L1 -->|"Required fields missing\nor amounts invalid\nor term sum mismatch"| F["Set process_status_cd = 'F'\npopulate error_description"]
L1 -->|Pass| L2{"Layer 2\nConsistency Validation"}
L2 -->|"Existing revenue_items found\nwith changed immutable field"| F
L2 -->|Pass| L3{"Layer 3\nReferential Validation"}
L3 -->|"FK or code master\nreference not found"| F
L3 -->|Pass| CHECK{"revenue_items exists\nfor sales_item_ref?"}
CHECK -->|Yes - Update path| UPD["Update revenue_items\nand billing items"]
CHECK -->|No - Create path| CRE["INSERT revenue_items\nINSERT billing_item rows\nINSERT billing_item_detail REV+PAY"]
UPD --> DONE["Set process_status_cd = 'P'"]
CRE --> DONE10. Cross-References
| Document | Relationship |
|---|---|
| Deals Sales Items Payment Terms Data Model | Defines all tables used in this workflow: deal, deal_party, sales_item, sales_item_party, sales_meta_data, sales_block, payment_term |
| Deals Sales Items Payment Terms Queries | Specifies all read operations used in this workflow: deal master queries, sales pipeline queries, and metadata queries |
| Deals Sales Items Payment Terms Procedures | Specifies all data mutation operations: deal CRUD, deal party management, sales item lifecycle, payment term management, revenue processing, and splits |
| Billing Items Workflow | Downstream: processRevenueUpdate creates billing_item and billing_item_detail records from payment_term data. These are the receivables applied in cash management. |
| Worksheets Workflow | Downstream: billing_item_detail rows (REV and PAY) are the receivables that users apply when a cash receipt arrives. |
| Assignments Workflow | deal.deal_id is the top level of the responsibility assignment hierarchy. If no deal-level assignment exists, the system walks up to client then department. |
| Tax Forms Workflow | sales_item.service_country_cd and service_state_cd drive tax jurisdiction determination at worksheet apply time via WithholdingTaxService. |
11. Gherkin Scenarios
Feature: Deals - Deal Master Management
Scenario: Create a new deal with parties
Given no deal exists for client "Taylor Swift" (party_id = 101)
When a user creates a deal with deal_name = "2026 Eras Tour - Stadium Block"
And assigns a party with party_id = 202 (StadiumCo), party_role_type_cd = 'BUYER', deal_party_commission_perc = '0.0000'
And assigns a party with party_id = 101 (Taylor Swift), party_role_type_cd = 'CLIENT', deal_party_commission_perc = '15.0000'
Then a new deal row exists with deal_name = "2026 Eras Tour - Stadium Block"
And deal.deal_reference is auto-generated matching the pattern 'DEAL-[A-Z0-9]+'
And two deal_party rows exist linked to the new deal.deal_id
And deal_party.deal_party_commission_perc = '15.0000' for party_id = 101
Scenario: Edit deal party commission percentage
Given a deal (deal_id = 500) has a deal_party row (deal_party_id = 88) with deal_party_commission_perc = '15.0000'
When a user updates deal_party_id = 88 to deal_party_commission_perc = '20.0000'
Then deal_party.deal_party_commission_perc = '20.0000' for deal_party_id = 88
Scenario: Remove a party from a deal via full-list upsert
Given a deal (deal_id = 500) has deal_party rows for deal_party_id = 88, 89, and 90
When a user saves the deal with a party list containing only deal_party_id = 88 and deal_party_id = 89
Then the deal_party row with deal_party_id = 90 no longer exists
And deal_party rows for deal_party_id = 88 and 89 still exist
Scenario: Blank commission value is defaulted to zero on save
Given a user creates a deal party with deal_party_commission_perc left blank
Then deal_party.deal_party_commission_perc = '0' in the saved deal_party rowFeature: Deals - Revenue Processing
Scenario: Process revenue update succeeds for a valid sales block
Given a sales_block (sales_block_id = 300) has process_status_cd = 'U'
And the associated sales_item has all required fields present and gross_amt = '75000.00'
And SUM(payment_term.gross_amt) for sales_block_id = 300 equals '75000.00'
And all deal, party, and code_master references resolve successfully
When a user selects the sales item row and clicks "Process Revenue Update"
Then sales_block.process_status_cd = 'P' for sales_block_id = 300
And one revenue_items row exists with sales_item_ref matching the block's sales_item
And N billing_item rows exist (one per payment_term in the block), each with two billing_item_detail rows typed 'REV' and 'PAY'
Scenario: Process revenue update fails referential validation
Given a sales_block (sales_block_id = 301) has process_status_cd = 'U'
And its associated sales_item references deal_id = 9999 which does not exist in the deal table
When the system processes sales_block_id = 301
Then sales_block.process_status_cd = 'F' for sales_block_id = 301
And sales_block.error_description contains the referential failure message
And no revenue_items or billing_item rows are created
Scenario: Consistency validation blocks immutable field change
Given a revenue_items row exists with sales_item_ref = 'REF-ABCD12', current_item_ind = true, and uta_entity_id = 10
And a new sales_block (sales_block_id = 302) has a sales_item with sales_item_ref = 'REF-ABCD12' and uta_entity_id = 20
When the system processes sales_block_id = 302
Then sales_block.process_status_cd = 'F' for sales_block_id = 302
And sales_block.error_description describes an immutable field mismatch on uta_entity_idFeature: Deals - Sales Item Management
Scenario: Edit a sales pipeline item with metadata-only change
Given a sales_item (sales_item_id = 400) exists with sales_item_ref = 'REF-XYZ', sales_item_ver = 2
And it has two payment_term rows
When a user edits the sales_item name from "Q1 License" to "Q1 License Fee"
Then a new sales_block is created with a new sales_item row at sales_item_ver = 3 and sales_item_ref = 'REF-XYZ'
And the two payment_term rows are copied with incremented payment_term_ver values
Scenario: Split a sales pipeline payment item
Given a sales_item (sales_item_id = 410) has gross_amt = '100000.00' and exactly one payment_term with gross_amt = '100000.00'
When a user splits with splitAmount = 40000.00 and newItemDueDate = '2026-06-30'
Then the original payment_term.gross_amt is reduced to '60000.00'
And a new sales_item exists with gross_amt = '40000.00' and one payment_term with due_dt = '2026-06-30'
Scenario: Split fails when the item has multiple payment terms
Given a sales_item (sales_item_id = 420) has two payment_term rows
When a user attempts to split sales_item_id = 420
Then the system returns an error that the item must have exactly one payment term to be split
And no changes are made to any rowsFeature: Deals - Deal Search
Scenario: Search for active deals by name
Given multiple deal rows exist, some with active_ind = true and some with active_ind = false
When a user enters deal_name = "Eras Tour", checks the Active Only filter, and clicks Search
Then only deal rows where deal.deal_name ILIKE '%Eras Tour%' AND deal.active_ind = true are returned
And the results grid displays the matching rows
Scenario: View party details for a deal in search results
Given a search has returned deal (deal_id = 500) in the results grid
And deal_id = 500 has two deal_party rows linked to it
When a user clicks the row for deal_id = 500
Then getDealById is executed with deal_id = 500
And the Deal Parties panel displays both deal_party rows with party names and commission fields
Scenario: Deep-link to a specific deal via URL parameter
Given a deal with deal_id = 500 exists
When a user navigates to /deals?dealId=500
Then getDealById is executed with deal_id = 500
And the deal appears in the results grid as the only result
And the Deal Parties panel is automatically populated for deal_id = 500