Skip to content

Booking Lifecycle Management - Requirements

Status: M1-M9 Complete -- This document covers M1 through M9. M6.6 is planned.

1. Domain Description

The Booking Lifecycle Management (BLM) module provides a unified system for travel agents to create, manage, and track bookings across all service types (hotel, flight, transfer, activity, cruise, visa, and other). It covers the complete lifecycle of a booking from initial enquiry through to completion, including service line management, passenger management, status tracking, amendments, activity logging, and email notifications. Integration with Odoo ERP enables customer synchronization and CRM lead generation.

Bookings are managed using the following entities:

  • Booking
  • Service Line
  • Booking Passenger
  • Booking Status History
  • Booking Amendment
  • Booking Activity Log
  • Action Template Set
  • Action Template
  • Action Item
  • Voucher Section Template
  • Booking Document

1.1 Entity Descriptions

Booking

The central record representing a customer's travel booking. Each booking has a unique system-generated reference in the format TQ-YYYY-NNNNN (e.g., TQ-2026-00042), a status reflecting its position in the lifecycle, travel dates, pricing totals (cost, sell, service charges, paid, balance due), currency, and references to the assigned agent, customer, and ERP records (customer ID, CRM lead ID, quote ID). Bookings also track an optional option expiry date for time-limited holds, a payment status, cart reference for browse-first flow, and an optimistic concurrency version counter.

Service Line

An individual service within a booking, such as a hotel stay, flight segment, airport transfer, or activity excursion. Each service line records its type (HOTEL, FLIGHT, TRANSFER, ACTIVITY, CRUISE, VISA, OTHER, SERVICE_CHARGE), a description, supplier information, date range, cost and sell pricing with currency, confirmation status (PENDING, CONFIRMED, CANCELLED), supplier reference, quantity, sort order, and optional attributes (stored as JSON text). Service lines may reference ERP product and variant IDs for integration with the product catalog. A service-charge flag distinguishes overhead charges from actual services.

Booking Passenger

