Skip to content

GoGlobal Hotel Integration Plugin - Implementation Plan

Context

TQPro needs a new backend plugin (tqgglbl) for Yanolja GoGlobal hotel search and booking (API v3.16.8). This plugin replaces the Amadeus hotel integration which is being discontinued. The architecture must support a pluggable online hotel supplier pattern: the searchMode API parameter routes between online (configured supplier plugin - GoGlobal now, others in the future) and contracted (always NTS for inbound group management). Amadeus hotel code will be disabled but retained.

XSD schemas already generated: design/GoGlobalRequestSchema.xsd, design/GoGlobalOperationSchemas.xsd.


Architecture: Pluggable Online Hotel Supplier

Search Mode Routing

HotelApi (searchMode parameter)
    |-- "online"  --> OnlineHotelSupplierI (interface)
    |                 |-- GoGlobalHotelSupplier (active)
    |                 |-- AmadeusHotelSupplier (disabled, retained)
    |                 +-- [Future suppliers]
    +-- "contracted" --> NTS plugin (always active)

Key Design Principle

A new OnlineHotelSupplierI interface in tqapp defines the contract for any online hotel supplier. HotelSearchFacade is refactored to delegate to whichever supplier is configured. The active supplier is configured via tourlinq-config.xml app properties.

// In tqapp - supplier-agnostic interface
public interface OnlineHotelSupplierI {
    List<CHotelOffer> searchOffers(CHotelSearch search);
    CHotelOffer valuateOffer(String hotelSearchCode, Date arrivalDate);
    Object createBooking(Map bookingParams);
    Object getBookingStatus(String bookingCode);
    Object getBookingDetails(String bookingCode);
    Object cancelBooking(String bookingCode);
    List searchHotelsByName(String keyword, String cityCode);
    List getHotelsByCity(String cityCode);
    Object getPriceBreakdown(String hotelSearchCode);
}

The active supplier is resolved at runtime:

<!-- tourlinq-config.xml AppProperties -->
<property name="hotel.online.supplier" value="GoGlobalServiceFactory"/>


Phase 1: Module Setup & Configuration

1.1 Create Gradle Module tqgglbl

New: tqgglbl/build.gradle.kts (pattern: tqryb2b/build.gradle.kts) - Dependencies: tqapp, tqcommon, JUnit Jupiter, Hibernate, Jackson, JAXB

Modify: settings.gradle.kts - add include("tqgglbl")

1.2 Plugin Registration

Modify: config/tourlinq-config.xml

Under <Plugins>:

<Plugin name="GoGlobalPlugin" constructorClass="com.perun.tlinq.framework.GoGlobalPlugin">
    <properties>
        <property name="dbname" value="##tlinq.dbname"/>
        <property name="dbpass" value="##tlinq.dbpass"/>
        <property name="configFile" value="goglobal-client.xml"/>
    </properties>
</Plugin>

Under <ServiceFactories>:

<ServiceFactory name="GoGlobalServiceFactory"
                code="GOGLOBAL" type="remote" enabled="true"
                class="com.perun.tlinq.client.goglobal.service.GoGlobalServiceFactory">
    <properties>
        <property name="supplier.code" value="GOGLOBAL"/>
    </properties>
</ServiceFactory>

Under <AppProperties> (new property):

<property name="hotel.online.supplier" value="GoGlobalServiceFactory"/>

1.3 Disable Amadeus Hotel

Modify: config/entities/hotel-entities.xml - Set enabled="false" on the AmadeusServiceFactory factories for HotelOffer, HotelByName, HotelByCity entities (lines 385-457)

Modify: config/amadeus-client.xml - Comment out or leave the 6 hotel service definitions (lines 61-86) - they won't be called since the factory is disabled

1.4 Plugin Client Configuration

New: config/goglobal-client.xml

