Skip to content

Commit 5977749

Browse files
🔃 [Magento Community Engineering] Community Contributions - 2.4-develop latest changes
Accepted Community Pull Requests: - #30077: Prevent "Overwrite the existing configuration for ...?" question (by @flancer64) - #27953: Fixed Issue 12225: Tier pricing tax shows only including tax (by @jiten-patel) - #28663: change error to code is reserved key instead of code already exists (by @AbdulRahmanAbouzaid) - #28491: Fix setup upgrade command re enables caches (by @AbdulRahmanAbouzaid) Fixed GitHub Issues: - #26762: undefined index db-ssl-verify (reported by @DanielRuf) has been fixed in #30077 by @flancer64 in 2.4-develop branch Related commits: 1. 5f98975 2. cf1a716 3. 5c23f4d 4. 23aa806 - #29612: [Issue] Prevent "Overwrite the existing configuration for db-ssl-verify?" question (reported by @m2-assistant[bot]) has been fixed in #30077 by @flancer64 in 2.4-develop branch Related commits: 1. 5f98975 2. cf1a716 3. 5c23f4d 4. 23aa806 - #12225: Tier pricing tax shows only including tax (reported by @erjenrijnders) has been fixed in #27953 by @jiten-patel in 2.4-develop branch Related commits: 1. c9bb1d3 2. 0b839e9 3. 53d7226 4. e4be19b 5. 406b1f4 6. f18aaf6 7. 1a78b49 8. 182edf6 9. bc6c2d6 10. 59d5d30 11. 659a6d9 12. 4bed3cb 13. c440566 - #28479: Product attributes product_type, type_id cannot be created/edited form admin (reported by @IgorM92) has been fixed in #28663 by @AbdulRahmanAbouzaid in 2.4-develop branch Related commits: 1. 580ffe5 2. 9bc6cc9 3. 74aaccd 4. 9c38339 5. f9374c8 6. 86f0c6b 7. e95d5d2 8. d396c0a 9. 1d0b91b 10. c9a1afa 11. 804a049 12. 1ea5d75 13. 2206f77 - #28186: Running bin/magento setup:upgrade re-enables layout, block_html and full_page caches (reported by @markshust) has been fixed in #28491 by @AbdulRahmanAbouzaid in 2.4-develop branch Related commits: 1. e73e8e4 2. ec9462e 3. d8c0afd 4. 3028f29 5. 6a82be1 6. 36198f2 7. 634d857 8. dceaeae 9. 46c60ea 10. e3b8b3b 11. 7e4cfe2 12. aaf944e 13. 461b644
2 parents b2e7753 + de9fbe2 commit 5977749

File tree

14 files changed

+527
-103
lines changed

14 files changed

