From d681b61b6a7e04059f1d3100f76557ca8ec1f848 Mon Sep 17 00:00:00 2001 From: Sasha Gerrand Date: Thu, 28 Apr 2022 17:41:43 +0100 Subject: [PATCH 1/4] Add Seat Maps API functionality --- src/Duffel/Api/SeatMaps.php | 11 ++++++++++ tests/Duffel/Api/SeatMapsTest.php | 34 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/Duffel/Api/SeatMaps.php create mode 100644 tests/Duffel/Api/SeatMapsTest.php diff --git a/src/Duffel/Api/SeatMaps.php b/src/Duffel/Api/SeatMaps.php new file mode 100644 index 0000000..09f3c9d --- /dev/null +++ b/src/Duffel/Api/SeatMaps.php @@ -0,0 +1,11 @@ +get('/air/seat_maps?offer_id='.self::encodePath($offerId)); + } +} diff --git a/tests/Duffel/Api/SeatMapsTest.php b/tests/Duffel/Api/SeatMapsTest.php new file mode 100644 index 0000000..21370f8 --- /dev/null +++ b/tests/Duffel/Api/SeatMapsTest.php @@ -0,0 +1,34 @@ +mock = $this->createMock(HttpMethodsClientInterface::class); + $this->stub = $this->createStub(Client::class); + $this->stub->method('getHttpClient') + ->willReturn($this->mock); + } + + public function testAllCallsGetWithExpectedUri(): void { + $this->mock->expects($this->once()) + ->method('get') + ->with( + $this->equalTo('/air/seat_maps?offer_id=some-offer-id'), + $this->equalTo([]), + ); + + $actual = new SeatMaps($this->stub); + $actual->all('some-offer-id'); + } +} From a1c465f3b3cbfff742b89ae24e8df9b22227c56a Mon Sep 17 00:00:00 2001 From: Sasha Gerrand Date: Thu, 28 Apr 2022 17:44:47 +0100 Subject: [PATCH 2/4] Integrate Seat Maps API into client --- src/Duffel/Client.php | 5 +++++ tests/Duffel/ClientTest.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/Duffel/Client.php b/src/Duffel/Client.php index 0d43349..74a047c 100644 --- a/src/Duffel/Client.php +++ b/src/Duffel/Client.php @@ -11,6 +11,7 @@ use Duffel\Api\Offers; use Duffel\Api\OrderCancellations; use Duffel\Api\Orders; +use Duffel\Api\SeatMaps; use Duffel\Exception\InvalidAccessTokenException; use Duffel\HttpClient\Builder; use Http\Client\Common\HttpMethodsClientInterface; @@ -73,6 +74,10 @@ public function orders(): Orders { return new Orders($this); } + public function seatMaps(): SeatMaps { + return new SeatMaps($this); + } + public function getAccessToken() { return $this->accessToken; } diff --git a/tests/Duffel/ClientTest.php b/tests/Duffel/ClientTest.php index d59aca2..8f3f4f5 100644 --- a/tests/Duffel/ClientTest.php +++ b/tests/Duffel/ClientTest.php @@ -11,6 +11,7 @@ use Duffel\Api\Offers; use Duffel\Api\OrderCancellations; use Duffel\Api\Orders; +use Duffel\Api\SeatMaps; use Duffel\Client; use Duffel\Exception\InvalidAccessTokenException; use Duffel\HttpClient\Builder; @@ -67,6 +68,10 @@ public function testOrdersUsesApiClass(): void { $this->assertInstanceOf(Orders::class, $this->subject->orders()); } + public function testSeatMapsUsesApiClass(): void { + $this->assertInstanceOf(SeatMaps::class, $this->subject->seatMaps()); + } + public function testSetAccessTokenChangesValue(): void { $this->subject->setAccessToken('some-token'); From 8b3218ec6ca86454ac317144374842b104555a90 Mon Sep 17 00:00:00 2001 From: Sasha Gerrand Date: Fri, 29 Apr 2022 09:44:38 +0100 Subject: [PATCH 3/4] Add Book With Seat example --- examples/book-with-seat.php | 116 ++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 examples/book-with-seat.php diff --git a/examples/book-with-seat.php b/examples/book-with-seat.php new file mode 100644 index 0000000..2f9070b --- /dev/null +++ b/examples/book-with-seat.php @@ -0,0 +1,116 @@ +setAccessToken(getenv('DUFFEL_ACCESS_TOKEN')); + +$departureDate = (new DateTime)->add(new DateInterval("P10D"))->format('Y-m-d'); + +$offerRequest = $client->offerRequests()->create( + "economy", + array( + array("type" => "adult") + ), + array( + array( + "origin" => "LHR", + "destination" => "STN", + "departure_date" => $departureDate + ) + ) +); + +echo sprintf("Created offer request: %s\n", $offerRequest["id"]); + +$offers = $client->offers()->all($offerRequest["id"]); + +echo sprintf("Got %s offers\n", count($offers)); + +$selectedOffer = $offers[0]; + +echo sprintf("Selected offer %s to book\n", $selectedOffer["id"]); + +$pricedOffer = $client->offers()->show($selectedOffer["id"]); + +echo sprintf("The final price for offer %s is %s (%s)\n", $pricedOffer["id"], + $pricedOffer["total_amount"], + $pricedOffer["total_currency"] +); + +$seatMaps = $client->seatMaps()->all($pricedOffer["id"]); +$availableSeats = []; +foreach($seatMaps as $seatMap) { + foreach($seatMap["cabins"] as $cabin) { + foreach($cabin["rows"] as $row) { + foreach($row["sections"] as $section) { + foreach($section["elements"] as $element) { + if ($element["type"] == "seat" && count($element["available_services"]) > 0) { + $availableSeats[] = $element; + } + } + } + } + } +} + +$availableSeat = array_shift($availableSeats); +$availableSeatService = array_shift($availableSeat["available_services"]); + +echo sprintf("Adding seat %s costing %s (%s)\n", $availableSeat["designator"], + $availableSeatService["total_amount"], + $availableSeatService["total_currency"], +); + +$totalAmount = round(($pricedOffer["total_amount"] + $availableSeatService["total_amount"]), 2); + +echo sprintf("Total amount is %s\n", $totalAmount); + +$order = $client->orders()->create(array( + "selected_offers" => array($pricedOffer["id"]), + "services" => array( + array( + "id" => $availableSeatService["id"], + "quantity" => 1, + ) + ), + "payments" => array( + array( + "type" => "balance", + "amount" => $totalAmount, + "currency" => $pricedOffer["total_currency"] + ) + ), + "passengers" => array( + array( + "id" => $pricedOffer["passengers"][0]["id"], + "title" => "mr", + "gender" => "m", + "given_name" => "Zepp", + "family_name" => "Lin", + "born_on" => "1990-01-26", + "phone_number" => "+441234567890", + "email" => "z.e.l@zeppelin.aero", + ) + ) +)); + +echo sprintf("Created order %s with booking reference %s\n", $order["id"], $order["booking_reference"]); + +$orderCancellation = $client->orderCancellations()->create($order["id"]); + +echo sprintf("Requested refund quote for order %s – %s (%s) is available\n", $order["id"], $orderCancellation["refund_amount"], $orderCancellation["refund_currency"]); + +$client->orderCancellations()->confirm($orderCancellation["id"]); + +echo sprintf("Confirmed refund quote for order %s\n", $order["id"]); + +$finish = time(); +echo sprintf("Finished in %d seconds.\n", ($finish - $start)); From ddad993966cf0b343844b32c69b6c3d27264b6b9 Mon Sep 17 00:00:00 2001 From: Sasha Gerrand Date: Fri, 29 Apr 2022 10:57:06 +0100 Subject: [PATCH 4/4] Run Book With Seat example in CI --- .github/workflows/examples.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index b333d6a..d3aaded 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -47,3 +47,6 @@ jobs: - name: Run book with extra baggage example run: php ./examples/book-with-extra-baggage.php + + - name: Run book with seat example + run: php ./examples/book-with-seat.php