<GoGlobalPluginConfig>
    <PluginProperties>
        <property name="dbname" value="local"/>
        <property name="goglobal.agency" value="AGENCY_ID"/>
        <property name="goglobal.user" value="USERNAME"/>
        <property name="goglobal.password" value="PASSWORD"/>
        <property name="goglobal.apiServer" value="https://api.goglobal.travel"/>
        <property name="goglobal.apiVersion" value="2.4"/>
        <property name="goglobal.currency" value="USD"/>
        <property name="goglobal.responseFormat" value="JSON"/>
        <property name="goglobal.staticdata.refresh.days" value="7"/>
    </PluginProperties>
    <Databases>
        <Database name="local" url="jdbc:postgresql://localhost:5432/tlinq"
                  username="tlinq" password="TlinqAdmin"/>
    </Databases>
    <Services>
        <Service name="searchAvailability"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="searchAvailability"
                 entity="com.perun.tlinq.client.goglobal.entity.GGHotelOffer"
                 idField="hotelSearchCode"/>
        <Service name="valuateBooking"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="valuateBooking"
                 entity="com.perun.tlinq.client.goglobal.entity.GGHotelOffer"
                 idField="hotelSearchCode"/>
        <Service name="createBooking"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="createBooking"
                 entity="com.perun.tlinq.client.goglobal.entity.GGBooking"
                 idField="goBookingCode"/>
        <Service name="getBookingStatus"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="getBookingStatus"
                 entity="com.perun.tlinq.client.goglobal.entity.GGBooking"
                 idField="goBookingCode"/>
        <Service name="getBookingDetails"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="getBookingDetails"
                 entity="com.perun.tlinq.client.goglobal.entity.GGBooking"
                 idField="goBookingCode"/>
        <Service name="cancelBooking"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="cancelBooking"
                 entity="com.perun.tlinq.client.goglobal.entity.GGBooking"
                 idField="goBookingCode"/>
        <Service name="searchHotelsByName"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="searchHotelsByName"
                 entity="com.perun.tlinq.client.goglobal.entity.GGHotelInfo"
                 idField="hotelId"/>
        <Service name="getHotelsByCity"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="getHotelsByCity"
                 entity="com.perun.tlinq.client.goglobal.entity.GGHotelInfo"
                 idField="hotelId"/>
        <Service name="getHotelInfo"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="getHotelInfo"
                 entity="com.perun.tlinq.client.goglobal.entity.GGHotelInfo"
                 idField="hotelId"/>
        <Service name="getPriceBreakdown"
                 class="com.perun.tlinq.client.goglobal.service.hotel.GoGlobalHotelService"
                 method="getPriceBreakdown"
                 entity="com.perun.tlinq.client.goglobal.entity.GGPriceBreakdown"
                 idField="hotelSearchCode"/>
    </Services>
</GoGlobalPluginConfig>


Phase 2: Online Hotel Supplier Interface (tqapp)

2.1 Supplier Interface

New: tqapp/.../entity/hotel/OnlineHotelSupplierI.java

Defines the contract that any online hotel supplier plugin must implement. This allows swapping GoGlobal for another supplier in the future by simply implementing this interface and changing the config property.

2.2 Supplier Registry

New: tqapp/.../entity/hotel/OnlineHotelSupplierRegistry.java

Singleton that resolves the active supplier based on hotel.online.supplier config property. Each plugin registers its supplier implementation at initialization time.

public class OnlineHotelSupplierRegistry {
    private static final Map<String, OnlineHotelSupplierI> suppliers = new ConcurrentHashMap<>();

    public static void register(String factoryName, OnlineHotelSupplierI supplier) { ... }
    public static OnlineHotelSupplierI getActiveSupplier() {
        String active = ClientConfig.instance().getAppProperty("hotel.online.supplier");
        return suppliers.get(active);
    }
}

2.3 Refactor HotelSearchFacade

Modify: tqapp/.../entity/hotel/HotelSearchFacade.java

  • executeBasicSearch() now calls OnlineHotelSupplierRegistry.getActiveSupplier().searchOffers() instead of hardcoded ef.search("HotelOffer", scl) via AmadeusServiceFactory
  • All sorting and pagination logic stays as-is
  • The facade becomes supplier-agnostic

2.4 Modify HotelApi.java

Modify: tqapi/.../api/HotelApi.java

Add searchMode parameter to relevant endpoints:

searchHotelOffers (~line 1087):

String searchMode = ApiUtil.gmp(reqData, "searchMode", String.class, false);
if (searchMode == null) searchMode = "online";

if ("contracted".equals(searchMode)) {
    ar = doSearchContractedHotels(session, reqData);
} else {
    ar = doSearchHotelOffers(session, reqData); // uses OnlineHotelSupplierRegistry
}

