Skip to content

Commit 77f9cdb

Browse files
committed
Merge branch 'ACP2E-3955' of https://github.com/adobe-commerce-tier-4/magento2ce into Tier4-08-13-2025
2 parents ab79011 + 97d6f3d commit 77f9cdb

File tree

4 files changed

+163
-10
lines changed

4 files changed

+163
-10
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRule\Plugin\Model\Indexer;
9+
10+
use Magento\Catalog\Model\Indexer\Product\Price;
11+
use Magento\Quote\Model\ResourceModel\Quote as QuoteResourceModel;
12+
13+
/**
14+
* Recollect quote on product ids after rule change.
15+
*/
16+
class RecollectQuoteAfterRuleChange
17+
{
18+
/**
19+
* @param QuoteResourceModel $quoteResourceModel
20+
*/
21+
public function __construct(
22+
private readonly QuoteResourceModel $quoteResourceModel
23+
) {
24+
}
25+
26+
/**
27+
* Recollect quote on product ids after rule change.
28+
*
29+
* @param Price $subject
30+
* @param void $result
31+
* @param array $ids
32+
* @return void
33+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
34+
*/
35+
public function afterExecute(Price $subject, $result, array $ids)
36+
{
37+
$this->quoteResourceModel->markQuotesRecollect($ids);
38+
}
39+
}

