{
  "apiVersion": 64,
  "label": "QuoteLineItem Term Derivation",
  "description": "Derives QuoteLineItem.Term_Months__c from the service window on every Create/Update before save. SERVICE_WINDOW_TERM_MONTHS is the single L2 owner shared with Quote.Term_months__c. Tier 1 returns an exact positive integer k when end+1 day equals the target-month-clamped anniversary addMonths(start, k); tier 2 preserves ROUND((calendar days + 1) / 30.4375, 1). This reproduces the source CRM entry convention without Salesforce Formula ADDMONTHS month-end anchoring. Incomplete, inverted, and non-positive windows continue through the existing fail-closed clear/gate path. Runs at triggerOrder 150 after the autofill chain and before QuoteLineItem_Net_Fees_Autocalc (200), which consumes the derived term in the same save.",
  "status": "Active",
  "processType": "AutoLaunchedFlow",
  "runAtomically": true,
  "start": {
    "triggerOrder": 150,
    "locationX": 0,
    "locationY": 0,
    "object": "QuoteLineItem",
    "triggerType": "RecordBeforeSave",
    "recordTriggerType": "CreateAndUpdate",
    "connector": {
      "targetReference": "Has_Both_Service_Dates"
    }
  },
  "decisions": [
    {
      "name": "Has_Both_Service_Dates",
      "label": "Has Both Service Dates",
      "locationX": 0,
      "locationY": 0,
      "defaultConnector": {
        "targetReference": "Clear_Term"
      },
      "defaultConnectorLabel": "Default - incomplete window, clear the term",
      "rules": [
        {
          "name": "Yes",
          "conditionLogic": "and",
          "conditions": [
            {
              "leftValueReference": "$Record.Service_Start_Date__c",
              "operator": "IsNull",
              "rightValue": {
                "booleanValue": false
              }
            },
            {
              "leftValueReference": "$Record.Service_End_Date__c",
              "operator": "IsNull",
              "rightValue": {
                "booleanValue": false
              }
            },
            {
              "leftValueReference": "DerivedTermMonths",
              "operator": "GreaterThan",
              "rightValue": {
                "numberValue": 0
              }
            }
          ],
          "connector": {
            "targetReference": "Stamp_Term"
          },
          "label": "Yes - derive the term from the window"
        }
      ]
    }
  ],
  "formulas": [
    {
      "name": "DerivedTermMonths",
      "dataType": "Number",
      "expression": "SERVICE_WINDOW_TERM_MONTHS({!$Record.Service_Start_Date__c}, {!$Record.Service_End_Date__c})"
    }
  ],
  "assignments": [
    {
      "name": "Stamp_Term",
      "label": "Stamp Derived Term",
      "locationX": 0,
      "locationY": 0,
      "assignmentItems": [
        {
          "assignToReference": "$Record.Term_Months__c",
          "operator": "Assign",
          "value": {
            "elementReference": "DerivedTermMonths"
          }
        }
      ]
    },
    {
      "name": "Clear_Term",
      "label": "Clear Term (incomplete window)",
      "locationX": 0,
      "locationY": 0,
      "assignmentItems": [
        {
          "assignToReference": "$Record.Term_Months__c",
          "operator": "Assign",
          "value": null
        }
      ]
    }
  ]
}