searchByName and getByCity: delegate to OnlineHotelSupplierRegistry.getActiveSupplier() methods. For contracted mode, search from NTS hotel table.

TripMakerApi.searchAccommodations(): Uses the online supplier via HotelSearchFacade - no hardcoded Amadeus dependency. Works automatically with GoGlobal once registered.

2.5 Add Missing api-roles.properties

Modify: config/api-roles.properties - add the 4 currently-missing endpoints:

hotel/searchOffers=guest,agent,admin
hotel/fetchOfferResults=guest,agent,admin
hotel/searchByName=guest,agent,admin
hotel/getByCity=guest,agent,admin


Phase 3: Database Schema & JPA Entities (Static Data Cache)

3.1 Database Schema

New: config/sql/goglobal-schema.sql

CREATE SCHEMA IF NOT EXISTS goglobal;

CREATE TABLE goglobal.country (
    country_id INTEGER PRIMARY KEY,
    country_name VARCHAR(200),
    country_code VARCHAR(10),
    last_updated TIMESTAMP DEFAULT NOW()
);

CREATE TABLE goglobal.city (
    city_id INTEGER PRIMARY KEY,
    city_name VARCHAR(200),
    country_id INTEGER REFERENCES goglobal.country(country_id),
    last_updated TIMESTAMP DEFAULT NOW()
);

CREATE TABLE goglobal.hotel (
    hotel_id INTEGER PRIMARY KEY,
    hotel_name VARCHAR(500),
    city_id INTEGER REFERENCES goglobal.city(city_id),
    star_rating INTEGER,
    address VARCHAR(500),
    latitude DOUBLE PRECISION,
    longitude DOUBLE PRECISION,
    thumbnail_url VARCHAR(500),
    description TEXT,
    last_updated TIMESTAMP DEFAULT NOW()
);

CREATE TABLE goglobal.star_rating (
    star_id INTEGER PRIMARY KEY,
    star_name VARCHAR(50),
    star_value NUMERIC(2,1)
);

CREATE TABLE goglobal.refresh_log (
    id SERIAL PRIMARY KEY,
    refresh_type VARCHAR(50),
    refresh_date TIMESTAMP DEFAULT NOW(),
    record_count INTEGER,
    status VARCHAR(20),
    error_message TEXT
);

3.2 JPA Entities

Package: com.perun.tlinq.client.goglobal.db

Class Table Purpose
GGCountryEntity goglobal.country Cached country data
GGCityEntity goglobal.city Cached city data
GGHotelEntity goglobal.hotel Cached hotel data
GGStarRatingEntity goglobal.star_rating Star rating reference
GGRefreshLogEntity goglobal.refresh_log Refresh audit log

All use JPA annotations with schema = "goglobal". Pattern: tqryb2b/db/ entities.

3.3 Hibernate Session

New: com.perun.tlinq.client.goglobal.util.GoGlobalDBSession (singleton) - Pattern: RaynaDBSession


Phase 4: Plugin Core (tqgglbl)

4.1 Package Structure

tqgglbl/src/main/java/com/perun/tlinq/
+-- framework/
|   +-- GoGlobalPlugin.java
+-- client/goglobal/
    +-- config/
    |   +-- GoGlobalPluginConfig.java      # JAXB config object
    +-- db/
    |   +-- GGCountryEntity.java
    |   +-- GGCityEntity.java
    |   +-- GGHotelEntity.java
    |   +-- GGStarRatingEntity.java
    |   +-- GGRefreshLogEntity.java
    +-- entity/
    |   +-- GGEntity.java                  # Base (extends AbstractEntity)
    |   +-- GGHotelOffer.java              # @TlinqClientEntity
    |   +-- GGBooking.java
    |   +-- GGHotelInfo.java
    |   +-- GGPriceBreakdown.java
    +-- remote/
    |   +-- GoGlobalSoapClient.java        # SOAP transport
    |   +-- GoGlobalRequestBuilder.java    # XML builder per operation
    |   +-- GoGlobalResponseParser.java    # JSON/XML parser
    |   +-- dto/                           # Response DTOs
    |       +-- GGAvailabilityResponse.java
    |       +-- GGValuationResponse.java
    |       +-- GGBookingResponse.java
    |       +-- GGBookingStatusResponse.java
    |       +-- GGBookingDetailsResponse.java
    |       +-- GGCancellationResponse.java
    |       +-- GGHotelInfoResponse.java
    |       +-- GGPriceBreakdownResponse.java
    +-- service/
    |   +-- GoGlobalServiceFactory.java
    |   +-- GoGlobalEntityService.java
    |   +-- SDRefreshRunner.java
    |   +-- StaticDataRefresher.java
    |   +-- hotel/
    |       +-- GoGlobalHotelService.java
    |       +-- GoGlobalHotelFacade.java   # Implements OnlineHotelSupplierI
    +-- util/
        +-- GoGlobalClientConfig.java
        +-- GoGlobalDBSession.java

