Skip to content

Cruise Offer Management - General Requirements

Domain description

This module manages cruise offers, their pricing, itineraries and bookings. They are managed using the following physical entities: - Cruise Company - Cruise Area - Cruise Ship - Cabin Type - Ship Cabin - Itinerary - Cruise - Cruise Port - Cruise Point - Charge Type - Cabin Charge - Other Charges - Cruise Template - Cabin Price Template - Other Charge Template - Cabin Pre-Booking - Cruise Booking - Cruise Passenger - Booked Cabin - Booking Add-on

Entity descriptions

Cruise offer entities are described in the sections below. The implementation is in the file cruises.sql

Cruise Company

Maintains a list of all cruise companies (e.g. MSC, Costa, Norwegian, Celestiyal...). Each company has a code, name, and optional color (hex code) used for visual identification in the UI (e.g. company-colored pill borders in the sailing strip).

Cruise area

Maintains a list of areas where cruises operate. For example: East Mediterranean, West Mediterranean, Gulf, Southeast Asia, Carribean...

Cruise Ship

Maintains a list of ships. Each ship belongs to a company.

Cabin type

Maintains a list of cabin types. These are not related to ships, and this is a dimension entity describing what types of cabins we have. For example: Inside, Inside Window, Outside Window, Outside Terrace, Suite, and others.

Ship Cabin

This is a linking entity, maintaining the link between the cruise ship and the cabin types available on this ship. The ship cabin's main characteristic is the number of people it can accommodate, and it can also have a description of the items / amenities available inside the cabin; this description is linked to the ship cabin because for the same cabin type, it can vary from ship to ship.

Itinerary

This entity maintains the list of itineraries, i.e. the different types of voyages. Typically, one ship can sail on the same itinerary multiple times within a period of time (season). The itinerary is related to the ship and to the cruise area. The itinerary normally has a name and a duration, for example: "7 nights GCC cruise". Optionally the itinerary can have an URL to the image showing the itinerary on the map (or other image).

Cruise

The cruise is the actual sailing, which is an instance of itinerary. It is related to the itinerary and characterizes with a precise start date. For example, the ship "Costa Toscana" may sail on the itinerary "7 Nights GCC cruise" on several cruises - 1st Dec, 10th Dec, 20th Dec etc.

Cruise Port

This is a list of all cruise ports where the ships may stop (a.k.a. ports of call). This is a dimension entity.

Cruise Point

This entity links the particular cruise with the ports at which the cruise stops. Each cruise point is characterized with its cruise (i.e. instance of itinerary), the arrival date/time, departure date/time, port of call, and short description.

Cabin Charge

This is the base charge of the cabin on a particular cruise. It is dependent on the ship cabin as well as the particular cruise instance. For example, the same cabin (outside window) may cost 100\$ on the cruise starting Dec 1st, but will cost 500\$ on the cruise starting Dec 20th. It may be in different currencies.

Charge type

A dimension table listing all types of charges that can be added to a cruise booking - for example: port tax, service charge, gratuity charge etc.

Other charges

This is the list of possible charges that can be added to a particular cruise, with their actual amounts. They are related to the charge type, and the cruise. Each other charge also has an optional single-letter indicator field displayed as a small badge in the UI.

Cruise template

This is a helper entity that is useful when creating cruise instances. For each itinerary, there will be multiple template entries. Each template entry will be linked to a particular port, and will contain the information of the day offset of the itinerary (e.g. day 1, day 3, day 6 etc), the arrival time, departure time, sequence of the stop, and optional description. Selecting all template records from this entity for a particular itinerary and sorting them by the stop sequence will give the route of the cruise. This entity should be used by the system to create a cruise record (instance of the itinerary) and its cruise points. The way it works is that the user will select the itinerary and input the start date; then, the system will load all template entries for this itinerary and for each entry will create one cruise point with arrival date and time combined from the cruise start date to which it will add the day offset and arrival / departure time from the template, and the port id from the template. For example: the user will choose the itinerary "7 days GCC cruise" with start date 1st Dec; the system will load the template records and if the template record has a port "Dubai" with date offset "2", arrival time "3am" and departure time "8pm", it will create a Cruise Point record with cruise ID of the newly created cruise instance, port ID of "Dubai", arrival date / time of 2nd Dec (which is the 2nd day of the cruise) at 3am, and departure date / time of 2nd Dec at 8pm - and repeat this for all entries in the template.

Cabin Price Template

Default cabin pricing for an itinerary. Each record links an itinerary to a ship cabin with a default amount, currency, exchange rate, and availability flag. When a new sailing is created, these templates can be used to pre-populate cabin charges. The "Init Cabins" function creates templates for all ship cabins of the itinerary's ship.

Other Charge Template

Default other charges for an itinerary. Each record links an itinerary to a charge type with a default amount, currency, exchange rate, mandatory flag, pax type, and optional indicator. When a new sailing is created, these templates pre-populate other charges.