A traveller on a booking. Each passenger record stores title, first name, last name, date of birth, nationality, passport number and expiry date, gender, phone, email, and a lead passenger flag. One passenger per booking is designated as the lead passenger (referenced by the booking's leadPassengerId). An optional customerProfileId links the passenger to an existing customer profile for data pre-fill.

Booking Status History

An audit record capturing each status transition of a booking. Each record stores the previous status, new status, the user who made the change, the timestamp, and optional notes explaining the reason for the transition.

Booking Amendment

A tracked change to a confirmed or amended booking. Each amendment has a sequential number (per booking), the date, the user who made the change, a description, optional field-level change details (stored as JSON text), and the previous and new booking totals to capture the financial impact of the amendment.

Booking Activity Log

A unified event log recording all significant actions on a booking. Each entry has an activity type (BOOKING_CREATED, STATUS_CHANGED, SERVICE_ADDED, SERVICE_UPDATED, SERVICE_REMOVED, PASSENGER_ADDED, PASSENGER_REMOVED, HOLD_EXTENDED, AMENDMENT_RECORDED, NOTE_ADDED, NOTIFICATION_SENT, etc.), a description, the user and username who triggered it, a timestamp, optional details (JSON), and optional references to a related entity type and ID for drill-down.

Action Template Set

A named collection of action templates for a specific service type. Each template set has a name, service type (HOTEL, FLIGHT, TRANSFER, ACTIVITY, etc.), description, an active flag, and a sort order. Template sets serve as reusable blueprints that define the standard sequence of operational actions required to fulfil a particular type of service. Administrators can create multiple template sets per service type and activate or deactivate them as needed.

Action Template

An individual action step within a template set. Each template defines a sequence number (execution order), action code (e.g., HOTEL_CONFIRM, FLIGHT_ETICKET), description, whether it is required for voucher readiness, whether it is conditional (created only when a specified service line field is non-empty), deadline configuration (days offset relative to TRAVEL_START, SERVICE_DATE, or BOOKING_CONFIRMED), a default assignee role (BOOKING_AGENT, FINANCE, OPERATIONS), optional result fields (JSON array defining structured data to collect on completion), a dependency on another template's sequence number, and notes.

Action Item

A concrete task instance generated from an action template for a specific booking and service line. Each action item tracks the booking ID, service line ID, source template reference, sequence, action code, description, status (PENDING, IN_PROGRESS, AWAITING_SUPPLIER, COMPLETED, FAILED, NOT_REQUIRED), assigned user, due date, completion timestamp and user, structured result data (JSON), notes, whether it is required for voucher readiness, whether it is a custom (manually created) action, a dependency reference to another action item, creation timestamp, and sort order.

2. Typical Workflow

2.1 Booking Creation

A travel agent creates a new booking by providing customer information (either selecting an existing customer by email or entering new customer details), travel dates, and currency. The system generates a unique booking reference, creates the booking in ENQUIRY status, and optionally synchronizes the customer with Odoo ERP and creates a CRM lead.

2.2 Service Line Management

The agent adds service lines to the booking, each representing a service being sold to the customer. Service lines have cost (what the agency pays the supplier) and sell (what the customer pays) pricing. When a service line is added, updated, or removed, the booking totals are automatically recalculated. Service lines can be duplicated for convenience and confirmed individually with a supplier reference.

2.3 Passenger Management

The agent adds passengers to the booking with their personal and passport details. One passenger is designated as the lead passenger. Passport expiry validation checks that passports are valid for at least 6 months from the travel start date.

2.4 Status Lifecycle

The booking progresses through a defined status lifecycle:

ENQUIRY --> QUOTED --> OPTION_HELD --> CONFIRMED --> AMENDED --> TICKETED --> COMPLETED
                            |
                            v
                         EXPIRED --> QUOTED (re-quote)

Any active status --> CANCELLED

Each transition is validated against the allowed transition map, recorded in the status history, and logged in the activity log.

2.5 Option Hold

A booking in QUOTED status can be placed on a time-limited option hold with an expiry date. If the booking is not confirmed before the expiry date, a background job automatically transitions it to EXPIRED status and sends a notification. The hold can be extended while in OPTION_HELD status.

2.6 Amendments

When a service line is added, updated, or removed on a booking in CONFIRMED or AMENDED status, an amendment record is automatically created capturing the change description and the financial impact (previous vs. new total).

2.7 Notifications

Agents can trigger email notifications for booking confirmation and payment reminders directly from the booking interface.

2.8 Actions Framework

When a booking is confirmed (status transitions to CONFIRMED), the system automatically generates action items for each non-cancelled, non-service-charge service line. For each service line, the system looks up the active action template set matching the service line's service type. If a template set exists, its templates are instantiated as action items in sequence order.

Default template sets are provided for HOTEL (8 steps), FLIGHT (4 steps), TRANSFER (4 steps), and ACTIVITY (4 steps) service types. Administrators can customize these or create new template sets.

Conditional action creation: Templates marked as conditional (isConditional=true) are only instantiated if the referenced conditionField on the service line is non-empty. For example, a "Confirm special requests" action is only created if the service line has specialRequests populated.

Deadline calculation: Each template specifies a deadline offset in days relative to a reference date: TRAVEL_START (booking travel start date), SERVICE_DATE (service line start date), or BOOKING_CONFIRMED (date the booking was confirmed). Negative values indicate days before the reference date.

Action lifecycle: Action items progress through the following statuses:

PENDING --> IN_PROGRESS --> COMPLETED
                |
                v
         AWAITING_SUPPLIER --> COMPLETED
                                  |
PENDING/IN_PROGRESS/AWAITING  --> FAILED
PENDING/IN_PROGRESS/AWAITING  --> NOT_REQUIRED

COMPLETED, FAILED, and NOT_REQUIRED are terminal statuses.

Dependency chains: Templates can declare a dependency on another template's sequence number. When instantiated, the dependency is wired as a reference between action items. An action cannot be completed until its dependency action is in COMPLETED status.

Assignee resolution: Templates specify a default assignee role (BOOKING_AGENT resolves to the booking's assigned agent; FINANCE and OPERATIONS remain unassigned for team pools).

Result fields: Templates can define structured result fields (JSON array) that must be provided when completing the action. Fields can be marked as showOnVoucher to indicate they should appear on the customer voucher.

Voucher readiness: A booking is considered voucher-ready when all required action items are in COMPLETED or NOT_REQUIRED status. The voucherReady endpoint checks this condition.

Custom actions: Agents can create ad-hoc action items not linked to any template, with manual description, assignee, and due date.

Service line hook: When a service line is added to a booking that is already in CONFIRMED or AMENDED status, actions are automatically generated for the new service line.

3. Requirements

3.1 Functional Requirements

ID Requirement Milestone Status
Booking Creation
BK-001 The system shall allow agents to create a new booking with customer details, travel dates, currency, and notes M1 Implemented
BK-002 The system shall generate a unique booking reference in the format TQ-YYYY-NNNNN using a dedicated database sequence M1 Implemented
BK-003 The system shall set the initial status of a new booking to ENQUIRY M1 Implemented
BK-004 The system shall default the booking currency to the system local currency (from configuration) if not specified M1 Implemented
BK-005 The system shall set the initial payment status to UNPAID M1 Implemented
BK-006 The system shall support creating a booking with service lines and passengers in a single operation M1 Implemented
ERP Integration
BK-007 The system shall find or create a customer in Odoo ERP when a booking is created, and store the ERP customer ID M1 Implemented
BK-008 The system shall create a CRM lead in Odoo ERP when a booking is created, and store the ERP lead ID M1 Implemented
BK-009 ERP integration failures shall be logged as warnings but shall not prevent booking creation M1 Implemented
Status Lifecycle
BK-010 The system shall enforce valid status transitions according to the defined state machine M1 Implemented
BK-011 The valid status transitions shall be: ENQUIRY to QUOTED/CONFIRMED/CANCELLED; QUOTED to OPTION_HELD/CONFIRMED/CANCELLED; OPTION_HELD to CONFIRMED/EXPIRED/CANCELLED; CONFIRMED to AMENDED/TICKETED/COMPLETED/CANCELLED; AMENDED to CONFIRMED/TICKETED/CANCELLED; TICKETED to COMPLETED/CANCELLED; EXPIRED to QUOTED/CANCELLED M1 Implemented
BK-012 The system shall reject any status transition not defined in the valid transition map with an appropriate error message M1 Implemented
BK-013 The system shall record every status change in the booking status history table M1 Implemented
BK-014 The system shall log every status change in the activity log M1 Implemented
Option Hold
BK-015 The system shall allow a booking in QUOTED status to be placed on option hold with an expiry date/time M1 Implemented
BK-016 The system shall allow extending the option hold expiry date for bookings in OPTION_HELD status M1 Implemented
BK-017 The system shall automatically transition OPTION_HELD bookings to EXPIRED when the expiry date has passed (checked on read and by background job) M1 Implemented
BK-018 The system shall provide an API to query bookings expiring within a specified number of hours M1 Implemented
Service Line Management
BK-019 The system shall allow adding service lines to a booking with type, description, supplier, dates, cost/sell pricing, and attributes M1 Implemented
BK-020 The system shall support service types: HOTEL, FLIGHT, TRANSFER, ACTIVITY, CRUISE, VISA, OTHER, SERVICE_CHARGE M1 Implemented
BK-021 The system shall automatically convert service line cost to local currency using the exchange rate service M1 Implemented
BK-022 The system shall recalculate booking totals (totalCost, totalSell, totalServiceCharges, balanceDue) whenever a service line is added, updated, or removed M1 Implemented
BK-023 The system shall allow updating individual fields of a service line without requiring all fields M1 Implemented
BK-024 The system shall allow removing a service line from a booking M1 Implemented
BK-025 The system shall allow duplicating a service line, creating a copy with PENDING confirmation status and no supplier reference M1 Implemented
BK-026 The system shall allow confirming a service line by setting its confirmation status to CONFIRMED and recording the supplier reference M1 Implemented
Amendments
BK-027 The system shall automatically record an amendment when a service line is added, updated, or removed on a CONFIRMED or AMENDED booking M1 Implemented
BK-028 Each amendment shall capture the description, previous total, and new total M1 Implemented
BK-029 Amendment numbers shall be sequential per booking M1 Implemented
Passengers
BK-030 The system shall allow adding passengers with title, name, DOB, nationality, passport details, gender, phone, email, and lead flag M1 Implemented
BK-031 The system shall allow designating one passenger as the lead passenger per booking M1 Implemented
BK-032 The system shall update the booking's leadPassengerId when a lead passenger is set or removed M1 Implemented
BK-033 The system shall validate passport expiry dates against the travel start date (minimum 6 months validity) M1 Implemented
Activity Logging
BK-034 The system shall automatically log all significant booking events (creation, status changes, service operations, passenger operations, hold extensions) M1 Implemented
BK-035 The system shall allow agents to manually add notes to the activity log M1 Implemented
BK-036 The system shall support querying the activity log with a configurable limit (default 50 entries) M1 Implemented
Notifications
BK-037 The system shall allow sending booking confirmation emails M1 Implemented
BK-038 The system shall allow sending payment reminder emails M1 Implemented
Search and Filtering
BK-039 The system shall allow searching bookings by status, agent, customer, booking reference (partial match), and date range M1 Implemented
BK-040 The system shall allow reading a booking by ID or by booking reference M1 Implemented
Cart and Browse-First Flow
BK-041 The system shall support a cart-based workflow where customers browse and add items before creating a booking M2 Planned
BK-042 The system shall convert a cart into a booking with pre-populated service lines M2 Planned
Checkout and Payment
BK-043 The system shall support online payment integration during checkout M3 Implemented
BK-044 The system shall track payment status and generate invoices via ERP M3 Implemented
BK-045 The system shall support booking export to Excel M3 Implemented
Cancellation and Terms
BK-046 The system shall support cancellation with configurable terms and conditions per service line M4 Implemented
BK-047 The system shall calculate cancellation fees based on T&C rules M4 Implemented
Actions Framework
BK-048 The system shall allow administrators to create, update, and deactivate action template sets per service type, and manage individual action templates within each set (sequence, action code, conditional flags, deadline rules, result field definitions, dependency chains) M5 Implemented
BK-049 The system shall automatically generate action items from the matching template set when a booking is confirmed or when a service line is added to an already-confirmed booking M5 Implemented
BK-050 The system shall skip conditional action templates when the referenced condition field on the service line is empty M5 Implemented
BK-051 The system shall prevent completing an action item until its dependency action is in COMPLETED status M5 Implemented
BK-052 The system shall validate structured result data against the template's result field definitions when an action is completed, enforcing required fields M5 Implemented
BK-053 The system shall support action lifecycle operations: update (assignee, due date, notes), complete (with result data), fail (with notes), mark as not required, and reassign to another user M5 Implemented
BK-054 The system shall determine voucher readiness by checking that all required action items for a booking are in COMPLETED or NOT_REQUIRED status M5 Implemented
Vouchers and Documents
BK-055 The system shall generate PDF vouchers for confirmed bookings, combining service details from action results with terms and conditions, and merging e-ticket PDFs when available M6 Implemented
BK-056 The system shall provide S3-backed document management for bookings (upload, download, delete, email with attachment) with MIME validation and KMS encryption M6 Implemented
BK-057-v The system shall maintain configurable voucher section templates per service type, defining which fields appear and their data source (service line, attribute, action result, or attachment) M6 Implemented
BK-058-v The system shall archive previous voucher versions when a voucher is re-generated, preserving the S3 object with a version suffix M6 Implemented
BK-059-v The system shall prevent voucher generation until all required actions are in COMPLETED or NOT_REQUIRED status M6 Implemented
Booking Terms Management
BK-065 The system shall provide a per-booking Terms tab where agents can view, include/exclude, reorder, and save T&C items that appear on the voucher M6.5 Implemented
BK-066 The system shall auto-populate booking terms from resolved templates on first access (SERVICE, CANCELLATION, and GLOBAL types matching booking service lines) M6.5 Implemented
BK-067 The system shall support up to 30 custom free-text T&C entries per booking, each with title, HTML content, and include/exclude toggle M6.5 Implemented
BK-068 The system shall allow refreshing booking terms from templates when service lines change, adding new terms without disturbing existing selections M6.5 Implemented
BK-069 Voucher generation shall use only the included booking terms items when present, falling back to dynamic template resolution for backwards compatibility M6.5 Implemented
BK-069-v Voucher section rendering shall be externalized to file-based HTML templates in config/templates/booking/, with per-service-type overrides and %LabelName% placeholder resolution from fieldsDefinition M6.5 Implemented
Vendor-Specific Terms
BK-070 The system shall extract T&C from online vendor responses (hotel cancellation policies, activity terms, tour conditions) and present them as VENDOR-type terms during booking terms initialization M6.6 Planned
TripMaker and Group Integration
BK-060 The system shall integrate with TripMaker to convert quoted trip plans into bookings. TripMakerFacade.convertToBooking(projectId, itineraryId) converts a QUOTED TripMaker project into a booking, mapping cost breakdown components (with margins) to service lines, creating the lead passenger from traveler details, and setting the project status to CLOSED. API: POST /tripmaker/project/convertToBooking. M7 Implemented
BK-061 The system shall support creating and updating bookings from inbound groups. GroupManagerFacade.createBookingFromInboundGroup(groupId) creates or updates a booking from an INBOUND group: partner agency becomes the customer, hotels are aggregated per-hotel, transports and services are imported with adult/child cost aggregation, and all passengers are imported. Supports re-sync (updates an existing ENQUIRY/QUOTED booking in-place; rejects if CONFIRMED or beyond). API: POST /groups/group/createBooking. M7 Implemented
Outbound Group Sales
BK-062 The system shall support outbound group sales with inventory management M8 Implemented
BK-063 The system shall support group departure management with passenger rosters M8 Implemented

3.2 Non-Functional Requirements

ID Requirement Category
BK-NF-001 All booking API endpoints shall require authentication (agent or admin role) Security
BK-NF-002 All write operations shall be logged in the activity log for audit compliance Security
BK-NF-003 The booking reference sequence shall be atomic to prevent duplicate references under concurrent creation Data Integrity
BK-NF-004 Booking total recalculation shall be atomic with the service line operation that triggers it Data Integrity
BK-NF-005 The option expiry background job shall use distributed locking (Hazelcast) to prevent duplicate execution in clustered deployments Reliability
BK-NF-006 ERP integration failures shall not block or fail booking operations Resilience
BK-NF-007 Optimistic concurrency control via the version field shall prevent lost updates Data Integrity
BK-NF-008 Database indexes shall be maintained on booking reference, status, customer ID, agent ID, and travel dates for query performance Performance
BK-NF-009 The activity log query shall support pagination via a configurable limit parameter Performance
BK-NF-010 The system shall use the standard TQPro three-layer architecture (API, Facade, Entity Framework) Maintainability

4. Implementation Reference

The M1 implementation is documented in: - Database schema: config/db-changes/0044-booking-core.sql - Entity configuration: config/entities/booking-entities.xml - Technical implementation: technical-implementation.md - Test cases: test-cases.md - Use cases: use-cases.md - User guide: ../../user/booking/overview.md


M2: Cart + Browse-First Flow (TQ-87)

Status: Complete

New Entities

  • BookingCart — persistent, agent-keyed shopping cart. Fields: cartId, customerId, createdBy, status (ACTIVE/PARKED/CHECKED_OUT/EXPIRED/ABANDONED), totalSell, currency, version, customerName/Email/Phone (denormalized), erpCustomerId, erpQuoteId, bookingId.
  • BookingCartItem — item within a cart. Fields: cartItemId, cartId, serviceType, description, supplierId, supplierName, serviceDate, serviceDateEnd, quantity, unitCost, unitSell, attributes (JSON), notes, sourceModule, sourceRef.

Functional Requirements Implemented

  • BK-017 Browse-First Flow: Agents can browse hotel, flight, and activity search pages and add items to a persistent cart before assigning a customer.
  • BK-018 Cart Lifecycle: Carts support ACTIVE, PARKED (auto-park when agent starts new cart), CHECKED_OUT, EXPIRED, and ABANDONED statuses.
  • BK-019 Cart Checkout: Converts cart items to booking service lines, creates booking with denormalized customer info, links to ERP.
  • BK-020 Agent Rotation: Cart transfer (empty agent cart → take over customer's existing cart) and merge (agent has items → copy customer's old items in). Parked carts are resumable by any agent.
  • BK-021 Customer Denormalization: Booking and cart tables store customerName, customerEmail, customerPhone for fast search without ERP lookup.
  • BK-022 Customer Quick Search: Unified autocomplete searching by name, email, or phone across all pages (booking cart, wizard, hotel packages, offline tickets, visa management).
  • BK-023 Online Hotel Search: Standalone hotel-search.html page for searching supplier inventory (GoGlobal) with cart integration.
  • BK-024 Price Editing: Inline editable qty, cost, and sell price on cart items.

Database Schema

  • config/db-changes/0045-booking-cart.sql — bookingcart + bookingcartitem tables
  • config/db-changes/0046-booking-customer-denorm.sql — customerName/Email/Phone columns on booking + bookingcart

M3: Checkout + Payment (TQ-89)

  • BK-025 Payment Initiation: initiateCheckout() — service charge calculation, PGW link generation, deposit modes (full/percentage/fixed)
  • BK-026 Manual Payment: registerManualPayment() — register offline payments with journal code and reference
  • BK-027 Financial Summary: getFinancialSummary() — Odoo invoice sync, payment status derivation
  • BK-028 PGW Callbacks: handlePgwSuccess/Cancel/Decline() — confirm SO, create invoice, register payment
  • BK-029 Service Charges: Configurable per payment method (percent/fixed), auto-added on checkout, single active charge per booking

M3.5: Service Integration — Unified BLM Financial Sink (TQ-92)

Requirements

  • BK-030 Cart-to-Booking Merge: Agent can search eligible bookings (UNPAID, not terminal, no active payment) and merge cart items into an existing booking. Service lines appended, totals recalculated, dates extended.
  • BK-031 Hotel Package Cart Integration: "Add to Cart" button on hotel-package-booking page. Cart item carries package metadata (rooms, passengers, meal plan) in attributes JSON. Passengers auto-extracted from attributes on checkout or merge.
  • BK-032 Offline Ticket Cart Integration: "Add to Cart" on offline-tickets-sale page. Tickets reserved (RESERVED, no ERP) on add-to-cart; released on removal/abandon/expiry; finalized as SOLD on BLM payment. Ticket quantity locked on service line.
  • BK-033 Standalone Booking Bridges: When standalone flows complete, BLM booking records are automatically created (COMPLETED/FULLY_PAID). Covers hotel packages, offline tickets, and cruise sailings. Uses sourceType + sourceRef for traceability and idempotency.
  • BK-034 Cruise BLM Payment Cycle: "Transfer to Booking" button on cruise booking page (Payment pending status). Agent assigns customer via search/create modal. BLM booking created in CONFIRMED/UNPAID state. BLM checkout generates payment link. PGW callback advances cruise to "Voucher pending".
  • BK-035 Security Hardening: Negative amount validation, terminal booking modification guard, payment amount vs balance check, cart ownership verification, concurrent checkout prevention (optimistic locking), error response sanitization, fee override audit logging.

API Endpoints

Endpoint Purpose Roles
POST /blm/cart/addToBooking Merge cart into existing booking agent, admin
POST /blm/booking/searchEligible Search bookings eligible for merge agent, admin
POST /offline/sale/reserveForCart Reserve tickets for BLM cart agent, admin
POST /cruise/booking/createBlmPayment Create BLM booking for cruise payment agent, admin
POST /cruise/booking/calculateTotal Server-side booking total with currency conversion agent, admin

M5: Actions Framework (TQ-95)

Status: Implemented

New Entities

  • Action Template Set — A named collection of action templates for a specific service type. Fields: templateSetId, name, serviceType, description, isActive, sortOrder.
  • Action Template — An individual action step within a template set. Fields: actionTemplateId, templateSetId, sequence, actionCode, description, isRequired, isConditional, conditionField, deadlineDays, deadlineRelativeTo, defaultAssigneeRole, resultFields (JSON), dependsOnSequence, notes.
  • Action Item — A concrete task instance for a booking/service line. Fields: actionId, bookingId, serviceLineId, actionTemplateId, sequence, actionCode, description, status, assignedTo, assignedToName, dueDate, completedAt, completedBy, resultData (JSON), notes, isRequired, isCustom, dependsOnActionId, createdAt, sortOrder.

Functional Requirements Implemented

  • BK-048 Action Template Management: Administrators can create and manage action template sets per service type, with individual templates defining sequence, conditional logic, deadlines, dependencies, and result field schemas.
  • BK-049 Action Generation on Confirmation: When a booking transitions to CONFIRMED, action items are automatically generated for each non-cancelled service line using the matching active template set.
  • BK-050 Conditional Action Creation: Conditional templates are skipped when the referenced service line field is empty.
  • BK-051 Action Dependency Enforcement: Actions with dependencies cannot be completed until the dependency action reaches COMPLETED status.
  • BK-052 Action Completion with Result Data: Completing an action validates structured result data against the template's field definitions, enforcing required fields.
  • BK-053 Action Lifecycle Operations: Actions support status updates, completion, failure, marking as not required, and reassignment.
  • BK-054 Voucher Readiness Check: A booking is voucher-ready when all required actions are COMPLETED or NOT_REQUIRED.

API Endpoints

Endpoint Purpose Roles
POST /blm/actiontemplate/sets List template sets (optional serviceType filter) admin
POST /blm/actiontemplate/set/read Read template set with its templates admin
POST /blm/actiontemplate/set/save Create or update a template set admin
POST /blm/actiontemplate/set/delete Soft-delete (deactivate) a template set admin
POST /blm/actiontemplate/save Create or update an action template admin
POST /blm/actiontemplate/delete Delete an action template (blocked if referenced) admin
POST /blm/action/create Create a custom (ad-hoc) action item agent, admin
POST /blm/action/update Update action fields (status, assignee, due date, notes) agent, admin
POST /blm/action/complete Complete an action with optional result data agent, admin
POST /blm/action/fail Mark an action as failed agent, admin
POST /blm/action/markNotRequired Mark an action as not required agent, admin
POST /blm/action/reassign Reassign an action to another user agent, admin
POST /blm/action/list List actions by bookingId, serviceLineId, or status agent, admin
POST /blm/action/myItems List actions assigned to the current user agent, admin
POST /blm/action/overdue List overdue actions across all bookings agent, admin
POST /blm/action/voucherReady Check voucher readiness for a booking agent, admin

Database Schema

  • config/db-changes/0050-booking-actions.sql — 3 tables (actiontemplateset, actiontemplate, actionitem), 3 sequences, 7 indexes, seed data for 4 default template sets

M6: Vouchers + Document Management (TQ-96)

Status: Implemented

New Entities

  • Voucher Section Template — Configurable template defining which fields appear in a voucher section for a given service type. Fields: voucherSectionTemplateId, serviceType (UNIQUE), sectionTitle, fieldsDefinition (JSON array), headerTemplate (HTML), isActive.
  • Booking Document — An S3-backed file associated with a booking. Fields: documentId, bookingId, serviceLineId, docType (VOUCHER, VOUCHER_ARCHIVE, ETICKET, CONFIRMATION, INVOICE, OTHER), fileName, s3Key, contentType, fileSize, uploadedBy, uploadedAt, notes, version.

Functional Requirements Implemented

  • BK-055 Voucher Generation: Agents can generate a PDF voucher for a confirmed booking. The voucher includes company branding, booking reference, travel dates, passenger list, per-service-line sections populated from action results, and resolved terms and conditions. E-ticket PDFs from completed FLIGHT_ETICKET actions are merged into the final document. Prior voucher versions are archived with a version suffix.
  • BK-056 Document Management: Agents can upload documents (PDF, JPEG, PNG; max 50 MB) to a booking via base64 encoding, download them, delete them, and email them as attachments. Documents are stored in S3 with KMS encryption. MIME type is validated via Apache Tika.
  • BK-057-v Voucher Section Templates: Administrators configure per-service-type templates defining field sources. Each field resolves from one of four sources: serviceline (entity getter), attribute (service line JSON attributes), action (completed action result data by actionCode), or attachment (file reference from action result). Six seed templates are provided (HOTEL, FLIGHT, TRANSFER, ACTIVITY, CRUISE, VISA).
  • BK-058-v Voucher Version Archiving: When a voucher is re-generated, the prior version's S3 object is copied with a -v{N} suffix, the document record is updated to type VOUCHER_ARCHIVE, and a new VOUCHER record is created.
  • BK-059-v Voucher Readiness Gate: Voucher generation is blocked unless all required actions are COMPLETED or NOT_REQUIRED (uses the isVoucherReady() check from M5).

API Endpoints

Endpoint Purpose Roles
POST /blm/vouchertemplate/list List active voucher section templates admin
POST /blm/vouchertemplate/read Read voucher section template by serviceType admin
POST /blm/vouchertemplate/save Create or update a voucher section template admin
POST /blm/booking/generateVoucher Generate a PDF voucher for a booking agent, admin
POST /blm/document/upload Upload a document to a booking (base64) agent, admin
POST /blm/document/download Download a document (binary response) agent, admin
POST /blm/document/list List documents for a booking agent, admin
POST /blm/document/delete Delete a document from S3 and database agent, admin
POST /blm/document/email Email a document as attachment agent, admin

Database Schema

  • config/db-changes/0051-booking-vouchers.sql — 2 tables (vouchersectiontemplate, bookingdocument), 2 sequences, 3 indexes, seed data for 6 voucher section templates

M6.5: Booking Terms & Conditions Tab + Voucher Externalization (TQ-100)

Status: Implemented

New Entity

  • Booking Terms Item — A per-booking link to a T&C template or a custom free-text term, with include/exclude flag and sort order. Fields: bookingTermsItemId, bookingId, termsTemplateId (nullable for custom items), title, contentHtml, termsType (SERVICE/CANCELLATION/GLOBAL/CUSTOM), serviceType, sortOrder, isIncluded, isCustom.

Functional Requirements

  • BK-065 Booking Terms Tab: A new tab between Passengers and Amendments showing all T&C items for the booking. Each item has an include checkbox. Only checked items appear on the generated voucher.
  • BK-066 Auto-population: On first tab open, the system resolves templates for all service types in the booking (SERVICE + CANCELLATION per type, plus all GLOBAL) and creates bookingtermsitem records. Idempotent — subsequent opens load existing records.
  • BK-067 Custom Terms: Agents can add up to 30 free-text T&C entries with title and HTML content. Custom items can be edited and deleted; template-based items can only be toggled.
  • BK-068 Refresh from Templates: When service lines change, agents can refresh to add terms for new service types without disturbing existing items or custom entries.
  • BK-069 Voucher Integration: generateVoucher() checks for saved booking terms items. If present, uses only included items sorted by sortOrder. If absent, falls back to dynamic resolveBookingTerms() for backwards compatibility.

API Endpoints

Endpoint Purpose Roles
POST /blm/terms/booking/list List booking terms items agent, admin
POST /blm/terms/booking/initialize Seed items from templates agent, admin
POST /blm/terms/booking/save Batch update include flags and sort order agent, admin
POST /blm/terms/booking/addCustom Add a custom free-text term agent, admin
POST /blm/terms/booking/refresh Add new template items without disturbing existing agent, admin
POST /blm/terms/booking/deleteCustom Delete a custom item agent, admin

Database Schema

  • config/db-changes/0052-booking-terms-items.sql — 1 table (bookingtermsitem), 1 sequence, 1 index

Voucher Template Externalization

All voucher section HTML has been moved from Java code to external file-based templates:

Template File Purpose
config/templates/booking/voucher-master.html Page shell (existing)
config/templates/booking/voucher-section.html Default section layout
config/templates/booking/voucher-passengers.html Passengers table
config/templates/booking/voucher-terms.html Terms & conditions wrapper
config/templates/booking/sections/section-HOTEL.html Hotel-specific with confirmation box
config/templates/booking/sections/section-FLIGHT.html Flight-specific with prominent PNR
config/templates/booking/sections/section-TRANSFER.html Transfer layout
config/templates/booking/sections/section-ACTIVITY.html Activity layout
config/templates/booking/sections/section-CRUISE.html Cruise/sailing layout

Section templates support %FIELD_ROWS%, %SECTION_TITLE%, %DESCRIPTION%, %SERVICE_DATES%, %SERVICE_TYPE%, %SUPPLIER_REF%, %SUPPLIER_NAME%, and %LabelName% (matching fieldsDefinition labels) for custom field placement. Unresolved placeholders are stripped.

resolveServiceLineField() expanded to all 21 CServiceLine getters: description, serviceType, supplierRef, supplierName, supplierId, notes, specialRequests, startDate, endDate, currency, cost, costLocal, sellPrice, quantity, confirmationStatus, sortOrder, erpProductId, erpVariantId, passengerIds, cancellationTerms, isServiceCharge.


M6.6: Vendor-Specific Terms (Planned)

Status: Planned — Scoped after M6.5 validation.

Will extract T&C from online vendor responses and present them as VENDOR-type booking terms items during initialization. Known data sources: - Hotels: cancellation policies from CHotelOffer (cancellationType, cancellationDeadline, cancellationDescription) - Tiqets activities: policies from TqProduct (cancellationPolicy, importantInfo, inclusions/exclusions) - Rayna B2B tours: terms from TourBase (termsAndConditions, cancellationPolicyDescription)


8. Outbound Group Sales (M8)

Status: Implemented (TQ-98, 24 commits, completed 2026-04-01)

8.1 Group Pricing Model

The group pricing model aggregates costs from all group itinerary components (hotels, activities, transports, flight blocks, expenses) into a single totalGroupCost, then derives per-pax pricing with a configurable margin.

  • Cost aggregation from 5 sources: hotel room-level costs (cost per room multiplied by nights), activities, transports, flight blocks (blockSize multiplied by costPerTicket), and general expenses -- all with currency conversion to the group pricing currency
  • Base pricing formula: baseCostPerPax = totalGroupCost / assumedPaxCount, baseSellingPrice = baseCostPerPax * (1 + marginPercent / 100)
  • Assumed pax count: the expected number of passengers for cost-splitting; adjustable by the agent
  • Max pax count: optional hard limit preventing overbooking beyond a threshold
  • Recalculation: agents can trigger cost recalculation at any time to pick up changes in itinerary components

8.2 Price Variations

Variations are supplements and discounts applied on top of the base selling price. Each variation has:

  • Variation code and description (e.g., SINGLE_SUPPL, CHILD_DISCOUNT)
  • Adjustment type: FIXED (absolute amount per pax) or PERCENT (percentage of base selling price per pax)
  • Adjustment value: signed -- positive for surcharges, negative for discounts
  • Applies to: PAX (per passenger) or BOOKING (flat amount)
  • Optional flag: agent selects per sale (e.g., desert safari add-on)
  • Automatic flag: auto-applied based on pax type (ADULT, CHILD, INFANT)

When calculating a sale price, automatic variations are applied to matching pax types, optional variations are applied only when selected by the agent, and all amounts are summed to produce adjustmentsTotal.

8.3 Sales Workflow

Each group sale tracks a customer purchasing seats on an outbound group departure:

  • Draft creation: agent selects customer, sets pax counts (adults/children/infants), selects optional variations. The system calculates basePriceTotal, adjustmentsTotal, and finalPrice. Status = DRAFT.
  • Price override: agent can override the calculated final price with a manual amount and required reason.
  • Confirmation: triggers booking creation via BookingServiceI with sourceType=GROUP_OUTBOUND. One GROUP_TRAVEL service line is created with the total sale price. One HOTEL service line is created per rooming assignment (room cost multiplied by nights, with currency conversion). All group sale passengers are added to the booking. The sale's bookingId is linked to the new booking. Status = CONFIRMED.
  • Cancellation: releases room assignments (CTripRoomPax), clears CGroupSalePax references, cancels the linked booking if one exists. Status = CANCELLED.
  • Bidirectional cancellation sync: cancelling a booking that has sourceType=GROUP_OUTBOUND automatically cancels the linked group sale; cancelling a group sale automatically cancels the linked booking.

8.4 Sale Passengers (CGroupSalePax)

Each passenger in a group sale is tracked with:

  • paxId: link to the group trip passenger
  • paxType: ADULT, CHILD, or INFANT
  • individualPrice: calculated price for this passenger
  • roomId: assigned room (from rooming step)
  • bookingPassengerId: link to the booking passenger record (set on confirmation)

CBookingPassenger has a reciprocal groupPaxId field for bidirectional sync.

8.5 Occupancy Tracking

The GroupOccupancy DTO provides real-time inventory visibility:

  • assumedPax: from group pricing configuration
  • soldPax: sum of paxCount across non-cancelled sales
  • remainingPax: assumedPax minus soldPax
  • fillPercentage: percentage of assumed capacity sold
  • isOverbooked: true when soldPax exceeds assumedPax
  • atHardLimit: true when soldPax reaches maxPaxCount (blocks further sales)

8.6 Booking Bridge

Sale confirmation creates a standard BLM booking via the BookingServiceI interface:

  • GROUP_TRAVEL product code configured in erp-booking.properties for ERP sales order creation
  • Service lines: one GROUP_TRAVEL line (total price) plus one HOTEL line per room assignment
  • Passengers: all sale pax imported as booking passengers
  • ERP integration: customer lookup/creation in Odoo, CRM lead generation
  • BookingServiceI expanded with: addServiceLine, updateServiceLine, removeServiceLine, addPassenger, updatePassenger, removePassenger, readBooking, getServiceLines, getPassengers, changeBookingStatus

8.7 Flight Blocks and Legs

Supporting entities for group flight inventory:

  • CTripFlightBlock: blockSize, costPerTicket, pricePerTicket, minCommitment, travelClass, status
  • CTripFlightLeg: direction (OUTBOUND/RETURN), departure/arrival airports and times, airline, flightNumber
  • Flight block costs feed into group pricing cost aggregation

8.8 General Expenses

  • CTripExpense: amount, currencyCode, category (VISA/INSURANCE/FEE/OTHER), description
  • Expense amounts feed into group pricing cost aggregation with currency conversion

8.9 Frontend

  • Group navigation workflow: Itinerary -> Passengers -> Accommodation -> Activities -> Transport -> Flights -> Expenses -> Pricing -> Rooming -> Sales -> Invoicing
  • Pricing page: group pricing panel (cost, assumed pax, margin, selling price), recalculate button, variations table with add/edit/delete
  • Flights page: two-panel layout for flight blocks and legs
  • Expenses page: expense list with category, amount, currency
  • Sales page: occupancy bar with color coding, sales list with customer name and booking reference links, 5-step sale wizard (Customer autocomplete -> Passengers -> Rooms -> Pricing with variation selection -> Confirm)

8.10 Functional Requirements Implemented

ID Requirement Status
BK-062 Group pricing model with cost aggregation from 5 sources, per-pax pricing, configurable margin, and recalculation Implemented
BK-062a Price variations (FIXED/PERCENT, automatic/optional, per pax type) with signed adjustment values Implemented
BK-062b Sale price calculation engine with automatic and agent-selected variations Implemented
BK-062c Flight block inventory (CTripFlightBlock, CTripFlightLeg) feeding into cost aggregation Implemented
BK-062d General expenses (CTripExpense) feeding into cost aggregation with currency conversion Implemented
BK-063 Sales workflow (DRAFT -> CONFIRMED -> CANCELLED) with booking bridge via BookingServiceI Implemented
BK-063a Occupancy tracking with fill percentage, overbooking detection, and hard limit enforcement Implemented
BK-063b Sale passenger management (CGroupSalePax) with room assignments and booking passenger sync Implemented
BK-063c Bidirectional cancellation sync between group sales and bookings Implemented
BK-063d GROUP_TRAVEL product code for ERP sales order integration Implemented

8.11 Database Schema

  • config/db-changes/0048-outbound-groups.sql -- 4 tables (grouppricing, grouppricingvariation, groupsale, groupsalevariation), 4 sequences, indexes
  • config/db-changes/0053-group-sale-pax.sql -- groupsalepax table
  • config/db-changes/0054-trip-flight-blocks.sql -- tripflightblock, tripflightleg tables
  • config/db-changes/0055-trip-expenses.sql -- tripexpense table

8.12 API Endpoints (22 new)

# Endpoint Purpose Roles
1 blm/group/pricing/read Get or create group pricing agent, admin
2 blm/group/pricing/update Update pricing fields agent, admin
3 blm/group/pricing/recalculate Recalculate from itinerary agent, admin
4 blm/group/variation/add Add price variation agent, admin
5 blm/group/variation/update Update variation agent, admin
6 blm/group/variation/remove Remove variation admin
7 blm/group/variation/list List variations agent, admin
8 blm/group/sale/create Create draft sale agent, admin
9 blm/group/sale/confirm Confirm sale (creates booking) agent, admin
10 blm/group/sale/cancel Cancel sale agent, admin
11 blm/group/sale/list List sales for group agent, admin
12 blm/group/sale/calculatePrice Preview sale price agent, admin
13 blm/group/occupancy Get occupancy summary agent, admin
14 groups/flightblock/create Create flight block agent, admin
15 groups/flightblock/update Update flight block agent, admin
16 groups/flightblock/list List flight blocks agent, admin
17 groups/flightleg/create Create flight leg agent, admin
18 groups/flightleg/update Update flight leg agent, admin
19 groups/flightleg/list List flight legs agent, admin
20 groups/expense/create Create expense agent, admin
21 groups/expense/update Update expense agent, admin
22 groups/expense/list List expenses agent, admin

9. Admin Maintenance & Data Health (M9)

9.1 Overview

M9 provides an admin-only maintenance page for monitoring booking system health, cleaning up stale data, detecting orphans, auditing ERP sync, and managing notification failures. Two background jobs run daily for automated monitoring and cart cleanup.

9.2 Cart Cleanup

ID Requirement Status
BK-070 Stale cart detection by age and status (ACTIVE, PARKED) with configurable thresholds Implemented
BK-071 Bulk expire action to mark selected carts as EXPIRED and clear their items Implemented
BK-072 Bulk abandon action to mark selected carts as ABANDONED and clear their items Implemented
BK-073 Cart statistics: count by status, by age range (0-7d, 7-30d, 30-90d, 90+d), with/without customer Implemented

9.3 Booking Health

ID Requirement Status
BK-074 Zombie booking detection: bookings in a given status with no activity for a configurable number of days Implemented
BK-075 Detect bookings in non-terminal status (ENQUIRY, QUOTED, CONFIRMED) with zero service lines Implemented
BK-076 Booking status distribution: count of bookings grouped by status Implemented

9.4 Option Expiry Monitoring

ID Requirement Status
BK-077 Expiry runner status: last execution time, status, items processed from maintenance job log Implemented
BK-078 Missed expiry detection: bookings with status OPTION_HELD and optionExpiryDate in the past Implemented
BK-079 Manual expiry trigger: admin can manually expire a single booking and send notification Implemented

9.5 Orphan Detection

ID Requirement Status
BK-080 Detect orphaned service lines (serviceline records with no matching booking) Implemented
BK-081 Detect orphaned passengers (bookingpassenger records with no matching booking) Implemented
BK-082 Detect orphaned cart items (bookingcartitem records with no matching bookingcart) Implemented
BK-083 Delete orphaned records by entity type and ID list, with activity logging Implemented

9.6 ERP Sync Audit

ID Requirement Status
BK-084 Detect bookings missing ERP customer ID (non-cancelled, older than 1 day) Implemented
BK-085 Detect bookings missing CRM lead ID Implemented
BK-086 Retry ERP sync for a specific booking (re-run findOrCreateErpCustomer + createCrmLead) Implemented

9.7 Notification Tracking

ID Requirement Status
BK-087 Track notification delivery status (SENT, FAILED, RETRIED, PENDING) in notificationstatus table Implemented
BK-088 Detect failed notifications within a configurable time range Implemented
BK-089 Retry failed notification for a specific booking and notification type Implemented
BK-090 Notification statistics: count by status, type, and age range Implemented

9.8 Activity Log Management

ID Requirement Status
BK-091 Activity log statistics: total entries, count by type, by age range, average per booking Implemented
BK-092 Archive activity logs older than a configurable threshold (export to JSON, then delete) Implemented
BK-093 Detect bookings with excessive activity entries (above configurable threshold) Implemented

9.9 System Health Dashboard

ID Requirement Status
BK-094 Aggregate health summary: stale cart count, zombie booking count, missed expiry count, ERP sync failure count, failed notification count, activity log total Implemented
BK-095 Dashboard cards display at top of maintenance page with key health metrics Implemented
BK-096 Tabbed navigation: Carts, Bookings, ERP Sync, Notifications, Activity Logs Implemented

9.10 Background Jobs

ID Requirement Status
BK-097 CartCleanupRunner: daily job to expire unassigned carts (7d), expire/abandon parked carts (30d), with Hazelcast distributed lock Implemented
BK-098 BookingHealthRunner: daily monitoring job for zombie bookings, missed expiries, ERP sync failures, with admin alert on threshold exceeded Implemented
BK-099 Job execution logging to maintenancejoblog table (job name, duration, items processed, status) Implemented

9.11 New Entities

Entity Purpose
MaintenanceJobLog Tracks background job execution history (job name, timestamp, duration, items processed, status, details)
NotificationStatus Tracks notification delivery per booking (type, recipient, sent time, status, error message, retry count)

9.12 Database Schema

  • config/db-changes/0057-maintenance-tables.sql -- 2 tables (maintenancejoblog, notificationstatus), 2 sequences, indexes

9.13 API Endpoints (20 new, admin-only)

# Endpoint Purpose Roles
1 blm/maintenance/health/summary System health summary (dashboard cards data) admin
2 blm/maintenance/cart/stale List of stale carts with filters admin
3 blm/maintenance/cart/statistics Cart count by status/age admin
4 blm/maintenance/cart/bulkExpire Bulk expire selected carts admin
5 blm/maintenance/cart/bulkAbandon Bulk abandon selected carts admin
6 blm/maintenance/booking/zombies List of zombie bookings admin
7 blm/maintenance/booking/noServices Bookings without service lines admin
8 blm/maintenance/booking/statusDistribution Count by status admin
9 blm/maintenance/expiry/status Option expiry runner status admin
10 blm/maintenance/expiry/missed Missed expiries list admin
11 blm/maintenance/expiry/trigger Manual trigger for one booking admin
12 blm/maintenance/orphan/detect Orphaned records by type admin
13 blm/maintenance/orphan/delete Delete orphans admin
14 blm/maintenance/erp/audit ERP sync failures admin
15 blm/maintenance/erp/retry Retry ERP sync for one booking admin
16 blm/maintenance/notification/failures Failed notifications admin
17 blm/maintenance/notification/retry Retry notification admin
18 blm/maintenance/notification/statistics Notification stats admin
19 blm/maintenance/activitylog/statistics Activity log stats admin
20 blm/maintenance/activitylog/archive Archive old logs admin