4.2 GoGlobalPlugin

New: GoGlobalPlugin extends AbstractPlugin

initializePlugin(): 1. Load config via GoGlobalClientConfig 2. Test DB via GoGlobalDBSession 3. Check refresh schedule, launch SDRefreshRunner if needed 4. Initialize GoGlobalServiceFactory 5. Register supplier: OnlineHotelSupplierRegistry.register("GoGlobalServiceFactory", GoGlobalHotelFacade.getInstance())

4.3 GoGlobalHotelFacade

Implements OnlineHotelSupplierI - this is the key integration point.

Method GoGlobal Op Description
searchOffers(CHotelSearch) 11 Maps CHotelSearch params to GoGlobal availability request; enriches results with cached hotel data; returns List<CHotelOffer>
valuateOffer(code, date) 9 Validates pricing and cancellation
createBooking(params) 2 Creates booking
getBookingStatus(code) 5 Returns status
getBookingDetails(code) 4 Returns full details
cancelBooking(code) 3 Cancels booking
searchHotelsByName(keyword, city) N/A Queries goglobal.hotel cache table (name LIKE)
getHotelsByCity(cityCode) N/A Queries goglobal.hotel cache table (city_id)
getPriceBreakdown(code) 14 Per-night pricing

Note: searchHotelsByName and getHotelsByCity use the local cached static data rather than GoGlobal API calls, since GoGlobal doesn't have dedicated endpoints for these. The cached goglobal.hotel table provides hotel reference data equivalent to what Amadeus AmdHotelRefDataService provided.


Phase 5: Remote Communication

5.1 SOAP Client

New: GoGlobalSoapClient - Builds SOAP 1.2 envelope, sets HTTP headers (API-Operation, API-AgencyID) - Inner XML: <Root><Header>...</Header><Main>...</Main></Root> per design/GoGlobalOperationSchemas.xsd - POST via java.net.http.HttpClient - JSON response for availability (Op 11), XML for others

5.2 Request Builder

New: GoGlobalRequestBuilder - One method per operation type, builds XML per schemas in design/GoGlobalOperationSchemas.xsd - Operations: 11 (availability), 9 (valuation), 2 (booking), 5 (status), 4 (details), 3 (cancel), 6/61 (hotel info), 14 (price breakdown)

5.3 Response Parser + DTOs

New: GoGlobalResponseParser - JSON parsing (availability) and XML parsing (all others)

New: remote/dto/ - Jackson-annotated DTOs for each GoGlobal response structure

Key response structures (from the GoGlobal specification):

GGAvailabilityResponse (JSON):

Header: Agency, User, Operation, OperationType
Stats: HotelQty, ResultsQty
Hotels[]:
  HotelName, HotelCode, CountryId, CityId, Location, LocationCode
  Thumbnail, HotelImage, Longitude, Latitude, BestSellerRank
  HotelFacilities[], RoomFacilities[]
  Offers[]:
    HotelSearchCode, CxlDeadline, NonRef, Rooms[], RoomBasis
    Availability, TotalPrice, Currency, TotalTax, RoomRate
    CommPercent, CommValue, Category
    CancellationPolicies[]: Id, Starting, BasedOn, Mode, Value
    Remark, Special, Preferred

GGValuationResponse (XML): HotelSearchCode, ArrivalDate, CancellationDeadline, Remarks, Rates, Currency, TotalTax

GGBookingResponse (XML): GoBookingCode, GoReference, BookingStatus, TotalPrice, Currency, HotelId, HotelName, HotelConfirmation, Rooms, Leader, PaymentTransactions


Phase 6: Entity Configuration

6.1 hotel-entities.xml Updates

Modify: config/entities/hotel-entities.xml

