Skip to content

Commit 6a0afa1

Browse files
Merge branch '2.4-develop' into ACP2E-3916
2 parents d2c5a24 + 3ad96f6 commit 6a0afa1

File tree

21 files changed

+671
-32
lines changed

21 files changed

+671
-32
lines changed

‎app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/MediaGalleryProcessor.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2019 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -51,7 +51,9 @@ public function process(
5151
array $attributeNames,
5252
?ContextInterface $context = null
5353
): Collection {
54-
if (in_array('media_gallery_entries', $attributeNames)) {
54+
if (in_array('media_gallery_entries', $attributeNames) ||
55+
in_array('media_gallery', $attributeNames)
56+
) {
5557
$mediaAttributes = $this->mediaConfig->getMediaAttributeCodes();
5658
foreach ($mediaAttributes as $mediaAttribute) {
5759
if (!in_array($mediaAttribute, $attributeNames)) {

‎app/code/Magento/CatalogGraphQl/etc/schema.graphqls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ interface MediaGalleryInterface @doc(description: "Contains basic information ab
229229
label: String @doc(description: "The label of the product image or video.")
230230
position: Int @doc(description: "The media item's position after it has been sorted.")
231231
disabled: Boolean @doc(description: "Indicates whether the image is hidden from view.")
232+
types: [String] @doc(description: "Array of image types. It can have the following values: image, small_image, thumbnail.")
232233
}
233234

234235
type ProductImage implements MediaGalleryInterface @doc(description: "Contains product image information, including the image URL and label.") {

‎app/code/Magento/CatalogImportExport/Model/Export/Product.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,13 +1004,13 @@ public function export()
10041004
++$page;
10051005
$entityCollection = $this->_getEntityCollection(true);
10061006
$entityCollection->setOrder('entity_id', 'asc');
1007-
$entityCollection->setStoreId(Store::DEFAULT_STORE_ID);
10081007
$this->_prepareEntityCollection($entityCollection);
10091008
$this->paginateCollection($page, $this->getItemsPerPage());
1010-
if ($entityCollection->count() == 0) {
1009+
1010+
$exportData = $this->getExportData();
1011+
if ($exportData == null || count($exportData) == 0) {
10111012
break;
10121013
}
1013-
$exportData = $this->getExportData();
10141014
if ($page == 1) {
10151015
$writer->setHeaderCols($this->_getHeaderColumns());
10161016
}
@@ -1096,10 +1096,11 @@ protected function getExportData()
10961096
protected function loadCollection(): array
10971097
{
10981098
$data = [];
1099-
$collection = $this->_getEntityCollection();
11001099
foreach (array_keys($this->_storeIdToCode) as $storeId) {
1100+
$collection = $this->_getEntityCollection(true);
11011101
$collection->setOrder('entity_id', 'asc');
11021102
$collection->setStoreId($storeId);
1103+
$this->_prepareEntityCollection($collection);
11031104
$collection->load();
11041105
foreach ($collection as $itemId => $item) {
11051106
$data[$itemId][$storeId] = $item;
@@ -1129,6 +1130,9 @@ protected function collectRawData()
11291130
*/
11301131
foreach ($items as $itemId => $itemByStore) {
11311132
foreach ($this->_storeIdToCode as $storeId => $storeCode) {
1133+
if (!key_exists($storeId, $itemByStore)) {
1134+
continue;
1135+
}
11321136
$item = $itemByStore[$storeId];
11331137
$additionalAttributes = [];
11341138
$productLinkId = $item->getData($this->getProductEntityLinkField());

‎app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,16 +342,12 @@ public function testExportCountZeroBreakInternalCalls()
342342
$this->product->expects($this->once())->method('getItemsPerPage')->willReturn($itemsPerPage);
343343
$this->product->expects($this->once())->method('paginateCollection')->with($page, $itemsPerPage);
344344
$this->abstractCollection->expects($this->once())->method('setOrder')->with('entity_id', 'asc');
345-
$this->abstractCollection->expects($this->once())->method('setStoreId')->with(Store::DEFAULT_STORE_ID);
346-
347-
$this->abstractCollection->expects($this->once())->method('count')->willReturn(0);
348345

349346
$this->abstractCollection->expects($this->never())->method('getCurPage');
350347
$this->abstractCollection->expects($this->never())->method('getLastPageNumber');
351348
$this->product->expects($this->never())->method('_getHeaderColumns');
352349
$this->writer->expects($this->never())->method('setHeaderCols');
353350
$this->writer->expects($this->never())->method('writeRow');
354-
$this->product->expects($this->never())->method('getExportData');
355351
$this->product->expects($this->never())->method('_customFieldsMapping');
356352

357353
$this->writer->expects($this->once())->method('getContents');
@@ -373,9 +369,6 @@ public function testExportCurPageEqualToLastBreakInternalCalls()
373369
$this->product->expects($this->once())->method('getItemsPerPage')->willReturn($itemsPerPage);
374370
$this->product->expects($this->once())->method('paginateCollection')->with($page, $itemsPerPage);
375371
$this->abstractCollection->expects($this->once())->method('setOrder')->with('entity_id', 'asc');
376-
$this->abstractCollection->expects($this->once())->method('setStoreId')->with(Store::DEFAULT_STORE_ID);
377-
378-
$this->abstractCollection->expects($this->once())->method('count')->willReturn(1);
379372

380373
$this->abstractCollection->expects($this->once())->method('getCurPage')->willReturn($curPage);
381374
$this->abstractCollection->expects($this->once())->method('getLastPageNumber')->willReturn($lastPage);
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2019 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88

@@ -11,6 +11,7 @@
1111
<section name="AdminCustomerActivitiesShoppingCartSection">
1212
<element name="productName" type="text" selector="//div[@id='sidebar_data_cart']//td[@class='col-item']"/>
1313
<element name="productPrice" type="text" selector="//div[@id='sidebar_data_cart']//td[@class='col-price']"/>
14+
<element name="productQty" type="text" selector="//div[@id='sidebar_data_cart']//td[@class='col-qty']"/>
1415
<element name="addToOrder" type="checkbox" selector="//input[contains(@id, 'sidebar-add_cart_item')]"/>
1516
</section>
1617
</sections>

‎app/code/Magento/Elasticsearch/ElasticAdapter/SearchAdapter/Aggregation/Interval.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2015 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -158,7 +158,11 @@ public function loadPrevious($data, $index, $lower = null)
158158
$offset = $offset['value'];
159159
}
160160

161-
return $this->load($index - $offset + 1, $offset - 1, $lower);
161+
if ($offset > 0) {
162+
return $this->load($index - $offset + 1, $offset - 1, $lower);
163+
}
164+
165+
return false;
162166
}
163167

164168
/**
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
10+
<test name="StorefrontRewardPointsAppliedAfterApplyingCouponTest">
11+
<annotations>
12+
<features value="PayPal"/>
13+
<stories value="Paypal express checkout with a discount and reward points"/>
14+
<title value="Reward Points should be added to orders after applying coupon and using PayPal Express payment method"/>
15+
<description value="Reward points should be added to a customer’s account when applied with a coupon code during checkout with the PayPal Express payment method. "/>
16+
<severity value="MAJOR"/>
17+
<testCaseId value="AC-6036"/>
18+
<useCaseId value="ACP2E-1029"/>
19+
<group value="3rd_party_integration"/>
20+
<group value="paypalExpress"/>
21+
<group value="pr_exclude"/>
22+
</annotations>
23+
<before>
24+
<!-- Simple product is created -->
25+
<createData entity="SimpleProduct" stepKey="createProduct"/>
26+
27+
<!-- US Customer is created -->
28+
<createData entity="Simple_US_Customer" stepKey="createCustomer"/>
29+
30+
<!-- Setup Paypal Express -->
31+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
32+
<actionGroup ref="AdminPayPalExpressCheckoutEnableActionGroup" stepKey="configPayPalExpress">
33+
<argument name="credentials" value="SamplePaypalExpressConfig2"/>
34+
</actionGroup>
35+
<magentoCLI command="config:set {{StorefrontPaypalExpressSalePaymentActionOptionConfigData.path}} {{StorefrontPaypalExpressSalePaymentActionOptionConfigData.value}}" stepKey="setPaymentAction"/>
36+
37+
<!-- Delete all existing cart price rules -->
38+
<actionGroup ref="AdminCartPriceRuleDeleteAllActionGroup" stepKey="deleteAllCartPriceRules"/>
39+
40+
<!-- Create a cart price rule -->
41+
<actionGroup ref="AdminOpenCartPriceRulesPageActionGroup" stepKey="amOnCartPriceList"/>
42+
<click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/>
43+
<fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/>
44+
<selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/>
45+
<selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="General" stepKey="selectCustomerGroup"/>
46+
<selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/>
47+
<fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/>
48+
<click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/>
49+
<selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/>
50+
<fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="0.99" stepKey="fillDiscountAmount"/>
51+
<fillField selector="{{AdminCartPriceRulesFormSection.addRewardPoints}}" userInput="100" stepKey="fillRewardPoints"/>
52+
<click selector="{{AdminCartPriceRulesFormSection.saveAndContinue}}" stepKey="clickSaveAndContinueButton"/>
53+
</before>
54+
<after>
55+
<magentoCLI command="config:set payment/paypal_express/active 0" stepKey="disablePayPalExpress"/>
56+
<magentoCLI command="config:set {{StorefrontPaypalExpressAuthorizationPaymentActionOptionConfigData.path}} {{StorefrontPaypalExpressAuthorizationPaymentActionOptionConfigData.value}}" stepKey="setPaymentAction"/>
57+
<deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/>
58+
<deleteData createDataKey="createProduct" stepKey="deleteProduct"/>
59+
<!--Delete cart price rule-->
60+
<actionGroup ref="DeleteCartPriceRuleByName" stepKey="deleteCartPriceRule">
61+
<argument name="ruleName" value="{{_defaultCoupon.code}}"/>
62+
</actionGroup>
63+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
64+
</after>
65+
<!-- Login to StoreFront -->
66+
<actionGroup ref="LoginToStorefrontActionGroup" stepKey="storefrontCustomerLogin">
67+
<argument name="Customer" value="$$createCustomer$$"/>
68+
</actionGroup>
69+
<!-- Add product to cart -->
70+
<actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addProductToCart">
71+
<argument name="product" value="$$createProduct$$"/>
72+
</actionGroup>
73+
<!-- Goto Checkout Page -->
74+
<actionGroup ref="StorefrontOpenCheckoutPageActionGroup" stepKey="goToCheckout"/>
75+
<actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShipping" />
76+
<actionGroup ref="StorefrontCheckoutClickNextOnShippingStepActionGroup" stepKey="clickNext"/>
77+
<!-- Apply Coupon Code to the Order -->
78+
<actionGroup ref="StorefrontApplyDiscountCodeActionGroup" stepKey="applyDiscountCoupon">
79+
<argument name="discountCode" value="{{_defaultCoupon.code}}"/>
80+
</actionGroup>
81+
<!-- Click on PayPal payment radio button -->
82+
<waitForElementClickable selector="{{CheckoutPaymentSection.PayPalPaymentRadio}}" stepKey="waitForPayPalRadioButton"/>
83+
<click selector="{{CheckoutPaymentSection.PayPalPaymentRadio}}" stepKey="selectPaypalPayment"/>
84+
<actionGroup ref="SwitchToPayPalGroupBtnActionGroup" stepKey="clickPayPalBtn"/>
85+
<!-- Login to PayPal in-context and verify order total on PayPal page-->
86+
<actionGroup ref="StorefrontLoginToPayPalPaymentAccountTwoStepActionGroup" stepKey="loginToPayPal"/>
87+
<waitForText selector="{{PayPalPaymentSection.orderTotalOnPaypalCheckout}}" userInput="$127.01" stepKey="verifyOrderTotalOnPaypalPage"/>
88+
<!-- Click PayPal button and go back to Magento site -->
89+
<actionGroup ref="StorefrontPaypalSwitchBackToMagentoFromCheckoutPageActionGroup" stepKey="confirmPaymentAndGoBackToMagento"/>
90+
<!-- I see order successful Page -->
91+
<actionGroup ref="AssertStorefrontCheckoutSuccessActionGroup" stepKey="assertOrderSuccess"/>
92+
<grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="orderNumber"/>
93+
<assertNotEmpty stepKey="assertOrderIdIsNotEmpty">
94+
<actualResult type="const">$orderNumber</actualResult>
95+
</assertNotEmpty>
96+
<!-- Navigate to customer Dashboard Page -->
97+
<amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="navigateToCustomerDashboardPage"/>
98+
<waitForPageLoad stepKey="waitForCustomerDashboardPageLoad"/>
99+
</test>
100+
</tests>

‎app/code/Magento/QuoteGraphQl/Model/CartItem/ProductStock.php

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
use Magento\Catalog\Api\Data\ProductInterface;
1111
use Magento\Catalog\Api\ProductRepositoryInterface;
12-
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1312
use Magento\CatalogInventory\Api\StockRegistryInterface;
1413
use Magento\CatalogInventory\Model\Configuration;
1514
use Magento\CatalogInventory\Model\StockState;
@@ -38,14 +37,12 @@ class ProductStock
3837
*
3938
* @param ProductRepositoryInterface $productRepositoryInterface
4039
* @param StockState $stockState
41-
* @param StockConfigurationInterface $stockConfiguration
4240
* @param ScopeConfigInterface $scopeConfig
4341
* @param StockRegistryInterface $stockRegistry
4442
*/
4543
public function __construct(
4644
private readonly ProductRepositoryInterface $productRepositoryInterface,
4745
private readonly StockState $stockState,
48-
private readonly StockConfigurationInterface $stockConfiguration,
4946
private readonly ScopeConfigInterface $scopeConfig,
5047
private readonly StockRegistryInterface $stockRegistry
5148
) {
@@ -70,9 +67,21 @@ public function isProductAvailable(Item $cartItem): bool
7067
$variantProduct = $this->getVariantProduct($cartItem);
7168
$requiredItemQty = $requestedQty + $previousQty;
7269
if ($variantProduct !== null) {
73-
return $this->isStockQtyAvailable($variantProduct, $requestedQty, $requiredItemQty, $previousQty);
70+
return $this->isStockQtyAvailable(
71+
$cartItem,
72+
$variantProduct,
73+
$requestedQty,
74+
$requiredItemQty,
75+
$previousQty
76+
);
7477
}
75-
return $this->isStockQtyAvailable($cartItem->getProduct(), $requestedQty, $requiredItemQty, $previousQty);
78+
return $this->isStockQtyAvailable(
79+
$cartItem,
80+
$cartItem->getProduct(),
81+
$requestedQty,
82+
$requiredItemQty,
83+
$previousQty
84+
);
7685
}
7786

7887
/**
@@ -93,7 +102,13 @@ public function isStockAvailableBundle(Item $cartItem, int $previousQty, $reques
93102
if ($totalRequestedQty) {
94103
$requiredItemQty = $requiredItemQty * $totalRequestedQty;
95104
}
96-
if (!$this->isStockQtyAvailable($qtyOption->getProduct(), $requestedQty, $requiredItemQty, $previousQty)) {
105+
if (!$this->isStockQtyAvailable(
106+
$cartItem,
107+
$qtyOption->getProduct(),
108+
$requestedQty,
109+
$requiredItemQty,
110+
$previousQty
111+
)) {
97112
return false;
98113
}
99114
}
@@ -147,24 +162,27 @@ private function getVariantProduct(Item $cartItem): ?ProductInterface
147162
/**
148163
* Check if product is available in stock
149164
*
165+
* @param Item $cartItem
150166
* @param ProductInterface $product
151167
* @param float $itemQty
152168
* @param float $requiredQuantity
153169
* @param float $prevQty
154170
* @return bool
155171
*/
156172
private function isStockQtyAvailable(
173+
Item $cartItem,
157174
ProductInterface $product,
158175
float $itemQty,
159176
float $requiredQuantity,
160177
float $prevQty
161178
): bool {
179+
$scopeId = $cartItem->getStore()->getId();
162180
$stockStatus = $this->stockState->checkQuoteItemQty(
163181
$product->getId(),
164182
$itemQty,
165183
$requiredQuantity,
166184
$prevQty,
167-
$this->stockConfiguration->getDefaultScopeId()
185+
$scopeId
168186
);
169187

170188
return ((bool) $stockStatus->getHasError()) === false;

0 commit comments

Comments
 (0)