Skip to content

Commit 0895d21

Browse files
ENGCOM-5122: #22856: Catalog price rules are not working with custom options as expected. #22917
- Merge Pull Request #22917 from p-bystritsky/magento2:ISSUE-22856 - Merged commits: 1. a8f3b9e 2. 4fb5da8 3. 56142ae 4. 7489207 5. 20ae9e3 6. 8b159d0 7. 4ac980b 8. fbea751
2 parents 34ef309 + fbea751 commit 0895d21

File tree

19 files changed

+775
-196
lines changed

19 files changed

+775
-196
lines changed

app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,14 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6-
7-
/**
8-
* Product options abstract type block
9-
*
10-
* @author Magento Core Team <core@magentocommerce.com>
11-
*/
6+
declare(strict_types=1);
127

138
namespace Magento\Catalog\Block\Product\View\Options;
149

10+
use Magento\Catalog\Pricing\Price\BasePrice;
11+
use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule;
1512
use Magento\Catalog\Pricing\Price\CustomOptionPriceInterface;
13+
use Magento\Framework\App\ObjectManager;
1614

1715
/**
1816
* Product options section abstract block.
@@ -47,20 +45,29 @@ abstract class AbstractOptions extends \Magento\Framework\View\Element\Template
4745
*/
4846
protected $_catalogHelper;
4947

48+
/**
49+
* @var CalculateCustomOptionCatalogRule
50+
*/
51+
private $calculateCustomOptionCatalogRule;
52+
5053
/**
5154
* @param \Magento\Framework\View\Element\Template\Context $context
5255
* @param \Magento\Framework\Pricing\Helper\Data $pricingHelper
5356
* @param \Magento\Catalog\Helper\Data $catalogData
5457
* @param array $data
58+
* @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule
5559
*/
5660
public function __construct(
5761
\Magento\Framework\View\Element\Template\Context $context,
5862
\Magento\Framework\Pricing\Helper\Data $pricingHelper,
5963
\Magento\Catalog\Helper\Data $catalogData,
60-
array $data = []
64+
array $data = [],
65+
CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null
6166
) {
6267
$this->pricingHelper = $pricingHelper;
6368
$this->_catalogHelper = $catalogData;
69+
$this->calculateCustomOptionCatalogRule = $calculateCustomOptionCatalogRule
70+
?? ObjectManager::getInstance()->get(CalculateCustomOptionCatalogRule::class);
6471
parent::__construct($context, $data);
6572
}
6673

@@ -161,6 +168,15 @@ protected function _formatPrice($value, $flag = true)
161168
$priceStr = $sign;
162169

