Skip to content

Commit 7399ea7

Browse files
authored
LYNX-681 Bundle products still shows IN_STOCK when one of its bundled product out of stock
1 parent 0208e43 commit 7399ea7

File tree

3 files changed

+45
-45
lines changed

3 files changed

+45
-45
lines changed

InventoryGraphQl/Model/Resolver/StockStatusProvider.php

+22-19
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,26 @@
1414
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1515
use Magento\InventoryCatalog\Model\GetStockIdForCurrentWebsite;
1616
use Magento\InventorySalesApi\Api\AreProductsSalableInterface;
17-
use Magento\Catalog\Model\Product\Type;
17+
use Magento\Bundle\Model\Product\Type;
1818

1919
/**
2020
* @inheritdoc
2121
*/
2222
class StockStatusProvider implements ResolverInterface
2323
{
24-
/**
25-
* @var GetStockIdForCurrentWebsite
26-
*/
27-
private $getStockIdForCurrentWebsite;
28-
29-
/**
30-
* @var AreProductsSalableInterface|null
31-
*/
32-
private $areProductsSalable;
24+
private const IN_STOCK = "IN_STOCK";
25+
private const OUT_OF_STOCK = "OUT_OF_STOCK";
3326

3427
/**
3528
* @param GetStockIdForCurrentWebsite $getStockIdForCurrentWebsite
3629
* @param AreProductsSalableInterface $areProductsSalable
30+
* @param Type $bundleType
3731
*/
3832
public function __construct(
39-
GetStockIdForCurrentWebsite $getStockIdForCurrentWebsite,
40-
AreProductsSalableInterface $areProductsSalable
33+
private readonly GetStockIdForCurrentWebsite $getStockIdForCurrentWebsite,
34+
private readonly AreProductsSalableInterface $areProductsSalable,
35+
private readonly Type $bundleType
4136
) {
42-
$this->getStockIdForCurrentWebsite = $getStockIdForCurrentWebsite;
43-
$this->areProductsSalable = $areProductsSalable;
4437
}
4538

4639
/**
@@ -52,15 +45,25 @@ public function resolve(Field $field, $context, ResolveInfo $info, ?array $value
5245
throw new LocalizedException(__('"model" value should be specified'));
5346
}
5447

55-
/* @var $product ProductInterface */
5648
$product = $value['model'];
5749

58-
$productSku = ($product->getTypeId() === TYPE::TYPE_BUNDLE || !empty($product->getOptions()))
59-
? $value['sku'] : $product->getSku();
50+
if ($product->getTypeId() === Type::TYPE_CODE) {
51+
try {
52+
if (!$product->getCustomOption('bundle_selection_ids')) {
53+
return self::OUT_OF_STOCK;
54+
}
55+
$this->bundleType->checkProductBuyState($product);
56+
} catch (LocalizedException $e) {
57+
return self::OUT_OF_STOCK;
58+
}
59+
60+
return self::IN_STOCK;
61+
}
62+
63+
$productSku = (!empty($product->getOptions())) ? $value['sku'] : $product->getSku();
6064
$stockId = $this->getStockIdForCurrentWebsite->execute();
6165
$result = $this->areProductsSalable->execute([$productSku], $stockId);
62-
$result = current($result);
6366

64-
return $result->isSalable() ? 'IN_STOCK' : 'OUT_OF_STOCK';
67+
return current($result)->isSalable() ? self::IN_STOCK : self::OUT_OF_STOCK;
6568
}
6669
}

InventoryGraphQl/composer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"magento/module-catalog": "*",
99
"magento/module-inventory-catalog": "*",
1010
"magento/module-inventory-configuration-api": "*",
11-
"magento/module-inventory-sales-api": "*"
11+
"magento/module-inventory-sales-api": "*",
12+
"magento/module-bundle": "*"
1213
},
1314
"license": [
1415
"OSL-3.0",

dev/tests/api-functional/testsuite/Magento/GraphQl/Inventory/BundleProductStockStatusTest.php

+21-25
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,7 @@
11
<?php
22
/**
3-
* ADOBE CONFIDENTIAL
4-
*
53
* Copyright 2024 Adobe
64
* All Rights Reserved.
7-
*
8-
* NOTICE: All information contained herein is, and remains
9-
* the property of Adobe and its suppliers, if any. The intellectual
10-
* and technical concepts contained herein are proprietary to Adobe
11-
* and its suppliers and are protected by all applicable intellectual
12-
* property laws, including trade secret and copyright laws.
13-
* Dissemination of this information or reproduction of this material
14-
* is strictly forbidden unless prior written permission is obtained
15-
* from Adobe.
165
*/
176
declare(strict_types=1);
187

@@ -25,6 +14,10 @@
2514
use Magento\Catalog\Api\ProductRepositoryInterface;
2615
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
2716
use Magento\Framework\DataObject;
17+
use Magento\Framework\Exception\CouldNotSaveException;
18+
use Magento\Framework\Exception\InputException;
19+
use Magento\Framework\Exception\NoSuchEntityException;
20+
use Magento\Framework\Exception\StateException;
2821
use Magento\Quote\Test\Fixture\GuestCart as GuestCartFixture;
2922
use Magento\Quote\Test\Fixture\QuoteIdMask as QuoteMaskFixture;
3023
use Magento\TestFramework\Fixture\DataFixture;
@@ -91,29 +84,32 @@ protected function setUp(): void
9184
* @param string $expected
9285
* @return void
9386
*
87+
* @throws CouldNotSaveException
88+
* @throws InputException
89+
* @throws NoSuchEntityException
90+
* @throws StateException
9491
* @dataProvider stockStatusProvider
9592
*/
9693
public function testStockStatusBundleProduct(bool $inStock, string $expected): void
9794
{
98-
$bundleProductSku = $this->fixtures->get('bundle_product')->getSku();
99-
$product = $this->productRepository->get($bundleProductSku);
95+
$product = $this->productRepository->get($this->fixtures->get('product1')->getSku());
10096
$product->getExtensionAttributes()->getStockItem()->setIsInStock($inStock);
10197
$this->productRepository->save($product);
10298

10399
$maskedQuoteId = $this->fixtures->get('quoteIdMask')->getMaskedId();
104100
$query = <<<QUERY
105-
{
106-
cart(cart_id: "$maskedQuoteId") {
107-
itemsV2 {
108-
items {
109-
product {
110-
stock_status
111-
}
112-
}
113-
}
114-
}
115-
}
116-
QUERY;
101+
{
102+
cart(cart_id: "$maskedQuoteId") {
103+
itemsV2 {
104+
items {
105+
product {
106+
stock_status
107+
}
108+
}
109+
}
110+
}
111+
}
112+
QUERY;
117113

118114
$response = $this->graphQlQuery($query);
119115
$responseDataObject = new DataObject($response);

0 commit comments

Comments
 (0)