Skip to content

Commit

Permalink
Merge pull request magento#769 from magento-engcom/MSI-757
Browse files Browse the repository at this point in the history
MSI-757: Add Inventory Index invalidation when Source is enabled or disabled.
  • Loading branch information
Valeriy Nayda authored Apr 5, 2018
2 parents e9b13e1 + e2374a6 commit 7a0e831
Show file tree
Hide file tree
Showing 11 changed files with 325 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
*/
declare(strict_types=1);

namespace Magento\InventoryIndexer\Model;
namespace Magento\InventoryIndexer\Model\ResourceModel;

use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Exception\LocalizedException;
use Magento\InventoryIndexer\Model\StockIndexTableNameResolverInterface;
use Magento\InventorySales\Model\GetStockItemDataInterface;
use Magento\InventoryIndexer\Indexer\IndexStructure;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryIndexer\Model\ResourceModel;

use Magento\Framework\App\ResourceConnection;
use Magento\Inventory\Model\ResourceModel\Source;
use Magento\Inventory\Model\ResourceModel\SourceItem;
use Magento\Inventory\Model\ResourceModel\StockSourceLink;
use Magento\InventoryApi\Api\Data\SourceInterface;

/**
* Is Inventory Indexer invalidation required after Source enabling or disabling.
*/
class IsInvalidationRequiredForSource
{
/**
* @var ResourceConnection
*/
private $resourceConnection;

/**
* @param ResourceConnection $resourceConnection
*/
public function __construct(
ResourceConnection $resourceConnection
) {
$this->resourceConnection = $resourceConnection;
}

/**
* Returns 'true' only if Source 'enabled' value is changed, Source is linked to Stock and contains at least one
* Source Item.
*
* @param string $sourceCode
* @param bool $enabled
* @return bool
*/
public function execute(string $sourceCode, bool $enabled): bool
{
$connection = $this->resourceConnection->getConnection();
$sourceTable = $this->resourceConnection->getTableName(Source::TABLE_NAME_SOURCE);
$sourceItemTable = $this->resourceConnection->getTableName(SourceItem::TABLE_NAME_SOURCE_ITEM);
$stockSourceLinkTable = $this->resourceConnection->getTableName(StockSourceLink::TABLE_NAME_STOCK_SOURCE_LINK);

$select = $connection->select()
->from(
['sources' => $sourceTable],
'(sources.' . SourceInterface::ENABLED . ' != ' . (int)$enabled . ')'
)
->joinInner(
['source_item' => $sourceItemTable],
'sources.' . SourceInterface::SOURCE_CODE . '=' . 'source_item.' . SourceInterface::SOURCE_CODE,
null
)->joinInner(
['stock_source_link' => $stockSourceLinkTable],
'sources.' . SourceInterface::SOURCE_CODE . '=' . 'stock_source_link.' . SourceInterface::SOURCE_CODE,
null
)
->where('sources.' . SourceInterface::SOURCE_CODE . ' = ?', $sourceCode);

return (bool)$connection->fetchOne($select);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryIndexer\Plugin\InventoryApi;

use Magento\Framework\Indexer\IndexerRegistry;
use Magento\InventoryApi\Api\Data\SourceInterface;
use Magento\InventoryApi\Api\SourceRepositoryInterface;
use Magento\InventoryIndexer\Indexer\InventoryIndexer;
use Magento\InventoryIndexer\Model\ResourceModel\IsInvalidationRequiredForSource;

/**
* Invalidate Inventory Indexer after Source was enabled or disabled.
*/
class InvalidateAfterEnablingOrDisablingSourcePlugin
{
/**
* @var IndexerRegistry
*/
private $indexerRegistry;

/**
* @var IsInvalidationRequiredForSource
*/
private $isInvalidationRequiredForSource;

/**
* @param IndexerRegistry $indexerRegistry
* @param IsInvalidationRequiredForSource $isInvalidationRequiredForSource
*/
public function __construct(
IndexerRegistry $indexerRegistry,
IsInvalidationRequiredForSource $isInvalidationRequiredForSource
) {
$this->indexerRegistry = $indexerRegistry;
$this->isInvalidationRequiredForSource = $isInvalidationRequiredForSource;
}

/**
* Invalidate Inventory Indexer after Source was enabled or disabled.
*
* @param SourceRepositoryInterface $subject
* @param callable $proceed
* @param SourceInterface $source
* @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function aroundSave(
SourceRepositoryInterface $subject,
callable $proceed,
SourceInterface $source
) {
$invalidationRequired = $this->isInvalidationRequiredForSource->execute(
$source->getSourceCode(),
(bool)$source->isEnabled()
);

$proceed($source);

if ($invalidationRequired) {
$indexer = $this->indexerRegistry->get(InventoryIndexer::INDEXER_ID);
if ($indexer->isValid()) {
$indexer->invalidate();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/**
* Invalidate InventoryIndexer
*/
class ReindexAfterStockSourceLinksDeletePlugin
class InvalidateAfterStockSourceLinksDeletePlugin
{
/**
* @var IndexerRegistry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/**
* Invalidate InventoryIndexer
*/
class ReindexAfterStockSourceLinksSavePlugin
class InvalidateAfterStockSourceLinksSavePlugin
{
/**
* @var IndexerRegistry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace Magento\InventoryIndexer\Test\Integration\Indexer;

use Magento\InventoryIndexer\Indexer\Source\SourceIndexer;
use Magento\InventoryIndexer\Model\GetStockItemData;
use Magento\InventoryIndexer\Model\ResourceModel\GetStockItemData;
use Magento\InventorySales\Model\GetStockItemDataInterface;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use Magento\InventoryApi\Api\SourceItemRepositoryInterface;
use Magento\InventoryIndexer\Indexer\SourceItem\GetSourceItemIds;
use Magento\InventoryIndexer\Indexer\SourceItem\SourceItemIndexer;
use Magento\InventoryIndexer\Model\GetStockItemData;
use Magento\InventoryIndexer\Model\ResourceModel\GetStockItemData;
use Magento\InventorySales\Model\GetStockItemDataInterface;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace Magento\InventoryIndexer\Test\Integration\Indexer;

use Magento\InventoryIndexer\Indexer\Stock\StockIndexer;
use Magento\InventoryIndexer\Model\GetStockItemData;
use Magento\InventoryIndexer\Model\ResourceModel\GetStockItemData;
use Magento\InventorySales\Model\GetStockItemDataInterface;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryIndexer\Test\Integration;

use Magento\Framework\Indexer\IndexerInterface;
use Magento\Framework\Indexer\IndexerRegistry;
use Magento\InventoryApi\Api\SourceRepositoryInterface;
use Magento\InventoryIndexer\Indexer\InventoryIndexer;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;

/**
* Tests Indexer invalidation after Source enabled or disabled.
*/
class InvalidateAfterEnablingOrDisablingSourceTest extends TestCase
{
/**
* @var SourceRepositoryInterface
*/
private $sourceRepository;

/**
* @var IndexerInterface
*/
private $indexer;

protected function setUp()
{
$this->sourceRepository = Bootstrap::getObjectManager()->get(SourceRepositoryInterface::class);
/** @var IndexerRegistry $indexerRegistry */
$indexerRegistry = Bootstrap::getObjectManager()->get(IndexerRegistry::class);
$this->indexer = $indexerRegistry->get(InventoryIndexer::INDEXER_ID);
}

/**
* Tests Source enabling and disabling when both Stocks and Source Items are connected to current Source.
*
* @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_links.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
*
* @dataProvider indexerInvalidationDataProvider
* @param string $sourceCode
* @param bool $enable
* @param bool $expectedValid
*/
public function testIndexerInvalidation(string $sourceCode, bool $enable, bool $expectedValid)
{
$this->setSourceEnabledStatus($sourceCode, $enable);

$this->assertEquals($expectedValid, $this->indexer->isValid());
}

/**
* @return array
*/
public function indexerInvalidationDataProvider(): array
{
return [
['eu-1', true, true],
['eu-1', false, false],
['eu-disabled', true, false],
['eu-disabled', false, true],
];
}

/**
* Tests Source enabling and disabling when no Stocks or Source Items are connected to Source.
*
* @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
*
* @dataProvider sourceDoesNotHaveAllRelationsDataProvider
* @param string $sourceCode
* @param bool $enable
* @param bool $expectedValid
*/
public function testIndexerInvalidationIfSourceDoesNotHaveAnyRelations(
string $sourceCode,
bool $enable,
bool $expectedValid
) {
$this->setSourceEnabledStatus($sourceCode, $enable);

$this->assertEquals($expectedValid, $this->indexer->isValid());
}

/**
* Tests Source enabling and disabling when no Stocks are connected to current Source.
*
* @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/source_items.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
*
* @dataProvider sourceDoesNotHaveAllRelationsDataProvider
* @param string $sourceCode
* @param bool $enable
* @param bool $expectedValid
*/
public function testIndexerInvalidationIfSourceDoesNotHaveStockLinks(
string $sourceCode,
bool $enable,
bool $expectedValid
) {
$this->setSourceEnabledStatus($sourceCode, $enable);

$this->assertEquals($expectedValid, $this->indexer->isValid());
}

/**
* Tests Source enabling and disabling when no Source Items are connected to current Source.
*
* @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/stock_source_links.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
*
* @dataProvider sourceDoesNotHaveAllRelationsDataProvider
* @param string $sourceCode
* @param bool $enable
* @param bool $expectedValid
*/
public function testIndexerInvalidationIfSourceDoesNotHaveSourceItems(
string $sourceCode,
bool $enable,
bool $expectedValid
) {
$this->setSourceEnabledStatus($sourceCode, $enable);

$this->assertEquals($expectedValid, $this->indexer->isValid());
}

/**
* @return array
*/
public function sourceDoesNotHaveAllRelationsDataProvider(): array
{
return [
['eu-1', true, true],
['eu-1', false, true],
['eu-disabled', true, true],
['eu-disabled', false, true],
];
}

/**
* @param string $sourceCode
* @param bool $enable
* @return void
*/
private function setSourceEnabledStatus(string $sourceCode, bool $enable)
{
$source = $this->sourceRepository->get($sourceCode);
$source->setEnabled($enable);
$this->sourceRepository->save($source);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
*/
declare(strict_types=1);

use Magento\Framework\Indexer\IndexerInterface;
use Magento\Framework\Indexer\IndexerRegistry;
use Magento\InventoryIndexer\Indexer\InventoryIndexer;
use Magento\TestFramework\Helper\Bootstrap;

/** @var IndexerInterface $indexer */
$indexer = Bootstrap::getObjectManager()->create(IndexerInterface::class);
$indexer->load(InventoryIndexer::INDEXER_ID);
/** @var IndexerRegistry $indexerRegistry */
$indexerRegistry = Bootstrap::getObjectManager()->get(IndexerRegistry::class);
$indexer = $indexerRegistry->get(InventoryIndexer::INDEXER_ID);
$indexer->reindexAll();
Loading

0 comments on commit 7a0e831

Please sign in to comment.