Loading bookings…

{{ getViewTitle() }}

View only
Last import
New bookings added — auto, every 2 min
{{ syncStatus.importAt ? fmtSyncFull(syncStatus.importAt) : 'Awaiting' }}
{{ syncStatus.importAt ? relativeTime(syncStatus.importAt) : '' }}
Last sync
Future bookings refreshed
{{ syncStatus.syncAt ? fmtSyncFull(syncStatus.syncAt) : 'Awaiting' }}
{{ syncStatus.syncAt ? relativeTime(syncStatus.syncAt) : '' }}
Refresh syncs this app to the RMS sheet — it does not pull from eZee. Data also refreshes automatically every 5 min and on tab focus.
{{ errorMessage }}

Filters

{{ activeAdvancedFilterCount }} active
From
To
From
To
From
To
{{ selectedRes.length }} selected
#{{ b.resNo }}
{{ b.status }}
{{ b.guest }}
GBV: {{ totalGBV }} ADR: {{ adr }} Nights: {{ totalNights }}
Escalated
{{ auditEscalated }} booking{{ auditEscalated === 1 ? '' : 's' }} checked out before yesterday and are still unaudited. {{ isSuperAdmin() ? 'Only you can clear these.' : 'Escalated to the super-admin.' }}
{{ selectedAudit.length }} selected
Res # Src Status Guest / Property Audit Date Stay GBV GST TA Comm Agent Action
{{ b.resNo }} {{ b.status }}
{{ b.guest }}
{{ propShort(b.property) }}
{{ shortDate(auditDateISO(b)) }}
cancellation
{{ shortDate(b.checkInISO) }} {{ shortDate(b.checkOutISO) }} · {{ b.nights }}n
{{ b.gbv }}
Tariff {{ b.nights ? inr(Math.round((b.gbvRaw || 0) / b.nights)) : '—' }}
{{ inr(b.gstRaw || 0) }}
{{ Math.round(pctOf(b.gstRaw, b.gbvRaw)) }}% of GBV
{{ inr(b.otaCommissionExcRaw || 0) }}
{{ Number(pctOf(b.otaCommissionExcRaw, b.gbvRaw)).toFixed(1) }}% of GBV
{{ b.agent || '—' }}
Nothing to show for this filter.
Loading…

{{ calendarMonthTitle }}

All Properties
{{ complex.name }}
{{ p }}
{{ calendarPropFilters.length }} selected
PROPERTY
{{ day.dayName }} {{ day.dayNum }}
No properties found.
{{ prop }}
{{ evt.title }}

{{ miniViewBooking.guest }}

#{{ miniViewBooking.resNo }} {{ miniViewBooking.status }}
Total Amount
{{ miniViewBooking.gbv }}
Add a user

Admins

{{ allUsers.filter(u => u.role === 'ADMIN').length }}
{{ u.name[0] }}
{{ u.name }}
{{ u.email }}
Admin

Managers

{{ allUsers.filter(u => u.role === 'MANAGER').length }}
{{ u.name[0] }}
{{ u.name }}
{{ u.email }}
Manager
Team {{ a.name }} no reports yet

Agents

