Skip to content

Pricing Management UI Implementation Plan

Overview

Implement pricing management using a template-based approach similar to cruise points: - Pricing Templates (at itinerary level) define the charge structure - Cruise Charges (at cruise level) are generated from templates, with editable values

Architecture

Itinerary Level (Templates)          Cruise Level (Instances)
─────────────────────────────        ─────────────────────────
Cabin Price Template                 Cabin Charges
  - shipCabinId                        - generated from template
  - defaultAmount                      - amount (editable)
  - defaultCurrency                    - available (editable)

Other Charge Template                Other Charges
  - chargeTypeId                       - generated from template
  - mandatory, paxType                 - amount (editable)
  - defaultAmount                      - + can add extra charges

Phase 1: Database Schema

New Tables

-- Cabin Price Template (default prices per itinerary)
CREATE TABLE nts.cabinpricetemplate (
    cabinpricetemplateid SERIAL PRIMARY KEY,
    itineraryid INTEGER NOT NULL REFERENCES nts.itinerary(itineraryid),
    shipcabinid INTEGER NOT NULL REFERENCES nts.shipcabin(shipcabinid),
    amount NUMERIC(12,2) DEFAULT 0,
    currency VARCHAR(3) DEFAULT 'USD',
    exrate NUMERIC(10,4) DEFAULT 1.0,
    UNIQUE(itineraryid, shipcabinid)
);

-- Other Charge Template (fee structure per itinerary)
CREATE TABLE nts.otherchargetemplate (
    otherchargetemplateid SERIAL PRIMARY KEY,
    itineraryid INTEGER NOT NULL REFERENCES nts.itinerary(itineraryid),
    chargetypeid INTEGER NOT NULL REFERENCES nts.chargetype(chargetypeid),
    amount NUMERIC(12,2) DEFAULT 0,
    currency VARCHAR(3) DEFAULT 'USD',
    exrate NUMERIC(10,4) DEFAULT 1.0,
    mandatory BOOLEAN DEFAULT false,
    paxtype VARCHAR(20) DEFAULT 'all',
    UNIQUE(itineraryid, chargetypeid)
);

Add to: config/db-changes/cruise-schema-updates.sql

Phase 2: Backend Entities

New Entity Classes

Class Location Fields
CabinpricetemplateEntity tqapp/.../client/nts/db/cruise/ id, itineraryid, shipcabinid, amount, currency, exrate
OtherchargetemplateEntity tqapp/.../client/nts/db/cruise/ id, itineraryid, chargetypeid, amount, currency, exrate, mandatory, paxtype
CCabinPriceTemplate tqapp/.../entity/cruise/ cabinPriceTemplateId, itineraryId, shipCabinId, amount, currency, exRate
COtherChargeTemplate tqapp/.../entity/cruise/ otherChargeTemplateId, itineraryId, chargeTypeId, amount, currency, exRate, mandatory, paxType

Entity Configuration

Add to config/entities/cruise-entities.xml: - CabinPriceTemplate entity with CRUD services - OtherChargeTemplate entity with CRUD services

Phase 3: Backend API

New Endpoints in CruiseApi.java

Endpoint Purpose
POST /cabinpricetemplate/list List cabin price templates for itinerary
POST /cabinpricetemplate/write Create/update cabin price template
POST /cabinpricetemplate/delete Delete cabin price template
POST /cabinpricetemplate/initForItinerary Initialize templates from ship cabins
POST /otherchargetemplate/list List other charge templates for itinerary
POST /otherchargetemplate/write Create/update other charge template
POST /otherchargetemplate/delete Delete other charge template

Modify CruiseFacade.java

Update createCruiseSkeleton() to generate charges from templates:

// Generate cabin charges from cabin price templates
List<CCabinPriceTemplate> cabinTemplates = getCabinPriceTemplates(itineraryId);
for (CCabinPriceTemplate t : cabinTemplates) {
    createCabinCharge(cruiseId, t.getShipCabinId(), t.getAmount(),
                      t.getExRate(), t.getCurrency(), true);
}

// Generate other charges from other charge templates
List<COtherChargeTemplate> chargeTemplates = getOtherChargeTemplates(itineraryId);
for (COtherChargeTemplate t : chargeTemplates) {
    createOtherCharge(t.getChargeTypeId(), cruiseId, t.getAmount(),
                      t.getCurrency(), t.getExRate(), t.getMandatory());
}

Phase 4: Frontend - Itinerary Level (Templates)

UI Location

Add "Pricing Template" section in the itinerary info panel, below the route template section.

HTML Structure (cruisemgmt.html)

<!-- Pricing Template Section (in itinerary panel) -->
<div class="form-section" id="pricing_template_section">
    <div class="form-section-title">
        <i class="fa-solid fa-dollar-sign"></i> Pricing Template
        <button class="button tiny success" id="btn_init_cabin_templates">
            <i class="fa-solid fa-wand-magic-sparkles"></i> Initialize Cabins
        </button>
    </div>

    <!-- Cabin Price Templates -->
    <h6><i class="fa-solid fa-bed"></i> Cabin Prices (Defaults)</h6>
    <table id="cabintemplate_table">...</table>

    <!-- Other Charge Templates -->
    <h6><i class="fa-solid fa-receipt"></i> Other Charges (Defaults)
        <button id="btn_add_chargetemplate">Add</button>
    </h6>
    <table id="chargetemplate_table">...</table>