app/code/Magento/CatalogRule/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"magento/module-eav": "*",
1414
"magento/module-rule": "*",
1515
"magento/module-store": "*",
16-
"magento/module-ui": "*"
16+
"magento/module-ui": "*",
17+
"magento/module-quote": "*"
1718
},
1819
"suggest": {
1920
"magento/module-import-export": "*",

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,7 @@
164164
<argument name="customConditionProvider" xsi:type="object">CatalogRuleCustomConditionProvider</argument>
165165
</arguments>
166166
</type>
167+
<type name="Magento\Catalog\Model\Indexer\Product\Price">
168+
<plugin name="recollect_quote_after_rule_change" type="Magento\CatalogRule\Plugin\Model\Indexer\RecollectQuoteAfterRuleChange"/>
169+
</type>
167170
</config>

dev/tests/integration/testsuite/Magento/CatalogRule/Model/RuleTest.php

Lines changed: 119 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,68 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2012 Adobe
4+
* All Rights Reserved.
55
*/
66
namespace Magento\CatalogRule\Model;
77

8-
class RuleTest extends \PHPUnit\Framework\TestCase
8+
use Exception;
9+
use Magento\Catalog\Model\Indexer\Product\Price\Processor as ProductPriceIndexerProcessor;
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
12+
use Magento\CatalogRule\Test\Fixture\Rule as CatalogRuleFixture;
13+
use Magento\Checkout\Model\CartFactory;
14+
use Magento\Customer\Test\Fixture\Customer as CustomerFixture;
15+
use Magento\Framework\ObjectManagerInterface;
16+
use Magento\Indexer\Cron\UpdateMview;
17+
use Magento\Indexer\Test\Fixture\UpdateMview as UpdateMviewCron;
18+
use Magento\Indexer\Test\Fixture\ScheduleMode;
19+
use Magento\Quote\Api\CartRepositoryInterface;
20+
use Magento\Quote\Test\Fixture\AddProductToCart as AddProductToCartFixture;
21+
use Magento\Quote\Test\Fixture\CustomerCart as CustomerCartFixture;
22+
use Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor;
23+
use Magento\TestFramework\Fixture\DataFixture;
24+
use Magento\TestFramework\Fixture\DataFixtureStorage;
25+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
26+
use Magento\CatalogRule\Api\CatalogRuleRepositoryInterface;
27+
use Magento\TestFramework\Fixture\DbIsolation;
28+
use Magento\TestFramework\Helper\Bootstrap;
29+
use PHPUnit\Framework\TestCase;
30+
31+
class RuleTest extends TestCase
932
{
33+
/** @var ObjectManagerInterface */
34+
private $objectManager;
35+
1036
/**
11-
* @var \Magento\CatalogRule\Model\Rule
37+
* @var CartRepositoryInterface
38+
*/
39+
private $cartRepository;
40+
41+
/**
42+
* @var CatalogRuleRepositoryInterface
43+
*/
44+
private $catalogRuleRepository;
45+
46+
/**
47+
* @var Rule
1248
*/
1349
protected $_object;
1450

51+
/**
52+
* @var DataFixtureStorage
53+
*/
54+
private $fixtures;
55+
1556
/**
1657
* Sets up the fixture, for example, opens a network connection.
1758
* This method is called before a test is executed.
1859
*/
1960
protected function setUp(): void
2061
{
62+
$this->objectManager = Bootstrap::getObjectManager();
63+
$this->fixtures = $this->objectManager->get(DataFixtureStorageManager::class)->getStorage();
64+
$this->cartRepository = $this->objectManager->get(CartRepositoryInterface::class);
65+
$this->catalogRuleRepository = $this->objectManager->get(CatalogRuleRepositoryInterface::class);
2166
$resourceMock = $this->createPartialMock(
2267
\Magento\CatalogRule\Model\ResourceModel\Rule::class,
2368
['getIdFieldName', 'getRulesFromProduct']
@@ -31,20 +76,19 @@ protected function setUp(): void
3176
$this->_getCatalogRulesFixtures()
3277
);
3378

34-
$this->_object = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
35-
\Magento\CatalogRule\Model\Rule::class,
79+
$this->_object = $this->objectManager ->create(
80+
Rule::class,
3681
['ruleResourceModel' => $resourceMock]
3782
);
3883
}
3984

4085
/**
4186
* @magentoAppIsolation enabled
42-
* @covers \Magento\CatalogRule\Model\Rule::calcProductPriceRule
4387
*/
4488
public function testCalcProductPriceRule()
4589
{
46-
$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
47-
\Magento\Catalog\Model\Product::class
90+
$product = $this->objectManager->create(
91+
Product::class
4892
);
4993
$this->assertEquals($this->_object->calcProductPriceRule($product, 100), 45);
5094
$product->setParentId(true);
@@ -71,4 +115,70 @@ protected function _getCatalogRulesFixtures()
71115
]
72116
];
73117
}
118+
119+
/**
120+
* Test case where changing in catalog rule price updates the quote price.
121+
*
122+
* @throws Exception
123+
*/
124+
#[
125+
DbIsolation(false),
126+
DataFixture(ProductFixture::class, ['type_id' => 'simple', 'price' => 100], as: 'product'),
127+
DataFixture(
128+
CatalogRuleFixture::class,
129+
[
130+
'name' => '50% Discount Rule',
131+
'simple_action' => 'by_percent',
132+
'discount_amount' => 50,
133+
'conditions' => [],
134+
'actions' => [],
135+
'website_ids' => [1],
136+
'customer_group_ids' => [0, 1],
137+
'is_active' => 1
138+
],
139+
as: 'catalog_rule'
140+
),
141+
DataFixture(UpdateMviewCron::class, as: 'updateMviewCron'),
142+
DataFixture(CustomerFixture::class, as: 'customer'),
143+
DataFixture(CustomerCartFixture::class, ['customer_id' => '$customer.id$'], as: 'cart'),
144+
DataFixture(
145+
AddProductToCartFixture::class,
146+
['cart_id' => '$cart.id$', 'product_id' => '$product.id$', 'qty' => 1]
147+
),
148+
DataFixture(ScheduleMode::class, ['indexer' => ProductPriceIndexerProcessor::INDEXER_ID]),
149+
DataFixture(ScheduleMode::class, ['indexer' => RuleProductProcessor::INDEXER_ID])
150+
]
151+
public function testChangeInCatalogPriceRuleUpdatesTheQuote()
152+
{
153+
$catalogRule = $this->fixtures->get('catalog_rule');
154+
$product = $this->fixtures->get('product');
155+
$cart = $this->fixtures->get('cart');
156+
$cartDetails = $this->objectManager->create(CartRepositoryInterface::class)
157+
->get($cart->getId());
158+
$items = $cartDetails->getAllItems();
159+
160+
//verify that the product is added to the cart with the correct price
161+
$this->assertCount(1, $items);
162+
$this->assertEquals($items[0]->getProduct()->getId(), $product->getId());
163+
$this->assertEquals((float) $items[0]->getPrice(), 50.00);
164+
165+
$catalogRuleDetails = $this->objectManager->create(CatalogRuleRepositoryInterface::class)
166+
->get($catalogRule->getId());
167+
$catalogRuleDetails->setDiscountAmount(40);
168+
$catalogRuleDetails->setSimpleAction('by_percent');
169+
$this->catalogRuleRepository->save($catalogRuleDetails);
170+
171+
/** @var $mViewCron UpdateMview */
172+
$mViewCron = $this->objectManager->create(UpdateMview::class);
173+
$mViewCron->execute();
174+
175+
$updatedCartRepo = $this->objectManager->create(CartRepositoryInterface::class);
176+
$updatedCartDetails = $updatedCartRepo->get($cart->getId());
177+
178+
$updatedItems = $updatedCartDetails->getAllItems();
179+
180+
$this->assertCount(1, $updatedItems);
181+
$this->assertEquals($updatedItems[0]->getProduct()->getId(), $product->getId());
182+
$this->assertEquals((float) $updatedItems[0]->getPrice(), 50.00);
183+
}
74184
}

0 commit comments

Comments
 (0)