[
  {
    "apiName": "QuoteLineItem",
    "keyPrefix": "0QL",
    "label": "Quote Line Item",
    "tableType": "standard_object",
    "category": "crm",
    "sharingModel": "ControlledByParent",
    "displayNameField": "LineNumber",
    "enableHierarchySharing": false,
    "description": "Standard Salesforce Quote Line Item — products on a quote; record-level access cascades from Quote.",
    "fields": [
      {
        "apiName": "QuoteId",
        "label": "Quote",
        "type": "masterdetail",
        "required": true,
        "referenceTo": [
          "Quote"
        ],
        "relationshipName": "Quote"
      },
      {
        "apiName": "PricebookEntryId",
        "label": "Price Book Entry",
        "type": "reference",
        "referenceTo": [
          "PricebookEntry"
        ],
        "relationshipName": "PricebookEntry",
        "validator": "runtime_scoped_lookup",
        "validatorConfig": "{\"filterMappings\":[{\"recordField\":\"QuoteId\",\"sourceField\":\"Pricebook2Id\",\"targetField\":\"Pricebook2Id\"}]}"
      },
      {
        "apiName": "Quantity",
        "label": "Quantity",
        "type": "double",
        "required": true
      },
      {
        "apiName": "UnitPrice",
        "label": "Sales Price",
        "type": "currency",
        "required": true
      },
      {
        "apiName": "CurrencyIsoCode",
        "label": "Currency ISO Code",
        "type": "picklist",
        "default": "USD",
        "options": [
          {
            "label": "Chinese Yuan",
            "value": "CNY"
          },
          {
            "label": "Japanese Yen",
            "value": "JPY"
          },
          {
            "label": "Singapore Dollar",
            "value": "SGD"
          },
          {
            "label": "U.S. Dollar",
            "value": "USD"
          }
        ]
      },
      {
        "apiName": "ListPrice",
        "label": "List Price",
        "type": "currency",
        "createable": false,
        "updateable": false
      },
      {
        "apiName": "TotalPrice",
        "label": "Total Price",
        "type": "formula",
        "createable": false,
        "updateable": false,
        "returnType": "currency",
        "formulaMode": "active",
        "formula": "Quantity * UnitPrice"
      },
      {
        "apiName": "Subtotal",
        "label": "Subtotal",
        "type": "formula",
        "createable": false,
        "updateable": false,
        "returnType": "currency",
        "formulaMode": "active",
        "formula": "Quantity * UnitPrice"
      },
      {
        "apiName": "Discount",
        "label": "Discount",
        "type": "percent"
      },
      {
        "apiName": "Description",
        "label": "Description",
        "type": "textarea"
      },
      {
        "apiName": "ServiceDate",
        "label": "Service Date",
        "type": "date"
      },
      {
        "apiName": "Product2Id",
        "type": "reference",
        "label": "Product",
        "referenceTo": [
          "Product2"
        ],
        "relationshipName": "Product2",
        "childRelationshipName": "QuoteLineItems"
      },
      {
        "apiName": "SourceOpportunityLineItemId__c",
        "type": "reference",
        "label": "Source Opportunity Line Item",
        "referenceTo": [
          "OpportunityLineItem"
        ],
        "relationshipName": "SourceOpportunityLineItem",
        "childRelationshipName": "QuoteLineItems"
      },
      {
        "apiName": "Net_fees__c",
        "type": "currency",
        "label": "Net Fees",
        "createable": false,
        "updateable": false,
        "description": "Whole-term net fees for this line, derived and read-only. Single writer is the QuoteLineItem_Net_Fees_Autocalc before-save flow: Unit_Net_Price__c * Quantity, multiplied by Term_Months__c only when PricebookEntry.Product2.Family is TiDB Enterprise Subscription (its unit price is a monthly rate; every other family's unit price is already the whole-engagement amount). Cleared when a required input goes blank. Enter Unit_Net_Price__c, Quantity and Term_Months__c — not this field, and not the deprecated Net_Fees_Total__c. Annualization happens once at the parent, in Quote.ACV_Amount__c; this field is never annualized."
      },
      {
        "apiName": "Net_Fees_Total__c",
        "type": "currency",
        "label": "Net Fees (Total) (Do Not Use)",
        "createable": false,
        "updateable": false,
        "description": "DEPRECATED and no longer read by anything. Net_fees__c is derived from Unit_Net_Price__c, Quantity and (for TiDB Enterprise Subscription) Term_Months__c, and the Quote NetFees/TCV header rollups sum Net_fees__c. Writing this field has no effect on any money figure. It is now read-only: a write is silently dropped by the platform capability gate, so callers get a 2xx and no value change - re-read the record if you need to confirm. Set Unit_Net_Price__c instead. The column is retained so the 24 historical rows stay readable; retiring it is a separate destructive migration."
      },
      {
        "apiName": "Product_Family__c",
        "label": "Product Family",
        "type": "formula",
        "formula": "TEXT(Product2.Family)",
        "returnType": "string",
        "formulaMode": "active",
        "createable": false,
        "updateable": false,
        "description": "Line product family, mirrored from the catalog (OLI-parity). Branch key for Total_List_Price__c term semantics."
      },
      {
        "apiName": "Total_List_Price__c",
        "label": "Total List Price",
        "type": "formula",
        "formula": "IF(TEXT(Product2.Family) = \"TiDB Enterprise Subscription\", ListPrice * Quantity * Term_Months__c, ListPrice * Quantity)",
        "returnType": "currency",
        "formulaMode": "active",
        "createable": false,
        "updateable": false,
        "description": "Pre-discount list total for this line, term-aware for Enterprise Subscription (SF source semantics: ES lines multiply by term months, all other families are list x quantity). Source for the Quote Total_List_Price__c header rollup (PR-B2a). ListPrice is stamped from the PricebookEntry by the autofill chain."
      },
      {
        "apiName": "Unit_Net_Price__c",
        "type": "currency",
        "label": "Unit Net Price"
      },
      {
        "apiName": "Service_Start_Date__c",
        "type": "date",
        "label": "Service Start Date"
      },
      {
        "apiName": "Service_End_Date__c",
        "type": "date",
        "label": "Service End Date"
      },
      {
        "apiName": "Term_Months__c",
        "type": "double",
        "label": "Term(Months)",
        "createable": false,
        "updateable": false,
        "description": "Derived and read-only. Single writer is the QuoteLineItem_Term_Derivation before-save flow, two-tier since the 2026-08-20 calendar-anniversary ruling: whole months when Service_End_Date__c + 1 day is a month-anniversary of Service_Start_Date__c (month-end clamping included, inverting the source-CRM addMonths(start, term) - 1 day entry convention), else ROUND((Service_End_Date__c - Service_Start_Date__c + 1) / 30.4375, 1); cleared when either date is blank or the window is inverted/same-day. The service dates are the authoritative input (2026-08-13 ACV overhaul decision) - enter dates, not this field; the identical two-tier expression in Quote.Term_months__c keeps line and header in agreement. Because the derivation clears it on an incomplete window, a populated value doubles as the per-line date-completeness marker counted by Quote.Termed_Line_Item_Count__c for the submit gate."
      },
      {
        "apiName": "Term_years__c",
        "type": "double",
        "label": "Term(years)"
      }
    ],
    "managedRelationships": [
      {
        "fieldApiName": "QuoteId",
        "parentObject": "Quote",
        "isSharingParent": true
      }
    ]
  }
]
