Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@
<argument name="secondAttributeCode" value="$$createSecondConfigProductAttribute.attribute_code$$"/>
<argument name="sourceName" value="$$customSource.source[name]$$"/>
</actionGroup>
<selectOption selector="{{AdminProductFormSection.productStockStatus}}" userInput="{{SourceStatusInStock.value}}" stepKey="selectStockStatus"/>
<actionGroup ref="SaveProductFormActionGroup" stepKey="saveProduct"/>

<amOnPage url="{{customStore.code}}" stepKey="amOnsecondStoreFront"/>
<actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="quickSearchByProductName2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Magento\InventoryConfigurableProduct\Plugin\CatalogInventory\Helper\Stock;

use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\CatalogInventory\Helper\Stock;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
Expand Down Expand Up @@ -74,6 +75,12 @@ public function beforeAssignStatusToProduct(
$status = null
): array {
if ($product->getTypeId() === Configurable::TYPE_CODE) {
$salable = (int)$product->getStatus() === Status::STATUS_ENABLED
&& $product->getQuantityAndStockStatus()['is_in_stock'];
if (!$salable) {
return [$product, (int)$salable];
}

$website = $this->storeManager->getWebsite();
$stock = $this->stockResolver->execute(SalesChannelInterface::TYPE_WEBSITE, $website->getCode());
$options = $this->configurable->getConfigurableOptions($product);
Expand Down
25 changes: 22 additions & 3 deletions InventoryConfigurableProductIndexer/Indexer/SelectBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
namespace Magento\InventoryConfigurableProductIndexer\Indexer;

use Exception;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Select;
use Magento\InventoryMultiDimensionalIndexerApi\Model\Alias;
Expand Down Expand Up @@ -40,22 +42,30 @@ class SelectBuilder
*/
private $metadataPool;

/**
* @var ScopeConfigInterface|null
*/
private $config;

/**
* @param ResourceConnection $resourceConnection
* @param IndexNameBuilder $indexNameBuilder
* @param IndexNameResolverInterface $indexNameResolver
* @param MetadataPool $metadataPool
* @param ScopeConfigInterface|null $config
*/
public function __construct(
ResourceConnection $resourceConnection,
IndexNameBuilder $indexNameBuilder,
IndexNameResolverInterface $indexNameResolver,
MetadataPool $metadataPool
MetadataPool $metadataPool,
ScopeConfigInterface $config = null
) {
$this->resourceConnection = $resourceConnection;
$this->indexNameBuilder = $indexNameBuilder;
$this->indexNameResolver = $indexNameResolver;
$this->metadataPool = $metadataPool;
$this->config = $config ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class);
}

/**
Expand All @@ -79,14 +89,19 @@ public function execute(int $stockId): Select

$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
$linkField = $metadata->getLinkField();

$manageStock = (int)$this->config->getValue('cataloginventory/item_options/manage_stock');
$isSalableExpr = $manageStock
? 'IF(MAX(parent_stock.manage_stock = 0), MAX(stock.is_salable), IF(MAX(parent_stock.is_in_stock) = 1, '
. 'MAX(stock.is_salable), 0))'
: 'IF(MAX(parent_stock.use_config_manage_stock) = 0, IF(MAX(parent_stock.manage_stock) = 1 AND '
. 'MAX(parent_stock.is_in_stock = 0), 0, MAX(stock.is_salable)), MAX(stock.is_salable))';
$select = $connection->select()
->from(
['stock' => $indexTableName],
[
IndexStructure::SKU => 'parent_product_entity.sku',
IndexStructure::QUANTITY => 'SUM(stock.quantity)',
IndexStructure::IS_SALABLE => 'MAX(stock.is_salable)',
IndexStructure::IS_SALABLE => $isSalableExpr,
]
)->joinInner(
['product_entity' => $this->resourceConnection->getTableName('catalog_product_entity')],
Expand All @@ -100,6 +115,10 @@ public function execute(int $stockId): Select
['parent_product_entity' => $this->resourceConnection->getTableName('catalog_product_entity')],
'parent_product_entity.' . $linkField . ' = parent_link.parent_id',
[]
)->joinInner(
['parent_stock' => $this->resourceConnection->getTableName('cataloginventory_stock_item')],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to avoid cataloginventory_stock_item table usage? CatalogInventory module will be deprecated and removed in the next releases, we should use Inventory logic only to handle such cases.

'parent_product_entity.entity_id = parent_stock.product_id',
[]
)
->group(['parent_product_entity.sku']);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@
*/
declare(strict_types=1);

namespace Magento\InventoryGroupedProductAdminUi\Plugin\Catalog\Model\Product\Link;
namespace Magento\InventoryGroupedProductAdminUi\Plugin\Catalog\Model\Product;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product\Link;
use Magento\Catalog\Model\Product;
use Magento\GroupedProduct\Model\Product\Type\Grouped as GroupedProductType;
use Magento\InventoryApi\Api\Data\SourceItemInterface;
use Magento\InventoryApi\Api\GetSourceItemsBySkuInterface;
use Magento\InventoryCatalogAdminUi\Observer\SourceItemsProcessor;

/**
* After save source links process child source items for reindex grouped product inventory.
* After save grouped product process child source items for reindex grouped product inventory.
*/
class ProcessSourceItemsAfterSaveAssociatedLinks
class ProcessSourceItemsPlugin
{
/**
* @var GetSourceItemsBySkuInterface
Expand All @@ -42,22 +41,22 @@ public function __construct(
}

/**
* @param Link $subject
* @param Link $result
* @param ProductInterface $product
* @return Link
* Process source items after grouped product has been saved.
*
* @param Product $subject
* @param Product $result
* @return Product
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterSaveProductRelations(
Link $subject,
Link $result,
ProductInterface $product
): Link {
if ($product->getTypeId() !== GroupedProductType::TYPE_CODE) {
public function afterAfterSave(
Product $subject,
Product $result
): Product {
if ($result->getTypeId() !== GroupedProductType::TYPE_CODE) {
return $result;
}

foreach ($product->getProductLinks() as $productLink) {
foreach ($result->getProductLinks() as $productLink) {
if ($productLink->getLinkType() === 'associated') {
$this->processSourceItemsForSku($productLink->getLinkedProductSku());
}
Expand All @@ -80,7 +79,7 @@ private function processSourceItemsForSku(string $sku): void
$processData[] = [
SourceItemInterface::SOURCE_CODE => $sourceItem->getSourceCode(),
SourceItemInterface::QUANTITY => $sourceItem->getQuantity(),
SourceItemInterface::STATUS => $sourceItem->getStatus()
SourceItemInterface::STATUS => $sourceItem->getStatus(),
];
}

Expand Down
4 changes: 2 additions & 2 deletions InventoryGroupedProductAdminUi/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\Product\Link">
<plugin name="process_source_items_after_save_links" type="Magento\InventoryGroupedProductAdminUi\Plugin\Catalog\Model\Product\Link\ProcessSourceItemsAfterSaveAssociatedLinks"/>
<type name="Magento\Catalog\Model\Product">
<plugin name="process_source_items_after_save" type="Magento\InventoryGroupedProductAdminUi\Plugin\Catalog\Model\Product\ProcessSourceItemsPlugin"/>
</type>
</config>
27 changes: 23 additions & 4 deletions InventoryGroupedProductIndexer/Indexer/SelectBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

use Exception;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Select;
use Magento\Framework\EntityManager\MetadataPool;
Expand Down Expand Up @@ -41,22 +43,30 @@ class SelectBuilder
*/
private $metadataPool;

/**
* @var ScopeConfigInterface|null
*/
private $config;

/**
* @param ResourceConnection $resourceConnection
* @param IndexNameBuilder $indexNameBuilder
* @param IndexNameResolverInterface $indexNameResolver
* @param MetadataPool $metadataPool
* @param ScopeConfigInterface|null $config
*/
public function __construct(
ResourceConnection $resourceConnection,
IndexNameBuilder $indexNameBuilder,
IndexNameResolverInterface $indexNameResolver,
MetadataPool $metadataPool
MetadataPool $metadataPool,
ScopeConfigInterface $config = null
) {
$this->resourceConnection = $resourceConnection;
$this->indexNameBuilder = $indexNameBuilder;
$this->indexNameResolver = $indexNameResolver;
$this->metadataPool = $metadataPool;
$this->config = $config ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class);
}

/**
Expand All @@ -80,28 +90,37 @@ public function execute(int $stockId): Select

$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
$linkField = $metadata->getLinkField();

$manageStock = (int)$this->config->getValue('cataloginventory/item_options/manage_stock');
$isSalableExpr = $manageStock
? 'IF(MAX(parent_stock.manage_stock = 0), MAX(stock.is_salable), IF(MAX(parent_stock.is_in_stock) = 1, '
. 'MAX(stock.is_salable), 0))'
: 'IF(MAX(parent_stock.use_config_manage_stock) = 0, IF(MAX(parent_stock.manage_stock) = 1 AND '
. 'MAX(parent_stock.is_in_stock = 0), 0, MAX(stock.is_salable)), MAX(stock.is_salable))';
$select = $connection->select()
->from(
['stock' => $indexTableName],
[
IndexStructure::SKU => 'parent_product_entity.sku',
IndexStructure::QUANTITY => 'SUM(stock.quantity)',
IndexStructure::IS_SALABLE => 'MAX(stock.is_salable)',
IndexStructure::IS_SALABLE => $isSalableExpr,
]
)->joinInner(
['product_entity' => $this->resourceConnection->getTableName('catalog_product_entity')],
'product_entity.sku = stock.sku',
[]
)->joinInner(
['parent_link' => $this->resourceConnection->getTableName('catalog_product_link')],
'parent_link.linked_product_id = product_entity.entity_id
'parent_link.linked_product_id = product_entity.entity_id
AND parent_link.link_type_id = ' . Link::LINK_TYPE_GROUPED,
[]
)->joinInner(
['parent_product_entity' => $this->resourceConnection->getTableName('catalog_product_entity')],
'parent_product_entity.' . $linkField . ' = parent_link.product_id',
[]
)->joinInner(
['parent_stock' => $this->resourceConnection->getTableName('cataloginventory_stock_item')],
'parent_product_entity.entity_id = parent_stock.product_id',
[]
)
->group(['parent_product_entity.sku']);

Expand Down