Cabin Pre-Booking

Pre-booked cabin inventory per sailing and cabin type. Each pre-booking record represents a single cabin reservation and has a status lifecycle: Available → Reserved → Booked. The transition from Available to Reserved occurs automatically when a booked cabin is assigned with a pre-booking reference. The transition from Reserved to Booked occurs automatically when the associated booking status reaches "Vouchered". The managePrebookings operation allows smart add/reduce to match a target count, with the constraint that the count cannot be reduced below the number of non-Available (Reserved + Booked) pre-bookings. Each pre-booking stores cost per cabin, price per cabin, and commission percentage.

Cruise Booking

Master booking record that links a booking to a specific cruise (sailing). Each booking has a system-generated booking number (format: PT-DDMM-XXXXXXXX), lead passenger name, passenger counts (total, adults, children, infants), total amount, and status. The booking status lifecycle progresses through: Documents pending → Availability pending → Payment pending → Voucher pending → Vouchered, with cancellation branches at each stage.

Cruise Passenger

Passenger details linked to a booking. Each passenger has first name, last name, nationality (ISO country code), date of birth, passport number, passport expiry date, lead passenger flag, and remarks. The system computes age categories (Adult ≥12, Child 2-11, Infant <2) based on date of birth relative to the sailing start date.

Booked Cabin

Cabin assignment within a booking. Each booked cabin links a booking to a ship cabin type with number of passengers, price, status, and an "own" flag indicating whether the cabin is from the company's own pre-booked inventory (isOwn=true with a preBookingId reference) or an external allocation (isOwn=false).

Booking Add-on

Optional charges attached to a booking and optionally to a specific passenger. Each add-on references a charge type with amount and currency. These represent non-mandatory charges selected during the booking process.

Typical workflow

Dimensional data

Dimensional data are the cruise companies, cruise areas, cruise ships, types of cabins, types of charges and ports. This data can be created and edited at any time, typically before the itineraries are created, but it can be manipulated independently (except deletion - this data should not be deleted).

The user first creates the cruise company followed by creating the ships of that company. Then, typically, the user links the ship cabin types to the created ship, to identify which ship has which types of cabins. If a cabin type is missing, it can be added.

Working data - itineraries and cruises

Once we have the dimensional data in place, the itineraries can be created. User first creates and names the itinerary with its duration, and chooses an area and ship for this itinerary. Then, it creates a template for this itinerary - the template is a list of entries for each cruise stop. Each entry has a sequence (the order of stops on the voyage), the day offset (which day of the voyage it is), the arrival time, the departure time (not dates - only times) and the identification of the port. The user should add all the stops with their respective offset, arrival and departure times and ports, and these will serve as a basis for creation of the cruises. This template, when entries are sorted by sequence, should inform that "on the 3rd day of the cruise, we arrive in Dubai at 3am and leave at 11pm". A short description can be added for each stop to illustrate any special conditions / events for that stop.

Next step is to create the cruises - the instances of the itinerary. Typically they are served by the same ship (which is why the itinerary is linked to the ship). The user can add a cruise to the selected itinerary by selecting the template and entering the starting date. With this information (having the starting date and the template) the system is able to present the entire cruise day by day. Given the above template entry example, the application should be able to present that, if the cruise starts on 1st Dec (thus the 3rd day being 3rd of Dec), "on 3rd of Dec 2025 we arrive in Dubai at 3am and stay there until 11am."

Once the cruise template is complete, the user should price the cruise. The price consists of following items: - Base price per cabin per trip - which is recorded in the Cabin Charge entity - Additional charges per person per trip - which are recorded in the Other Charges entity. Some charges are mandatory (e.g. port taxes, gratuity charges), while some are optional (e.g. alcohol or spa packages). The charge types can be adult, child or unified.

One cruise can have only one base charge per cabin, but multiple additional charges.

Once the pricing is complete, the cruise is ready for booking.

Pre-booking management

Before bookings are taken, the cruise manager may pre-book cabins for specific sailings. Pre-booking reserves cabin inventory through the pre-booking dialog, specifying the cabin type, target count, cost per cabin, price per cabin, and commission percentage. The system uses smart add/reduce logic to match the target count, ensuring it cannot go below the number of already reserved or booked cabins.

Booking workflow

