Skip to content

Commit 5609fd2

Browse files
author
Gabriel da Gama
authored
Merge branch '2.4-develop' into feature-additional-country-regions
2 parents 93b1d30 + 479f304 commit 5609fd2

File tree

122 files changed

+2111
-393
lines changed

Some content is hidden

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

122 files changed

+2111
-393
lines changed

app/code/Magento/Authorization/Model/Rules.php

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,44 +25,30 @@
2525
class Rules extends \Magento\Framework\Model\AbstractModel
2626
{
2727
/**
28-
* Class constructor
29-
*
30-
* @param \Magento\Framework\Model\Context $context
31-
* @param \Magento\Framework\Registry $registry
32-
* @param \Magento\Authorization\Model\ResourceModel\Rules $resource
33-
* @param \Magento\Authorization\Model\ResourceModel\Rules\Collection $resourceCollection
34-
* @param array $data
35-
*/
36-
public function __construct(
37-
\Magento\Framework\Model\Context $context,
38-
\Magento\Framework\Registry $registry,
39-
\Magento\Authorization\Model\ResourceModel\Rules $resource,
40-
\Magento\Authorization\Model\ResourceModel\Rules\Collection $resourceCollection,
41-
array $data = []
42-
) {
43-
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
44-
}
45-
46-
/**
47-
* Class constructor
48-
*
49-
* @return void
28+
* @inheritdoc
5029
*/
5130
protected function _construct()
5231
{
5332
$this->_init(\Magento\Authorization\Model\ResourceModel\Rules::class);
5433
}
5534

5635
/**
36+
* Obsolete method of update
37+
*
5738
* @return $this
39+
* @deprecated Method was never implemented and used.
5840
*/
5941
public function update()
6042
{
61-
$this->getResource()->update($this);
43+
// phpcs:disable Magento2.Functions.DiscouragedFunction
44+
trigger_error('Method was never implemented and used.', E_USER_DEPRECATED);
45+
6246
return $this;
6347
}
6448

6549
/**
50+
* Save authorization rule relation
51+
*
6652
* @return $this
6753
*/
6854
public function saveRel()

app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212

1313
namespace Magento\Catalog\Block\Product\View\Options;
1414

15-
use Magento\Catalog\Pricing\Price\BasePrice;
1615
use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule;
1716
use Magento\Catalog\Pricing\Price\CustomOptionPriceInterface;
1817
use Magento\Framework\App\ObjectManager;
18+
use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
19+
use Magento\Framework\Pricing\PriceCurrencyInterface;
1920

2021
/**
2122
* Product options section abstract block.
@@ -55,24 +56,42 @@ abstract class AbstractOptions extends \Magento\Framework\View\Element\Template
5556
*/
5657
private $calculateCustomOptionCatalogRule;
5758

59+
/**
60+
* @var CalculatorInterface
61+
*/
62+
private $calculator;
63+
64+
/**
65+
* @var PriceCurrencyInterface
66+
*/
67+
private $priceCurrency;
68+
5869
/**
5970
* @param \Magento\Framework\View\Element\Template\Context $context
6071
* @param \Magento\Framework\Pricing\Helper\Data $pricingHelper
6172
* @param \Magento\Catalog\Helper\Data $catalogData
6273
* @param array $data
6374
* @param CalculateCustomOptionCatalogRule|null $calculateCustomOptionCatalogRule
75+
* @param CalculatorInterface|null $calculator
76+
* @param PriceCurrencyInterface|null $priceCurrency
6477
*/
6578
public function __construct(
6679
\Magento\Framework\View\Element\Template\Context $context,
6780
\Magento\Framework\Pricing\Helper\Data $pricingHelper,
6881
\Magento\Catalog\Helper\Data $catalogData,
6982
array $data = [],
70-
CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null
83+
CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null,
84+
CalculatorInterface $calculator = null,
85+
PriceCurrencyInterface $priceCurrency = null
7186
) {
7287
$this->pricingHelper = $pricingHelper;
7388
$this->_catalogHelper = $catalogData;
7489
$this->calculateCustomOptionCatalogRule = $calculateCustomOptionCatalogRule
7590
?? ObjectManager::getInstance()->get(CalculateCustomOptionCatalogRule::class);
91+
$this->calculator = $calculator
92+
?? ObjectManager::getInstance()->get(CalculatorInterface::class);
93+
$this->priceCurrency = $priceCurrency
94+
?? ObjectManager::getInstance()->get(PriceCurrencyInterface::class);
7695
parent::__construct($context, $data);
7796
}
7897

@@ -188,7 +207,13 @@ protected function _formatPrice($value, $flag = true)
188207
}
189208

