Deal Engine Structure and API
Purpose
This document outlines the technical specifications for the Deal Engine application to Client Processing. It details the data structures, business logic, user interface defaults, and the API contract for integrating with the core Sales Service. This is a work in progress.
1. Data Structure
1.1 Deal Engine Sales Item
The core entity representing a revenue opportunity in the Deal Engine. Table: deal_engine_sales_item
| Field | Type | Description |
|---|---|---|
dealEngineSalesItemId | Integer (PK) | Unique identifier for the sales item in Deal Engine. |
salesItemRef | String(500) | Immutable reference string linking to core Sales Items. Generated if new. |
dealId | Integer (FK) | Reference to the parent Deal. |
name | String(200) | Descriptive name of the sales item. |
utaEntityId | Integer | ID of the internal UTA business entity. |
departmentId | Integer | ID of the internal department. |
clientEntityId | Integer | ID of the Client party. |
contractedPartyId | Integer | ID of the Contracted Party (contracts/legal). |
buyerEntityId | Integer | ID of the Buyer party. |
projectId | Integer | ID of the Project (optional). |
currencyCd | String(10) | Currency code (e.g., 'USD'). |
grossAmt | Decimal(15,2) | Total gross amount of the sales item. |
utaCommissionType | String(50) | 'P' (Percentage) or 'F' (Flat). |
utaCommissionPerc | Decimal(5,4) | Commission percentage (e.g., 0.1000 for 10%). |
utaCommissionAmt | Decimal(15,2) | Total commission amount. |
revenueStartDt | Date | Start date for revenue recognition. |
revenueEndDt | Date | End date for revenue recognition. |
revRecStyleCd | String(1) | 'I' (Immediate), 'M' (Monthly), 'C' (Cash). |
revenueDateStatusCd | String(50) | Status of the revenue date (e.g., 'C' Confirmed, 'E' Estimated). |
salesItemStatusCd | String(50) | Status of the item (e.g., 'C' Confirmed). |
paymentTermsTypeCd | String(1) | Configuration for payment terms ('I', 'W', 'M', 'Q', 'Y', 'C'). |
1.2 Sales Meta Data
Allows for custom, deal-specific metadata to be attached to the sales item. Table: sales_meta_data
| Field | Type | Description |
|---|---|---|
salesMetaDataId | Integer (PK) | Unique identifier. |
salesItemRef | String(500) | Reference to the parent Sales Item. |
metaDataTypeCd | String(50) | Type code identifying the nature of the data (e.g., 'PROJECT_NAME', 'TERRITORY'). |
metaDataValue | String(500) | The actual value of the metadata if not a date. |
metaDataDateValue | String(500) | The actual value of the metadata if a date. |
comment | String(2000) | Optional comments or context. |
startDt | Date | Effective start date. |
endDt | Date | Effective end date. |
1.3 Deal Engine Payment Term
Represents the installment plan for collecting the manufacturing gross amount. Table: deal_engine_payment_term
| Field | Type | Description |
|---|---|---|
dealEnginePaymentTermId | Integer (PK) | Unique identifier for the payment term. |
dealEngineSalesItemId | Integer (FK) | Reference to parent Sales Item. |
paymentTermRef | String(500) | Immutable reference string. |
name | String(200) | Name of the installment (e.g., "Installment 1"). |
paymentPartyId | Integer | ID of the party responsible for payment (Buyer or Client). |
grossAmt | Decimal(15,2) | Amount for this specific installment. |
dueDt | Date | Due date for payment. |
dueDateStatusCd | String(50) | Status of the due date (e.g., 'U' Unconfirmed, 'C' Confirmed). |
serviceLocation | String(200) | Location the service is taking plance (Data model TBD) |
1.4 Validation Schemas (Zod)
The application uses Zod for runtime validation of Data Transfer Objects (DTOs).
Sales Item Schema (CreateDealEngineSalesItemDTOSchema)
z.object({
dealId: z.number().optional().nullable(),
name: z.string().min(1, "Name is required"),
utaEntityId: z.number().optional().nullable(),
// ...other IDs
grossAmt: z.string().optional().nullable(),
utaCommissionType: z.string().optional().nullable(), // 'P' or 'F'
utaCommissionPerc: z.string().optional().nullable(),
// ...dates
paymentTerms: z.array(z.object({ ... })).optional() // Nested terms
})Payment Term Schema (CreateDealEnginePaymentTermDTOSchema)
z.object({
dealEngineSalesItemId: z.number().int().positive(),
paymentPartyId: z.number().optional().nullable(),
grossAmt: z.string().optional().nullable(),
dueDt: z.string().optional().nullable(),
dueDateStatusCd: z.string().optional().nullable(),
// ...
})2. Business Rules & Logic
2.1 Dropdown Logic
Rules for setting default values
Dropdown Filtering Logic:
- Deals: Filtered by the selected Client. If no client is selected, the list is empty.
- Payment Party: Composed of the Deal Parties list PLUS the selected Buyer (if not already in the list).
- Sales Item / Payment Term Sync: If deal terms are custom, the user can choose to sync the payment terms to the sales item. If sync is enabled, updating payment term amounts automatically updates the Sales Item Gross Amount.
2.2 Payment Term Generation
When paymentTermsTypeCd is NOT 'C' (Custom), payment terms are auto-generated based on the grossAmt and date range.
- Schedule Logic:
- Immediate ('I'): 1 term on
revenueStartDt. - Weekly ('W'): Terms every 7 days between start and end date.
- Monthly ('M'): Terms on the same day of each month.
- Quarterly ('Q'): Terms every 3 months.
- Annual ('Y'): Terms every year.
- Immediate ('I'): 1 term on
- Amount Logic (Penny Perfect):
- Calculate raw
amountPerTerm = gross / count, floored to 2 decimals. - First
N-1terms getamountPerTerm. - Last term gets
gross - (amountPerTerm * (N-1))to ensure the total exactly matches the input gross, handling any rounding remainders.
- Calculate raw
2.3 Data Integrity Layers
The system enforces three layers of validation before processing:
Layer 1: Data Validation
- Required Fields: All critical IDs and codes must be present.
- Non-Negative: Amounts cannot be less than zero.
- Math Check: Sum of
payment_term.gross_amtmust exactly equalsales_item.gross_amt(tolerance 0.01).
Layer 2: Consistency
- Immutable Fields: If the Sales Item already exists (has a
salesItemReflinked to arevenue_item), certain fields cannot change to preserve financial history:dealIdutaEntityIdclientEntityIdbuyerEntityIdcurrencyCdsalesItemRefitself.
- Immutable Fields: If the Sales Item already exists (has a
Layer 3: Referential Integrity
- Validates that all Foreign Keys (
dealId,clientEntityId, etc.) point to existing records in the database. - Validates that all Codes (
currencyCd,salesItemStatusCd, etc.) exist in thecode_mastertable.
- Validates that all Foreign Keys (
2.4 Meta Data Usage
The Sales Meta Data structure allows for custom, extensible data points to be associated with a Sales Block. This feature is designed to support deal-specific requirements where the standard data model may not capture all necessary nuances.
- Flexibility: The structure (
Type,Value) allows defining any key-value pair. - Deal Specificity: Metadata Schema can vary by Deal or Department.
- Filmed Entertainment Example:
- Context: A sales item represents a specific film or TV show.
- Requirement: The specific "Project Name" (Internal Title) needs to be passed through for reporting, even if it differs from the Deal Name.
- Usage:
metaDataTypeCd: 'PROJECT_NAME'metaDataValue: 'Mission Impossible 8'comment: 'Working Title'
3. API Specification
Operation: Create Deal Sales Block
This operation simulates an API call from the Deal Engine to the core Sales Service. It packages the Sales Item and its Payment Terms into a single transaction block for processing.
3.1 Request Structure (JSON)
Endpoint: (Conceptual) POST /api/sales-service/create-deal-sales-block
Payload:
{
"salesItem": {
"salesItemRef": "REF-12345", // Optional (if updating), Null for new
"salesItemVer": 1, // Optional, defaults to 1
"dealId": 101, // Required
"name": "Global Licensing Rights", // Required
"utaEntityId": 1, // Required
"departmentId": 5, // Optional
"clientEntityId": 500, // Required
"contractedPartyId": 500, // Required
"buyerEntityId": 600, // Required
"currencyCd": "USD", // Required
"grossAmt": "10000.00", // Required, String for precision
"utaCommissionType": "P", // 'P' or 'F'
"utaCommissionPerc": "0.1000", // Required for 'P'
"utaCommissionAmt": "1000.00", // Required
"revenueStartDt": "2024-01-01", // YYYY-MM-DD
"revenueEndDt": "2024-12-31", // YYYY-MM-DD
"revRecStyleCd": "M", // Required
"revenueDateStatusCd": "C", // Required
"salesItemStatusCd": "C" // Required
},
"paymentTerms": [
{
"paymentTermRef": "TERM-A", // Optional (update), Null for new
"paymentTermVer": 1,
"name": "Installment 1",
"paymentPartyId": 600, // Typically Buyer or Client
"grossAmt": "5000.00", // String for precision
"dueDt": "2024-01-01", // YYYY-MM-DD
"dueDateStatusCd": "C",
"serviceLocation": "US" // Optional
},
{
"paymentTermRef": "TERM-B",
"paymentTermVer": 1,
"name": "Installment 2",
"paymentPartyId": 600,
"grossAmt": "5000.00",
"dueDt": "2024-06-01",
"dueDateStatusCd": "E"
}
],
"metaData": [
{
"metaDataTypeCd": "PROJECT_NAME", // Required
"metaDataValue": "Top Gun 3", // Required
"comment": "Tentative Title", // Optional
"startDt": "2024-01-01", // Optional
"endDt": "2024-12-31" // Optional
}
],
"options": {
"user": "SYSTEM_USER" // String: Actor ID
}
}3.2 Response Structure
Success Response:
{
"success": true,
"data": {
"salesBlockId": 55001,
"processResult": {
"success": true,
"data": null // Void on success
}
}
}Failure Response (Validation Error):
{
"success": false,
"error": "Validation Failure - Payment Gross does not match Sales Item"
}Failure Response (Referential Error):
{
"success": false,
"error": "Reference Data not found - Client Entity"
}