Skip to content

Commit

Permalink
Make cart items implementation extensible in core (#17)
Browse files Browse the repository at this point in the history
* Fix failure in unit tests

* Define Cart Item factory to allow extensibility

* Clean unused code

* Run PHPUnit before the PHPStan on the pipeline
  • Loading branch information
mescalantea authored Jul 10, 2024
1 parent 31c175e commit df628aa
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 40 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ jobs:
- name: PHP_CodeSniffer
run: docker run --rm -v "$(pwd)":/app -w /app php:7.2-cli-alpine php vendor/bin/phpcs --standard=.phpcs.xml.dist --warning-severity=0 . # Ignore Warnings for now...

- name: PHPStan
run: docker run --rm -v "$(pwd)":/app -w /app php:7.2-cli-alpine php vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=512M --error-format github --no-progress

- name: Run Tests
run: docker run --rm -v "$(pwd)":/app -w /app php:7.2-cli-alpine php vendor/bin/phpunit --configuration phpunit.xml --testdox

- name: PHPStan
run: docker run --rm -v "$(pwd)":/app -w /app php:7.2-cli-alpine php vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=512M --error-format github --no-progress
9 changes: 9 additions & 0 deletions src/BusinessLogic/BootstrapComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
use SeQura\Core\BusinessLogic\Domain\Integration\Version\VersionServiceInterface as VersionStoreService;
use SeQura\Core\BusinessLogic\Domain\Merchant\ProxyContracts\MerchantProxyInterface;
use SeQura\Core\BusinessLogic\Domain\Multistore\StoreContext;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\AbstractItemFactory;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\ItemFactory;
use SeQura\Core\BusinessLogic\Domain\Order\Models\SeQuraOrder;
use SeQura\Core\BusinessLogic\Domain\Order\ProxyContracts\OrderProxyInterface;
use SeQura\Core\BusinessLogic\Domain\Order\RepositoryContracts\SeQuraOrderRepositoryInterface;
Expand Down Expand Up @@ -425,6 +427,13 @@ static function () {
);
}
);

ServiceRegister::registerService(
AbstractItemFactory::class,
static function () {
return new ItemFactory();
}
);
}

/**
Expand Down
43 changes: 7 additions & 36 deletions src/BusinessLogic/Domain/Order/Models/OrderRequest/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@

namespace SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest;

use InvalidArgumentException;
use SeQura\Core\BusinessLogic\Domain\Order\Exceptions\InvalidCartItemsException;
use SeQura\Core\BusinessLogic\Domain\Order\Exceptions\InvalidDateException;
use SeQura\Core\BusinessLogic\Domain\Order\Exceptions\InvalidDurationException;
use SeQura\Core\BusinessLogic\Domain\Order\Exceptions\InvalidQuantityException;
use SeQura\Core\BusinessLogic\Domain\Order\Exceptions\InvalidServiceEndTimeException;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\AbstractItemFactory;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\DiscountItem;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\HandlingItem;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\InvoiceFeeItem;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\Item;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\ItemType;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\OtherPaymentItem;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\ProductItem;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\ServiceItem;
use SeQura\Core\Infrastructure\ServiceRegister;

/**
* Class Cart
Expand Down Expand Up @@ -107,38 +103,13 @@ public function __construct(
public static function fromArray(array $data): Cart
{
$orderTotal = self::getDataValue($data, 'order_total_with_tax', 0);
$items = self::getDataValue($data, 'items', []);
$items = (array) self::getDataValue($data, 'items', []);

// Convert item arrays to Item instances
/**
* @type Item[] $itemInstances
*/
$itemInstances = [];
foreach ($items as $itemData) {
$type = $itemData['type'];
switch ($type) {
case ItemType::TYPE_PRODUCT:
$itemInstances[] = ProductItem::fromArray($itemData);
break;
case ItemType::TYPE_HANDLING:
$itemInstances[] = HandlingItem::fromArray($itemData);
break;
case ItemType::TYPE_DISCOUNT:
$itemInstances[] = DiscountItem::fromArray($itemData);
break;
case ItemType::TYPE_SERVICE:
$itemInstances[] = ServiceItem::fromArray($itemData);
break;
case ItemType::TYPE_INVOICE_FEE:
$itemInstances[] = InvoiceFeeItem::fromArray($itemData);
break;
case ItemType::TYPE_OTHER_PAYMENT:
$itemInstances[] = OtherPaymentItem::fromArray($itemData);
break;
default:
throw new InvalidArgumentException('Invalid cart item type ' . $type);
}
}
* @var AbstractItemFactory $itemFactory
*/
$itemFactory = ServiceRegister::getService(AbstractItemFactory::class);
$itemInstances = $itemFactory->createListFromArray($items);