190209
$context = [CustomOptionPriceInterface::CONFIGURATION_OPTION_FLAG => true];
191-
$optionAmount = $customOptionPrice->getCustomAmount($value['pricing_value'], null, $context);
210+
$optionAmount = $isPercent
211+
? $this->calculator->getAmount(
212+
$this->priceCurrency->roundPrice($value['pricing_value']),
213+
$this->getProduct(),
214+
null,
215+
$context
216+
) : $customOptionPrice->getCustomAmount($value['pricing_value'], null, $context);
192217
$priceStr .= $this->getLayout()->getBlock('product.price.render.default')->renderAmount(
193218
$optionAmount,
194219
$customOptionPrice,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AssertStorefrontCustomOptionCheckboxByPriceActionGroup">
12+
<annotations>
13+
<description>Validates that the provided price for Custom Option Checkbox is present on the Storefront Product page.</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="optionTitle" type="string" defaultValue="{{ProductOptionCheckbox.title}}"/>
17+
<argument name="price" type="string" defaultValue="10"/>
18+
</arguments>
19+
20+
<seeElement selector="{{StorefrontProductInfoMainSection.productAttributeOptionsCheckbox(optionTitle, price)}}" stepKey="checkPriceProductOptionCheckbox"/>
21+
</actionGroup>
22+
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,10 @@
577577
<var key="sku" entityType="product" entityKey="sku" />
578578
<requiredEntity type="product_option">ProductOptionDropDownWithLongValuesTitle</requiredEntity>
579579
</entity>
580+
<entity name="productWithCheckbox" type="product">
581+
<var key="sku" entityType="product" entityKey="sku" />
582+
<requiredEntity type="product_option">ProductOptionCheckbox</requiredEntity>
583+
</entity>
580584
<entity name="productWithDropdownOption" type="product">
581585
<var key="sku" entityType="product" entityKey="sku" />
582586
<requiredEntity type="product_option">ProductOptionValueDropdown</requiredEntity>

app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryToAnotherPositionInCategoryTreeTest.xml

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,27 @@
3838
<waitForPageLoad stepKey="waitForPageToLoad"/>
3939
<!-- Create three level deep sub Category -->
4040
<click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickAddSubCategoryButton"/>
41+
<waitForPageLoad stepKey="waitForAddSubCategoryClick1"/>
42+
<waitForElementVisible selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" stepKey="waitForSubCategoryName1"/>
4143
<fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{FirstLevelSubCat.name}}" stepKey="fillSubCategoryName"/>
4244
<actionGroup ref="AdminSaveCategoryActionGroup" stepKey="saveFirstLevelSubCategory"/>
43-
<seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="seeSuccessMessage"/>
45+
<waitForElementVisible selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="seeSuccessMessage"/>
4446
<click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButtonAgain"/>
47+
<waitForPageLoad stepKey="waitForAddSubCategoryClick2"/>
48+
<waitForElementVisible selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" stepKey="waitForSubCategoryName2"/>
4549
<fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SecondLevelSubCat.name}}" stepKey="fillSecondLevelSubCategoryName"/>
4650
<actionGroup ref="AdminSaveCategoryActionGroup" stepKey="saveSecondLevelSubCategory"/>
47-
<seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="seeSaveSuccessMessage"/>
51+
<waitForElementVisible selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="seeSaveSuccessMessage"/>
4852
<grabFromCurrentUrl stepKey="categoryId" regex="#\/([0-9]*)?\/$#" />
4953

