Skip to content

Commit 6d1b8fd

Browse files
Merge branch '2.4-develop' into comps_78764_2205
2 parents 7db8285 + a20a6ff commit 6d1b8fd

File tree

7 files changed

+203
-45
lines changed

7 files changed

+203
-45
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ public function execute(Rule $rule, $batchCount, $useAdditionalTable = false)
129129
continue;
130130
}
131131

132+
if (isset($validationByWebsite['has_antecedent_rule'])) {
133+
$antecedentRuleProductList = array_keys(
134+
$connection->fetchAssoc(
135+
$connection->select()->from($indexTable)
136+
->where('product_id = ?', $productId)
137+
->where('rule_id NOT IN (?)', $rule->getId())
138+
->where('sort_order = ?', $sortOrder)
139+
)
140+
);
141+
$connection->delete($indexTable, ['rule_product_id IN (?)' => $antecedentRuleProductList]);
142+
}
143+
132144
foreach ($customerGroupIds as $customerGroupId) {
133145
if (!array_key_exists($customerGroupId, $excludedWebsites)
134146
|| !in_array((int)$websiteId, array_values($excludedWebsites[$customerGroupId]), true)

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

Lines changed: 60 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,40 @@
33
* Copyright 2015 Adobe
44
* All Rights Reserved.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule;
79

8-
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
910
use Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\ConfigurableProductsProvider;
11+
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable as ConfigurableProductsResourceModel;
1012

1113
/**
1214
* Add configurable sub products to catalog rule indexer on full reindex
1315
*/
1416
class ConfigurableProductHandler
1517
{
1618
/**
17-
* @var \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable
19+
* @var ConfigurableProductsResourceModel
1820
*/
19-
private $configurable;
21+
private ConfigurableProductsResourceModel $configurable;
2022

2123
/**
22-
* @var \Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\ConfigurableProductsProvider
24+
* @var ConfigurableProductsProvider
2325
*/
24-
private $configurableProductsProvider;
26+
private ConfigurableProductsProvider $configurableProductsProvider;
2527

2628
/**
2729
* @var array
2830
*/
29-
private $childrenProducts = [];
31+
private array $childrenProducts = [];
3032

3133
/**
32-
* @param \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $configurable
34+
* @param ConfigurableProductsResourceModel $configurable
3335
* @param ConfigurableProductsProvider $configurableProductsProvider
3436
*/
3537
public function __construct(
36-
\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $configurable,
37-
ConfigurableProductsProvider $configurableProductsProvider
38+
ConfigurableProductsResourceModel $configurable,
39+
ConfigurableProductsProvider $configurableProductsProvider
3840
) {
3941
$this->configurable = $configurable;
4042
$this->configurableProductsProvider = $configurableProductsProvider;
@@ -48,40 +50,71 @@ public function __construct(
4850
* @return array
4951
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
5052
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
53+
* @SuppressWarnings(PHPMD.NPathComplexity)
54+
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
5155
*/
5256
public function aroundGetMatchingProductIds(
5357
\Magento\CatalogRule\Model\Rule $rule,
5458
\Closure $proceed
55-
) {
59+
): array {
5660
$productsFilter = $rule->getProductsFilter() ? (array) $rule->getProductsFilter() : [];
5761
if ($productsFilter) {
58-
$parentProductIds = $this->configurable->getParentIdsByChild($productsFilter);
59-
$rule->setProductsFilter(array_unique(array_merge($productsFilter, $parentProductIds)));
62+
$rule->setProductsFilter(
63+
array_unique(
64+
array_merge(
65+
$productsFilter,
66+
$this->configurable->getParentIdsByChild($productsFilter)
67+
)
68+
)
69+
);
6070
}
6171

6272
$productIds = $proceed();
73+
foreach ($productIds as $productId => $productData) {
74+
if ($this->hasAntecedentRule((int) $productId)) {
75+
$productIds[$productId]['has_antecedent_rule'] = true;
76+
}
77+
}
6378

64-
$configurableProductIds = $this->configurableProductsProvider->getIds(array_keys($productIds));
65-
foreach ($configurableProductIds as $productId) {
66-
if (!isset($this->childrenProducts[$productId])) {
67-
$this->childrenProducts[$productId] = $this->configurable->getChildrenIds($productId)[0];
79+
foreach ($this->configurableProductsProvider->getIds(array_keys($productIds)) as $configurableProductId) {
80+
if (!isset($this->childrenProducts[$configurableProductId])) {
81+
$this->childrenProducts[$configurableProductId] =
82+
$this->configurable->getChildrenIds($configurableProductId)[0];
6883
}
69-
$subProductIds = $this->childrenProducts[$productId];
70-
$parentValidationResult = isset($productIds[$productId])
71-
? array_filter($productIds[$productId])
84+
85+
$parentValidationResult = isset($productIds[$configurableProductId])
86+
? array_filter($productIds[$configurableProductId])
7287
: [];
73-
$processAllChildren = !$productsFilter || in_array($productId, $productsFilter);
74-
foreach ($subProductIds as $subProductId) {
75-
if ($processAllChildren || in_array($subProductId, $productsFilter)) {
76-
$childValidationResult = isset($productIds[$subProductId])
77-
? array_filter($productIds[$subProductId])
88+
$processAllChildren = !$productsFilter || in_array($configurableProductId, $productsFilter);
89+
foreach ($this->childrenProducts[$configurableProductId] as $childrenProductId) {
90+
if ($processAllChildren || in_array($childrenProductId, $productsFilter)) {
91+
$childValidationResult = isset($productIds[$childrenProductId])
92+
? array_filter($productIds[$childrenProductId])
7893
: [];
79-
$productIds[$subProductId] = $parentValidationResult + $childValidationResult;
94+
$productIds[$childrenProductId] = $parentValidationResult + $childValidationResult;
8095
}
81-
8296
}
83-
unset($productIds[$productId]);
97+
unset($productIds[$configurableProductId]);
8498
}
99+
85100
return $productIds;
86101
}
102+
103+
/**
104+
* Check if simple product has previously applied rule.
105+
*
106+
* @param int $productId
107+
* @return bool
108+
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
109+
*/
110+
private function hasAntecedentRule(int $productId): bool
111+
{
112+
foreach ($this->childrenProducts as $parent => $children) {
113+
if (in_array($productId, $children)) {
114+
return true;
115+
}
116+
}
117+
118+
return false;
119+
}
87120
}

app/code/Magento/Sales/Block/Order/Recent.php

Lines changed: 5 additions & 6 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 2011 Adobe
4+
* All Rights Reserved.
55
*/
66
namespace Magento\Sales\Block\Order;
77

@@ -23,7 +23,7 @@ class Recent extends \Magento\Framework\View\Element\Template
2323
/**
2424
* Limit of orders
2525
*/
26-
const ORDER_LIMIT = 5;
26+
public const ORDER_LIMIT = 5;
2727

2828
/**
2929
* @var CollectionFactoryInterface
@@ -90,9 +90,6 @@ private function getRecentOrders()
9090
)->addAttributeToFilter(
9191
'customer_id',
9292
$customerId
93-
)->addAttributeToFilter(
94-
'store_id',
95-
$this->storeManager->getStore()->getId()
9693
)->addAttributeToFilter(
9794
'status',
9895
['in' => $this->_orderConfig->getVisibleOnFrontStatuses()]
@@ -122,6 +119,8 @@ public function getViewUrl($order)
122119
* @param object $order
123120
* @return string
124121
* @deprecated 102.0.3 Action does not exist
122+
* @see This method is not used anymore
123+
*
125124
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
126125
*/
127126
public function getTrackUrl($order)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="StorefrontVerifyOrderDashboardTest">
12+
<annotations>
13+
<features value="Sales"/>
14+
<stories value="Recent Orders appearing on Dashboard"/>
15+
<title value="Verify recent Orders appearing in other store view if the orders are created on another store view"/>
16+
<description value="Verify recent Orders appearing in other store view if the orders are created on another store view"/>
17+
<testCaseId value="AC-14595"/>
18+
<useCaseId value="ACP2E-3807"/>
19+
<severity value="MINOR"/>
20+
<group value="Sales"/>
21+
</annotations>
22+
23+
<before>
24+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
25+
<!-- Create customer -->
26+
<createData entity="Simple_US_Customer" stepKey="createCustomer"/>
27+
<!-- Create store view -->
28+
<actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView">
29+
<argument name="customStore" value="customStore"/>
30+
</actionGroup>
31+
<!-- Create product -->
32+
<createData entity="SimpleProduct2" stepKey="createProduct"/>
33+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexInvalidatedIndices">
34+
<argument name="indices" value=""/>
35+
</actionGroup>
36+
</before>
37+
<after>
38+
<!-- Customer log out -->
39+
<actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="customerLogout"/>
40+
<!-- Delete customer -->
41+
<deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/>
42+
<!-- Delete product -->
43+
<deleteData createDataKey="createProduct" stepKey="deleteProduct"/>
44+
<actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView">
45+
<argument name="customStore" value="customStore"/>
46+
</actionGroup>
47+
<!-- Admin log out -->
48+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
49+
</after>
50+
<!-- Login as customer -->
51+
<actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount">
52+
<argument name="Customer" value="$$createCustomer$$"/>
53+
</actionGroup>
54+
<!-- 2. Switch store view -->
55+
<amOnPage url="{{StorefrontProductPage.url($createProduct.custom_attributes[url_key]$)}}" stepKey="goToStore2ProductPage"/>
56+
<actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="SwitchStoreView">
57+
<argument name="storeView" value="customStore"/>
58+
</actionGroup>
59+
<waitForPageLoad time="10" stepKey="waitForProductPageLoad"/>
60+
<!-- Add product to cart -->
61+
<click selector="{{StorefrontProductPageSection.addToCart}}" stepKey="addToCart"/>
62+
<actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart"/>
63+
<actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRate"/>
64+
<actionGroup ref="StorefrontCheckoutClickNextOnShippingStepActionGroup" stepKey="goToReview"/>
65+
<actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectCheckMoneyOrder"/>
66+
<actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="clickOnPlaceOrder">
67+
<argument name="orderNumberMessage" value="CONST.successCheckoutOrderNumberMessage"/>
68+
<argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage"/>
69+
</actionGroup>
70+
<grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/>
71+
<actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="switchToDefaultStoreView">
72+
<argument name="storeView" value="_defaultStore"/>
73+
</actionGroup>
74+
<amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="navigateToCustomerDashboardPage"/>
75+
<waitForPageLoad stepKey="waitForPageLoad2"/>
76+
<scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/>
77+
<seeElement selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderNumber})}}" stepKey="seeOrderInGrid"/>
78+
</test>
79+
</tests>

app/code/Magento/Sales/Test/Unit/Block/Order/RecentTest.php

Lines changed: 3 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
declare(strict_types=1);
77

@@ -95,7 +95,7 @@ public function testConstructMethod(): void
9595
->getMockForAbstractClass();
9696
$storeMock = $this->getMockBuilder(StoreInterface::class)
9797
->getMockForAbstractClass();
98-
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($storeMock);
98+
$this->storeManagerMock->expects($this->exactly(0))->method('getStore')->willReturn($storeMock);
9999
$storeMock->expects($this->any())->method('getId')->willReturn($storeId);
100100

101101
$orderCollection = $this->createPartialMock(Collection::class, [

dev/tests/integration/testsuite/Magento/CatalogRuleConfigurable/Model/Product/Type/Configurable/PriceTest.php

Lines changed: 9 additions & 9 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 2020 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -105,27 +105,27 @@ public function testGetFinalPriceWithCustomOptionAndCatalogRulesForChildren(): v
105105
$indexPrices = [
106106
'simple_10' => [
107107
'price' => 10,
108-
'final_price' => 4.5,
109-
'min_price' => 4.5,
108+
'final_price' => 9,
109+
'min_price' => 9,
110110
'max_price' => 9,
111111
'tier_price' => null
112112
],
113113
'simple_20' => [
114114
'price' => 20,
115-
'final_price' => 8,
116-
'min_price' => 8,
115+
'final_price' => 15,
116+
'min_price' => 15,
117117
'max_price' => 15,
118118
'tier_price' => 15
119119
],
120120
'configurable' => [
121121
'price' => 0,
122122
'final_price' => 0,
123-
'min_price' => 4.5,
124-
'max_price' => 23,
123+
'min_price' => 9,
124+
'max_price' => 30,
125125
'tier_price' => 15
126126
],
127127
];
128-
$this->assertConfigurableProductPrice(19.5, 23, $indexPrices);
128+
$this->assertConfigurableProductPrice(24, 30, $indexPrices);
129129
}
130130

131131
/**

dev/tests/integration/testsuite/Magento/CustomerImportExport/Model/Import/CustomerTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ public function testUpdateExistingCustomers(): void
497497
*
498498
* @magentoAppIsolation enabled
499499
* @magentoDbIsolation disabled
500+
* @magentoDataFixture deleteAllCustomers
500501
* @return void
501502
*/
502503
public function testCustomerIndexer(): void
@@ -510,6 +511,40 @@ public function testCustomerIndexer(): void
510511
$this->assertEquals(StateInterface::STATUS_INVALID, $statusAfterImport);
511512
}
512513

514+
public static function deleteAllCustomers(): void
515+
{
516+
//Do nothing. we just need the rollback method to be called
517+
}
518+
519+
public static function deleteAllCustomersRollback(): void
520+
{
521+
static::deleteAllCustomersInCsvFile(__DIR__ . '/_files/customers_with_gender_to_import.csv');
522+
}
523+
524+
private static function deleteAllCustomersInCsvFile(string $file): void
525+
{
526+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
527+
/** @var CustomerRepositoryInterface $repository */
528+
$repository = $objectManager->get(CustomerRepositoryInterface::class);
529+
$rows = $objectManager->get(\Magento\Framework\File\Csv::class)->getData($file);
530+
$header = array_shift($rows);
531+
if ($header === false) {
532+
return;
533+
}
534+
$emailIndex = array_search('email', $header);
535+
if ($emailIndex === false) {
536+
return;
537+
}
538+
foreach (array_column($rows, $emailIndex) as $email) {
539+
try {
540+
$customer = $repository->get(strtolower(trim($email)));
541+
$repository->delete($customer);
542+
} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) {
543+
continue;
544+
}
545+
}
546+
}
547+
513548
/**
514549
* Gets customer entity.
515550
*

0 commit comments

Comments
 (0)