Skip to content

Commit c5e0e76

Browse files
committed
MC-30160: Indexer price calculation for fixed/dynamic bundle product with different type prices
1 parent 0595b0d commit c5e0e76

16 files changed

+1434
-30
lines changed

dev/tests/integration/testsuite/Magento/Bundle/Model/Product/PriceTest.php

Lines changed: 619 additions & 26 deletions
Large diffs are not rendered by default.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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+
use Magento\Bundle\Model\Product\Price;
9+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
10+
use Magento\Catalog\Model\Product\Type;
11+
use Magento\Catalog\Model\Product\Type\AbstractType;
12+
use Magento\Catalog\Model\Product\Visibility;
13+
use Magento\CatalogRule\Api\CatalogRuleRepositoryInterface;
14+
use Magento\CatalogRule\Api\Data\RuleInterface;
15+
use Magento\CatalogRule\Api\Data\RuleInterfaceFactory;
16+
use Magento\CatalogRule\Model\Indexer\IndexBuilder;
17+
use Magento\CatalogRule\Model\Rule\Condition\Combine;
18+
use Magento\CatalogRule\Model\Rule\Condition\Product;
19+
use Magento\Customer\Model\Group;
20+
use Magento\Store\Api\WebsiteRepositoryInterface;
21+
use Magento\TestFramework\Bundle\Model\PrepareBundleLinks;
22+
23+
require __DIR__ . '/../../../Magento/Catalog/_files/category_with_different_price_products.php';
24+
25+
/** @var WebsiteRepositoryInterface $websiteRepository */
26+
$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class);
27+
$defaultWebsiteId = $websiteRepository->get('base')->getId();
28+
/** @var PrepareBundleLinks $prepareBundleLinks */
29+
$prepareBundleLinks = $objectManager->get(PrepareBundleLinks::class);
30+
/** @var RuleInterfaceFactory $catalogRuleFactory */
31+
$catalogRuleFactory = $objectManager->get(RuleInterfaceFactory::class);
32+
/** @var CatalogRuleRepositoryInterface $catalogRuleRepository */
33+
$catalogRuleRepository = $objectManager->get(CatalogRuleRepositoryInterface::class);
34+
/** @var IndexBuilder $indexBuilder */
35+
$indexBuilder = $objectManager->get(IndexBuilder::class);
36+
37+
$category = $categoryFactory->create();
38+
$category->isObjectNew(true);
39+
$category->setName('Category with bundle product and rule')
40+
->setParentId(2)
41+
->setIsActive(true)
42+
->setPosition(1);
43+
$category = $categoryRepository->save($category);
44+
45+
$bundleProduct = $productFactory->create();
46+
$bundleProduct->setTypeId(Type::TYPE_BUNDLE)
47+
->setAttributeSetId($bundleProduct->getDefaultAttributeSetId())
48+
->setWebsiteIds([$defaultWebsiteId])
49+
->setName('Bundle Product')
50+
->setSku('dynamic_bundle_product_with_catalog_rule')
51+
->setVisibility(Visibility::VISIBILITY_BOTH)
52+
->setStatus(Status::STATUS_ENABLED)
53+
->setStockData(
54+
[
55+
'use_config_manage_stock' => 1,
56+
'qty' => 100,
57+
'is_qty_decimal' => 0,
58+
'is_in_stock' => 1,
59+
]
60+
)
61+
->setSkuType(0)
62+
->setPriceView(0)
63+
->setPriceType(Price::PRICE_TYPE_DYNAMIC)
64+
->setPrice(null)
65+
->setWeightType(0)
66+
->setCategoryIds([$category->getId()])
67+
->setShipmentType(AbstractType::SHIPMENT_TOGETHER);
68+
69+
$bundleOptionsData = [
70+
[
71+
'title' => 'Option 1',
72+
'default_title' => 'Option 1',
73+
'type' => 'select',
74+
'required' => 1,
75+
],
76+
];
77+
$bundleSelectionsData = [
78+
[
79+
[
80+
'sku' => $product->getSku(),
81+
'selection_qty' => 1,
82+
'selection_price_value' => 0,
83+
'selection_can_change_qty' => 1,
84+
],
85+
[
86+
'sku' => $product2->getSku(),
87+
'selection_qty' => 1,
88+
'selection_price_value' => 0,
89+
'selection_can_change_qty' => 1,
90+
],
91+
]
92+
];
93+
$bundleProduct = $prepareBundleLinks->execute($bundleProduct, $bundleOptionsData, $bundleSelectionsData);
94+
$productRepository->save($bundleProduct);
95+
96+
$ruleData = [
97+
RuleInterface::NAME => 'Rule for bundle product',
98+
RuleInterface::IS_ACTIVE => 1,
99+
'website_ids' => [$defaultWebsiteId],
100+
'customer_group_ids' => Group::NOT_LOGGED_IN_ID,
101+
RuleInterface::DISCOUNT_AMOUNT => 50,
102+
RuleInterface::SIMPLE_ACTION => 'by_percent',
103+
'conditions' => [
104+
'1' => [
105+
'type' => Combine::class,
106+
'aggregator' => 'all',
107+
'value' => '1',
108+
],
109+
'1--1' => [
110+
'type' => Product::class,
111+
'attribute' => 'category_ids',
112+
'operator' => '==',
113+
'value' => $category->getId(),
114+
],
115+
],
116+
];
117+
$catalogRule = $catalogRuleFactory->create();
118+
$catalogRule->loadPost($ruleData);
119+
$catalogRuleRepository->save($catalogRule);
120+
$indexBuilder->reindexFull();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
use Magento\CatalogRule\Api\CatalogRuleRepositoryInterface;
9+
use Magento\CatalogRule\Model\Indexer\IndexBuilder;
10+
use Magento\CatalogRule\Model\ResourceModel\Rule\CollectionFactory;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\TestFramework\Catalog\Model\GetCategoryByName;
13+
14+
require __DIR__ . '/../../../Magento/Catalog/_files/category_with_different_price_products_rollback.php';
15+
16+
/** @var GetCategoryByName $getCategoryByName */
17+
$getCategoryByName = $objectManager->create(GetCategoryByName::class);
18+
/** @var CollectionFactory $ruleCollectionFactory */
19+
$ruleCollectionFactory = $objectManager->get(CollectionFactory::class);
20+
/** @var CatalogRuleRepositoryInterface $ruleRepository */
21+
$ruleRepository = $objectManager->get(CatalogRuleRepositoryInterface::class);
22+
/** @var IndexBuilder $indexBuilder */
23+
$indexBuilder = $objectManager->get(IndexBuilder::class);
24+
25+
$registry->unregister('isSecureArea');
26+
$registry->register('isSecureArea', true);
27+
28+
try {
29+
$product = $productRepository->get('dynamic_bundle_product_with_catalog_rule', false, null, true);
30+
$productRepository->delete($product);
31+
} catch (NoSuchEntityException $e) {
32+
//product already deleted.
33+
}
34+
35+
$category = $getCategoryByName->execute('Category with bundle product and rule');
36+
37+
try {
38+
$categoryRepository->delete($category);
39+
} catch (NoSuchEntityException $e) {
40+
//category already deleted.
41+
}
42+
43+
$ruleCollection = $ruleCollectionFactory->create();
44+
$ruleCollection->addFieldToFilter('name', ['eq' => 'Rule for bundle product']);
45+
$ruleCollection->setPageSize(1);
46+
$catalogRule = $ruleCollection->getFirstItem();
47+
48+
try {
49+
$ruleRepository->delete($catalogRule);
50+
} catch (Exception $ex) {
51+
//Nothing to remove
52+
}
53+
54+
$indexBuilder->reindexFull();
55+
56+
$registry->unregister('isSecureArea');
57+
$registry->register('isSecureArea', false);
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
use Magento\Bundle\Model\Product\Price;
9+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
10+
use Magento\Catalog\Model\Product\Type;
11+
use Magento\Catalog\Model\Product\Type\AbstractType;
12+
use Magento\Catalog\Model\Product\Visibility;
13+
use Magento\Store\Api\WebsiteRepositoryInterface;
14+
use Magento\TestFramework\Bundle\Model\PrepareBundleLinks;
15+
16+
require __DIR__ . '/../../../Magento/Catalog/_files/category_with_different_price_products.php';
17+
18+
/** @var WebsiteRepositoryInterface $websiteRepository */
19+
$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class);
20+
$defaultWebsiteId = $websiteRepository->get('base')->getId();
21+
/** @var PrepareBundleLinks $prepareBundleLinks */
22+
$prepareBundleLinks = $objectManager->get(PrepareBundleLinks::class);
23+
24+
$bundleProduct = $productFactory->create();
25+
$bundleProduct->setTypeId(Type::TYPE_BUNDLE)
26+
->setAttributeSetId($bundleProduct->getDefaultAttributeSetId())
27+
->setWebsiteIds([$defaultWebsiteId])
28+
->setName('Bundle Product')
29+
->setSku('dynamic_bundle_product_with_special_price')
30+
->setVisibility(Visibility::VISIBILITY_BOTH)
31+
->setStatus(Status::STATUS_ENABLED)
32+
->setStockData(
33+
[
34+
'use_config_manage_stock' => 1,
35+
'qty' => 100,
36+
'is_qty_decimal' => 0,
37+
'is_in_stock' => 1,
38+
]
39+
)
40+
->setSkuType(0)
41+
->setPriceView(0)
42+
->setPriceType(Price::PRICE_TYPE_DYNAMIC)
43+
->setPrice(null)
44+
->setSpecialPrice(75)
45+
->setWeightType(0)
46+
->setShipmentType(AbstractType::SHIPMENT_TOGETHER);
47+
48+
$bundleOptionsData = [
49+
[
50+
'title' => 'Option 1',
51+
'default_title' => 'Option 1',
52+
'type' => 'select',
53+
'required' => 1,
54+
],
55+
];
56+
$bundleSelectionsData = [
57+
[
58+
[
59+
'sku' => $product->getSku(),
60+
'selection_qty' => 1,
61+
'selection_price_value' => 0,
62+
'selection_can_change_qty' => 1,
63+
],
64+
[
65+
'sku' => $product2->getSku(),
66+
'selection_qty' => 1,
67+
'selection_price_value' => 0,
68+
'selection_can_change_qty' => 1,
69+
],
70+
]
71+
];
72+
$bundleProduct = $prepareBundleLinks->execute($bundleProduct, $bundleOptionsData, $bundleSelectionsData);
73+
$productRepository->save($bundleProduct);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
use Magento\Framework\Exception\NoSuchEntityException;
9+
10+
require __DIR__ . '/../../../Magento/Catalog/_files/category_with_different_price_products_rollback.php';
11+
12+
$registry->unregister('isSecureArea');
13+
$registry->register('isSecureArea', true);
14+
15+
try {
16+
$product = $productRepository->get('dynamic_bundle_product_with_special_price', false, null, true);
17+
$productRepository->delete($product);
18+
} catch (NoSuchEntityException $e) {
19+
//product already deleted.
20+
}
21+
22+
$registry->unregister('isSecureArea');
23+
$registry->register('isSecureArea', false);
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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+
use Magento\Bundle\Model\Product\Price;
9+
use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory;
10+
use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory;
11+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
12+
use Magento\Catalog\Model\Product\Type;
13+
use Magento\Catalog\Model\Product\Type\AbstractType;
14+
use Magento\Catalog\Model\Product\Visibility;
15+
use Magento\Store\Api\WebsiteRepositoryInterface;
16+
use Magento\TestFramework\Bundle\Model\PrepareBundleLinks;
17+
use Magento\Customer\Model\Group;
18+
19+
require __DIR__ . '/../../../Magento/Catalog/_files/category_with_different_price_products.php';
20+
21+
/** @var WebsiteRepositoryInterface $websiteRepository */
22+
$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class);
23+
$defaultWebsiteId = $websiteRepository->get('base')->getId();
24+
/** @var PrepareBundleLinks $prepareBundleLinks */
25+
$prepareBundleLinks = $objectManager->get(PrepareBundleLinks::class);
26+
/** @var ProductTierPriceInterfaceFactory $tierPriceFactory */
27+
$tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class);
28+
/** @var $tierPriceExtensionAttributesFactory */
29+
$tierPriceExtensionAttributesFactory = $objectManager->get(ProductTierPriceExtensionFactory::class);
30+
31+
$bundleProduct = $productFactory->create();
32+
$bundleProduct->setTypeId(Type::TYPE_BUNDLE)
33+
->setAttributeSetId($bundleProduct->getDefaultAttributeSetId())
34+
->setWebsiteIds([$defaultWebsiteId])
35+
->setName('Bundle Product')
36+
->setSku('dynamic_bundle_product_with_tier_price')
37+
->setVisibility(Visibility::VISIBILITY_BOTH)
38+
->setStatus(Status::STATUS_ENABLED)
39+
->setStockData(
40+
[
41+
'use_config_manage_stock' => 1,
42+
'qty' => 100,
43+
'is_qty_decimal' => 0,
44+
'is_in_stock' => 1,
45+
]
46+
)
47+
->setSkuType(0)
48+
->setPriceView(0)
49+
->setPriceType(Price::PRICE_TYPE_DYNAMIC)
50+
->setPrice(null)
51+
->setWeightType(0)
52+
->setShipmentType(AbstractType::SHIPMENT_TOGETHER);
53+
54+
$bundleOptionsData = [
55+
[
56+
'title' => 'Option 1',
57+
'default_title' => 'Option 1',
58+
'type' => 'select',
59+
'required' => 1,
60+
],
61+
];
62+
$bundleSelectionsData = [
63+
[
64+
[
65+
'sku' => $product->getSku(),
66+
'selection_qty' => 1,
67+
'selection_price_value' => 0,
68+
'selection_can_change_qty' => 1,
69+
],
70+
[
71+
'sku' => $product2->getSku(),
72+
'selection_qty' => 1,
73+
'selection_price_value' => 0,
74+
'selection_can_change_qty' => 1,
75+
],
76+
]
77+
];
78+
$bundleProduct = $prepareBundleLinks->execute($bundleProduct, $bundleOptionsData, $bundleSelectionsData);
79+
80+
$tierPriceExtensionAttribute = $tierPriceExtensionAttributesFactory->create(
81+
[
82+
'data' => [
83+
'website_id' => $websiteRepository->get('admin')->getId(),
84+
'percentage_value' => 25,
85+
]
86+
]
87+
);
88+
$tierPrices[] = $tierPriceFactory->create(
89+
[
90+
'data' => [
91+
'customer_group_id' => Group::CUST_GROUP_ALL,
92+
'qty' => 1,
93+
]
94+
]
95+
)->setExtensionAttributes($tierPriceExtensionAttribute);
96+
$bundleProduct->setTierPrices($tierPrices);
97+
$productRepository->save($bundleProduct);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
use Magento\Framework\Exception\NoSuchEntityException;
9+
10+
require __DIR__ . '/../../../Magento/Catalog/_files/category_with_different_price_products_rollback.php';
11+
12+
$registry->unregister('isSecureArea');
13+
$registry->register('isSecureArea', true);
14+
15+
try {
16+
$product = $productRepository->get('dynamic_bundle_product_with_tier_price', false, null, true);
17+
$productRepository->delete($product);
18+
} catch (NoSuchEntityException $e) {
19+
//product already deleted.
20+
}
21+
22+
$registry->unregister('isSecureArea');
23+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)