Skip to content

Commit

Permalink
Fix order cancellation process to be more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
convenient committed Sep 29, 2023
1 parent cb547cf commit 0a26269
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 30 deletions.
90 changes: 90 additions & 0 deletions dev/MagentoTests/Integration/Cancel/CancelOrder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
namespace Ampersand\DisableStockReservation\Test\Integration\Cancel;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\TestFramework\Helper\Bootstrap;
use TddWizard\Fixtures\Catalog\ProductBuilder;
use TddWizard\Fixtures\Catalog\ProductFixture;
use TddWizard\Fixtures\Checkout\CustomerCheckout;
use TddWizard\Fixtures\Checkout\CartBuilder;
use TddWizard\Fixtures\Customer\CustomerFixture;
use TddWizard\Fixtures\Customer\CustomerBuilder;
use TddWizard\Fixtures\Customer\AddressBuilder;
use PHPUnit\Framework\TestCase;

class CancelOrder extends TestCase
{
/** @var ObjectManagerInterface */
private $objectManager;

/** @var ProductRepositoryInterface */
private $productRepository;

/** @var ProductFixture */
private $productFixture;

/** @var CustomerFixture */
private $customerFixture;

public function setUp(): void
{
parent::setUp();

$this->objectManager = Bootstrap::getObjectManager();
$this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
$this->productRepository->cleanCache();
}

public function testCancelOrderBaseline()
{
$sku = uniqid('cancel_order_baseline');

/**
* Create a product with 5 qty
*/
$this->productFixture = new ProductFixture(
ProductBuilder::aSimpleProduct()
->withSku($sku)
->withPrice(10)
->withStockQty(5)
->withIsInStock(true)
->build()
);

/**
* Create a customer and login
*/
$this->customerFixture = new CustomerFixture(CustomerBuilder::aCustomer()->withAddresses(
AddressBuilder::anAddress()->asDefaultBilling(),
AddressBuilder::anAddress()->asDefaultShipping()
)->build());
$this->customerFixture->login();

/**
* Order 1 qty
*/
$checkout = CustomerCheckout::fromCart(
CartBuilder::forCurrentSession()
->withSimpleProduct(
$this->productFixture->getSku(),
1
)
->build()
);

$order = $checkout
->withPaymentMethodCode('checkmo')
->placeOrder();
$this->assertGreaterThan(0, strlen($order->getIncrementId()), 'the order does not have a valid increment_id');
$this->assertIsNumeric($order->getId(), 'the order does not have an entity_id');

/**
* Cancel the order
*/
$this->assertTrue($order->canCancel(), 'Cannot cancel the order');
$order->cancel();
$this->assertEquals('canceled', $order->getStatus(), 'The order was not cancelled');
}
}
61 changes: 31 additions & 30 deletions src/Service/ExecuteSourceDeductionForItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,38 +139,39 @@ public function executeSourceDeductionForItems(OrderItem $orderItem, array $item

/** @var OrderItem $item */
foreach ($itemsToCancel as $item) {
$itemsSkus[] = $item->getSku();
$sourceCodesBySku = $this->getSourceCodesBySkus->execute([$item->getSku()]);
$sourceItems = $this->sourceRepository->getSourceItemBySku(
(string)$order->getId(),
$item->getSku()
);
foreach ($sourceItems as $sourceItem) {
$sourceCode = $sourceItem->getSourceCode();

// if source has been unassigned, return to default stock
if (!in_array($sourceCode, $sourceCodesBySku)) {
$sourceCode = 'default';
}
$sourceDeductionRequest = $this->sourceDeductionRequestFactory->create([
'sourceCode' => $sourceCode,
'items' => [
$this->itemToDeductFactory->create([
'sku' => $item->getSku(),
'qty' => -$sourceItem->getQtyToDeduct()
])
],
'salesChannel' => $salesChannel,
'salesEvent' => $salesEvent
]);

try {
$this->sourceDeductionService->execute($sourceDeductionRequest);
} catch (NoSuchEntityException $noSuchEntityException) {
if (!$graceful) {
throw $noSuchEntityException;
try {
$itemsSkus[] = $item->getSku();
$sourceCodesBySku = $this->getSourceCodesBySkus->execute([$item->getSku()]);
$sourceItems = $this->sourceRepository->getSourceItemBySku(
(string)$order->getId(),
$item->getSku()
);
foreach ($sourceItems as $sourceItem) {
$sourceCode = $sourceItem->getSourceCode();

// if source has been unassigned, return to default stock
if (!in_array($sourceCode, $sourceCodesBySku)) {
$sourceCode = 'default';
}
$sourceDeductionRequest = $this->sourceDeductionRequestFactory->create([
'sourceCode' => $sourceCode,
'items' => [
$this->itemToDeductFactory->create([
'sku' => $item->getSku(),
'qty' => -$sourceItem->getQtyToDeduct()
])
],
'salesChannel' => $salesChannel,
'salesEvent' => $salesEvent
]);

$this->sourceDeductionService->execute($sourceDeductionRequest);
}
} catch (NoSuchEntityException $noSuchEntityException) {
if ($graceful) {
continue;
}
throw $noSuchEntityException;
}
}

Expand Down

0 comments on commit 0a26269

Please sign in to comment.