Skip to content

Commit 02b67fa

Browse files
Indrani SonawaneIndrani Sonawane
authored andcommitted
Merge remote-tracking branch '38427/tier-price-isssue' into community_prs_march
2 parents f439b52 + 4470413 commit 02b67fa

File tree

3 files changed

+244
-0
lines changed

3 files changed

+244
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\ConfigurableProduct\Plugin\Catalog\Model\Product\Attribute\Backend\TierPrice;
10+
11+
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
12+
use Magento\Catalog\Model\Product\Attribute\Backend\TierPrice\UpdateHandler;
13+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
14+
15+
/**
16+
* Plugin for handling tier prices during product attribute backend update.
17+
*/
18+
class UpdateHandlerPlugin
19+
{
20+
/**
21+
* @var ProductAttributeRepositoryInterface
22+
*/
23+
private readonly ProductAttributeRepositoryInterface $attributeRepository;
24+
25+
/**
26+
* UpdateHandlerPlugin constructor.
27+
*
28+
* @param ProductAttributeRepositoryInterface $attributeRepository
29+
*/
30+
public function __construct(ProductAttributeRepositoryInterface $attributeRepository)
31+
{
32+
$this->attributeRepository = $attributeRepository;
33+
}
34+
35+
/**
36+
* Before execute plugin.
37+
*
38+
* @param UpdateHandler $subject
39+
* @param mixed $entity
40+
* @param array $arguments
41+
* @return array
42+
*/
43+
public function beforeExecute(UpdateHandler $subject, $entity, $arguments = []): array
44+
{
45+
$attribute = $this->attributeRepository->get('tier_price');
46+
$origPrices = $entity->getOrigData($attribute->getName());
47+
48+
if ($entity->getTypeId() === Configurable::TYPE_CODE && $origPrices !== null) {
49+
$entity->setData($attribute->getName(), []);
50+
}
51+
52+
return [$entity, $arguments];
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ConfigurableProduct\Test\Unit\Plugin\Catalog\Model\Product\Attribute\Backend\TierPrice;
9+
10+
use Magento\Catalog\Api\Data\ProductAttributeInterface;
11+
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
12+
use Magento\Catalog\Model\Product;
13+
use Magento\Catalog\Model\Product\Attribute\Backend\TierPrice\UpdateHandler;
14+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
15+
use Magento\ConfigurableProduct\Plugin\Catalog\Model\Product\Attribute\Backend\TierPrice\UpdateHandlerPlugin;
16+
use PHPUnit\Framework\MockObject\MockObject;
17+
use PHPUnit\Framework\TestCase;
18+
19+
/**
20+
* Plugin for handling tier prices during product attribute backend update.
21+
*/
22+
class UpdateHandlerPluginTest extends TestCase
23+
{
24+
/**
25+
* @var UpdateHandlerPlugin|MockObject
26+
*/
27+
private $updateHandlerPlugin;
28+
29+
/**
30+
* @var ProductAttributeRepositoryInterface|MockObject
31+
*/
32+
private $attributeRepositoryMock;
33+
34+
/**
35+
* @var UpdateHandler|MockObject
36+
*/
37+
private $updateHandlerMock;
38+
39+
/**
40+
* @var Product|MockObject
41+
*/
42+
private $entityMock;
43+
44+
/**
45+
* @var ProductAttributeInterface|MockObject
46+
*/
47+
private $attributeMock;
48+
49+
protected function setUp(): void
50+
{
51+
$this->attributeRepositoryMock = $this->createMock(ProductAttributeRepositoryInterface::class);
52+
$this->entityMock = $this->createMock(Product::class);
53+
$this->updateHandlerMock = $this->createMock(UpdateHandler::class);
54+
55+
$this->attributeMock = $this->getMockBuilder(ProductAttributeInterface::class)
56+
->addMethods(['getName'])
57+
->disableOriginalConstructor()
58+
->getMockForAbstractClass();
59+
$this->attributeRepositoryMock->expects($this->once())
60+
->method('get')
61+
->with('tier_price')
62+
->willReturn($this->attributeMock);
63+
$this->attributeMock->expects($this->any())
64+
->method('getName')
65+
->willReturn('tier_price');
66+
67+
$this->updateHandlerPlugin = new UpdateHandlerPlugin($this->attributeRepositoryMock);
68+
}
69+
70+
/**
71+
* Test for the 'beforeExecute' method when tier prices exist for configurable products.
72+
*
73+
* @return void
74+
*/
75+
public function testBeforeExecute()
76+
{
77+
$origPrices = [
78+
[
79+
'price_id' => 28,
80+
'website_id' => 0,
81+
'all_groups' => 1,
82+
'cust_group' => 32000,
83+
'price' => 50.000000,
84+
'price_qty' => 2.0000,
85+
'percentage_value' => null,
86+
'product_id' => 29,
87+
'website_price' => 50.000000
88+
]
89+
];
90+
91+
$this->entityMock->expects($this->once())
92+
->method('getOrigData')
93+
->with('tier_price')
94+
->willReturn($origPrices);
95+
96+
$this->entityMock->expects($this->once())
97+
->method('getTypeId')
98+
->willReturn(Configurable::TYPE_CODE);
99+
100+
$this->entityMock->expects($this->once())
101+
->method('setData')
102+
->with($this->equalTo('tier_price'), $this->equalTo([]));
103+
104+
$result = $this->updateHandlerPlugin->beforeExecute($this->updateHandlerMock, $this->entityMock);
105+
106+
$this->assertEquals(
107+
[$this->entityMock, []],
108+
$result
109+
);
110+
}
111+
112+
/**
113+
* Test case to verify the behavior of beforeExecute method for a simple product.
114+
*
115+
* @return void
116+
*/
117+
public function testBeforeExecuteSimpleProduct()
118+
{
119+
$origPrices = [
120+
[
121+
'price_id' => 12,
122+
'website_id' => 0,
123+
'all_groups' => 1,
124+
'cust_group' => 4200,
125+
'price' => 100.000000,
126+
'price_qty' => 5.0000,
127+
'percentage_value' => null,
128+
'product_id' => 30,
129+
'website_price' => 50.000000
130+
]
131+
];
132+
133+
$this->entityMock->expects($this->once())
134+
->method('getOrigData')
135+
->with('tier_price')
136+
->willReturn($origPrices);
137+
138+
$this->entityMock->expects($this->once())
139+
->method('getTypeId')
140+
->willReturn(Product\Type::TYPE_SIMPLE);
141+
142+
$this->entityMock->expects($this->never())
143+
->method('setData')
144+
->with($this->equalTo('tier_price'), $this->equalTo([]));
145+
146+
$result = $this->updateHandlerPlugin->beforeExecute($this->updateHandlerMock, $this->entityMock, []);
147+
148+
$this->assertEquals(
149+
[$this->entityMock, []],
150+
$result
151+
);
152+
}
153+
154+
/**
155+
* Test case to verify the behavior when original prices data is empty.
156+
*
157+
* @return void
158+
*/
159+
public function testOriginalPrices()
160+
{
161+
$origPrices = [];
162+
$this->entityMock->expects($this->once())
163+
->method('getOrigData')
164+
->with('tier_price')
165+
->willReturn($origPrices);
166+
167+
$this->entityMock->expects($this->once())
168+
->method('getTypeId')
169+
->willReturn(Configurable::TYPE_CODE);
170+
171+
$this->entityMock->expects($this->once())
172+
->method('getOrigData')
173+
->with('tier_price')
174+
->willReturn($origPrices);
175+
176+
$this->entityMock->expects($this->once())
177+
->method('setData')
178+
->with($this->equalTo('tier_price'), $this->equalTo([]));
179+
180+
$result = $this->updateHandlerPlugin->beforeExecute($this->updateHandlerMock, $this->entityMock, []);
181+
182+
$this->assertEquals(
183+
[$this->entityMock, []],
184+
$result
185+
);
186+
}
187+
}

app/code/Magento/ConfigurableProduct/etc/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,7 @@
285285
<type name="Magento\CatalogInventory\Model\ResourceModel\Stock\Item">
286286
<plugin name="updateStockChangedAuto" type="Magento\ConfigurableProduct\Model\Plugin\UpdateStockChangedAuto" />
287287
</type>
288+
<type name="Magento\Catalog\Model\Product\Attribute\Backend\TierPrice\UpdateHandler">
289+
<plugin name="tier_price_update_handler_plugin" type="Magento\ConfigurableProduct\Plugin\Catalog\Model\Product\Attribute\Backend\TierPrice\UpdateHandlerPlugin" sortOrder="10" disabled="false"/>
290+
</type>
288291
</config>

0 commit comments

Comments
 (0)