5054
<!-- Move Category to another position in category tree, but click cancel button -->
5155
<dragAndDrop selector1="{{AdminCategorySidebarTreeSection.categoryInTree(SecondLevelSubCat.name)}}" selector2="{{AdminCategorySidebarTreeSection.categoryInTree('Default Category')}}" stepKey="moveCategory"/>
52-
<see selector="{{AdminCategoryModalSection.message}}" userInput="This operation can take a long time" stepKey="seeWarningMessage"/>
56+
<waitForText selector="{{AdminCategoryModalSection.message}}" userInput="This operation can take a long time" stepKey="seeWarningMessage"/>
5357
<click selector="{{AdminCategoryModalSection.cancel}}" stepKey="clickCancelButtonOnWarningPopup"/>
5458
<!-- Verify Category in store front page after clicking cancel button -->
5559
<amOnPage url="/$$createDefaultCategory.name$$/{{FirstLevelSubCat.name}}/{{SecondLevelSubCat.name}}.html" stepKey="seeTheCategoryInStoreFrontPage"/>
5660
<waitForPageLoad stepKey="waitForStoreFrontPageLoad"/>
57-
<seeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(_defaultCategory.name)}}" stepKey="seeDefaultCategoryOnStoreNavigationBar"/>
61+
<waitForElementVisible selector="{{StorefrontHeaderSection.NavigationCategoryByName(_defaultCategory.name)}}" stepKey="seeDefaultCategoryOnStoreNavigationBar"/>
5862
<dontSeeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SimpleSubCategory.name)}}" stepKey="dontSeeSubCategoryOnStoreNavigationBar"/>
5963
<!-- Verify breadcrumbs in store front page after clicking cancel button -->
6064
<grabMultiple selector="{{StorefrontNavigationSection.categoryBreadcrumbs}}" stepKey="breadcrumbs"/>
@@ -67,17 +71,18 @@
6771
<actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openTheAdminCategoryIndexPage"/>
6872
<actionGroup ref="AdminExpandCategoryTreeActionGroup" stepKey="clickOnExpandTree"/>
6973
<dragAndDrop selector1="{{AdminCategorySidebarTreeSection.categoryInTree(SecondLevelSubCat.name)}}" selector2="{{AdminCategorySidebarTreeSection.categoryInTree('Default Category')}}" stepKey="DragCategory"/>
70-
<see selector="{{AdminCategoryModalSection.message}}" userInput="This operation can take a long time" stepKey="seeWarningMessageForOneMoreTime"/>
74+
<waitForText selector="{{AdminCategoryModalSection.message}}" userInput="This operation can take a long time" stepKey="seeWarningMessageForOneMoreTime"/>
75+
<waitForElementVisible selector="{{AdminCategoryModalSection.ok}}" stepKey="waitForOkButtonOnWarningPopup"/>
7176
<click selector="{{AdminCategoryModalSection.ok}}" stepKey="clickOkButtonOnWarningPopup"/>
7277
<waitForPageLoad stepKey="waitTheForPageToLoad"/>
73-
<see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You moved the category." stepKey="seeSuccessMoveMessage"/>
78+
<waitForText selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You moved the category." stepKey="seeSuccessMoveMessage"/>
7479
<amOnPage url="/{{SimpleSubCategory.name}}.html" stepKey="seeCategoryNameInStoreFrontPage"/>
7580
<waitForPageLoad stepKey="waitForStoreFrontPageToLoad"/>
7681
<!-- Verify Category in store front after moving category to another position in category tree -->
7782
<amOnPage url="{{StorefrontCategoryPage.url(SecondLevelSubCat.name)}}" stepKey="amOnCategoryPage"/>
7883
<waitForPageLoad stepKey="waitForPageToBeLoaded"/>
79-
<seeElement selector="{{StorefrontCategoryMainSection.CategoryTitle(SecondLevelSubCat.name)}}" stepKey="seeCategoryInTitle"/>
80-
<seeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SecondLevelSubCat.name)}}" stepKey="seeCategoryOnStoreNavigationBarAfterMove"/>
84+
<waitForElementVisible selector="{{StorefrontCategoryMainSection.CategoryTitle(SecondLevelSubCat.name)}}" stepKey="seeCategoryInTitle"/>
85+
<waitForElementVisible selector="{{StorefrontHeaderSection.NavigationCategoryByName(SecondLevelSubCat.name)}}" stepKey="seeCategoryOnStoreNavigationBarAfterMove"/>
8186
<!-- Verify breadcrumbs in store front page after moving category to another position in category tree -->
8287
<click selector="{{StorefrontHeaderSection.NavigationCategoryByName(SecondLevelSubCat.name)}}" stepKey="clickCategoryOnNavigation"/>
8388
<waitForPageLoad stepKey="waitForCategoryLoad"/>
@@ -91,6 +96,7 @@
9196
<amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="openUrlRewriteIndexPage"/>
9297
<waitForPageLoad stepKey="waitForUrlRewritePageLoad"/>
9398
<click selector="{{AdminDataGridHeaderSection.filters}}" stepKey="openUrlRewriteGridFilters"/>
99+
<waitForElementVisible selector="{{AdminDataGridHeaderSection.filterFieldInput('request_path')}}" stepKey="waitForCategoryUrlKey"/>
94100
<fillField selector="{{AdminDataGridHeaderSection.filterFieldInput('request_path')}}" userInput="{{SecondLevelSubCat.name_lwr}}.html" stepKey="fillCategoryUrlKey"/>
95101
<click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickOrderApplyFilters"/>
96102
<waitForPageLoad stepKey="waitForSearch"/>
@@ -102,6 +108,7 @@
102108
<see selector="{{AdminUrlRewriteIndexSection.gridCellByColumnRowNumber('2', 'Redirect Type')}}" userInput="No" stepKey="verifyTheRedirectTypeAfterMove"/>
103109
<!-- Verify before move Redirect Path displayed with associated Target Path and Redirect Type-->
104110
<click selector="{{AdminDataGridHeaderSection.filters}}" stepKey="openUrlRewriteGridFilters1"/>
111+
<waitForElementVisible selector="{{AdminDataGridHeaderSection.filterFieldInput('request_path')}}" stepKey="waitForTheCategoryUrlKey"/>
105112
<fillField selector="{{AdminDataGridHeaderSection.filterFieldInput('request_path')}}" userInput="{{SecondLevelSubCat.name_lwr}}" stepKey="fillTheCategoryUrlKey"/>
106113
<click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickOrderApplyFilters1"/>
107114
<waitForPageLoad stepKey="waitForSearch1"/>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
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="StorefrontCheckCustomOptionPriceDifferentCurrencyTest">
11+
<annotations>
12+
<features value="Catalog"/>
13+
<stories value="Custom options"/>
14+
<title value="Check custom option price with different currency"/>
15+
<description value="Check custom option price with different currency on the product page"/>
16+
<severity value="CRITICAL"/>
17+
<testCaseId value="MC-38926"/>
18+
<useCaseId value="MC-30626"/>
19+
<group value="catalog"/>
20+
</annotations>
21+
<before>
22+
<magentoCLI command="config:set {{SetAllowedCurrenciesConfigForUSD.path}} {{SetAllowedCurrenciesConfigForUSD.value}},{{SetAllowedCurrenciesConfigForEUR.value}}" stepKey="setCurrencyAllow"/>
23+
<createData entity="_defaultCategory" stepKey="createCategory"/>
24+
<createData entity="_defaultProduct" stepKey="createProduct">
25+
<requiredEntity createDataKey="createCategory"/>
26+
<field key="price">10</field>
27+
</createData>
28+
<updateData createDataKey="createProduct" entity="productWithCheckbox" stepKey="updateProductWithOptions"/>
29+
</before>
30+
<after>
31+
<magentoCLI command="config:set {{SetAllowedCurrenciesConfigForUSD.path}} {{SetAllowedCurrenciesConfigForUSD.value}}" stepKey="setCurrencyAllow"/>
32+
<deleteData createDataKey="createProduct" stepKey="deleteProduct"/>
33+
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
34+
</after>
35+
<actionGroup ref="StorefrontOpenProductEntityPageActionGroup" stepKey="openProductPageOnStorefront">
36+
<argument name="product" value="$createProduct$"/>
37+
</actionGroup>
38+
<actionGroup ref="AssertStorefrontCustomOptionCheckboxByPriceActionGroup" stepKey="checkPriceProductOptionUSD">
39+
<argument name="price" value="12.3"/>
40+
</actionGroup>
41+
<actionGroup ref="StorefrontSwitchCurrencyActionGroup" stepKey="switchEURCurrency">
42+
<argument name="currency" value="EUR"/>
43+
</actionGroup>
44+
<actionGroup ref="AssertStorefrontCustomOptionCheckboxByPriceActionGroup" stepKey="checkPriceProductOptionEUR">
45+
<argument name="price" value="8.7"/>
46+
</actionGroup>
47+
</test>
48+
</tests>