{{ allUsers.filter(u => u.role === 'AGENT').length }}
{{ u.name[0] }}
{{ u.name }}
Reports to
Agent
All admin changes save locally in your browser for preview. Backend wiring will land alongside the API Sync work.
Sources & icons
Pick an icon for each source you've ever received a booking from. Unmatched sources fall back to a globe.
SourcePreviewIcon
{{ src }}
Status colours
Each unique reservation status from your bookings sheet appears here. Pick a tone for its label.
StatusPreviewColour
{{ st }} {{ st }}
Auto-assignment
How should new (non-Direct) reservations be assigned to agents?
Mode
Source → Agent
{{ src }}
Round-robin pool
{{ a.name }} No agents added yet — add some under Users & Teams.
Next pick: {{ nextRoundRobinAgent || '—' }}
Owner Postings
{{ op.total.toLocaleString() }} records
Portfolio Calendar
{{ calMultiFilteredProperties().length }} properties · {{ calMulti.bookings.length }} bookings
{{ calMultiRangeLabel() }}
Booked Comp Stay Block Cancelled
No properties match the filter.
Property
{{ ['Su','Mo','Tu','We','Th','Fr','Sa'][dt.getDay()] }}
{{ dt.getDate() }}
{{ prop }}
{{ ['January','February','March','April','May','June','July','August','September','October','November','December'][cal.month] }} {{ cal.year }}
Pick a property.
{{ d }}
Booked Comp Stay Block Cancelled
Property mapping
Map every eZee room to the SM property allocation(s) it sells as. Mother rooms map to multiple SM properties (different owners); Child rooms map to exactly one.
{{ pmList.length }} of {{ pmTotal }} mappings
eZee Room Type SM Property Allocation  
{{ m.ezee_room_no }} Mother Child Unmapped
No mappings match.
Property list
Every SM property from the Supply Monitor import — the master behind property mapping and the mother-booking room split. Read-only.
{{ propertyListRows.length }} of {{ propertyList.rows.length }} properties
{{ propertyList.error }}
Property Bedrooms Type
Loading properties…
No properties found.
{{ p.name }} {{ p.bedrooms }} BR {{ p.type }}
Charge mapping
Tag every eZee charge (room & extra) as Accommodation, Concierge or F&B. Any new charge added in eZee shows up here automatically as unmapped. This drives the split in each booking's Charges tab.
{{ ccm.error }}
{{ ccmList().length }} of {{ ccm.counts.total }} · {{ ccm.counts.unmapped }} unmapped
Scanning charges…
Charge Name Seen As Count Category
{{ row.name }} Room Extra Room + Extra saved {{ row.count ? row.count.toLocaleString() : '—' }}
{{ row.appliesFrom }}
{{ ccm.rows.length === 0 ? 'No charges found yet.' : 'No charges match.' }}
Apply charge mapping
Tag "{{ scopeModal.name }}" as {{ scopeModal.category === 'fnb' ? 'F&B' : (scopeModal.category.charAt(0).toUpperCase() + scopeModal.category.slice(1)) }}. Apply to:
{{ scopeModal.error }}
{{ pmModal.mode === 'create' ? 'Add property mapping' : 'Edit mapping' }}
Mother = sold as multiple SM properties. Child = single property.
{{ name }}
All properties already added.
Child rooms map to exactly one SM property — drop the extras or switch to Mother.
{{ pmModal.error }}

{{ activeBooking.guest || 'Guest' }}

Group
Split
#{{ activeBooking.resNo }} · {{ formatPhone(activeBooking.mobile).display || '—' }} · {{ activeBooking.totalGuests || 0 }} guests · {{ activeBooking.ratePlan }}
{{ activeBooking.gbv || '—' }}
Tariff {{ activeBooking.nights ? inr(Math.round(activeBooking.gbvRaw / activeBooking.nights)) : '—' }}/night
{{ countdownText(activeBooking) }} · {{ activeBooking.checkIn || '—' }} {{ activeBooking.checkOut || '—' }} · {{ activeBooking.nights || 0 }} nights ·
{{ prop.trim() }}
· {{ activeBooking.source }}
{{ activeBooking.status || '—' }}
Stay
Arrival
{{ activeBooking.checkIn || '—' }}
2:00 PM
Departure
{{ activeBooking.checkOut || '—' }}
11:00 AM
Nights
{{ activeBooking.nights || 0 }}
ADR {{ activeBooking.nights ? inr(Math.round(activeBooking.gbvRaw / activeBooking.nights)) : '—' }}
Countdown
{{ countdownText(activeBooking) }}
Lead Guest
{{ activeBooking.guest || '—' }} {{ activeBooking.vipStatus }}
Phone
{{ formatPhone(activeBooking.mobile).display || '—' }}
Email
{{ activeBooking.email || '—' }}
Guests
{{ activeBooking.adults || 0 }} adults · {{ activeBooking.kids || 0 }} kids
VIP
Booked on
{{ activeBooking.resDateDisplay || '—' }}
Cancelled on
{{ activeBooking.cancelDateDisplay }}
Bill to company
{{ activeBooking.billTo }}
Property
MOTHER · SPLIT
eZee Category
{{ activeBooking.roomCat || '—' }}
eZee Room
{{ activeBooking.roomNo || '—' }}
SM Allocation
No mapping yet
Rate plan
{{ activeBooking.ratePlan || '—' }}
Voucher
{{ activeBooking.voucher || '—' }}
Money summary
GBV ex tax
{{ activeBooking.gbv || '—' }}
Taxes
{{ inr(activeBooking.gstRaw) }}
OTA commission
{{ inr(activeBooking.otaCommissionIncRaw) }}
Lost revenue
{{ activeBooking.lostRevRaw ? inr(activeBooking.lostRevRaw) : '—' }}
Est. net
{{ inr(netRevenue(activeBooking)) }}
Recent activity
No activity yet for this booking.
  1. {{ (h.ts || '').slice(0, 16).replace('T', ' ') }} {{ h.detail }} {{ h.user }}
{{ activeBooking.roomCat || '-' }}
{{ activeBooking.roomNo || '-' }}

