Skip to content

Commit b66d23d

Browse files
committed
Merge branch 'ACP2E-1579' of https://github.com/magento-l3/magento2ce into PR-06022023
2 parents 1722914 + 1fbb7cc commit b66d23d

File tree

7 files changed

+140
-91
lines changed

7 files changed

+140
-91
lines changed

app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Magento\Catalog\Model\Product;
1010
use Magento\Catalog\Model\ProductFactory;
1111
use Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher;
12+
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
1213
use Magento\CatalogRule\Model\Indexer\IndexBuilder\ProductLoader;
1314
use Magento\CatalogRule\Model\Indexer\IndexerTableSwapperInterface as TableSwapper;
1415
use Magento\CatalogRule\Model\ResourceModel\Rule\Collection as RuleCollection;
@@ -167,6 +168,11 @@ class IndexBuilder
167168
*/
168169
private $productLoader;
169170

171+
/**
172+
* @var ProductCollectionFactory
173+
*/
174+
private $productCollectionFactory;
175+
170176
/**
171177
* @param RuleCollectionFactory $ruleCollectionFactory
172178
* @param PriceCurrencyInterface $priceCurrency
@@ -188,6 +194,7 @@ class IndexBuilder
188194
* @param ProductLoader|null $productLoader
189195
* @param TableSwapper|null $tableSwapper
190196
* @param TimezoneInterface|null $localeDate
197+
* @param ProductCollectionFactory|null $productCollectionFactory
191198
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
192199
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
193200
*/
@@ -211,7 +218,8 @@ public function __construct(
211218
ActiveTableSwitcher $activeTableSwitcher = null,
212219
ProductLoader $productLoader = null,
213220
TableSwapper $tableSwapper = null,
214-
TimezoneInterface $localeDate = null
221+
TimezoneInterface $localeDate = null,
222+
ProductCollectionFactory $productCollectionFactory = null
215223
) {
216224
$this->resource = $resource;
217225
$this->connection = $resource->getConnection();
@@ -253,6 +261,8 @@ public function __construct(
253261
ObjectManager::getInstance()->get(TableSwapper::class);
254262
$this->localeDate = $localeDate ??
255263
ObjectManager::getInstance()->get(TimezoneInterface::class);
264+
$this->productCollectionFactory = $productCollectionFactory ??
265+
ObjectManager::getInstance()->get(ProductCollectionFactory::class);
256266
}
257267

258268
/**
@@ -497,13 +507,20 @@ protected function applyRule(Rule $rule, $product)
497507
*/
498508
private function applyRules(RuleCollection $ruleCollection, Product $product): void
499509
{
510+
/** @var \Magento\CatalogRule\Model\Rule $rule */
500511
foreach ($ruleCollection as $rule) {
501-
if (!$rule->validate($product)) {
502-
continue;
503-
}
504-
512+
$productCollection = $this->productCollectionFactory->create();
513+
$productCollection->addIdFilter($product->getId());
514+
$rule->getConditions()->collectValidatedAttributes($productCollection);
515+
$validationResult = [];
505516
$websiteIds = array_intersect($product->getWebsiteIds(), $rule->getWebsiteIds());
506-
$this->assignProductToRule($rule, $product->getId(), $websiteIds);
517+
foreach ($websiteIds as $websiteId) {
518+
$defaultGroupId = $this->storeManager->getWebsite($websiteId)->getDefaultGroupId();
519+
$defaultStoreId = $this->storeManager->getGroup($defaultGroupId)->getDefaultStoreId();
520+
$product->setStoreId($defaultStoreId);
521+
$validationResult[$websiteId] = $rule->validate($product);
522+
}
523+
$this->assignProductToRule($rule, $product->getId(), array_keys(array_filter($validationResult)));
507524
}
508525

509526
$this->cleanProductPriceIndex([$product->getId()]);

app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Rule/Validation.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
namespace Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule;
88

9+
use Magento\Catalog\Api\ProductRepositoryInterface;
910
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
1011
use Magento\CatalogRule\Model\Rule;
1112
use Magento\Framework\DataObject;
@@ -21,12 +22,19 @@ class Validation
2122
*/
2223
private $configurable;
2324

25+
/**
26+
* @var ProductRepositoryInterface
27+
*/
28+
private $productRepository;
29+
2430
/**
2531
* @param Configurable $configurableType
32+
* @param ProductRepositoryInterface $productRepository
2633
*/
27-
public function __construct(Configurable $configurableType)
34+
public function __construct(Configurable $configurableType, ProductRepositoryInterface $productRepository)
2835
{
2936
$this->configurable = $configurableType;
37+
$this->productRepository = $productRepository;
3038
}
3139

3240
/**
@@ -41,7 +49,12 @@ public function afterValidate(Rule $rule, $validateResult, DataObject $product)
4149
{
4250
if (!$validateResult && ($configurableProducts = $this->configurable->getParentIdsByChild($product->getId()))) {
4351
foreach ($configurableProducts as $configurableProductId) {
44-
$validateResult = $rule->getConditions()->validateByEntityId($configurableProductId);
52+
$configurableProduct = $this->productRepository->getById(
53+
$configurableProductId,
54+
false,
55+
$product->getStoreId()
56+
);
57+
$validateResult = $rule->getConditions()->validate($configurableProduct);
4558
// If any of configurable product is valid for current rule, then their sub-product must be valid too
4659
if ($validateResult) {
4760
break;

app/code/Magento/CatalogRuleConfigurable/Test/Unit/Plugin/CatalogRule/Model/Rule/ValidationTest.php

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77

88
namespace Magento\CatalogRuleConfigurable\Test\Unit\Plugin\CatalogRule\Model\Rule;
99

10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\Product;
1012
use Magento\CatalogRule\Model\Rule;
1113
use Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\Validation;
1214
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
13-
use Magento\Framework\DataObject;
1415
use Magento\Rule\Model\Condition\Combine;
1516
use PHPUnit\Framework\MockObject\MockObject;
1617
use PHPUnit\Framework\TestCase;
@@ -30,13 +31,18 @@ class ValidationTest extends TestCase
3031
*/
3132
private $configurableMock;
3233

34+
/**
35+
* @var ProductRepositoryInterface|MockObject
36+
*/
37+
private $productRepositoryMock;
38+
3339
/** @var Rule|MockObject */
3440
private $ruleMock;
3541

3642
/** @var Combine|MockObject */
3743
private $ruleConditionsMock;
3844

39-
/** @var DataObject|MockObject */
45+
/** @var Product|MockObject */
4046
private $productMock;
4147

4248
/**
@@ -48,16 +54,15 @@ protected function setUp(): void
4854
Configurable::class,
4955
['getParentIdsByChild']
5056
);
57+
$this->productRepositoryMock = $this->createMock(ProductRepositoryInterface::class);
5158

5259
$this->ruleMock = $this->createMock(Rule::class);
5360
$this->ruleConditionsMock = $this->createMock(Combine::class);
54-
$this->productMock = $this->getMockBuilder(DataObject::class)
55-
->addMethods(['getId'])
56-
->disableOriginalConstructor()
57-
->getMock();
61+
$this->productMock = $this->createMock(Product::class);
5862

5963
$this->validation = new Validation(
60-
$this->configurableMock
64+
$this->configurableMock,
65+
$this->productRepositoryMock
6166
);
6267
}
6368

@@ -75,13 +80,49 @@ public function testAfterValidateWithValidConfigurableProduct(
7580
$runValidateAmount,
7681
$result
7782
) {
78-
$this->productMock->expects($this->once())->method('getId')->willReturn('product_id');
79-
$this->configurableMock->expects($this->once())->method('getParentIdsByChild')->with('product_id')
83+
$storeId = 1;
84+
$this->productMock->expects($this->once())
85+
->method('getId')
86+
->willReturn(10);
87+
$this->configurableMock->expects($this->once())
88+
->method('getParentIdsByChild')
89+
->with(10)
8090
->willReturn($parentsIds);
81-
$this->ruleMock->expects($this->exactly($runValidateAmount))->method('getConditions')
91+
$this->productMock->expects($this->exactly($runValidateAmount))
92+
->method('getStoreId')
93+
->willReturn($storeId);
94+
$parentsProducts = array_map(
95+
function ($parentsId) {
96+
$parent = $this->createMock(Product::class);
97+
$parent->method('getId')->willReturn($parentsId);
98+
return $parent;
99+
},
100+
$parentsIds
101+
);
102+
$this->productRepositoryMock->expects($this->exactly($runValidateAmount))
103+
->method('getById')
104+
->withConsecutive(
105+
...array_map(
106+
function ($parentsId) use ($storeId) {
107+
return [$parentsId, false, $storeId];
108+
},
109+
$parentsIds
110+
)
111+
)->willReturnOnConsecutiveCalls(...$parentsProducts);
112+
$this->ruleMock->expects($this->exactly($runValidateAmount))
113+
->method('getConditions')
82114
->willReturn($this->ruleConditionsMock);
83-
$this->ruleConditionsMock->expects($this->exactly($runValidateAmount))->method('validateByEntityId')
84-
->willReturnMap($validationResult);
115+
$this->ruleConditionsMock->expects($this->exactly($runValidateAmount))
116+
->method('validate')
117+
->withConsecutive(
118+
...array_map(
119+
function ($parentsProduct) {
120+
return [$parentsProduct];
121+
},
122+
$parentsProducts
123+
)
124+
)
125+
->willReturnOnConsecutiveCalls(...$validationResult);
85126

86127
$this->assertEquals(
87128
$result,
@@ -97,31 +138,19 @@ public function dataProviderForValidateWithValidConfigurableProduct()
97138
return [
98139
[
99140
[1, 2, 3],
100-
[
101-
[1, false],
102-
[2, true],
103-
[3, true],
104-
],
141+
[false, true, true],
105142
2,
106143
true,
107144
],
108145
[
109146
[1, 2, 3],
110-
[
111-
[1, true],
112-
[2, false],
113-
[3, true],
114-
],
147+
[true, false, true],
115148
1,
116149
true,
117150
],
118151
[
119152
[1, 2, 3],
120-
[
121-
[1, false],
122-
[2, false],
123-
[3, false],
124-
],
153+
[false, false, false],
125154
3,
126155
false,
127156
],

dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/IndexerBuilderTest.php

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@
99
use Magento\Catalog\Model\Indexer\Product\Price\Processor;
1010
use Magento\Framework\App\ResourceConnection;
1111
use Magento\Store\Model\StoreManagerInterface;
12+
use Magento\TestFramework\Fixture\AppIsolation;
13+
use Magento\TestFramework\Fixture\DataFixture;
14+
use Magento\TestFramework\Fixture\DbIsolation;
1215
use Magento\TestFramework\Helper\Bootstrap;
1316

17+
#[
18+
DbIsolation(false),
19+
AppIsolation(true),
20+
]
1421
class IndexerBuilderTest extends \PHPUnit\Framework\TestCase
1522
{
1623
/**
@@ -93,8 +100,6 @@ protected function tearDown(): void
93100
}
94101

95102
/**
96-
* @magentoDbIsolation disabled
97-
* @magentoAppIsolation enabled
98103
* @magentoDataFixture Magento/CatalogRule/_files/attribute.php
99104
* @magentoDataFixture Magento/CatalogRule/_files/rule_by_attribute.php
100105
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
@@ -111,8 +116,6 @@ public function testReindexById()
111116
}
112117

113118
/**
114-
* @magentoDbIsolation disabled
115-
* @magentoAppIsolation enabled
116119
* @magentoDataFixture Magento/CatalogRule/_files/simple_product_with_catalog_rule_50_percent_off_tomorrow.php
117120
* @magentoConfigFixture base_website general/locale/timezone Europe/Amsterdam
118121
* @magentoConfigFixture general/locale/timezone America/Chicago
@@ -139,8 +142,6 @@ public function testReindexByIdDifferentTimezones()
139142
}
140143

141144
/**
142-
* @magentoDbIsolation disabled
143-
* @magentoAppIsolation enabled
144145
* @magentoDataFixture Magento/CatalogRule/_files/attribute.php
145146
* @magentoDataFixture Magento/CatalogRule/_files/rule_by_attribute.php
146147
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
@@ -166,8 +167,6 @@ public function testReindexByIds()
166167
}
167168

168169
/**
169-
* @magentoDbIsolation disabled
170-
* @magentoAppIsolation enabled
171170
* @magentoDataFixtureBeforeTransaction Magento/CatalogRule/_files/attribute.php
172171
* @magentoDataFixtureBeforeTransaction Magento/CatalogRule/_files/rule_by_attribute.php
173172
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
@@ -187,9 +186,6 @@ public function testReindexFull()
187186

188187
/**
189188
* Tests restoring triggers on `catalogrule_product_price` table after full reindexing in 'Update by schedule' mode.
190-
*
191-
* @magentoDbIsolation disabled
192-
* @magentoAppIsolation enabled
193189
*/
194190
public function testRestoringTriggersAfterFullReindex()
195191
{
@@ -208,6 +204,42 @@ public function testRestoringTriggersAfterFullReindex()
208204
$this->assertEquals(0, $this->getTriggersCount($tableName));
209205
}
210206

207+
#[
208+
DataFixture('Magento/CatalogRule/_files/simple_product_with_catalog_rule_50_percent_off.php'),
209+
]
210+
public function testReindexByIdForSecondStore(): void
211+
{
212+
$websiteId = $this->storeManager->getWebsite('test')->getId();
213+
$simpleProduct = $this->productRepository->get('simple');
214+
$this->indexerBuilder->reindexById($simpleProduct->getId());
215+
$rulePrice = $this->resourceRule->getRulePrice(new \DateTime(), $websiteId, 1, $simpleProduct->getId());
216+
$this->assertEquals(25, $rulePrice);
217+
}
218+
219+
#[
220+
DataFixture('Magento/CatalogRule/_files/simple_product_with_catalog_rule_50_percent_off.php'),
221+
]
222+
public function testReindexByIdsForSecondStore(): void
223+
{
224+
$websiteId = $this->storeManager->getWebsite('test')->getId();
225+
$simpleProduct = $this->productRepository->get('simple');
226+
$this->indexerBuilder->reindexByIds([$simpleProduct->getId()]);
227+
$rulePrice = $this->resourceRule->getRulePrice(new \DateTime(), $websiteId, 1, $simpleProduct->getId());
228+
$this->assertEquals(25, $rulePrice);
229+
}
230+
231+
#[
232+
DataFixture('Magento/CatalogRule/_files/simple_product_with_catalog_rule_50_percent_off.php'),
233+
]
234+
public function testReindexFullForSecondStore(): void
235+
{
236+
$websiteId = $this->storeManager->getWebsite('test')->getId();
237+
$simpleProduct = $this->productRepository->get('simple');
238+
$this->indexerBuilder->reindexFull();
239+
$rulePrice = $this->resourceRule->getRulePrice(new \DateTime(), $websiteId, 1, $simpleProduct->getId());
240+
$this->assertEquals(25, $rulePrice);
241+
}
242+
211243
/**
212244
* Returns triggers count.
213245
*

0 commit comments

Comments
 (0)