+527
-103
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
class Validate extends AttributeAction implements HttpGetActionInterface, HttpPostActionInterface
3434
{
3535
const DEFAULT_MESSAGE_KEY = 'message';
36+
private const RESERVED_ATTRIBUTE_CODES = ['product_type', 'type_id'];
3637

3738
/**
3839
* @var JsonFactory
@@ -145,11 +146,16 @@ public function execute()
145146
);
146147
}
147148

148-
if ($attribute->getId() && !$attributeId || $attributeCode === 'product_type' || $attributeCode === 'type_id') {
149+
if (in_array($attributeCode, self::RESERVED_ATTRIBUTE_CODES, true)) {
150+
$message = __('Code (%1) is a reserved key and cannot be used as attribute code.', $attributeCode);
151+
$this->setMessageToResponse($response, [$message]);
152+
$response->setError(true);
153+
}
154+
155+
if ($attribute->getId() && !$attributeId) {
149156
$message = strlen($this->getRequest()->getParam('attribute_code'))
150157
? __('An attribute with this code already exists.')
151158
: __('An attribute with the same code (%1) already exists.', $attributeCode);
152-
153159
$this->setMessageToResponse($response, [$message]);
154160

155161
$response->setError(true);

app/code/Magento/Catalog/Pricing/Price/TierPrice.php

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,27 @@
99
use Magento\Catalog\Model\Product;
1010
use Magento\Customer\Api\GroupManagementInterface;
1111
use Magento\Customer\Model\Session;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Framework\App\ObjectManager;
1214
use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
1315
use Magento\Framework\Pricing\Amount\AmountInterface;
1416
use Magento\Framework\Pricing\Price\AbstractPrice;
1517
use Magento\Framework\Pricing\Price\BasePriceProviderInterface;
18+
use Magento\Framework\Pricing\PriceCurrencyInterface;
1619
use Magento\Framework\Pricing\PriceInfoInterface;
1720
use Magento\Customer\Model\Group\RetrieverInterface as CustomerGroupRetrieverInterface;
21+
use Magento\Tax\Model\Config;
1822

1923
/**
2024
* @api
2125
* @since 100.0.2
26+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
27+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
2228
*/
2329
class TierPrice extends AbstractPrice implements TierPriceInterface, BasePriceProviderInterface
2430
{
31+
private const XML_PATH_TAX_DISPLAY_TYPE = 'tax/display/type';
32+
2533
/**
2634
* Price type tier
2735
*/
@@ -62,35 +70,43 @@ class TierPrice extends AbstractPrice implements TierPriceInterface, BasePricePr
6270
*/
6371
private $customerGroupRetriever;
6472

73+
/**
74+
* @var ScopeConfigInterface
75+
*/
76+
private $scopeConfig;
77+
6578
/**
6679
* @param Product $saleableItem
6780
* @param float $quantity
6881
* @param CalculatorInterface $calculator
69-
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
82+
* @param PriceCurrencyInterface $priceCurrency
7083
* @param Session $customerSession
7184
* @param GroupManagementInterface $groupManagement
7285
* @param CustomerGroupRetrieverInterface|null $customerGroupRetriever
86+
* @param ScopeConfigInterface|null $scopeConfig
7387
*/
7488
public function __construct(
7589
Product $saleableItem,
7690
$quantity,
7791
CalculatorInterface $calculator,
78-
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
92+
PriceCurrencyInterface $priceCurrency,
7993
Session $customerSession,
8094
GroupManagementInterface $groupManagement,
81-
CustomerGroupRetrieverInterface $customerGroupRetriever = null
95+
CustomerGroupRetrieverInterface $customerGroupRetriever = null,
96+
?ScopeConfigInterface $scopeConfig = null
8297
) {
8398
$quantity = (float)$quantity ? $quantity : 1;
8499
parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency);
85100
$this->customerSession = $customerSession;
86101
$this->groupManagement = $groupManagement;
87102
$this->customerGroupRetriever = $customerGroupRetriever
88-
?? \Magento\Framework\App\ObjectManager::getInstance()->get(CustomerGroupRetrieverInterface::class);
103+
?? ObjectManager::getInstance()->get(CustomerGroupRetrieverInterface::class);
89104
if ($saleableItem->hasCustomerGroupId()) {
90105
$this->customerGroup = (int) $saleableItem->getCustomerGroupId();
91106
} else {
92107
$this->customerGroup = (int) $this->customerGroupRetriever->getCustomerGroupId();
93108
}
109+
$this->scopeConfig = $scopeConfig ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class);
94110
}
95111

96112
/**
@@ -136,6 +152,8 @@ protected function isFirstPriceBetter($firstPrice, $secondPrice)
136152
}
137153

138154
/**
155+
* Returns tier price count
156+
*
139157
* @return int
140158
*/
141159
public function getTierPriceCount()
@@ -144,6 +162,8 @@ public function getTierPriceCount()
144162
}
145163

146164
/**
165+
* Returns tier price list
166+
*
147167
* @return array
148168
*/
149169
public function getTierPriceList()
@@ -155,15 +175,32 @@ public function getTierPriceList()
155175
$this->priceList,
156176
function (&$priceData) {
157177
/* convert string value to float */
158-
$priceData['price_qty'] = $priceData['price_qty'] * 1;
178+
$priceData['price_qty'] *= 1;
179+
if ($this->getConfigTaxDisplayType() === Config::DISPLAY_TYPE_BOTH) {
180+
$exclTaxPrice = $this->calculator->getAmount($priceData['price'], $this->product, true);
181+
$priceData['excl_tax_price'] = $exclTaxPrice;
182+
}
159183
$priceData['price'] = $this->applyAdjustment($priceData['price']);
160184
}
161185
);
162186
}
187+
163188
return $this->priceList;
164189
}
165190

166191
/**
192+
* Returns config tax display type
193+
*
194+
* @return int
195+
*/
196+
private function getConfigTaxDisplayType(): int
197+
{
198+
return (int) $this->scopeConfig->getValue(self::XML_PATH_TAX_DISPLAY_TYPE);
199+
}
200+
201+
/**
202+
* Filters tier prices
203+
*
167204
* @param array $priceList
168205
* @return array
169206
*/
@@ -204,6 +241,8 @@ protected function filterTierPrices(array $priceList)
204241
}
205242

206243
/**
244+
* Returns base price
245+
*
207246
* @return float
208247
*/
209248
protected function getBasePrice()
@@ -213,25 +252,22 @@ protected function getBasePrice()
213252
}
214253