</div>

JavaScript Functions

Template Data Loading: - loadCabinPriceTemplates(itineraryId) - loadOtherChargeTemplates(itineraryId)

Template Rendering: - renderCabinPriceTemplatesTable() - renderOtherChargeTemplatesTable()

Template CRUD: - editCabinPriceTemplate(id), saveCabinPriceTemplate() - newOtherChargeTemplate(), editOtherChargeTemplate(id), saveOtherChargeTemplate(), deleteOtherChargeTemplate(id) - initCabinPriceTemplates() - creates templates for all ship cabins

Phase 5: Frontend - Cruise Level (Instances)

UI Location

Add "Cruise Pricing" section in the cruise points panel (right side), visible when a cruise is selected.

HTML Structure (cruisemgmt.html)

<!-- Cruise Pricing Section (in cruise panel) -->
<div class="form-section" id="pricing_section" style="display: none;">
    <div class="form-section-title">
        <i class="fa-solid fa-dollar-sign"></i> Cruise Pricing
    </div>

    <!-- Cabin Charges -->
    <h6><i class="fa-solid fa-bed"></i> Cabin Prices</h6>
    <table id="cabincharges_table">...</table>

    <!-- Other Charges -->
    <h6><i class="fa-solid fa-receipt"></i> Other Charges
        <button id="btn_add_othercharge">Add</button>
    </h6>
    <table id="othercharges_table">...</table>
</div>

JavaScript Functions

Data Loading: - loadCabinCharges(cruiseId) - existing API - loadOtherCharges(cruiseId) - existing API

Rendering: - renderCabinChargesTable() - renderOtherChargesTable()

CRUD: - editCabinCharge(id), saveCabinCharge(), toggleCabinAvailability(id) - newOtherCharge(), editOtherCharge(id), saveOtherCharge(), deleteOtherCharge(id)

Files to Modify/Create

Database

  • config/db-changes/cruise-schema-updates.sql - add 2 tables

Backend - New Files

  • tqapp/.../client/nts/db/cruise/CabinpricetemplateEntity.java
  • tqapp/.../client/nts/db/cruise/OtherchargetemplateEntity.java
  • tqapp/.../entity/cruise/CCabinPriceTemplate.java
  • tqapp/.../entity/cruise/COtherChargeTemplate.java

Backend - Modify

  • config/entities/cruise-entities.xml - add entity mappings
  • tqapp/.../entity/cruise/CruiseFacade.java - add template methods, modify createCruiseSkeleton
  • tqapi/.../api/CruiseApi.java - add template endpoints

Frontend

  • tqweb-adm/cruisemgmt.html - add template section, pricing section, dialogs
  • tqweb-adm/js/modules/cruisemgmt.js - add all template and charge functions

Implementation Order

  1. Database schema - create tables
  2. Native entities - JPA entity classes
  3. Canonical entities - CCabinPriceTemplate, COtherChargeTemplate
  4. Entity configuration - XML mappings
  5. CruiseFacade - template CRUD methods
  6. CruiseApi - template endpoints
  7. Modify createCruiseSkeleton - generate from templates
  8. Frontend templates UI - itinerary panel
  9. Frontend charges UI - cruise panel
  10. Testing - verify flow end-to-end

Use Case Coverage

Use Case Implementation
UC-PRC-01: Configure Cabin Charges Cruise: editCabinCharge
UC-PRC-02: Set Cabin Availability Cruise: toggleCabinAvailability
UC-PRC-03: Add Other Charges Cruise: newOtherCharge (for extras not in template)
UC-PRC-04: Edit Other Charges Cruise: editOtherCharge
UC-PRC-05: Remove Other Charges Cruise: deleteOtherCharge
UC-PRC-06: Initialize Pricing Template: initCabinPriceTemplates, auto-generate on cruise create

Data Flow

1. Create Itinerary
   └── Select Ship
       └── "Initialize Cabins" button creates cabin price templates

2. Configure Templates (Itinerary Level)
   ├── Edit cabin price defaults
   └── Add/edit other charge templates

3. Create Cruise
   └── createCruiseSkeleton() auto-generates:
       ├── Cabin charges from cabin price templates
       └── Other charges from other charge templates

4. Configure Cruise Pricing (Cruise Level)
   ├── Edit cabin prices/availability
   ├── Edit other charge amounts
   └── Add extra charges not in template

Design Decisions

  1. Backward Compatibility: Existing cruises (created before templates) continue to work with manual charge management. Templates only affect newly created cruises.

  2. Ship Change Handling: When ship is changed on an itinerary, show a warning that cabin price templates may need to be re-initialized. Do not automatically delete templates - let user manage manually.