{
  "name": "Smart Housekeeping Auto-Assignment & Task Tracking (Hospitality Industries)",
  "nodes": [
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        496,
        80
      ],
      "id": "f8ec5702-8119-475e-a2c8-a3a383045101",
      "name": "Loop Over Bookings"
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Bookings",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=0"
        },
        "event": "rowUpdate",
        "options": {
          "columnsToWatch": [
            "Status",
            "Priority"
          ]
        }
      },
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "typeVersion": 1,
      "position": [
        272,
        80
      ],
      "id": "a76f0feb-431f-426f-9f98-1109a036d6e6",
      "name": "Trigger to Booking Status Updated",
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "id": "rZ2gM5fVqsChvwb9",
          "name": "Suresh_Google Sheets Trigger"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "b7ee02b6-d3d0-4474-9e1d-2f750e2c12ce",
              "leftValue": "={{ $json.Status }}",
              "rightValue": "Checked Out",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        704,
        0
      ],
      "id": "19dab76f-b484-46e5-bfe7-0602ec9b3f36",
      "name": "Check Status = Checked Out"
    },
    {
      "parameters": {
        "jsCode": "// // Your Booking sheet uses \"RoomType\" (not roomType)\n// const roomType = $json.RoomType;\n\n// let cleaningMinutes = 25;\n// let priority = \"Normal\";\n// let requiredStaffCount = 1;\n\n// if (roomType === \"Standard\") {\n//   cleaningMinutes = 25;\n//   priority = \"Normal\";\n//   requiredStaffCount = 1;\n// } else if (roomType === \"Deluxe\") {\n//   cleaningMinutes = 40;\n//   priority = \"High\";\n//   requiredStaffCount = 2;\n// } else if (roomType === \"Suite\") {\n//   cleaningMinutes = 60;\n//   priority = \"Urgent\";\n//   requiredStaffCount = 3;\n// }\n\n// // IMPORTANT: Return original booking fields also\n// return [\n//   {\n//     ...$json,\n//     cleaningMinutes,\n//     priority,\n//     requiredStaffCount,\n//   },\n// ];\n\n\n\n\n// -----------------------------\n// INPUT FROM GOOGLE SHEET\n// -----------------------------\nconst roomType = String($json.RoomType || \"\").trim();\nconst sheetPriority = String($json.Priority || \"\").trim(); // Manager sets this in sheet\n\n// -----------------------------\n// DEFAULT VALUES\n// -----------------------------\nlet cleaningMinutes = 25;\n\n// Cleaning time based on RoomType (optional logic)\nif (roomType.toLowerCase() === \"standard\") {\n  cleaningMinutes = 20;\n} else if (roomType.toLowerCase() === \"deluxe\") {\n  cleaningMinutes = 30;\n} else if (roomType.toLowerCase() === \"suite\") {\n  cleaningMinutes = 40;\n}\n\n// -----------------------------\n// STAFF COUNT BASED ON PRIORITY (Manager Controlled)\n// -----------------------------\nlet priority = \"Normal\";\nlet requiredStaffCount = 1;\n\nconst p = sheetPriority.toLowerCase();\n\nif (p === \"normal\") {\n  priority = \"Normal\";\n  requiredStaffCount = 1;\n} else if (p === \"high\") {\n  priority = \"High\";\n  requiredStaffCount = 2;\n} else if (p === \"urgent\") {\n  priority = \"Urgent\";\n  requiredStaffCount = 3;\n} else {\n  // If manager forgot to set priority\n  priority = \"Normal\";\n  requiredStaffCount = 1;\n}\n\n// -----------------------------\n// OUTPUT (KEEP ORIGINAL DATA)\n// -----------------------------\nreturn [\n  {\n    ...$json,\n    cleaningMinutes,\n    priority,\n    requiredStaffCount,\n  },\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        928,
        -16
      ],
      "id": "978d63ef-0bd5-40e5-b405-1ea5893c1004",
      "name": "Logic for RoomType → Priority + Staff Count"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 79555193,
          "mode": "list",
          "cachedResultName": "Staff",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=79555193"
        },
        "filtersUI": {
          "values": [
            {
              "lookupColumn": "Status",
              "lookupValue": "Available"
            },
            {
              "lookupColumn": "Active",
              "lookupValue": "Yes"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1104,
        -16
      ],
      "id": "a0620fed-2644-43bb-8aec-229774d0c5e1",
      "name": "Get Available Staff List",
      "alwaysOutputData": true,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "WdaCQmtoNquNSoAA",
          "name": "Suresh_Google Sheets"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Booking data comes from \"Code in JavaScript\" node\nconst booking = $items(\"Logic for RoomType → Priority + Staff Count\")[0].json;\n\n// Staff list comes from current input\nconst staffRows = $input.all().map(i => i.json);\n\n// Required staff count based on priority\nconst required = Number(booking.requiredStaffCount || 1);\n\n// Filter staff Active = Yes\nconst available = staffRows\n  .filter(s => (s.Active || \"\").toLowerCase() === \"yes\")\n  .map(s => ({\n    ...s,\n    activeTasks: Number(s[\"Active Tasks\"] || 0),\n  }))\n  .sort((a, b) => a.activeTasks - b.activeTasks);\n\n// -------------------------------\n// ❌ NOT ENOUGH STAFF AVAILABLE\n// -------------------------------\nif (available.length < required) {\n  const roomNo = booking[\"Room No\"];\n  const bookingId = booking[\"Booking ID\"];\n  const roomType = booking.RoomType;\n  const priority = booking.priority;\n\n  const availableStaffList = available.map(s =>\n    `${s[\"Staff Name\"]} (${s.Phone}) - ActiveTasks=${s.activeTasks}`\n  );\n\n  const slackMessage = `🚨 *Housekeeping Assignment Failed (Insufficient Staff)*\n\n• Booking ID: *${bookingId}*\n• Room No: *${roomNo}*\n• Room Type: *${roomType}*\n• Priority: *${priority}*\n• Required Staff: *${required}*\n• Available Staff: *${available.length}*\n\nReason: Not enough housekeeping staff available\n\nAvailable Staff Found:\n${availableStaffList.length ? availableStaffList.join(\"\\n\") : \"None\"}\n\nAction Needed:\n1) Assign manually for this room\n2) Or reduce required staff temporarily`;\n\n  return [\n    {\n      json: {\n        ...booking,\n        isError: true,\n        errorType: \"STAFF_NOT_AVAILABLE\",\n        requiredStaff: required,\n        availableStaffCount: available.length,\n        slackMessage,\n      },\n    },\n  ];\n}\n\n// -------------------------------\n// ✅ STAFF AVAILABLE (SUCCESS)\n// -------------------------------\nconst selected = available.slice(0, required);\n\n// Create taskId\nconst now = new Date();\nconst yyyy = now.getFullYear();\nconst mm = String(now.getMonth() + 1).padStart(2, \"0\");\nconst dd = String(now.getDate()).padStart(2, \"0\");\n\nconst roomNo = booking[\"Room No\"];\nconst taskId = `HK${yyyy}${mm}${dd}-${roomNo}`;\n\nreturn [\n  {\n    json: {\n      ...booking,\n      isError: false,\n      taskId,\n      assignedTo: selected.map(s => s[\"Staff Name\"]),\n      phones: selected.map(s => String(s.Phone)),\n      staffIds: selected.map(s => s[\"Staff ID\"]),\n    },\n  },\n];\n\n\n\n// // Booking data comes from \"Logic for RoomType → Priority + Staff Count\" node\n// const booking = $items(\"Logic for RoomType → Priority + Staff Count\")[0].json;\n\n// // Staff list comes from current input\n// const staffRows = $input.all().map(i => i.json);\n\n// // Required staff count\n// const required = Number(booking.requiredStaffCount || 1);\n\n// // Priority from booking (manager set)\n// const priority = String(booking.priority || booking.Priority || \"Normal\").trim();\n// const p = priority.toLowerCase();\n\n// // Filter staff Active = Yes\n// const available = staffRows\n//   .filter(s => (s.Active || \"\").toLowerCase() === \"yes\")\n//   .map(s => ({\n//     ...s,\n//     activeTasks: Number(s[\"Active Tasks\"] || 0),\n//   }))\n//   .sort((a, b) => a.activeTasks - b.activeTasks);\n\n// // Booking details\n// const roomNo = booking[\"Room No\"];\n// const bookingId = booking[\"Booking ID\"];\n// const roomType = booking.RoomType;\n\n// // -------------------------------\n// // FALLBACK ASSIGNMENT LOGIC\n// // -------------------------------\n// let assignCount = required;\n// let isPartial = false;\n// let slackMessage = \"\";\n\n// // If not enough staff, allow partial assignment for High/Urgent\n// if (available.length < required) {\n//   if (p === \"urgent\" && available.length >= 2) {\n//     assignCount = 2; // fallback\n//     isPartial = true;\n//   } else if (p === \"high\" && available.length >= 1) {\n//     assignCount = 1; // fallback\n//     isPartial = true;\n//   } else {\n//     // ❌ No fallback possible → return error\n//     const availableStaffList = available.map(s =>\n//       `${s[\"Staff Name\"]} (${s.Phone}) - ActiveTasks=${s.activeTasks}`\n//     );\n\n//     slackMessage = `🚨 *Housekeeping Assignment Failed (No Staff Available)*\n\n// • Booking ID: *${bookingId}*\n// • Room No: *${roomNo}*\n// • Room Type: *${roomType}*\n// • Priority: *${priority}*\n// • Required Staff: *${required}*\n// • Available Staff: *${available.length}*\n\n// Reason: Not enough housekeeping staff available\n\n// Available Staff Found:\n// ${availableStaffList.length ? availableStaffList.join(\"\\n\") : \"None\"}\n\n// Action Needed:\n// 1) Assign manually for this room\n// 2) Mark more staff as Available`;\n\n//     return [\n//       {\n//         json: {\n//           ...booking,\n//           isError: true,\n//           errorType: \"STAFF_NOT_AVAILABLE\",\n//           requiredStaff: required,\n//           availableStaffCount: available.length,\n//           slackMessage,\n//         },\n//       },\n//     ];\n//   }\n// }\n\n// // -------------------------------\n// // SELECT STAFF (LOWEST ACTIVE TASKS)\n// // -------------------------------\n// const selected = available.slice(0, assignCount);\n\n// // Create taskId\n// const now = new Date();\n// const yyyy = now.getFullYear();\n// const mm = String(now.getMonth() + 1).padStart(2, \"0\");\n// const dd = String(now.getDate()).padStart(2, \"0\");\n\n// const taskId = `HK${yyyy}${mm}${dd}-${roomNo}`;\n\n// // Slack message only when partial assignment happens\n// if (isPartial) {\n//   slackMessage = `⚠️ *Housekeeping Partial Assignment*\n\n// • Booking ID: *${bookingId}*\n// • Room No: *${roomNo}*\n// • Room Type: *${roomType}*\n// • Priority: *${priority}*\n// • Required Staff: *${required}*\n// • Assigned Staff: *${assignCount}*\n// • Missing Staff: *${required - assignCount}*\n\n// Assigned Staff:\n// ${selected.map(s => `- ${s[\"Staff Name\"]} (${s.Phone})`).join(\"\\n\")}\n\n// Action Needed:\n// Please arrange extra staff manually if required.`;\n// }\n\n// // -------------------------------\n// // SUCCESS OUTPUT\n// // -------------------------------\n// return [\n//   {\n//     json: {\n//       ...booking,\n//       isError: false,\n//       isPartialAssignment: isPartial,\n//       required,\n//       assignedStaffCount: assignCount,\n//       missingStaffCount: required - assignCount,\n//       slackMessage, // will be empty if full assignment\n//       taskId,\n//       assignedTo: selected.map(s => s[\"Staff Name\"]),\n//       phones: selected.map(s => String(s.Phone)),\n//       staffIds: selected.map(s => s[\"Staff ID\"]),\n//     },\n//   },\n// ];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1280,
        -16
      ],
      "id": "9e0b8240-58f0-4ddc-8586-63893c2b30cf",
      "name": "Auto Assign Staff (Lowest Active Tasks)",
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "C090F70N52M",
          "mode": "list",
          "cachedResultName": "website-uptime"
        },
        "text": "={{ $json.slackMessage }}",
        "otherOptions": {}
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        1696,
        -96
      ],
      "id": "47551de1-be38-42e5-94d1-1e2658261495",
      "name": "Alert - Slack (No Staff Available)",
      "webhookId": "4e68035f-de9a-4894-9506-d4fc3152afa9",
      "credentials": {
        "slackOAuth2Api": {
          "id": "VgwGmlOcfqlGImrU",
          "name": "Slack account"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "4c0803ed-1df7-4a66-b18a-afc16f3ea565",
              "leftValue": "={{ $json.isError === true }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1456,
        -16
      ],
      "id": "da3127ef-51bb-49ad-a3b5-68576cf04533",
      "name": "Check Staff Availability"
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 1227995560,
          "mode": "list",
          "cachedResultName": "Tasks",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=1227995560"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Booking ID": "={{ $json[\"Booking ID\"] }}",
            "Room No": "={{ $json[\"Room No\"] }}",
            "RoomType": "={{ $json.RoomType }}",
            "Cleaning Minutes": "={{ $json.cleaningMinutes }}",
            "Priority": "={{ $json.priority }}",
            "Assigned To": "={{ $json.assignedTo }}",
            "Phone": "={{ $json.phones }}",
            "CreatedAt": "={{ $now.format('yyyy-MM-dd hh:mma') }}",
            "Status": "In Progress",
            "Task ID": "=TSK{{ Math.floor(Math.random() * 100000) }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "Task ID",
              "displayName": "Task ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Booking ID",
              "displayName": "Booking ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Room No",
              "displayName": "Room No",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "RoomType",
              "displayName": "RoomType",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Cleaning Minutes",
              "displayName": "Cleaning Minutes",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Priority",
              "displayName": "Priority",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Assigned To",
              "displayName": "Assigned To",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "displayName": "Phone",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "CreatedAt",
              "displayName": "CreatedAt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "CompletedAt",
              "displayName": "CompletedAt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1712,
        80
      ],
      "id": "4e651874-a010-4bb3-b103-f454cb2b5644",
      "name": "Append - New Task",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "WdaCQmtoNquNSoAA",
          "name": "Suresh_Google Sheets"
        }
      }
    },
    {
      "parameters": {
        "fieldToSplitOut": "Phone",
        "options": {}
      },
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        1904,
        80
      ],
      "id": "300d9e2f-6956-4b41-8b48-21a23836de82",
      "name": "Split Out Staff Phone Number"
    },
    {
      "parameters": {
        "from": "=+14155238886",
        "to": "=+{{ $json.Phone }}",
        "toWhatsapp": true,
        "message": "=New Housekeeping Task Assigned\n\nTask ID: {{ $('Append - New Task').item.json[\"Task ID\"] }}\nRoom: {{ $('Append - New Task').item.json[\"Room No\"] }}\nPriority: {{ $('Append - New Task').item.json.Priority }}\n\nAfter cleaning, submit this form:\nhttps://forms.gle/QWP3BaS4fFMbpK5P6\n\nFill Right Task ID and select Status is Completed.\n\n\n",
        "options": {}
      },
      "type": "n8n-nodes-base.twilio",
      "typeVersion": 1,
      "position": [
        2096,
        80
      ],
      "id": "8a98f4f0-a656-4bb0-bf8e-affa46526469",
      "name": "Notify For Task Assigned to Staff",
      "credentials": {
        "twilioApi": {
          "id": "vTM9zbcO5mzo9dps",
          "name": "Twilio account 3"
        }
      }
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 79555193,
          "mode": "list",
          "cachedResultName": "Staff",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=79555193"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Status": "On Working",
            "Phone": "={{ $json.to.replace('whatsapp:+','') }}"
          },
          "matchingColumns": [
            "Phone"
          ],
          "schema": [
            {
              "id": "Staff ID",
              "displayName": "Staff ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Staff Name",
              "displayName": "Staff Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Phone",
              "displayName": "Phone",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Shift",
              "displayName": "Shift",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Active Tasks",
              "displayName": "Active Tasks",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Active",
              "displayName": "Active",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "row_number",
              "displayName": "row_number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "readOnly": true,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        2304,
        80
      ],
      "id": "105a1443-d58a-42c6-aacb-9b208ef9a3ce",
      "name": "Update Staff Status = On Working",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "WdaCQmtoNquNSoAA",
          "name": "Suresh_Google Sheets"
        }
      }
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 1388130356,
          "mode": "list",
          "cachedResultName": "Form Responses 1",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=1388130356"
        },
        "event": "rowAdded",
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "typeVersion": 1,
      "position": [
        272,
        464
      ],
      "id": "1b03d897-3bd6-4bd0-98ed-4bc4cabf8ba5",
      "name": "Trigger - Form Response Added",
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "id": "rZ2gM5fVqsChvwb9",
          "name": "Suresh_Google Sheets Trigger"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        496,
        464
      ],
      "id": "593bb3db-5794-4328-84f1-c09c52eba4ce",
      "name": "Loop Over Form Responses"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "33673385-2519-41bf-82a1-6b424887f029",
              "leftValue": "={{ $json.Status }}",
              "rightValue": "Completed",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        720,
        400
      ],
      "id": "ded58d4a-cb1f-4780-b734-c355b7986e82",
      "name": "Check Response Status = Completed"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 1227995560,
          "mode": "list",
          "cachedResultName": "Tasks",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=1227995560"
        },
        "filtersUI": {
          "values": [
            {
              "lookupColumn": "Task ID",
              "lookupValue": "={{ $json[\"Task ID\"] }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        944,
        384
      ],
      "id": "a26b99c7-0bdd-4f52-a798-3f155a47c09b",
      "name": "Get Task Row By Task ID",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "WdaCQmtoNquNSoAA",
          "name": "Suresh_Google Sheets"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const task = $json;\n\n// Phone is stored as string: [\"9196...\",\"9178...\"]\nlet phones = [];\n\ntry {\n  phones = JSON.parse(task.Phone);\n} catch (e) {\n  // fallback if stored as comma-separated\n  phones = String(task.Phone || \"\")\n    .replace(/[\\[\\]\"]/g, \"\")\n    .split(\",\")\n    .map(p => p.trim())\n    .filter(Boolean);\n}\n\nreturn phones.map(phone => ({\n  json: {\n    phone,\n    taskId: task[\"Task ID\"],\n    roomNo: task[\"Room No\"],\n  }\n}));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1136,
        384
      ],
      "id": "9fd376a0-693e-4209-acbd-c3cdc2d12ce0",
      "name": "Split Task Phones (Multiple Staff)"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 79555193,
          "mode": "list",
          "cachedResultName": "Staff",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=79555193"
        },
        "filtersUI": {
          "values": [
            {
              "lookupColumn": "Phone",
              "lookupValue": "={{ $json.phone }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1328,
        384
      ],
      "id": "91669e9f-2fd4-485a-8418-047fb150d4a3",
      "name": "Get Staff Row By Phone",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "WdaCQmtoNquNSoAA",
          "name": "Suresh_Google Sheets"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\n\nreturn items.map((item) => {\n  const row = item.json;\n\n  const current = Number(row[\"Active Tasks\"] || 0);\n  const updated = current + 1;\n\n  return {\n    json: {\n      ...row,\n      updatedActiveTasks: updated,\n    },\n  };\n});"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1536,
        384
      ],
      "id": "ac3795a9-3866-4491-874a-32e223ddef99",
      "name": "Logic - Update Active Tasks (+1)"
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 79555193,
          "mode": "list",
          "cachedResultName": "Staff",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=79555193"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Active Tasks": "={{ $json.updatedActiveTasks }}",
            "Status": "Available",
            "Staff ID": "={{ $json[\"Staff ID\"] }}"
          },
          "matchingColumns": [
            "Staff ID"
          ],
          "schema": [
            {
              "id": "Staff ID",
              "displayName": "Staff ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Staff Name",
              "displayName": "Staff Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Phone",
              "displayName": "Phone",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Shift",
              "displayName": "Shift",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Active Tasks",
              "displayName": "Active Tasks",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Active",
              "displayName": "Active",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "row_number",
              "displayName": "row_number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "readOnly": true,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1728,
        384
      ],
      "id": "f0888e5b-aeed-4121-bc81-a09ea903e9c3",
      "name": "Update Staff Status 'Available' + 'ActiveTasks'",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "WdaCQmtoNquNSoAA",
          "name": "Suresh_Google Sheets"
        }
      }
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E",
          "mode": "list",
          "cachedResultName": "Housekeeping Auto-Task",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 1227995560,
          "mode": "list",
          "cachedResultName": "Tasks",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit#gid=1227995560"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Status": "Completed",
            "CompletedAt": "={{ $now.format(\"yyyy-MM-dd hh:mma\") }}",
            "Task ID": "={{ $('Get Task Row By Task ID').item.json[\"Task ID\"] }}"
          },
          "matchingColumns": [
            "Task ID"
          ],
          "schema": [
            {
              "id": "Task ID",
              "displayName": "Task ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Booking ID",
              "displayName": "Booking ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Room No",
              "displayName": "Room No",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "RoomType",
              "displayName": "RoomType",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Cleaning Minutes",
              "displayName": "Cleaning Minutes",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Priority",
              "displayName": "Priority",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Assigned To",
              "displayName": "Assigned To",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Phone",
              "displayName": "Phone",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "CreatedAt",
              "displayName": "CreatedAt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "CompletedAt",
              "displayName": "CompletedAt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "displayName": "row_number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "readOnly": true,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1904,
        384
      ],
      "id": "5dbb56f4-9505-4320-9357-44a1a614eda3",
      "name": "Update Task Status = Completed",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "WdaCQmtoNquNSoAA",
          "name": "Suresh_Google Sheets"
        }
      }
    },
    {
      "parameters": {
        "content": "## WF-01 | Housekeeping Auto Task Creator + Smart Staff Assignment (Checkout → WhatsApp Alert)",
        "height": 192,
        "width": 560
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        48,
        -16
      ],
      "id": "78e96e7f-dcfb-4c4e-8825-6b906ad89438",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "## WF-02 | Housekeeping Completion Tracker (Google Form Response → Update Task + Staff Available)",
        "height": 192,
        "width": 560
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        48,
        384
      ],
      "id": "e0526802-6f27-4cea-b195-365d2ec7b7fc",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## Google Sheet\nhttps://docs.google.com/spreadsheets/d/17Tv15bRRvaBEc4QPkUsgf7Gbnm3JV9B6xRZkOIJQd4E/edit?usp=sharing",
        "height": 144
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -80,
        208
      ],
      "id": "b78c7644-1b6b-4525-9075-c30d7a88145b",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "from": "=+14155238886",
        "to": "=\"Manager Number\" (e.g. +918985456858)",
        "toWhatsapp": true,
        "message": "=✅ Housekeeping Update\n\nRoom {{ $('Get Task Row By Task ID').item.json[\"Room No\"] }} has been cleaned and is ready for the next guest.",
        "options": {}
      },
      "type": "n8n-nodes-base.twilio",
      "typeVersion": 1,
      "position": [
        2112,
        464
      ],
      "id": "fa26a376-8b7a-4c49-9690-42eca5bb60b1",
      "name": "Notify to Manager",
      "credentials": {
        "twilioApi": {
          "id": "vTM9zbcO5mzo9dps",
          "name": "Twilio account 3"
        }
      }
    }
  ],
  "pinData": {},
  "connections": {
    "Loop Over Bookings": {
      "main": [
        [],
        [
          {
            "node": "Check Status = Checked Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger to Booking Status Updated": {
      "main": [
        [
          {
            "node": "Loop Over Bookings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Status = Checked Out": {
      "main": [
        [
          {
            "node": "Logic for RoomType → Priority + Staff Count",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Logic for RoomType → Priority + Staff Count": {
      "main": [
        [
          {
            "node": "Get Available Staff List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Available Staff List": {
      "main": [
        [
          {
            "node": "Auto Assign Staff (Lowest Active Tasks)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Auto Assign Staff (Lowest Active Tasks)": {
      "main": [
        [
          {
            "node": "Check Staff Availability",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Check Staff Availability": {
      "main": [
        [
          {
            "node": "Alert - Slack (No Staff Available)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Append - New Task",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append - New Task": {
      "main": [
        [
          {
            "node": "Split Out Staff Phone Number",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Staff Phone Number": {
      "main": [
        [
          {
            "node": "Notify For Task Assigned to Staff",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify For Task Assigned to Staff": {
      "main": [
        [
          {
            "node": "Update Staff Status = On Working",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Staff Status = On Working": {
      "main": [
        [
          {
            "node": "Loop Over Bookings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger - Form Response Added": {
      "main": [
        [
          {
            "node": "Loop Over Form Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Form Responses": {
      "main": [
        [],
        [
          {
            "node": "Check Response Status = Completed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Response Status = Completed": {
      "main": [
        [
          {
            "node": "Get Task Row By Task ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Task Row By Task ID": {
      "main": [
        [
          {
            "node": "Split Task Phones (Multiple Staff)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Task Phones (Multiple Staff)": {
      "main": [
        [
          {
            "node": "Get Staff Row By Phone",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Staff Row By Phone": {
      "main": [
        [
          {
            "node": "Logic - Update Active Tasks (+1)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Logic - Update Active Tasks (+1)": {
      "main": [
        [
          {
            "node": "Update Staff Status 'Available' + 'ActiveTasks'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Staff Status 'Available' + 'ActiveTasks'": {
      "main": [
        [
          {
            "node": "Update Task Status = Completed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Task Status = Completed": {
      "main": [
        [
          {
            "node": "Notify to Manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify to Manager": {
      "main": [
        [
          {
            "node": "Loop Over Form Responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false
  },
  "versionId": "758fb76d-0072-40fc-b24e-66c8460a2767",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "9272721148ea09184b6bbb7ce6219dab088562dd450e2df8280d57c2e34c7d84"
  },
  "id": "ZyDsKwEb_ecmIxNGpxCbt",
  "tags": []
}