Skip to content

TP-34177: Out of stock label is not working correctly for different t… #2

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

Open
wants to merge 1 commit into
base: 1.1-develop
Choose a base branch
from
Open
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,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="StorefrontCreateOrderAllQuantityGroupedProductOptionDefaultStockTest">
<annotations>
<stories value="Grouped Product Default Stock."/>
<title value="Place order with all quantity with grouped product option on default stock."/>
<description value="Verify, grouped product option will change status after order placement with all it's quantity on default stock"/>
<severity value="CRITICAL"/>
<group value="msi"/>
<group value="multi_mode"/>
</annotations>
<before>
<!--Login to admin-->
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
<!--Disable all custom sources-->
<actionGroup ref="DisableAllSourcesActionGroup" stepKey="disableSource"/>
<!--Create category-->
<createData entity="ApiCategory" stepKey="createCategory"/>
<!--Create grouped product-->
<createData entity="ApiGroupedProduct" stepKey="groupedProduct"/>
<!--Create simple product (1) with qty 10-->
<createData entity="ApiSimplePrice10Qty10" stepKey="product1">
<requiredEntity createDataKey="createCategory"/>
</createData>
<!--Create simple product (2) with qty 10-->
<createData entity="ApiSimplePrice10Qty10" stepKey="product2">
<requiredEntity createDataKey="createCategory"/>
</createData>
<!--Add simple product (1) to grouped product-->
<createData entity="OneSimpleProductLink" stepKey="addProductOne">
<requiredEntity createDataKey="groupedProduct"/>
<requiredEntity createDataKey="product1"/>
</createData>
<!--Add simple product (2) to grouped product-->
<updateData entity="OneMoreSimpleProductLink" createDataKey="addProductOne" stepKey="addProductTwo">
<requiredEntity createDataKey="groupedProduct"/>
<requiredEntity createDataKey="product2"/>
</updateData>
<!--Create customer-->
<createData entity="MsiCustomer1" stepKey="customer"/>
</before>
<after>
<!--Logout from admin-->
<actionGroup ref="logout" stepKey="logoutOfAdmin"/>
<!--Delete category-->
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
<!--Delete grouped product-->
<deleteData createDataKey="groupedProduct" stepKey="deleteGroupedProduct"/>
<!--Delete simple product (1)-->
<deleteData createDataKey="product1" stepKey="deleteSimpleProduct1"/>
<!--Delete simple product (2)-->
<deleteData createDataKey="product2" stepKey="deleteSimpleProduct2"/>
<!--Delete customer-->
<deleteData createDataKey="customer" stepKey="deleteCustomer"/>
</after>

<!--Login To storefront as Customer-->
<actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefront">
<argument name="Customer" value="$$customer$$"/>
</actionGroup>
<!--Navigate to group product PDP.-->
<amOnPage url="{{StorefrontProductPage.url($groupedProduct.custom_attributes[url_key]$)}}" stepKey="goToProductPage"/>
<waitForPageLoad stepKey="waitForProductPageLoaded"/>
<!--Add grouped product to cart with all available quantity of product (1).-->
<actionGroup ref="StorefrontAddGroupedProductWithTwoLinksToCartActionGroup" stepKey="addGroupedProductToCart">
<argument name="product" value="$groupedProduct$"/>
<argument name="linkedProduct1Name" value="$product1.name$"/>
<argument name="linkedProduct2Name" value="$product2.name$"/>
<argument name="linkedProduct1Qty" value="{{Qty_10.qty}}"/>
<argument name="linkedProduct2Qty" value="{{Qty_1.qty}}"/>
</actionGroup>
<!--Place order.-->
<actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="navigateToCheckoutPage"/>
<click selector="{{CheckoutShippingSection.next}}" stepKey="clickNextButton"/>
<actionGroup ref="ClickPlaceOrderActionGroup" stepKey="clickOnPlaceOrder"/>
<!--Run queue consumer.-->
<magentoCLI command="queue:consumers:start" arguments="inventory.reservations.updateSalabilityStatus" stepKey="startSalabilityUpdate" timeout="30"/>
<!--Navigate to group product PDP.-->
<amOnPage url="{{StorefrontProductPage.url($groupedProduct.custom_attributes[url_key]$)}}" stepKey="navigateToGroupedProductPDPAfterOrderPlacement"/>
<waitForPageLoad stepKey="waitForProductPageLoaded2"/>
<!--Verify that product1 is not present.-->
<dontSee selector="{{StorefrontProductInfoMainSection.groupedProductsTable}}" userInput="$product1.name$" stepKey="dontSeeProduct1"/>
<!--Verify that product2 is present.-->
<actionGroup ref="AssertLinkPresenceOnGroupedProductPage" stepKey="verifySecondOptionIsStillPresentedOnPage">
<argument name="productName" value="$product2.name$"/>
</actionGroup>
</test>
</tests>
87 changes: 87 additions & 0 deletions InventoryIndexer/Model/Queue/GetSalabilityDataForUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryIndexer\Model\Queue;