Disable Amadeus factories (set enabled="false"): - HotelOffer entity -> AmadeusServiceFactory (line 389) - HotelByName entity -> AmadeusServiceFactory (line 421) - HotelByCity entity -> AmadeusServiceFactory (line 440)

Add GoGlobal factory to HotelOffer:

<Factory name="GoGlobalServiceFactory"
         nativeEntity="com.perun.tlinq.client.goglobal.entity.GGHotelOffer">
    <ServiceList>
        <Service name="searchAvailability" action="search"
                 returnClass="com.perun.tlinq.entity.hotel.CHotelOffer"/>
    </ServiceList>
    <FieldMappingList>
        <FieldMapping targetField="offerId" sourceField="hotelSearchCode" mapping="DirectMapping"/>
        <FieldMapping targetField="hotelId" sourceField="hotelCode" mapping="DirectMapping"/>
        <FieldMapping targetField="hotelName" sourceField="hotelName" mapping="DirectMapping"/>
        <FieldMapping targetField="cityCode" sourceField="cityId" mapping="DirectMapping"/>
        <FieldMapping targetField="available" sourceField="available" mapping="DirectMapping"/>
        <FieldMapping targetField="checkInDate" sourceField="checkInDate" mapping="DirectMapping"/>
        <FieldMapping targetField="checkOutDate" sourceField="checkOutDate" mapping="DirectMapping"/>
        <FieldMapping targetField="roomType" sourceField="rooms" mapping="DirectMapping"/>
        <FieldMapping targetField="roomCategory" sourceField="category" mapping="DirectMapping"/>
        <FieldMapping targetField="currencyCode" sourceField="currency" mapping="DirectMapping"/>
        <FieldMapping targetField="totalAmount" sourceField="totalPrice" mapping="DirectMapping"/>
        <FieldMapping targetField="cancellationType" sourceField="nonRef" mapping="DirectMapping"/>
        <FieldMapping targetField="cancellationDeadline" sourceField="cxlDeadline" mapping="DirectMapping"/>
        <FieldMapping targetField="boardType" sourceField="roomBasis" mapping="DirectMapping"/>
    </FieldMappingList>
</Factory>

Add GoGlobal factory to HotelByName and HotelByCity (using GGHotelInfo native entity, mapping to cached data fields).


Phase 7: Static Data Caching

7.1 Refresh Mechanism

New: StaticDataRefresher - refreshes countries, cities, hotels from GoGlobal static data feeds into goglobal schema. Batch operations for large datasets.

New: SDRefreshRunner (Runnable) - scheduled by plugin, checks goglobal.refresh_log vs goglobal.staticdata.refresh.days config.

7.2 Usage

  • searchHotelsByName() -> SQL query on goglobal.hotel (name ILIKE '%keyword%')
  • getHotelsByCity() -> SQL query on goglobal.hotel WHERE city_id = ?
  • Enrichment: availability results enriched with hotel details from cache
  • City code resolution: frontend city names mapped to GoGlobal city IDs

Phase 8: Dual-Mode API

Summary of searchMode Routing

