Skip to content

Commit 44ee9c4

Browse files
authored
Merge pull request #8973 from magento-lynx/graphql-api-enhancements
2 parents ef81f5a + 88d338f commit 44ee9c4

File tree

53 files changed

+3037
-654
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3037
-654
lines changed

app/code/Magento/CatalogGraphQl/Model/PriceRangeDataProvider.php

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Magento\Framework\Exception\LocalizedException;
1616
use Magento\Framework\GraphQl\Query\Resolver\Value;
1717
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
18+
use Magento\Framework\Pricing\PriceCurrencyInterface;
1819
use Magento\Framework\Pricing\SaleableInterface;
1920
use Magento\GraphQl\Model\Query\ContextInterface;
2021
use Magento\Store\Api\Data\StoreInterface;
@@ -26,26 +27,16 @@ class PriceRangeDataProvider
2627
{
2728
private const STORE_FILTER_CACHE_KEY = '_cache_instance_store_filter';
2829

29-
/**
30-
* @var Discount
31-
*/
32-
private Discount $discount;
33-
34-
/**
35-
* @var PriceProviderPool
36-
*/
37-
private PriceProviderPool $priceProviderPool;
38-
3930
/**
4031
* @param PriceProviderPool $priceProviderPool
4132
* @param Discount $discount
33+
* @param PriceCurrencyInterface $priceCurrency
4234
*/
4335
public function __construct(
44-
PriceProviderPool $priceProviderPool,
45-
Discount $discount
36+
private readonly PriceProviderPool $priceProviderPool,
37+
private readonly Discount $discount,
38+
private readonly PriceCurrencyInterface $priceCurrency
4639
) {
47-
$this->priceProviderPool = $priceProviderPool;
48-
$this->discount = $discount;
4940
}
5041

5142
/**
@@ -141,11 +132,11 @@ private function formatPrice(float $regularPrice, float $finalPrice, StoreInterf
141132
{
142133
return [
143134
'regular_price' => [
144-
'value' => $regularPrice,
135+
'value' => $this->priceCurrency->roundPrice($regularPrice),
145136
'currency' => $store->getCurrentCurrencyCode(),
146137
],
147138
'final_price' => [
148-
'value' => $finalPrice,
139+
'value' => $this->priceCurrency->roundPrice($finalPrice),
149140
'currency' => $store->getCurrentCurrencyCode(),
150141
],
151142
'discount' => $this->discount->getDiscountByDifference($regularPrice, $finalPrice),
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
/**
9+
* Catalog Inventory Config Backend Model
10+
*/
11+
namespace Magento\CatalogInventory\Model\Config\Source;
12+
13+
use Magento\Framework\Data\OptionSourceInterface;
14+
15+
class NotAvailableMessage implements OptionSourceInterface
16+
{
17+
/**
18+
* Options getter
19+
*
20+
* @return array
21+
*/
22+
public function toOptionArray(): array
23+
{
24+
$options = [];
25+
$options[] = [
26+
'value' => 1,
27+
'label' => __('Only X available for sale. Please adjust the quantity to continue'),
28+
];
29+
$options[] = [
30+
'value' => 2,
31+
'label' => __('Not enough items for sale. Please adjust the quantity to continue'),
32+
];
33+
return $options;
34+
}
35+
36+
/**
37+
* Get options in "key-value" format
38+
*
39+
* @return array
40+
*/
41+
public function toArray(): array
42+
{
43+
return [
44+
1 => __('Only X available for sale. Please adjust the quantity to continue'),
45+
2 => __('Not enough items for sale. Please adjust the quantity to continue')
46+
];
47+
}
48+
}

app/code/Magento/CatalogInventory/Model/StockStateProvider.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Magento\Catalog\Model\ProductFactory;
1010
use Magento\CatalogInventory\Api\Data\StockItemInterface;
1111
use Magento\CatalogInventory\Model\Spi\StockStateProviderInterface;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
1213
use Magento\Framework\DataObject\Factory as ObjectFactory;
1314
use Magento\Framework\Locale\FormatInterface;
1415
use Magento\Framework\Math\Division as MathDivision;
@@ -48,13 +49,15 @@ class StockStateProvider implements StockStateProviderInterface
4849
* @param FormatInterface $localeFormat
4950
* @param ObjectFactory $objectFactory
5051
* @param ProductFactory $productFactory
52+
* @param ScopeConfigInterface $scopeConfig
5153
* @param bool $qtyCheckApplicable
5254
*/
5355
public function __construct(
5456
MathDivision $mathDivision,
5557
FormatInterface $localeFormat,
5658
ObjectFactory $objectFactory,
5759
ProductFactory $productFactory,
60+
private readonly ScopeConfigInterface $scopeConfig,
5861
$qtyCheckApplicable = true
5962
) {
6063
$this->mathDivision = $mathDivision;
@@ -165,9 +168,17 @@ public function checkQuoteItemQty(StockItemInterface $stockItem, $qty, $summaryQ
165168

166169
if (!$this->checkQty($stockItem, $summaryQty) || !$this->checkQty($stockItem, $qty)) {
167170
$message = __('The requested qty is not available');
171+
if ((int) $this->scopeConfig->getValue('cataloginventory/options/not_available_message') === 1) {
172+
$itemMessage = (__(sprintf(
173+
'Only %s available for sale. Please adjust the quantity to continue',
174+
$stockItem->getQty() - $stockItem->getMinQty()
175+
)));
176+
} else {
177+
$itemMessage = (__('Not enough items for sale. Please adjust the quantity to continue'));
178+
}
168179
$result->setHasError(true)
169180
->setErrorCode('qty_available')
170-
->setMessage($message)
181+
->setMessage($itemMessage)
171182
->setQuoteMessage($message)
172183
->setQuoteMessageIndex('qty');
173184
return $result;

app/code/Magento/CatalogInventory/etc/adminhtml/system.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
<label>Display Products Availability in Stock on Storefront</label>
3636
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
3737
</field>
38+
<field id="not_available_message" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="1" canRestore="1">
39+
<label>Not Available Message</label>
40+
<source_model>Magento\CatalogInventory\Model\Config\Source\NotAvailableMessage</source_model>
41+
</field>
3842
</group>
3943
<group id="item_options" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
4044
<comment>

app/code/Magento/CatalogInventory/etc/config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<show_out_of_stock>0</show_out_of_stock>
1515
<stock_threshold_qty>0</stock_threshold_qty>
1616
<display_product_stock_status>1</display_product_stock_status>
17+
<not_available_message>2</not_available_message>
1718
</options>
1819
<item_options>
1920
<manage_stock>1</manage_stock>

app/code/Magento/CatalogInventory/i18n/en_US.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,6 @@ Stock,Stock
7373
"Done","Done"
7474
"The requested qty exceeds the maximum qty allowed in shopping cart","The requested qty exceeds the maximum qty allowed in shopping cart"
7575
"You cannot use decimal quantity for this product.","You cannot use decimal quantity for this product."
76+
"Not enough items for sale. Please adjust the quantity to continue","Not enough items for sale. Please adjust the quantity to continue"
77+
"Only X available for sale. Please adjust the quantity to continue","Only X available for sale. Please adjust the quantity to continue"
78+
"Only %s available for sale. Please adjust the quantity to continue","Only %s available for sale. Please adjust the quantity to continue"
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogInventoryGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Quote\Model\Quote\Item;
16+
use Magento\QuoteGraphQl\Model\CartItem\ProductStock;
17+
18+
/**
19+
* Resolver for not_available_message
20+
* Returns the configured response to the shopper if the requested quantity is not available
21+
*/
22+
class NotAvailableMessageResolver implements ResolverInterface
23+
{
24+
/**
25+
* @param ScopeConfigInterface $scopeConfig
26+
* @param ProductStock $productStock
27+
*/
28+
public function __construct(
29+
private readonly ScopeConfigInterface $scopeConfig,
30+
private readonly ProductStock $productStock
31+
) {
32+
}
33+
34+
/**
35+
* @inheritdoc
36+
*/
37+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
38+
{
39+
if (!isset($value['model'])) {
40+
throw new LocalizedException(__('"model" value should be specified'));
41+
}
42+
/** @var Item $cartItem */
43+
$cartItem = $value['model'];
44+
45+
if ($this->productStock->isProductAvailable($cartItem)) {
46+
return null;
47+
}
48+
49+
if ((int) $this->scopeConfig->getValue('cataloginventory/options/not_available_message') === 1) {
50+
return sprintf(
51+
'Only %s available for sale. Please adjust the quantity to continue',
52+
(string) $this->productStock->getProductAvailableStock($cartItem)
53+
);
54+
}
55+
56+
return 'Not enough items for sale. Please adjust the quantity to continue';
57+
}
58+
}

app/code/Magento/CatalogInventoryGraphQl/composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"magento/module-store": "*",
99
"magento/module-catalog": "*",
1010
"magento/module-catalog-inventory": "*",
11+
"magento/module-quote": "*",
12+
"magento/module-quote-graph-ql": "*",
1113
"magento/module-graph-ql": "*"
1214
},
1315
"license": [

app/code/Magento/CatalogInventoryGraphQl/etc/schema.graphqls

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ enum ProductStockStatus @doc(description: "States whether a product stock status
1010
IN_STOCK
1111
OUT_OF_STOCK
1212
}
13+
14+
interface CartItemInterface @typeResolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CartItemTypeResolver") @doc(description: "An interface for products in a cart.") {
15+
not_available_message: String @doc(description: "Message to display when the product is not available with this selected option.") @resolver(class: "Magento\\CatalogInventoryGraphQl\\Model\\Resolver\\NotAvailableMessageResolver")
16+
}

app/code/Magento/Customer/Model/AccountManagement.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,9 +847,14 @@ public function getConfirmationStatus($customerId)
847847
*/
848848
public function createAccount(CustomerInterface $customer, $password = null, $redirectUrl = '')
849849
{
850+
$customerEmail = $customer->getEmail();
851+
if ($customerEmail === null) {
852+
throw new LocalizedException(
853+
__("The email address is required to create a customer account.")
854+
);
855+
}
850856
if ($password !== null) {
851857
$this->checkPasswordStrength($password);
852-
$customerEmail = $customer->getEmail();
853858
try {
854859
$this->credentialsValidator->checkPasswordDifferentFromEmail($customerEmail, $password);
855860
} catch (InputException $e) {

0 commit comments

Comments
 (0)