{
  "apiVersion": 65,
  "label": "Quote Expiration Date Default",
  "description": "Defaults a blank Quote.ExpirationDate to the end of the quarter of the save that stamps it (quarter boundaries 3/31, 6/30, 9/30, 12/31), rolling to the next quarter end when fewer than 15 days remain (deal-desk rule: a quote created 2026-06-20 expires 2026-09-30, not in 10 days). On the create path this IS the creation quarter - the deal-desk contract verbatim. On the update path (which exists to heal the blank stock) it is deliberately the quarter of the healing save, NOT the creation quarter: stock quotes are months old, and a creation-quarter stamp would set an expiration already in the past - expired at the moment of stamping. The source org fills this field on 899 of 899 quotes yet has no platform mechanism for it - no validation rule, not on any page layout, no Apex/flow writer; the value is set by its custom quote-creation surface under a month/quarter-end convention (95 percent of values are month ends). This platform's native createQuote path has no such surface, so native quotes were left blank (25 of 37). Blank-only stamping: a hand-set date always wins, and firing on update as well lets the blank stock heal on the next save of each quote. Before-save direct $Record assignment (Std_OpportunityStageDerivedFields pattern); the formula avoids DATE()/TEXT() deliberately - DATE(y,m,d) is not in the expression-engine registry and TEXT of numbers is subject to the decimal-rendering gap - building month arithmetic from DATE_ADD/ADDMONTHS on TODAY() only.",
  "processType": "AutoLaunchedFlow",
  "status": "Active",
  "start": {
    "locationX": 0,
    "locationY": 0,
    "connector": {
      "targetReference": "Expiration_Is_Blank"
    },
    "object": "Quote",
    "recordTriggerType": "CreateAndUpdate",
    "triggerType": "RecordBeforeSave"
  },
  "formulas": [
    {
      "name": "QuarterEndWithGrace",
      "dataType": "Date",
      "expression": "IF(AND(MOD(MONTH(TODAY()),3)=0, DAY(TODAY()) > CASE(MONTH(TODAY()),3,16,6,15,9,15,12,16,31)), DATE_ADD(ADDMONTHS(DATE_ADD(TODAY(),1-DAY(TODAY())), 6-MOD(MONTH(TODAY())-1,3)), -1), DATE_ADD(ADDMONTHS(DATE_ADD(TODAY(),1-DAY(TODAY())), 3-MOD(MONTH(TODAY())-1,3)), -1))"
    }
  ],
  "decisions": [
    {
      "name": "Expiration_Is_Blank",
      "label": "Expiration Is Blank",
      "locationX": 0,
      "locationY": 0,
      "defaultConnectorLabel": "Already Set",
      "rules": [
        {
          "name": "Blank",
          "conditionLogic": "and",
          "conditions": [
            {
              "leftValueReference": "$Record.ExpirationDate",
              "operator": "IsNull",
              "rightValue": {
                "booleanValue": true
              }
            }
          ],
          "connector": {
            "targetReference": "Assign_Quarter_End"
          },
          "label": "Blank"
        }
      ]
    }
  ],
  "assignments": [
    {
      "name": "Assign_Quarter_End",
      "label": "Assign Quarter End",
      "locationX": 0,
      "locationY": 0,
      "assignmentItems": [
        {
          "assignToReference": "$Record.ExpirationDate",
          "operator": "Assign",
          "value": {
            "elementReference": "QuarterEndWithGrace"
          }
        }
      ]
    }
  ]
}