215254
/**
216-
* Calculates savings percentage according to the given tier price amount
217-
* and related product price amount.
255+
* Calculates savings percentage according to the given tier price amount and related product price amount.
218256
*
219257
* @param AmountInterface $amount
220-
*
221258
* @return float
222259
*/
223260
public function getSavePercent(AmountInterface $amount)
224261
{
225-
$productPriceAmount = $this->priceInfo->getPrice(
226-
FinalPrice::PRICE_CODE
227-
)->getAmount();
262+
$productPriceAmount = $this->priceInfo->getPrice(FinalPrice::PRICE_CODE)
263+
->getAmount();
228264

229-
return round(
230-
100 - ((100 / $productPriceAmount->getValue()) * $amount->getValue())
231-
);
265+
return round(100 - ((100 / $productPriceAmount->getValue()) * $amount->getValue()));
232266
}
233267

234268
/**
269+
* Apply adjustment to price
270+
*
235271
* @param float|string $price
236272
* @return \Magento\Framework\Pricing\Amount\AmountInterface
237273
*/
@@ -314,6 +350,8 @@ protected function getStoredTierPrices()
314350
}
315351

316352
/**
353+
* Return is percentage discount
354+
*
317355
* @return bool
318356
*/
319357
public function isPercentageDiscount()

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,20 @@
385385
<data key="default_store_label" unique="suffix">Attribute Store label &lt;span&gt; </data>
386386
<data key="frontend_input">text</data>
387387
</entity>
388+
<entity name="ProductTypeIdAttribute" type="ProductAttribute">
389+
<data key="frontend_label">Type id</data>
390+
<data key="attribute_code">type_id</data>
391+
<data key="frontend_input">text</data>
392+
<data key="is_required">No</data>
393+
<data key="is_required_admin">No</data>
394+
</entity>
395+
<entity name="ProductProductTypeAttribute" type="ProductAttribute">
396+
<data key="frontend_label">Product type</data>
397+
<data key="attribute_code">product_type</data>
398+
<data key="frontend_input">text</data>
399+
<data key="is_required">No</data>
400+
<data key="is_required_admin">No</data>
401+
</entity>
388402
<!-- Product attribute from file "export_import_configurable_product.csv" -->
389403
<entity name="ProductAttributeWithTwoOptionsForExportImport" extends="productAttributeDropdownTwoOptions" type="ProductAttribute">
390404
<data key="attribute_code">attribute</data>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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="CreateProductAttributeEntityWithReservedKeysTest">
11+
<annotations>
12+
<features value="Catalog"/>
13+
<stories value="Create Product Attributes"/>
14+
<title value="Attributess with reserved codes should not be created"/>
15+
<description value="Admin should not be able to create product attribute with reserved codes"/>
16+
<severity value="MINOR"/>
17+
<testCaseId value="MC-37806"/>
18+
<group value="catalog"/>
19+
</annotations>
20+
21+
<before>
22+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
23+
</before>
24+
<after>
25+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
26+
</after>
27+
28+
<!--Navigate to Stores > Attributes > Product.-->
29+
<amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="goToProductAttributesGrid"/>
30+
31+
<!--Create new Product Attribute as TextField, with type_id code.-->
32+
<actionGroup ref="CreateProductAttributeActionGroup" stepKey="createAttribute">
33+
<argument name="attribute" value="ProductTypeIdAttribute"/>
34+
</actionGroup>
35+
<see stepKey="seeErrorMessage" selector="{{AdminMessagesSection.errorMessage}}" userInput="Code (type_id) is a reserved key and cannot be used as attribute code."/>
36+
37+
<!--Navigate to Stores > Attributes > Product.-->
38+
<amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="backToProductAttributesGrid"/>
39+
40+
<!--Create new Product Attribute as TextField, with product_type code.-->
41+
<actionGroup ref="CreateProductAttributeActionGroup" stepKey="createAttribute2">
42+
<argument name="attribute" value="ProductProductTypeAttribute"/>
43+
</actionGroup>
44+
45+
<see stepKey="seeErrorMessage2" selector="{{AdminMessagesSection.errorMessage}}" userInput="Code (product_type) is a reserved key and cannot be used as attribute code."/>
46+
</test>
47+
</tests>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ Catalog,Catalog
209209
"You saved the product attribute.","You saved the product attribute."
210210
"An attribute with this code already exists.","An attribute with this code already exists."
211211
"An attribute with the same code (%1) already exists.","An attribute with the same code (%1) already exists."
212+
"Code (%1) is a reserved key and cannot be used as attribute code.","Code (%1) is a reserved key and cannot be used as attribute code."
212213
"The value of Admin must be unique.","The value of Admin must be unique."
213214
"The value of Admin scope can't be empty.","The value of Admin scope can't be empty."
214215
"You duplicated the product.","You duplicated the product."

0 commit comments

Comments
 (0)