Skip to content
This repository has been archived by the owner on Sep 12, 2024. It is now read-only.

Commit

Permalink
Merge pull request #11 from duffelhq/api-order_cancellations
Browse files Browse the repository at this point in the history
API: Order Cancellations
  • Loading branch information
sgerrand authored Apr 28, 2022
2 parents 3364d57 + 7f65156 commit a6d3758
Show file tree
Hide file tree
Showing 7 changed files with 314 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,9 @@ jobs:

- name: Run exploring data example
run: php ./examples/exploring-data.php

- name: Run search and book example
run: php ./examples/search-and-book.php

- name: Run book with extra baggage example
run: php ./examples/book-with-extra-baggage.php
104 changes: 104 additions & 0 deletions examples/book-with-extra-baggage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Duffel\Client;

echo "Duffel Flights API - book with extra baggage example\n";
$start = time();

$client = new Client;
$client->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 = array_shift($offers);

echo sprintf("Selected offer %s to book\n", $selectedOffer["id"]);

$pricedOffer = $client->offers()->show($selectedOffer["id"], true);

echo sprintf("The final price for offer %s is %s (%s)\n", $pricedOffer["id"],
$pricedOffer["total_amount"],
$pricedOffer["total_currency"]
);

$availableBaggage = array_filter($pricedOffer["available_services"],
function ($service) {
return $service["type"] === "baggage";
}
);
$availableBaggage = array_pop($availableBaggage);

echo sprintf("Adding an extra bag with %s kg costing %s (%s)\n", $availableBaggage["metadata"]["maximum_weight_kg"],
$availableBaggage["total_amount"],
$availableBaggage["total_currency"],
);

$totalAmount = round(($pricedOffer["total_amount"] + $availableBaggage["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" => $availableBaggage["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));
99 changes: 99 additions & 0 deletions examples/search-and-book.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Duffel\Client;

echo "Duffel Flights API - search and book example\n";
$start = time();

$client = new Client();
$client->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 = array_shift($offers);

echo sprintf("Selected offer %s to book\n", $selectedOffer["id"]);

$pricedOffer = $client->offers()->show($selectedOffer["id"], true);

echo sprintf("The final price for offer %s is %s (%s)\n", $pricedOffer["id"],
$pricedOffer["total_amount"],
$pricedOffer["total_currency"]
);

$availableService = array_shift($pricedOffer["available_services"]);

echo sprintf("Adding an extra bag with service %s costing %s (%s)\n", $availableService["id"],
$availableService["total_amount"],
$availableService["total_currency"],
);

$totalAmount = round(($pricedOffer["total_amount"] + $availableService["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" => $availableService["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));
29 changes: 29 additions & 0 deletions src/Duffel/Api/OrderCancellations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Duffel\Api;

class OrderCancellations extends AbstractApi {
public function all() {
return $this->get('/air/order_cancellations');
}

public function show(string $id) {
return $this->get('/air/order_cancellations/'.self::encodePath($id));
}

public function create(string $orderId) {
$params = array(
"order_id" => $orderId
);

return $this->post('/air/order_cancellations', \array_filter($params, function ($value) {
return null !== $value && (!\is_string($value) || '' !== $value);
}));
}

public function confirm(string $id) {
return $this->post('/air/order_cancellations/'.self::encodePath($id).'/actions/confirm');
}
}
5 changes: 5 additions & 0 deletions src/Duffel/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Duffel\Api\Airports;
use Duffel\Api\OfferRequests;
use Duffel\Api\Offers;
use Duffel\Api\OrderCancellations;
use Duffel\Api\Orders;
use Duffel\Exception\InvalidAccessTokenException;
use Duffel\HttpClient\Builder;
Expand Down Expand Up @@ -64,6 +65,10 @@ public function offers(): Offers {
return new Offers($this);
}

public function orderCancellations(): OrderCancellations {
return new OrderCancellations($this);
}

public function orders(): Orders {
return new Orders($this);
}
Expand Down
66 changes: 66 additions & 0 deletions tests/Duffel/Api/OrderCancellationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace Duffel\Tests\Api;

use Duffel\Api\OrderCancellations;
use Duffel\Client;
use Http\Client\Common\HttpMethodsClientInterface;
use PHPUnit\Framework\TestCase;

class TestOrderCancellations extends TestCase {
private $mock;
private $stub;

public function setUp(): void {
$this->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/order_cancellations'));

$actual = new OrderCancellations($this->stub);
$actual->all();
}

public function testShowWithIdCallsGetWithExpectedUri(): void {
$this->mock->expects($this->once())
->method('get')
->with($this->equalTo('/air/order_cancellations/some-id'));

$actual = new OrderCancellations($this->stub);
$actual->show('some-id');
}

public function testCreateWithIdCallsGetWithExpectedUri(): void {
$this->mock->expects($this->once())
->method('post')
->with(
$this->equalTo('/air/order_cancellations'),
$this->equalTo(['Content-Type' => 'application/json']),
$this->equalTo('{"data":{"order_id":"some-id"}}'),
);

$actual = new OrderCancellations($this->stub);
$actual->create('some-id');
}

public function testConfirmWithIdCallsGetWithExpectedUri(): void {
$this->mock->expects($this->once())
->method('post')
->with(
$this->equalTo('/air/order_cancellations/some-id/actions/confirm'),
$this->equalTo([]),
$this->equalTo(null),
);

$actual = new OrderCancellations($this->stub);
$actual->confirm('some-id');
}
}
5 changes: 5 additions & 0 deletions tests/Duffel/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Duffel\Api\Airports;
use Duffel\Api\OfferRequests;
use Duffel\Api\Offers;
use Duffel\Api\OrderCancellations;
use Duffel\Api\Orders;
use Duffel\Client;
use Duffel\Exception\InvalidAccessTokenException;
Expand Down Expand Up @@ -58,6 +59,10 @@ public function testOffersUsesApiClass(): void {
$this->assertInstanceOf(Offers::class, $this->subject->offers());
}

public function testOrderCancellationsUsesApiClass(): void {
$this->assertInstanceOf(OrderCancellations::class, $this->subject->orderCancellations());
}

public function testOrdersUsesApiClass(): void {
$this->assertInstanceOf(Orders::class, $this->subject->orders());
}
Expand Down

0 comments on commit a6d3758

Please sign in to comment.