From efd84832d21985cf1fc4aa7d290c918ad9ef1dca Mon Sep 17 00:00:00 2001 From: Edie Lemoine Date: Mon, 4 Dec 2023 10:45:51 +0100 Subject: [PATCH] fix(products): improve handling of nonexistent products (#229) Resolves #228 --- .../Order/Repository/PsPdkOrderRepository.php | 43 +++++++++++-------- .../Repository/PsPdkProductRepository.php | 32 +++++++++++--- src/Service/PsProductService.php | 15 +++++++ 3 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 src/Service/PsProductService.php diff --git a/src/Pdk/Order/Repository/PsPdkOrderRepository.php b/src/Pdk/Order/Repository/PsPdkOrderRepository.php index 25b76a14..66a49f6d 100644 --- a/src/Pdk/Order/Repository/PsPdkOrderRepository.php +++ b/src/Pdk/Order/Repository/PsPdkOrderRepository.php @@ -10,7 +10,6 @@ use MyParcelNL\Pdk\App\Order\Model\PdkOrder; use MyParcelNL\Pdk\App\Order\Repository\AbstractPdkOrderRepository; use MyParcelNL\Pdk\Base\Contract\CurrencyServiceInterface; -use MyParcelNL\Pdk\Base\Contract\WeightServiceInterface; use MyParcelNL\Pdk\Base\Support\Collection; use MyParcelNL\Pdk\Shipment\Model\Shipment; use MyParcelNL\Pdk\Storage\MemoryCacheStorage; @@ -18,6 +17,7 @@ use MyParcelNL\PrestaShop\Entity\MyparcelnlOrderShipment; use MyParcelNL\PrestaShop\Pdk\Base\Adapter\PsAddressAdapter; use MyParcelNL\PrestaShop\Repository\PsOrderShipmentRepository; +use MyParcelNL\PrestaShop\Service\PsProductService; use Order as PsOrder; final class PsPdkOrderRepository extends AbstractPdkOrderRepository @@ -48,35 +48,35 @@ final class PsPdkOrderRepository extends AbstractPdkOrderRepository private $psOrderShipmentRepository; /** - * @var \MyParcelNL\Pdk\Base\Contract\WeightServiceInterface + * @var \MyParcelNL\PrestaShop\Service\PsProductService */ - private $weightService; + private PsProductService $psProductService; /** * @param \MyParcelNL\Pdk\Storage\MemoryCacheStorage $storage * @param \MyParcelNL\PrestaShop\Repository\PsOrderShipmentRepository $psOrderShipmentRepository * @param \MyParcelNL\Pdk\Base\Contract\CurrencyServiceInterface $currencyService * @param \MyParcelNL\Pdk\App\Order\Contract\PdkProductRepositoryInterface $productRepository - * @param \MyParcelNL\Pdk\Base\Contract\WeightServiceInterface $weightService * @param \MyParcelNL\PrestaShop\Pdk\Base\Adapter\PsAddressAdapter $addressAdapter * @param \MyParcelNL\PrestaShop\Contract\PsOrderServiceInterface $psOrderService + * @param \MyParcelNL\PrestaShop\Service\PsProductService $psProductService */ public function __construct( MemoryCacheStorage $storage, PsOrderShipmentRepository $psOrderShipmentRepository, CurrencyServiceInterface $currencyService, PdkProductRepositoryInterface $productRepository, - WeightServiceInterface $weightService, PsAddressAdapter $addressAdapter, - PsOrderServiceInterface $psOrderService + PsOrderServiceInterface $psOrderService, + PsProductService $psProductService ) { parent::__construct($storage); $this->psOrderShipmentRepository = $psOrderShipmentRepository; $this->currencyService = $currencyService; $this->productRepository = $productRepository; - $this->weightService = $weightService; $this->addressAdapter = $addressAdapter; $this->psOrderService = $psOrderService; + $this->psProductService = $psProductService; } /** @@ -98,7 +98,7 @@ public function get($input): PdkOrder return $this->retrieve((string) $psOrder->id, function () use ($psOrder) { $orderData = $this->psOrderService->getOrderData($psOrder); - $orderProducts = $psOrder->getProducts() ?: []; + $orderProducts = new Collection($psOrder->getProducts() ?: []); return new PdkOrder( array_replace([ @@ -164,21 +164,26 @@ public function updateMany(PdkOrderCollection $collection): PdkOrderCollection } /** - * @param array $orderProducts + * @param \MyParcelNL\Pdk\Base\Support\Collection $orderProducts * * @return array|array[] */ - protected function createOrderLines(array $orderProducts): array + protected function createOrderLines(Collection $orderProducts): array { - return array_map(function (array $product) { - return [ - 'quantity' => $product['product_quantity'] ?? 1, - 'price' => $this->currencyService->convertToCents($product['product_price'] ?? 0), - 'priceAfterVat' => $this->currencyService->convertToCents($product['product_price_wt'] ?? 0), - 'product' => $this->productRepository->getProduct($product['product_id']), - 'vatRate' => $product['tax_rate'], - ]; - }, array_values($orderProducts)); + return $orderProducts + ->filter(function (array $product) { + return $this->psProductService->exists($product['id_product'] ?? 0); + }) + ->map(function (array $product) { + return [ + 'quantity' => $product['product_quantity'] ?? 1, + 'price' => $this->currencyService->convertToCents($product['product_price'] ?? 0), + 'priceAfterVat' => $this->currencyService->convertToCents($product['product_price_wt'] ?? 0), + 'product' => $this->productRepository->getProduct($product['product_id'] ?? 0), + 'vatRate' => $product['tax_rate'] ?? 0, + ]; + }) + ->toArrayWithoutNull(); } /** diff --git a/src/Pdk/Product/Repository/PsPdkProductRepository.php b/src/Pdk/Product/Repository/PsPdkProductRepository.php index aea25a3c..7c896bdd 100644 --- a/src/Pdk/Product/Repository/PsPdkProductRepository.php +++ b/src/Pdk/Product/Repository/PsPdkProductRepository.php @@ -5,16 +5,19 @@ namespace MyParcelNL\PrestaShop\Pdk\Product\Repository; use Context; +use InvalidArgumentException; use MyParcelNL\Pdk\App\Order\Collection\PdkProductCollection; use MyParcelNL\Pdk\App\Order\Model\PdkProduct; use MyParcelNL\Pdk\App\Order\Repository\AbstractPdkPdkProductRepository; use MyParcelNL\Pdk\Base\Contract\CurrencyServiceInterface; +use MyParcelNL\Pdk\Facade\Logger; use MyParcelNL\Pdk\Settings\Model\ProductSettings; use MyParcelNL\Pdk\Storage\Contract\StorageInterface; use MyParcelNL\PrestaShop\Pdk\Base\Service\PsWeightService; use MyParcelNL\PrestaShop\Repository\PsProductSettingsRepository; +use MyParcelNL\PrestaShop\Service\PsProductService; use MyParcelNL\Sdk\src\Support\Arr; -use Product; +use Product as PsProduct; class PsPdkProductRepository extends AbstractPdkPdkProductRepository { @@ -23,6 +26,11 @@ class PsPdkProductRepository extends AbstractPdkPdkProductRepository */ private $currencyService; + /** + * @var \MyParcelNL\PrestaShop\Service\PsProductService + */ + private PsProductService $psProductService; + /** * @var \MyParcelNL\PrestaShop\Repository\PsProductSettingsRepository */ @@ -37,17 +45,20 @@ class PsPdkProductRepository extends AbstractPdkPdkProductRepository * @param \MyParcelNL\Pdk\Storage\Contract\StorageInterface $storage * @param \MyParcelNL\PrestaShop\Pdk\Base\Service\PsWeightService $weightService * @param \MyParcelNL\PrestaShop\Repository\PsProductSettingsRepository $productSettingsRepository + * @param \MyParcelNL\PrestaShop\Service\PsProductService $psProductService * @param \MyParcelNL\Pdk\Base\Contract\CurrencyServiceInterface $currencyService */ public function __construct( StorageInterface $storage, PsWeightService $weightService, PsProductSettingsRepository $productSettingsRepository, + PsProductService $psProductService, CurrencyServiceInterface $currencyService ) { parent::__construct($storage); $this->weightService = $weightService; $this->psProductSettingsRepository = $productSettingsRepository; + $this->psProductService = $psProductService; $this->currencyService = $currencyService; } @@ -58,21 +69,28 @@ public function __construct( */ public function getProduct($identifier): PdkProduct { + if (! $this->psProductService->exists($identifier)) { + Logger::error("Product with id $identifier not found"); + throw new InvalidArgumentException('Product not found'); + } + return $this->retrieve((string) $identifier, function () use ($identifier) { - $psProduct = new Product($identifier); + /** @var PsProduct $psProduct */ + $psProduct = $this->psProductService->get($identifier); + $translate = static function (array $strings) { - return $strings[Context::getContext()->language->id] ?? $strings[1] ?? reset($strings); + return $strings[Context::getContext()->language->id] ?? $strings[1] ?? Arr::last($strings); }; return new PdkProduct([ 'externalIdentifier' => $psProduct->id, - 'name' => $translate($psProduct->name), - 'weight' => $this->weightService->convertToGrams($psProduct->weight), + 'name' => $translate($psProduct->name ?? []), + 'weight' => $this->weightService->convertToGrams($psProduct->weight ?? 0), 'settings' => $this->getProductSettings($identifier), 'isDeliverable' => $this->isDeliverable($psProduct), 'price' => [ 'currency' => Context::getContext()->currency->iso_code, - 'amount' => $this->currencyService->convertToCents($psProduct->price), + 'amount' => $this->currencyService->convertToCents($psProduct->price ?? 0), ], ]); }); @@ -138,7 +156,7 @@ protected function getKeyPrefix(): string * * @return bool */ - private function isDeliverable(Product $psProduct): bool + private function isDeliverable(PsProduct $psProduct): bool { return $psProduct->available_for_order && $psProduct->active diff --git a/src/Service/PsProductService.php b/src/Service/PsProductService.php new file mode 100644 index 00000000..ace7c241 --- /dev/null +++ b/src/Service/PsProductService.php @@ -0,0 +1,15 @@ +