{
  "apiVersion": 63,
  "status": "Active",
  "label": "Standard Create Order from Quote",
  "description": "Creates a draft Order from an Accepted Quote and copies the persistable Quote-to-Order fields through metadata field mappings. Linked Account data is carried by AccountId; denormalized Account billing/contact fields require target Order fields before they can be copied.",
  "runAtomically": true,
  "start": {
    "locationX": 40,
    "locationY": 0,
    "connector": {
      "targetReference": "GetQuote"
    }
  },
  "variables": [
    {
      "name": "quoteId",
      "dataType": "String",
      "isInput": true,
      "isOutput": true
    },
    {
      "name": "orderId",
      "dataType": "String",
      "isOutput": true
    }
  ],
  "recordLookups": [
    {
      "name": "GetQuote",
      "label": "Get source Quote",
      "locationX": 40,
      "locationY": 120,
      "object": "Quote",
      "filters": [
        {
          "field": "Id",
          "operator": "EqualTo",
          "value": {
            "elementReference": "quoteId"
          }
        }
      ],
      "outputReference": "$quote",
      "getFirstRecordOnly": true,
      "connector": {
        "targetReference": "ValidateQuoteExists"
      }
    },
    {
      "name": "GetSourceQuoteRecordType",
      "label": "Get source Quote RecordType",
      "locationX": 40,
      "locationY": 480,
      "object": "_System_RecordType",
      "filters": [
        {
          "field": "Id",
          "operator": "EqualTo",
          "value": {
            "elementReference": "$quote.RecordTypeId"
          }
        }
      ],
      "outputReference": "$sourceQuoteRecordType",
      "getFirstRecordOnly": true,
      "connector": {
        "targetReference": "GetOrderObjectMetadata"
      }
    },
    {
      "name": "GetOrderObjectMetadata",
      "label": "Get Order object metadata row",
      "locationX": 40,
      "locationY": 600,
      "object": "_System_Object",
      "filters": [
        {
          "field": "ApiName",
          "operator": "EqualTo",
          "value": {
            "stringValue": "Order"
          }
        }
      ],
      "outputReference": "$orderObjectMetadata",
      "getFirstRecordOnly": true,
      "connector": {
        "targetReference": "GetMatchingOrderRecordType"
      }
    },
    {
      "name": "GetMatchingOrderRecordType",
      "label": "Get matching Order RecordType",
      "locationX": 40,
      "locationY": 720,
      "object": "_System_RecordType",
      "filterLogic": "and",
      "filters": [
        {
          "field": "ObjectId",
          "operator": "EqualTo",
          "value": {
            "elementReference": "$orderObjectMetadata.Id"
          }
        },
        {
          "field": "Name",
          "operator": "EqualTo",
          "value": {
            "elementReference": "$sourceQuoteRecordType.Name"
          }
        },
        {
          "field": "IsActive",
          "operator": "EqualTo",
          "value": true
        }
      ],
      "outputReference": "$orderRecordType",
      "getFirstRecordOnly": true,
      "connector": {
        "targetReference": "ChooseOrderRecordType"
      }
    },
    {
      "name": "GetDefaultOrderRecordType",
      "label": "Get default Order RecordType",
      "locationX": 40,
      "locationY": 960,
      "object": "_System_RecordType",
      "filterLogic": "and",
      "filters": [
        {
          "field": "ObjectId",
          "operator": "EqualTo",
          "value": {
            "elementReference": "$orderObjectMetadata.Id"
          }
        },
        {
          "field": "Name",
          "operator": "EqualTo",
          "value": {
            "stringValue": "New"
          }
        },
        {
          "field": "IsActive",
          "operator": "EqualTo",
          "value": true
        }
      ],
      "outputReference": "$orderRecordType",
      "getFirstRecordOnly": true,
      "connector": {
        "targetReference": "ValidateOrderRecordTypeResolved"
      }
    },
    {
      "name": "GetQuoteLineItems",
      "label": "Get Quote line items",
      "locationX": 40,
      "locationY": 1200,
      "object": "QuoteLineItem",
      "filterLogic": "and",
      "filters": [
        {
          "field": "QuoteId",
          "operator": "EqualTo",
          "value": {
            "elementReference": "quoteId"
          }
        }
      ],
      "outputReference": "$quoteLineItems",
      "getFirstRecordOnly": false,
      "connector": {
        "targetReference": "CreateOrder"
      }
    }
  ],
  "decisions": [
    {
      "name": "ValidateQuoteExists",
      "label": "Reject if quoteId does not resolve",
      "locationX": 220,
      "locationY": 240,
      "rules": [
        {
          "name": "QuoteNotFound",
          "conditionLogic": "and",
          "conditions": [
            {
              "leftValueReference": "$quote.Id",
              "operator": "IsBlank"
            }
          ],
          "connector": {
            "targetReference": "FailInvalidQuoteId"
          },
          "label": "Quote not found"
        }
      ],
      "defaultConnector": {
        "targetReference": "ValidateQuoteAccepted"
      }
    },
    {
      "name": "ValidateQuoteAccepted",
      "label": "Reject if Quote is not Accepted",
      "locationX": 220,
      "locationY": 360,
      "rules": [
        {
          "name": "QuoteNotAccepted",
          "conditionLogic": "and",
          "conditions": [
            {
              "leftValueReference": "$quote.Status",
              "operator": "NotEqualTo",
              "rightValue": {
                "stringValue": "Accepted"
              }
            }
          ],
          "connector": {
            "targetReference": "FailQuoteNotAccepted"
          },
          "label": "Quote not Accepted"
        }
      ],
      "defaultConnector": {
        "targetReference": "ValidateQuoteHasAccount"
      }
    },
    {
      "name": "ValidateQuoteHasAccount",
      "label": "Reject if Quote has no Account",
      "locationX": 220,
      "locationY": 420,
      "rules": [
        {
          "name": "QuoteMissingAccount",
          "conditionLogic": "and",
          "conditions": [
            {
              "leftValueReference": "$quote.AccountId",
              "operator": "IsBlank"
            }
          ],
          "connector": {
            "targetReference": "FailQuoteMissingAccount"
          },
          "label": "Quote missing Account"
        }
      ],
      "defaultConnector": {
        "targetReference": "GetSourceQuoteRecordType"
      }
    },
    {
      "name": "ChooseOrderRecordType",
      "label": "Use matching Order RecordType or fall back to New",
      "locationX": 220,
      "locationY": 840,
      "rules": [
        {
          "name": "MatchingOrderRecordTypeMissing",
          "conditionLogic": "and",
          "conditions": [
            {
              "leftValueReference": "$orderRecordType.Id",
              "operator": "IsBlank"
            }
          ],
          "connector": {
            "targetReference": "GetDefaultOrderRecordType"
          },
          "label": "Matching Order RecordType missing"
        }
      ],
      "defaultConnector": {
        "targetReference": "GetQuoteLineItems"
      }
    },
    {
      "name": "ValidateOrderRecordTypeResolved",
      "label": "Reject if Order RecordType metadata does not resolve",
      "locationX": 220,
      "locationY": 1080,
      "rules": [
        {
          "name": "OrderRecordTypeMissing",
          "conditionLogic": "and",
          "conditions": [
            {
              "leftValueReference": "$orderRecordType.Id",
              "operator": "IsBlank"
            }
          ],
          "connector": {
            "targetReference": "FailMissingOrderRecordType"
          },
          "label": "Order RecordType missing"
        }
      ],
      "defaultConnector": {
        "targetReference": "GetQuoteLineItems"
      }
    }
  ],
  "customErrors": [
    {
      "name": "FailInvalidQuoteId",
      "label": "Invalid quoteId supplied",
      "locationX": 400,
      "locationY": 240,
      "customErrorMessages": [
        {
          "errorMessage": "quoteId does not refer to a Quote the current user can access",
          "statusCode": "MALFORMED_ID"
        }
      ]
    },
    {
      "name": "FailQuoteNotAccepted",
      "label": "Quote must be Accepted",
      "locationX": 400,
      "locationY": 360,
      "customErrorMessages": [
        {
          "errorMessage": "Create Order requires an Accepted Quote",
          "statusCode": "FIELD_INTEGRITY_EXCEPTION"
        }
      ]
    },
    {
      "name": "FailQuoteMissingAccount",
      "label": "Quote must have an Account",
      "locationX": 400,
      "locationY": 420,
      "customErrorMessages": [
        {
          "errorMessage": "Create Order requires Quote.AccountId",
          "statusCode": "REQUIRED_FIELD_MISSING"
        }
      ]
    },
    {
      "name": "FailMissingOrderRecordType",
      "label": "Missing Order RecordType metadata",
      "locationX": 400,
      "locationY": 1080,
      "customErrorMessages": [
        {
          "errorMessage": "Create Order could not resolve an active Order RecordType from source mapping or the New default",
          "statusCode": "FIELD_INTEGRITY_EXCEPTION"
        }
      ]
    }
  ],
  "recordCreates": [
    {
      "name": "CreateOrder",
      "label": "Create Order from Quote",
      "locationX": 40,
      "locationY": 1320,
      "object": "Order",
      "fieldMapping": {
        "sourceObject": "Quote",
        "sourceReference": "$quote",
        "targetObject": "Order",
        "actionType": "createOrder"
      },
      "inputAssignments": [
        {
          "field": "QuoteId",
          "value": {
            "elementReference": "quoteId"
          }
        },
        {
          "field": "RecordTypeId",
          "value": {
            "elementReference": "$orderRecordType.Id"
          }
        },
        {
          "field": "Status",
          "value": "Draft"
        },
        {
          "field": "EffectiveDate",
          "value": {
            "elementReference": "$Flow.CurrentDate"
          }
        }
      ],
      "assignRecordIdToReference": "orderId",
      "connector": {
        "targetReference": "CopyQuoteLineItems"
      }
    },
    {
      "name": "CreateOrderItem",
      "label": "Create OrderItem from QuoteLineItem",
      "locationX": 220,
      "locationY": 1560,
      "object": "OrderItem",
      "fieldMapping": {
        "sourceObject": "QuoteLineItem",
        "sourceReference": "$currentQuoteLineItem",
        "targetObject": "OrderItem",
        "actionType": "createOrder"
      },
      "inputAssignments": [
        {
          "field": "OrderId",
          "value": {
            "elementReference": "orderId"
          }
        }
      ],
      "connector": {
        "targetReference": "CopyQuoteLineItems"
      }
    }
  ],
  "loops": [
    {
      "name": "CopyQuoteLineItems",
      "label": "Copy QuoteLineItems",
      "locationX": 40,
      "locationY": 1440,
      "collectionReference": "$quoteLineItems",
      "assignNextValueToReference": "$currentQuoteLineItem",
      "iterationOrder": "Asc",
      "nextValueConnector": {
        "targetReference": "CreateOrderItem"
      }
    }
  ]
}
