{
  "info": {
    "_postman_id": "9f5d1b74-2a28-47d5-93a0-55fe08c2f726",
    "name": "Revestimientos Chile · API Cotizaciones v1",
    "description": "Colección oficial del contrato v1 para inyectar cotizaciones. Ejecute las solicitudes en orden para validar creación, idempotencia, conflicto, seguridad, versión y reglas de negocio.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "endpoint",
      "value": "{{baseUrl}}/api/v1/integraciones/cotizaciones"
    },
    { "key": "pendingBody", "value": "" }
  ],
  "item": [
    {
      "name": "01 - Inyectar cotización pagada",
      "request": {
        "method": "POST",
        "header": [
          { "key": "Content-Type", "value": "application/json" },
          {
            "key": "X-Integration-Token",
            "value": "{{integrationToken}}",
            "type": "text"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"versionContrato\": \"1.0\",\n  \"idSolicitud\": \"POSTMAN-PAID-EVIDENCE-001\",\n  \"claveIdempotencia\": \"POSTMAN|RC-SCL|PAID-EVIDENCE-001\",\n  \"fechaHoraEnvio\": \"2026-07-27T12:00:00-04:00\",\n  \"origen\": { \"software\": { \"identificador\": \"POSTMAN\", \"nombre\": \"Postman\", \"version\": \"1.0\", \"ambiente\": \"DESARROLLO\" }, \"evento\": \"FORMALIZAR_COTIZACION\", \"fechaHoraEvento\": \"2026-07-27T11:59:00-04:00\", \"usuario\": { \"idUsuarioOrigen\": \"USR-001\", \"nombreUsuario\": \"vendedor\", \"nombreCompleto\": \"Vendedor Postman\", \"correo\": \"vendedor@example.cl\" } },\n  \"destino\": { \"codigoEmpresa\": \"REVESTIMIENTOS-CHILE\", \"codigoOrganizacion\": \"RC-SCL\" },\n  \"cotizacion\": {\n    \"idCotizacionOrigen\": \"POSTMAN-PAID-EVIDENCE-001\", \"numeroCotizacion\": \"ORIG-PAID-EVIDENCE-001\", \"versionOrigen\": 1, \"fechaHoraFormalizacion\": \"2026-07-27T11:59:00-04:00\", \"moneda\": \"CLP\",\n    \"clienteCotizacion\": { \"rut\": \"76123456-0\", \"nombreORazonSocial\": \"Constructora Pagada SpA\", \"giro\": \"Construcción\", \"correo\": \"compras@example.cl\", \"direccion\": { \"linea\": \"Av. Central 123\", \"comuna\": \"Santiago\", \"ciudad\": \"Santiago\", \"pais\": \"CL\" } },\n    \"clienteFacturacion\": { \"inicialmenteIgualAClienteCotizacion\": true, \"rut\": \"76123456-0\", \"razonSocial\": \"Constructora Pagada SpA\", \"giro\": \"Construcción\", \"correoDte\": \"dte@example.cl\" },\n    \"lineas\": [{ \"numeroLinea\": 1, \"producto\": { \"sku\": \"WPC-POSTMAN-01\", \"nombre\": \"Revestimiento WPC\", \"unidadMedida\": \"UN\" }, \"cantidad\": 10, \"precioUnitarioNeto\": 10000, \"descuento\": { \"porcentaje\": 0, \"monto\": 0 }, \"montoNeto\": 100000, \"montoIva\": 19000, \"montoTotal\": 119000, \"asignacionesStock\": [{ \"secuencia\": 1, \"tipoStock\": \"FISICO\", \"cantidad\": 10, \"bodega\": { \"codigo\": \"BOD-SCL-01\", \"nombre\": \"Bodega Santiago\" } }] }],\n    \"totales\": { \"montoNeto\": 100000, \"montoIva\": 19000, \"montoTotal\": 119000, \"montoPagado\": 119000, \"saldo\": 0 },\n    \"estadoPago\": \"PAGADO\", \"pagos\": [{ \"idPagoOrigen\": \"PAY-EVIDENCE-001\", \"fechaHoraPago\": \"2026-07-27T11:58:00-04:00\", \"monto\": 119000, \"medioPago\": \"TRANSFERENCIA\", \"referencia\": \"TRX-EVIDENCE-001\", \"pagador\": { \"rut\": \"76123456-0\", \"nombreORazonSocial\": \"Constructora Pagada SpA\", \"correo\": \"pagos@example.cl\" }, \"registradoPor\": { \"idUsuarioOrigen\": \"USR-001\", \"nombreUsuario\": \"vendedor\", \"nombreCompleto\": \"Vendedor Postman\", \"correo\": \"vendedor@example.cl\" }, \"observacion\": \"Pago total verificado en origen\" }],\n    \"observaciones\": { \"comercial\": \"Cotización pagada de prueba.\", \"interna\": \"Lista para facturar.\" }, \"embarquesEnCamino\": []\n  }\n}"
        },
        "url": "{{endpoint}}"
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "exec": [
              "pm.test('Creada o reintentada correctamente', () => pm.expect([200, 201]).to.include(pm.response.code));",
              "pm.test('Pagada queda habilitada para facturar', () => { const r = pm.response.json(); pm.expect(r.estadoPago).to.eql('Pagado'); pm.expect(r.estadoFacturacion).to.eql('HabilitadaParaFacturar'); });"
            ]
          }
        }
      ]
    },
    {
      "name": "02 - Inyectar pago pendiente",
      "request": {
        "method": "POST",
        "header": [
          { "key": "Content-Type", "value": "application/json" },
          {
            "key": "X-Integration-Token",
            "value": "{{integrationToken}}",
            "type": "text"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"versionContrato\": \"1.0\", \"idSolicitud\": \"POSTMAN-PENDING-001\", \"claveIdempotencia\": \"POSTMAN|RC-SCL|PENDING-001\", \"fechaHoraEnvio\": \"2026-07-27T12:10:00-04:00\",\n  \"origen\": { \"software\": { \"identificador\": \"POSTMAN\", \"nombre\": \"Postman\", \"version\": \"1.0\", \"ambiente\": \"DESARROLLO\" }, \"evento\": \"FORMALIZAR_COTIZACION\", \"fechaHoraEvento\": \"2026-07-27T12:09:00-04:00\", \"usuario\": { \"idUsuarioOrigen\": \"USR-002\", \"nombreUsuario\": \"vendedor\", \"nombreCompleto\": \"Vendedor Postman\", \"correo\": \"vendedor@example.cl\" } },\n  \"destino\": { \"codigoEmpresa\": \"REVESTIMIENTOS-CHILE\", \"codigoOrganizacion\": \"RC-SCL\" },\n  \"cotizacion\": {\n    \"idCotizacionOrigen\": \"POSTMAN-PENDING-001\", \"numeroCotizacion\": \"ORIG-PENDING-001\", \"versionOrigen\": 1, \"fechaHoraFormalizacion\": \"2026-07-27T12:09:00-04:00\", \"moneda\": \"CLP\",\n    \"clienteCotizacion\": { \"rut\": \"96543210-K\", \"nombreORazonSocial\": \"Cliente Pendiente Ltda.\", \"giro\": \"Terminaciones\", \"correo\": \"cliente@example.cl\" },\n    \"lineas\": [{ \"numeroLinea\": 1, \"producto\": { \"sku\": \"PERFIL-POSTMAN-01\", \"nombre\": \"Perfil terminación\", \"unidadMedida\": \"UN\" }, \"cantidad\": 4, \"precioUnitarioNeto\": 20000, \"descuento\": { \"porcentaje\": 0, \"monto\": 0 }, \"montoNeto\": 80000, \"montoIva\": 15200, \"montoTotal\": 95200, \"asignacionesStock\": [{ \"secuencia\": 1, \"tipoStock\": \"EN_CAMINO\", \"cantidad\": 4, \"numeroEnvio\": \"ENV-POSTMAN-001\" }] }],\n    \"totales\": { \"montoNeto\": 80000, \"montoIva\": 15200, \"montoTotal\": 95200, \"montoPagado\": 0, \"saldo\": 95200 }, \"estadoPago\": \"PAGO_PENDIENTE\", \"pagos\": [],\n    \"observaciones\": { \"comercial\": \"Pendiente de pago.\", \"interna\": \"Requiere aprobación.\" }, \"embarquesEnCamino\": [{ \"numeroEnvio\": \"ENV-POSTMAN-001\", \"fechaTentativaArribo\": \"2026-08-15\", \"estado\": \"EN_TRANSITO\" }]\n  }\n}"
        },
        "url": "{{endpoint}}"
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "exec": [
              "pm.collectionVariables.set('pendingBody', pm.request.body.raw);"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "exec": [
              "pm.test('Creada o reintentada correctamente', () => pm.expect([200, 201]).to.include(pm.response.code));",
              "pm.test('Pendiente requiere aprobación', () => { const r = pm.response.json(); pm.expect(r.estadoAprobacionPago).to.eql('Pendiente'); pm.expect(r.estadoFacturacion).to.eql('NoHabilitada'); });"
            ]
          }
        }
      ]
    },
    {
      "name": "03 - Reintento exacto idempotente",
      "request": {
        "method": "POST",
        "header": [
          { "key": "Content-Type", "value": "application/json" },
          { "key": "X-Integration-Token", "value": "{{integrationToken}}" }
        ],
        "body": { "mode": "raw", "raw": "{{pendingExactBody}}" },
        "url": "{{endpoint}}"
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "exec": [
              "const source = pm.collectionVariables.get('pendingBody');",
              "pm.collectionVariables.set('pendingExactBody', source);"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "exec": [
              "pm.test('Retorna 200 por reintento', () => pm.response.to.have.status(200));",
              "pm.test('Marca reintento', () => pm.expect(pm.response.json().reintento).to.eql(true));"
            ]
          }
        }
      ]
    },
    {
      "name": "04 - Conflicto misma clave y contenido diferente",
      "request": {
        "method": "POST",
        "header": [
          { "key": "Content-Type", "value": "application/json" },
          { "key": "X-Integration-Token", "value": "{{integrationToken}}" }
        ],
        "body": { "mode": "raw", "raw": "{{conflictBody}}" },
        "url": "{{endpoint}}"
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "exec": [
              "const value = JSON.parse(pm.collectionVariables.get('pendingBody'));",
              "value.cotizacion.observaciones.interna = 'Contenido intencionalmente modificado';",
              "pm.variables.set('conflictBody', JSON.stringify(value));"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "exec": [
              "pm.test('Conflicto 409', () => pm.response.to.have.status(409));"
            ]
          }
        }
      ]
    },
    {
      "name": "05 - Token inválido",
      "request": {
        "method": "POST",
        "header": [
          { "key": "Content-Type", "value": "application/json" },
          { "key": "X-Integration-Token", "value": "token-invalido" }
        ],
        "body": { "mode": "raw", "raw": "{{pendingExactBody}}" },
        "url": "{{endpoint}}"
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "exec": [
              "pm.test('No autorizado', () => pm.response.to.have.status(401));"
            ]
          }
        }
      ]
    },
    {
      "name": "06 - Validación de stock",
      "request": {
        "method": "POST",
        "header": [
          { "key": "Content-Type", "value": "application/json" },
          { "key": "X-Integration-Token", "value": "{{integrationToken}}" }
        ],
        "body": { "mode": "raw", "raw": "{{invalidBody}}" },
        "url": "{{endpoint}}"
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "exec": [
              "const value = JSON.parse(pm.collectionVariables.get('pendingBody'));",
              "value.idSolicitud = 'POSTMAN-INVALID-001'; value.claveIdempotencia = 'POSTMAN|INVALID|001'; value.cotizacion.idCotizacionOrigen = 'POSTMAN-INVALID-001';",
              "value.cotizacion.lineas[0].asignacionesStock[0].cantidad = 2;",
              "pm.variables.set('invalidBody', JSON.stringify(value));"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "exec": [
              "pm.test('Regla de negocio 422', () => pm.response.to.have.status(422));"
            ]
          }
        }
      ]
    },
    {
      "name": "07 - Versión de contrato no soportada",
      "request": {
        "method": "POST",
        "header": [
          { "key": "Content-Type", "value": "application/json" },
          { "key": "X-Integration-Token", "value": "{{integrationToken}}" }
        ],
        "body": { "mode": "raw", "raw": "{{invalidVersionBody}}" },
        "url": "{{endpoint}}"
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "exec": [
              "const value = JSON.parse(pm.collectionVariables.get('pendingBody'));",
              "value.versionContrato = '9.9'; value.idSolicitud = 'POSTMAN-VERSION-INVALIDA-001'; value.claveIdempotencia = 'POSTMAN|VERSION-INVALIDA|001'; value.cotizacion.idCotizacionOrigen = 'POSTMAN-VERSION-INVALIDA-001';",
              "pm.variables.set('invalidVersionBody', JSON.stringify(value));"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "exec": [
              "pm.test('Versión no soportada retorna 422', () => pm.response.to.have.status(422));",
              "pm.test('La respuesta informa la versión vigente', () => pm.expect(pm.response.text()).to.include('1.0'));"
            ]
          }
        }
      ]
    }
  ],
  "auth": { "type": "noauth" }
}