Property Revenue Splits

Property Name Amount Tax
{{ split.name }} {{ split.amount }} {{ split.gst }}

Primary Guest Contact

{{ activeBooking.guest }}
{{ activeBooking.email }}
{{ formatPhone(activeBooking.mobile).code }}
{{ formatPhone(activeBooking.mobile).number }}

Nightly Schedule

Edit the property and rate for each night, or add an extra room for selected nights only.
{{ shortDate(nights.checkIn) }}{{ shortDate(nights.checkOut) }} {{ activeBooking.nights || 0 }} nights
Loading nightly schedule…
{{ nights.error }}
No nights to display — this booking has no stay dates set.
Date
SM Property
Rate (₹)
Notes
Actions
Total
{{ nights.rows.length }} room-nights
{{ inr(totalScheduledRate) }}
vs. GBV {{ inr(activeBooking.gbvRaw || 0) }}
This booking is locked (past sales / verified). Schedule view-only.
Loading charges…
{{ charges.error }}
Payments coming next
A booking can carry multiple payments (deposit, balance, refund, OTA payout). The Payments backend isn't wired yet — this tab will populate once the booking_payments table is in place.
Booking Source
Source
{{ activeBooking.source || '—' }}
Voucher / Channel ref
{{ activeBooking.voucher || '—' }}
TA / OTA Commission
{{ inr(activeBooking.otaCommissionExcRaw || 0) }}
exc. taxes · {{ Number(pctOf(activeBooking.otaCommissionExcRaw, activeBooking.gbvRaw)).toFixed(1) }}% of GBV
+ GST {{ inr(activeBooking.gstOnTa || 0) }} ({{ Math.round(pctOf(activeBooking.gstOnTa, activeBooking.otaCommissionExcRaw)) }}% of comm.)
inc. tax {{ inr(activeBooking.otaCommissionIncRaw || 0) }}
Deductions
TDS
{{ inr(activeBooking.tdsRaw || 0) }}
{{ Number(pctOf(activeBooking.tdsRaw, activeBooking.gbvRaw)).toFixed(2) }}% of GBV
TCS
{{ inr(activeBooking.tcsRaw || 0) }}
{{ Number(pctOf(activeBooking.tcsRaw, activeBooking.gbvRaw)).toFixed(2) }}% of GBV
Loading folio from the billing sheet…
{{ billing.data.note }}
Couldn't load billing: {{ billing.data.error }}
Verification Status
{{ isStale(activeBooking) ? 'Stale — checkout passed without verification' : (activeBooking.verification || 'Unverified — editable until checkout day') }}
Frozen Escalated

History

No history yet for this booking.
  1. {{ h.action }} {{ h.ts }}
    {{ h.detail }}
    by {{ h.user }} · golden-rule override
Agent: {{ activeBooking.agent || 'Unassigned' }}
Reassign
{{ activeBooking.edited ? 'Overridden' : 'Verified' }} & frozen Escalated — super-admin only
Sync failed Synced just now Sync disabled (past sales)
Override booking
#{{ overrideModal.resNo }} · {{ overrideModal.guestName }} — your entry overwrites the RMS row and freezes it from sync.
{{ overrideModal.error }}
Guest
Stay
Money
Notes
This overwrites the booking and stops eZee sync for it.
{{ toast.message }}