Skip to content

Commit 8442ee0

Browse files
Merge branch '2.4-develop' into fix-for-issue-39169
2 parents 015fd43 + 8953613 commit 8442ee0

File tree

6 files changed

+103
-38
lines changed

6 files changed

+103
-38
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\ViewModel\Attribute;
9+
10+
use Magento\Framework\View\Element\Block\ArgumentInterface;
11+
use Magento\Catalog\Helper\Data as CatalogHelper;
12+
13+
class ProductAttributeHelper implements ArgumentInterface
14+
{
15+
/**
16+
* @var CatalogHelper
17+
*/
18+
private CatalogHelper $catalogHelper;
19+
20+
/**
21+
* @param CatalogHelper $catalogHelper
22+
*/
23+
public function __construct(CatalogHelper $catalogHelper)
24+
{
25+
$this->catalogHelper = $catalogHelper;
26+
}
27+
28+
/**
29+
* Retrieve the Catalog Helper instance
30+
*
31+
* @return CatalogHelper
32+
*/
33+
public function getCatalogHelper(): CatalogHelper
34+
{
35+
return $this->catalogHelper;
36+
}
37+
}

app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_attribute_edit.xml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<!--
33
/**
4-
* Copyright 2013 Adobe
4+
* Copyright 2014 Adobe
55
* All Rights Reserved.
66
*/
77
-->
@@ -22,7 +22,11 @@
2222
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit" name="attribute_edit_content"/>
2323
</referenceContainer>
2424
<referenceContainer name="js">
25-
<block class="Magento\Backend\Block\Template" name="attribute_edit_js" template="Magento_Catalog::catalog/product/attribute/js.phtml"/>
25+
<block class="Magento\Backend\Block\Template" name="attribute_edit_js" template="Magento_Catalog::catalog/product/attribute/js.phtml">
26+
<arguments>
27+
<argument name="view_model" xsi:type="object">Magento\Catalog\ViewModel\Attribute\ProductAttributeHelper</argument>
28+
</arguments>
29+
</block>
2630
</referenceContainer>
2731
</body>
2832
</page>

