Allow for easily sending multiple order items

This allows for the sending of multiple items in a single order, by
adding a new `OrderItem` class and moving all of the order item specific
fields from the `Order` to an individual item.

These can then be assigned to an order using the `withOrderItems()`
method as an array of order items.

Fixes #19
This commit is contained in:
Oliver Davies 2020-06-08 19:33:49 +01:00
parent 0ed99797f5
commit ae766763b2
9 changed files with 86 additions and 53 deletions

View file

@ -8,6 +8,7 @@ use Opdavies\Glassboxx\Enum\InteractionType;
use Opdavies\Glassboxx\Traits\UsesAuthTokenTrait; use Opdavies\Glassboxx\Traits\UsesAuthTokenTrait;
use Opdavies\Glassboxx\Traits\UsesCreatedAtTrait; use Opdavies\Glassboxx\Traits\UsesCreatedAtTrait;
use Opdavies\Glassboxx\ValueObject\OrderInterface; use Opdavies\Glassboxx\ValueObject\OrderInterface;
use Opdavies\Glassboxx\ValueObject\OrderItem;
use RuntimeException; use RuntimeException;
class OrderRequest extends AbstractRequest implements OrderRequestInterface class OrderRequest extends AbstractRequest implements OrderRequestInterface
@ -18,6 +19,9 @@ class OrderRequest extends AbstractRequest implements OrderRequestInterface
/** @var OrderInterface|null */ /** @var OrderInterface|null */
private $order; private $order;
/** @var OrderItem[] */
private $orderItems = [];
public function forOrder(OrderInterface $order): AbstractRequest public function forOrder(OrderInterface $order): AbstractRequest
{ {
$this->order = $order; $this->order = $order;
@ -25,6 +29,13 @@ class OrderRequest extends AbstractRequest implements OrderRequestInterface
return $this; return $this;
} }
public function withOrderItems(array $orderItems): AbstractRequest
{
$this->orderItems = $orderItems;
return $this;
}
public function execute(): string public function execute(): string
{ {
if (!$this->config) { if (!$this->config) {
@ -39,24 +50,24 @@ class OrderRequest extends AbstractRequest implements OrderRequestInterface
throw new RuntimeException('There is no customer'); throw new RuntimeException('There is no customer');
} }
$body = [ $body = [];
'items' => [
[ foreach ($this->orderItems as $orderItem) {
'created_at' => $this->getCreatedAtDate(), $body['items'][] = [
'currency_code' => $this->order->getCurrencyCode(), 'created_at' => $this->getCreatedAtDate(),
'customer_email' => $this->order->getCustomer()->getEmailAddress(), 'currency_code' => $this->order->getCurrencyCode(),
'customer_firstname' => $this->order->getCustomer()->getFirstName(), 'customer_email' => $this->order->getCustomer()->getEmailAddress(),
'customer_lastname' => $this->order->getCustomer()->getLastName(), 'customer_firstname' => $this->order->getCustomer()->getFirstName(),
'discount_amount' => 0, 'customer_lastname' => $this->order->getCustomer()->getLastName(),
'duration_for_loan' => 0, 'discount_amount' => 0,
'hostname' => $this->config->getVendorId(), 'duration_for_loan' => 0,
'original_order_number' => $this->order->getOrderNumber(), 'hostname' => $this->config->getVendorId(),
'price_incl_tax' => $this->order->getPrice(), 'original_order_number' => $this->order->getOrderNumber(),
'sku' => $this->order->getSku(), 'price_incl_tax' => $orderItem->getPrice(),
'type_of_interaction' => InteractionType::PURCHASE, 'sku' => $orderItem->getSku(),
], 'type_of_interaction' => InteractionType::PURCHASE,
], ];
]; }
$response = $this->client->request( $response = $this->client->request(
'POST', 'POST',

View file

@ -12,5 +12,7 @@ interface OrderRequestInterface
public function forOrder(OrderInterface $order): AbstractRequest; public function forOrder(OrderInterface $order): AbstractRequest;
public function withOrderItems(array $orderItems): AbstractRequest;
public function execute(): string; public function execute(): string;
} }

View file

@ -9,30 +9,20 @@ final class Order implements OrderInterface
/** @var CustomerInterface */ /** @var CustomerInterface */
private $customer; private $customer;
/** @var string */
private $sku;
/** @var string */ /** @var string */
private $orderNumber; private $orderNumber;
/** @var string */ /** @var string */
private $currencyCode; private $currencyCode;
/** @var float */
private $price;
public function __construct( public function __construct(
CustomerInterface $customer, CustomerInterface $customer,
string $sku,
string $orderNumber, string $orderNumber,
string $currencyCode, string $currencyCode
float $price
) { ) {
$this->customer = $customer; $this->customer = $customer;
$this->sku = $sku;
$this->orderNumber = $orderNumber; $this->orderNumber = $orderNumber;
$this->currencyCode = $currencyCode; $this->currencyCode = $currencyCode;
$this->price = $price;
} }
public function getCurrencyCode(): string public function getCurrencyCode(): string
@ -49,14 +39,4 @@ final class Order implements OrderInterface
{ {
return $this->orderNumber; return $this->orderNumber;
} }
public function getPrice(): float
{
return $this->price;
}
public function getSku(): string
{
return $this->sku;
}
} }