app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77

88
namespace Magento\CatalogSearch\Model\Layer\Filter;
99

10+
use Magento\Catalog\Api\Data\ProductAttributeInterface;
1011
use Magento\Catalog\Model\Layer\Filter\AbstractFilter;
12+
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection;
13+
use Magento\Framework\App\RequestInterface;
1114

1215
/**
1316
* Layer attribute filter
@@ -48,25 +51,27 @@ public function __construct(
4851
/**
4952
* Apply attribute option filter to product collection
5053
*
51-
* @param \Magento\Framework\App\RequestInterface $request
54+
* @param RequestInterface $request
5255
* @return $this
53-
* @throws \Magento\Framework\Exception\LocalizedException
5456
*/
55-
public function apply(\Magento\Framework\App\RequestInterface $request)
57+
public function apply(RequestInterface $request)
5658
{
5759
$attributeValue = $request->getParam($this->_requestVar);
5860
if (empty($attributeValue) && !is_numeric($attributeValue)) {
5961
return $this;
6062
}
6163

6264
$attribute = $this->getAttributeModel();
63-
/** @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $productCollection */
65+
/** @var Collection $productCollection */
6466
$productCollection = $this->getLayer()
6567
->getProductCollection();
66-
$productCollection->addFieldToFilter($attribute->getAttributeCode(), $attributeValue);
68+
$productCollection->addFieldToFilter(
69+
$attribute->getAttributeCode(),
70+
$this->convertAttributeValue($attribute, $attributeValue)
71+
);
6772

6873
$labels = [];
69-
foreach ((array) $attributeValue as $value) {
74+
foreach ((array)$attributeValue as $value) {
7075
$label = $this->getOptionText($value);
7176
$labels[] = is_array($label) ? $label : [$label];
7277
}
@@ -76,6 +81,7 @@ public function apply(\Magento\Framework\App\RequestInterface $request)
7681
->addFilter($this->_createItem($label, $attributeValue));
7782

7883
$this->setItems([]); // set items to disable show filtering
84+
7985
return $this;
8086
}
8187

@@ -88,7 +94,7 @@ public function apply(\Magento\Framework\App\RequestInterface $request)
8894
protected function _getItemsData()
8995
{
9096
$attribute = $this->getAttributeModel();
91-
/** @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $productCollection */
97+
/** @var Collection $productCollection */
9298
$productCollection = $this->getLayer()
9399
->getProductCollection();
94100
$optionsFacetedData = $productCollection->getFacetedData($attribute->getAttributeCode());
@@ -163,6 +169,22 @@ private function getOptionCount($value, $optionsFacetedData)
163169
: 0;
164170
}
165171

172+
/**
173+
* Convert attribute value according to its backend type.
174+
*
175+
* @param ProductAttributeInterface $attribute
176+
* @param mixed $value
177+
* @return int|string
178+
*/
179+
private function convertAttributeValue(ProductAttributeInterface $attribute, $value)
180+
{
181+
if ($attribute->getBackendType() === 'int') {
182+
return (int)$value;
183+
}
184+
185+
return $value;
186+
}
187+
166188
/**
167189
* @inheritdoc
168190
*/

0 commit comments

Comments
 (0)