Skip to content
Merged
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
@@ -0,0 +1,29 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryConfigurableProduct\Model\ResourceModel\IsStockItemSalableCondition;

use Magento\Framework\DB\Select;
use Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\GetIsStockItemSalableConditionInterface;

/**
* //todo https://github.com/magento-engcom/msi/issues/524
* Condition for configurable products.
*/
class GetConfigurableCondition implements GetIsStockItemSalableConditionInterface
{
/**
* @inheritdoc
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function execute(Select $select): string
{
$condition = 'product_entity.type_id = \'configurable\'';

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

namespace Magento\InventoryConfigurableProduct\Model\ResourceModel\Product;

use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\Framework\DB\Select;
use Magento\InventoryCatalog\Model\GetStockIdForCurrentWebsite;
use Magento\InventoryIndexer\Model\StockIndexTableNameResolverInterface;
use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
use Magento\InventorySalesApi\Api\StockResolverInterface;
use Magento\Store\Model\StoreManagerInterface;

/**
* Add stock item filter to selects.
*/
class StockStatusBaseSelectProcessor implements BaseSelectProcessorInterface
{
/**
* @var StockIndexTableNameResolverInterface
*/
private $stockIndexTableNameResolver;

/**
* @var StockConfigurationInterface
*/
private $stockConfig;

/**
* @var GetStockIdForCurrentWebsite
*/
private $getStockIdForCurrentWebsite;

/**
* @var StoreManagerInterface
*/
private $storeManager;

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

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

/**
* @param Select $select
* @return Select
*/
public function process(Select $select)
{
if (!$this->stockConfig->isShowOutOfStock()) {
$websiteCode = $this->storeManager->getWebsite()->getCode();
$stock = $this->stockResolver->get(SalesChannelInterface::TYPE_WEBSITE, $websiteCode);
$stockId = (int)$stock->getStockId();

$stockTable = $this->stockIndexTableNameResolver->execute($stockId);

/** @var Select $select */
$select->join(
['stock' => $stockTable],
sprintf('stock.sku = %s.sku', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
[]
)->where('stock.is_salable = ?', 1);
}

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

namespace Magento\InventoryConfigurableProduct\Test\Integration\Price;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver;
use Magento\ConfigurableProduct\Pricing\Price\FinalPriceResolver;
use Magento\Store\Model\StoreManagerInterface;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;

class FinalPriceResolverTest extends TestCase
{
/**
* @var StoreManagerInterface
*/
private $storeManager;

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

/**
* @var string
*/
private $storeCodeBefore;

/**
* @var ConfigurablePriceResolver
*/
private $configurablePriceResolver;

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

$this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
$this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
$this->storeCodeBefore = $this->storeManager->getStore()->getCode();
$finalPrice = Bootstrap::getObjectManager()->get(FinalPriceResolver::class);

$this->configurablePriceResolver = Bootstrap::getObjectManager()->create(
ConfigurablePriceResolver::class,
['priceResolver' => $finalPrice]
);
}

// @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
* @return void
*/
// @codingStandardsIgnoreEnd
public function testResolvePriceWithAllChildren()
{
$this->storeManager->setCurrentStore('store_for_us_website');

$configurableProduct = $this->productRepository->get('configurable', false, null, true);
$actualPrice = $this->configurablePriceResolver->resolvePrice($configurableProduct);

self::assertEquals(10, $actualPrice);
}

/// @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/InventoryConfigurableProduct/Test/_files/set_product_configurable_out_of_stock.php
* @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/stock_website_sales_channels.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
* @return void
*/
// @codingStandardsIgnoreEnd
public function testResolvePriceIfOneOfChildIsOutOfStock()
{
$this->storeManager->setCurrentStore('store_for_us_website');

$configurableProduct = $this->productRepository->get('configurable', false, null, true);
$actualPrice = $this->configurablePriceResolver->resolvePrice($configurableProduct);
self::assertEquals(20, $actualPrice);
}

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

if (null !== $this->storeCodeBefore) {
$this->storeManager->setCurrentStore($this->storeCodeBefore);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryConfigurableProduct\Test\Integration\Price;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver;
use Magento\ConfigurableProduct\Pricing\Price\FinalPriceResolver;
use Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProviderInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;

class LowestPriceOptionProviderTest extends TestCase
{
/**
* @var StoreManagerInterface
*/
private $storeManager;

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

/**
* @var string
*/
private $storeCodeBefore;

/**
* @var ConfigurablePriceResolver
*/
private $configurablePriceResolver;

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

$this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
$this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
$this->storeCodeBefore = $this->storeManager->getStore()->getCode();
$finalPrice = Bootstrap::getObjectManager()->get(FinalPriceResolver::class);

$this->configurablePriceResolver = Bootstrap::getObjectManager()->create(
ConfigurablePriceResolver::class,
['priceResolver' => $finalPrice]
);
}

// @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
* @return void
*/
// @codingStandardsIgnoreEnd
public function testGetProductsWithAllChildren()
{
$this->storeManager->setCurrentStore('store_for_us_website');

$configurableProduct = $this->productRepository->get('configurable', false, null, true);
$lowestPriceChildrenProducts = $this->createLowestPriceOptionsProvider()->getProducts($configurableProduct);
self::assertCount(1, $lowestPriceChildrenProducts);
$lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
self::assertEquals(10, $lowestPriceChildrenProduct->getPrice());
}

/// @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/InventoryConfigurableProduct/Test/_files/set_product_configurable_out_of_stock.php
* @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/stock_website_sales_channels.php
* @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
* @return void
*/
// @codingStandardsIgnoreEnd
public function testGetProductsIfOneOfChildIsOutOfStock()
{
$this->storeManager->setCurrentStore('store_for_us_website');

$configurableProduct = $this->productRepository->get('configurable', false, null, true);
$lowestPriceChildrenProducts = $this->createLowestPriceOptionsProvider()->getProducts($configurableProduct);
self::assertCount(1, $lowestPriceChildrenProducts);
$lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
self::assertEquals(20, $lowestPriceChildrenProduct->getPrice());
}

/**
* As LowestPriceOptionsProviderInterface used multiple times in scope
* of one test we need to always recreate it and prevent internal caching in property
*
* @return LowestPriceOptionsProviderInterface
*/
private function createLowestPriceOptionsProvider()
{
return Bootstrap::getObjectManager()->create(
LowestPriceOptionsProviderInterface::class
);
}

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

if (null !== $this->storeCodeBefore) {
$this->storeManager->setCurrentStore($this->storeCodeBefore);
}
}
}
Loading