View file

@ -6,10 +6,8 @@ interface OrderInterface
{ {
public function __construct( public function __construct(
CustomerInterface $customer, CustomerInterface $customer,
string $sku,
string $orderNumber, string $orderNumber,
string $currencyCode, string $currencyCode
float $price
); );
public function getCurrencyCode(): string; public function getCurrencyCode(): string;
@ -17,8 +15,4 @@ interface OrderInterface
public function getCustomer(): CustomerInterface; public function getCustomer(): CustomerInterface;
public function getOrderNumber(): string; public function getOrderNumber(): string;
public function getPrice(): float;
public function getSku(): string;
} }

View file

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Opdavies\Glassboxx\ValueObject;
class OrderItem implements OrderItemInterface
{
/** @var string */
private $sku;
/** @var float */
private $price;
public function __construct(float $price, string $sku)
{
$this->price = $price;
$this->sku = $sku;
}
public function getPrice(): float
{
return $this->price;
}
public function getSku(): string
{
return $this->sku;
}
}

View file

@ -0,0 +1,10 @@
<?php
namespace Opdavies\Glassboxx\ValueObject;
interface OrderItemInterface
{
public function getPrice(): float;
public function getSku(): string;
}

View file

@ -7,6 +7,7 @@ namespace Opdavies\Glassboxx\Tests\Glassboxx\Request;
use DateTime; use DateTime;
use Opdavies\Glassboxx\Request\OrderRequest; use Opdavies\Glassboxx\Request\OrderRequest;
use Opdavies\Glassboxx\Tests\Glassboxx\TestCase; use Opdavies\Glassboxx\Tests\Glassboxx\TestCase;
use Opdavies\Glassboxx\ValueObject\OrderItemInterface;
use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Contracts\HttpClient\ResponseInterface; use Symfony\Contracts\HttpClient\ResponseInterface;
@ -56,6 +57,7 @@ final class OrderRequestTest extends TestCase
$request = (new OrderRequest($client)) $request = (new OrderRequest($client))
->forOrder($this->getMockOrder()) ->forOrder($this->getMockOrder())
->withOrderItems([$this->getMockOrderItem()])
->withAuthToken($authTokenRequest->getToken()) ->withAuthToken($authTokenRequest->getToken())
->withConfig($this->config) ->withConfig($this->config)
->setCreatedDate('2020-06-04 12:00:00'); ->setCreatedDate('2020-06-04 12:00:00');
@ -63,4 +65,14 @@ final class OrderRequestTest extends TestCase
// A successful response returns the original body. // A successful response returns the original body.
$this->assertSame(json_encode($body), $request->execute()); $this->assertSame(json_encode($body), $request->execute());
} }
private function getMockOrderItem(): OrderItemInterface
{
$orderItem = $this->getMockBuilder(OrderItemInterface::class)
->getMock();
$orderItem->method('getPrice')->willReturn(7.99);
$orderItem->method('getSku')->willReturn('this-is-the-first-sku');
return $orderItem;
}
} }

View file

@ -60,8 +60,6 @@ class TestCase extends \PHPUnit\Framework\TestCase
$order->method('getCurrencyCode')->willReturn('GBP'); $order->method('getCurrencyCode')->willReturn('GBP');
$order->method('getCustomer')->willReturn($this->getMockCustomer()); $order->method('getCustomer')->willReturn($this->getMockCustomer());
$order->method('getOrderNumber')->willReturn('abc123'); $order->method('getOrderNumber')->willReturn('abc123');
$order->method('getPrice')->willReturn(7.99);
$order->method('getSku')->willReturn('this-is-the-first-sku');
return $order; return $order;
} }

View file

@ -19,16 +19,12 @@ class OrderTest extends TestCase
$order = new Order( $order = new Order(
$customer, $customer,
'this-is-the-sku',
'123', '123',
'GBP', 'GBP'
10.00
); );
$this->assertSame('GBP', $order->getCurrencyCode()); $this->assertSame('GBP', $order->getCurrencyCode());
$this->assertSame($customer, $order->getCustomer()); $this->assertSame($customer, $order->getCustomer());
$this->assertSame('123', $order->getOrderNumber()); $this->assertSame('123', $order->getOrderNumber());
$this->assertSame(10.0, $order->getPrice());
$this->assertSame('this-is-the-sku', $order->getSku());
} }
} }