app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/js.phtml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ use Magento\Catalog\Helper\Data;
1313
<?php
1414
/** @var \Magento\Framework\Json\Helper\Data $jsonHelper */
1515
$jsonHelper = $block->getData('jsonHelper');
16+
if (!method_exists($jsonHelper, 'getAttributeHiddenFields')) {
17+
/** @var \Magento\Catalog\ViewModel\Attribute\ProductAttributeHelper $viewModel */
18+
$viewModel = $block->getViewModel();
19+
$jsonHelper = $viewModel->getCatalogHelper();
20+
}
1621
$scriptString = <<<script
1722
require([
1823
"jquery",

app/code/Magento/Tax/Model/Calculation/AbstractAggregateCalculator.php

Lines changed: 9 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 2014 Adobe
4+
* All Rights Reserved.
55
*/
66
namespace Magento\Tax\Model\Calculation;
77

@@ -119,7 +119,13 @@ protected function calculateWithTaxNotInPrice(QuoteDetailsItemInterface $item, $
119119
if ($applyTaxAfterDiscount) {
120120
$deltaRoundingType = self::KEY_TAX_BEFORE_DISCOUNT_DELTA_ROUNDING;
121121
}
122-
$rowTaxPerRate = $this->roundAmount($rowTaxPerRate, $taxId, false, $deltaRoundingType, $round, $item);
122+
123+
if ($round && strpos((string) $item->getCode(), 'weee') !== false) {
124+
$rowTaxPerRate = $this->calculationTool->round($rowTaxPerRate);
125+
} else {
126+
$rowTaxPerRate = $this->roundAmount($rowTaxPerRate, $taxId, false, $deltaRoundingType, $round, $item);
127+
}
128+
123129
$rowTaxAfterDiscount = $rowTaxPerRate;
124130

125131
//Handle discount

dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php

Lines changed: 30 additions & 18 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 2014 Adobe
4+
* All Rights Reserved.
55
*/
66
namespace Magento\Tax\Model;
77

@@ -1088,30 +1088,42 @@ public static function calculateTaxTaxInclDataProvider()
10881088
$productInclTaxWithoutStoreIdWithoutTaxClassId = $productTaxInclBase;
10891089

10901090
$productInclTaxWithStoreIdWithTaxClassId['storeId'] = 1;
1091-
$productInclTaxWithStoreIdWithTaxClassId['quoteDetailsData']['items'][] = $quoteDetailTaxInclItemWithDefaultProductTaxClass;
1091+
$productInclTaxWithStoreIdWithTaxClassId['quoteDetailsData']['items'][] =
1092+
$quoteDetailTaxInclItemWithDefaultProductTaxClass;
10921093
$productInclTaxWithStoreIdWithTaxClassId['expectedTaxDetails']['tax_amount'] = 0.70;
10931094
$productInclTaxWithStoreIdWithTaxClassId['expectedTaxDetails']['subtotal'] = 9.30;
10941095
$productInclTaxWithStoreIdWithTaxClassId['expectedTaxDetails']['applied_taxes'] = $quoteDetailAppliedTaxesBase;
1095-
$productInclTaxWithStoreIdWithTaxClassId['expectedTaxDetails']['items'] = $productTaxInclExpectedItemWithDefaultProductTaxClass;
1096+
$productInclTaxWithStoreIdWithTaxClassId['expectedTaxDetails']['items'] =
1097+
$productTaxInclExpectedItemWithDefaultProductTaxClass;
10961098

10971099
$productInclTaxWithStoreIdWithoutTaxClassId['storeId'] = 1;
10981100
$productInclTaxWithStoreIdWithoutTaxClassId['quoteDetailsData']['items'][] = $productTaxInclQuoteDetailItemBase;
1099-
$productInclTaxWithStoreIdWithoutTaxClassId['expectedTaxDetails']['items'] = $productTaxInclExpectedItemWithNoProductTaxClass;
1101+
$productInclTaxWithStoreIdWithoutTaxClassId['expectedTaxDetails']['items'] =
1102+
$productTaxInclExpectedItemWithNoProductTaxClass;
11001103

1101-
$productInclTaxWithoutStoreIdWithTaxClassId['quoteDetailsData']['items'][] = $quoteDetailTaxInclItemWithDefaultProductTaxClass;
1104+
$productInclTaxWithoutStoreIdWithTaxClassId['quoteDetailsData']['items'][] =
1105+
$quoteDetailTaxInclItemWithDefaultProductTaxClass;
11021106
$productInclTaxWithoutStoreIdWithTaxClassId['expectedTaxDetails']['tax_amount'] = 0.70;
11031107
$productInclTaxWithoutStoreIdWithTaxClassId['expectedTaxDetails']['subtotal'] = 9.30;
1104-
$productInclTaxWithoutStoreIdWithTaxClassId['expectedTaxDetails']['applied_taxes'] = $quoteDetailAppliedTaxesBase;
1105-
$productInclTaxWithoutStoreIdWithTaxClassId['expectedTaxDetails']['items'] = $productTaxInclExpectedItemWithDefaultProductTaxClass;
1108+
$productInclTaxWithoutStoreIdWithTaxClassId['expectedTaxDetails']['applied_taxes'] =
1109+
$quoteDetailAppliedTaxesBase;
1110+
$productInclTaxWithoutStoreIdWithTaxClassId['expectedTaxDetails']['items'] =
1111+
$productTaxInclExpectedItemWithDefaultProductTaxClass;
11061112

1107-
$productInclTaxWithoutStoreIdWithoutTaxClassId['quoteDetailsData']['items'][] = $productTaxInclQuoteDetailItemBase;
1108-
$productInclTaxWithoutStoreIdWithoutTaxClassId['expectedTaxDetails']['items'] = $productTaxInclExpectedItemWithNoProductTaxClass;
1113+
$productInclTaxWithoutStoreIdWithoutTaxClassId['quoteDetailsData']['items'][] =
1114+
$productTaxInclQuoteDetailItemBase;
1115+
$productInclTaxWithoutStoreIdWithoutTaxClassId['expectedTaxDetails']['items'] =
1116+
$productTaxInclExpectedItemWithNoProductTaxClass;
11091117

11101118
return [
1111-
'product incl tax with store id, with tax class id' => $productInclTaxWithStoreIdWithTaxClassId,
1112-
'product incl tax with store id, without tax class id' => $productInclTaxWithStoreIdWithoutTaxClassId,
1113-
'product incl tax without store id, with tax class id' => $productInclTaxWithoutStoreIdWithTaxClassId,
1114-
'product incl tax without store id, without tax class id' => $productInclTaxWithoutStoreIdWithoutTaxClassId,
1119+
'product incl tax with store id, with tax class id' =>
1120+
$productInclTaxWithStoreIdWithTaxClassId,
1121+
'product incl tax with store id, without tax class id' =>
1122+
$productInclTaxWithStoreIdWithoutTaxClassId,
1123+
'product incl tax without store id, with tax class id' =>
1124+
$productInclTaxWithoutStoreIdWithTaxClassId,
1125+
'product incl tax without store id, without tax class id' =>
1126+
$productInclTaxWithoutStoreIdWithoutTaxClassId,
11151127
];
11161128
}
11171129

@@ -1397,10 +1409,10 @@ public static function calculateTaxRowBasedDataProvider()
13971409
'weee1-Recycling Fee' => [
13981410
'code' => 'weee1-Recycling Fee',
13991411
'row_tax' => 0.57,
1400-
'price' => 7,
1401-
'price_incl_tax' => 7.57,
1402-
'row_total' => 7,
1403-
'row_total_incl_tax' => 7.57,
1412+
'price' => 7.0,
1413+
'price_incl_tax' => 7.58,
1414+
'row_total' => 7.0,
1415+
'row_total_incl_tax' => 7.58,
14041416
'type' => 'weee',
14051417
'tax_percent' => 8.25,
14061418
'discount_tax_compensation_amount' => 0,

lib/web/jquery/jquery.validate.js

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/*!
2-
* jQuery Validation Plugin v1.20.0
2+
* jQuery Validation Plugin v1.21.0
33
*
44
* https://jqueryvalidation.org/
55
*
6-
* Copyright (c) 2023 Jörn Zaefferer
6+
* Copyright (c) 2024 Jörn Zaefferer
77
* Released under the MIT license
88
*/
99
(function( factory ) {
@@ -294,6 +294,7 @@
294294
onsubmit: true,
295295
ignore: ":hidden",
296296
ignoreTitle: false,
297+
customElements: [],
297298
onfocusin: function( element ) {
298299
this.lastActive = element;
299300

@@ -441,17 +442,17 @@
441442
settings[ eventType ].call( validator, this, event );
442443
}
443444
}
444-
445+
var focusListeners = [ ":text", "[type='password']", "[type='file']", "select", "textarea", "[type='number']", "[type='search']",
446+
"[type='tel']", "[type='url']", "[type='email']", "[type='datetime']", "[type='date']", "[type='month']",
447+
"[type='week']", "[type='time']", "[type='datetime-local']", "[type='range']", "[type='color']",
448+
"[type='radio']", "[type='checkbox']", "[contenteditable]", "[type='button']" ];
449+
var clickListeners = [ "select", "option", "[type='radio']", "[type='checkbox']" ];
445450
$( this.currentForm )
446-
.on( "focusin.validate focusout.validate keyup.validate",
447-
":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
448-
"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
449-
"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
450-
"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
451+
.on( "focusin.validate focusout.validate keyup.validate", focusListeners.concat( this.settings.customElements ).join( ", " ), delegate )
451452

452453
// Support: Chrome, oldIE
453454
// "select" is provided as event.target when clicking a option
454-
.on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
455+
.on( "click.validate", clickListeners.concat( this.settings.customElements ).join( ", " ), delegate );
455456

456457
if ( this.settings.invalidHandler ) {
457458
$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
@@ -648,11 +649,12 @@
648649

649650
elements: function() {
650651
var validator = this,
651-
rulesCache = {};
652+
rulesCache = {},
653+
selectors = [ "input", "select", "textarea", "[contenteditable]" ];
652654

653655
// Select all valid inputs inside the form (no submit or reset buttons)
654656
return $( this.currentForm )
655-
.find( "input, select, textarea, [contenteditable]" )
657+
.find( selectors.concat( this.settings.customElements ).join( ", " ) )
656658
.not( ":submit, :reset, :image, :disabled" )
657659
.not( this.settings.ignore )
658660
.filter( function() {
@@ -1310,7 +1312,6 @@
13101312

13111313
return rules;
13121314
},
1313-
13141315
metadataRules: function (element) {
13151316
if (!$.metadata) {
13161317
return {};
@@ -1321,7 +1322,6 @@
13211322
$(element).metadata()[meta] :
13221323
$(element).metadata();
13231324
},
1324-
13251325
dataRules: function( element ) {
13261326
var rules = {},
13271327
$element = $( element ),
@@ -1513,7 +1513,7 @@
15131513

15141514
// https://jqueryvalidation.org/number-method/
15151515
number: function( value, element ) {
1516-
return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
1516+
return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:-?\.\d+)?$/.test( value );
15171517
},
15181518

15191519
// https://jqueryvalidation.org/digits-method/
@@ -1624,11 +1624,12 @@
16241624

16251625
param = typeof param === "string" && { url: param } || param;
16261626
optionDataString = $.param( $.extend( { data: value }, param.data ) );
1627-
if ( previous.old === optionDataString ) {
1627+
if ( previous.valid !== null && previous.old === optionDataString ) {
16281628
return previous.valid;
16291629
}
16301630

16311631
previous.old = optionDataString;
1632+
previous.valid = null;
16321633
validator = this;
16331634
this.startRequest( element );
16341635
data = {};

0 commit comments

Comments
 (0)