use Magento\Framework\Exception\LocalizedException;
use Magento\InventorySalesApi\Api\IsProductSalableInterface;
use Magento\InventorySalesApi\Model\GetStockItemDataInterface;

/**
* Get stock status changes for given reservation.
*/
class GetSalabilityDataForUpdate
{
/**
* @var IsProductSalableInterface
*/
private $isProductSalable;

/**
* @var GetStockItemDataInterface
*/
private $getStockItemData;

/**
* @param IsProductSalableInterface $isProductSalable
* @param GetStockItemDataInterface $getStockItemData
*/
public function __construct(
IsProductSalableInterface $isProductSalable,
GetStockItemDataInterface $getStockItemData
) {
$this->isProductSalable = $isProductSalable;
$this->getStockItemData = $getStockItemData;
}

/**
* Get stock status changes for given reservation.
*
* @param ReservationData $reservationData
* @return bool[] - ['sku' => bool]
*/
public function execute(ReservationData $reservationData): array
{
$salabilityData = [];
foreach ($reservationData->getSkus() as $sku) {
$salabilityData[$sku] = $this->isProductSalable->execute($sku, $reservationData->getStock());
}

$data = [];
foreach ($salabilityData as $sku => $isSalable) {
$currentStatus = $this->isCurrentlySalable(
$sku,
$reservationData->getStock()
);
if ($isSalable !== $currentStatus) {
$data[$sku] = $isSalable;
}
}

return $data;
}

/**
* Get current is_salable value.
*
* @param string $sku
* @param int $stockId
*
* @return bool
*/
private function isCurrentlySalable(string $sku, int $stockId): bool
{
try {
$data = $this->getStockItemData->execute($sku, $stockId);
$isSalable = $data ? (bool)$data[GetStockItemDataInterface::IS_SALABLE] : false;
} catch (LocalizedException $e) {
$isSalable = false;
}

return $isSalable;
}
}
18 changes: 15 additions & 3 deletions InventoryIndexer/Model/Queue/UpdateIndexSalabilityStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Magento\Framework\Exception\StateException;
use Magento\InventoryCatalogApi\Api\DefaultStockProviderInterface;
use Magento\InventoryIndexer\Model\Queue\UpdateIndexSalabilityStatus\UpdateLegacyStock;
use Magento\InventoryIndexer\Model\Queue\UpdateIndexSalabilityStatus\IndexProcessor;

/**
Expand All @@ -25,17 +26,24 @@ class UpdateIndexSalabilityStatus
* @var IndexProcessor
*/
private $indexProcessor;
/**
* @var UpdateLegacyStock
*/
private $updateLegacyStock;

/**
* @param DefaultStockProviderInterface $defaultStockProvider
* @param IndexProcessor $indexProcessor
* @param UpdateLegacyStock $updateLegacyStock
*/
public function __construct(
DefaultStockProviderInterface $defaultStockProvider,
IndexProcessor $indexProcessor
IndexProcessor $indexProcessor,
UpdateLegacyStock $updateLegacyStock
) {
$this->defaultStockProvider = $defaultStockProvider;
$this->indexProcessor = $indexProcessor;
$this->updateLegacyStock = $updateLegacyStock;
}