163170
$customOptionPrice = $this->getProduct()->getPriceInfo()->getPrice('custom_option_price');
171+
172+
if (!$value['is_percent']) {
173+
$value['pricing_value'] = $this->calculateCustomOptionCatalogRule->execute(
174+
$this->getProduct(),
175+
(float)$value['pricing_value'],
176+
(bool)$value['is_percent']
177+
);
178+
}
179+
164180
$context = [CustomOptionPriceInterface::CONFIGURATION_OPTION_FLAG => true];
165181
$optionAmount = $customOptionPrice->getCustomAmount($value['pricing_value'], null, $context);
166182
$priceStr .= $this->getLayout()->getBlock('product.price.render.default')->renderAmount(

app/code/Magento/Catalog/Model/Product/Option.php

Lines changed: 43 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Catalog\Model\Product;
89

@@ -16,8 +17,10 @@
1617
use Magento\Catalog\Model\Product\Option\Type\File;
1718
use Magento\Catalog\Model\Product\Option\Type\Select;
1819
use Magento\Catalog\Model\Product\Option\Type\Text;
20+
use Magento\Catalog\Model\Product\Option\Value;
1921
use Magento\Catalog\Model\ResourceModel\Product\Option\Value\Collection;
20-
use Magento\Catalog\Pricing\Price\BasePrice;
22+
use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule;
23+
use Magento\Framework\App\ObjectManager;
2124
use Magento\Framework\EntityManager\MetadataPool;
2225
use Magento\Framework\Exception\LocalizedException;
2326
use Magento\Framework\Model\AbstractExtensibleModel;
@@ -123,6 +126,11 @@ class Option extends AbstractExtensibleModel implements ProductCustomOptionInter
123126
*/
124127
private $customOptionValuesFactory;
125128

129+
/**
130+
* @var CalculateCustomOptionCatalogRule
131+
*/
132+
private $calculateCustomOptionCatalogRule;
133+
126134
/**
127135
* @param \Magento\Framework\Model\Context $context
128136
* @param \Magento\Framework\Registry $registry
@@ -138,6 +146,7 @@ class Option extends AbstractExtensibleModel implements ProductCustomOptionInter
138146
* @param ProductCustomOptionValuesInterfaceFactory|null $customOptionValuesFactory
139147
* @param array $optionGroups
140148
* @param array $optionTypesToGroups
149+
* @param CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule
141150
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
142151
*/
143152
public function __construct(
@@ -154,14 +163,17 @@ public function __construct(
154163
array $data = [],
155164
ProductCustomOptionValuesInterfaceFactory $customOptionValuesFactory = null,
156165
array $optionGroups = [],
157-
array $optionTypesToGroups = []
166+
array $optionTypesToGroups = [],
167+
CalculateCustomOptionCatalogRule $calculateCustomOptionCatalogRule = null
158168
) {
159169
$this->productOptionValue = $productOptionValue;
160170
$this->optionTypeFactory = $optionFactory;
161171
$this->string = $string;
162172
$this->validatorPool = $validatorPool;
163173
$this->customOptionValuesFactory = $customOptionValuesFactory ?:
164-
\Magento\Framework\App\ObjectManager::getInstance()->get(ProductCustomOptionValuesInterfaceFactory::class);
174+
ObjectManager::getInstance()->get(ProductCustomOptionValuesInterfaceFactory::class);
175+
$this->calculateCustomOptionCatalogRule = $calculateCustomOptionCatalogRule ??
176+
ObjectManager::getInstance()->get(CalculateCustomOptionCatalogRule::class);
165177
$this->optionGroups = $optionGroups ?: [
166178
self::OPTION_GROUP_DATE => Date::class,
167179
self::OPTION_GROUP_FILE => File::class,
@@ -193,10 +205,7 @@ public function __construct(
193205
}
194206

195207
/**
196-
* Get resource instance
197-
*
198-
* @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
199-
* @deprecated 101.1.0 because resource models should be used directly
208+
* @inheritdoc
200209
*/
201210
protected function _getResource()
202211
{
@@ -462,10 +471,12 @@ public function afterSave()
462471
*/
463472
public function getPrice($flag = false)
464473
{
465-
if ($flag && $this->getPriceType() == self::$typePercent) {
466-
$basePrice = $this->getProduct()->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getValue();
467-
$price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100);
468-
return $price;
474+
if ($flag) {
475+
return $this->calculateCustomOptionCatalogRule->execute(
476+
$this->getProduct(),
477+
(float)$this->getData(self::KEY_PRICE),
478+
$this->getPriceType() === Value::TYPE_PERCENT
479+
);
469480
}
470481
return $this->_getData(self::KEY_PRICE);
471482
}
@@ -559,9 +570,7 @@ public function getSearchableData($productId, $storeId)
559570
}
560571

561572
/**
562-
* Clearing object's data
563-
*
564-
* @return $this
573+
* @inheritdoc
565574
*/
566575
protected function _clearData()
567576
{
@@ -571,9 +580,7 @@ protected function _clearData()
571580
}
572581

573582
/**
574-
* Clearing cyclic references
575-
*
576-
* @return $this
583+
* @inheritdoc
577584
*/
578585
protected function _clearReferences()
579586
{
@@ -594,9 +601,7 @@ protected function _getValidationRulesBeforeSave()
594601
}
595602

596603
/**
597-
* Get product SKU
598-
*
599-
* @return string
604+
* @inheritdoc
600605
*/
601606
public function getProductSku()
602607
{
@@ -608,9 +613,7 @@ public function getProductSku()
608613
}
609614

610615
/**
611-
* Get option id
612-
*
613-
* @return int|null
616+
* @inheritdoc
614617
* @codeCoverageIgnoreStart
615618
*/
616619
public function getOptionId()
@@ -619,60 +622,47 @@ public function getOptionId()
619622
}
620623

621624
/**
622-
* Get option title
623-
*
624-
* @return string
625+
* @inheritdoc
625626
*/
626627
public function getTitle()
627628
{
628629
return $this->_getData(self::KEY_TITLE);
629630
}
630631

631632
/**
632-
* Get option type
633-
*
634-
* @return string
633+
* @inheritdoc
635634
*/
636635
public function getType()
637636
{
638637
return $this->_getData(self::KEY_TYPE);
639638
}
640639

641640
/**
642-
* Get sort order
643-
*
644-
* @return int
641+
* @inheritdoc
645642
*/
646643
public function getSortOrder()
647644
{
648645
return $this->_getData(self::KEY_SORT_ORDER);
649646
}
650647

651648
/**
652-
* Get is require
653-
*
654-
* @return bool
655-
* @SuppressWarnings(PHPMD.BooleanGetMethodName)
649+
* @inheritdoc
656650
*/
657651
public function getIsRequire()
658652
{
659653
return $this->_getData(self::KEY_IS_REQUIRE);
660654
}
661655

662656
/**
663-
* Get price type
664-
*
665-
* @return string|null
657+
* @inheritdoc
666658
*/
667659
public function getPriceType()
668660
{
669661
return $this->_getData(self::KEY_PRICE_TYPE);
670662
}
671663

672664
/**
673-
* Get Sku
674-
*
675-
* @return string|null
665+
* @inheritdoc
676666
*/
677667
public function getSku()
678668
{
@@ -720,98 +710,71 @@ public function getImageSizeY()
720710
}
721711

722712
/**
723-
* Set product SKU
724-
*
725-
* @param string $productSku
726-
* @return $this
713+
* @inheritdoc
727714
*/
728715
public function setProductSku($productSku)
729716
{
730717
return $this->setData(self::KEY_PRODUCT_SKU, $productSku);
731718
}
732719

733720
/**
734-
* Set option id
735-
*
736-
* @param int $optionId
737-
* @return $this
721+
* @inheritdoc
738722
*/
739723
public function setOptionId($optionId)
740724
{
741725
return $this->setData(self::KEY_OPTION_ID, $optionId);
742726
}
743727

744728
/**
745-
* Set option title
746-
*
747-
* @param string $title
748-
* @return $this
729+
* @inheritdoc
749730
*/
750731
public function setTitle($title)
751732
{
752733
return $this->setData(self::KEY_TITLE, $title);
753734
}
754735

755736
/**
756-
* Set option type
757-
*
758-
* @param string $type
759-
* @return $this
737+
* @inheritdoc
760738
*/
761739
public function setType($type)
762740
{
763741
return $this->setData(self::KEY_TYPE, $type);
764742
}
765743

766744
/**
767-
* Set sort order
768-
*
769-
* @param int $sortOrder
770-
* @return $this
745+
* @inheritdoc
771746
*/
772747
public function setSortOrder($sortOrder)
773748
{
774749
return $this->setData(self::KEY_SORT_ORDER, $sortOrder);
775750
}
776751

777752
/**
778-
* Set is require
779-
*
780-
* @param bool $isRequired
781-
* @return $this
753+
* @inheritdoc
782754
*/
783755
public function setIsRequire($isRequired)
784756
{
785757
return $this->setData(self::KEY_IS_REQUIRE, $isRequired);
786758
}
787759

788760
/**
789-
* Set price
790-
*
791-
* @param float $price
792-
* @return $this
761+
* @inheritdoc
793762
*/
794763
public function setPrice($price)
795764
{
796765
return $this->setData(self::KEY_PRICE, $price);
797766
}
798767

799768
/**
800-
* Set price type
801-
*
802-
* @param string $priceType
803-
* @return $this
769+
* @inheritdoc
804770
*/
805771
public function setPriceType($priceType)
806772
{
807773
return $this->setData(self::KEY_PRICE_TYPE, $priceType);
808774
}
809775

810776
/**
811-
* Set Sku
812-
*
813-
* @param string $sku
814-
* @return $this
777+
* @inheritdoc
815778
*/
816779
public function setSku($sku)
817780
{
@@ -952,7 +915,7 @@ public function setExtensionAttributes(
952915
private function getOptionRepository()
953916
{
954917
if (null === $this->optionRepository) {
955-
$this->optionRepository = \Magento\Framework\App\ObjectManager::getInstance()
918+
$this->optionRepository = ObjectManager::getInstance()
956919
->get(\Magento\Catalog\Model\Product\Option\Repository::class);
957920
}
958921
return $this->optionRepository;
@@ -966,7 +929,7 @@ private function getOptionRepository()
966929
private function getMetadataPool()
967930
{
968931
if (null === $this->metadataPool) {
969-
$this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance()
932+
$this->metadataPool = ObjectManager::getInstance()
970933
->get(\Magento\Framework\EntityManager\MetadataPool::class);
971934
}
972935
return $this->metadataPool;

0 commit comments

Comments
 (0)