Skip to content

Commit cac6fcd

Browse files
committed
ACP2E-694: [Magento Cloud] REST API intermittently over writes the results of shipping results
1 parent 745a465 commit cac6fcd

File tree

2 files changed

+118
-11
lines changed

2 files changed

+118
-11
lines changed

app/code/Magento/Sales/Model/RefundOrder.php

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\Sales\Model;
88

9+
use Magento\Framework\App\ObjectManager;
910
use Magento\Framework\App\ResourceConnection;
1011
use Magento\Sales\Api\CreditmemoRepositoryInterface;
1112
use Magento\Sales\Api\OrderRepositoryInterface;
@@ -19,7 +20,7 @@
1920
use Psr\Log\LoggerInterface;
2021

2122
/**
22-
* Class RefundOrder
23+
* Class RefundOrder for an order
2324
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2425
*/
2526
class RefundOrder implements RefundOrderInterface
@@ -74,6 +75,11 @@ class RefundOrder implements RefundOrderInterface
7475
*/
7576
private $logger;
7677

78+
/**
79+
* @var OrderMutexInterface
80+
*/
81+
private $orderMutex;
82+
7783
/**
7884
* RefundOrder constructor.
7985
*
@@ -87,6 +93,7 @@ class RefundOrder implements RefundOrderInterface
8793
* @param NotifierInterface $notifier
8894
* @param OrderConfig $config
8995
* @param LoggerInterface $logger
96+
* @param OrderMutex|null $orderMutex
9097
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
9198
*/
9299
public function __construct(
@@ -99,7 +106,8 @@ public function __construct(
99106
RefundOrderValidator $validator,
100107
NotifierInterface $notifier,
101108
OrderConfig $config,
102-
LoggerInterface $logger
109+
LoggerInterface $logger,
110+
?OrderMutexInterface $orderMutex = null
103111
) {
104112
$this->resourceConnection = $resourceConnection;
105113
$this->orderStateResolver = $orderStateResolver;
@@ -111,6 +119,7 @@ public function __construct(
111119
$this->notifier = $notifier;
112120
$this->config = $config;
113121
$this->logger = $logger;
122+
$this->orderMutex = $orderMutex ?: ObjectManager::getInstance()->get(OrderMutexInterface::class);
114123
}
115124

116125
/**
@@ -124,7 +133,45 @@ public function execute(
124133
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
125134
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
126135
) {
127-
$connection = $this->resourceConnection->getConnection('sales');
136+
return $this->orderMutex->execute(
137+
(int) $orderId,
138+
\Closure::fromCallable([$this, 'createRefund']),
139+
[
140+
$orderId,
141+
$items,
142+
$notify,
143+
$appendComment,
144+
$comment,
145+
$arguments
146+
]
147+
);
148+
}
149+
150+
/**
151+
* Creates refund for provided order ID
152+
*
153+
* @param int $orderId
154+
* @param array $items
155+
* @param bool $notify
156+
* @param bool $appendComment
157+
* @param \Magento\Sales\Api\Data\InvoiceCommentCreationInterface|null $comment
158+
* @param \Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface|null $arguments
159+
* @return int
160+
* @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface
161+
* @throws \Magento\Sales\Api\Exception\CouldNotRefundException
162+
* @throws \Magento\Framework\Exception\InputException
163+
* @throws \Magento\Framework\Exception\NoSuchEntityException
164+
* @throws \DomainException
165+
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
166+
*/
167+
private function createRefund(
168+
$orderId,
169+
array $items = [],
170+
$notify = false,
171+
$appendComment = false,
172+
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
173+
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
174+
) {
128175
$order = $this->orderRepository->get($orderId);
129176
$creditmemo = $this->creditmemoDocumentFactory->createFromOrder(
130177
$order,
@@ -147,7 +194,6 @@ public function execute(
147194
__("Creditmemo Document Validation Error(s):\n" . implode("\n", $validationMessages->getMessages()))
148195
);
149196
}
150-
$connection->beginTransaction();
151197
try {
152198
$creditmemo->setState(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED);
153199
$order->setCustomerNoteNotify($notify);
@@ -162,10 +208,8 @@ public function execute(
162208

163209
$order = $this->orderRepository->save($order);
164210
$creditmemo = $this->creditmemoRepository->save($creditmemo);
165-
$connection->commit();
166211
} catch (\Exception $e) {
167212
$this->logger->critical($e);
168-
$connection->rollBack();
169213
throw new \Magento\Sales\Exception\CouldNotRefundException(
170214
__('Could not save a Creditmemo, see error log for details')
171215
);

app/code/Magento/Sales/Model/ShipOrder.php

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\Sales\Model;
77

8+
use Magento\Framework\App\ObjectManager;
89
use Magento\Framework\App\ResourceConnection;
910
use Magento\Sales\Api\OrderRepositoryInterface;
1011
use Magento\Sales\Api\ShipmentRepositoryInterface;
@@ -75,6 +76,11 @@ class ShipOrder implements ShipOrderInterface
7576
*/
7677
private $orderRegistrar;
7778

79+
/**
80+
* @var OrderMutexInterface
81+
*/
82+
private $orderMutex;
83+
7884
/**
7985
* @param ResourceConnection $resourceConnection
8086
* @param OrderRepositoryInterface $orderRepository
@@ -86,6 +92,7 @@ class ShipOrder implements ShipOrderInterface
8692
* @param NotifierInterface $notifierInterface
8793
* @param OrderRegistrarInterface $orderRegistrar
8894
* @param LoggerInterface $logger
95+
* @param OrderMutex|null $orderMutex
8996
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
9097
*/
9198
public function __construct(
@@ -98,7 +105,8 @@ public function __construct(
98105
ShipOrderValidator $shipOrderValidator,
99106
NotifierInterface $notifierInterface,
100107
OrderRegistrarInterface $orderRegistrar,
101-
LoggerInterface $logger
108+
LoggerInterface $logger,
109+
?OrderMutexInterface $orderMutex = null
102110
) {
103111
$this->resourceConnection = $resourceConnection;
104112
$this->orderRepository = $orderRepository;
@@ -110,6 +118,7 @@ public function __construct(
110118
$this->notifierInterface = $notifierInterface;
111119
$this->logger = $logger;
112120
$this->orderRegistrar = $orderRegistrar;
121+
$this->orderMutex = $orderMutex ?: ObjectManager::getInstance()->get(OrderMutexInterface::class);
113122
}
114123

115124
/**
@@ -139,8 +148,53 @@ public function execute(
139148
array $tracks = [],
140149
array $packages = [],
141150
\Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null
151+
)
152+
{
153+
return $this->orderMutex->execute(
154+
(int)$orderId,
155+
\Closure::fromCallable([$this, 'createShipment']),
156+
[
157+
$orderId,
158+
$items,
159+
$notify,
160+
$appendComment,
161+
$comment,
162+
$tracks,
163+
$packages,
164+
$arguments
165+
]
166+
);
167+
}
168+
169+
/**
170+
* Creates shipment for provided order ID
171+
*
172+
* @param int $orderId
173+
* @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items
174+
* @param bool $notify
175+
* @param bool $appendComment
176+
* @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment
177+
* @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks
178+
* @param \Magento\Sales\Api\Data\ShipmentPackageCreationInterface[] $packages
179+
* @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments
180+
* @return int
181+
* @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface
182+
* @throws \Magento\Sales\Api\Exception\CouldNotShipExceptionInterface
183+
* @throws \Magento\Framework\Exception\InputException
184+
* @throws \Magento\Framework\Exception\NoSuchEntityException
185+
* @throws \DomainException
186+
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
187+
*/
188+
private function createShipment(
189+
$orderId,
190+
array $items = [],
191+
$notify = false,
192+
$appendComment = false,
193+
\Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null,
194+
array $tracks = [],
195+
array $packages = [],
196+
\Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null
142197
) {
143-
$connection = $this->resourceConnection->getConnection('sales');
144198
$order = $this->orderRepository->get($orderId);
145199
$shipment = $this->shipmentDocumentFactory->create(
146200
$order,
@@ -166,9 +220,20 @@ public function execute(
166220
__("Shipment Document Validation Error(s):\n" . implode("\n", $validationMessages->getMessages()))
167221
);
168222
}
169-
$connection->beginTransaction();
170223
try {
171224
$this->orderRegistrar->register($order, $shipment);
225+
/*foreach ($shipment->getItems() as $item) {
226+
if ($item->getQty() > 0) {
227+
$orderItem = $item->getOrderItem();
228+
}
229+
$orderItem = $item->getOrderItem();
230+
$orderItem->setQtyShipped( $item->getQty() );
231+
$orderItem->setQtyShipped( $orderItem->getQtyShipped() + $item->getQty() );
232+
$orderItem->save();
233+
}
234+
$order = $shipment->getOrder()->load( $shipment->getOrder()->getId() );
235+
$order->save();*/
236+
172237
$shipment = $this->shipmentRepository->save($shipment);
173238
if ($order->getState() === Order::STATE_NEW) {
174239
$order->setState(
@@ -177,10 +242,8 @@ public function execute(
177242
$order->setStatus($this->config->getStateDefaultStatus($order->getState()));
178243
}
179244
$this->orderRepository->save($order);
180-
$connection->commit();
181245
} catch (\Exception $e) {
182246
$this->logger->critical($e);
183-
$connection->rollBack();
184247
throw new \Magento\Sales\Exception\CouldNotShipException(
185248
__('Could not save a shipment, see error log for details')
186249
);

0 commit comments

Comments
 (0)