-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inventory sales backorder functionality #156
Changes from 5 commits
944d803
34027e6
5554add
bd49c0c
ed34aa9
0b26fcb
f872393
a423acd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\InventorySales\Plugin\Model; | ||
|
||
use Magento\CatalogInventory\Model\Stock\Item; | ||
use Magento\InventoryApi\Api\IsProductInStockInterface; | ||
use Magento\CatalogInventory\Model\Stock\StockItemRepository; | ||
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory; | ||
use Magento\Catalog\Model\ProductRepository; | ||
|
||
class BackorderStockStatusPlugin | ||
{ | ||
/** | ||
* @var StockItemRepository | ||
*/ | ||
private $stockItemRepository; | ||
|
||
/** | ||
* @var StockItemCriteriaInterfaceFactory | ||
*/ | ||
private $stockItemCriteriaFactory; | ||
|
||
/** | ||
* @var ProductRepository | ||
*/ | ||
private $productRepository; | ||
|
||
public function __construct( | ||
StockItemRepository $stockItemRepository, | ||
StockItemCriteriaInterfaceFactory $stockItemCriteriaFactory, | ||
ProductRepository $productRepository | ||
) { | ||
$this->stockItemRepository = $stockItemRepository; | ||
$this->stockItemCriteriaFactory = $stockItemCriteriaFactory; | ||
$this->productRepository = $productRepository; | ||
} | ||
|
||
/** | ||
* Return true status if backorders is enabled for the item | ||
* | ||
* @param IsProductInStockInterface $subject | ||
* @param callable $proceed | ||
* @param string $sku | ||
* @param int $stockId | ||
* @return bool | ||
* @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||
*/ | ||
public function aroundExecute( | ||
IsProductInStockInterface $subject, | ||
callable $proceed, | ||
string $sku, | ||
int $stockId | ||
): bool { | ||
$productData = $this->productRepository->get($sku); | ||
$productId = $productData->getId(); | ||
|
||
$stockItemCriteria = $this->stockItemCriteriaFactory->create(); | ||
$stockItemCriteria->setProductsFilter($productId); | ||
$stockItemsCollection = $this->stockItemRepository->getList($stockItemCriteria); | ||
|
||
/** @var Item $stockItem */ | ||
$stockItem = current($stockItemsCollection->getItems()); | ||
|
||
if ($stockItem->getData('backorders') > 0) { | ||
return true; | ||
} | ||
|
||
return $proceed($sku, $stockId); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
namespace Magento\InventorySales\Test\Integration\Stock; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix code style |
||
|
||
use Magento\Catalog\Api\Data\ProductInterface; | ||
use Magento\Catalog\Api\ProductRepositoryInterface; | ||
use Magento\Catalog\Model\ProductRepository; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like unused dependency |
||
use Magento\CatalogInventory\Api\Data\StockItemInterface; | ||
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory; | ||
use Magento\CatalogInventory\Api\StockItemRepositoryInterface; | ||
use Magento\Framework\Api\SearchCriteriaBuilder; | ||
use Magento\Framework\Api\SearchCriteriaInterface; | ||
use Magento\Framework\Indexer\IndexerInterface; | ||
use Magento\Inventory\Indexer\StockItemIndexerInterface; | ||
use Magento\InventoryApi\Api\Data\SourceItemInterface; | ||
use Magento\InventoryApi\Api\GetProductQuantityInStockInterface; | ||
use Magento\InventoryApi\Api\IsProductInStockInterface; | ||
use Magento\InventoryApi\Api\SourceItemRepositoryInterface; | ||
use Magento\InventoryApi\Api\SourceItemsSaveInterface; | ||
use Magento\TestFramework\Helper\Bootstrap; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class IsBackorderedProductInStockTest extends TestCase | ||
{ | ||
const PRODUCT_SKU = 'SKU-2'; | ||
|
||
/** | ||
* @var SourceItemRepositoryInterface | ||
*/ | ||
private $sourceItemRepository; | ||
|
||
/** | ||
* @var SearchCriteriaBuilder | ||
*/ | ||
private $searchCriteriaBuilder; | ||
|
||
/** | ||
* @var SourceItemsSaveInterface | ||
*/ | ||
private $sourceItemsSaveInterface; | ||
|
||
/** | ||
* @var IndexerInterface | ||
*/ | ||
private $indexer; | ||
|
||
/** | ||
* @var ProductRepository | ||
*/ | ||
private $productRepository; | ||
|
||
/** | ||
* @var GetProductQuantityInStockInterface | ||
*/ | ||
private $isProductInStock; | ||
|
||
/** | ||
* @var StockItemRepositoryInterface | ||
*/ | ||
private $stockItemRepository; | ||
|
||
/** | ||
* @var StockItemCriteriaInterfaceFactory | ||
*/ | ||
protected $stockItemCriteriaInterfaceFactory; | ||
|
||
protected function setUp() | ||
{ | ||
$this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class); | ||
$this->stockItemRepository = Bootstrap::getObjectManager()->create(StockItemRepositoryInterface::class); | ||
$this->stockItemCriteriaInterfaceFactory = Bootstrap::getObjectManager()->create( | ||
StockItemCriteriaInterfaceFactory::class | ||
); | ||
$this->sourceItemRepository = Bootstrap::getObjectManager()->create(SourceItemRepositoryInterface::class); | ||
$this->searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); | ||
$this->sourceItemsSaveInterface = Bootstrap::getObjectManager()->create(SourceItemsSaveInterface::class); | ||
$this->indexer = Bootstrap::getObjectManager()->create(IndexerInterface::class); | ||
$this->indexer->load(StockItemIndexerInterface::INDEXER_ID); | ||
$this->isProductInStock = Bootstrap::getObjectManager()->create( | ||
IsProductInStockInterface::class | ||
); | ||
} | ||
|
||
/** | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stocks.php | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/source_items.php | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock_source_link.php | ||
* @magentoDbIsolation disabled | ||
*/ | ||
public function testBackorderedZeroQtyProductIsInStock() | ||
{ | ||
/** @var ProductInterface $product */ | ||
$product = $this->productRepository->get(self::PRODUCT_SKU); | ||
$stockItemSearchCriteria = $this->stockItemCriteriaInterfaceFactory->create(); | ||
$stockItemSearchCriteria->setProductsFilter($product->getId()); | ||
$stockItemsCollection = $this->stockItemRepository->getList($stockItemSearchCriteria); | ||
|
||
/** @var StockItemInterface $stockItem */ | ||
$stockItem = current($stockItemsCollection->getItems()); | ||
$stockItem->setBackorders(1); | ||
$this->stockItemRepository->save($stockItem); | ||
|
||
$sourceItem = $this->getSourceItemBySKU(self::PRODUCT_SKU); | ||
$this->changeSourceItemQty($sourceItem, -15); | ||
|
||
$this->assertTrue($this->isProductInStock->execute(self::PRODUCT_SKU, 1)); | ||
} | ||
|
||
/** | ||
* @magentoDbIsolation disabled | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stocks.php | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/source_items.php | ||
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock_source_link.php | ||
*/ | ||
public function testZeroQtyProductIsOutOfStock() | ||
{ | ||
$sourceItem = $this->getSourceItemBySKU(self::PRODUCT_SKU); | ||
$this->changeSourceItemQty($sourceItem, 0); | ||
|
||
$this->assertFalse($this->isProductInStock->execute(self::PRODUCT_SKU, 1)); | ||
} | ||
|
||
/** | ||
* @param string $sku | ||
* @return SourceItemInterface | ||
*/ | ||
private function getSourceItemBySKU(string $sku) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Provide return typing |
||
{ | ||
/** @var SearchCriteriaInterface $sourceItemSearchCriteria */ | ||
$sourceItemSearchCriteria = $this->searchCriteriaBuilder->addFilter('sku', $sku)->create(); | ||
$sourceItemSearchResult = $this->sourceItemRepository->getList($sourceItemSearchCriteria); | ||
|
||
/** @var SourceItemInterface $sourceItem */ | ||
return current($sourceItemSearchResult->getItems()); | ||
} | ||
|
||
/** | ||
* @param SourceItemInterface $sourceItem | ||
* @param $qty | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Specify type |
||
*/ | ||
private function changeSourceItemQty(SourceItemInterface $sourceItem, $qty) | ||
{ | ||
$sourceItem->setQuantity($qty); | ||
$this->sourceItemsSaveInterface->execute([$sourceItem]); | ||
$this->indexer->reindexRow(5); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?xml version="1.0"?> | ||
<!-- | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
--> | ||
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> | ||
<type name="Magento\InventoryApi\Api\IsProductInStockInterface"> | ||
<plugin name="backorderInventoryStockStatus" type="Magento\InventorySales\Plugin\Model\BackorderStockStatusPlugin"/> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use underscore for mane separating |
||
</type> | ||
</config> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use methods from interface but not from implementation
\Magento\CatalogInventory\Api\Data\StockItemInterface::getBackorders