diff --git a/CHANGELOG.md b/CHANGELOG.md index cb217e213..7d8a5dfe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ +# Release 1.1.0 (unreleased) + +* Fare_MasterPricerTravelBoardSearch: added new request options (https://github.com/amabnl/amadeus-ws-client/issues/20): + - Preferred/excluded/... airlines option 'airlineOptions'. + - Itinerary date: support for Date range +/- 1 day. + - Itinerary date: Specify date & time of segment as departure or arrival date & time. + - Itinerary date: deprecated 'date' and 'time' properties, replaced by unified 'dateTime' property. + - Support for flight options such as direct flight, non-stop flight, etc. + - Support for Cabin Mode (Mandatory, Major, Recommended) when specifying a cabin code. + - Support for Fare Options such as Published Fares, Unifares, Electronic/Paper ticketing, ... + - Support for "Price to beat" feature. +* Implemented Ticket_DisplayTST + # Release 1.0.0 (18 September 2016) * PNR_AddMultiElements: support for adding OSI elements to a PNR. +* Implemented Ticket_DeleteTST * Updated docs for 1.0.0 release. * Released version 1: now following [semantic versioning](http://semver.org/). @@ -50,4 +64,4 @@ The library will now also convert `\SoapFault` exceptions to a FATAL result stat # UNSTABLE -The library's API will be unstable until we release the first version. \ No newline at end of file +The library's API will be unstable until we release the first version. diff --git a/docs/list-of-supported-messages.rst b/docs/list-of-supported-messages.rst index adc120995..f9caa1b6f 100644 --- a/docs/list-of-supported-messages.rst +++ b/docs/list-of-supported-messages.rst @@ -27,6 +27,7 @@ This is the list of messages that are at least partially supported at this time: - Air_RetrieveSeatMap - DocIssuance_IssueTicket - Ticket_CreateTSTFromPricing +- Ticket_DisplayTST - Ticket_DeleteTST - Offer_VerifyOffer - Offer_ConfirmAirOffer @@ -54,7 +55,6 @@ On the to-do list / work in progress: - Offer_CreateOffer - MiniRule_GetFromPricing - FOP_CreateFormOfPayment -- Ticket_DisplayTST - Ticket_CreateTSMFromPricing - Media_GetMedia - Service_IntegratedPricing diff --git a/docs/samples.rst b/docs/samples.rst index 0f587f7e0..3790aa727 100644 --- a/docs/samples.rst +++ b/docs/samples.rst @@ -393,7 +393,7 @@ Make a simple Masterpricer availability & fare search: 'departureLocation' => new MPLocation(['city' => 'BRU']), 'arrivalLocation' => new MPLocation(['city' => 'LON']), 'date' => new MPDate([ - 'date' => new \DateTime('2017-01-15T00:00:00+0000', new \DateTimeZone('UTC')) + 'dateTime' => new \DateTime('2017-01-15T00:00:00+0000', new \DateTimeZone('UTC')) ]) ]) ] @@ -401,6 +401,10 @@ Make a simple Masterpricer availability & fare search: $recommendations = $client->fareMasterPricerTravelBoardSearch($opt); + +`More examples of MasterPricer messages `_ + + ----------------------------- Fare_PricePNRWithBookingClass ----------------------------- @@ -734,7 +738,7 @@ Delete the TST with number 2: $deleteTstResult = $client->ticketDeleteTST( new TicketDeleteTstOptions([ 'deleteMode' => TicketDeleteTstOptions::DELETE_MODE_SELECTIVE, - 'tstNumber' => 1 + 'tstNumber' => 2 ]) ); @@ -743,8 +747,30 @@ Delete the TST with number 2: Ticket_DisplayTST ----------------- -View the TST's of a PNR: +View all TST's of a PNR: + +.. code-block:: php + + use Amadeus\Client\RequestOptions\TicketDisplayTstOptions; + $deleteTstResult = $client->ticketDisplayTST( + new TicketDisplayTstOptions([ + 'displayMode' => TicketDisplayTstOptions::MODE_ALL + ]) + ); + +Display TST number 2: + +.. code-block:: php + + use Amadeus\Client\RequestOptions\TicketDisplayTstOptions; + + $deleteTstResult = $client->ticketDisplayTST( + new TicketDisplayTstOptions([ + 'displayMode' => TicketDisplayTstOptions::MODE_SELECTIVE, + 'tstNumbers' => [2] + ]) + ); *********** DocIssuance diff --git a/docs/samples/masterpricertravelboard.rst b/docs/samples/masterpricertravelboard.rst new file mode 100644 index 000000000..bc16d54d1 --- /dev/null +++ b/docs/samples/masterpricertravelboard.rst @@ -0,0 +1,341 @@ +=========================================== +Fare_MasterPricerTravelBoardSearch examples +=========================================== + +Brussels - Madrid return flight with 2 adults and 1 child. +Outbound flight 5 (or +/- 1 day) March 2017 at 10:00 (+/- 5 hours). +Inbound flight 12 (or + 1 day) March 2017 at 18:00 (+/- 5 hours). +Maximum 30 recommendations: + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 3, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 2 + ]), + new MPPassenger([ + 'type' => MPPassenger::TYPE_CHILD, + 'count' => 1 + ]), + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'MAD']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-03-05T10:00:00+0000', new \DateTimeZone('UTC')), + 'timeWindow' => 5, + 'rangeMode' => MPDate::RANGEMODE_MINUS_PLUS, + 'range' => 1 + ]) + ]), + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'MAD']), + 'arrivalLocation' => new MPLocation(['city' => 'BRU']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-03-12T18:00:00+0000', new \DateTimeZone('UTC')), + 'timeWindow' => 5, + 'rangeMode' => MPDate::RANGEMODE_PLUS, + 'range' => 1 + ]) + ]) + ] + ]); + + +Brussels - Lisbon one-way flight on 15 January 2017 - only direct & non-stop flights: + +Note that the :code:`dateTime` property of the requested flight has the time part set to 00:00:00 - the result will be that the message will only send a requested date, and will not specify a time. If you specify a time which is different from 00:00:00, a time will be specified as well. + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 200, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'LIS']), + 'date' => new MPDate(['dateTime' => new \DateTime('2017-01-15T00:00:00+0000', new \DateTimeZone('UTC'))]) + ]) + ], + 'requestedFlightTypes' => [ + FareMasterPricerTbSearch::FLIGHTTYPE_DIRECT, + FareMasterPricerTbSearch::FLIGHTTYPE_NONSTOP + ] + ]); + + +London - New York return flight with mandatory Cabin class Business: + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 50, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'LON']), + 'arrivalLocation' => new MPLocation(['city' => 'NYC']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-01-15T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]), + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'NYC']), + 'arrivalLocation' => new MPLocation(['city' => 'LON']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-01-27T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'cabinClass' => FareMasterPricerTbSearch::CABIN_BUSINESS, + 'cabinOption' => FareMasterPricerTbSearch::CABINOPT_MANDATORY + ]); + +Brussels - London with preferred airlines BA or SN: + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'LON']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-01-15T14:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'airlineOptions' => [ + FareMasterPricerTbSearch::AIRLINEOPT_PREFERRED => ['BA', 'SN'] + ] + ]); + + $message = new MasterPricerTravelBoardSearch($opt); + +Multi-city request: Brussels or Charleroi to Valencia or Alicante for 2 passengers - exclude airline Vueling: + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 2, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 2 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation([ + 'multiCity' => ['BRU', 'CRL'] + ]), + 'arrivalLocation' => new MPLocation([ + 'multiCity' => ['VLC', 'ALC'] + ]), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-05-30T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'airlineOptions' => [ + FareMasterPricerTbSearch::AIRLINEOPT_EXCLUDED => ['VY'] + ] + ]); + + $message = new MasterPricerTravelBoardSearch($opt); + + +Do a ticketability pre-check on recommendations: + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'PAR']), + 'arrivalLocation' => new MPLocation(['city' => 'MUC']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-04-18T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]), + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'MUC']), + 'arrivalLocation' => new MPLocation(['city' => 'PAR']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-04-22T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'doTicketabilityPreCheck' => true + ]); + +Paris to Seattle, _arrive_ in Seattle on 13 June 2017 at 18:30 (+/- 6 hours) + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'PAR']), + 'arrivalLocation' => new MPLocation(['city' => 'SEA']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-06-13T18:30:00+0000', new \DateTimeZone('UTC')), + 'timeWindow' => 6, + 'isDeparture' => false + ]) + ]) + ] + ]); + +Simple flight, request published fares, unifares and corporate unifares (with a corporate number): + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BER']), + 'arrivalLocation' => new MPLocation(['city' => 'MOW']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-05-01T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'flightOptions' => [ + FareMasterPricerTbSearch::FLIGHTOPT_PUBLISHED, + FareMasterPricerTbSearch::FLIGHTOPT_UNIFARES, + FareMasterPricerTbSearch::FLIGHTOPT_CORPORATE_UNIFARES, + ], + 'corporateCodesUnifares' => ['123456'] + ]); + +Simple flight, set "price to beat" at 500 EURO: Recommendations returned must be cheaper than 500 EURO. + +.. code-block:: php + + use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; + use Amadeus\Client\RequestOptions\Fare\MPItinerary; + use Amadeus\Client\RequestOptions\Fare\MPLocation; + use Amadeus\Client\RequestOptionsFare\MPPassenger; + use Amadeus\Client\RequestOptionsFare\MPDate; + + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BER']), + 'arrivalLocation' => new MPLocation(['city' => 'MOW']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-05-01T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'priceToBeat' => 500, + 'priceToBeatCurrency' => 'EUR', + ]); \ No newline at end of file diff --git a/src/Amadeus/Client.php b/src/Amadeus/Client.php index 8b934d911..2eb725547 100644 --- a/src/Amadeus/Client.php +++ b/src/Amadeus/Client.php @@ -62,7 +62,7 @@ class Client * * @var string */ - const VERSION = "1.0.0"; + const VERSION = "1.1.0-dev"; /** * An identifier string for the library (to be used in Received From entries) @@ -672,6 +672,20 @@ public function ticketDeleteTST(RequestOptions\TicketDeleteTstOptions $options, return $this->callMessage($msgName, $options, $messageOptions); } + /** + * Ticket_DisplayTST + * + * @param RequestOptions\TicketDisplayTstOptions $options + * @param array $messageOptions (OPTIONAL) + * @return Result + */ + public function ticketDisplayTST(RequestOptions\TicketDisplayTstOptions $options, $messageOptions = []) + { + $msgName = 'Ticket_DisplayTST'; + + return $this->callMessage($msgName, $options, $messageOptions); + } + /** * DocIssuance_IssueTicket * diff --git a/src/Amadeus/Client/RequestCreator/Base.php b/src/Amadeus/Client/RequestCreator/Base.php index 9e0a3776a..bf152d987 100644 --- a/src/Amadeus/Client/RequestCreator/Base.php +++ b/src/Amadeus/Client/RequestCreator/Base.php @@ -57,6 +57,7 @@ use Amadeus\Client\RequestOptions\SecurityAuthenticateOptions; use Amadeus\Client\RequestOptions\TicketCreateTstFromPricingOptions; use Amadeus\Client\RequestOptions\TicketDeleteTstOptions; +use Amadeus\Client\RequestOptions\TicketDisplayTstOptions; use Amadeus\Client\Struct; /** @@ -456,6 +457,17 @@ protected function createTicketDeleteTST(TicketDeleteTstOptions $params) return new Struct\Ticket\DeleteTST($params); } + /** + * Ticket_DisplayTST + * + * @param TicketDisplayTstOptions $params + * @return Struct\Ticket\DisplayTST + */ + protected function createTicketDisplayTST(TicketDisplayTstOptions $params) + { + return new Struct\Ticket\DisplayTST($params); + } + /** * DocIssuance_IssueTicket * diff --git a/src/Amadeus/Client/RequestOptions/Fare/MPDate.php b/src/Amadeus/Client/RequestOptions/Fare/MPDate.php index 654fde2d0..f7ce8d4e7 100644 --- a/src/Amadeus/Client/RequestOptions/Fare/MPDate.php +++ b/src/Amadeus/Client/RequestOptions/Fare/MPDate.php @@ -32,22 +32,41 @@ */ class MPDate extends LoadParamsFromArray { + const RANGEMODE_MINUS_PLUS = "C"; + const RANGEMODE_MINUS = "M"; + const RANGEMODE_PLUS = "P"; + + /** + * Departure or arrival date & time. + * + * The time part is only used if it is not "00:00" when converted to string. + * + * @var \DateTime + */ + public $dateTime; + + /** * Departure or arrival date * * We only use the date portion! * + * @deprecated use dateTime instead. When using both, dateTime property has priority * @var \DateTime */ public $date; + /** * Departure or arrival time * * We only use the time portion! * + * @deprecated use dateTime instead. When using both, dateTime property has priority * @var \DateTime */ + public $time; + /** * Whether date & time are for specifying departure * @@ -56,11 +75,28 @@ class MPDate extends LoadParamsFromArray * * @var bool */ - public $isDeparture; + public $isDeparture = true; + /** * Window (number of hours) before/after specified time. * * @var int */ public $timeWindow; + + /** + * If you want a range of dates, provide the range mode here + * + * self::RANGEMODE_* + * + * @var string + */ + public $rangeMode; + + /** + * Date range expressed in days + * + * @var int + */ + public $range; } diff --git a/src/Amadeus/Client/RequestOptions/FareMasterPricerTbSearch.php b/src/Amadeus/Client/RequestOptions/FareMasterPricerTbSearch.php index c99a761fd..84e385182 100644 --- a/src/Amadeus/Client/RequestOptions/FareMasterPricerTbSearch.php +++ b/src/Amadeus/Client/RequestOptions/FareMasterPricerTbSearch.php @@ -40,54 +40,150 @@ class FareMasterPricerTbSearch extends Base const CABIN_BUSINESS = "C"; const CABIN_FIRST_SUPERSONIC = "F"; + const AIRLINEOPT_PREFERRED = "F"; + const AIRLINEOPT_MANDATORY = "M"; + const AIRLINEOPT_NIGHT_CLASS = "N"; + const AIRLINEOPT_FORCE_FULLAIRLINE_RECOMMENDATION = "O"; + const AIRLINEOPT_CARRIERS_LIST_BYPASS_BSP_CHECKS = "T"; + const AIRLINEOPT_MANDATORY_VALIDATING_CARRIER = "V"; + const AIRLINEOPT_EXCLUDED_VALIDATING_CARRIER = "W"; + const AIRLINEOPT_EXCLUDED = "X"; + + const FLIGHTOPT_PUBLISHED = "RP"; + const FLIGHTOPT_UNIFARES = "RU"; + const FLIGHTOPT_CORPORATE_UNIFARES = "RW"; + const FLIGHTOPT_NO_RESTRICTION = "NR"; + const FLIGHTOPT_REFUNDABLE = "RF"; + const FLIGHTOPT_NO_ADVANCE_PURCHASE = "NAP"; + const FLIGHTOPT_NO_PENALTIES = "NPE"; + const FLIGHTOPT_NO_LOWCOST = "XLC"; + const FLIGHTOPT_ELECTRONIC_TICKET = "ET"; + const FLIGHTOPT_PAPER_TICKET = "PT"; + const FLIGHTOPT_ELECTRONIC_PAPER_TICKET = "EP"; + const FLIGHTOPT_FORCE_NEUTRAL_FARE_SEARCH = "NPF"; + const FLIGHTOPT_NO_SLICE_AND_DICE = "NSD"; + const FLIGHTOPT_DISPLAY_MIN_MAX_STAY = "MST"; + + /** + * Major cabin + */ + const CABINOPT_MAJOR = "MC"; + /** + * Mandatory cabin for all segments + */ + const CABINOPT_MANDATORY = "MD"; + /** + * Recommended cabin to be used at least one segment + */ + const CABINOPT_RECOMMENDED = "RC"; + /** * @var int */ public $nrOfRequestedPassengers; + /** + * Maximum number of recommendations requested + * * @var int */ public $nrOfRequestedResults; /** + * Whether to perform a ticketability pre-check + * * @var bool */ - public $doTicketabilityPreCheck = true; + public $doTicketabilityPreCheck = false; /** - * List of airline codes that the search is restricted to. + * List of airline options. + * + * Keys are the option to be used (self::AIRLINEOPT_*), values are the airline codes: + * + * e.g. + * 'airlineOptions' => [ + * self::AIRLINEOPT_PREFERRED => [ + * 'LH', + * 'BA' + * ] + * ] * - * e.g. ['LH', 'BA'] * @var array */ - public $mandatoryAirlines = []; + public $airlineOptions = []; /** * Itinerary-level flight options * * Choose from self::FLIGHTTYPE_* * - * @var array + * @var string[] + */ + public $requestedFlightTypes = []; + + /** + * Provide extra fare & flight options + * + * self::FLIGHTOPT_* + * + * @var string[] */ - public $requestedFlightOptions = []; + public $flightOptions = []; /** + * Corporate numbers for returning Corporate Unifares + * + * In combination with fareType self::FARETYPE::CORPORATE_UNIFARES + * + * @var string[] + */ + public $corporateCodesUnifares = []; + + /** + * Cabin class requested for the entire itinerary + * * self::CABIN_* * - * @var + * @var string */ public $cabinClass; + + /** + * Cabin option - how to interpret the cabin class + * + * self::CABINOPT_* + * + * @var string[] + */ + public $cabinOption; + /** * Passenger info * * @var Fare\MPPassenger[] */ public $passengers = []; + /** * Requested flight itinerary * * @var Fare\MPItinerary[] */ public $itinerary = []; + + /** + * The maximum price to be returned in the recommendations + * + * @var int|null + */ + public $priceToBeat; + + /** + * Currency of the maximum price to beat + * + * @var string|null + */ + public $priceToBeatCurrency; } diff --git a/src/Amadeus/Client/RequestOptions/TicketDisplayTstOptions.php b/src/Amadeus/Client/RequestOptions/TicketDisplayTstOptions.php new file mode 100644 index 000000000..0d7866029 --- /dev/null +++ b/src/Amadeus/Client/RequestOptions/TicketDisplayTstOptions.php @@ -0,0 +1,80 @@ + + */ +class TicketDisplayTstOptions extends Base +{ + const MODE_ALL = "ALL"; + + const MODE_SELECTIVE = "SEL"; + + /** + * Display all TST's or display selectively? + * + * self::MODE_* + * + * @var string + */ + public $displayMode; + + /** + * TST numbers to retrieve + * + * @var int[] + */ + public $tstNumbers = []; + + /** + * Segment Tattoo numbers for which to retrieve TST's + * + * @var int[] + */ + public $segments = []; + + /** + * Passenger Tattoo numbers for who to retrieve TST's + * + * @var int[] + */ + public $passengers = []; + + /** + * Scrolling view - display TST's starting from this number + * + * @var int + */ + public $scrollingStart; + + /** + * Scrolling view - how many TST's to display + * + * @var int + */ + public $scrollingCount; +} diff --git a/src/Amadeus/Client/ResponseHandler/Base.php b/src/Amadeus/Client/ResponseHandler/Base.php index 2887525ec..ed43439c8 100644 --- a/src/Amadeus/Client/ResponseHandler/Base.php +++ b/src/Amadeus/Client/ResponseHandler/Base.php @@ -591,6 +591,15 @@ protected function analyzeDocIssuanceIssueTicketResponse($response) return $this->analyzeSimpleResponseErrorCodeAndMessageStatusCode($response); } + /** + * @param SendResult $response Ticket_DeleteTST result + * @return Result + */ + protected function analyzeTicketDisplayTSTResponse($response) + { + return $this->analyzeSimpleResponseErrorCodeAndMessage($response); + } + /** * @param SendResult $response Ticket_DeleteTST result * @return Result diff --git a/src/Amadeus/Client/Struct/BaseWsMessage.php b/src/Amadeus/Client/Struct/BaseWsMessage.php index bf28efe73..6ed3a46c0 100644 --- a/src/Amadeus/Client/Struct/BaseWsMessage.php +++ b/src/Amadeus/Client/Struct/BaseWsMessage.php @@ -30,4 +30,25 @@ */ class BaseWsMessage { + /** + * Check if any parameter to the current function is not empty + * + * @param mixed + * @return boolean true if at least 1 parameter is not empty + */ + protected function checkAnyNotEmpty() + { + $foundNotEmpty = false; + + $args = func_get_args(); + + foreach ($args as $arg) { + if (!empty($arg)) { + $foundNotEmpty = true; + break; + } + } + + return $foundNotEmpty; + } } diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/CabinId.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/CabinId.php index 7fd916086..d68dd482b 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/CabinId.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/CabinId.php @@ -35,6 +35,19 @@ class CabinId const CABIN_BUSINESS = "C"; const CABIN_FIRST_SUPERSONIC = "F"; + /** + * Major cabin + */ + const CABINOPT_MAJOR = "MC"; + /** + * Mandatory cabin for all segments + */ + const CABINOPT_MANDATORY = "MD"; + /** + * Recommended cabin to be used at least one segment + */ + const CABINOPT_RECOMMENDED = "RC"; + /** * MC Major cabin * MD Mandatory cabin for all segments @@ -55,9 +68,11 @@ class CabinId * CabinId constructor. * * @param string $cabinCode self::CABIN_* + * @param string $cabinOption self::CABINOPT_* */ - public function __construct($cabinCode) + public function __construct($cabinCode, $cabinOption = null) { $this->cabin = $cabinCode; + $this->cabinQualifier = $cabinOption; } } diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/CompanyIdentity.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/CompanyIdentity.php new file mode 100644 index 000000000..cd746b18c --- /dev/null +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/CompanyIdentity.php @@ -0,0 +1,73 @@ + + */ +class CompanyIdentity +{ + const QUAL_PREFERRED = "F"; + const QUAL_MANDATORY = "M"; + const QUAL_NIGHT_CLASS = "N"; + const QUAL_FORCE_FULLAIRLINE_RECOMMENDATION = "O"; + /** + * @deprecated + */ + const QUAL_POLLED = "P"; + /** + * @deprecated + */ + const QUAL_FARE_FAMILY_REPARTITION = "R"; + const QUAL_CARRIERS_LIST_BYPASS_BSP_CHECKS = "T"; + const QUAL_MANDATORY_VALIDATING_CARRIER = "V"; + const QUAL_EXCLUDED_VALIDATING_CARRIER = "W"; + const QUAL_EXCLUDED = "X"; + + /** + * self::QUAL_* + * + * @var string + */ + public $carrierQualifier; + + /** + * @var string[] + */ + public $carrierId = []; + + /** + * CompanyIdentity constructor. + * + * @param string $carrierQualifier self::QUAL_* + * @param \string[] $carrierId + */ + public function __construct($carrierQualifier, array $carrierId) + { + $this->carrierQualifier = $carrierQualifier; + $this->carrierId = $carrierId; + } +} diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/CorporateId.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/CorporateId.php index de615d146..65f69cf07 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/CorporateId.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/CorporateId.php @@ -30,7 +30,22 @@ */ class CorporateId { + /** + * @var string + */ public $corporateQualifier; + /** + * @var string[] + */ + public $identity = []; - public $identity; + /** + * CorporateId constructor. + * + * @param \string[] $identity + */ + public function __construct(array $identity) + { + $this->identity = $identity; + } } diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/FareFamilies.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/FareFamilies.php new file mode 100644 index 000000000..59d5c9eeb --- /dev/null +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/FareFamilies.php @@ -0,0 +1,40 @@ + + */ +class FareFamilies +{ + public $familyInformation; + + public $familyCriteria; + + public $fareFamilySegment = []; + + public $otherPossibleCriteria = []; +} diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/FareOptions.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/FareOptions.php index 21a97bf60..f6852e576 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/FareOptions.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/FareOptions.php @@ -54,4 +54,30 @@ class FareOptions public $frequentTravellerInfo; public $monetaryCabinInfo; + + /** + * FareOptions constructor. + * + * @param array $flightOptions List of flight / fare options + * @param array $corpCodesUniFares list of Corporate codes for Corporate Unifares + * @param bool $tickPreCheck Do Ticketability pre-check? + */ + public function __construct(array $flightOptions, array $corpCodesUniFares, $tickPreCheck) + { + $this->pricingTickInfo = new PricingTickInfo(); + $this->pricingTickInfo->pricingTicketing = new PricingTicketing(); + + if ($tickPreCheck === true) { + $this->pricingTickInfo->pricingTicketing->priceType[] = PricingTicketing::PRICETYPE_TICKETABILITY_PRECHECK; + } + + foreach ($flightOptions as $flightOption) { + $this->pricingTickInfo->pricingTicketing->priceType[] = $flightOption; + + if ($flightOption === PricingTicketing::PRICETYPE_CORPORATE_UNIFARES) { + $this->corporate = new Corporate(); + $this->corporate->corporateId[] = new CorporateId($corpCodesUniFares); + } + } + } } diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/FirstDateTimeDetail.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/FirstDateTimeDetail.php index a9453c36b..ae398d887 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/FirstDateTimeDetail.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/FirstDateTimeDetail.php @@ -42,18 +42,21 @@ class FirstDateTimeDetail * @var string */ public $timeQualifier; + /** * DDMMYY * * @var string */ public $date; + /** * HHMM * * @var string */ public $time; + /** * Nr of Hours * diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/FlightDetail.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/FlightDetail.php new file mode 100644 index 000000000..ab8cf4b92 --- /dev/null +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/FlightDetail.php @@ -0,0 +1,56 @@ + + */ +class FlightDetail +{ + const FLIGHT_TYPE_CONNECTING = "C"; + const FLIGHT_TYPE_DIRECT = "D"; + const FLIGHT_TYPE_DISABLE_NEGO_SPACE = "DN"; + const FLIGHT_TYPE_NON_STOP = "N"; + const FLIGHT_TYPE_RETURN_CHEAPEST_ONLINE = "OL"; + const FLIGHT_TYPE_OVERNIGHT_NOT_ALLOWED = "OV"; + + /** + * self::FLIGHT_TYPE_* + * + * @var string[] + */ + public $flightType = []; + + /** + * FlightDetail constructor. + * + * @param \string[] $flightType + */ + public function __construct(array $flightType = []) + { + $this->flightType = $flightType; + } +} diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/MoneyInfo.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/MoneyInfo.php new file mode 100644 index 000000000..fc7da82d6 --- /dev/null +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/MoneyInfo.php @@ -0,0 +1,64 @@ + + */ +class MoneyInfo +{ + /** + * @var string + */ + public $qualifier; + + /** + * @var int + */ + public $amount; + + /** + * @var null|string + */ + public $currency; + + /** + * @var string + */ + public $locationId; + + /** + * MoneyInfo constructor. + * + * @param int $amount + * @param string|null $currency + */ + public function __construct($amount, $currency = null) + { + $this->amount = $amount; + $this->currency = $currency; + } +} diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/NumberOfUnit.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/NumberOfUnit.php index 7a41e1d6b..c20bddd82 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/NumberOfUnit.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/NumberOfUnit.php @@ -36,12 +36,22 @@ class NumberOfUnit public $unitNumberDetail = []; /** - * @param int|null $mainUnitNumber - * @param string|null $mainUnitType + * @param int|null $requestedPax + * @param int|null $requestedResults */ - public function __construct($mainUnitNumber = null, $mainUnitType = null) + public function __construct($requestedPax, $requestedResults) { - $this->unitNumberDetail[] = - new UnitNumberDetail($mainUnitNumber, $mainUnitType); + if (is_int($requestedPax)) { + $this->unitNumberDetail[] = new UnitNumberDetail( + $requestedPax, + UnitNumberDetail::TYPE_PASS + ); + } + if (is_int($requestedResults)) { + $this->unitNumberDetail[] = new UnitNumberDetail( + $requestedResults, + UnitNumberDetail::TYPE_RESULTS + ); + } } } diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/PriceToBeat.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/PriceToBeat.php new file mode 100644 index 000000000..5234a0f43 --- /dev/null +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/PriceToBeat.php @@ -0,0 +1,53 @@ + + */ +class PriceToBeat +{ + /** + * @var MoneyInfo + */ + public $moneyInfo; + + /** + * @var MoneyInfo[] + */ + public $additionalMoneyInfo = []; + + /** + * PriceToBeat constructor. + * + * @param int $amount + * @param string|null $currency + */ + public function __construct($amount, $currency = null) + { + $this->moneyInfo = new MoneyInfo($amount, $currency); + } +} diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/PricingTicketing.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/PricingTicketing.php index 3d138aa93..ae6729b81 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/PricingTicketing.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/PricingTicketing.php @@ -32,8 +32,19 @@ class PricingTicketing { const PRICETYPE_TICKETABILITY_PRECHECK = 'TAC'; const PRICETYPE_UNIFARES = 'RU'; - const PRICETYPE_PUBLICFARES = 'RP'; + const PRICETYPE_PUBLISHEDFARES = 'RP'; const PRICETYPE_CORPORATE_UNIFARES = 'RW'; + const PRICETYPE_NO_RESTRICTION = "NR"; + const PRICETYPE_REFUNDABLE = "RF"; + const PRICETYPE_NO_ADVANCE_PURCHASE = "NAP"; + const PRICETYPE_NO_PENALTIES = "NPE"; + const PRICETYPE_NO_LOWCOST = "XLC"; + const PRICETYPE_ELECTRONIC_TICKET = "ET"; + const PRICETYPE_PAPER_TICKET = "PT"; + const PRICETYPE_ELECTRONIC_PAPER_TICKET = "EP"; + const PRICETYPE_FORCE_NEUTRAL_FARE_SEARCH = "NPF"; + const PRICETYPE_NO_SLICE_AND_DICE = "NSD"; + const PRICETYPE_DISPLAY_MIN_MAX_STAY = "MST"; /** * self::PRICETYPE_* diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/RangeOfDate.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/RangeOfDate.php index f76b0adb9..0d6ad5817 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/RangeOfDate.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/RangeOfDate.php @@ -30,9 +30,36 @@ */ class RangeOfDate { + const RANGEMODE_MINUS_PLUS = "C"; + const RANGEMODE_MINUS = "M"; + const RANGEMODE_PLUS = "P"; + + /** + * self::RANGEMODE_* + * + * @var string + */ public $rangeQualifier; + /** + * @var int + */ public $dayInterval; + /** + * @var string + */ public $timeAtdestination; + + /** + * RangeOfDate constructor. + * + * @param string $rangeMode self::RANGEMODE_* + * @param int $range + */ + public function __construct($rangeMode, $range) + { + $this->dayInterval = $range; + $this->rangeQualifier = $rangeMode; + } } diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/TimeDetails.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/TimeDetails.php index 2f342c247..70f42cacf 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/TimeDetails.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/TimeDetails.php @@ -52,13 +52,66 @@ class TimeDetails */ public function __construct(MPDate $theDate) { - $this->firstDateTimeDetail = new FirstDateTimeDetail($theDate->date->format('dmy')); + $this->firstDateTimeDetail = new FirstDateTimeDetail( + $this->makeDateString($theDate->dateTime, $theDate->date) + ); - if ($theDate->time instanceof \DateTime) { - $this->firstDateTimeDetail->time = $theDate->time->format('Hi'); + $timeString = $this->makeTimeString($theDate->dateTime, $theDate->time); + if ($timeString !== '0000') { + $this->firstDateTimeDetail->time = $timeString; } + if (is_int($theDate->timeWindow)) { $this->firstDateTimeDetail->timeWindow = $theDate->timeWindow; } + + if ($theDate->isDeparture) { + $this->firstDateTimeDetail->timeQualifier = FirstDateTimeDetail::TIMEQUAL_DEPART_FROM; + } else { + $this->firstDateTimeDetail->timeQualifier = FirstDateTimeDetail::TIMEQUAL_ARRIVAL_BY; + } + + if (!is_null($theDate->range) && !is_null($theDate->rangeMode)) { + $this->rangeOfDate = new RangeOfDate( + $theDate->rangeMode, + $theDate->range + ); + } + } + + /** + * @param \DateTime|null $dateTime + * @param \DateTime|null $date + * @return string + */ + protected function makeDateString($dateTime, $date) + { + $dateStr = '000000'; + + if ($dateTime instanceof \DateTime) { + $dateStr = $dateTime->format('dmy'); + } elseif ($date instanceof \DateTime) { + $dateStr = $date->format('dmy'); + } + + return $dateStr; + } + + /** + * @param \DateTime|null $dateTime + * @param \DateTime|null $time + * @return string + */ + protected function makeTimeString($dateTime, $time) + { + $timeStr = '0000'; + + if ($dateTime instanceof \DateTime) { + $timeStr = $dateTime->format('Hi'); + } elseif ($time instanceof \DateTime) { + $timeStr = $time->format('Hi'); + } + + return $timeStr; } } diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/TravelFlightInfo.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/TravelFlightInfo.php index a4b420d8e..4e7580227 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/TravelFlightInfo.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/TravelFlightInfo.php @@ -34,8 +34,14 @@ class TravelFlightInfo */ public $cabinId; + /** + * @var CompanyIdentity[] + */ public $companyIdentity = []; + /** + * @var FlightDetail + */ public $flightDetail; public $inclusionDetail = []; @@ -47,12 +53,28 @@ class TravelFlightInfo /** * TravelFlightInfo constructor. * - * @param string|null $cabinCode + * @param string|null $cabinCode CabinId::CABIN_* + * @param string|null $cabinOption CabinId::CABINOPT_* + * @param string[]|null $flightTypes + * @param array|null $airlineOptions */ - public function __construct($cabinCode = null) + public function __construct($cabinCode = null, $cabinOption = null, $flightTypes = null, $airlineOptions = null) { - if (!is_null($cabinCode)) { - $this->cabinId = new CabinId($cabinCode); + if (!is_null($cabinCode) || !is_null($cabinOption)) { + $this->cabinId = new CabinId($cabinCode, $cabinOption); + } + + if (is_array($flightTypes)) { + $this->flightDetail = new FlightDetail($flightTypes); + } + + if (!empty($airlineOptions)) { + foreach ($airlineOptions as $qualifier => $airlines) { + $this->companyIdentity[] = new CompanyIdentity( + $qualifier, + $airlines + ); + } } } } diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricer/UnitNumberDetail.php b/src/Amadeus/Client/Struct/Fare/MasterPricer/UnitNumberDetail.php index a46ab9da6..45e82b92f 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricer/UnitNumberDetail.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricer/UnitNumberDetail.php @@ -37,6 +37,7 @@ class UnitNumberDetail * @var int */ public $numberOfUnits; + /** * * Possible values: diff --git a/src/Amadeus/Client/Struct/Fare/MasterPricerTravelBoardSearch.php b/src/Amadeus/Client/Struct/Fare/MasterPricerTravelBoardSearch.php index 47415e7c1..8c1b9fec2 100644 --- a/src/Amadeus/Client/Struct/Fare/MasterPricerTravelBoardSearch.php +++ b/src/Amadeus/Client/Struct/Fare/MasterPricerTravelBoardSearch.php @@ -65,15 +65,19 @@ class MasterPricerTravelBoardSearch extends BaseWsMessage */ public $solutionFamily; /** - * @var mixed + * @var mixed[] + */ + public $passengerInfoGrp = []; + /** + * @var MasterPricer\FareFamilies[] */ - public $fareFamilies; + public $fareFamilies = []; /** * @var MasterPricer\FareOptions */ public $fareOptions; /** - * @var mixed + * @var MasterPricer\PriceToBeat */ public $priceToBeat; /** @@ -84,8 +88,14 @@ class MasterPricerTravelBoardSearch extends BaseWsMessage * @var MasterPricer\TravelFlightInfo */ public $travelFlightInfo; - + /** + * @var array + */ public $valueSearch = []; + /** + * @var array + */ + public $buckets = []; /** * Itinerary * @@ -128,11 +138,13 @@ protected function loadOptions(FareMasterPricerTbSearch $options) { $this->loadNrOfPaxAndResults($options); - if ($options->doTicketabilityPreCheck === true) { - $this->fareOptions = new MasterPricer\FareOptions(); - $this->fareOptions->pricingTickInfo = new MasterPricer\PricingTickInfo(); - $this->fareOptions->pricingTickInfo->pricingTicketing = new MasterPricer\PricingTicketing( - MasterPricer\PricingTicketing::PRICETYPE_TICKETABILITY_PRECHECK + if ($options->doTicketabilityPreCheck === true || + $this->checkAnyNotEmpty($options->corporateCodesUnifares, $options->flightOptions) + ) { + $this->fareOptions = new MasterPricer\FareOptions( + $options->flightOptions, + $options->corporateCodesUnifares, + $options->doTicketabilityPreCheck ); } @@ -147,8 +159,25 @@ protected function loadOptions(FareMasterPricerTbSearch $options) $this->loadItinerary($itinerary, $segmentCounter); } - if (!empty($options->cabinClass)) { - $this->travelFlightInfo = new MasterPricer\TravelFlightInfo($options->cabinClass); + if ($this->checkAnyNotEmpty( + $options->cabinClass, + $options->cabinOption, + $options->requestedFlightTypes, + $options->airlineOptions + )) { + $this->travelFlightInfo = new MasterPricer\TravelFlightInfo( + $options->cabinClass, + $options->cabinOption, + $options->requestedFlightTypes, + $options->airlineOptions + ); + } + + if (!empty($options->priceToBeat)) { + $this->priceToBeat = new MasterPricer\PriceToBeat( + $options->priceToBeat, + $options->priceToBeatCurrency + ); } } @@ -190,18 +219,22 @@ protected function loadPassenger($passenger, &$counter, &$infantCounter) } /** - * @param MPItinerary $itinerary + * @param MPItinerary $itineraryOptions * @param int $counter BYREF */ - protected function loadItinerary($itinerary, &$counter) + protected function loadItinerary($itineraryOptions, &$counter) { - $tmpItin = new MasterPricer\Itinerary($counter); + $tmpItinerary = new MasterPricer\Itinerary($counter); - $tmpItin->departureLocalization = new MasterPricer\DepartureLocalization($itinerary->departureLocation); - $tmpItin->arrivalLocalization = new MasterPricer\ArrivalLocalization($itinerary->arrivalLocation); - $tmpItin->timeDetails = new MasterPricer\TimeDetails($itinerary->date); + $tmpItinerary->departureLocalization = new MasterPricer\DepartureLocalization( + $itineraryOptions->departureLocation + ); + $tmpItinerary->arrivalLocalization = new MasterPricer\ArrivalLocalization( + $itineraryOptions->arrivalLocation + ); + $tmpItinerary->timeDetails = new MasterPricer\TimeDetails($itineraryOptions->date); - $this->itinerary[] = $tmpItin; + $this->itinerary[] = $tmpItinerary; $counter++; } @@ -213,19 +246,10 @@ protected function loadItinerary($itinerary, &$counter) protected function loadNrOfPaxAndResults(FareMasterPricerTbSearch $options) { if (is_int($options->nrOfRequestedPassengers) || is_int($options->nrOfRequestedResults)) { - $this->numberOfUnit = new MasterPricer\NumberOfUnit(); - if (is_int($options->nrOfRequestedPassengers)) { - $this->numberOfUnit->unitNumberDetail[] = new MasterPricer\UnitNumberDetail( - $options->nrOfRequestedPassengers, - MasterPricer\UnitNumberDetail::TYPE_PASS - ); - } - if (is_int($options->nrOfRequestedResults)) { - $this->numberOfUnit->unitNumberDetail[] = new MasterPricer\UnitNumberDetail( - $options->nrOfRequestedResults, - MasterPricer\UnitNumberDetail::TYPE_RESULTS - ); - } + $this->numberOfUnit = new MasterPricer\NumberOfUnit( + $options->nrOfRequestedPassengers, + $options->nrOfRequestedResults + ); } } } diff --git a/src/Amadeus/Client/Struct/Fare/PricePNRWithBookingClass12.php b/src/Amadeus/Client/Struct/Fare/PricePNRWithBookingClass12.php index 7c141c96b..68c0072bb 100644 --- a/src/Amadeus/Client/Struct/Fare/PricePNRWithBookingClass12.php +++ b/src/Amadeus/Client/Struct/Fare/PricePNRWithBookingClass12.php @@ -106,9 +106,7 @@ public function __construct(FarePricePnrWithBookingClassOptions $options) $this->validatingCarrier = new ValidatingCarrier($options->validatingCarrier); } - if (in_array(AttributeDetails::OVERRIDE_FAREBASIS, $options->overrideOptions) && - !empty($options->pricingsFareBasis) - ) { + if (in_array(AttributeDetails::OVERRIDE_FAREBASIS, $options->overrideOptions) && !empty($options->pricingsFareBasis)) { foreach ($options->pricingsFareBasis as $pricingFareBasis) { $this->pricingFareBase[] = new PricingFareBase($pricingFareBasis); } diff --git a/src/Amadeus/Client/Struct/SalesReports/DisplayQueryReport.php b/src/Amadeus/Client/Struct/SalesReports/DisplayQueryReport.php index 3fda693e3..e5b3f33e1 100644 --- a/src/Amadeus/Client/Struct/SalesReports/DisplayQueryReport.php +++ b/src/Amadeus/Client/Struct/SalesReports/DisplayQueryReport.php @@ -160,7 +160,7 @@ protected function loadRequestOptions($requestOptions) */ protected function loadAgencySource($agencySourceType, $iataNumber, $officeId) { - if (!empty($agencySourceType) || !empty($iataNumber) || !empty($officeId)) { + if ($this->checkAnyNotEmpty($agencySourceType, $iataNumber, $officeId)) { $this->agencyDetails = new AgencyDetails($agencySourceType, $iataNumber, $officeId); } } @@ -182,7 +182,7 @@ protected function loadAgent($agentCode) */ protected function loadTransaction($code, $type, $issueIndicator) { - if (!empty($type) || !empty($code) || !empty($issueIndicator)) { + if ($this->checkAnyNotEmpty($type, $code, $issueIndicator)) { $this->transactionData[] = new TransactionData($type, $code, $issueIndicator); } } @@ -203,7 +203,7 @@ protected function loadValidatingCarrier($validatingCarrier) */ protected function loadDateRange($startDate, $endDate) { - if (!empty($startDate) || !empty($endDate)) { + if ($this->checkAnyNotEmpty($startDate, $endDate)) { $this->salesPeriodDetails = new SalesPeriodDetails($startDate, $endDate); } } @@ -214,7 +214,7 @@ protected function loadDateRange($startDate, $endDate) */ protected function loadDate($type, $date) { - if (!empty($type) || !empty($date)) { + if ($this->checkAnyNotEmpty($type, $date)) { $this->dateDetails = new DateDetails($type, $date); } } @@ -225,7 +225,7 @@ protected function loadDate($type, $date) */ protected function loadCurrency($type, $currency) { - if (!empty($type) || !empty($currency)) { + if ($this->checkAnyNotEmpty($type, $currency)) { $this->currencyInfo = new CurrencyInfo($type, $currency); } } @@ -236,7 +236,7 @@ protected function loadCurrency($type, $currency) */ protected function loadFormOfPayment($type, $vendor) { - if (!empty($type) || !empty($vendor)) { + if ($this->checkAnyNotEmpty($type, $vendor)) { $this->formOfPaymentDetails = new FormOfPaymentDetails($type, $vendor); } } @@ -257,7 +257,7 @@ protected function loadSalesIndicator($indicator) */ protected function loadScrolling($count, $fromItem) { - if (!empty($count) || !empty($fromItem)) { + if ($this->checkAnyNotEmpty($count, $fromItem)) { $this->actionDetails = new ActionDetails($count, $fromItem); } } diff --git a/src/Amadeus/Client/Struct/Ticket/DisplayMode.php b/src/Amadeus/Client/Struct/Ticket/DisplayMode.php new file mode 100644 index 000000000..31b6b9750 --- /dev/null +++ b/src/Amadeus/Client/Struct/Ticket/DisplayMode.php @@ -0,0 +1,47 @@ + + */ +class DisplayMode +{ + /** + * @var AttributeDetails + */ + public $attributeDetails; + + /** + * DisplayMode constructor. + * + * @param string $displayMode + */ + public function __construct($displayMode) + { + $this->attributeDetails = new AttributeDetails($displayMode); + } +} diff --git a/src/Amadeus/Client/Struct/Ticket/DisplayTST.php b/src/Amadeus/Client/Struct/Ticket/DisplayTST.php new file mode 100644 index 000000000..46f0ea657 --- /dev/null +++ b/src/Amadeus/Client/Struct/Ticket/DisplayTST.php @@ -0,0 +1,105 @@ + + */ +class DisplayTST extends BaseWsMessage +{ + /** + * @var DisplayMode + */ + public $displayMode; + + /** + * @var PnrLocatorData + */ + public $pnrLocatorData; + + /** + * @var ScrollingInformation + */ + public $scrollingInformation; + + /** + * @var TstReference[] + */ + public $tstReference = []; + + /** + * @var PsaInformation + */ + public $psaInformation; + + /** + * DisplayTST constructor. + * + * @param TicketDisplayTstOptions $params + */ + public function __construct(TicketDisplayTstOptions $params) + { + $this->displayMode = new DisplayMode($params->displayMode); + + if ($params->displayMode === AttributeDetails::MODE_SELECTIVE) { + $this->loadSelective($params); + } + } + + /** + * @param TicketDisplayTstOptions $params + */ + protected function loadSelective($params) + { + if (!empty($params->tstNumbers)) { + foreach ($params->tstNumbers as $tstNumber) { + $this->tstReference[] = new TstReference($tstNumber); + } + } + + if ($this->checkAnyNotEmpty($params->passengers, $params->segments)) { + $this->psaInformation = new PsaInformation(); + + foreach ($params->passengers as $passenger) { + $this->psaInformation->refDetails[] = new RefDetails($passenger, RefDetails::QUAL_PASSENGER); + } + + foreach ($params->segments as $segment) { + $this->psaInformation->refDetails[] = new RefDetails($segment, RefDetails::QUAL_SEGMENT_REFERENCE); + } + } + + if (!empty($params->scrollingCount) && !empty($params->scrollingStart)) { + $this->scrollingInformation = new ScrollingInformation( + $params->scrollingCount, + $params->scrollingStart + ); + } + } +} diff --git a/src/Amadeus/Client/Struct/Ticket/NextListInformation.php b/src/Amadeus/Client/Struct/Ticket/NextListInformation.php new file mode 100644 index 000000000..2b0bae69e --- /dev/null +++ b/src/Amadeus/Client/Struct/Ticket/NextListInformation.php @@ -0,0 +1,58 @@ + + */ +class NextListInformation +{ + /** + * Number indicating the position in a sequence. + * + * @var int + */ + public $remainingInformation; + + /** + * Identification number. + * + * @var int + */ + public $remainingReference; + + /** + * NextListInformation constructor. + * + * @param int $amount + * @param int $start + */ + public function __construct($amount, $start) + { + $this->remainingInformation = $amount; + $this->remainingReference = $start; + } +} diff --git a/src/Amadeus/Client/Struct/Ticket/PsaInformation.php b/src/Amadeus/Client/Struct/Ticket/PsaInformation.php new file mode 100644 index 000000000..cb677dd2c --- /dev/null +++ b/src/Amadeus/Client/Struct/Ticket/PsaInformation.php @@ -0,0 +1,37 @@ + + */ +class PsaInformation +{ + /** + * @var RefDetails[] + */ + public $refDetails = []; +} diff --git a/src/Amadeus/Client/Struct/Ticket/ScrollingInformation.php b/src/Amadeus/Client/Struct/Ticket/ScrollingInformation.php new file mode 100644 index 000000000..f63299509 --- /dev/null +++ b/src/Amadeus/Client/Struct/Ticket/ScrollingInformation.php @@ -0,0 +1,48 @@ + + */ +class ScrollingInformation +{ + /** + * @var NextListInformation + */ + public $nextListInformation; + + /** + * ScrollingInformation constructor. + * + * @param int $amount + * @param int $start + */ + public function __construct($amount, $start) + { + $this->nextListInformation = new NextListInformation($amount, $start); + } +} diff --git a/src/Amadeus/Client/Struct/Ticket/TstReference.php b/src/Amadeus/Client/Struct/Ticket/TstReference.php new file mode 100644 index 000000000..0fa4f7077 --- /dev/null +++ b/src/Amadeus/Client/Struct/Ticket/TstReference.php @@ -0,0 +1,33 @@ + + */ +class TstReference extends ItemReference +{ +} diff --git a/tests/Amadeus/Client/ResponseHandler/BaseTest.php b/tests/Amadeus/Client/ResponseHandler/BaseTest.php index 4745792ae..b1e52795f 100644 --- a/tests/Amadeus/Client/ResponseHandler/BaseTest.php +++ b/tests/Amadeus/Client/ResponseHandler/BaseTest.php @@ -801,6 +801,21 @@ public function testCanHandleTicketDeleteTSTErrResponse() $this->assertEquals("NEED PNR", $result->messages[0]->text); } + public function testCanHandleTicketDisplayTSTErrResponse() + { + $respHandler = new ResponseHandler\Base(); + + $sendResult = new SendResult(); + $sendResult->responseXml = $this->getTestFile('dummyTicketDisplayTstReplyErrorResponse.txt'); + + $result = $respHandler->analyzeResponse($sendResult, 'Ticket_DisplayTST'); + + $this->assertEquals(Result::STATUS_ERROR, $result->status); + $this->assertEquals(1, count($result->messages)); + $this->assertEquals('2075', $result->messages[0]->code); + $this->assertEquals("INVALID TST NUMBER", $result->messages[0]->text); + } + public function testCanHandleMiniRuleGetFromPricingRecErrResponse() { $respHandler = new ResponseHandler\Base(); diff --git a/tests/Amadeus/Client/ResponseHandler/testfiles/dummyTicketDisplayTstReplyErrorResponse.txt b/tests/Amadeus/Client/ResponseHandler/testfiles/dummyTicketDisplayTstReplyErrorResponse.txt new file mode 100644 index 000000000..fc5896c68 --- /dev/null +++ b/tests/Amadeus/Client/ResponseHandler/testfiles/dummyTicketDisplayTstReplyErrorResponse.txt @@ -0,0 +1,18 @@ + + + + + 2075 + EC + + + + + 1 + M + 7 + + INVALID TST NUMBER + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/Struct/Fare/MasterPricer/PricingTicketingTest.php b/tests/Amadeus/Client/Struct/Fare/MasterPricer/PricingTicketingTest.php new file mode 100644 index 000000000..acacdae9e --- /dev/null +++ b/tests/Amadeus/Client/Struct/Fare/MasterPricer/PricingTicketingTest.php @@ -0,0 +1,45 @@ + + */ +class PricingTicketingTest extends BaseTestCase +{ + public function testCanMakeWithMainPricingType() + { + $opt = new PricingTicketing( + PricingTicketing::PRICETYPE_NO_LOWCOST + ); + + $this->assertCount(1, $opt->priceType); + $this->assertEquals(PricingTicketing::PRICETYPE_NO_LOWCOST, $opt->priceType[0]); + } +} diff --git a/tests/Amadeus/Client/Struct/Fare/MasterPricerTravelBoardSearchTest.php b/tests/Amadeus/Client/Struct/Fare/MasterPricerTravelBoardSearchTest.php index 1ebd10c6a..fc157a229 100644 --- a/tests/Amadeus/Client/Struct/Fare/MasterPricerTravelBoardSearchTest.php +++ b/tests/Amadeus/Client/Struct/Fare/MasterPricerTravelBoardSearchTest.php @@ -29,9 +29,15 @@ use Amadeus\Client\RequestOptions\FareMasterPricerTbSearch; use Amadeus\Client\Struct\Fare\MasterPricer\ArrivalLocalization; use Amadeus\Client\Struct\Fare\MasterPricer\CabinId; +use Amadeus\Client\Struct\Fare\MasterPricer\CompanyIdentity; use Amadeus\Client\Struct\Fare\MasterPricer\DepartureLocalization; +use Amadeus\Client\Struct\Fare\MasterPricer\FirstDateTimeDetail; +use Amadeus\Client\Struct\Fare\MasterPricer\FlightDetail; use Amadeus\Client\Struct\Fare\MasterPricer\Itinerary; use Amadeus\Client\Struct\Fare\MasterPricer\NumberOfUnit; +use Amadeus\Client\Struct\Fare\MasterPricer\PaxReference; +use Amadeus\Client\Struct\Fare\MasterPricer\PricingTicketing; +use Amadeus\Client\Struct\Fare\MasterPricer\RangeOfDate; use Amadeus\Client\Struct\Fare\MasterPricer\TimeDetails; use Amadeus\Client\Struct\Fare\MasterPricer\Traveller; use Amadeus\Client\Struct\Fare\MasterPricer\UnitNumberDetail; @@ -71,13 +77,116 @@ public function testCanMakeBaseMasterPricerMessage() $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\FirstDateTimeDetail', $message->itinerary[0]->timeDetails->firstDateTimeDetail); $this->assertEquals('150117', $message->itinerary[0]->timeDetails->firstDateTimeDetail->date); $this->assertNull($message->itinerary[0]->timeDetails->firstDateTimeDetail->time); + $this->assertEquals(FirstDateTimeDetail::TIMEQUAL_DEPART_FROM, $message->itinerary[0]->timeDetails->firstDateTimeDetail->timeQualifier); $this->assertEquals('BRU', $message->itinerary[0]->departureLocalization->departurePoint->locationId); $this->assertEquals('C', $message->itinerary[0]->departureLocalization->departurePoint->airportCityQualifier); $this->assertEquals('LON', $message->itinerary[0]->arrivalLocalization->arrivalPointDetails->locationId); $this->assertEquals('C', $message->itinerary[0]->arrivalLocalization->arrivalPointDetails->airportCityQualifier); - //TODO assert passenger + $this->assertCount(2, $message->numberOfUnit->unitNumberDetail); + $this->assertEquals(1, $message->numberOfUnit->unitNumberDetail[0]->numberOfUnits); + $this->assertEquals(UnitNumberDetail::TYPE_PASS, $message->numberOfUnit->unitNumberDetail[0]->typeOfUnit); + $this->assertEquals(200, $message->numberOfUnit->unitNumberDetail[1]->numberOfUnits); + $this->assertEquals(UnitNumberDetail::TYPE_RESULTS, $message->numberOfUnit->unitNumberDetail[1]->typeOfUnit); + $this->assertCount(1, $message->paxReference); + $this->assertCount(1, $message->paxReference[0]->ptc); + $this->assertEquals('ADT', $message->paxReference[0]->ptc[0]); + $this->assertCount(1, $message->paxReference[0]->traveller); + $this->assertEquals(1, $message->paxReference[0]->traveller[0]->ref); + $this->assertNull($message->paxReference[0]->traveller[0]->infantIndicator); + } + + public function testCanMakeReturnRequest() + { + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 3, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 2 + ]), + new MPPassenger([ + 'type' => MPPassenger::TYPE_CHILD, + 'count' => 1 + ]), + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'MAD']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-03-05T10:00:00+0000', new \DateTimeZone('UTC')), + 'timeWindow' => 5, + 'rangeMode' => MPDate::RANGEMODE_MINUS_PLUS, + 'range' => 1 + ]) + ]), + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'MAD']), + 'arrivalLocation' => new MPLocation(['city' => 'BRU']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-03-12T18:00:00+0000', new \DateTimeZone('UTC')), + 'timeWindow' => 5, + 'rangeMode' => MPDate::RANGEMODE_PLUS, + 'range' => 1 + ]) + ]) + ] + ]); + + $message = new MasterPricerTravelBoardSearch($opt); + + $this->assertCount(2, $message->numberOfUnit->unitNumberDetail); + $this->assertEquals(3, $message->numberOfUnit->unitNumberDetail[0]->numberOfUnits); + $this->assertEquals(UnitNumberDetail::TYPE_PASS, $message->numberOfUnit->unitNumberDetail[0]->typeOfUnit); + $this->assertEquals(30, $message->numberOfUnit->unitNumberDetail[1]->numberOfUnits); + $this->assertEquals(UnitNumberDetail::TYPE_RESULTS, $message->numberOfUnit->unitNumberDetail[1]->typeOfUnit); + + $this->assertNull($message->combinationFareFamilies); + $this->assertNull($message->customerRef); + $this->assertEmpty($message->fareFamilies); + $this->assertNull($message->fareOptions); + $this->assertNull($message->feeOption); + $this->assertNull($message->formOfPaymentByPassenger); + $this->assertNull($message->globalOptions); + $this->assertNull($message->officeIdDetails); + $this->assertNull($message->priceToBeat); + $this->assertNull($message->solutionFamily); + $this->assertNull($message->taxInfo); + $this->assertNull($message->ticketChangeInfo); + $this->assertEmpty($message->valueSearch); + $this->assertNull($message->travelFlightInfo); + + $this->assertCount(2, $message->paxReference); + $this->assertEquals('ADT', $message->paxReference[0]->ptc[0]); + $this->assertCount(2, $message->paxReference[0]->traveller); + $this->assertEquals(1, $message->paxReference[0]->traveller[0]->ref); + $this->assertEquals(2, $message->paxReference[0]->traveller[1]->ref); + + $this->assertEquals('CH', $message->paxReference[1]->ptc[0]); + $this->assertCount(1, $message->paxReference[1]->traveller); + $this->assertEquals(3, $message->paxReference[1]->traveller[0]->ref); + + $this->assertCount(2, $message->itinerary); + $this->assertEquals('BRU', $message->itinerary[0]->departureLocalization->departurePoint->locationId); + $this->assertEquals('MAD', $message->itinerary[0]->arrivalLocalization ->arrivalPointDetails->locationId); + $this->assertEquals('050317', $message->itinerary[0]->timeDetails->firstDateTimeDetail->date); + $this->assertEquals('1000', $message->itinerary[0]->timeDetails->firstDateTimeDetail->time); + $this->assertEquals(5, $message->itinerary[0]->timeDetails->firstDateTimeDetail->timeWindow); + $this->assertEquals(FirstDateTimeDetail::TIMEQUAL_DEPART_FROM, $message->itinerary[0]->timeDetails->firstDateTimeDetail->timeQualifier); + $this->assertEquals(1, $message->itinerary[0]->timeDetails->rangeOfDate->dayInterval); + $this->assertEquals(RangeOfDate::RANGEMODE_MINUS_PLUS, $message->itinerary[0]->timeDetails->rangeOfDate->rangeQualifier); + + $this->assertEquals('MAD', $message->itinerary[1]->departureLocalization->departurePoint->locationId); + $this->assertEquals('BRU', $message->itinerary[1]->arrivalLocalization ->arrivalPointDetails->locationId); + $this->assertEquals('120317', $message->itinerary[1]->timeDetails->firstDateTimeDetail->date); + $this->assertEquals('1800', $message->itinerary[1]->timeDetails->firstDateTimeDetail->time); + $this->assertEquals(5, $message->itinerary[1]->timeDetails->firstDateTimeDetail->timeWindow); + $this->assertEquals(FirstDateTimeDetail::TIMEQUAL_DEPART_FROM, $message->itinerary[1]->timeDetails->firstDateTimeDetail->timeQualifier); + $this->assertEquals(1, $message->itinerary[1]->timeDetails->rangeOfDate->dayInterval); + $this->assertEquals(RangeOfDate::RANGEMODE_PLUS, $message->itinerary[1]->timeDetails->rangeOfDate->rangeQualifier); } public function testCanMakeMasterPricerMessageWithCabinClass() @@ -103,6 +212,51 @@ public function testCanMakeMasterPricerMessageWithCabinClass() $this->assertNull($message->travelFlightInfo->cabinId->cabinQualifier); } + public function testCanMakeMasterPricerMessageWithTicketabilityPreCheck() + { + $opt = new FareMasterPricerTbSearch(); + $opt->nrOfRequestedResults = 200; + $opt->nrOfRequestedPassengers = 1; + $opt->passengers[] = new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]); + $opt->itinerary[] = new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'LON']), + 'date' => new MPDate(['date' => new \DateTime('2017-01-15T00:00:00+0000', new \DateTimeZone('UTC'))]) + ]); + $opt->doTicketabilityPreCheck = true; + + $message = new MasterPricerTravelBoardSearch($opt); + + $this->assertEquals(PricingTicketing::PRICETYPE_TICKETABILITY_PRECHECK, $message->fareOptions->pricingTickInfo->pricingTicketing->priceType[0]); + } + + public function testCanMakeMasterPricerMessageWithCabinClassAndCod() + { + $opt = new FareMasterPricerTbSearch(); + $opt->nrOfRequestedResults = 200; + $opt->nrOfRequestedPassengers = 1; + $opt->passengers[] = new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]); + $opt->itinerary[] = new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'LON']), + 'date' => new MPDate(['date' => new \DateTime('2017-01-15T00:00:00+0000', new \DateTimeZone('UTC'))]) + ]); + $opt->cabinClass = FareMasterPricerTbSearch::CABIN_ECONOMY_PREMIUM; + $opt->cabinOption = FareMasterPricerTbSearch::CABINOPT_RECOMMENDED; + + + $message = new MasterPricerTravelBoardSearch($opt); + + $this->assertEquals(CabinId::CABIN_ECONOMY_PREMIUM, $message->travelFlightInfo->cabinId->cabin); + $this->assertEquals(CabinId::CABINOPT_RECOMMENDED, $message->travelFlightInfo->cabinId->cabinQualifier); + } + public function testCanMakeMasterPricerMessageWithMultiAdultAndInfant() { $opt = new FareMasterPricerTbSearch(); @@ -137,7 +291,6 @@ public function testCanMakeMasterPricerMessageWithMultiAdultAndInfant() $this->assertEquals(2, $message->paxReference[1]->traveller[1]->ref); $this->assertEquals(1, $message->paxReference[1]->traveller[1]->infantIndicator); - } public function testCanMakeMasterPricerMessageWithCityLocationAndGeoCoordinatesAndRadius() @@ -232,4 +385,216 @@ public function testCanMakeMasterPricerMessageWithMultiCity() $this->assertEquals('MAN', $message->itinerary[0]->arrivalLocalization->arrivalMultiCity[1]->locationId); $this->assertNull($message->itinerary[0]->arrivalLocalization->arrivalPointDetails); } + + + + public function testCanMakeMessageWithFlightType() + { + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 200, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'LON']), + 'date' => new MPDate(['date' => new \DateTime('2017-01-15T00:00:00+0000', new \DateTimeZone('UTC'))]) + ]) + ], + 'requestedFlightTypes' => [ + FareMasterPricerTbSearch::FLIGHTTYPE_DIRECT + ] + ]); + + $message = new MasterPricerTravelBoardSearch($opt); + + $this->assertInternalType('array', $message->itinerary); + $this->assertEquals(1, count($message->itinerary)); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\Itinerary', $message->itinerary[0]); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\TimeDetails', $message->itinerary[0]->timeDetails); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\FirstDateTimeDetail', $message->itinerary[0]->timeDetails->firstDateTimeDetail); + $this->assertEquals('150117', $message->itinerary[0]->timeDetails->firstDateTimeDetail->date); + $this->assertNull($message->itinerary[0]->timeDetails->firstDateTimeDetail->time); + $this->assertEquals('BRU', $message->itinerary[0]->departureLocalization->departurePoint->locationId); + $this->assertEquals('C', $message->itinerary[0]->departureLocalization->departurePoint->airportCityQualifier); + $this->assertEquals('LON', $message->itinerary[0]->arrivalLocalization->arrivalPointDetails->locationId); + $this->assertEquals('C', $message->itinerary[0]->arrivalLocalization->arrivalPointDetails->airportCityQualifier); + + $this->assertCount(1, $message->paxReference); + $this->assertCount(1, $message->paxReference[0]->ptc); + $this->assertEquals('ADT', $message->paxReference[0]->ptc[0]); + $this->assertCount(1, $message->paxReference[0]->traveller); + $this->assertEquals(1, $message->paxReference[0]->traveller[0]->ref); + $this->assertNull($message->paxReference[0]->traveller[0]->infantIndicator); + + $this->assertEquals( + [FlightDetail::FLIGHT_TYPE_DIRECT], + $message->travelFlightInfo->flightDetail->flightType + ); + } + + public function testCanMakeMessageWithDateTimeAndDateRange() + { + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 200, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'LON']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-01-15T14:00:00+0000', new \DateTimeZone('UTC')), + 'isDeparture' => false, + 'rangeMode' => MPDate::RANGEMODE_MINUS_PLUS, + 'range' => 1 + ]) + ]) + ] + ]); + + $message = new MasterPricerTravelBoardSearch($opt); + + $this->assertInternalType('array', $message->itinerary); + $this->assertEquals(1, count($message->itinerary)); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\Itinerary', $message->itinerary[0]); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\TimeDetails', $message->itinerary[0]->timeDetails); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\FirstDateTimeDetail', $message->itinerary[0]->timeDetails->firstDateTimeDetail); + $this->assertEquals('150117', $message->itinerary[0]->timeDetails->firstDateTimeDetail->date); + $this->assertEquals('1400', $message->itinerary[0]->timeDetails->firstDateTimeDetail->time); + $this->assertEquals(FirstDateTimeDetail::TIMEQUAL_ARRIVAL_BY, $message->itinerary[0]->timeDetails->firstDateTimeDetail->timeQualifier); + $this->assertNull($message->itinerary[0]->timeDetails->firstDateTimeDetail->timeWindow); + + $this->assertEquals(1, $message->itinerary[0]->timeDetails->rangeOfDate->dayInterval); + $this->assertEquals(RangeOfDate::RANGEMODE_MINUS_PLUS, $message->itinerary[0]->timeDetails->rangeOfDate->rangeQualifier); + $this->assertNull($message->itinerary[0]->timeDetails->rangeOfDate->timeAtdestination); + } + + public function testCanMakeMessageWithPreferredAirlines() + { + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 200, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BRU']), + 'arrivalLocation' => new MPLocation(['city' => 'LON']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-01-15T14:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'airlineOptions' => [ + FareMasterPricerTbSearch::AIRLINEOPT_PREFERRED => ['BA', 'SN'] + ] + ]); + + $message = new MasterPricerTravelBoardSearch($opt); + + $this->assertInternalType('array', $message->itinerary); + $this->assertEquals(1, count($message->itinerary)); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\Itinerary', $message->itinerary[0]); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\TimeDetails', $message->itinerary[0]->timeDetails); + $this->assertInstanceOf('Amadeus\Client\Struct\Fare\MasterPricer\FirstDateTimeDetail', $message->itinerary[0]->timeDetails->firstDateTimeDetail); + $this->assertEquals('150117', $message->itinerary[0]->timeDetails->firstDateTimeDetail->date); + $this->assertEquals('1400', $message->itinerary[0]->timeDetails->firstDateTimeDetail->time); + $this->assertEquals(FirstDateTimeDetail::TIMEQUAL_DEPART_FROM, $message->itinerary[0]->timeDetails->firstDateTimeDetail->timeQualifier); + $this->assertNull($message->itinerary[0]->timeDetails->firstDateTimeDetail->timeWindow); + + $this->assertCount(1, $message->travelFlightInfo->companyIdentity); + $this->assertEquals(CompanyIdentity::QUAL_PREFERRED, $message->travelFlightInfo->companyIdentity[0]->carrierQualifier); + $this->assertCount(2, $message->travelFlightInfo->companyIdentity[0]->carrierId); + $this->assertEquals(['BA', 'SN'], $message->travelFlightInfo->companyIdentity[0]->carrierId); + } + + public function testCanMakeMessageWithPublishedUnifaresCorporateUnifares() + { + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BER']), + 'arrivalLocation' => new MPLocation(['city' => 'MOW']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-05-01T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'flightOptions' => [ + FareMasterPricerTbSearch::FLIGHTOPT_PUBLISHED, + FareMasterPricerTbSearch::FLIGHTOPT_UNIFARES, + FareMasterPricerTbSearch::FLIGHTOPT_CORPORATE_UNIFARES, + ], + 'corporateCodesUnifares' => ['123456'] + ]); + + $message = new MasterPricerTravelBoardSearch($opt); + + $this->assertCount(3, $message->fareOptions->pricingTickInfo->pricingTicketing->priceType); + $this->assertEquals( + [ + PricingTicketing::PRICETYPE_PUBLISHEDFARES, + PricingTicketing::PRICETYPE_UNIFARES, + PricingTicketing::PRICETYPE_CORPORATE_UNIFARES + ], + $message->fareOptions->pricingTickInfo->pricingTicketing->priceType + ); + $this->assertEquals('123456', $message->fareOptions->corporate->corporateId[0]->identity[0]); + } + + public function testCanMakeMessageWithPriceToBeat() + { + $opt = new FareMasterPricerTbSearch([ + 'nrOfRequestedResults' => 30, + 'nrOfRequestedPassengers' => 1, + 'passengers' => [ + new MPPassenger([ + 'type' => MPPassenger::TYPE_ADULT, + 'count' => 1 + ]) + ], + 'itinerary' => [ + new MPItinerary([ + 'departureLocation' => new MPLocation(['city' => 'BER']), + 'arrivalLocation' => new MPLocation(['city' => 'MOW']), + 'date' => new MPDate([ + 'dateTime' => new \DateTime('2017-05-01T00:00:00+0000', new \DateTimeZone('UTC')) + ]) + ]) + ], + 'priceToBeat' => 500, + 'priceToBeatCurrency' => 'EUR', + ]); + + $message = new MasterPricerTravelBoardSearch($opt); + + $this->assertNull($message->fareOptions); + + $this->assertEquals(500, $message->priceToBeat->moneyInfo->amount); + $this->assertEquals('EUR', $message->priceToBeat->moneyInfo->currency); + } } + diff --git a/tests/Amadeus/Client/Struct/Info/EncodeDecodeCityTest.php b/tests/Amadeus/Client/Struct/Info/EncodeDecodeCityTest.php index 3b946a1a4..652f68b55 100644 --- a/tests/Amadeus/Client/Struct/Info/EncodeDecodeCityTest.php +++ b/tests/Amadeus/Client/Struct/Info/EncodeDecodeCityTest.php @@ -118,4 +118,26 @@ public function testCanMakeMessageForRequestWithCountryRestriction() $this->assertEquals('FR', $msg->countryStateRestriction->countryIdentification->countryCode); $this->assertNull($msg->countryStateRestriction->countryIdentification->stateCode); } + + /** + * I don't think this is a valid request, but it helps with code coverage :-/ + */ + public function testCanMakeMessageExplicitRequestOption() + { + $opt = new InfoEncodeDecodeCityOptions([ + 'locationCode' => 'OPO', + 'searchMode' => null, + 'selectResult' => InfoEncodeDecodeCityOptions::SELECT_HELIPORTS + ]); + + $msg = new EncodeDecodeCity($opt); + + $this->assertEquals('OPO', $msg->locationInformation->locationDescription->code); + $this->assertEquals(LocationInformation::TYPE_LOCATION, $msg->locationInformation->locationType); + + $this->assertEquals(SelectionDetails::OPT_LOCATION_TYPE, $msg->requestOption->selectionDetails->option); + $this->assertEquals(SelectionDetails::OPTINF_HELIPORT, $msg->requestOption->selectionDetails->optionInformation); + + $this->assertCount(0, $msg->requestOption->otherSelectionDetails); + } } diff --git a/tests/Amadeus/Client/Struct/Ticket/DisplayTSTTest.php b/tests/Amadeus/Client/Struct/Ticket/DisplayTSTTest.php new file mode 100644 index 000000000..d02a11a65 --- /dev/null +++ b/tests/Amadeus/Client/Struct/Ticket/DisplayTSTTest.php @@ -0,0 +1,130 @@ + + */ +class DisplayTSTTest extends BaseTestCase +{ + public function testCanMakeMessage() + { + $msg = new DisplayTST(new TicketDisplayTstOptions([ + 'displayMode' => TicketDisplayTstOptions::MODE_ALL + ])); + + $this->assertEquals(AttributeDetails::MODE_ALL, $msg->displayMode->attributeDetails->attributeType); + $this->assertNull($msg->pnrLocatorData); + $this->assertEmpty($msg->psaInformation); + $this->assertNull($msg->scrollingInformation); + $this->assertEmpty($msg->tstReference); + } + + public function testCanMakeMessageWithTstRef() + { + $msg = new DisplayTST(new TicketDisplayTstOptions([ + 'displayMode' => TicketDisplayTstOptions::MODE_SELECTIVE, + 'tstNumbers' => [1,2] + ])); + + $this->assertEquals(AttributeDetails::MODE_SELECTIVE, $msg->displayMode->attributeDetails->attributeType); + $this->assertCount(2, $msg->tstReference); + $this->assertEquals(1, $msg->tstReference[0]->uniqueReference); + $this->assertEquals(TstReference::REFTYPE_TST, $msg->tstReference[0]->referenceType); + $this->assertEquals(2, $msg->tstReference[1]->uniqueReference); + $this->assertEquals(TstReference::REFTYPE_TST, $msg->tstReference[1]->referenceType); + + $this->assertNull($msg->pnrLocatorData); + $this->assertEmpty($msg->psaInformation); + $this->assertNull($msg->scrollingInformation); + } + + public function testCanMakeMessageWithPassengerRef() + { + $msg = new DisplayTST(new TicketDisplayTstOptions([ + 'displayMode' => TicketDisplayTstOptions::MODE_SELECTIVE, + 'passengers' => [2,3] + ])); + + $this->assertEquals(AttributeDetails::MODE_SELECTIVE, $msg->displayMode->attributeDetails->attributeType); + + $this->assertCount(2, $msg->psaInformation->refDetails); + $this->assertEquals(2, $msg->psaInformation->refDetails[0]->refNumber); + $this->assertEquals(RefDetails::QUAL_PASSENGER, $msg->psaInformation->refDetails[0]->refQualifier); + $this->assertEquals(3, $msg->psaInformation->refDetails[1]->refNumber); + $this->assertEquals(RefDetails::QUAL_PASSENGER, $msg->psaInformation->refDetails[1]->refQualifier); + + $this->assertEmpty($msg->tstReference); + $this->assertNull($msg->pnrLocatorData); + $this->assertNull($msg->scrollingInformation); + } + + public function testCanMakeMessageWithSegmentRef() + { + $msg = new DisplayTST(new TicketDisplayTstOptions([ + 'displayMode' => TicketDisplayTstOptions::MODE_SELECTIVE, + 'segments' => [1,2,3] + ])); + + $this->assertEquals(AttributeDetails::MODE_SELECTIVE, $msg->displayMode->attributeDetails->attributeType); + + $this->assertCount(3, $msg->psaInformation->refDetails); + $this->assertEquals(1, $msg->psaInformation->refDetails[0]->refNumber); + $this->assertEquals(RefDetails::QUAL_SEGMENT_REFERENCE, $msg->psaInformation->refDetails[0]->refQualifier); + $this->assertEquals(2, $msg->psaInformation->refDetails[1]->refNumber); + $this->assertEquals(RefDetails::QUAL_SEGMENT_REFERENCE, $msg->psaInformation->refDetails[1]->refQualifier); + $this->assertEquals(3, $msg->psaInformation->refDetails[2]->refNumber); + $this->assertEquals(RefDetails::QUAL_SEGMENT_REFERENCE, $msg->psaInformation->refDetails[2]->refQualifier); + + $this->assertEmpty($msg->tstReference); + $this->assertNull($msg->pnrLocatorData); + $this->assertNull($msg->scrollingInformation); + } + + public function testCanMakeMessageWithScrolling() + { + $msg = new DisplayTST(new TicketDisplayTstOptions([ + 'displayMode' => TicketDisplayTstOptions::MODE_SELECTIVE, + 'scrollingStart' => 25, + 'scrollingCount' => 2 + ])); + + $this->assertEquals(AttributeDetails::MODE_SELECTIVE, $msg->displayMode->attributeDetails->attributeType); + $this->assertEquals(2, $msg->scrollingInformation->nextListInformation->remainingInformation); + $this->assertEquals(25, $msg->scrollingInformation->nextListInformation->remainingReference); + + $this->assertEmpty($msg->psaInformation); + $this->assertEmpty($msg->tstReference); + $this->assertNull($msg->pnrLocatorData); + } +} diff --git a/tests/Amadeus/ClientTest.php b/tests/Amadeus/ClientTest.php index cb30ad601..9536759ba 100644 --- a/tests/Amadeus/ClientTest.php +++ b/tests/Amadeus/ClientTest.php @@ -1206,6 +1206,61 @@ public function testCanDoTicketDeleteTST() $this->assertEquals($messageResult, $response); } + public function testCanDoTicketDisplayTST() + { + $mockSessionHandler = $this->getMockBuilder('Amadeus\Client\Session\Handler\HandlerInterface')->getMock(); + + $mockedSendResult = new Client\Session\Handler\SendResult(); + $mockedSendResult->responseXml = 'dummyTicketDisplayTSTmessage'; + + $messageResult = new Client\Result($mockedSendResult); + + $expectedMessageResult = new Client\Struct\Ticket\DisplayTST( + new Client\RequestOptions\TicketDisplayTstOptions([ + 'displayMode' => Client\RequestOptions\TicketDisplayTstOptions::MODE_ALL + ]) + ); + + $mockSessionHandler + ->expects($this->once()) + ->method('sendMessage') + ->with('Ticket_DisplayTST', $expectedMessageResult, ['endSession' => false]) + ->will($this->returnValue($mockedSendResult)); + $mockSessionHandler + ->expects($this->never()) + ->method('getLastResponse'); + $mockSessionHandler + ->expects($this->once()) + ->method('getMessagesAndVersions') + ->will($this->returnValue(['Ticket_DisplayTST' => "04.1"])); + + $mockResponseHandler = $this->getMockBuilder('Amadeus\Client\ResponseHandler\ResponseHandlerInterface')->getMock(); + + $mockResponseHandler + ->expects($this->once()) + ->method('analyzeResponse') + ->with($mockedSendResult, 'Ticket_DisplayTST') + ->will($this->returnValue($messageResult)); + + $par = new Params(); + $par->sessionHandler = $mockSessionHandler; + $par->requestCreatorParams = new Params\RequestCreatorParams([ + 'receivedFrom' => 'some RF string', + 'originatorOfficeId' => 'BRUXXXXXX' + ]); + $par->responseHandler = $mockResponseHandler; + + $client = new Client($par); + + $response = $client->ticketDisplayTST( + new Client\RequestOptions\TicketDisplayTstOptions([ + 'displayMode' => Client\RequestOptions\TicketDisplayTstOptions::MODE_ALL + ]) + ); + + $this->assertEquals($messageResult, $response); + } + public function testCanDoOfferConfirmAirOffer() { $mockSessionHandler = $this->getMockBuilder('Amadeus\Client\Session\Handler\HandlerInterface')->getMock(); @@ -1578,7 +1633,9 @@ public function testCanSendFareMasterPricerTravelBoardSearch() ]) ]) ], - 'requestedFlightOptions' => Client\RequestOptions\FareMasterPricerTbSearch::FLIGHTTYPE_DIRECT + 'requestedFlightTypes' => [ + Client\RequestOptions\FareMasterPricerTbSearch::FLIGHTTYPE_DIRECT + ] ]) ); @@ -1632,7 +1689,9 @@ public function testCanSendFareMasterPricerTravelBoardSearch() ]) ]) ], - 'requestedFlightOptions' => Client\RequestOptions\FareMasterPricerTbSearch::FLIGHTTYPE_DIRECT + 'requestedFlightTypes' => [ + Client\RequestOptions\FareMasterPricerTbSearch::FLIGHTTYPE_DIRECT + ] ]) );