diff --git a/vendor/magento/module-sales/Model/RefundOrder.php b/vendor/magento/module-sales/Model/RefundOrder.php index 07555cba1b7..ab7461308ca 100644 --- a/vendor/magento/module-sales/Model/RefundOrder.php +++ b/vendor/magento/module-sales/Model/RefundOrder.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ResourceConnection; use Magento\Sales\Api\CreditmemoRepositoryInterface; use Magento\Sales\Api\OrderRepositoryInterface; @@ -19,7 +20,7 @@ use Magento\Sales\Model\Order\Validation\RefundOrderInterface as RefundOrderVali use Psr\Log\LoggerInterface; /** - * Class RefundOrder + * Class RefundOrder for an order * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class RefundOrder implements RefundOrderInterface @@ -74,6 +75,11 @@ class RefundOrder implements RefundOrderInterface */ private $logger; + /** + * @var OrderMutexInterface + */ + private $orderMutex; + /** * RefundOrder constructor. * @@ -87,6 +93,7 @@ class RefundOrder implements RefundOrderInterface * @param NotifierInterface $notifier * @param OrderConfig $config * @param LoggerInterface $logger + * @param OrderMutex|null $orderMutex * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -99,7 +106,8 @@ class RefundOrder implements RefundOrderInterface RefundOrderValidator $validator, NotifierInterface $notifier, OrderConfig $config, - LoggerInterface $logger + LoggerInterface $logger, + ?OrderMutexInterface $orderMutex = null ) { $this->resourceConnection = $resourceConnection; $this->orderStateResolver = $orderStateResolver; @@ -111,6 +119,7 @@ class RefundOrder implements RefundOrderInterface $this->notifier = $notifier; $this->config = $config; $this->logger = $logger; + $this->orderMutex = $orderMutex ?: ObjectManager::getInstance()->get(OrderMutexInterface::class); } /** @@ -124,7 +133,45 @@ class RefundOrder implements RefundOrderInterface \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null, \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null ) { - $connection = $this->resourceConnection->getConnection('sales'); + return $this->orderMutex->execute( + (int) $orderId, + \Closure::fromCallable([$this, 'createRefund']), + [ + $orderId, + $items, + $notify, + $appendComment, + $comment, + $arguments + ] + ); + } + + /** + * Creates refund for provided order ID + * + * @param int $orderId + * @param array $items + * @param bool $notify + * @param bool $appendComment + * @param \Magento\Sales\Api\Data\InvoiceCommentCreationInterface|null $comment + * @param \Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface|null $arguments + * @return int + * @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface + * @throws \Magento\Sales\Api\Exception\CouldNotRefundException + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \DomainException + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + */ + private function createRefund( + $orderId, + array $items = [], + $notify = false, + $appendComment = false, + \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null, + \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null + ) { $order = $this->orderRepository->get($orderId); $creditmemo = $this->creditmemoDocumentFactory->createFromOrder( $order, @@ -147,7 +194,6 @@ class RefundOrder implements RefundOrderInterface __("Creditmemo Document Validation Error(s):\n" . implode("\n", $validationMessages->getMessages())) ); } - $connection->beginTransaction(); try { $creditmemo->setState(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED); $order->setCustomerNoteNotify($notify); @@ -162,10 +208,8 @@ class RefundOrder implements RefundOrderInterface $order = $this->orderRepository->save($order); $creditmemo = $this->creditmemoRepository->save($creditmemo); - $connection->commit(); } catch (\Exception $e) { $this->logger->critical($e); - $connection->rollBack(); throw new \Magento\Sales\Exception\CouldNotRefundException( __('Could not save a Creditmemo, see error log for details') ); diff --git a/vendor/magento/module-sales/Model/ShipOrder.php b/vendor/magento/module-sales/Model/ShipOrder.php index 3bb8527d6e5..aa9b76ff505 100644 --- a/vendor/magento/module-sales/Model/ShipOrder.php +++ b/vendor/magento/module-sales/Model/ShipOrder.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ResourceConnection; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Api\ShipmentRepositoryInterface; @@ -75,6 +76,11 @@ class ShipOrder implements ShipOrderInterface */ private $orderRegistrar; + /** + * @var OrderMutexInterface + */ + private $orderMutex; + /** * @param ResourceConnection $resourceConnection * @param OrderRepositoryInterface $orderRepository @@ -86,6 +92,7 @@ class ShipOrder implements ShipOrderInterface * @param NotifierInterface $notifierInterface * @param OrderRegistrarInterface $orderRegistrar * @param LoggerInterface $logger + * @param OrderMutex|null $orderMutex * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -98,7 +105,8 @@ class ShipOrder implements ShipOrderInterface ShipOrderValidator $shipOrderValidator, NotifierInterface $notifierInterface, OrderRegistrarInterface $orderRegistrar, - LoggerInterface $logger + LoggerInterface $logger, + ?OrderMutexInterface $orderMutex = null ) { $this->resourceConnection = $resourceConnection; $this->orderRepository = $orderRepository; @@ -110,6 +118,7 @@ class ShipOrder implements ShipOrderInterface $this->notifierInterface = $notifierInterface; $this->logger = $logger; $this->orderRegistrar = $orderRegistrar; + $this->orderMutex = $orderMutex ?: ObjectManager::getInstance()->get(OrderMutexInterface::class); } /** @@ -140,7 +149,51 @@ class ShipOrder implements ShipOrderInterface array $packages = [], \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null ) { - $connection = $this->resourceConnection->getConnection('sales'); + return $this->orderMutex->execute( + (int)$orderId, + \Closure::fromCallable([$this, 'createShipment']), + [ + $orderId, + $items, + $notify, + $appendComment, + $comment, + $tracks, + $packages, + $arguments + ] + ); + } + + /** + * Creates shipment for provided order ID + * + * @param int $orderId + * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items + * @param bool $notify + * @param bool $appendComment + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment + * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks + * @param \Magento\Sales\Api\Data\ShipmentPackageCreationInterface[] $packages + * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments + * @return int + * @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface + * @throws \Magento\Sales\Api\Exception\CouldNotShipExceptionInterface + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \DomainException + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + */ + private function createShipment( + $orderId, + array $items = [], + $notify = false, + $appendComment = false, + \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + array $tracks = [], + array $packages = [], + \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null + ) { $order = $this->orderRepository->get($orderId); $shipment = $this->shipmentDocumentFactory->create( $order, @@ -166,7 +219,6 @@ class ShipOrder implements ShipOrderInterface __("Shipment Document Validation Error(s):\n" . implode("\n", $validationMessages->getMessages())) ); } - $connection->beginTransaction(); try { $this->orderRegistrar->register($order, $shipment); $shipment = $this->shipmentRepository->save($shipment); @@ -177,10 +229,8 @@ class ShipOrder implements ShipOrderInterface $order->setStatus($this->config->getStateDefaultStatus($order->getState())); } $this->orderRepository->save($order); - $connection->commit(); } catch (\Exception $e) { $this->logger->critical($e); - $connection->rollBack(); throw new \Magento\Sales\Exception\CouldNotShipException( __('Could not save a shipment, see error log for details') );