From 27f2d9d6dbc8b256d590a5557e0537c6b642fd3a Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Wed, 16 Sep 2020 11:18:50 +0300 Subject: [PATCH 01/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Catalog/Model/Product/Option/Value.php | 21 ++++- .../CalculateCustomOptionCatalogRule.php | 94 +++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php diff --git a/app/code/Magento/Catalog/Model/Product/Option/Value.php b/app/code/Magento/Catalog/Model/Product/Option/Value.php index 313513a9151dc..6eeaa44cda706 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Value.php @@ -10,6 +10,8 @@ use Magento\Catalog\Model\Product\Option; use Magento\Framework\Model\AbstractModel; use Magento\Catalog\Pricing\Price\BasePrice; +use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule; +use Magento\Framework\App\ObjectManager; use Magento\Catalog\Pricing\Price\CustomOptionPriceCalculator; use Magento\Catalog\Pricing\Price\RegularPrice; @@ -69,6 +71,11 @@ class Value extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCu */ private $customOptionPriceCalculator; + /** + * @var CalculateCustomOptionCatalogRule + */ + private $calculateCustomOptionCatalogRule; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -77,6 +84,7 @@ class Value extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCu * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data * @param CustomOptionPriceCalculator|null $customOptionPriceCalculator + * @param CalculateCustomOptionCatalogRule|null $CalculateCustomOptionCatalogRule */ public function __construct( \Magento\Framework\Model\Context $context, @@ -85,11 +93,14 @@ public function __construct( \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - CustomOptionPriceCalculator $customOptionPriceCalculator = null + CustomOptionPriceCalculator $customOptionPriceCalculator = null, + CalculateCustomOptionCatalogRule $CalculateCustomOptionCatalogRule = null ) { $this->_valueCollectionFactory = $valueCollectionFactory; $this->customOptionPriceCalculator = $customOptionPriceCalculator - ?? \Magento\Framework\App\ObjectManager::getInstance()->get(CustomOptionPriceCalculator::class); + ?? ObjectManager::getInstance()->get(CustomOptionPriceCalculator::class); + $this->calculateCustomOptionCatalogRule = $CalculateCustomOptionCatalogRule + ?? ObjectManager::getInstance()->get(CalculateCustomOptionCatalogRule::class); parent::__construct( $context, @@ -253,7 +264,11 @@ public function saveValues() public function getPrice($flag = false) { if ($flag) { - return $this->customOptionPriceCalculator->getOptionPriceByPriceCode($this, BasePrice::PRICE_CODE); + return $this->calculateCustomOptionCatalogRule->execute( + $this->getProduct(), + (float)$this->getData(self::KEY_PRICE), + $this->getPriceType() === self::TYPE_PERCENT + ); } return $this->_getData(self::KEY_PRICE); } diff --git a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php new file mode 100644 index 0000000000000..eb3ae760cbfed --- /dev/null +++ b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php @@ -0,0 +1,94 @@ +priceModifier = $priceModifier; + $this->priceCurrency = $priceCurrency; + } + + /** + * Calculate prices of custom options of the product with catalog rules applied. + * + * @param Product $product + * @param float $optionPriceValue + * @param bool $isPercent + * @return float + */ + public function execute( + Product $product, + float $optionPriceValue, + bool $isPercent + ): float { + $regularPrice = (float)$product->getPriceInfo() + ->getPrice(RegularPrice::PRICE_CODE) + ->getValue(); + $catalogRulePrice = $this->priceModifier->modifyPrice( + $regularPrice, + $product + ); + + // Apply catalog price rules to product options only if catalog price rules are applied to product. + if ($catalogRulePrice < $regularPrice) { + $optionPrice = $this->getOptionPriceWithoutPriceRule($optionPriceValue, $isPercent, $regularPrice); + $totalCatalogRulePrice = $this->priceModifier->modifyPrice( + $regularPrice + $optionPrice, + $product + ); + $finalOptionPrice = $totalCatalogRulePrice - $catalogRulePrice; + } else { + $finalOptionPrice = $this->getOptionPriceWithoutPriceRule( + $optionPriceValue, + $isPercent, + $regularPrice + ); + } + + return $this->priceCurrency->convertAndRound($finalOptionPrice); + } + + + /** + * Calculate option price without catalog price rule discount. + * + * @param float $optionPriceValue + * @param bool $isPercent + * @param float $basePrice + * @return float + */ + private function getOptionPriceWithoutPriceRule(float $optionPriceValue, bool $isPercent, float $basePrice): float + { + return $isPercent ? $basePrice * $optionPriceValue / 100 : $optionPriceValue; + } +} From 902fcdd03159d65c51f52576c828468285d58611 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Thu, 17 Sep 2020 10:36:31 +0300 Subject: [PATCH 02/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Unit/Model/Product/Option/ValueTest.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php index e46884d1637da..28cb53bd3cb2f 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php @@ -12,12 +12,12 @@ use Magento\Catalog\Model\Product\Option\Value; use Magento\Catalog\Model\ResourceModel\Product\Option\Value\Collection; use Magento\Catalog\Model\ResourceModel\Product\Option\Value\CollectionFactory; -use Magento\Catalog\Pricing\Price\CustomOptionPriceCalculator; - use Magento\Framework\Pricing\Price\PriceInterface; use Magento\Framework\Pricing\PriceInfoInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit\Framework\TestCase; +use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule; +use PHPUnit\Framework\MockObject\MockObject; /** * Test for \Magento\Catalog\Model\Product\Option\Value class. @@ -30,17 +30,18 @@ class ValueTest extends TestCase private $model; /** - * @var CustomOptionPriceCalculator + * @var CalculateCustomOptionCatalogRule|MockObject */ - private $customOptionPriceCalculatorMock; + private $CalculateCustomOptionCatalogRule; protected function setUp(): void { $mockedResource = $this->getMockedResource(); $mockedCollectionFactory = $this->getMockedValueCollectionFactory(); - $this->customOptionPriceCalculatorMock = $this->createMock( - CustomOptionPriceCalculator::class + + $this->CalculateCustomOptionCatalogRule = $this->createMock( + CalculateCustomOptionCatalogRule::class ); $helper = new ObjectManager($this); @@ -49,7 +50,7 @@ protected function setUp(): void [ 'resource' => $mockedResource, 'valueCollectionFactory' => $mockedCollectionFactory, - 'customOptionPriceCalculator' => $this->customOptionPriceCalculatorMock, + 'CalculateCustomOptionCatalogRule' => $this->CalculateCustomOptionCatalogRule ] ); $this->model->setOption($this->getMockedOption()); @@ -77,8 +78,8 @@ public function testGetPrice() $this->assertEquals($price, $this->model->getPrice(false)); $percentPrice = 100.0; - $this->customOptionPriceCalculatorMock->expects($this->atLeastOnce()) - ->method('getOptionPriceByPriceCode') + $this->CalculateCustomOptionCatalogRule->expects($this->atLeastOnce()) + ->method('execute') ->willReturn($percentPrice); $this->assertEquals($percentPrice, $this->model->getPrice(true)); } From 3db593beb44cdd8823f280e628c42d1c41d25cec Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Thu, 17 Sep 2020 11:55:31 +0300 Subject: [PATCH 03/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Price/CalculateCustomOptionCatalogRule.php | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php index eb3ae760cbfed..5e5e1b08cf721 100644 --- a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php +++ b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php @@ -54,19 +54,12 @@ public function execute( $regularPrice = (float)$product->getPriceInfo() ->getPrice(RegularPrice::PRICE_CODE) ->getValue(); - $catalogRulePrice = $this->priceModifier->modifyPrice( - $regularPrice, - $product - ); - + $catalogRulePrice = $product->getPriceInfo()->getPrice('final_price')->getValue(); // Apply catalog price rules to product options only if catalog price rules are applied to product. if ($catalogRulePrice < $regularPrice) { $optionPrice = $this->getOptionPriceWithoutPriceRule($optionPriceValue, $isPercent, $regularPrice); - $totalCatalogRulePrice = $this->priceModifier->modifyPrice( - $regularPrice + $optionPrice, - $product - ); - $finalOptionPrice = $totalCatalogRulePrice - $catalogRulePrice; + $discount = $catalogRulePrice / $regularPrice; + $finalOptionPrice = $optionPrice*$discount; } else { $finalOptionPrice = $this->getOptionPriceWithoutPriceRule( $optionPriceValue, @@ -78,7 +71,6 @@ public function execute( return $this->priceCurrency->convertAndRound($finalOptionPrice); } - /** * Calculate option price without catalog price rule discount. * From 9a28b746c36caa53d8c16e4603cffab55d789926 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Thu, 17 Sep 2020 16:21:38 +0300 Subject: [PATCH 04/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Product/View/Options/AbstractOptions.php | 26 +++- .../Magento/Catalog/Model/Product/Option.php | 125 ++++++------------ .../Model/Product/Option/Type/DefaultType.php | 19 ++- .../Model/Product/Option/Type/Select.php | 30 +++-- .../Test/Mftf/Data/ProductOptionValueData.xml | 6 + .../Unit/Model/Product/Option/ValueTest.php | 1 - ...RuleForSimpleProductAndFixedMethodTest.xml | 7 +- ...SimpleProductWithSelectFixedMethodTest.xml | 110 +++++++++++++++ 8 files changed, 226 insertions(+), 98 deletions(-) create mode 100644 app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php b/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php index 1dcbf60db15c3..310158ed99948 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php @@ -12,7 +12,10 @@ namespace Magento\Catalog\Block\Product\View\Options; +use Magento\Catalog\Pricing\Price\BasePrice; +use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule; use Magento\Catalog\Pricing\Price\CustomOptionPriceInterface; +use Magento\Framework\App\ObjectManager; /** * Product options section abstract block. @@ -47,20 +50,29 @@ abstract class AbstractOptions extends \Magento\Framework\View\Element\Template */ protected $_catalogHelper; + /** + * @var CalculateCustomOptionCatalogRule + */ + private $calculateCustomOptionCatalogRule; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Framework\Pricing\Helper\Data $pricingHelper * @param \Magento\Catalog\Helper\Data $catalogData * @param array $data + * @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Pricing\Helper\Data $pricingHelper, \Magento\Catalog\Helper\Data $catalogData, - array $data = [] + array $data = [], + CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null ) { $this->pricingHelper = $pricingHelper; $this->_catalogHelper = $catalogData; + $this->calculateCustomOptionCatalogRule = $calculateCustomOptionCatalogRule + ?? ObjectManager::getInstance()->get(CalculateCustomOptionCatalogRule::class); parent::__construct($context, $data); } @@ -112,7 +124,6 @@ public function getOption() * Retrieve formatted price * * @return string - * @since 102.0.6 */ public function getFormattedPrice() { @@ -132,7 +143,7 @@ public function getFormattedPrice() * * @return string * - * @deprecated 102.0.6 + * @deprecated * @see getFormattedPrice() */ public function getFormatedPrice() @@ -162,6 +173,15 @@ protected function _formatPrice($value, $flag = true) $priceStr = $sign; $customOptionPrice = $this->getProduct()->getPriceInfo()->getPrice('custom_option_price'); + + if (!$value['is_percent']) { + $value['pricing_value'] = $this->calculateCustomOptionCatalogRule->execute( + $this->getProduct(), + (float)$value['pricing_value'], + (bool)$value['is_percent'] + ); + } + $context = [CustomOptionPriceInterface::CONFIGURATION_OPTION_FLAG => true]; $optionAmount = $customOptionPrice->getCustomAmount($value['pricing_value'], null, $context); $priceStr .= $this->getLayout()->getBlock('product.price.render.default')->renderAmount( diff --git a/app/code/Magento/Catalog/Model/Product/Option.php b/app/code/Magento/Catalog/Model/Product/Option.php index e83982b8ce672..ca5251de13e69 100644 --- a/app/code/Magento/Catalog/Model/Product/Option.php +++ b/app/code/Magento/Catalog/Model/Product/Option.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Catalog\Model\Product; @@ -16,8 +17,10 @@ use Magento\Catalog\Model\Product\Option\Type\File; use Magento\Catalog\Model\Product\Option\Type\Select; use Magento\Catalog\Model\Product\Option\Type\Text; +use Magento\Catalog\Model\Product\Option\Value; use Magento\Catalog\Model\ResourceModel\Product\Option\Value\Collection; -use Magento\Catalog\Pricing\Price\BasePrice; +use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule; +use Magento\Framework\App\ObjectManager; use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Model\AbstractExtensibleModel; @@ -123,6 +126,11 @@ class Option extends AbstractExtensibleModel implements ProductCustomOptionInter */ private $customOptionValuesFactory; + /** + * @var CalculateCustomOptionCatalogRule + */ + private $calculateCustomOptionCatalogRule; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -138,6 +146,7 @@ class Option extends AbstractExtensibleModel implements ProductCustomOptionInter * @param ProductCustomOptionValuesInterfaceFactory|null $customOptionValuesFactory * @param array $optionGroups * @param array $optionTypesToGroups + * @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -154,14 +163,17 @@ public function __construct( array $data = [], ProductCustomOptionValuesInterfaceFactory $customOptionValuesFactory = null, array $optionGroups = [], - array $optionTypesToGroups = [] + array $optionTypesToGroups = [], + CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null ) { $this->productOptionValue = $productOptionValue; $this->optionTypeFactory = $optionFactory; $this->string = $string; $this->validatorPool = $validatorPool; $this->customOptionValuesFactory = $customOptionValuesFactory ?: - \Magento\Framework\App\ObjectManager::getInstance()->get(ProductCustomOptionValuesInterfaceFactory::class); + ObjectManager::getInstance()->get(ProductCustomOptionValuesInterfaceFactory::class); + $this->calculateCustomOptionCatalogRule = $calculateCustomOptionCatalogRule ?? + ObjectManager::getInstance()->get(CalculateCustomOptionCatalogRule::class); $this->optionGroups = $optionGroups ?: [ self::OPTION_GROUP_DATE => Date::class, self::OPTION_GROUP_FILE => File::class, @@ -193,10 +205,7 @@ public function __construct( } /** - * Get resource instance - * - * @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb - * @deprecated 102.0.0 because resource models should be used directly + * @inheritdoc */ protected function _getResource() { @@ -246,7 +255,7 @@ public function getValueById($valueId) * * @param string $type * @return bool - * @since 102.0.0 + * @since 101.1.0 */ public function hasValues($type = null) { @@ -462,10 +471,12 @@ public function afterSave() */ public function getPrice($flag = false) { - if ($flag && $this->getPriceType() == self::$typePercent) { - $basePrice = $this->getProduct()->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getValue(); - $price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100); - return $price; + if ($flag) { + return $this->calculateCustomOptionCatalogRule->execute( + $this->getProduct(), + (float)$this->getData(self::KEY_PRICE), + $this->getPriceType() === Value::TYPE_PERCENT + ); } return $this->_getData(self::KEY_PRICE); } @@ -559,9 +570,7 @@ public function getSearchableData($productId, $storeId) } /** - * Clearing object's data - * - * @return $this + * @inheritdoc */ protected function _clearData() { @@ -571,9 +580,7 @@ protected function _clearData() } /** - * Clearing cyclic references - * - * @return $this + * @inheritdoc */ protected function _clearReferences() { @@ -594,9 +601,7 @@ protected function _getValidationRulesBeforeSave() } /** - * Get product SKU - * - * @return string + * @inheritdoc */ public function getProductSku() { @@ -608,9 +613,7 @@ public function getProductSku() } /** - * Get option id - * - * @return int|null + * @inheritdoc * @codeCoverageIgnoreStart */ public function getOptionId() @@ -619,9 +622,7 @@ public function getOptionId() } /** - * Get option title - * - * @return string + * @inheritdoc */ public function getTitle() { @@ -629,9 +630,7 @@ public function getTitle() } /** - * Get option type - * - * @return string + * @inheritdoc */ public function getType() { @@ -639,9 +638,7 @@ public function getType() } /** - * Get sort order - * - * @return int + * @inheritdoc */ public function getSortOrder() { @@ -649,10 +646,7 @@ public function getSortOrder() } /** - * Get is require - * - * @return bool - * @SuppressWarnings(PHPMD.BooleanGetMethodName) + * @inheritdoc */ public function getIsRequire() { @@ -660,9 +654,7 @@ public function getIsRequire() } /** - * Get price type - * - * @return string|null + * @inheritdoc */ public function getPriceType() { @@ -670,9 +662,7 @@ public function getPriceType() } /** - * Get Sku - * - * @return string|null + * @inheritdoc */ public function getSku() { @@ -720,10 +710,7 @@ public function getImageSizeY() } /** - * Set product SKU - * - * @param string $productSku - * @return $this + * @inheritdoc */ public function setProductSku($productSku) { @@ -731,10 +718,7 @@ public function setProductSku($productSku) } /** - * Set option id - * - * @param int $optionId - * @return $this + * @inheritdoc */ public function setOptionId($optionId) { @@ -742,10 +726,7 @@ public function setOptionId($optionId) } /** - * Set option title - * - * @param string $title - * @return $this + * @inheritdoc */ public function setTitle($title) { @@ -753,10 +734,7 @@ public function setTitle($title) } /** - * Set option type - * - * @param string $type - * @return $this + * @inheritdoc */ public function setType($type) { @@ -764,10 +742,7 @@ public function setType($type) } /** - * Set sort order - * - * @param int $sortOrder - * @return $this + * @inheritdoc */ public function setSortOrder($sortOrder) { @@ -775,10 +750,7 @@ public function setSortOrder($sortOrder) } /** - * Set is require - * - * @param bool $isRequired - * @return $this + * @inheritdoc */ public function setIsRequire($isRequired) { @@ -786,10 +758,7 @@ public function setIsRequire($isRequired) } /** - * Set price - * - * @param float $price - * @return $this + * @inheritdoc */ public function setPrice($price) { @@ -797,10 +766,7 @@ public function setPrice($price) } /** - * Set price type - * - * @param string $priceType - * @return $this + * @inheritdoc */ public function setPriceType($priceType) { @@ -808,10 +774,7 @@ public function setPriceType($priceType) } /** - * Set Sku - * - * @param string $sku - * @return $this + * @inheritdoc */ public function setSku($sku) { @@ -952,7 +915,7 @@ public function setExtensionAttributes( private function getOptionRepository() { if (null === $this->optionRepository) { - $this->optionRepository = \Magento\Framework\App\ObjectManager::getInstance() + $this->optionRepository = ObjectManager::getInstance() ->get(\Magento\Catalog\Model\Product\Option\Repository::class); } return $this->optionRepository; @@ -966,7 +929,7 @@ private function getOptionRepository() private function getMetadataPool() { if (null === $this->metadataPool) { - $this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance() + $this->metadataPool = ObjectManager::getInstance() ->get(\Magento\Framework\EntityManager\MetadataPool::class); } return $this->metadataPool; diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php b/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php index 16fdd4cdeeb1c..a6ab77a090b4e 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php @@ -13,6 +13,8 @@ use Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface; use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface; use Magento\Catalog\Model\Product\Option\Value; +use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule; +use Magento\Framework\App\ObjectManager; /** * Catalog product option default type @@ -60,21 +62,30 @@ class DefaultType extends \Magento\Framework\DataObject */ protected $_checkoutSession; + /** + * @var CalculateCustomOptionCatalogRule + */ + private $calculateCustomOptionCatalogRule; + /** * Construct * * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param array $data + * @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule */ public function __construct( \Magento\Checkout\Model\Session $checkoutSession, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, - array $data = [] + array $data = [], + CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null ) { $this->_checkoutSession = $checkoutSession; parent::__construct($data); $this->_scopeConfig = $scopeConfig; + $this->calculateCustomOptionCatalogRule = $calculateCustomOptionCatalogRule ?? ObjectManager::getInstance() + ->get(CalculateCustomOptionCatalogRule::class); } /** @@ -341,7 +352,11 @@ public function getOptionPrice($optionValue, $basePrice) { $option = $this->getOption(); - return $this->_getChargeableOptionPrice($option->getPrice(), $option->getPriceType() == 'percent', $basePrice); + return $this->calculateCustomOptionCatalogRule->execute( + $option->getProduct(), + (float)$option->getPrice(), + $option->getPriceType() === Value::TYPE_PERCENT + ); } /** diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php b/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php index d2766b1bbb054..17f0fb3b25f99 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php @@ -6,6 +6,9 @@ namespace Magento\Catalog\Model\Product\Option\Type; +use Magento\Catalog\Model\Product\Option\Value; +use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; /** @@ -37,6 +40,11 @@ class Select extends \Magento\Catalog\Model\Product\Option\Type\DefaultType */ private $singleSelectionTypes; + /** + * @var CalculateCustomOptionCatalogRule + */ + private $calculateCustomOptionCatalogRule; + /** * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig @@ -44,6 +52,7 @@ class Select extends \Magento\Catalog\Model\Product\Option\Type\DefaultType * @param \Magento\Framework\Escaper $escaper * @param array $data * @param array $singleSelectionTypes + * @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule */ public function __construct( \Magento\Checkout\Model\Session $checkoutSession, @@ -51,7 +60,8 @@ public function __construct( \Magento\Framework\Stdlib\StringUtils $string, \Magento\Framework\Escaper $escaper, array $data = [], - array $singleSelectionTypes = [] + array $singleSelectionTypes = [], + CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null ) { $this->string = $string; $this->_escaper = $escaper; @@ -61,6 +71,8 @@ public function __construct( 'drop_down' => \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN, 'radio' => \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_RADIO, ]; + $this->calculateCustomOptionCatalogRule = $calculateCustomOptionCatalogRule ?? ObjectManager::getInstance() + ->get(CalculateCustomOptionCatalogRule::class); } /** @@ -248,10 +260,10 @@ public function getOptionPrice($optionValue, $basePrice) foreach (explode(',', $optionValue) as $value) { $_result = $option->getValueById($value); if ($_result) { - $result += $this->_getChargeableOptionPrice( - $_result->getPrice(), - $_result->getPriceType() == 'percent', - $basePrice + $result += $this->calculateCustomOptionCatalogRule->execute( + $option->getProduct(), + (float)$_result->getPrice(), + $_result->getPriceType() === Value::TYPE_PERCENT ); } else { if ($this->getListener()) { @@ -263,10 +275,10 @@ public function getOptionPrice($optionValue, $basePrice) } elseif ($this->_isSingleSelection()) { $_result = $option->getValueById($optionValue); if ($_result) { - $result = $this->_getChargeableOptionPrice( - $_result->getPrice(), - $_result->getPriceType() == 'percent', - $basePrice + $result = $this->calculateCustomOptionCatalogRule->execute( + $option->getProduct(), + (float)$_result->getPrice(), + $_result->getPriceType() === Value::TYPE_PERCENT ); } else { if ($this->getListener()) { diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductOptionValueData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductOptionValueData.xml index e738994357366..04c24ff7e36dd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductOptionValueData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductOptionValueData.xml @@ -26,6 +26,12 @@ 99.99 fixed + + OptionValueRadioButtons1 + 1 + 78.33 + fixed + OptionValueRadioButtons2 2 diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php index 28cb53bd3cb2f..d604e41018c07 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php @@ -39,7 +39,6 @@ protected function setUp(): void $mockedResource = $this->getMockedResource(); $mockedCollectionFactory = $this->getMockedValueCollectionFactory(); - $this->CalculateCustomOptionCatalogRule = $this->createMock( CalculateCustomOptionCatalogRule::class ); diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductAndFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductAndFixedMethodTest.xml index 8103e6b115950..43f8decb874cb 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductAndFixedMethodTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductAndFixedMethodTest.xml @@ -7,16 +7,19 @@ --> - + - + <title value="DEPRECATED. Admin should be able to apply the catalog price rule for simple product with custom options"/> <description value="Admin should be able to apply the catalog price rule for simple product with custom options"/> <severity value="CRITICAL"/> <testCaseId value="MC-14771"/> <group value="CatalogRule"/> <group value="mtf_migrated"/> + <skip> + <issueId value="DEPRECATED">Use ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest instead</issueId> + </skip> </annotations> <before> <!-- Login as Admin --> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml new file mode 100644 index 0000000000000..8b96feee6dbc6 --- /dev/null +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest"> + <annotations> + <features value="CatalogRule"/> + <stories value="Apply catalog price rule"/> + <title value="Admin should be able to apply the catalog price rule for simple product with custom options"/> + <description value="Admin should be able to apply the catalog price rule for simple product with custom options"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-14771"/> + <group value="CatalogRule"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <!-- Login as Admin --> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + + <!-- Create category --> + <createData entity="_defaultCategory" stepKey="createCategory"/> + + <!-- Create Simple Product --> + <createData entity="_defaultProduct" stepKey="createProduct1"> + <requiredEntity createDataKey="createCategory"/> + <field key="price">56.78</field> + </createData> + + <!-- Update all products to have custom options --> + <updateData createDataKey="createProduct1" entity="productWithFixedOptions" stepKey="updateProductWithOptions1"/> + <magentoCron stepKey="runCronIndex" groups="index"/> + </before> + <after> + <!-- Delete products and category --> + <deleteData createDataKey="createProduct1" stepKey="deleteProduct1"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + + <!-- Delete the catalog price rule --> + <actionGroup ref="AdminOpenCatalogPriceRulePageActionGroup" stepKey="goToPriceRulePage"/> + <actionGroup stepKey="deletePriceRule" ref="deleteEntitySecondaryGrid"> + <argument name="name" value="{{CatalogRuleByFixed.name}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> + </actionGroup> + + <!-- Logout --> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + </after> + <!-- 1. Begin creating a new catalog price rule --> + <actionGroup ref="NewCatalogPriceRuleByUIWithConditionIsCategoryActionGroup" stepKey="newCatalogPriceRuleByUIWithConditionIsCategory"> + <argument name ="categoryId" value="$createCategory.id$"/> + <argument name ="catalogRule" value="CatalogRuleByFixed"/> + </actionGroup> + + <!-- Select not logged in customer group --> + <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroup"/> + + <!-- Save and apply the new catalog price rule --> + <actionGroup ref="SaveAndApplyCatalogPriceRuleActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> + <actionGroup ref="CreateCatalogRuleStagingUpdateWithItsStartActionGroup" stepKey="fillOutActionGroup"> + <argument name="stagingUpdate" value="_defaultCatalogRule"/> + </actionGroup> + + <!-- Navigate to category on store front --> + <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToCategoryPage"/> + + <!-- Check product 1 name on store front category page --> + <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1Name"> + <argument name="productInfo" value="$createProduct1.name$"/> + <argument name="productNumber" value="1"/> + </actionGroup> + + <!-- Check product 1 price on store front category page --> + <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1Price"> + <argument name="productInfo" value="$44.48"/> + <argument name="productNumber" value="1"/> + </actionGroup> + + <!-- Check product 1 regular price on store front category page --> + <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1RegularPrice"> + <argument name="productInfo" value="$56.78"/> + <argument name="productNumber" value="1"/> + </actionGroup> + + <!-- Navigate to product 1 on store front --> + <amOnPage url="{{StorefrontProductPage.url($createProduct1.name$)}}" stepKey="goToProductPage1"/> + + <!-- Assert regular and special price after selecting ProductOptionValueDropdown1 --> + <actionGroup ref="StorefrontSelectCustomOptionRadioAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices1"> + <argument name="customOption" value="ProductOptionRadioButton2"/> + <argument name="customOptionValue" value="ProductOptionValueRadioButtonsWithDiscountedPrice"/> + <argument name="productPrice" value="$156.77"/> + <argument name="productFinalPrice" value="$122.81"/> + </actionGroup> + + <!-- Add product 1 to cart --> + <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="cartAddSimpleProduct1ToCart"> + <argument name="productQty" value="1"/> + </actionGroup> + + <!-- Assert sub total on mini shopping cart --> + <actionGroup ref="AssertSubTotalOnStorefrontMiniCartActionGroup" stepKey="assertSubTotalOnStorefrontMiniCart"> + <argument name="subTotal" value="$122.81"/> + </actionGroup> + </test> +</tests> From d0e1712311067e1941d75e231bdfa40b30cdfbd9 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Fri, 18 Sep 2020 14:38:32 +0300 Subject: [PATCH 05/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Magento/Catalog/Model/Product/Option.php | 98 ++++++++++++++----- .../CalculateCustomOptionCatalogRule.php | 40 +++++++- ...SimpleProductWithSelectFixedMethodTest.xml | 13 +-- 3 files changed, 115 insertions(+), 36 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Option.php b/app/code/Magento/Catalog/Model/Product/Option.php index ca5251de13e69..15c40af09d7b9 100644 --- a/app/code/Magento/Catalog/Model/Product/Option.php +++ b/app/code/Magento/Catalog/Model/Product/Option.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); namespace Magento\Catalog\Model\Product; @@ -205,7 +204,10 @@ public function __construct( } /** - * @inheritdoc + * Get resource instance + * + * @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb + * @deprecated 102.0.0 because resource models should be used directly */ protected function _getResource() { @@ -255,7 +257,7 @@ public function getValueById($valueId) * * @param string $type * @return bool - * @since 101.1.0 + * @since 102.0.0 */ public function hasValues($type = null) { @@ -570,7 +572,9 @@ public function getSearchableData($productId, $storeId) } /** - * @inheritdoc + * Clearing object's data + * + * @return $this */ protected function _clearData() { @@ -580,7 +584,9 @@ protected function _clearData() } /** - * @inheritdoc + * Clearing cyclic references + * + * @return $this */ protected function _clearReferences() { @@ -601,7 +607,9 @@ protected function _getValidationRulesBeforeSave() } /** - * @inheritdoc + * Get product SKU + * + * @return string */ public function getProductSku() { @@ -613,7 +621,9 @@ public function getProductSku() } /** - * @inheritdoc + * Get option id + * + * @return int|null * @codeCoverageIgnoreStart */ public function getOptionId() @@ -622,7 +632,9 @@ public function getOptionId() } /** - * @inheritdoc + * Get option title + * + * @return string */ public function getTitle() { @@ -630,7 +642,9 @@ public function getTitle() } /** - * @inheritdoc + * Get option type + * + * @return string */ public function getType() { @@ -638,7 +652,9 @@ public function getType() } /** - * @inheritdoc + * Get sort order + * + * @return int */ public function getSortOrder() { @@ -646,7 +662,10 @@ public function getSortOrder() } /** - * @inheritdoc + * Get is require + * + * @return bool + * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ public function getIsRequire() { @@ -654,7 +673,9 @@ public function getIsRequire() } /** - * @inheritdoc + * Get price type + * + * @return string|null */ public function getPriceType() { @@ -662,7 +683,9 @@ public function getPriceType() } /** - * @inheritdoc + * Get Sku + * + * @return string|null */ public function getSku() { @@ -710,7 +733,10 @@ public function getImageSizeY() } /** - * @inheritdoc + * Set product SKU + * + * @param string $productSku + * @return $this */ public function setProductSku($productSku) { @@ -718,7 +744,10 @@ public function setProductSku($productSku) } /** - * @inheritdoc + * Set option id + * + * @param int $optionId + * @return $this */ public function setOptionId($optionId) { @@ -726,7 +755,10 @@ public function setOptionId($optionId) } /** - * @inheritdoc + * Set option title + * + * @param string $title + * @return $this */ public function setTitle($title) { @@ -734,7 +766,10 @@ public function setTitle($title) } /** - * @inheritdoc + * Set option type + * + * @param string $type + * @return $this */ public function setType($type) { @@ -742,7 +777,10 @@ public function setType($type) } /** - * @inheritdoc + * Set sort order + * + * @param int $sortOrder + * @return $this */ public function setSortOrder($sortOrder) { @@ -750,7 +788,10 @@ public function setSortOrder($sortOrder) } /** - * @inheritdoc + * Set is require + * + * @param bool $isRequired + * @return $this */ public function setIsRequire($isRequired) { @@ -758,7 +799,10 @@ public function setIsRequire($isRequired) } /** - * @inheritdoc + * Set price + * + * @param float $price + * @return $this */ public function setPrice($price) { @@ -766,7 +810,10 @@ public function setPrice($price) } /** - * @inheritdoc + * Set price type + * + * @param string $priceType + * @return $this */ public function setPriceType($priceType) { @@ -774,7 +821,10 @@ public function setPriceType($priceType) } /** - * @inheritdoc + * Set Sku + * + * @param string $sku + * @return $this */ public function setSku($sku) { @@ -915,7 +965,7 @@ public function setExtensionAttributes( private function getOptionRepository() { if (null === $this->optionRepository) { - $this->optionRepository = ObjectManager::getInstance() + $this->optionRepository = \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Catalog\Model\Product\Option\Repository::class); } return $this->optionRepository; @@ -929,7 +979,7 @@ private function getOptionRepository() private function getMetadataPool() { if (null === $this->metadataPool) { - $this->metadataPool = ObjectManager::getInstance() + $this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Framework\EntityManager\MetadataPool::class); } return $this->metadataPool; diff --git a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php index 5e5e1b08cf721..cf7c12b4560e0 100644 --- a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php +++ b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php @@ -9,6 +9,8 @@ use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\PriceModifierInterface; +use Magento\CatalogRule\Pricing\Price\CatalogRulePrice; +use Magento\Framework\Pricing\Price\BasePriceProviderInterface; use Magento\Framework\Pricing\PriceCurrencyInterface; /** @@ -54,23 +56,53 @@ public function execute( $regularPrice = (float)$product->getPriceInfo() ->getPrice(RegularPrice::PRICE_CODE) ->getValue(); - $catalogRulePrice = $product->getPriceInfo()->getPrice('final_price')->getValue(); + $catalogRulePrice = $this->priceModifier->modifyPrice( + $regularPrice, + $product + ); // Apply catalog price rules to product options only if catalog price rules are applied to product. if ($catalogRulePrice < $regularPrice) { $optionPrice = $this->getOptionPriceWithoutPriceRule($optionPriceValue, $isPercent, $regularPrice); - $discount = $catalogRulePrice / $regularPrice; - $finalOptionPrice = $optionPrice*$discount; + $totalCatalogRulePrice = $this->priceModifier->modifyPrice( + $regularPrice + $optionPrice, + $product + ); + $finalOptionPrice = $totalCatalogRulePrice - $catalogRulePrice; } else { $finalOptionPrice = $this->getOptionPriceWithoutPriceRule( $optionPriceValue, $isPercent, - $regularPrice + $this->getGetBasePriceWithOutCatalogRules($product) ); } return $this->priceCurrency->convertAndRound($finalOptionPrice); } + /** + * Get product base price without catalog rules applied. + * + * @param Product $product + * @return float + */ + private function getGetBasePriceWithOutCatalogRules(Product $product): float + { + $basePrice = null; + foreach ($product->getPriceInfo()->getPrices() as $price) { + if ($price instanceof BasePriceProviderInterface + && $price->getPriceCode() !== CatalogRulePrice::PRICE_CODE + && $price->getValue() !== false + ) { + $basePrice = min( + $price->getValue(), + $basePrice ?? $price->getValue() + ); + } + } + + return $basePrice ?? $product->getPrice(); + } + /** * Calculate option price without catalog price rule discount. * diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml index 8b96feee6dbc6..ff144c1686e5d 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml @@ -15,7 +15,7 @@ <description value="Admin should be able to apply the catalog price rule for simple product with custom options"/> <severity value="CRITICAL"/> <testCaseId value="MC-14771"/> - <group value="CatalogRule"/> + <group value="catalogRule"/> <group value="mtf_migrated"/> </annotations> <before> @@ -33,7 +33,7 @@ <!-- Update all products to have custom options --> <updateData createDataKey="createProduct1" entity="productWithFixedOptions" stepKey="updateProductWithOptions1"/> - <magentoCron stepKey="runCronIndex" groups="index"/> + <magentoCron groups="index" stepKey="runCronIndex"/> </before> <after> <!-- Delete products and category --> @@ -42,7 +42,7 @@ <!-- Delete the catalog price rule --> <actionGroup ref="AdminOpenCatalogPriceRulePageActionGroup" stepKey="goToPriceRulePage"/> - <actionGroup stepKey="deletePriceRule" ref="deleteEntitySecondaryGrid"> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRule"> <argument name="name" value="{{CatalogRuleByFixed.name}}"/> <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> </actionGroup> @@ -60,13 +60,10 @@ <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroup"/> <!-- Save and apply the new catalog price rule --> - <actionGroup ref="SaveAndApplyCatalogPriceRuleActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> - <actionGroup ref="CreateCatalogRuleStagingUpdateWithItsStartActionGroup" stepKey="fillOutActionGroup"> - <argument name="stagingUpdate" value="_defaultCatalogRule"/> - </actionGroup> + <actionGroup ref="AdminEnableCatalogPriceRuleActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> <!-- Navigate to category on store front --> - <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToCategoryPage"/> + <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToStorefrontCategoryPage"/> <!-- Check product 1 name on store front category page --> <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1Name"> From b7f2ba1fa13cb3976290a170906e2e6394d72f9f Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Mon, 21 Sep 2020 17:00:20 +0300 Subject: [PATCH 06/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- app/code/Magento/CatalogRule/Model/Rule.php | 8 ++++++++ ...leForSimpleProductWithSelectFixedMethodTest.xml | 14 +++++++++----- .../Bundle/Model/Product/BundlePriceAbstract.php | 8 ++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogRule/Model/Rule.php b/app/code/Magento/CatalogRule/Model/Rule.php index f2e8e54d34665..bcd01dae96e81 100644 --- a/app/code/Magento/CatalogRule/Model/Rule.php +++ b/app/code/Magento/CatalogRule/Model/Rule.php @@ -895,4 +895,12 @@ public function getIdentities() { return ['price']; } + + /** + * Clear price rules cache. + */ + public function clearPriceRulesData(): void + { + self::$_priceRulesData = []; + } } diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml index ff144c1686e5d..c863ebb55f41a 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml @@ -19,9 +19,6 @@ <group value="mtf_migrated"/> </annotations> <before> - <!-- Login as Admin --> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <!-- Create category --> <createData entity="_defaultCategory" stepKey="createCategory"/> @@ -33,7 +30,12 @@ <!-- Update all products to have custom options --> <updateData createDataKey="createProduct1" entity="productWithFixedOptions" stepKey="updateProductWithOptions1"/> - <magentoCron groups="index" stepKey="runCronIndex"/> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> + <argument name="indices" value=""/> + </actionGroup> + + <!-- Login as Admin --> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <!-- Delete products and category --> @@ -60,7 +62,9 @@ <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroup"/> <!-- Save and apply the new catalog price rule --> - <actionGroup ref="AdminEnableCatalogPriceRuleActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> + <conditionalClick selector="{{AdminNewCatalogPriceRule.active}}" dependentSelector="{{AdminNewCatalogPriceRule.activeIsEnabled}}" visible="false" stepKey="enableActiveBtn"/> + <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> + <waitForPageLoad stepKey="waitForSave"/> <!-- Navigate to category on store front --> <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToStorefrontCategoryPage"/> diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/BundlePriceAbstract.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/BundlePriceAbstract.php index bf369ed28167b..a18f1e0799dfa 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/BundlePriceAbstract.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/BundlePriceAbstract.php @@ -30,6 +30,11 @@ abstract class BundlePriceAbstract extends \PHPUnit\Framework\TestCase */ protected $productCollectionFactory; + /** + * @var \Magento\CatalogRule\Model\RuleFactory + */ + private $ruleFactory; + protected function setUp(): void { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -43,6 +48,7 @@ protected function setUp(): void true, \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); + $this->ruleFactory = $this->objectManager->get(\Magento\CatalogRule\Model\RuleFactory::class); } /** @@ -62,6 +68,8 @@ abstract public function getTestCases(); */ protected function prepareFixture($strategyModifiers, $productSku) { + $this->ruleFactory->create()->clearPriceRulesData(); + $bundleProduct = $this->productRepository->get($productSku); foreach ($strategyModifiers as $modifier) { From 0aa181c520c7ce62293d3798b2be277fc7ec4523 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Tue, 22 Sep 2020 09:54:38 +0300 Subject: [PATCH 07/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Catalog/Test/Mftf/Data/ProductOptionValueData.xml | 6 ------ ...CatalogRuleForSimpleProductWithSelectFixedMethodTest.xml | 6 +++--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductOptionValueData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductOptionValueData.xml index 04c24ff7e36dd..e738994357366 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductOptionValueData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductOptionValueData.xml @@ -26,12 +26,6 @@ <data key="price">99.99</data> <data key="price_type">fixed</data> </entity> - <entity name="ProductOptionValueRadioButtonsWithDiscountedPrice" type="product_option_value"> - <data key="title">OptionValueRadioButtons1</data> - <data key="sort_order">1</data> - <data key="price">78.33</data> - <data key="price_type">fixed</data> - </entity> <entity name="ProductOptionValueRadioButtons2" type="product_option_value"> <data key="title">OptionValueRadioButtons2</data> <data key="sort_order">2</data> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml index c863ebb55f41a..0a6f5c5f104b4 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml @@ -93,9 +93,9 @@ <!-- Assert regular and special price after selecting ProductOptionValueDropdown1 --> <actionGroup ref="StorefrontSelectCustomOptionRadioAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices1"> <argument name="customOption" value="ProductOptionRadioButton2"/> - <argument name="customOptionValue" value="ProductOptionValueRadioButtonsWithDiscountedPrice"/> + <argument name="customOptionValue" value="ProductOptionValueRadioButtons1"/> <argument name="productPrice" value="$156.77"/> - <argument name="productFinalPrice" value="$122.81"/> + <argument name="productFinalPrice" value="$144.47"/> </actionGroup> <!-- Add product 1 to cart --> @@ -105,7 +105,7 @@ <!-- Assert sub total on mini shopping cart --> <actionGroup ref="AssertSubTotalOnStorefrontMiniCartActionGroup" stepKey="assertSubTotalOnStorefrontMiniCart"> - <argument name="subTotal" value="$122.81"/> + <argument name="subTotal" value="$144.47"/> </actionGroup> </test> </tests> From a1673bb085020222124db45db08421b49e67f5cd Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Tue, 22 Sep 2020 16:59:03 +0300 Subject: [PATCH 08/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml index d9b62ef8fc913..8efc5b1c5769c 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml @@ -67,7 +67,9 @@ <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroup"/> <!-- Save and apply the new catalog price rule --> - <actionGroup ref="SaveAndApplyCatalogPriceRuleActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> + <conditionalClick selector="{{AdminNewCatalogPriceRule.active}}" dependentSelector="{{AdminNewCatalogPriceRule.activeIsEnabled}}" visible="false" stepKey="enableActiveBtn"/> + <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> + <waitForPageLoad stepKey="waitForSave"/> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> <argument name="indices" value=""/> </actionGroup> From 2cc1dab7aa16f5a4a3d5b0bef8e32c84b08cb377 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Wed, 23 Sep 2020 09:47:16 +0300 Subject: [PATCH 09/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- ...eForSimpleProductWithCustomOptionsTest.xml | 11 +- ...ForSimpleProductsWithCustomOptionsTest.xml | 161 ++++++++++++++++++ 2 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml index 8efc5b1c5769c..31aed3f71608f 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml @@ -7,16 +7,19 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="ApplyCatalogRuleForSimpleProductWithCustomOptionsTest"> + <test name="ApplyCatalogRuleForSimpleProductWithCustomOptionsTest" deprecated="Use ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest instead"> <annotations> <features value="CatalogRule"/> <stories value="Apply catalog price rule"/> - <title value="Admin should be able to apply the catalog price rule for simple product with 3 custom options"/> + <title value="Deprecated. Admin should be able to apply the catalog price rule for simple product with 3 custom options"/> <description value="Admin should be able to apply the catalog price rule for simple product with 3 custom options"/> <severity value="CRITICAL"/> <testCaseId value="MC-14769"/> <group value="CatalogRule"/> <group value="mtf_migrated"/> + <skip> + <issueId value="DEPRECATED">Use ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest instead</issueId> + </skip> </annotations> <before> <!-- Login as Admin --> @@ -67,9 +70,7 @@ <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroup"/> <!-- Save and apply the new catalog price rule --> - <conditionalClick selector="{{AdminNewCatalogPriceRule.active}}" dependentSelector="{{AdminNewCatalogPriceRule.activeIsEnabled}}" visible="false" stepKey="enableActiveBtn"/> - <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> - <waitForPageLoad stepKey="waitForSave"/> + <actionGroup ref="SaveAndApplyCatalogPriceRuleActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> <argument name="indices" value=""/> </actionGroup> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml new file mode 100644 index 0000000000000..e5453f6ecfd36 --- /dev/null +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest"> + <annotations> + <features value="CatalogRule"/> + <stories value="Apply catalog price rule"/> + <title value="Admin should be able to apply the catalog price rule for simple product with 3 custom options"/> + <description value="Admin should be able to apply the catalog price rule for simple product with 3 custom options"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-14769"/> + <group value="catalogRule"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <!-- Login as Admin --> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct1"> + <requiredEntity createDataKey="createCategory"/> + <field key="price">56.78</field> + </createData> + <createData entity="_defaultProduct" stepKey="createProduct2"> + <requiredEntity createDataKey="createCategory"/> + <field key="price">56.78</field> + </createData> + <createData entity="_defaultProduct" stepKey="createProduct3"> + <requiredEntity createDataKey="createCategory"/> + <field key="price">56.78</field> + </createData> + + <!-- Update all products to have custom options --> + <updateData createDataKey="createProduct1" entity="productWithCustomOptions" stepKey="updateProductWithOptions1"/> + <updateData createDataKey="createProduct2" entity="productWithCustomOptions" stepKey="updateProductWithOptions2"/> + <updateData createDataKey="createProduct3" entity="productWithCustomOptions" stepKey="updateProductWithOptions3"/> + <magentoCron stepKey="runCronIndex" groups="index"/> + </before> + <after> + <!-- Delete products and category --> + <deleteData createDataKey="createProduct1" stepKey="deleteProduct1"/> + <deleteData createDataKey="createProduct2" stepKey="deleteProduct2"/> + <deleteData createDataKey="createProduct3" stepKey="deleteProduct3"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + + <!-- Delete the catalog price rule --> + <actionGroup ref="AdminOpenCatalogPriceRulePageActionGroup" stepKey="goToPriceRulePage"/> + <actionGroup stepKey="deletePriceRule" ref="deleteEntitySecondaryGrid"> + <argument name="name" value="{{_defaultCatalogRule.name}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> + </actionGroup> + + <!-- Logout --> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <!-- 1. Begin creating a new catalog price rule --> + <actionGroup ref="NewCatalogPriceRuleByUIWithConditionIsCategoryActionGroup" stepKey="newCatalogPriceRuleByUIWithConditionIsCategory"> + <argument name ="categoryId" value="$createCategory.id$"/> + </actionGroup> + + <!-- Select not logged in customer group --> + <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroup"/> + + <!-- Save and apply the new catalog price rule --> + <conditionalClick selector="{{AdminNewCatalogPriceRule.active}}" dependentSelector="{{AdminNewCatalogPriceRule.activeIsEnabled}}" visible="false" stepKey="enableActiveBtn"/> + <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> + <waitForPageLoad stepKey="waitForSave"/> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> + <argument name="indices" value=""/> + </actionGroup> + <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> + <argument name="tags" value=""/> + </actionGroup> + + <!-- Navigate to category on store front --> + <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToCategoryPage"/> + + <!-- Check product 1 price on store front category page --> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct1.name$)}}" userInput="$51.10" stepKey="storefrontProduct1Price"/> + + <!-- Check product 1 regular price on store front category page --> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct1.name$)}}" userInput="$56.78" stepKey="storefrontProduct1RegularPrice"/> + + <!-- Check product 2 price on store front category page --> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct2.name$)}}" userInput="$51.10" stepKey="storefrontProduct2Price"/> + + <!-- Check product 2 regular price on store front category page --> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct2.name$)}}" userInput="$56.78" stepKey="storefrontProduct2RegularPrice"/> + + <!-- Check product 3 price on store front category page --> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct3.name$)}}" userInput="$51.10" stepKey="storefrontProduct3Price"/> + + <!-- Check product 3 regular price on store front category page --> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct3.name$)}}" userInput="$56.78" stepKey="storefrontProduct3RegularPrice"/> + + <!-- Navigate to product 1 on store front --> + <amOnPage url="{{StorefrontProductPage.url($createProduct1.name$)}}" stepKey="goToProductPage1"/> + + <!-- Assert regular and special price after selecting ProductOptionValueDropdown1 --> + <actionGroup ref="StorefrontSelectCustomOptionDropDownAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices1"> + <argument name="customOption" value="{{ProductOptionValueDropdown1.title}} +$0.01"/> + <argument name="productPrice" value="$56.79"/> + <argument name="productFinalPrice" value="$51.11"/> + </actionGroup> + + <!-- Add product 1 to cart --> + <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="cartAddSimpleProduct1ToCart"> + <argument name="productQty" value="1"/> + </actionGroup> + + <!-- Navigate to product 2 on store front --> + <amOnPage url="{{StorefrontProductPage.url($createProduct1.name$)}}" stepKey="goToProductPage2"/> + + <!-- Assert regular and special price after selecting ProductOptionValueDropdown3 --> + <actionGroup ref="StorefrontSelectCustomOptionDropDownAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices2"> + <argument name="customOption" value="{{ProductOptionValueDropdown3.title}} +$5.11"/> + <argument name="productPrice" value="$62.46"/> + <argument name="productFinalPrice" value="$56.21"/> + </actionGroup> + + <!-- Add product 2 to cart --> + <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="cartAddSimpleProduct2ToCart"> + <argument name="productQty" value="1"/> + </actionGroup> + + <!-- Navigate to product 3 on store front --> + <amOnPage url="{{StorefrontProductPage.url($createProduct3.name$)}}" stepKey="goToProductPage3"/> + + <!-- Add product 3 to cart with no custom option --> + <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="cartAddSimpleProduct3ToCart"> + <argument name="productQty" value="1"/> + </actionGroup> + + <!-- Assert sub total on mini shopping cart --> + <actionGroup ref="AssertSubTotalOnStorefrontMiniCartActionGroup" stepKey="assertSubTotalOnStorefrontMiniCart"> + <argument name="subTotal" value="$158.42"/> + </actionGroup> + + <!-- Navigate to checkout shipping page --> + <amOnPage stepKey="navigateToShippingPage" url="{{CheckoutShippingPage.url}}"/> + <waitForPageLoad stepKey="waitFoCheckoutShippingPageLoad"/> + + <!-- Fill Shipping information --> + <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="fillOrderShippingInfo"> + <argument name="customerVar" value="Simple_US_Customer"/> + <argument name="customerAddressVar" value="US_Address_TX"/> + </actionGroup> + + <!-- Verify order summary on payment page --> + <actionGroup ref="VerifyCheckoutPaymentOrderSummaryActionGroup" stepKey="verifyCheckoutPaymentOrderSummaryActionGroup"> + <argument name="orderSummarySubTotal" value="$158.42"/> + <argument name="orderSummaryShippingTotal" value="$15.00"/> + <argument name="orderSummaryTotal" value="$173.42"/> + </actionGroup> + </test> +</tests> From a8e07e93ca5598b19bf7ce3b3c47a0e576362a50 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Wed, 23 Sep 2020 12:20:31 +0300 Subject: [PATCH 10/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- ...plyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml index e5453f6ecfd36..cbb75dc4c9aff 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml @@ -70,12 +70,6 @@ <conditionalClick selector="{{AdminNewCatalogPriceRule.active}}" dependentSelector="{{AdminNewCatalogPriceRule.activeIsEnabled}}" visible="false" stepKey="enableActiveBtn"/> <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> <waitForPageLoad stepKey="waitForSave"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> - <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> - <argument name="tags" value=""/> - </actionGroup> <!-- Navigate to category on store front --> <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToCategoryPage"/> From 01a715933ab73d9fc3af90c2244277d5eb1d30dc Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Thu, 24 Sep 2020 12:19:47 +0300 Subject: [PATCH 11/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Product/View/Options/AbstractOptions.php | 8 +++- .../Magento/Catalog/Model/Product/Option.php | 11 ++++- .../Model/Product/Option/Type/DefaultType.php | 11 ++++- .../Model/Product/Option/Type/Select.php | 22 +++++++++- .../Catalog/Model/Product/Option/Value.php | 7 +++- .../CalculateCustomOptionCatalogRule.php | 41 +++---------------- ...ForSimpleProductsWithCustomOptionsTest.xml | 17 +++++++- 7 files changed, 71 insertions(+), 46 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php b/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php index 310158ed99948..2093ac68e321f 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php @@ -124,6 +124,7 @@ public function getOption() * Retrieve formatted price * * @return string + * @since 102.0.6 */ public function getFormattedPrice() { @@ -143,7 +144,7 @@ public function getFormattedPrice() * * @return string * - * @deprecated + * @deprecated 102.0.6 * @see getFormattedPrice() */ public function getFormatedPrice() @@ -175,11 +176,14 @@ protected function _formatPrice($value, $flag = true) $customOptionPrice = $this->getProduct()->getPriceInfo()->getPrice('custom_option_price'); if (!$value['is_percent']) { - $value['pricing_value'] = $this->calculateCustomOptionCatalogRule->execute( + $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( $this->getProduct(), (float)$value['pricing_value'], (bool)$value['is_percent'] ); + if ($catalogPriceValue!==null) { + $value['pricing_value'] = $catalogPriceValue; + } } $context = [CustomOptionPriceInterface::CONFIGURATION_OPTION_FLAG => true]; diff --git a/app/code/Magento/Catalog/Model/Product/Option.php b/app/code/Magento/Catalog/Model/Product/Option.php index 15c40af09d7b9..4b8fd5d1a602a 100644 --- a/app/code/Magento/Catalog/Model/Product/Option.php +++ b/app/code/Magento/Catalog/Model/Product/Option.php @@ -18,6 +18,7 @@ use Magento\Catalog\Model\Product\Option\Type\Text; use Magento\Catalog\Model\Product\Option\Value; use Magento\Catalog\Model\ResourceModel\Product\Option\Value\Collection; +use Magento\Catalog\Pricing\Price\BasePrice; use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule; use Magento\Framework\App\ObjectManager; use Magento\Framework\EntityManager\MetadataPool; @@ -473,12 +474,18 @@ public function afterSave() */ public function getPrice($flag = false) { - if ($flag) { - return $this->calculateCustomOptionCatalogRule->execute( + if ($flag && $this->getPriceType() == self::$typePercent) { + $price = $this->calculateCustomOptionCatalogRule->execute( $this->getProduct(), (float)$this->getData(self::KEY_PRICE), $this->getPriceType() === Value::TYPE_PERCENT ); + + if ($price == null) { + $basePrice = $this->getProduct()->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getValue(); + $price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100); + } + return $price; } return $this->_getData(self::KEY_PRICE); } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php b/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php index a6ab77a090b4e..86b3a72f73ec0 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php @@ -352,11 +352,20 @@ public function getOptionPrice($optionValue, $basePrice) { $option = $this->getOption(); - return $this->calculateCustomOptionCatalogRule->execute( + $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( $option->getProduct(), (float)$option->getPrice(), $option->getPriceType() === Value::TYPE_PERCENT ); + if ($catalogPriceValue!==null) { + return $catalogPriceValue; + } else { + return $this->_getChargeableOptionPrice( + $option->getPrice(), + $option->getPriceType() == 'percent', + $basePrice + ); + } } /** diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php b/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php index 17f0fb3b25f99..25aeb340605ab 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php @@ -260,11 +260,20 @@ public function getOptionPrice($optionValue, $basePrice) foreach (explode(',', $optionValue) as $value) { $_result = $option->getValueById($value); if ($_result) { - $result += $this->calculateCustomOptionCatalogRule->execute( + $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( $option->getProduct(), (float)$_result->getPrice(), $_result->getPriceType() === Value::TYPE_PERCENT ); + if ($catalogPriceValue!==null) { + $result += $catalogPriceValue; + } else { + $result += $this->_getChargeableOptionPrice( + $_result->getPrice(), + $_result->getPriceType() == 'percent', + $basePrice + ); + } } else { if ($this->getListener()) { $this->getListener()->setHasError(true)->setMessage($this->_getWrongConfigurationMessage()); @@ -275,11 +284,20 @@ public function getOptionPrice($optionValue, $basePrice) } elseif ($this->_isSingleSelection()) { $_result = $option->getValueById($optionValue); if ($_result) { - $result = $this->calculateCustomOptionCatalogRule->execute( + $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( $option->getProduct(), (float)$_result->getPrice(), $_result->getPriceType() === Value::TYPE_PERCENT ); + if ($catalogPriceValue !== null) { + $result = $catalogPriceValue; + } else { + $result = $this->_getChargeableOptionPrice( + $_result->getPrice(), + $_result->getPriceType() == 'percent', + $basePrice + ); + } } else { if ($this->getListener()) { $this->getListener()->setHasError(true)->setMessage($this->_getWrongConfigurationMessage()); diff --git a/app/code/Magento/Catalog/Model/Product/Option/Value.php b/app/code/Magento/Catalog/Model/Product/Option/Value.php index 6eeaa44cda706..638eaca328ff5 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Value.php @@ -264,11 +264,16 @@ public function saveValues() public function getPrice($flag = false) { if ($flag) { - return $this->calculateCustomOptionCatalogRule->execute( + $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( $this->getProduct(), (float)$this->getData(self::KEY_PRICE), $this->getPriceType() === self::TYPE_PERCENT ); + if ($catalogPriceValue!==null) { + return $catalogPriceValue; + } else { + return $this->customOptionPriceCalculator->getOptionPriceByPriceCode($this, BasePrice::PRICE_CODE); + } } return $this->_getData(self::KEY_PRICE); } diff --git a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php index cf7c12b4560e0..2f7156bc70dbf 100644 --- a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php +++ b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php @@ -9,8 +9,6 @@ use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\PriceModifierInterface; -use Magento\CatalogRule\Pricing\Price\CatalogRulePrice; -use Magento\Framework\Pricing\Price\BasePriceProviderInterface; use Magento\Framework\Pricing\PriceCurrencyInterface; /** @@ -29,6 +27,7 @@ class CalculateCustomOptionCatalogRule private $priceModifier; /** + * CalculateCustomOptionCatalogRule constructor. * @param PriceCurrencyInterface $priceCurrency * @param PriceModifierInterface $priceModifier */ @@ -46,13 +45,13 @@ public function __construct( * @param Product $product * @param float $optionPriceValue * @param bool $isPercent - * @return float + * @return float|null */ public function execute( Product $product, float $optionPriceValue, bool $isPercent - ): float { + ) { $regularPrice = (float)$product->getPriceInfo() ->getPrice(RegularPrice::PRICE_CODE) ->getValue(); @@ -68,39 +67,9 @@ public function execute( $product ); $finalOptionPrice = $totalCatalogRulePrice - $catalogRulePrice; - } else { - $finalOptionPrice = $this->getOptionPriceWithoutPriceRule( - $optionPriceValue, - $isPercent, - $this->getGetBasePriceWithOutCatalogRules($product) - ); - } - - return $this->priceCurrency->convertAndRound($finalOptionPrice); - } - - /** - * Get product base price without catalog rules applied. - * - * @param Product $product - * @return float - */ - private function getGetBasePriceWithOutCatalogRules(Product $product): float - { - $basePrice = null; - foreach ($product->getPriceInfo()->getPrices() as $price) { - if ($price instanceof BasePriceProviderInterface - && $price->getPriceCode() !== CatalogRulePrice::PRICE_CODE - && $price->getValue() !== false - ) { - $basePrice = min( - $price->getValue(), - $basePrice ?? $price->getValue() - ); - } + return $this->priceCurrency->convertAndRound($finalOptionPrice); } - - return $basePrice ?? $product->getPrice(); + return null; } /** diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml index cbb75dc4c9aff..2944b76434330 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml @@ -20,7 +20,6 @@ </annotations> <before> <!-- Login as Admin --> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="_defaultCategory" stepKey="createCategory"/> <createData entity="_defaultProduct" stepKey="createProduct1"> <requiredEntity createDataKey="createCategory"/> @@ -39,7 +38,7 @@ <updateData createDataKey="createProduct1" entity="productWithCustomOptions" stepKey="updateProductWithOptions1"/> <updateData createDataKey="createProduct2" entity="productWithCustomOptions" stepKey="updateProductWithOptions2"/> <updateData createDataKey="createProduct3" entity="productWithCustomOptions" stepKey="updateProductWithOptions3"/> - <magentoCron stepKey="runCronIndex" groups="index"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <!-- Delete products and category --> @@ -55,6 +54,13 @@ <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> </actionGroup> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexAdterTest"> + <argument name="indices" value=""/> + </actionGroup> + <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCacheAfterTest"> + <argument name="tags" value=""/> + </actionGroup> + <!-- Logout --> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> @@ -71,6 +77,13 @@ <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> <waitForPageLoad stepKey="waitForSave"/> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> + <argument name="indices" value=""/> + </actionGroup> + <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> + <argument name="tags" value=""/> + </actionGroup> + <!-- Navigate to category on store front --> <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToCategoryPage"/> From bb78ad80e8b2613ea34f2b432da8f044eaf2e1e3 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Thu, 24 Sep 2020 15:18:43 +0300 Subject: [PATCH 12/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Model/Product/Option/Type/Select.php | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php b/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php index 25aeb340605ab..435b1629d0c85 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php @@ -260,20 +260,7 @@ public function getOptionPrice($optionValue, $basePrice) foreach (explode(',', $optionValue) as $value) { $_result = $option->getValueById($value); if ($_result) { - $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( - $option->getProduct(), - (float)$_result->getPrice(), - $_result->getPriceType() === Value::TYPE_PERCENT - ); - if ($catalogPriceValue!==null) { - $result += $catalogPriceValue; - } else { - $result += $this->_getChargeableOptionPrice( - $_result->getPrice(), - $_result->getPriceType() == 'percent', - $basePrice - ); - } + $result += $this->getCalculatedOptionValue($option, $_result, $basePrice); } else { if ($this->getListener()) { $this->getListener()->setHasError(true)->setMessage($this->_getWrongConfigurationMessage()); @@ -359,4 +346,31 @@ protected function _isSingleSelection() { return in_array($this->getOption()->getType(), $this->singleSelectionTypes, true); } + + /** + * Returns calculated price of option + * + * @param \Magento\Catalog\Model\Product\Option $option + * @param \Magento\Catalog\Model\Product\Option\Value $result + * @param float $basePrice + * @return float|null + */ + protected function getCalculatedOptionValue($option, $result, $basePrice) + { + $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( + $option->getProduct(), + (float)$result->getPrice(), + $result->getPriceType() === Value::TYPE_PERCENT + ); + if ($catalogPriceValue!==null) { + $optionCalculatedValue = $catalogPriceValue; + } else { + $optionCalculatedValue = $this->_getChargeableOptionPrice( + $result->getPrice(), + $result->getPriceType() == 'percent', + $basePrice + ); + } + return $optionCalculatedValue; + } } From a7ee62f69f6f5c3ba6cce9d1b647188145ee7b01 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Mon, 5 Oct 2020 12:17:32 +0300 Subject: [PATCH 13/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Product/View/Options/AbstractOptions.php | 9 +- .../Magento/Catalog/Model/Product/Option.php | 8 +- .../Model/Product/Option/Type/DefaultType.php | 6 +- .../Model/Product/Option/Type/Select.php | 15 +-- .../CalculateCustomOptionCatalogRule.php | 4 +- .../Unit/Model/Product/Option/ValueTest.php | 8 +- app/code/Magento/CatalogRule/Model/Rule.php | 1 + ...RuleForSimpleProductAndFixedMethodTest.xml | 4 +- ...eForSimpleProductWithCustomOptionsTest.xml | 4 +- ...impleProductWithSelectFixedMethodTest.xml} | 57 +++++----- ...orSimpleProductsWithCustomOptionsTest.xml} | 103 ++++++++++-------- 11 files changed, 119 insertions(+), 100 deletions(-) rename app/code/Magento/CatalogRule/Test/Mftf/Test/{ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml => StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml} (67%) rename app/code/Magento/CatalogRule/Test/Mftf/Test/{ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml => StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml} (56%) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php b/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php index 2093ac68e321f..de92546a8dd88 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php @@ -60,7 +60,7 @@ abstract class AbstractOptions extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\Pricing\Helper\Data $pricingHelper * @param \Magento\Catalog\Helper\Data $catalogData * @param array $data - * @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule + * @param CalculateCustomOptionCatalogRule|null $calculateCustomOptionCatalogRule */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, @@ -174,14 +174,15 @@ protected function _formatPrice($value, $flag = true) $priceStr = $sign; $customOptionPrice = $this->getProduct()->getPriceInfo()->getPrice('custom_option_price'); + $isPercent = (bool) $value['is_percent']; - if (!$value['is_percent']) { + if (!$isPercent) { $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( $this->getProduct(), (float)$value['pricing_value'], - (bool)$value['is_percent'] + $isPercent ); - if ($catalogPriceValue!==null) { + if ($catalogPriceValue !== null) { $value['pricing_value'] = $catalogPriceValue; } } diff --git a/app/code/Magento/Catalog/Model/Product/Option.php b/app/code/Magento/Catalog/Model/Product/Option.php index 4b8fd5d1a602a..44d6fb04b01b0 100644 --- a/app/code/Magento/Catalog/Model/Product/Option.php +++ b/app/code/Magento/Catalog/Model/Product/Option.php @@ -146,7 +146,7 @@ class Option extends AbstractExtensibleModel implements ProductCustomOptionInter * @param ProductCustomOptionValuesInterfaceFactory|null $customOptionValuesFactory * @param array $optionGroups * @param array $optionTypesToGroups - * @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule + * @param CalculateCustomOptionCatalogRule|null $calculateCustomOptionCatalogRule * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -474,19 +474,21 @@ public function afterSave() */ public function getPrice($flag = false) { - if ($flag && $this->getPriceType() == self::$typePercent) { + if ($flag && $this->getPriceType() === self::$typePercent) { $price = $this->calculateCustomOptionCatalogRule->execute( $this->getProduct(), (float)$this->getData(self::KEY_PRICE), $this->getPriceType() === Value::TYPE_PERCENT ); - if ($price == null) { + if ($price === null) { $basePrice = $this->getProduct()->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getValue(); $price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100); } + return $price; } + return $this->_getData(self::KEY_PRICE); } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php b/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php index 86b3a72f73ec0..e819f36b5cf7d 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php @@ -73,7 +73,7 @@ class DefaultType extends \Magento\Framework\DataObject * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param array $data - * @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule + * @param CalculateCustomOptionCatalogRule|null $calculateCustomOptionCatalogRule */ public function __construct( \Magento\Checkout\Model\Session $checkoutSession, @@ -357,12 +357,12 @@ public function getOptionPrice($optionValue, $basePrice) (float)$option->getPrice(), $option->getPriceType() === Value::TYPE_PERCENT ); - if ($catalogPriceValue!==null) { + if ($catalogPriceValue !== null) { return $catalogPriceValue; } else { return $this->_getChargeableOptionPrice( $option->getPrice(), - $option->getPriceType() == 'percent', + $option->getPriceType() === Value::TYPE_PERCENT, $basePrice ); } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php b/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php index 435b1629d0c85..580ef7689ff4e 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/Select.php @@ -10,6 +10,7 @@ use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule; use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; +use Magento\Catalog\Model\Product\Option; /** * Catalog product option select type @@ -52,7 +53,7 @@ class Select extends \Magento\Catalog\Model\Product\Option\Type\DefaultType * @param \Magento\Framework\Escaper $escaper * @param array $data * @param array $singleSelectionTypes - * @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule + * @param CalculateCustomOptionCatalogRule|null $calculateCustomOptionCatalogRule */ public function __construct( \Magento\Checkout\Model\Session $checkoutSession, @@ -350,24 +351,24 @@ protected function _isSingleSelection() /** * Returns calculated price of option * - * @param \Magento\Catalog\Model\Product\Option $option - * @param \Magento\Catalog\Model\Product\Option\Value $result + * @param Option $option + * @param Option\Value $result * @param float $basePrice - * @return float|null + * @return float */ - protected function getCalculatedOptionValue($option, $result, $basePrice) + protected function getCalculatedOptionValue(Option $option, Value $result, float $basePrice) : float { $catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute( $option->getProduct(), (float)$result->getPrice(), $result->getPriceType() === Value::TYPE_PERCENT ); - if ($catalogPriceValue!==null) { + if ($catalogPriceValue !== null) { $optionCalculatedValue = $catalogPriceValue; } else { $optionCalculatedValue = $this->_getChargeableOptionPrice( $result->getPrice(), - $result->getPriceType() == 'percent', + $result->getPriceType() === Value::TYPE_PERCENT, $basePrice ); } diff --git a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php index 2f7156bc70dbf..1090867aa51a5 100644 --- a/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php +++ b/app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php @@ -27,7 +27,6 @@ class CalculateCustomOptionCatalogRule private $priceModifier; /** - * CalculateCustomOptionCatalogRule constructor. * @param PriceCurrencyInterface $priceCurrency * @param PriceModifierInterface $priceModifier */ @@ -51,7 +50,7 @@ public function execute( Product $product, float $optionPriceValue, bool $isPercent - ) { + ): ?float { $regularPrice = (float)$product->getPriceInfo() ->getPrice(RegularPrice::PRICE_CODE) ->getValue(); @@ -69,6 +68,7 @@ public function execute( $finalOptionPrice = $totalCatalogRulePrice - $catalogRulePrice; return $this->priceCurrency->convertAndRound($finalOptionPrice); } + return null; } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php index d604e41018c07..e084a8cbbde27 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php @@ -32,14 +32,14 @@ class ValueTest extends TestCase /** * @var CalculateCustomOptionCatalogRule|MockObject */ - private $CalculateCustomOptionCatalogRule; + private $calculateCustomOptionCatalogRule; protected function setUp(): void { $mockedResource = $this->getMockedResource(); $mockedCollectionFactory = $this->getMockedValueCollectionFactory(); - $this->CalculateCustomOptionCatalogRule = $this->createMock( + $this->calculateCustomOptionCatalogRule = $this->createMock( CalculateCustomOptionCatalogRule::class ); @@ -49,7 +49,7 @@ protected function setUp(): void [ 'resource' => $mockedResource, 'valueCollectionFactory' => $mockedCollectionFactory, - 'CalculateCustomOptionCatalogRule' => $this->CalculateCustomOptionCatalogRule + 'CalculateCustomOptionCatalogRule' => $this->calculateCustomOptionCatalogRule ] ); $this->model->setOption($this->getMockedOption()); @@ -77,7 +77,7 @@ public function testGetPrice() $this->assertEquals($price, $this->model->getPrice(false)); $percentPrice = 100.0; - $this->CalculateCustomOptionCatalogRule->expects($this->atLeastOnce()) + $this->calculateCustomOptionCatalogRule->expects($this->atLeastOnce()) ->method('execute') ->willReturn($percentPrice); $this->assertEquals($percentPrice, $this->model->getPrice(true)); diff --git a/app/code/Magento/CatalogRule/Model/Rule.php b/app/code/Magento/CatalogRule/Model/Rule.php index bcd01dae96e81..c9d912f500ebd 100644 --- a/app/code/Magento/CatalogRule/Model/Rule.php +++ b/app/code/Magento/CatalogRule/Model/Rule.php @@ -898,6 +898,7 @@ public function getIdentities() /** * Clear price rules cache. + * @return void; */ public function clearPriceRulesData(): void { diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductAndFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductAndFixedMethodTest.xml index 43f8decb874cb..ece8dc4bacf28 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductAndFixedMethodTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductAndFixedMethodTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="ApplyCatalogRuleForSimpleProductAndFixedMethodTest" deprecated="Use ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest instead"> + <test name="ApplyCatalogRuleForSimpleProductAndFixedMethodTest" deprecated="Use StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest instead"> <annotations> <features value="CatalogRule"/> <stories value="Apply catalog price rule"/> @@ -18,7 +18,7 @@ <group value="CatalogRule"/> <group value="mtf_migrated"/> <skip> - <issueId value="DEPRECATED">Use ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest instead</issueId> + <issueId value="DEPRECATED">Use StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest instead</issueId> </skip> </annotations> <before> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml index 31aed3f71608f..45e97f179a11f 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="ApplyCatalogRuleForSimpleProductWithCustomOptionsTest" deprecated="Use ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest instead"> + <test name="ApplyCatalogRuleForSimpleProductWithCustomOptionsTest" deprecated="Use StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest instead"> <annotations> <features value="CatalogRule"/> <stories value="Apply catalog price rule"/> @@ -18,7 +18,7 @@ <group value="CatalogRule"/> <group value="mtf_migrated"/> <skip> - <issueId value="DEPRECATED">Use ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest instead</issueId> + <issueId value="DEPRECATED">Use StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest instead</issueId> </skip> </annotations> <before> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml similarity index 67% rename from app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml rename to app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml index 0a6f5c5f104b4..cb1e20aa2b227 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="ApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest"> + <test name="StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest"> <annotations> <features value="CatalogRule"/> <stories value="Apply catalog price rule"/> @@ -17,6 +17,7 @@ <testCaseId value="MC-14771"/> <group value="catalogRule"/> <group value="mtf_migrated"/> + <group value="catalog"/> </annotations> <before> <!-- Create category --> @@ -29,13 +30,16 @@ </createData> <!-- Update all products to have custom options --> - <updateData createDataKey="createProduct1" entity="productWithFixedOptions" stepKey="updateProductWithOptions1"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <updateData createDataKey="createProduct1" entity="productWithFixedOptions" stepKey="updateFirstProductWithOptions"/> <!-- Login as Admin --> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + + <!-- Clear all catalog price rules and reindex before test --> + <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesBeforeTest"/> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> + <argument name="indices" value=""/> + </actionGroup> </before> <after> <!-- Delete products and category --> @@ -43,31 +47,28 @@ <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <!-- Delete the catalog price rule --> - <actionGroup ref="AdminOpenCatalogPriceRulePageActionGroup" stepKey="goToPriceRulePage"/> - <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRule"> - <argument name="name" value="{{CatalogRuleByFixed.name}}"/> - <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> - </actionGroup> - + <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesAfterTest"/> <!-- Logout --> <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> </after> <!-- 1. Begin creating a new catalog price rule --> - <actionGroup ref="NewCatalogPriceRuleByUIWithConditionIsCategoryActionGroup" stepKey="newCatalogPriceRuleByUIWithConditionIsCategory"> - <argument name ="categoryId" value="$createCategory.id$"/> - <argument name ="catalogRule" value="CatalogRuleByFixed"/> + <actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="startCreatingFirstPriceRule"/> + <actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForFirstPriceRule"> + <argument name="groups" value="'NOT LOGGED IN'"/> </actionGroup> - - <!-- Select not logged in customer group --> - <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroup"/> - - <!-- Save and apply the new catalog price rule --> - <conditionalClick selector="{{AdminNewCatalogPriceRule.active}}" dependentSelector="{{AdminNewCatalogPriceRule.activeIsEnabled}}" visible="false" stepKey="enableActiveBtn"/> - <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> - <waitForPageLoad stepKey="waitForSave"/> + <actionGroup ref="AdminFillCatalogRuleConditionActionGroup" stepKey="createCatalogPriceRule"> + <argument name="conditionValue" value="$createCategory.id$"/> + </actionGroup> + <actionGroup ref="AdminCatalogPriceRuleFillActionsActionGroup" stepKey="fillActionsForCatalogPriceRule"> + <argument name="apply" value="by_fixed"/> + <argument name="discountAmount" value="12.3"/> + </actionGroup> + <actionGroup ref="AdminCatalogPriceRuleSaveAndApplyActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> <!-- Navigate to category on store front --> - <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToStorefrontCategoryPage"/> + <actionGroup ref="StorefrontNavigateCategoryPageActionGroup" stepKey="goToStorefrontCategoryPage"> + <argument name="category" value="$createCategory$"/> + </actionGroup> <!-- Check product 1 name on store front category page --> <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1Name"> @@ -87,8 +88,10 @@ <argument name="productNumber" value="1"/> </actionGroup> - <!-- Navigate to product 1 on store front --> - <amOnPage url="{{StorefrontProductPage.url($createProduct1.name$)}}" stepKey="goToProductPage1"/> + <!-- Navigate to product on store front --> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage1"> + <argument name="productUrlKey" value="$createProduct1.custom_attributes[url_key]$"/> + </actionGroup> <!-- Assert regular and special price after selecting ProductOptionValueDropdown1 --> <actionGroup ref="StorefrontSelectCustomOptionRadioAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices1"> @@ -99,8 +102,8 @@ </actionGroup> <!-- Add product 1 to cart --> - <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="cartAddSimpleProduct1ToCart"> - <argument name="productQty" value="1"/> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage1"> + <argument name="productName" value="$createProduct1.name$"/> </actionGroup> <!-- Assert sub total on mini shopping cart --> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml similarity index 56% rename from app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml rename to app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml index 2944b76434330..4cfbae45b4dcc 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest"> + <test name="StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest"> <annotations> <features value="CatalogRule"/> <stories value="Apply catalog price rule"/> @@ -17,6 +17,7 @@ <testCaseId value="MC-14769"/> <group value="catalogRule"/> <group value="mtf_migrated"/> + <group value="catalog"/> </annotations> <before> <!-- Login as Admin --> @@ -39,6 +40,7 @@ <updateData createDataKey="createProduct2" entity="productWithCustomOptions" stepKey="updateProductWithOptions2"/> <updateData createDataKey="createProduct3" entity="productWithCustomOptions" stepKey="updateProductWithOptions3"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesBeforeTest"/> </before> <after> <!-- Delete products and category --> @@ -48,65 +50,71 @@ <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <!-- Delete the catalog price rule --> - <actionGroup ref="AdminOpenCatalogPriceRulePageActionGroup" stepKey="goToPriceRulePage"/> - <actionGroup stepKey="deletePriceRule" ref="deleteEntitySecondaryGrid"> - <argument name="name" value="{{_defaultCatalogRule.name}}"/> - <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> - </actionGroup> - - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexAdterTest"> - <argument name="indices" value=""/> - </actionGroup> - <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCacheAfterTest"> - <argument name="tags" value=""/> - </actionGroup> + <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesAfterTest"/> + <magentoCron groups="index" stepKey="fixInvalidatedIndices"/> <!-- Logout --> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- 1. Begin creating a new catalog price rule --> - <actionGroup ref="NewCatalogPriceRuleByUIWithConditionIsCategoryActionGroup" stepKey="newCatalogPriceRuleByUIWithConditionIsCategory"> - <argument name ="categoryId" value="$createCategory.id$"/> + <actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="startCreatingFirstPriceRule"/> + <actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForFirstPriceRule"> + <argument name="groups" value="'NOT LOGGED IN'"/> </actionGroup> - - <!-- Select not logged in customer group --> - <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroup"/> - - <!-- Save and apply the new catalog price rule --> - <conditionalClick selector="{{AdminNewCatalogPriceRule.active}}" dependentSelector="{{AdminNewCatalogPriceRule.activeIsEnabled}}" visible="false" stepKey="enableActiveBtn"/> - <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> - <waitForPageLoad stepKey="waitForSave"/> - - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> + <actionGroup ref="AdminFillCatalogRuleConditionActionGroup" stepKey="createCatalogPriceRule"> + <argument name="conditionValue" value="$createCategory.id$"/> </actionGroup> - <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> - <argument name="tags" value=""/> + <actionGroup ref="AdminCatalogPriceRuleFillActionsActionGroup" stepKey="fillActionsForCatalogPriceRule"> + <argument name="apply" value="by_percent"/> + <argument name="discountAmount" value="10"/> </actionGroup> + <actionGroup ref="AdminCatalogPriceRuleSaveAndApplyActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> <!-- Navigate to category on store front --> - <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToCategoryPage"/> + <actionGroup ref="StorefrontNavigateCategoryPageActionGroup" stepKey="goToStorefrontCategoryPage"> + <argument name="category" value="$createCategory$"/> + </actionGroup> <!-- Check product 1 price on store front category page --> - <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct1.name$)}}" userInput="$51.10" stepKey="storefrontProduct1Price"/> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct1Price"> + <argument name="productName" value="$createProduct1.name$"/> + <argument name="productPrice" value="$51.10"/> + </actionGroup> <!-- Check product 1 regular price on store front category page --> - <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct1.name$)}}" userInput="$56.78" stepKey="storefrontProduct1RegularPrice"/> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct1RegularPrice"> + <argument name="productName" value="$createProduct1.name$"/> + <argument name="productPrice" value="$56.78"/> + </actionGroup> <!-- Check product 2 price on store front category page --> - <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct2.name$)}}" userInput="$51.10" stepKey="storefrontProduct2Price"/> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct2Price"> + <argument name="productName" value="$createProduct2.name$"/> + <argument name="productPrice" value="$51.10"/> + </actionGroup> <!-- Check product 2 regular price on store front category page --> - <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct2.name$)}}" userInput="$56.78" stepKey="storefrontProduct2RegularPrice"/> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct2RegularPrice"> + <argument name="productName" value="$createProduct2.name$"/> + <argument name="productPrice" value="$56.78"/> + </actionGroup> <!-- Check product 3 price on store front category page --> - <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct3.name$)}}" userInput="$51.10" stepKey="storefrontProduct3Price"/> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct3Price"> + <argument name="productName" value="$createProduct3.name$"/> + <argument name="productPrice" value="$51.10"/> + </actionGroup> <!-- Check product 3 regular price on store front category page --> - <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct3.name$)}}" userInput="$56.78" stepKey="storefrontProduct3RegularPrice"/> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct3RegularPrice"> + <argument name="productName" value="$createProduct3.name$"/> + <argument name="productPrice" value="$56.78"/> + </actionGroup> <!-- Navigate to product 1 on store front --> - <amOnPage url="{{StorefrontProductPage.url($createProduct1.name$)}}" stepKey="goToProductPage1"/> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage1"> + <argument name="productUrlKey" value="$createProduct1.custom_attributes[url_key]$"/> + </actionGroup> <!-- Assert regular and special price after selecting ProductOptionValueDropdown1 --> <actionGroup ref="StorefrontSelectCustomOptionDropDownAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices1"> @@ -116,12 +124,14 @@ </actionGroup> <!-- Add product 1 to cart --> - <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="cartAddSimpleProduct1ToCart"> - <argument name="productQty" value="1"/> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage1"> + <argument name="productName" value="$createProduct1.name$"/> </actionGroup> <!-- Navigate to product 2 on store front --> - <amOnPage url="{{StorefrontProductPage.url($createProduct1.name$)}}" stepKey="goToProductPage2"/> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage2"> + <argument name="productUrlKey" value="$createProduct2.custom_attributes[url_key]$"/> + </actionGroup> <!-- Assert regular and special price after selecting ProductOptionValueDropdown3 --> <actionGroup ref="StorefrontSelectCustomOptionDropDownAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices2"> @@ -131,16 +141,18 @@ </actionGroup> <!-- Add product 2 to cart --> - <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="cartAddSimpleProduct2ToCart"> - <argument name="productQty" value="1"/> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage2"> + <argument name="productName" value="$createProduct2.name$"/> </actionGroup> <!-- Navigate to product 3 on store front --> - <amOnPage url="{{StorefrontProductPage.url($createProduct3.name$)}}" stepKey="goToProductPage3"/> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage3"> + <argument name="productUrlKey" value="$createProduct3.custom_attributes[url_key]$"/> + </actionGroup> <!-- Add product 3 to cart with no custom option --> - <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="cartAddSimpleProduct3ToCart"> - <argument name="productQty" value="1"/> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage3"> + <argument name="productName" value="$createProduct3.name$"/> </actionGroup> <!-- Assert sub total on mini shopping cart --> @@ -149,8 +161,7 @@ </actionGroup> <!-- Navigate to checkout shipping page --> - <amOnPage stepKey="navigateToShippingPage" url="{{CheckoutShippingPage.url}}"/> - <waitForPageLoad stepKey="waitFoCheckoutShippingPageLoad"/> + <actionGroup ref="OpenStoreFrontCheckoutShippingPageActionGroup" stepKey="onCheckout"/> <!-- Fill Shipping information --> <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="fillOrderShippingInfo"> From 5347b598cc3455210369b80770cbc9780162c043 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Mon, 5 Oct 2020 15:50:23 +0300 Subject: [PATCH 14/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- app/code/Magento/CatalogRule/Model/Rule.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogRule/Model/Rule.php b/app/code/Magento/CatalogRule/Model/Rule.php index c9d912f500ebd..2d92192368960 100644 --- a/app/code/Magento/CatalogRule/Model/Rule.php +++ b/app/code/Magento/CatalogRule/Model/Rule.php @@ -898,6 +898,7 @@ public function getIdentities() /** * Clear price rules cache. + * * @return void; */ public function clearPriceRulesData(): void From 544296e3172e9343e1c87a8502220dff64efa89b Mon Sep 17 00:00:00 2001 From: engcom-Kilo <mikola.malevanec@transoftgroup.com> Date: Tue, 6 Oct 2020 15:32:48 +0300 Subject: [PATCH 15/20] MC-37666: Incorrect Customer TAX Class saved with Quote when VAT Validation used on Guest orders --- .../Magento/Quote/Model/QuoteManagement.php | 4 +- .../Quote/Model/QuoteManagementTest.php | 57 +++++++++++++++++++ .../_files/guest_quote_with_addresses.php | 5 +- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index b0aef022dcd25..1d4b8feba07f5 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -8,6 +8,7 @@ namespace Magento\Quote\Model; use Magento\Authorization\Model\UserContextInterface; +use Magento\Customer\Api\Data\GroupInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Event\ManagerInterface as EventManager; use Magento\Framework\Exception\CouldNotSaveException; @@ -396,7 +397,8 @@ public function placeOrder($cartId, PaymentInterface $paymentMethod = null) } } $quote->setCustomerIsGuest(true); - $quote->setCustomerGroupId(\Magento\Customer\Api\Data\GroupInterface::NOT_LOGGED_IN_ID); + $groupId = $quote->getCustomer()->getGroupId() ?: GroupInterface::NOT_LOGGED_IN_ID; + $quote->setCustomerGroupId($groupId); } $remoteAddress = $this->remoteAddress->getRemoteAddress(); diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php index facb4879650b1..26ae82120b2c7 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php @@ -10,10 +10,15 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product\Type; use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\Vat; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\DataObject; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\StateException; use Magento\Framework\ObjectManagerInterface; use Magento\Quote\Api\CartManagementInterface; +use Magento\Quote\Observer\Frontend\Quote\Address\CollectTotalsObserver; +use Magento\Quote\Observer\Frontend\Quote\Address\VatValidator; use Magento\Sales\Api\OrderManagementInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Store\Model\StoreManagerInterface; @@ -21,6 +26,7 @@ use Magento\TestFramework\Quote\Model\GetQuoteByReservedOrderId; use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; /** * Class for testing QuoteManagement model @@ -106,6 +112,28 @@ public function testSubmit(): void } } + /** + * Verify guest customer place order with auto-group assigment. + * + * @magentoDataFixture Magento/Sales/_files/guest_quote_with_addresses.php + * + * @magentoConfigFixture default_store customer/create_account/auto_group_assign 1 + * @magentoConfigFixture default_store customer/create_account/tax_calculation_address_type shipping + * @magentoConfigFixture default_store customer/create_account/viv_intra_union_group 2 + * @magentoConfigFixture default_store customer/create_account/viv_on_each_transaction 1 + * + * @return void + */ + public function testSubmitGuestCustomer(): void + { + $this->mockVatValidation(); + $quote = $this->getQuoteByReservedOrderId->execute('guest_quote'); + $this->cartManagement->placeOrder($quote->getId()); + $quoteAfterOrderPlaced = $this->getQuoteByReservedOrderId->execute('guest_quote'); + self::assertEquals(2, $quoteAfterOrderPlaced->getCustomerGroupId()); + self::assertEquals(3, $quoteAfterOrderPlaced->getCustomerTaxClassId()); + } + /** * Tries to create order with product that has child items and one of them was deleted. * @@ -231,4 +259,33 @@ private function makeProductOutOfStock(string $sku): void $stockItem->setIsInStock(false); $this->productRepository->save($product); } + + /** + * Makes customer vat validator 'check vat number' response successful. + * + * @return void + */ + private function mockVatValidation(): void + { + $vatMock = $this->getMockBuilder(Vat::class) + ->setConstructorArgs( + [ + 'scopeConfig' => $this->objectManager->get(ScopeConfigInterface::class), + 'logger' => $this->objectManager->get(LoggerInterface::class), + ] + ) + ->onlyMethods(['checkVatNumber']) + ->getMock(); + $gatewayResponse = new DataObject([ + 'is_valid' => true, + 'request_date' => 'testData', + 'request_identifier' => 'testRequestIdentifier', + 'request_success' => true, + ]); + $vatMock->method('checkVatNumber')->willReturn($gatewayResponse); + $this->objectManager->removeSharedInstance(CollectTotalsObserver::class); + $this->objectManager->removeSharedInstance(VatValidator::class); + $this->objectManager->removeSharedInstance(Vat::class); + $this->objectManager->addSharedInstance($vatMock, Vat::class); + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/guest_quote_with_addresses.php b/dev/tests/integration/testsuite/Magento/Sales/_files/guest_quote_with_addresses.php index d613b60c1d52f..019b3114e04c8 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/guest_quote_with_addresses.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/guest_quote_with_addresses.php @@ -40,14 +40,14 @@ $addressData = [ 'telephone' => 3234676, 'postcode' => 47676, - 'country_id' => 'US', + 'country_id' => 'DE', 'city' => 'CityX', 'street' => ['Black str, 48'], 'lastname' => 'Smith', 'firstname' => 'John', + 'vat_id' => 12345, 'address_type' => 'shipping', 'email' => 'some_email@mail.com', - 'region_id' => 1, ]; $billingAddress = $objectManager->create( @@ -66,6 +66,7 @@ $quote->setCustomerIsGuest(true) ->setStoreId($store->getId()) ->setReservedOrderId('guest_quote') + ->setCheckoutMethod('guest') ->setBillingAddress($billingAddress) ->setShippingAddress($shippingAddress) ->addProduct($product); From ac843d37b7a9878f124f50c209a24aca997e40fd Mon Sep 17 00:00:00 2001 From: engcom-Kilo <mikola.malevanec@transoftgroup.com> Date: Wed, 7 Oct 2020 09:53:38 +0300 Subject: [PATCH 16/20] MC-37666: Incorrect Customer TAX Class saved with Quote when VAT Validation used on Guest orders. Fix unit test. --- .../Quote/Test/Unit/Model/QuoteManagementTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php index ea758f7ce34f3..4197af2f2848a 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php @@ -247,6 +247,7 @@ protected function setUp(): void 'getPayment', 'setCheckoutMethod', 'setCustomerIsGuest', + 'getCustomer', 'getId' ] ) @@ -799,6 +800,12 @@ public function testPlaceOrderIfCustomerIsGuest() $this->quoteMock->expects($this->once()) ->method('getCheckoutMethod') ->willReturn(Onepage::METHOD_GUEST); + $customerMock = $this->getMockBuilder(Customer::class) + ->disableOriginalConstructor() + ->getMock(); + $this->quoteMock->expects($this->once()) + ->method('getCustomer') + ->willReturn($customerMock); $this->quoteMock->expects($this->once())->method('setCustomerId')->with(null)->willReturnSelf(); $this->quoteMock->expects($this->once())->method('setCustomerEmail')->with($email)->willReturnSelf(); @@ -866,6 +873,9 @@ public function testPlaceOrderIfCustomerIsGuest() $this->assertEquals($orderId, $service->placeOrder($cartId)); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testPlaceOrder() { $cartId = 323; From 5929940c2e47cd30fd55c7f4a7ed30c294beb726 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Wed, 7 Oct 2020 16:16:52 +0300 Subject: [PATCH 17/20] MC-24010: Broken integration test RelationTest.php on mainline 2.3 --- .../Product/Flat/Action/RelationTest.php | 102 +++++++++++------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RelationTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RelationTest.php index e3b5bc8d5fd0d..745f71801352b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RelationTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RelationTest.php @@ -11,7 +11,12 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Store\Model\StoreManagerInterface; -use Magento\TestFramework\Catalog\Model\Indexer\Product\Flat\Action\Full as FlatIndexerFull; +use Magento\Catalog\Model\Indexer\Product\Flat\Action\Full as FlatIndexerFull; +use Magento\Catalog\Helper\Product\Flat\Indexer; +use Magento\Catalog\Model\Indexer\Product\Flat\TableBuilder; +use Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder; +use Magento\Framework\Exception\LocalizedException; +use Magento\TestFramework\Helper\Bootstrap; /** * Test relation customization @@ -42,33 +47,79 @@ class RelationTest extends \Magento\TestFramework\Indexer\TestCase */ private $flatUpdated = []; + /** + * @var Indexer + */ + private $productIndexerHelper; + /** * @inheritdoc */ protected function setUp(): void { - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); - $tableBuilderMock = $this->createMock(\Magento\Catalog\Model\Indexer\Product\Flat\TableBuilder::class); - $flatTableBuilderMock = $this->createMock(\Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder::class); + $tableBuilderMock = $objectManager->get(TableBuilder::class); + $flatTableBuilderMock = + $objectManager->get(FlatTableBuilder::class); - $productIndexerHelper = $objectManager->create( - \Magento\Catalog\Helper\Product\Flat\Indexer::class, - ['addChildData' => 1] + $this->productIndexerHelper = $objectManager->create( + Indexer::class, + ['addChildData' => true] ); $this->indexer = $objectManager->create( FlatIndexerFull::class, [ - 'productHelper' => $productIndexerHelper, + 'productHelper' => $this->productIndexerHelper, 'tableBuilder' => $tableBuilderMock, 'flatTableBuilder' => $flatTableBuilderMock ] ); - $this->storeManager = $objectManager->create(StoreManagerInterface::class); + $this->storeManager = $objectManager->get(StoreManagerInterface::class); $this->connection = $objectManager->get(ResourceConnection::class)->getConnection(); + } + + /** + * @inheritdoc + */ + protected function tearDown(): void + { + foreach ($this->flatUpdated as $flatTable) { + $this->connection->dropColumn($flatTable, 'child_id'); + $this->connection->dropColumn($flatTable, 'is_child'); + } + } + + /** + * Test that SQL generated for relation customization is valid + * + * @return void + * @throws LocalizedException + * @throws \Exception + */ + public function testExecute() : void + { + $this->addChildColumns(); + try { + $result = $this->indexer->execute(); + } catch (LocalizedException $e) { + if ($e->getPrevious() instanceof \Zend_Db_Statement_Exception) { + $this->fail($e->getMessage()); + } + throw $e; + } + $this->assertInstanceOf(FlatIndexerFull::class, $result); + } + /** + * Add child columns to tables if needed + * + * @return void + */ + private function addChildColumns(): void + { foreach ($this->storeManager->getStores() as $store) { - $flatTable = $productIndexerHelper->getFlatTableName($store->getId()); + $flatTable = $this->productIndexerHelper->getFlatTableName($store->getId()); if ($this->connection->isTableExists($flatTable) && !$this->connection->tableColumnExists($flatTable, 'child_id') && !$this->connection->tableColumnExists($flatTable, 'is_child') @@ -103,35 +154,4 @@ protected function setUp(): void } } } - - /** - * @inheritdoc - */ - protected function tearDown(): void - { - foreach ($this->flatUpdated as $flatTable) { - $this->connection->dropColumn($flatTable, 'child_id'); - $this->connection->dropColumn($flatTable, 'is_child'); - } - } - - /** - * Test that SQL generated for relation customization is valid - * - * @return void - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Exception - */ - public function testExecute() : void - { - $this->markTestSkipped('MC-19675'); - try { - $this->indexer->execute(); - } catch (\Magento\Framework\Exception\LocalizedException $e) { - if ($e->getPrevious() instanceof \Zend_Db_Statement_Exception) { - $this->fail($e->getMessage()); - } - throw $e; - } - } } From 7394a5af99f7f44348d364dd5d08504b3b01995c Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Thu, 8 Oct 2020 10:16:05 +0300 Subject: [PATCH 18/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- .../Catalog/Model/Product/Option/Value.php | 6 +- .../Unit/Model/Product/Option/ValueTest.php | 5 +- ...SimpleProductWithSelectFixedMethodTest.xml | 38 ++++++------- ...ForSimpleProductsWithCustomOptionsTest.xml | 55 ++++++++++--------- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Option/Value.php b/app/code/Magento/Catalog/Model/Product/Option/Value.php index 638eaca328ff5..12b418c33deec 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Value.php @@ -84,7 +84,7 @@ class Value extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCu * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data * @param CustomOptionPriceCalculator|null $customOptionPriceCalculator - * @param CalculateCustomOptionCatalogRule|null $CalculateCustomOptionCatalogRule + * @param CalculateCustomOptionCatalogRule|null $calculateCustomOptionCatalogRule */ public function __construct( \Magento\Framework\Model\Context $context, @@ -94,12 +94,12 @@ public function __construct( \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], CustomOptionPriceCalculator $customOptionPriceCalculator = null, - CalculateCustomOptionCatalogRule $CalculateCustomOptionCatalogRule = null + CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null ) { $this->_valueCollectionFactory = $valueCollectionFactory; $this->customOptionPriceCalculator = $customOptionPriceCalculator ?? ObjectManager::getInstance()->get(CustomOptionPriceCalculator::class); - $this->calculateCustomOptionCatalogRule = $CalculateCustomOptionCatalogRule + $this->calculateCustomOptionCatalogRule = $calculateCustomOptionCatalogRule ?? ObjectManager::getInstance()->get(CalculateCustomOptionCatalogRule::class); parent::__construct( diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php index e084a8cbbde27..d4c1db4ec1b28 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php @@ -34,6 +34,9 @@ class ValueTest extends TestCase */ private $calculateCustomOptionCatalogRule; + /** + * @inheritDoc + */ protected function setUp(): void { $mockedResource = $this->getMockedResource(); @@ -49,7 +52,7 @@ protected function setUp(): void [ 'resource' => $mockedResource, 'valueCollectionFactory' => $mockedCollectionFactory, - 'CalculateCustomOptionCatalogRule' => $this->calculateCustomOptionCatalogRule + 'calculateCustomOptionCatalogRule' => $this->calculateCustomOptionCatalogRule ] ); $this->model->setOption($this->getMockedOption()); diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml index cb1e20aa2b227..e96526c5cd256 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml @@ -14,7 +14,7 @@ <title value="Admin should be able to apply the catalog price rule for simple product with custom options"/> <description value="Admin should be able to apply the catalog price rule for simple product with custom options"/> <severity value="CRITICAL"/> - <testCaseId value="MC-14771"/> + <testCaseId value="MC-28347"/> <group value="catalogRule"/> <group value="mtf_migrated"/> <group value="catalog"/> @@ -24,13 +24,13 @@ <createData entity="_defaultCategory" stepKey="createCategory"/> <!-- Create Simple Product --> - <createData entity="_defaultProduct" stepKey="createProduct1"> + <createData entity="_defaultProduct" stepKey="createProduct"> <requiredEntity createDataKey="createCategory"/> <field key="price">56.78</field> </createData> <!-- Update all products to have custom options --> - <updateData createDataKey="createProduct1" entity="productWithFixedOptions" stepKey="updateFirstProductWithOptions"/> + <updateData createDataKey="createProduct" entity="productWithFixedOptions" stepKey="updateProductWithOptions"/> <!-- Login as Admin --> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> @@ -43,7 +43,7 @@ </before> <after> <!-- Delete products and category --> - <deleteData createDataKey="createProduct1" stepKey="deleteProduct1"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <!-- Delete the catalog price rule --> @@ -52,11 +52,11 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> </after> <!-- 1. Begin creating a new catalog price rule --> - <actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="startCreatingFirstPriceRule"/> - <actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForFirstPriceRule"> + <actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="openNewCatalogPriceRulePage"/> + <actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForCatalogPriceRule"> <argument name="groups" value="'NOT LOGGED IN'"/> </actionGroup> - <actionGroup ref="AdminFillCatalogRuleConditionActionGroup" stepKey="createCatalogPriceRule"> + <actionGroup ref="AdminFillCatalogRuleConditionActionGroup" stepKey="fillConditionsForCatalogPriceRule"> <argument name="conditionValue" value="$createCategory.id$"/> </actionGroup> <actionGroup ref="AdminCatalogPriceRuleFillActionsActionGroup" stepKey="fillActionsForCatalogPriceRule"> @@ -70,31 +70,31 @@ <argument name="category" value="$createCategory$"/> </actionGroup> - <!-- Check product 1 name on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1Name"> - <argument name="productInfo" value="$createProduct1.name$"/> + <!-- Check product name on store front category page --> + <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="assertStorefrontProductName"> + <argument name="productInfo" value="$createProduct.name$"/> <argument name="productNumber" value="1"/> </actionGroup> - <!-- Check product 1 price on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1Price"> + <!-- Check product price on store front category page --> + <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="assertStorefrontProductPrice"> <argument name="productInfo" value="$44.48"/> <argument name="productNumber" value="1"/> </actionGroup> - <!-- Check product 1 regular price on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1RegularPrice"> + <!-- Check product regular price on store front category page --> + <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="assertStorefrontProductRegularPrice"> <argument name="productInfo" value="$56.78"/> <argument name="productNumber" value="1"/> </actionGroup> <!-- Navigate to product on store front --> - <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage1"> - <argument name="productUrlKey" value="$createProduct1.custom_attributes[url_key]$"/> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage"> + <argument name="productUrlKey" value="$createProduct.custom_attributes[url_key]$"/> </actionGroup> <!-- Assert regular and special price after selecting ProductOptionValueDropdown1 --> - <actionGroup ref="StorefrontSelectCustomOptionRadioAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices1"> + <actionGroup ref="StorefrontSelectCustomOptionRadioAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices"> <argument name="customOption" value="ProductOptionRadioButton2"/> <argument name="customOptionValue" value="ProductOptionValueRadioButtons1"/> <argument name="productPrice" value="$156.77"/> @@ -102,8 +102,8 @@ </actionGroup> <!-- Add product 1 to cart --> - <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage1"> - <argument name="productName" value="$createProduct1.name$"/> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage"> + <argument name="productName" value="$createProduct.name$"/> </actionGroup> <!-- Assert sub total on mini shopping cart --> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml index 4cfbae45b4dcc..92567c38ca152 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml @@ -14,13 +14,12 @@ <title value="Admin should be able to apply the catalog price rule for simple product with 3 custom options"/> <description value="Admin should be able to apply the catalog price rule for simple product with 3 custom options"/> <severity value="CRITICAL"/> - <testCaseId value="MC-14769"/> + <testCaseId value="MC-28345"/> <group value="catalogRule"/> <group value="mtf_migrated"/> <group value="catalog"/> </annotations> <before> - <!-- Login as Admin --> <createData entity="_defaultCategory" stepKey="createCategory"/> <createData entity="_defaultProduct" stepKey="createProduct1"> <requiredEntity createDataKey="createCategory"/> @@ -36,10 +35,14 @@ </createData> <!-- Update all products to have custom options --> - <updateData createDataKey="createProduct1" entity="productWithCustomOptions" stepKey="updateProductWithOptions1"/> - <updateData createDataKey="createProduct2" entity="productWithCustomOptions" stepKey="updateProductWithOptions2"/> - <updateData createDataKey="createProduct3" entity="productWithCustomOptions" stepKey="updateProductWithOptions3"/> + <updateData createDataKey="createProduct1" entity="productWithCustomOptions" stepKey="updateProduc1tWithOptions"/> + <updateData createDataKey="createProduct2" entity="productWithCustomOptions" stepKey="updateProduct2WithOptions"/> + <updateData createDataKey="createProduct3" entity="productWithCustomOptions" stepKey="updateProduct3WithOptions"/> + + <!-- Login as Admin --> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + + <!-- Clear all catalog price rules before test --> <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesBeforeTest"/> </before> <after> @@ -54,14 +57,14 @@ <magentoCron groups="index" stepKey="fixInvalidatedIndices"/> <!-- Logout --> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> </after> <!-- 1. Begin creating a new catalog price rule --> - <actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="startCreatingFirstPriceRule"/> - <actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForFirstPriceRule"> + <actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="openNewCatalogPriceRulePage"/> + <actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForCatalogPriceRule"> <argument name="groups" value="'NOT LOGGED IN'"/> </actionGroup> - <actionGroup ref="AdminFillCatalogRuleConditionActionGroup" stepKey="createCatalogPriceRule"> + <actionGroup ref="AdminFillCatalogRuleConditionActionGroup" stepKey="fillConditionsForCatalogPriceRule"> <argument name="conditionValue" value="$createCategory.id$"/> </actionGroup> <actionGroup ref="AdminCatalogPriceRuleFillActionsActionGroup" stepKey="fillActionsForCatalogPriceRule"> @@ -76,86 +79,86 @@ </actionGroup> <!-- Check product 1 price on store front category page --> - <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct1Price"> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="assertStorefrontProduct1Price"> <argument name="productName" value="$createProduct1.name$"/> <argument name="productPrice" value="$51.10"/> </actionGroup> <!-- Check product 1 regular price on store front category page --> - <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct1RegularPrice"> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="assertStorefrontProduct1RegularPrice"> <argument name="productName" value="$createProduct1.name$"/> <argument name="productPrice" value="$56.78"/> </actionGroup> <!-- Check product 2 price on store front category page --> - <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct2Price"> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="assertStorefrontProduct2Price"> <argument name="productName" value="$createProduct2.name$"/> <argument name="productPrice" value="$51.10"/> </actionGroup> <!-- Check product 2 regular price on store front category page --> - <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct2RegularPrice"> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="assertStorefrontProduct2RegularPrice"> <argument name="productName" value="$createProduct2.name$"/> <argument name="productPrice" value="$56.78"/> </actionGroup> <!-- Check product 3 price on store front category page --> - <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct3Price"> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="assertStorefrontProduct3Price"> <argument name="productName" value="$createProduct3.name$"/> <argument name="productPrice" value="$51.10"/> </actionGroup> <!-- Check product 3 regular price on store front category page --> - <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="storefrontProduct3RegularPrice"> + <actionGroup ref="StorefrontAssertProductPriceOnCategoryPageActionGroup" stepKey="assertStorefrontProduct3RegularPrice"> <argument name="productName" value="$createProduct3.name$"/> <argument name="productPrice" value="$56.78"/> </actionGroup> <!-- Navigate to product 1 on store front --> - <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage1"> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProduct1Page"> <argument name="productUrlKey" value="$createProduct1.custom_attributes[url_key]$"/> </actionGroup> - <!-- Assert regular and special price after selecting ProductOptionValueDropdown1 --> - <actionGroup ref="StorefrontSelectCustomOptionDropDownAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices1"> + <!-- Assert regular and special price for product 1 after selecting ProductOptionValueDropdown1 --> + <actionGroup ref="StorefrontSelectCustomOptionDropDownAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertProduct1Prices"> <argument name="customOption" value="{{ProductOptionValueDropdown1.title}} +$0.01"/> <argument name="productPrice" value="$56.79"/> <argument name="productFinalPrice" value="$51.11"/> </actionGroup> <!-- Add product 1 to cart --> - <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage1"> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProduct1Page"> <argument name="productName" value="$createProduct1.name$"/> </actionGroup> <!-- Navigate to product 2 on store front --> - <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage2"> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProduct2Page"> <argument name="productUrlKey" value="$createProduct2.custom_attributes[url_key]$"/> </actionGroup> - <!-- Assert regular and special price after selecting ProductOptionValueDropdown3 --> - <actionGroup ref="StorefrontSelectCustomOptionDropDownAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertPrices2"> + <!-- Assert regular and special price for product 2 after selecting ProductOptionValueDropdown3 --> + <actionGroup ref="StorefrontSelectCustomOptionDropDownAndAssertPricesActionGroup" stepKey="storefrontSelectCustomOptionAndAssertProduct2Prices"> <argument name="customOption" value="{{ProductOptionValueDropdown3.title}} +$5.11"/> <argument name="productPrice" value="$62.46"/> <argument name="productFinalPrice" value="$56.21"/> </actionGroup> <!-- Add product 2 to cart --> - <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage2"> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProduct2Page"> <argument name="productName" value="$createProduct2.name$"/> </actionGroup> <!-- Navigate to product 3 on store front --> - <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProductPage3"> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="goToProduct3Page"> <argument name="productUrlKey" value="$createProduct3.custom_attributes[url_key]$"/> </actionGroup> <!-- Add product 3 to cart with no custom option --> - <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage3"> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProduct3Page"> <argument name="productName" value="$createProduct3.name$"/> </actionGroup> - <!-- Assert sub total on mini shopping cart --> + <!-- Assert subtotal on mini shopping cart --> <actionGroup ref="AssertSubTotalOnStorefrontMiniCartActionGroup" stepKey="assertSubTotalOnStorefrontMiniCart"> <argument name="subTotal" value="$158.42"/> </actionGroup> From e8a3261dc87e748f49eef9ac774bc7b960e22ac5 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Thu, 8 Oct 2020 14:14:40 +0300 Subject: [PATCH 19/20] MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page --- ...yCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml | 5 ++--- ...pplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml index e96526c5cd256..c127f19db3749 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductWithSelectFixedMethodTest.xml @@ -37,9 +37,7 @@ <!-- Clear all catalog price rules and reindex before test --> <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesBeforeTest"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <magentoCron groups="index" stepKey="fixInvalidatedIndicesBeforeTest"/> </before> <after> <!-- Delete products and category --> @@ -48,6 +46,7 @@ <!-- Delete the catalog price rule --> <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesAfterTest"/> + <magentoCron groups="index" stepKey="fixInvalidatedIndicesAfter"/> <!-- Logout --> <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> </after> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml index 92567c38ca152..a616a7ab172f1 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml @@ -44,6 +44,7 @@ <!-- Clear all catalog price rules before test --> <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesBeforeTest"/> + <magentoCron groups="index" stepKey="fixInvalidatedIndicesBeforeTest"/> </before> <after> <!-- Delete products and category --> @@ -54,7 +55,7 @@ <!-- Delete the catalog price rule --> <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogRulesAfterTest"/> - <magentoCron groups="index" stepKey="fixInvalidatedIndices"/> + <magentoCron groups="index" stepKey="fixInvalidatedIndicesAfterTest"/> <!-- Logout --> <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> From 223388d5712478a24f42cdb07b7fc011b67dfdc2 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Thu, 8 Oct 2020 14:58:54 +0300 Subject: [PATCH 20/20] MC-24010: Broken integration test RelationTest.php on mainline 2.3 --- .../Indexer/Product/Flat/Action/Full.php | 22 ------------------- .../Product/Flat/Action/RelationTest.php | 14 +++--------- 2 files changed, 3 insertions(+), 33 deletions(-) delete mode 100644 dev/tests/integration/framework/Magento/TestFramework/Catalog/Model/Indexer/Product/Flat/Action/Full.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Catalog/Model/Indexer/Product/Flat/Action/Full.php b/dev/tests/integration/framework/Magento/TestFramework/Catalog/Model/Indexer/Product/Flat/Action/Full.php deleted file mode 100644 index 17ffb5cf2748a..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/Catalog/Model/Indexer/Product/Flat/Action/Full.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\TestFramework\Catalog\Model\Indexer\Product\Flat\Action; - -/** - * Class Full reindex action - */ -class Full extends \Magento\Catalog\Model\Indexer\Product\Flat\Action\Full -{ - /** - * List of product types available in installation - * - * @var array - */ - protected $_productTypes; -} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RelationTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RelationTest.php index 745f71801352b..c9ad7ad720daa 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RelationTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RelationTest.php @@ -13,8 +13,6 @@ use Magento\Store\Model\StoreManagerInterface; use Magento\Catalog\Model\Indexer\Product\Flat\Action\Full as FlatIndexerFull; use Magento\Catalog\Helper\Product\Flat\Indexer; -use Magento\Catalog\Model\Indexer\Product\Flat\TableBuilder; -use Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder; use Magento\Framework\Exception\LocalizedException; use Magento\TestFramework\Helper\Bootstrap; @@ -59,10 +57,6 @@ protected function setUp(): void { $objectManager = Bootstrap::getObjectManager(); - $tableBuilderMock = $objectManager->get(TableBuilder::class); - $flatTableBuilderMock = - $objectManager->get(FlatTableBuilder::class); - $this->productIndexerHelper = $objectManager->create( Indexer::class, ['addChildData' => true] @@ -71,8 +65,6 @@ protected function setUp(): void FlatIndexerFull::class, [ 'productHelper' => $this->productIndexerHelper, - 'tableBuilder' => $tableBuilderMock, - 'flatTableBuilder' => $flatTableBuilderMock ] ); $this->storeManager = $objectManager->get(StoreManagerInterface::class); @@ -120,9 +112,9 @@ private function addChildColumns(): void { foreach ($this->storeManager->getStores() as $store) { $flatTable = $this->productIndexerHelper->getFlatTableName($store->getId()); - if ($this->connection->isTableExists($flatTable) && - !$this->connection->tableColumnExists($flatTable, 'child_id') && - !$this->connection->tableColumnExists($flatTable, 'is_child') + if ($this->connection->isTableExists($flatTable) + && !$this->connection->tableColumnExists($flatTable, 'child_id') + && !$this->connection->tableColumnExists($flatTable, 'is_child') ) { $this->connection->addColumn( $flatTable,