Kaizen 256 Build an Arrival Readiness Web Tab in Zoho CRM

Kaizen 256 Build an Arrival Readiness Web Tab in Zoho CRM




Hi everyone!

Welcome back to the Kaizen series! In the post, we discuss a use case in hospitality industry: how an Arrival Readiness web tab widget can be used to let reception staff identify and resolve issues before arrival of guests. 

Use case

In the hospitality industry, every guest interaction is an opportunity to make a lasting impression. To ensure a smoother check-in process, reception staff should have access to information about which guests are arriving soon and be able to take the necessary action without hassle. The important question is:

                        "Which arrivals require action before the guest reaches the property?"

For example:
  1. A guest's ID verification is still pending.
  2. A guest has requested a service that has not yet been assigned.
  3. Other bookings are already ready for arrival.

Instead of making the reception staff open individual records and manually check these details, we can surface the information in a Zoho CRM Widget and provide an action directly from the dashboard. Without a focused dashboard, the team has to open each booking, inspect fields, and decide what to do. That takes time and increases the chance of missing something before guests arrive.

In this Kaizen, we'll build an Arrival Readiness Web Tab that:
  1. Retrieves bookings arriving within the next 48 hours.
  2. Determines the readiness of each booking.
  3. Displays a summary of arrivals requiring action.
  4. Allows staff to send an ID verification reminder.
  5. Allows staff to create a follow-up task for an unassigned special request.
  6. Updates the Booking record after the action is completed.


The solution combines CRM Widgets, Deluge Functions, REST API-enabled Functions, and CRM APIs.

To showcase this solution, we have created a custom module, Bookings, with the following custom fields:

Field Name
API Name
Data Type
Arrival Date Check_In DateTime
Departure Date Check_Out DateTime
Guest Name Guest_Name Single Line
ID Verification ID_Verification Single Line
Owner Owner1 Single Line
Payment Status Payment_Status Pick List
Readiness Readiness Pick List
Reminder Sent Reminder_Sent Boolean
Reminder Sent At Reminder_Sent_At DateTime
Request Status Request_Status Pick List
Special Request Special_Request Multi Line (Small)
Verification Link Verification_Link Single Line


We also have a web tab widget in which details are displayed.

Real-time flow inside the widget

When the widget loads:
  1. It calls 'getArrivalReadiness()'.
  2. The function fetches bookings and filters arrivals within the next 48 hours.
  3. Each booking is evaluated and assigned:
    1. readiness ('Ready', 'Action Required', 'Attention')
    2. issue
    3. recommended action
  4. The widget renders this as an actionable list.
  5. Staff can immediately trigger row-level actions:
    1. 'Send reminder' which then calls 'sendArrivalReminder(bookingId)'
    2. 'Assign task' which then creates a CRM Task and then calls 'assignArrivalTask(bookingId)'
  6. Booking fields are updated, and the widget refreshes to show status.

How the solution is split

We keep each responsibility separate:
  1. Three deluge functions
    1. getArrivalReadiness() that evaluates bookings and returns dashboard data
    2. sendArrivalReminder(bookingId) that sends reminder and updates reminder fields
    3. assignArrivalTask(bookingId) that updates booking request status after task creation
  2. Widget logic that renders UI, handles clicks, calls functions, refreshes view
This separation keeps UI logic in widget code and business rules in Deluge.

Step 1: Evaluate arrivals in the next 48 hours
When the widget loads, it calls getArrivalReadiness().
This function fetches bookings, filters arrivals within the next 48 hours, and evaluates each booking for readiness conditions.

Readiness rules:

Field
Field Conditions (exact)
Issue
Recommended Action
Action Required ID_Verification == "Pending" ID verification pending Send reminder
Action Required Special_Request != "" AND Request_Status != "Assigned" AND Request_Status != "Completed" Special request is unassigned Assign task
Ready None of the above conditions matched No action required No action

The getArrivalReadiness() evaluates a 48-hour window in four concrete sub-steps:
  1. Define the time window
    1. It sets now = zoho.currenttime
    2. It sets endTime = now.addHour(48)
    3. This creates the comparison range: [current time, current time + 48 hours]
  2. Fetch candidate bookings
    1. It pulls booking records using:
    2. zoho.crm.getRecords("Bookings", 1, 200)
    3. This gives the function a working set of bookings to inspect.
  3. Normalize each booking’s check-in time for comparison
    1. For each booking, it reads Check_In.
    2. It preserves the original CRM datetime string (checkInOriginal) for display/output.
    3. It extracts only the datetime portion (subString(0,19)) and parses it into a time object:
    4. checkIn = checkInText.toTime("yyyy-MM-dd'T'HH:mm:ss")
    5. This parsed value is used only for logical comparison.
  4. Filter to “arriving soon” records
    1. It includes only bookings where:
    2. checkIn >= now && checkIn <= endTime
    3. Only these bookings move to readiness classification (Ready, Action Required, Attention).
The function computes a rolling 48-hour window, converts each booking’s check-in to a comparable datetime, and keeps only records whose check-in falls inside that window.

Step 2: Return one action-ready payload to the widget
After each booking is classified, the function getArrivalReadiness()  adds one row object to arrivals with: id, booking, guest, arrival, readiness, priority, issue, action.
At the same time, it builds summary with: total, ready, action_required, attention.
Finally, it returns a single response object:
  1. success
  2. generated_at
  3. window_hours
  4. summary
  5. arrivals
Because both summary cards and row-level actions come from this single payload, the widget can render in one function call (getArrivalReadiness) without additional CRM fetches.

Step 3: Render dashboard and bind row actions
Widget JS reads response.details.output, renders summary cards and actionable rows, then maps row actions to functions:
  1. Send reminder → sendArrivalReminder(bookingId)
  2. Assign task → create CRM Task, then call assignArrivalTask(bookingId)
All Deluge functions used by widget must be configured as Invoke as REST API.

Step 4: Execute “Send reminder” path for pending verification
For verification-pending bookings, sendArrivalReminder(bookingId) handles:
  1. Booking ID validation
  2. Booking lookup
  3. Guest email validation
  4. Duplicate reminder protection
  5. Email send
  6. Booking field updates (Reminder_Sent, Reminder_Sent_At)
This enables quick verification follow-up during pre-check-in.

Step 5: Execute “Assign task” path for unassigned requests
For unassigned special requests, widget creates a CRM Task linked to Bookings, then calls assignArrivalTask(bookingId) to update:
  1. Request_Status = Assigned
Using $se_module: "Bookings" ensures proper linkage to the custom module context.

Step 6: Refresh and reflect current operational truth
After any row action, widget refreshes readiness data so users immediately see updated status.
This creates a fast “identify → act → update → verify” loop.

Example outcomes:

  1. Laura Martin (BK-10492): ID verification pending → Action Required → Send reminder
  2. Ian Thomas (BK-10489): Late dinner request pending/unassigned → Action Required → Assign task
  3. Vivek Shah (BK-10491): Verification complete, no open request → Ready → No action
You can find the full code  of the widget and functions used in this function in the Kaizen github repository.

Conclusion

With this setup, the front office or operations team can move from record-checking to action execution in one screen.
You now have a working pattern that combines:
  1. readiness classification in Deluge
  2. direct actions in widget UI
  3. immediate CRM updates after each action
That combination is what makes the dashboard practically useful during real check-in prep.

We hope this Kaizen post is useful. If you have questions or suggestions, share them in the comments.