Skip to content

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

FieldTypeDescription
dealEngineSalesItemIdInteger (PK)Unique identifier for the sales item in Deal Engine.
salesItemRefString(500)Immutable reference string linking to core Sales Items. Generated if new.
dealIdInteger (FK)Reference to the parent Deal.
nameString(200)Descriptive name of the sales item.
utaEntityIdIntegerID of the internal UTA business entity.
departmentIdIntegerID of the internal department.
clientEntityIdIntegerID of the Client party.
contractedPartyIdIntegerID of the Contracted Party (contracts/legal).
buyerEntityIdIntegerID of the Buyer party.
projectIdIntegerID of the Project (optional).
currencyCdString(10)Currency code (e.g., 'USD').
grossAmtDecimal(15,2)Total gross amount of the sales item.
utaCommissionTypeString(50)'P' (Percentage) or 'F' (Flat).
utaCommissionPercDecimal(5,4)Commission percentage (e.g., 0.1000 for 10%).
utaCommissionAmtDecimal(15,2)Total commission amount.
revenueStartDtDateStart date for revenue recognition.
revenueEndDtDateEnd date for revenue recognition.
revRecStyleCdString(1)'I' (Immediate), 'M' (Monthly), 'C' (Cash).
revenueDateStatusCdString(50)Status of the revenue date (e.g., 'C' Confirmed, 'E' Estimated).
salesItemStatusCdString(50)Status of the item (e.g., 'C' Confirmed).
paymentTermsTypeCdString(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

FieldTypeDescription
salesMetaDataIdInteger (PK)Unique identifier.
salesItemRefString(500)Reference to the parent Sales Item.
metaDataTypeCdString(50)Type code identifying the nature of the data (e.g., 'PROJECT_NAME', 'TERRITORY').
metaDataValueString(500)The actual value of the metadata if not a date.
metaDataDateValueString(500)The actual value of the metadata if a date.
commentString(2000)Optional comments or context.
startDtDateEffective start date.
endDtDateEffective end date.

1.3 Deal Engine Payment Term

Represents the installment plan for collecting the manufacturing gross amount. Table: deal_engine_payment_term

FieldTypeDescription
dealEnginePaymentTermIdInteger (PK)Unique identifier for the payment term.
dealEngineSalesItemIdInteger (FK)Reference to parent Sales Item.
paymentTermRefString(500)Immutable reference string.
nameString(200)Name of the installment (e.g., "Installment 1").
paymentPartyIdIntegerID of the party responsible for payment (Buyer or Client).
grossAmtDecimal(15,2)Amount for this specific installment.
dueDtDateDue date for payment.
dueDateStatusCdString(50)Status of the due date (e.g., 'U' Unconfirmed, 'C' Confirmed).
serviceLocationString(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)

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

typescript
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.
  • Amount Logic (Penny Perfect):
    • Calculate raw amountPerTerm = gross / count, floored to 2 decimals.
    • First N-1 terms get amountPerTerm.
    • Last term gets gross - (amountPerTerm * (N-1)) to ensure the total exactly matches the input gross, handling any rounding remainders.

2.3 Data Integrity Layers

The system enforces three layers of validation before processing:

  1. 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_amt must exactly equal sales_item.gross_amt (tolerance 0.01).
  2. Layer 2: Consistency

    • Immutable Fields: If the Sales Item already exists (has a salesItemRef linked to a revenue_item), certain fields cannot change to preserve financial history:
      • dealId
      • utaEntityId
      • clientEntityId
      • buyerEntityId
      • currencyCd
      • salesItemRef itself.
  3. 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 the code_master table.

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:

json
{
  "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:

json
{
  "success": true,
  "data": {
    "salesBlockId": 55001,
    "processResult": {
      "success": true,
      "data": null         // Void on success
    }
  }
}

Failure Response (Validation Error):

json
{
  "success": false,
  "error": "Validation Failure - Payment Gross does not match Sales Item"
}

Failure Response (Referential Error):

json
{
  "success": false,
  "error": "Reference Data not found - Client Entity"
}

Confidential. For internal use only.