From f159bdd8d29153bdc4342be685574ce9db03bf43 Mon Sep 17 00:00:00 2001 From: Melvin Achterhuis Date: Wed, 1 Jun 2022 15:51:04 +0200 Subject: [PATCH 1/3] Save reset stock in order line item custom field with refund --- .../RefundData/OrderItem/AbstractItem.php | 4 ++- .../RefundData/OrderItem/DeliveryItem.php | 3 ++- .../RefundData/OrderItem/ProductItem.php | 5 +++- .../RefundData/OrderItem/PromotionItem.php | 3 ++- .../RefundManager/RefundManager.php | 25 ++++++++++++++++--- src/Resources/config/services/components.xml | 1 + 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/Components/RefundManager/RefundData/OrderItem/AbstractItem.php b/src/Components/RefundManager/RefundData/OrderItem/AbstractItem.php index f54f39d59..13f66c30e 100644 --- a/src/Components/RefundManager/RefundData/OrderItem/AbstractItem.php +++ b/src/Components/RefundManager/RefundData/OrderItem/AbstractItem.php @@ -17,9 +17,10 @@ abstract class AbstractItem * @param float $promotionDiscount * @param int $promotionAffectedQty * @param int $refundedQty + * @param int $resetStock * @return array */ - protected function buildArray(string $id, string $label, string $referenceNumber, bool $isPromotion, bool $isDelivery, float $unitPrice, int $quantity, float $totalPrice, float $promotionDiscount, int $promotionAffectedQty, int $refundedQty): array + protected function buildArray(string $id, string $label, string $referenceNumber, bool $isPromotion, bool $isDelivery, float $unitPrice, int $quantity, float $totalPrice, float $promotionDiscount, int $promotionAffectedQty, int $refundedQty, int $resetStock): array { return [ 'refunded' => $refundedQty, @@ -37,6 +38,7 @@ protected function buildArray(string $id, string $label, string $referenceNumber ], 'isPromotion' => $isPromotion, 'isDelivery' => $isDelivery, + 'resetStock' => $resetStock ], ]; } diff --git a/src/Components/RefundManager/RefundData/OrderItem/DeliveryItem.php b/src/Components/RefundManager/RefundData/OrderItem/DeliveryItem.php index 209254e98..e446c54c6 100644 --- a/src/Components/RefundManager/RefundData/OrderItem/DeliveryItem.php +++ b/src/Components/RefundManager/RefundData/OrderItem/DeliveryItem.php @@ -51,7 +51,8 @@ public function toArray(): array $this->delivery->getShippingCosts()->getTotalPrice(), 0, 0, - $this->alreadyRefundedQty + $this->alreadyRefundedQty, + 0 ); } diff --git a/src/Components/RefundManager/RefundData/OrderItem/ProductItem.php b/src/Components/RefundManager/RefundData/OrderItem/ProductItem.php index 9401c42df..553b84412 100644 --- a/src/Components/RefundManager/RefundData/OrderItem/ProductItem.php +++ b/src/Components/RefundManager/RefundData/OrderItem/ProductItem.php @@ -68,6 +68,8 @@ private function extractPromotionDiscounts(array $promotionCompositions) */ public function toArray(): array { + $resetStock = $this->lineItem->getCustomFields()['mollie_payments_stock']['reset_stock_quantity'] ?? 0; + return $this->buildArray( $this->lineItem->getId(), $this->lineItem->getLabel(), @@ -79,7 +81,8 @@ public function toArray(): array $this->lineItem->getTotalPrice(), $this->promotionDiscount, $this->promotionAffectedQuantity, - $this->alreadyRefundedQty + $this->alreadyRefundedQty, + $resetStock ); } diff --git a/src/Components/RefundManager/RefundData/OrderItem/PromotionItem.php b/src/Components/RefundManager/RefundData/OrderItem/PromotionItem.php index 8ab89a796..385c19981 100644 --- a/src/Components/RefundManager/RefundData/OrderItem/PromotionItem.php +++ b/src/Components/RefundManager/RefundData/OrderItem/PromotionItem.php @@ -44,7 +44,8 @@ public function toArray(): array $this->lineItem->getTotalPrice(), 0, 0, - $this->alreadyRefundedQty + $this->alreadyRefundedQty, + 0 ); } diff --git a/src/Components/RefundManager/RefundManager.php b/src/Components/RefundManager/RefundManager.php index 983bb10bf..49fc5f11a 100644 --- a/src/Components/RefundManager/RefundManager.php +++ b/src/Components/RefundManager/RefundManager.php @@ -29,6 +29,7 @@ use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Framework\Context; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; class RefundManager implements RefundManagerInterface { @@ -73,6 +74,11 @@ class RefundManager implements RefundManagerInterface */ private $logger; + /** + * @var EntityRepositoryInterface + */ + private $orderLineItemRepository; + /** * @param RefundDataBuilder $refundDataBuilder @@ -83,9 +89,10 @@ class RefundManager implements RefundManagerInterface * @param FlowBuilderEventFactory $flowBuilderEventFactory * @param StockManagerInterface $stockUpdater * @param LoggerInterface $logger + * @param EntityRepositoryInterface $orderLineItemRepository * @throws \Exception */ - public function __construct(RefundDataBuilder $refundDataBuilder, OrderServiceInterface $orderService, RefundServiceInterface $refundService, Order $mollieOrder, FlowBuilderFactoryInterface $flowBuilderFactory, FlowBuilderEventFactory $flowBuilderEventFactory, StockManagerInterface $stockUpdater, LoggerInterface $logger) + public function __construct(RefundDataBuilder $refundDataBuilder, OrderServiceInterface $orderService, RefundServiceInterface $refundService, Order $mollieOrder, FlowBuilderFactoryInterface $flowBuilderFactory, FlowBuilderEventFactory $flowBuilderEventFactory, StockManagerInterface $stockUpdater, LoggerInterface $logger, EntityRepositoryInterface $orderLineItemRepository) { $this->builderData = $refundDataBuilder; $this->orderService = $orderService; @@ -93,10 +100,9 @@ public function __construct(RefundDataBuilder $refundDataBuilder, OrderServiceIn $this->refundService = $refundService; $this->stockManager = $stockUpdater; $this->logger = $logger; - $this->flowBuilderEventFactory = $flowBuilderEventFactory; - $this->flowBuilderDispatcher = $flowBuilderFactory->createDispatcher(); + $this->orderLineItemRepository = $orderLineItemRepository; } @@ -215,6 +221,19 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont $refund->id ); } + # also add reset stock to order line item, so we can retrieve it through API + # multiple refunds for a single line item are possible, so if previous reset stock exists, increase it + $alreadyResetStock = $orderItem->getCustomFields()['mollie_payments_stock']['reset_stock_quantity'] ?? 0; + $this->orderLineItemRepository->update([ + [ + 'id' => $orderItem->getId(), + 'customFields' => [ + 'mollie_payments_stock' => [ + 'reset_stock_quantity' => $alreadyResetStock + $item->getStockIncreaseQty() + ] + ] + ], + ], $context); } return $refund; diff --git a/src/Resources/config/services/components.xml b/src/Resources/config/services/components.xml index c04027f5f..7319be64a 100644 --- a/src/Resources/config/services/components.xml +++ b/src/Resources/config/services/components.xml @@ -14,6 +14,7 @@ + From 6e7cfdfb325d324ce5a3b5e2d74722bc3b71bf76 Mon Sep 17 00:00:00 2001 From: Melvin Achterhuis Date: Fri, 8 Jul 2022 14:07:42 +0200 Subject: [PATCH 2/3] Improve code, add tests --- .../RefundData/OrderItem/AbstractItem.php | 6 ++--- .../RefundData/OrderItem/ProductItem.php | 6 +++-- .../RefundManager/RefundManager.php | 24 ++++++++++--------- .../OrderLineItemEntityAttributes.php | 14 +++++++++++ .../RefundData/RefundDataTest.php | 2 ++ .../RefundManager/RefundManagerTest.php | 8 +++++-- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/Components/RefundManager/RefundData/OrderItem/AbstractItem.php b/src/Components/RefundManager/RefundData/OrderItem/AbstractItem.php index 13f66c30e..6569dd788 100644 --- a/src/Components/RefundManager/RefundData/OrderItem/AbstractItem.php +++ b/src/Components/RefundManager/RefundData/OrderItem/AbstractItem.php @@ -17,10 +17,10 @@ abstract class AbstractItem * @param float $promotionDiscount * @param int $promotionAffectedQty * @param int $refundedQty - * @param int $resetStock + * @param int $resetStockQuantity * @return array */ - protected function buildArray(string $id, string $label, string $referenceNumber, bool $isPromotion, bool $isDelivery, float $unitPrice, int $quantity, float $totalPrice, float $promotionDiscount, int $promotionAffectedQty, int $refundedQty, int $resetStock): array + protected function buildArray(string $id, string $label, string $referenceNumber, bool $isPromotion, bool $isDelivery, float $unitPrice, int $quantity, float $totalPrice, float $promotionDiscount, int $promotionAffectedQty, int $refundedQty, int $resetStockQuantity): array { return [ 'refunded' => $refundedQty, @@ -38,7 +38,7 @@ protected function buildArray(string $id, string $label, string $referenceNumber ], 'isPromotion' => $isPromotion, 'isDelivery' => $isDelivery, - 'resetStock' => $resetStock + 'resetStockQuantity' => $resetStockQuantity ], ]; } diff --git a/src/Components/RefundManager/RefundData/OrderItem/ProductItem.php b/src/Components/RefundManager/RefundData/OrderItem/ProductItem.php index 553b84412..5eb9f872d 100644 --- a/src/Components/RefundManager/RefundData/OrderItem/ProductItem.php +++ b/src/Components/RefundManager/RefundData/OrderItem/ProductItem.php @@ -2,6 +2,7 @@ namespace Kiener\MolliePayments\Components\RefundManager\RefundData\OrderItem; +use Kiener\MolliePayments\Struct\OrderLineItemEntity\OrderLineItemEntityAttributes; use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity; class ProductItem extends AbstractItem @@ -68,7 +69,8 @@ private function extractPromotionDiscounts(array $promotionCompositions) */ public function toArray(): array { - $resetStock = $this->lineItem->getCustomFields()['mollie_payments_stock']['reset_stock_quantity'] ?? 0; + $lineItemAttributes = new OrderLineItemEntityAttributes($this->lineItem); + $resetStockQuantity = $lineItemAttributes->getResetStockQuantity(); return $this->buildArray( $this->lineItem->getId(), @@ -82,7 +84,7 @@ public function toArray(): array $this->promotionDiscount, $this->promotionAffectedQuantity, $this->alreadyRefundedQty, - $resetStock + $resetStockQuantity ); } diff --git a/src/Components/RefundManager/RefundManager.php b/src/Components/RefundManager/RefundManager.php index f881f6a55..a624c2f21 100644 --- a/src/Components/RefundManager/RefundManager.php +++ b/src/Components/RefundManager/RefundManager.php @@ -249,17 +249,19 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont } # also add reset stock to order line item, so we can retrieve it through API # multiple refunds for a single line item are possible, so if previous reset stock exists, increase it - $alreadyResetStock = $orderItem->getCustomFields()['mollie_payments_stock']['reset_stock_quantity'] ?? 0; - $this->orderLineItemRepository->update([ - [ - 'id' => $orderItem->getId(), - 'customFields' => [ - 'mollie_payments_stock' => [ - 'reset_stock_quantity' => $alreadyResetStock + $item->getStockIncreaseQty() - ] - ] - ], - ], $context); + $lineItemAttributes = new OrderLineItemEntityAttributes($orderItem); + $alreadyResetStock = $lineItemAttributes->getResetStockQuantity() ?? 0; + + #todo: The mollieOrderLineID always gets removed when upserting/updating the repository, for now update the array + $customFields = $orderItem->getCustomFields(); + $customFields['mollie_payments']['reset_stock_quantity'] = $alreadyResetStock + $item->getStockIncreaseQty(); + + $data = [ + 'id' => $orderItem->getId(), + 'customFields' => $customFields + ]; + + $this->orderLineItemRepository->upsert([$data], $context); } return $refund; diff --git a/src/Struct/OrderLineItemEntity/OrderLineItemEntityAttributes.php b/src/Struct/OrderLineItemEntity/OrderLineItemEntityAttributes.php index 02b99abf9..c263e20f8 100644 --- a/src/Struct/OrderLineItemEntity/OrderLineItemEntityAttributes.php +++ b/src/Struct/OrderLineItemEntity/OrderLineItemEntityAttributes.php @@ -39,6 +39,11 @@ class OrderLineItemEntityAttributes */ private $subscriptionRepetitionCount; + /** + * @var int + */ + private $resetStockQuantity; + /** * @param OrderLineItemEntity $lineItem @@ -47,6 +52,7 @@ public function __construct(OrderLineItemEntity $lineItem) { $this->voucherType = $this->getCustomFieldValue($lineItem, 'voucher_type'); $this->mollieOrderLineID = $this->getCustomFieldValue($lineItem, 'order_line_id'); + $this->resetStockQuantity = (int)$this->getCustomFieldValue($lineItem, 'reset_stock_quantity'); $this->subscriptionProduct = (bool)$this->getCustomFieldValue($lineItem, 'subscription_enabled'); $this->subscriptionInterval = (int)$this->getCustomFieldValue($lineItem, 'subscription_interval'); @@ -81,6 +87,14 @@ public function getMollieOrderLineID(): string return $this->mollieOrderLineID; } + /** + * @return int + */ + public function getResetStockQuantity(): int + { + return $this->resetStockQuantity; + } + /** * @return bool */ diff --git a/tests/PHPUnit/Components/RefundManager/RefundData/RefundDataTest.php b/tests/PHPUnit/Components/RefundManager/RefundData/RefundDataTest.php index f4a6cf8e1..18694e2f9 100644 --- a/tests/PHPUnit/Components/RefundManager/RefundData/RefundDataTest.php +++ b/tests/PHPUnit/Components/RefundManager/RefundData/RefundDataTest.php @@ -56,6 +56,7 @@ public function testCartItems() $lineItem->setTotalPrice(2 * 19.99); $lineItem->setReferencedId('product-id-1'); $lineItem->setPayload(['productNumber' => 'P123']); + $resetStockQuantity = 0; $items[] = new ProductItem($lineItem, [], 2); @@ -78,6 +79,7 @@ public function testCartItems() ], 'isPromotion' => false, 'isDelivery' => false, + 'resetStockQuantity' => $resetStockQuantity + 2 ], ] ]; diff --git a/tests/PHPUnit/Components/RefundManager/RefundManagerTest.php b/tests/PHPUnit/Components/RefundManager/RefundManagerTest.php index 131e142f0..2216e25d4 100644 --- a/tests/PHPUnit/Components/RefundManager/RefundManagerTest.php +++ b/tests/PHPUnit/Components/RefundManager/RefundManagerTest.php @@ -10,6 +10,7 @@ use Kiener\MolliePayments\Components\RefundManager\Request\RefundRequest; use Kiener\MolliePayments\Components\RefundManager\Request\RefundRequestItem; use Kiener\MolliePayments\Service\MollieApi\Order; +use MolliePayments\Tests\Fakes\FakeEntityRepository; use MolliePayments\Tests\Fakes\FakeOrderService; use MolliePayments\Tests\Fakes\FakeRefundService; use MolliePayments\Tests\Fakes\FlowBuilder\FakeFlowBuilderDispatcher; @@ -19,6 +20,7 @@ use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection; +use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemDefinition; use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Framework\Context; @@ -60,6 +62,7 @@ protected function setUp(): void $fakeOrderService = new FakeOrderService($order); $fakeRefundService = new FakeRefundService('r-xyz-123', 9999); + $fakeOrderLineItemRepository = new FakeEntityRepository(new OrderLineItemDefinition()); $this->fakeStockUpdater = new FakeStockManager(); /** @var Order $fakeOrder */ @@ -77,7 +80,8 @@ protected function setUp(): void new FakeFlowBuilderFactory($this->fakeFlowBuilderDispatcher), $flowBuilderEventFactory, $this->fakeStockUpdater, - new NullLogger() + new NullLogger(), + $fakeOrderLineItemRepository ); } @@ -162,4 +166,4 @@ public function testStockReset() $this->assertEquals('r-xyz-123', $this->fakeStockUpdater->getMollieRefundID()); } -} \ No newline at end of file +} From 0833ee252a4f6de7d1a8408fb59f3e8d3e7cc5c4 Mon Sep 17 00:00:00 2001 From: Melvin Achterhuis Date: Tue, 26 Jul 2022 09:55:23 +0200 Subject: [PATCH 3/3] Fix unit test --- .../RefundManager/RefundData/RefundDataTest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/PHPUnit/Components/RefundManager/RefundData/RefundDataTest.php b/tests/PHPUnit/Components/RefundManager/RefundData/RefundDataTest.php index 18694e2f9..f94ef450c 100644 --- a/tests/PHPUnit/Components/RefundManager/RefundData/RefundDataTest.php +++ b/tests/PHPUnit/Components/RefundManager/RefundData/RefundDataTest.php @@ -56,7 +56,11 @@ public function testCartItems() $lineItem->setTotalPrice(2 * 19.99); $lineItem->setReferencedId('product-id-1'); $lineItem->setPayload(['productNumber' => 'P123']); - $resetStockQuantity = 0; + $lineItem->setCustomFields([ + 'mollie_payments' => [ + 'reset_stock_quantity' => 2 + ], + ]); $items[] = new ProductItem($lineItem, [], 2); @@ -79,7 +83,7 @@ public function testCartItems() ], 'isPromotion' => false, 'isDelivery' => false, - 'resetStockQuantity' => $resetStockQuantity + 2 + 'resetStockQuantity' => 2 ], ] ];