Endpoint searchMode=online searchMode=contracted
hotel/searchOffers OnlineHotelSupplierI.searchOffers() -> GoGlobal availability NTSHotelFacade.searchAllHotels()
hotel/fetchOfferResults Paginated results from persistent search Same (uses saved results)
hotel/searchByName OnlineHotelSupplierI.searchHotelsByName() -> cached data NTSServiceFactory hotel search
hotel/getByCity OnlineHotelSupplierI.getHotelsByCity() -> cached data N/A (NTS hotels don't have city codes)
hotel/listHotels N/A (always contracted) NTS contracted hotels

Default: online for searchOffers/searchByName/getByCity; contracted for listHotels.


Implementation Order

Step Description Key Files
1 Module setup + build tqgglbl/build.gradle.kts, settings.gradle.kts
2 Config classes + client XML GoGlobalPluginConfig, GoGlobalClientConfig, goglobal-client.xml
3 DB schema + JPA entities + session goglobal-schema.sql, GG*Entity, GoGlobalDBSession
4 OnlineHotelSupplierI + Registry (in tqapp) OnlineHotelSupplierI.java, OnlineHotelSupplierRegistry.java
5 SOAP client + request builder GoGlobalSoapClient, GoGlobalRequestBuilder
6 Response DTOs + parser dto/*.java, GoGlobalResponseParser
7 Native plugin entities GGEntity, GGHotelOffer, GGBooking, GGHotelInfo, GGPriceBreakdown
8 Service factory + entity service GoGlobalServiceFactory, GoGlobalEntityService
9 Hotel facade (implements supplier interface) GoGlobalHotelFacade, GoGlobalHotelService
10 Static data refresh StaticDataRefresher, SDRefreshRunner
11 Main plugin class GoGlobalPlugin
12 Entity config updates hotel-entities.xml (add GG, disable Amadeus), tourlinq-config.xml
13 Refactor HotelSearchFacade (supplier-agnostic) HotelSearchFacade.java
14 Dual-mode HotelApi + TripMakerApi HotelApi.java, TripMakerApi.java
15 api-roles.properties update Add 4 missing endpoints
16 Unit + integration + E2E tests Test classes

Critical Files Summary

New Files (~35 files)

  • tqgglbl/ module: ~25 Java classes + build.gradle.kts
  • config/goglobal-client.xml
  • config/sql/goglobal-schema.sql
  • tqapp/.../OnlineHotelSupplierI.java
  • tqapp/.../OnlineHotelSupplierRegistry.java

Modified Files (Existing)

File Change
settings.gradle.kts Add tqgglbl
config/tourlinq-config.xml Add plugin, factory, hotel.online.supplier property
config/entities/hotel-entities.xml Disable Amadeus factories, add GoGlobal factories
config/api-roles.properties Add 4 missing hotel endpoints
tqapi/.../HotelApi.java Add searchMode routing, refactor to use supplier registry
tqapi/.../TripMakerApi.java Refactor searchAccommodations() to use supplier registry
tqapp/.../HotelSearchFacade.java Refactor to use OnlineHotelSupplierI

Disabled (Not Deleted)

File Action
Amadeus hotel entities (5 files in tqamds/) Retained, factory disabled in config
Amadeus hotel services (2 files in tqamds/) Retained, not called
Amadeus hotel tests (2 files in tqamds/) Retained, can be skipped

Verification

  1. ./gradlew build succeeds with new module
  2. goglobal schema populated with static data
  3. hotel/searchOffers with searchMode=online -> GoGlobal results
  4. hotel/searchOffers with searchMode=contracted -> NTS results
  5. hotel/searchByName -> results from goglobal.hotel cache
  6. hotel/getByCity -> results from goglobal.hotel cache
  7. TripMaker searchAccommodations() works with GoGlobal
  8. Booking lifecycle: search -> valuate -> book -> status -> cancel
  9. Static data refresh runs on schedule
  10. Amadeus flight functionality unaffected

GoGlobal API v3.16.8 — Supported Parameters

Operation 11: Availability Search (HOTEL_SEARCH_REQUEST v2.4)

Request parameters: CityCode, HotelId, ArrivalDate, Nights, Stars, Rooms (multi-room with per-room Adults/ChildCount/ChildAge), Nationality, Currency, MaxHotels, MaxOffers, ExactDestination, IncludeGeo, ReturnTaxData, IncludeCommission, ResponseFormat=JSON

Response fields: HotelCode, HotelName, Category, Address, CityId, CountryId, Location, Latitude, Longitude, Thumbnail, HotelImage, BestSellerRank; per-offer: HotelSearchCode, TotalPrice, Currency, CxlDeadLine, NonRef, Rooms, RoomBasis, Category, Availability, Remark, Special, Preferred, TotalTax, RoomRate, CommPercent, CommValue, CancellationPolicies, Fee, Tax

Operation 9: Valuation (BOOKING_VALUATION_REQUEST v2.0)

Request parameters: HotelSearchCode, ArrivalDate, ReturnTaxData, Nationality

Operation 2: Booking Insert (BOOKING_INSERT_REQUEST v2.3)

Request parameters: HotelSearchCode, ClientBookingCode, ArrivalDate, Nights, NoAlternativeHotel, Leader (Title/FirstName/LastName), RoomType/Person (per-room guest names with PersonID/Title/FirstName/LastName/Age), Nationality, Email, Phone, ArrivalTime, Remarks, IncludeHotelConfirmation, IncludeCommission

Operation 6: Hotel Info (HOTEL_INFO_REQUEST v2.2)

Request parameters: InfoHotelId, Language