The booking interface (separate web page) allows the agent to create and manage bookings for specific sailings:

  1. Sailing selection - Agent selects a sailing from the sailing strip (scrollable pill-shaped buttons showing date and status, with company-colored borders)
  2. New booking - Agent opens the new booking dialog, enters passenger counts (adults, children, infants), selects a cabin type, and enters lead passenger details including nationality (with autocomplete). The system generates a booking number (PT-DDMM-XXXXXXXX format), creates the booking, lead passenger, and initial cabin assignment
  3. Cabin assignment - When assigning cabins, the system checks for available pre-bookings and assigns them as "own" cabins (isOwn=true) when possible. Additional cabins without pre-bookings are assigned as non-own
  4. Passenger management - Agent adds passengers with nationality (autocomplete from country list), date of birth (system computes age category), passport details. The system performs visa check against destination ports
  5. Add-on management - Agent attaches optional charges per passenger from the sailing's non-mandatory other charges
  6. Status progression - Booking moves through: Documents pending → Availability pending → Payment pending → Voucher pending → Vouchered, with cancellation options at each stage (Cancelled-NonRefundable, Cancelled-RefundPending, Cancelled-Refunded)
  7. Totals - Booking total is automatically recalculated from booked cabin prices plus add-on amounts

Interface description

The cruise management interface is split across three dedicated pages, accessible from the main navigation menu under "Sailings":

Page 1: Dashboard (cruise-dash.html)

The dashboard provides a high-level overview of all cruise data with company management:

  • Left pane: Company accordion with collapsible sections per company (company-colored headers), each showing ship list and action buttons (add/edit company, add ship). A settings button opens dimensional data management (areas, ports, cabin types, charge types)
  • Right pane: KPI summary cards (sailing areas, ships, itineraries, sailings, bookings), a filter bar (search, area, status filters, New Itinerary button), and an itinerary card grid showing all itineraries with key metrics including port count. Each itinerary card has Edit, Copy, Manage, and Print buttons. Creating a new itinerary redirects to the itinerary page. Copy opens a dialog pre-populated with source data (name suffixed with "(Copy)") and redirects after save. Print opens the itinerary page in a new tab with auto-print

Page 2: Itinerary Management (cruise-itin.html)

Accessed via cruise-itin.html?itineraryId=N from the dashboard. Uses a two-pane, 50/50 split layout:

  • Left pane: Itinerary info form (code, name, duration, area, ship dropdowns, status badge, save/delete), itinerary template table (port sequence with add/edit/delete), and pricing templates section with cabin prices (with "Init Cabins" to auto-create from ship cabins) and other charge templates (with indicator badge column)
  • Right pane: Sailing bar (pill-shaped buttons per sailing showing date + status), and when a sailing is selected: action toolbar (regen points, status dropdown, delete), sailing itinerary (cruise points table), cabin pricing (with Prebk/Avail columns and Prebook button), other charges (with indicator badges), and bookings table (showing current bookings with clickable rows linking to the booking page)
  • New features: Exchange rate auto-fill on currency change, indicator badges on charge templates and charges, pre-booking management dialog, breadcrumb navigation

Page 3: Agent Booking (cruise-agt-book.html)

Accessed via cruise-agt-book.html?cruiseId=N or ?bookingId=N. Uses a three-section layout:

  • Sailing strip (full width): Horizontally scrollable pill-shaped buttons for each sailing, with company-colored borders, showing date and itinerary code. Clicking a pill loads that sailing's data
  • Left pane: Cabin availability table (cabin type, max pax, charge, prebook count with quick +/- buttons, available count) and bookings list for the selected sailing
  • Right pane (shown when a booking is selected): Booking header with booking number, status dropdown, delete button, and New button; passengers table with "X of Y" count header, visa badges, age badges, capacity warning, and add/edit/delete actions; booked cabins table with own/prebook indicators, maxPax validation, prices, and totals; add-ons table with paxType-filtered passenger dropdown and totals. Left and right panes scroll independently
  • Key features: Nationality autocomplete from country API, visa requirement check against destination ports, age category computation (Adult/Child/Infant), own cabin priority from pre-bookings, booking number generation (PT-DDMM-XXXXXXXX), automatic totals recalculation, cabin capacity validation (numPax <= maxPax), adult-only add-on filtering by paxType, customer name column in booking list

Implementation

The cruise management module is fully implemented across backend and frontend:

Backend

  • Database schema: config/db-changes/cruises.sql (13 original tables) and config/db-changes/cruise-booking.sql (5 booking tables)
  • Native (JPA) entities: tqapp/src/main/java/com/perun/tlinq/client/nts/db/cruise/
  • Canonical entities and facade: tqapp/src/main/java/com/perun/tlinq/entity/cruise/
  • REST API: tqapi/src/main/java/com/perun/tlinq/api/CruiseApi.java
  • Entity configuration: config/entities/cruise-entities.xml
  • Service definitions: config/nts-client.xml

Frontend

  • Dashboard: tqweb-adm/cruise-dash.html + tqweb-adm/js/modules/cruise-dash.js
  • Itinerary management: tqweb-adm/cruise-itin.html + tqweb-adm/js/modules/cruise-itin.js
  • Agent booking: tqweb-adm/cruise-agt-book.html + tqweb-adm/js/modules/cruise-agt-book.js
  • Shared API client: tqweb-adm/js/modules/cruise-common.js
  • Exchange rate service: tqweb-adm/js/modules/exchange-rate-service.js
  • Styles: tqweb-adm/css/cruise.css