$itemTotal = array_reduce($itemInstances, static function ($sum, $item) {
return $sum + $item->getTotalWithTax();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item;

use InvalidArgumentException;

/**
* AbstractItemFactory
*
* @package SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item
*/
abstract class AbstractItemFactory
{
/**
* Create Item object from array.
*
* @param array<string, mixed> $data
*
* @throws InvalidArgumentException
*/
abstract public function createFromArray(array $data): Item;

/**
* Create a list of Item objects from an array of data.
*
* @param array<array<string, mixed>> $data Array of arrays containing the data of the items.
*
* @throws InvalidArgumentException
*
* @return Item[]
*/
public function createListFromArray(array $data): array
{
$items = [];
foreach ($data as $itemData) {
$item = $this->createFromArray($itemData);
if ($item !== null) {
$items[] = $item;
}
}
return $items;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item;

use InvalidArgumentException;

/**
* AbstractItemFactory implementation
*
* @package SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item
*/
class ItemFactory extends AbstractItemFactory
{
/**
* Create Item object from array.
*
* @param array<string, mixed> $itemData
*
* @throws InvalidArgumentException
*/
public function createFromArray(array $itemData): Item
{
$type = $itemData['type'] ?? null;
switch ($type) {
case ItemType::TYPE_PRODUCT:
return ProductItem::fromArray($itemData);
case ItemType::TYPE_HANDLING:
return HandlingItem::fromArray($itemData);
case ItemType::TYPE_DISCOUNT:
return DiscountItem::fromArray($itemData);
case ItemType::TYPE_SERVICE:
return ServiceItem::fromArray($itemData);
case ItemType::TYPE_INVOICE_FEE:
return InvoiceFeeItem::fromArray($itemData);
case ItemType::TYPE_OTHER_PAYMENT:
return OtherPaymentItem::fromArray($itemData);
default:
throw new InvalidArgumentException('Invalid cart item type ' . $type);
}
}
}
2 changes: 1 addition & 1 deletion src/Infrastructure/Data/DataTransferObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ abstract public function toArray();
*
* @return mixed
*/
protected static function getDataValue(array $rawData, string $key, mixed $default = '')
protected static function getDataValue(array $rawData, string $key, $default = '')
{
return isset($rawData[$key]) ? $rawData[$key] : $default;
}
Expand Down
5 changes: 5 additions & 0 deletions tests/BusinessLogic/Common/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
use SeQura\Core\BusinessLogic\Domain\Integration\Version\VersionServiceInterface;
use SeQura\Core\BusinessLogic\Domain\Merchant\ProxyContracts\MerchantProxyInterface;
use SeQura\Core\BusinessLogic\Domain\Multistore\StoreContext;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\AbstractItemFactory;
use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Item\ItemFactory;
use SeQura\Core\BusinessLogic\Domain\Order\Models\SeQuraOrder;
use SeQura\Core\BusinessLogic\Domain\Order\ProxyContracts\OrderProxyInterface;
use SeQura\Core\BusinessLogic\Domain\Order\RepositoryContracts\SeQuraOrderRepositoryInterface;
Expand Down Expand Up @@ -351,6 +353,9 @@ protected function setUp(): void
return new PromotionalWidgetsController(
TestServiceRegister::getService(WidgetSettingsService::class)
);
},
AbstractItemFactory::class => function () {
return new ItemFactory();
}
]);

Expand Down

0 comments on commit df628aa

Please sign in to comment.