/**
Expand All @@ -50,8 +58,12 @@ public function execute(ReservationData $reservationData): array
{
$stockId = $reservationData->getStock();
$dataForUpdate = [];
if ($stockId !== $this->defaultStockProvider->getId() && $reservationData->getSkus()) {
$dataForUpdate = $this->indexProcessor->execute($reservationData, $stockId);
if ($reservationData->getSkus()) {
if ($stockId !== $this->defaultStockProvider->getId()) {
$dataForUpdate = $this->indexProcessor->execute($reservationData, $stockId);
} else {
$dataForUpdate = $this->updateLegacyStock->execute($reservationData);
}
}

return $dataForUpdate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@
namespace Magento\InventoryIndexer\Model\Queue\UpdateIndexSalabilityStatus;

use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\StateException;
use Magento\InventoryIndexer\Indexer\InventoryIndexer;
use Magento\InventoryIndexer\Model\Queue\GetSalabilityDataForUpdate;
use Magento\InventoryIndexer\Model\Queue\ReservationData;
use Magento\InventoryIndexer\Model\ResourceModel\UpdateIsSalable;
use Magento\InventoryMultiDimensionalIndexerApi\Model\Alias;
use Magento\InventoryMultiDimensionalIndexerApi\Model\IndexNameBuilder;
use Magento\InventoryMultiDimensionalIndexerApi\Model\IndexStructureInterface;
use Magento\InventorySalesApi\Api\IsProductSalableInterface;
use Magento\InventorySalesApi\Model\GetStockItemDataInterface;

/**
* Update 'is salable' index data processor.
Expand All @@ -35,39 +33,31 @@ class IndexProcessor
private $indexStructure;

/**
* @var IsProductSalableInterface
*/
private $isProductSalable;

/**
* @var GetStockItemDataInterface
* @var UpdateIsSalable
*/
private $getStockItemData;
private $updateIsSalable;

/**
* @var UpdateIsSalable
* @var GetSalabilityDataForUpdate
*/
private $updateIsSalable;
private $getSalabilityDataForUpdate;

/**
* @param IndexNameBuilder $indexNameBuilder
* @param IndexStructureInterface $indexStructure
* @param GetStockItemDataInterface $getStockItemData
* @param UpdateIsSalable $updateIsSalable
* @param IsProductSalableInterface $isProductSalable
* @param GetSalabilityDataForUpdate $getSalabilityDataForUpdate
*/
public function __construct(
IndexNameBuilder $indexNameBuilder,
IndexStructureInterface $indexStructure,
GetStockItemDataInterface $getStockItemData,
UpdateIsSalable $updateIsSalable,
IsProductSalableInterface $isProductSalable
GetSalabilityDataForUpdate $getSalabilityDataForUpdate
) {
$this->indexNameBuilder = $indexNameBuilder;
$this->indexStructure = $indexStructure;
$this->isProductSalable = $isProductSalable;
$this->getStockItemData = $getStockItemData;
$this->updateIsSalable = $updateIsSalable;
$this->getSalabilityDataForUpdate = $getSalabilityDataForUpdate;
}

/**
Expand All @@ -77,6 +67,7 @@ public function __construct(
* @param int $stockId
* @return bool[]
* @throws StateException
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function execute(ReservationData $reservationData, int $stockId): array
{
Expand All @@ -89,12 +80,7 @@ public function execute(ReservationData $reservationData, int $stockId): array
$this->indexStructure->create($mainIndexName, ResourceConnection::DEFAULT_CONNECTION);
}

$salabilityData = [];
foreach ($reservationData->getSkus() as $sku) {
$salabilityData[$sku] = $this->isProductSalable->execute($sku, $reservationData->getStock());
}

$dataForUpdate = $this->getDataForUpdate($salabilityData, $stockId);
$dataForUpdate = $this->getSalabilityDataForUpdate->execute($reservationData);
$this->updateIsSalable->execute(
$mainIndexName,
$dataForUpdate,
Expand All @@ -103,45 +89,4 @@ public function execute(ReservationData $reservationData, int $stockId): array

return $dataForUpdate;
}

/**
* Build data for index update.
*
* @param array $salabilityData
* @param int $stockId
*
* @return bool[] - ['sku' => bool]
*/
private function getDataForUpdate(array $salabilityData, int $stockId): array
{
$data = [];
foreach ($salabilityData as $sku => $isSalable) {
$currentStatus = $this->getIndexSalabilityStatus($sku, $stockId);
if ($isSalable != $currentStatus && $currentStatus !== null) {
$data[$sku] = $isSalable;
}
}

return $data;
}

/**
* Get current index is_salable value.
*
* @param string $sku
* @param int $stockId
*
* @return bool|null
*/
private function getIndexSalabilityStatus(string $sku, int $stockId): ?bool
{
try {
$data = $this->getStockItemData->execute($sku, $stockId);
$isSalable = $data ? (bool)$data[GetStockItemDataInterface::IS_SALABLE] : false;
} catch (LocalizedException $e) {
$isSalable = null;
}

return $isSalable;
}
}
Loading