{
  "id": "SCN-QTO-001",
  "name": "Quote-to-Order Full Flow (Positive + Negative)",
  "description": "完整链路测试：Opportunity → Quote → Order，含正向流程和反向用例，覆盖 Quote-to-Order 全链路字段自动填充、状态联动、权限校验",
  "priority": "P0",
  "bug_ref": "#511, #563, #564, #565, #572",

  "setup": {
    "description": "前置数据：Account + Opportunity + OpportunityLineItems + Effective Contract",
    "seed_keys": ["Account_0", "Opportunity_0", "Contract_0"],
    "custom_setup": null
  },

  "teardown_scenario": "teardown_positive",

  "steps": [

    {
      "step": 1,
      "name": "【正向】从 Opportunity 创建 Quote",
      "api": {
        "method": "POST",
        "endpoint": "/services/data/v63.0/sobjects/Quote",
        "payload": {
          "OpportunityId": "{OpportunityId}",
          "Name": "Auto-Quote-{timestamp}",
          "Status": "Draft"
        }
      },
      "expects": { "status_code": 201 },
      "extract": {
        "QuoteId": "id",
        "QuoteNumber": "QuoteNumber"
      },
      "verify": {
        "query_after": {
          "object": "Quote",
          "assertions": [
            { "field": "OpportunityId", "operator": "eq", "value": "{OpportunityId}" },
            { "field": "Status", "operator": "eq", "value": "Draft" },
            { "field": "AccountId", "operator": "is_not_null" }
          ]
        }
      }
    },

    {
      "step": 2,
      "name": "【正向】验证 Quote 产品行从 Opportunity 完整复制",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/query/?q=SELECT+Id,Product2Id,ProductName,Quantity,UnitPrice,Discount,NetPrice+FROM+QuoteLineItem+WHERE+QuoteId='{QuoteId}'"
      },
      "expects": { "status_code": 200 },
      "extract": { "QuoteLineItemCount": "totalSize" },
      "verify": {
        "assertions": [
          { "field": "totalSize", "operator": "gt", "value": 0 }
        ]
      }
    },

    {
      "step": 3,
      "name": "【正向】验证 Quote 8个产品字段完整性",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/sobjects/Quote/{QuoteId}"
      },
      "expects": { "status_code": 200 },
      "verify": {
        "assertions": [
          { "field": "Net_Fees__c", "operator": "is_not_null" },
          { "field": "Discount__c", "operator": "is_not_null" },
          { "field": "TCV__c", "operator": "is_not_null" },
          { "field": "ACV__c", "operator": "is_not_null" }
        ]
      }
    },

    {
      "step": 4,
      "name": "【正向】验证 Quote Status=Pending（新创建未提交）",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/sobjects/Quote/{QuoteId}"
      },
      "expects": { "status_code": 200 },
      "verify": {
        "assertions": [
          { "field": "Status", "operator": "eq", "value": "Pending" }
        ]
      }
    },

    {
      "step": 5,
      "name": "【正向】Quote 提交审批，Status 变为 Approved",
      "api": {
        "method": "POST",
        "endpoint": "/process/approvals",
        "payload": {
          "objectId": "{QuoteId}",
          "actionType": "Submit"
        }
      },
      "expects": { "status_code": 200 },
      "verify": {
        "query_after": {
          "object": "Quote",
          "assertions": [
            { "field": "Status", "operator": "eq", "value": "Approved" }
          ]
        }
      }
    },

    {
      "step": 6,
      "name": "【正向】基于 Approved Quote 创建 Order（Account 下有 Effective Contract）",
      "api": {
        "method": "POST",
        "endpoint": "/services/data/v63.0/sobjects/Order",
        "payload": {
          "QuoteId__c": "{QuoteId}",
          "AccountId": "{AccountId}",
          "Status": "Draft"
        }
      },
      "expects": { "status_code": 201 },
      "extract": {
        "OrderId": "id",
        "OrderNumber": "OrderNumber"
      },
      "verify": {
        "query_after": {
          "object": "Order",
          "assertions": [
            { "field": "Status", "operator": "eq", "value": "Draft" },
            { "field": "AccountId", "operator": "eq", "value": "{AccountId}" },
            { "field": "ContractId", "operator": "is_not_null" }
          ]
        }
      }
    },

    {
      "step": 7,
      "name": "【正向】验证 Order Name 格式为 JP-OF-XXXXXXXX",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/sobjects/Order/{OrderId}"
      },
      "expects": { "status_code": 200 },
      "extract": { "OrderName": "Name" },
      "verify": {
        "assertions": [
          { "field": "Name", "operator": "matches", "value": "^JP-OF-\\d{8}$" },
          { "field": "OrderNumber", "operator": "is_not_null" }
        ]
      }
    },

    {
      "step": 8,
      "name": "【正向】验证 Order 产品行与 Quote 完全一致",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/query/?q=SELECT+Id,Product2Id,Quantity,UnitPrice+FROM+OrderItem+WHERE+OrderId='{OrderId}'"
      },
      "expects": { "status_code": 200 },
      "extract": { "OrderLineItemCount": "totalSize" },
      "verify": {
        "assertions": [
          { "field": "totalSize", "operator": "eq", "value": "{QuoteLineItemCount}" }
        ]
      }
    },

    {
      "step": 9,
      "name": "【正向】验证 Order 字段从 Quote 自动带入",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/sobjects/Order/{OrderId}"
      },
      "expects": { "status_code": 200 },
      "verify": {
        "assertions": [
          { "field": "EffectiveDate", "operator": "is_not_null" },
          { "field": "AccountId", "operator": "eq", "value": "{AccountId}" }
        ]
      }
    },

    {
      "step": 10,
      "name": "【正向】Order 上传 PDF 后 Status 从 Draft 变为 Activated",
      "api": {
        "method": "PATCH",
        "endpoint": "/services/data/v63.0/sobjects/Order/{OrderId}",
        "payload": {
          "Status": "Activated",
          "ActivatedDate": "{today}"
        }
      },
      "expects": { "status_code": 200 },
      "verify": {
        "query_after": {
          "object": "Order",
          "assertions": [
            { "field": "Status", "operator": "eq", "value": "Activated" }
          ]
        }
      }
    },

    {
      "step": 11,
      "name": "【正向】验证 Contract 失效后 Order 保持 Activated 不受影响",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/sobjects/Order/{OrderId}"
      },
      "expects": { "status_code": 200 },
      "verify": {
        "assertions": [
          { "field": "Status", "operator": "eq", "value": "Activated" }
        ]
      }
    },

    {
      "step": 12,
      "name": "【正向】验证 Order 关联的 Contract 名称正确显示",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/sobjects/Order/{OrderId}?fields=ContractId,Contract.Name"
      },
      "expects": { "status_code": 200 },
      "verify": {
        "assertions": [
          { "field": "ContractId", "operator": "is_not_null" }
        ]
      }
    },

    {
      "step": 13,
      "name": "【正向】验证 Order TotalAmount 计算正确",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/sobjects/Order/{OrderId}"
      },
      "expects": { "status_code": 200 },
      "verify": {
        "assertions": [
          { "field": "TotalAmount", "operator": "is_not_null" }
        ]
      }
    },

    {
      "step": 14,
      "name": "【反向】Quote 未 Approved 时创建 Order 应返回错误",
      "api": {
        "method": "POST",
        "endpoint": "/services/data/v63.0/sobjects/Quote",
        "payload": {
          "OpportunityId": "{OpportunityId}",
          "Name": "Reverse-Quote-{timestamp}",
          "Status": "Draft"
        }
      },
      "expects": { "status_code": 201 },
      "extract": { "ReverseQuoteId": "id" },
      "verify": {
        "query_after": {
          "object": "Quote",
          "assertions": [
            { "field": "Status", "operator": "eq", "value": "Draft" }
          ]
        }
      },
      "teardown": {
        "method": "DELETE",
        "endpoint": "/services/data/v63.0/sobjects/Quote/{ReverseQuoteId}"
      }
    },

    {
      "step": 15,
      "name": "【反向】对 Draft Quote 创建 Order 应返回错误",
      "api": {
        "method": "POST",
        "endpoint": "/services/data/v63.0/sobjects/Order",
        "payload": {
          "QuoteId__c": "{ReverseQuoteId}",
          "AccountId": "{AccountId}",
          "Status": "Draft"
        }
      },
      "expects": { "status_code": 400 },
      "verify": {},
      "teardown": null
    },

    {
      "step": 16,
      "name": "【反向】Quote Name 和 Number 不可编辑（PATCH 应返回 400）",
      "api": {
        "method": "PATCH",
        "endpoint": "/services/data/v63.0/sobjects/Quote/{QuoteId}",
        "payload": {
          "Name": "Modified-Name-{timestamp}"
        }
      },
      "expects": { "status_code": 400 },
      "verify": {}
    },

    {
      "step": 17,
      "name": "【正向】SOQL 查询 Order 支持按 AccountId/Status/EffectiveDate 过滤",
      "api": {
        "method": "GET",
        "endpoint": "/services/data/v63.0/query/?q=SELECT+Id,Status,EffectiveDate+FROM+Order+WHERE+AccountId='{AccountId}'+AND+Status='Activated'"
      },
      "expects": { "status_code": 200 },
      "verify": {
        "assertions": [
          { "field": "totalSize", "operator": "gt", "value": 0 }
        ]
      }
    }

  ],

  "teardown": {
    "steps": [
      { "method": "DELETE", "endpoint": "/services/data/v63.0/sobjects/Order/{OrderId}" },
      { "method": "DELETE", "endpoint": "/services/data/v63.0/sobjects/Quote/{QuoteId}" }
    ]
  }
}
