Skip to content

Commit 58bea08

Browse files
authored
Merge branch '2.4-develop' into comprv1
2 parents e64679c + 9608ca2 commit 58bea08

File tree

110 files changed

+5218
-2707
lines changed

Some content is hidden

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

110 files changed

+5218
-2707
lines changed

app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php

+34-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
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

77
namespace Magento\Backend\Block\Widget\Grid\Column\Renderer;
88

9+
use Magento\Framework\Exception\NoSuchEntityException;
10+
911
/**
1012
* Backend grid item renderer currency
1113
*
@@ -82,7 +84,6 @@ public function render(\Magento\Framework\DataObject $row)
8284
{
8385
if ($data = (string)$this->_getValue($row)) {
8486
$currency_code = $this->_getCurrencyCode($row);
85-
$data = (float)$data * $this->_getRate($row);
8687
$sign = (bool)(int)$this->getColumn()->getShowNumberSign() && $data > 0 ? '+' : '';
8788
$data = sprintf("%f", $data);
8889
$data = $this->_localeCurrency->getCurrency($currency_code)->toCurrency($data);
@@ -103,11 +104,28 @@ protected function _getCurrencyCode($row)
103104
return $code;
104105
}
105106
$currency = $this->getColumn()->getCurrency();
106-
107107
if ($currency !== null && $code = $row->getData($currency)) {
108108
return $code;
109109
}
110-
110+
$storeId = $row->getData('store_id');
111+
if ($storeId) {
112+
try {
113+
$store = $this->_storeManager->getStore($storeId);
114+
// Check if the currency is set at the store level
115+
$currencyCode = $store->getCurrentCurrencyCode();
116+
if ($currencyCode) {
117+
return $currencyCode;
118+
}
119+
$website = $store->getWebsite();
120+
// Check if the currency is set at the website level
121+
$currencyCode = $website->getBaseCurrencyCode();
122+
if ($currencyCode) {
123+
return $currencyCode;
124+
}
125+
} catch (NoSuchEntityException $e) {
126+
$this->_logger->warning('Failed to get website currency: ' . $e->getMessage());
127+
}
128+
}
111129
return $this->_currencyLocator->getDefaultCurrency($this->_request);
112130
}
113131

@@ -128,6 +146,17 @@ protected function _getRate($row)
128146
return (float) $rate;
129147
}
130148

149+
$storeId = $row->getData('store_id');
150+
if ($storeId) {
151+
try {
152+
$store = $this->_storeManager->getStore($storeId);
153+
return $store->getBaseCurrency()->getRate($store->getCurrentCurrencyCode());
154+
} catch (NoSuchEntityException $e) {
155+
$this->_logger->warning('Failed to get website currency: ' . $e->getMessage());
156+
}
157+
158+
}
159+
131160
return $this->_defaultBaseCurrency->getRate($this->_getCurrencyCode($row));
132161
}
133162

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Backend\Cron;
9+
10+
use Magento\Framework\Lock\Backend\FileLock;
11+
use Magento\Framework\Lock\LockBackendFactory;
12+
use Psr\Log\LoggerInterface;
13+
14+
class CleanLocks
15+
{
16+
/**
17+
* @param LockBackendFactory $lockFactory
18+
* @param LoggerInterface $logger
19+
*/
20+
public function __construct(
21+
private readonly LockBackendFactory $lockFactory,
22+
private readonly LoggerInterface $logger,
23+
) {
24+
}
25+
26+
/**
27+
* Cron job to cleanup old locks
28+
*/
29+
public function execute(): void
30+
{
31+
$locker = $this->lockFactory->create();
32+
33+
if ($locker instanceof FileLock) {
34+
$numberOfLockFilesDeleted = $locker->cleanupOldLocks();
35+
36+
$this->logger->info(sprintf('Deleted %d old lock files', $numberOfLockFilesDeleted));
37+
}
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
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
declare(strict_types=1);
77

88
namespace Magento\Backend\Test\Unit\Block\Widget\Grid\Column\Renderer;
99

10-
use Magento\Backend\Block\Widget\Grid\Column;
11-
use Magento\Backend\Block\Widget\Grid\Column\Renderer\Currency;
1210
use Magento\Directory\Model\Currency\DefaultLocator;
13-
use Magento\Directory\Model\CurrencyFactory;
1411
use Magento\Framework\App\RequestInterface;
15-
use Magento\Framework\Currency\Data\Currency as CurrencyData;
12+
use Magento\Directory\Model\CurrencyFactory;
13+
use Magento\Backend\Block\Widget\Grid\Column;
1614
use Magento\Framework\DataObject;
17-
use Magento\Framework\Locale\CurrencyInterface;
1815
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
16+
use Magento\Backend\Block\Widget\Grid\Column\Renderer\Currency;
17+
use Magento\Framework\Locale\Currency as LocaleCurrency;
18+
use Magento\Directory\Model\Currency as CurrencyData;
19+
use Magento\Store\Model\Store;
1920
use Magento\Store\Model\StoreManagerInterface;
2021
use PHPUnit\Framework\MockObject\MockObject;
2122
use PHPUnit\Framework\TestCase;
@@ -28,114 +29,128 @@ class CurrencyTest extends TestCase
2829
/**
2930
* @var Currency
3031
*/
31-
protected $_blockCurrency;
32+
private $currencyRenderer;
3233

3334
/**
34-
* @var MockObject
35+
* @var ObjectManager
3536
*/
36-
protected $_localeMock;
37+
private $objectManager;
3738

3839
/**
39-
* @var MockObject
40+
* @var Store|MockObject
4041
*/
41-
protected $_curLocatorMock;
42+
private $storeManagerMock;
4243

4344
/**
44-
* @var MockObject
45+
* @var DefaultLocator|MockObject
4546
*/
46-
protected $_columnMock;
47+
private $currencyLocatorMock;
4748

4849
/**
49-
* @var MockObject
50+
* @var CurrencyFactory|MockObject
5051
*/
51-
protected $_storeManagerMock;
52+
private $currencyFactoryMock;
5253

5354
/**
54-
* @var MockObject
55+
* @var LocaleCurrency|MockObject
5556
*/
56-
protected $_requestMock;
57+
private $localeCurrencyMock;
5758

5859
/**
59-
* @var MockObject
60+
* @var RequestInterface|MockObject
6061
*/
61-
protected $_currencyMock;
62+
private $requestMock;
6263

6364
/**
64-
* @var DataObject
65+
* @var Column|MockObject
6566
*/
66-
protected $_row;
67+
private $columnMock;
6768

6869
protected function setUp(): void
6970
{
70-
$this->_storeManagerMock = $this->getMockForAbstractClass(StoreManagerInterface::class);
71-
$this->_localeMock = $this->getMockForAbstractClass(CurrencyInterface::class);
72-
$this->_requestMock = $this->getMockForAbstractClass(RequestInterface::class);
73-
74-
$this->_curLocatorMock = $this->createMock(DefaultLocator::class);
75-
$this->_columnMock = $this->getMockBuilder(Column::class)
76-
->addMethods(['getIndex', 'getCurrency', 'getRateField'])
71+
$this->objectManager = new ObjectManager($this);
72+
$this->storeManagerMock = $this->createMock(StoreManagerInterface::class);
73+
$this->currencyLocatorMock = $this->createMock(DefaultLocator::class);
74+
$this->currencyFactoryMock = $this->createMock(CurrencyFactory::class);
75+
$this->requestMock = $this->createMock(RequestInterface::class);
76+
$defaultCurrencyCode = 'USD';
77+
$currencyMock = $this->createMock(CurrencyData::class);
78+
$this->currencyFactoryMock->method('create')
79+
->willReturn($currencyMock);
80+
$currencyMock->method('load')
81+
->with($defaultCurrencyCode)
82+
->willReturnSelf();
83+
$this->currencyLocatorMock->method('getDefaultCurrency')
84+
->with($this->requestMock)
85+
->willReturn($defaultCurrencyCode);
86+
$this->columnMock = $this->getMockBuilder(Column::class)
87+
->addMethods(['getIndex', 'getShowNumberSign', 'getDefault'])
7788
->disableOriginalConstructor()
7889
->getMock();
79-
$this->_columnMock->expects($this->any())->method('getIndex')->willReturn('columnIndex');
80-
81-
$this->_currencyMock = $this->createMock(\Magento\Directory\Model\Currency::class);
82-
$this->_currencyMock->expects($this->any())->method('load')->willReturnSelf();
83-
$currencyFactoryMock = $this->createPartialMock(CurrencyFactory::class, ['create']);
84-
$currencyFactoryMock->expects($this->any())->method('create')->willReturn($this->_currencyMock);
85-
86-
$this->_row = new DataObject(['columnIndex' => '10']);
87-
88-
$helper = new ObjectManager($this);
89-
$this->_blockCurrency = $helper->getObject(
90+
$this->columnMock->method('getIndex')->willReturn('value');
91+
$this->columnMock->method('getShowNumberSign')->willReturn(false);
92+
$this->columnMock->method('getDefault')->willReturn('');
93+
$this->localeCurrencyMock = $this->getMockBuilder(LocaleCurrency::class)
94+
->onlyMethods(['getCurrency'])
95+
->addMethods(['toCurrency'])
96+
->disableOriginalConstructor()
97+
->getMock();
98+
$this->currencyRenderer = $this->objectManager->getObject(
9099
Currency::class,
91100
[
92-
'storeManager' => $this->_storeManagerMock,
93-
'localeCurrency' => $this->_localeMock,
94-
'currencyLocator' => $this->_curLocatorMock,
95-
'request' => $this->_requestMock,
96-
'currencyFactory' => $currencyFactoryMock
101+
'storeManager' => $this->storeManagerMock,
102+
'localeCurrency' => $this->localeCurrencyMock,
103+
'currencyLocator' => $this->currencyLocatorMock,
104+
'request' => $this->requestMock,
105+
'currencyFactory' => $this->currencyFactoryMock
97106
]
98107
);
99-
100-
$this->_blockCurrency->setColumn($this->_columnMock);
101108
}
102109

103-
protected function tearDown(): void
110+
public function testRenderWithDefaultCurrency()
104111
{
105-
unset($this->_localeMock);
106-
unset($this->_curLocatorMock);
107-
unset($this->_columnMock);
108-
unset($this->_row);
109-
unset($this->_storeManagerMock);
110-
unset($this->_requestMock);
111-
unset($this->_blockCurrency);
112+
$defaultCurrencyCode = 'USD';
113+
$amount = 123.45;
114+
$formattedAmount = '$123.45';
115+
$row = new DataObject(['value' => $amount]);
116+
$this->currencyRenderer->setColumn($this->columnMock);
117+
$this->localeCurrencyMock->method('getCurrency')
118+
->with($defaultCurrencyCode)
119+
->willReturn($this->localeCurrencyMock);
120+
$this->localeCurrencyMock->method('toCurrency')
121+
->with(sprintf("%f", $amount))
122+
->willReturn($formattedAmount);
123+
$result = $this->currencyRenderer->render($row);
124+
$this->assertEquals($formattedAmount, $result);
112125
}
113126

114-
/**
115-
* @covers \Magento\Backend\Block\Widget\Grid\Column\Renderer\Currency::render
116-
*/
117-
public function testRenderWithDefaultCurrency()
127+
public function testRenderWithNonDefaultCurrency()
118128
{
119-
$this->_currencyMock->expects($this->once())
120-
->method('getRate')
121-
->with('defaultCurrency')
122-
->willReturn(1.5);
123-
$this->_curLocatorMock->expects($this->any())
124-
->method('getDefaultCurrency')
125-
->with($this->_requestMock)
126-
->willReturn('defaultCurrency');
127-
$currLocaleMock = $this->createMock(CurrencyData::class);
128-
$currLocaleMock->expects($this->once())
129-
->method('toCurrency')
130-
->with(15.0000)
131-
->willReturn('15USD');
132-
$this->_localeMock->expects($this->once())
133-
->method('getCurrency')
134-
->with('defaultCurrency')
135-
->willReturn($currLocaleMock);
136-
$this->_columnMock->method('getCurrency')->willReturn('USD');
137-
$this->_columnMock->method('getRateField')->willReturn('test_rate_field');
138-
139-
$this->assertEquals('15USD', $this->_blockCurrency->render($this->_row));
129+
$nonDefaultCurrencyCode = 'EUR';
130+
$amount = 123.45;
131+
$formattedAmount = '€123.45';
132+
$storeId = 2;
133+
$row = new DataObject([
134+
'value' => $amount,
135+
'store_id' => $storeId
136+
]);
137+
$this->currencyRenderer->setColumn($this->columnMock);
138+
$storeMock = $this->getMockBuilder(Store::class)
139+
->onlyMethods(['getCurrentCurrencyCode'])
140+
->disableOriginalConstructor()
141+
->getMock();
142+
$this->storeManagerMock->method('getStore')
143+
->with($storeId)
144+
->willReturn($storeMock);
145+
$storeMock->method('getCurrentCurrencyCode')
146+
->willReturn($nonDefaultCurrencyCode);
147+
$this->localeCurrencyMock->method('getCurrency')
148+
->with($nonDefaultCurrencyCode)
149+
->willReturn($this->localeCurrencyMock);
150+
$this->localeCurrencyMock->method('toCurrency')
151+
->with(sprintf("%f", $amount))
152+
->willReturn($formattedAmount);
153+
$result = $this->currencyRenderer->render($row);
154+
$this->assertEquals($formattedAmount, $result);
140155
}
141156
}
+5-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
<?xml version="1.0"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2015 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
99
<group id="default">
1010
<job name="backend_clean_cache" instance="Magento\Backend\Cron\CleanCache" method="execute">
1111
<schedule>30 2 * * *</schedule>
1212
</job>
13+
<job name="backend_clean_locks" instance="Magento\Backend\Cron\CleanLocks" method="execute">
14+
<schedule>20 2 * * *</schedule>
15+
</job>
1316
</group>
1417
</config>

app/code/Magento/CacheInvalidate/Test/Mftf/Test/AdminValidateEAVTypesAndAttributesConfigurationTest.xml

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
<description value="Validate EAVTypes And Attributes Cache Type After Cache Management"/>
1616
<severity value="MAJOR"/>
1717
<testCaseId value="AC-3833"/>
18+
<!-- pr exclude group is added as test case failing because of entity not found and will be fixed and removed in ACQE-7691 -->
19+
<group value="pr_exclude"/>
1820
</annotations>
1921
<before>
2022
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>

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

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?php
22
/**
3-
*
43
* Copyright 2024 Adobe
54
* All Rights Reserved.
65
*/
@@ -272,6 +271,16 @@ public function execute()
272271
if (array_key_exists('reset_is-default_option', $data) && $data['reset_is-default_option']) {
273272
unset($data['reset_is-default_option']);
274273
$data['default_value'] = null;
274+
} elseif (isset($data['default'])) {
275+
$defaultOptions = [];
276+
foreach ($data['default'] as $defaultValue) {
277+
if ((int)$defaultValue > 0) {
278+
$defaultOptions[] = $defaultValue;
279+
}
280+
}
281+
if (!empty($defaultOptions)) {
282+
$data['default_value'] = implode(",", $defaultOptions);
283+
}
275284
}
276285

277286
$model->addData($data);

0 commit comments

Comments
 (0)