{
  "info": {
    "name": "ChannelPro JSON PMS - End-to-End Demo",
    "description": "Executable frontend/PMS integration flow for the seeded DEMO-PMS property. Run database/seeders/DemoJsonPmsSeeder.php first, then run this collection in order. The collection exercises authenticated inventory initialization, idempotent replay, incremental inventory, rate synchronization, reservation delivery, and acknowledgement.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "function isoDate(offset) {",
          "  const date = new Date();",
          "  date.setHours(0, 0, 0, 0);",
          "  date.setDate(date.getDate() + offset);",
          "  return date.toISOString().slice(0, 10);",
          "}",
          "pm.collectionVariables.set('sync_start_date', isoDate(3));",
          "pm.collectionVariables.set('sync_second_date', isoDate(4));",
          "pm.collectionVariables.set('sync_third_date', isoDate(5));",
          "pm.collectionVariables.set('sync_end_date', isoDate(95));",
          "pm.collectionVariables.set('arrival_date', isoDate(3));",
          "pm.collectionVariables.set('departure_date', isoDate(5));"
        ]
      }
    }
  ],
  "variable": [
    { "key": "base_url", "value": "https://staging.channel-p.com/api/v1.0" },
    { "key": "property_code", "value": "DEMO-PMS" },
    { "key": "pms_api_key", "value": "pms_demo_json_test_7f3a9c2e5d1b4a6f8c0e2b7d9a1f3c5e7b9d2f4a6c8e0b1d3f5a7c9e2b4d6f8" },
    { "key": "admin_jwt", "value": "" },
    { "key": "credential_id", "value": "" },
    { "key": "reservation_number", "value": "DEMO-PMS-RES-001" }
  ],
  "item": [
    {
      "name": "00 - Optional administrator setup",
      "description": "The demo property and deterministic PMS API key are created by the dedicated Laravel seeder. Use this request only when you want to issue an additional credential through the admin API. Set admin_jwt before sending.",
      "item": [
        {
          "name": "Create additional PMS credential",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "Authorization", "value": "Bearer {{admin_jwt}}" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"name\": \"Frontend JSON PMS Test Key\",\n  \"scopes\": [\n    \"inventory.write\",\n    \"rates.write\",\n    \"reservations.read\",\n    \"reservations.acknowledge\"\n  ]\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{base_url}}/properties/{{property_code}}/pms-credentials", "host": ["{{base_url}}"], "path": ["properties", "{{property_code}}", "pms-credentials"] }
          }
        }
      ]
    },
    {
      "name": "01 - Inventory synchronization",
      "item": [
        {
          "name": "Initialize complete inventory",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-PMS-API-Key", "value": "{{pms_api_key}}" },
              { "key": "Idempotency-Key", "value": "demo-inventory-initial-v1" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"inventory\": [\n    {\n      \"date\": \"{{sync_start_date}}\",\n      \"rooms\": [\n        {\"room_type\": \"STD\", \"total\": 20, \"available\": 18, \"out_of_order\": 1, \"house_overbook\": 0, \"room_type_overbook\": 0, \"virtual_suite\": false, \"metadata\": {\"source\": \"demo-pms\", \"reservation_count\": 1}},\n        {\"room_type\": \"DLX\", \"total\": 12, \"available\": 10, \"out_of_order\": 0, \"house_overbook\": 0, \"room_type_overbook\": 0, \"virtual_suite\": false, \"metadata\": {\"source\": \"demo-pms\"}}\n      ]\n    },\n    {\n      \"date\": \"{{sync_second_date}}\",\n      \"rooms\": [\n        {\"room_type\": \"STD\", \"total\": 20, \"available\": 19, \"out_of_order\": 0, \"house_overbook\": 0, \"room_type_overbook\": 0, \"virtual_suite\": false},\n        {\"room_type\": \"DLX\", \"total\": 12, \"available\": 11, \"out_of_order\": 0, \"house_overbook\": 0, \"room_type_overbook\": 0, \"virtual_suite\": false}\n      ]\n    },\n    {\n      \"date\": \"{{sync_third_date}}\",\n      \"rooms\": [\n        {\"room_type\": \"STD\", \"total\": 20, \"available\": 20, \"out_of_order\": 0, \"house_overbook\": 0, \"room_type_overbook\": 0, \"virtual_suite\": false},\n        {\"room_type\": \"DLX\", \"total\": 12, \"available\": 12, \"out_of_order\": 0, \"house_overbook\": 0, \"room_type_overbook\": 0, \"virtual_suite\": false}\n      ]\n    }\n  ]\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{base_url}}/pms/channel/{{property_code}}/inventory/initial", "host": ["{{base_url}}"], "path": ["pms", "channel", "{{property_code}}", "inventory", "initial"] }
          }
        },
        {
          "name": "Re-submit initial inventory safely",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-PMS-API-Key", "value": "{{pms_api_key}}" },
              { "key": "Idempotency-Key", "value": "demo-inventory-initial-replay-v1" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"inventory\": [{\"date\": \"{{sync_start_date}}\", \"rooms\": [{\"room_type\": \"STD\", \"total\": 20, \"available\": 18}, {\"room_type\": \"DLX\", \"total\": 12, \"available\": 10}]}]\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{base_url}}/pms/channel/{{property_code}}/inventory/initial", "host": ["{{base_url}}"], "path": ["pms", "channel", "{{property_code}}", "inventory", "initial"] }
          }
        },
        {
          "name": "Apply incremental inventory update",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-PMS-API-Key", "value": "{{pms_api_key}}" },
              { "key": "Idempotency-Key", "value": "demo-inventory-update-v1" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"inventory\": [\n    {\n      \"date\": \"{{sync_start_date}}\",\n      \"rooms\": [\n        {\"room_type\": \"STD\", \"total\": 20, \"available\": 16, \"out_of_order\": 1, \"house_overbook\": 0, \"room_type_overbook\": 0, \"metadata\": {\"reason\": \"new booking\"}}\n      ]\n    }\n  ]\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{base_url}}/pms/channel/{{property_code}}/inventory/update", "host": ["{{base_url}}"], "path": ["pms", "channel", "{{property_code}}", "inventory", "update"] }
          }
        }
      ]
    },
    {
      "name": "02 - Rate synchronization",
      "item": [
        {
          "name": "Sync complete PMS rate definitions",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-PMS-API-Key", "value": "{{pms_api_key}}" },
              { "key": "Idempotency-Key", "value": "demo-rates-v1" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"rates\": [\n    {\n      \"code\": \"DEMO-BAR\",\n      \"category_code\": \"RACK\",\n      \"room_type\": \"STD\",\n      \"name\": \"Demo Best Available Rate - Standard\",\n      \"description\": \"Flexible public standard-room rate\",\n      \"start_date\": \"{{sync_start_date}}\",\n      \"end_date\": \"{{sync_end_date}}\",\n      \"currency_code\": \"NGN\",\n      \"tax_included\": true,\n      \"minimum_length_of_stay\": 1,\n      \"rate_status\": \"ACTIVE\",\n      \"yield_status\": \"NONE\",\n      \"sell_sequence\": 1,\n      \"rate_message_type\": \"HEADERWITHDETAIL\",\n      \"sell_start_date\": \"{{sync_start_date}}\",\n      \"sell_end_date\": \"{{sync_end_date}}\",\n      \"market_code\": \"LEISURE\",\n      \"source_code\": \"DIRECT\",\n      \"department_code\": \"ROOMS\",\n      \"package_transaction_code\": \"7000\",\n      \"days_of_week\": {\"monday\": true, \"tuesday\": true, \"wednesday\": true, \"thursday\": true, \"friday\": true, \"saturday\": true, \"sunday\": true},\n      \"free_children\": 1,\n      \"child_thresholds\": {\"threshold_1\": 0, \"threshold_2\": 0, \"threshold_3\": 0},\n      \"packages\": [{\"code\": \"BB\", \"description\": \"Bed and Breakfast\", \"currency_code\": \"NGN\", \"calculation_rule\": \"R\", \"posting_rhythm\": \"D\", \"package_element\": \"BREAKFAST\", \"add_to_rate_mode\": \"INCLUDE\", \"print_separately\": false, \"add_to_rate\": false, \"tax_included\": true, \"allowance\": 0, \"sell_separate\": false, \"post_next_day\": false, \"catering_package\": true, \"forecast_next_day\": false, \"override_fixed_rate\": false, \"contains_inactive_details\": false}],\n      \"metadata\": {\"source_system\": \"demo-pms\", \"negotiated\": false},\n      \"detail_metadata\": {\"bar\": true, \"bar_rounding\": \"N\"},\n      \"prices\": {\"base\": 125000, \"single\": 125000, \"double\": 145000, \"extra_adult\": 25000}\n    },\n    {\n      \"code\": \"DEMO-BAR-DLX\",\n      \"category_code\": \"RACK\",\n      \"room_type\": \"DLX\",\n      \"name\": \"Demo Best Available Rate - Deluxe\",\n      \"description\": \"Flexible public deluxe-room rate\",\n      \"start_date\": \"{{sync_start_date}}\",\n      \"end_date\": \"{{sync_end_date}}\",\n      \"currency_code\": \"NGN\",\n      \"tax_included\": true,\n      \"minimum_length_of_stay\": 1,\n      \"rate_status\": \"ACTIVE\",\n      \"yield_status\": \"NONE\",\n      \"sell_sequence\": 2,\n      \"days_of_week\": {\"monday\": true, \"tuesday\": true, \"wednesday\": true, \"thursday\": true, \"friday\": true, \"saturday\": true, \"sunday\": true},\n      \"free_children\": 1,\n      \"child_thresholds\": {\"threshold_1\": 0, \"threshold_2\": 0, \"threshold_3\": 0},\n      \"metadata\": {\"source_system\": \"demo-pms\"},\n      \"prices\": {\"base\": 165000, \"single\": 165000, \"double\": 190000, \"extra_adult\": 30000}\n    }\n  ]\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{base_url}}/pms/channel/{{property_code}}/rates", "host": ["{{base_url}}"], "path": ["pms", "channel", "{{property_code}}", "rates"] }
          }
        }
      ]
    },
    {
      "name": "03 - Reservation delivery",
      "item": [
        {
          "name": "Pull pending reservations from ChannelPro",
          "request": {
            "method": "GET",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "X-PMS-API-Key", "value": "{{pms_api_key}}" }
            ],
            "url": { "raw": "{{base_url}}/pms/channel/{{property_code}}/reservations?per_page=20", "host": ["{{base_url}}"], "path": ["pms", "channel", "{{property_code}}", "reservations"], "query": [{ "key": "per_page", "value": "20" }] }
          }
        },
        {
          "name": "Acknowledge delivered reservation",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-PMS-API-Key", "value": "{{pms_api_key}}" },
              { "key": "Idempotency-Key", "value": "demo-reservation-ack-v1" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"reservation_numbers\": [\n    \"{{reservation_number}}\"\n  ]\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{base_url}}/pms/channel/{{property_code}}/reservations/acknowledge", "host": ["{{base_url}}"], "path": ["pms", "channel", "{{property_code}}", "reservations", "acknowledge"] }
          }
        },
        {
          "name": "Verify no pending demo reservation remains",
          "request": {
            "method": "GET",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "X-PMS-API-Key", "value": "{{pms_api_key}}" }
            ],
            "url": { "raw": "{{base_url}}/pms/channel/{{property_code}}/reservations?per_page=20", "host": ["{{base_url}}"], "path": ["pms", "channel", "{{property_code}}", "reservations"], "query": [{ "key": "per_page", "value": "20" }] }
          }
        }
      ]
    }
  ]
}
