Skip to content

Commit

Permalink
Merge pull request magento#924 from magento-engcom/MSI-885
Browse files Browse the repository at this point in the history
MSI-885: Options on Storefront Product View Page for Configurable Product Assigned to Custom Stock are Empty.
  • Loading branch information
vadimjustus authored Apr 19, 2018
2 parents 4882a24 + 79e815c commit e7d3363
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryConfigurableProduct\Plugin\Model\ResourceModel\Attribute;

use Magento\ConfigurableProduct\Model\ResourceModel\Attribute\OptionSelectBuilderInterface;
use Magento\Framework\DB\Select;
use Magento\InventoryIndexer\Model\StockIndexTableNameResolverInterface;
use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
use Magento\InventorySalesApi\Api\StockResolverInterface;
use Magento\Store\Model\StoreManagerInterface;

/**
* Plugin for OptionSelectBuilderInterface to add "is_salable" filter.
*/
class IsSalableOptionSelectBuilder
{
/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* @var StockResolverInterface
*/
private $stockResolver;

/**
* @var StockIndexTableNameResolverInterface
*/
private $stockIndexTableNameResolver;

/**
* @param StoreManagerInterface $storeManager
* @param StockResolverInterface $stockResolver
* @param StockIndexTableNameResolverInterface $stockIndexTableNameResolver
*/
public function __construct(
StoreManagerInterface $storeManager,
StockResolverInterface $stockResolver,
StockIndexTableNameResolverInterface $stockIndexTableNameResolver
) {
$this->storeManager = $storeManager;
$this->stockResolver = $stockResolver;
$this->stockIndexTableNameResolver = $stockIndexTableNameResolver;
}

/**
* Add "is_salable" filter to select.
*
* @param OptionSelectBuilderInterface $subject
* @param Select $select
* @return Select
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterGetSelect(
OptionSelectBuilderInterface $subject,
Select $select
) {
$websiteCode = $this->storeManager->getWebsite()->getCode();
$stock = $this->stockResolver->get(SalesChannelInterface::TYPE_WEBSITE, $websiteCode);
$stockId = (int)$stock->getStockId();
$stockTable = $this->stockIndexTableNameResolver->execute($stockId);

$select->joinInner(
['stock' => $stockTable],
'stock.sku = entity.sku',
[]
)->where(
'stock.is_salable = ?',
1
);

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

namespace Magento\InventoryConfigurableProduct\Test\Integration\Options;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\ConfigurableProduct\Block\Product\View\Type\Configurable as ConfigurableView;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;

/**
* @magentoAppArea frontend
*/
class OptionsAvailabilityTest extends TestCase
{
/**
* @var StoreManagerInterface
*/
private $storeManager;

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

/**
* @var ConfigurableView
*/
private $configurableView;

/**
* @var SerializerInterface
*/
private $serializer;

/**
* @inheritdoc
*/
protected function setUp()
{
parent::setUp();

$this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
$this->configurableView = Bootstrap::getObjectManager()->get(ConfigurableView::class);
$this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
$this->serializer = Bootstrap::getObjectManager()->get(SerializerInterface::class);
}

/**
* @codingStandardsIgnoreStart
* @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/websites_with_stores.php
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryConfigurableProduct/Test/_files/product_configurable.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/stock_source_links.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryConfigurableProduct/Test/_files/source_items_configurable.php
* @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/stock_website_sales_channels.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
* @codingStandardsIgnoreEnd
* @dataProvider getSalableOptionsDataProvider
* @param string $storeCode
* @param int $expected
* @return void
*/
public function testGetSalableOptions(string $storeCode, int $expected)
{
$this->storeManager->setCurrentStore($storeCode);

$configurableProduct = $this->productRepository->get('configurable', false, null, true);
$this->configurableView->setProduct($configurableProduct);
$result = $this->serializer->unserialize($this->configurableView->getJsonConfig());
$attributes = reset($result['attributes']);
$actual = count($attributes['options'] ?? []);

$this->assertEquals(
$expected,
$actual
);
}

/**
* @return array
*/
public function getSalableOptionsDataProvider()
{
return [
[
'store_for_eu_website',
0
],
[
'store_for_us_website',
2
],
];
}
}
3 changes: 3 additions & 0 deletions app/code/Magento/InventoryConfigurableProduct/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"magento/module-store": "*",
"magento/module-catalog-inventory": "*"
},
"suggest": {
"magento/module-configurable-product": "*"
},
"type": "magento2-module",
"license": [
"OSL-3.0",
Expand Down
12 changes: 12 additions & 0 deletions app/code/Magento/InventoryConfigurableProduct/etc/frontend/di.xml
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\ConfigurableProduct\Model\ResourceModel\Attribute\OptionSelectBuilderInterface">
<plugin name="Magento_ConfigurableProduct_Plugin_Model_ResourceModel_Attribute_InStockOptionSelectBuilder" type="Magento\InventoryConfigurableProduct\Plugin\Model\ResourceModel\Attribute\IsSalableOptionSelectBuilder"/>
</type>
</config>

0 comments on commit e7d3363

Please sign in to comment.