123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Catalog\Pricing\Price;
- use Magento\Catalog\Model\Product\Option\Value;
- use Magento\Catalog\Pricing\Price;
- use Magento\Framework\Pricing\Price\AbstractPrice;
- use Magento\Framework\Pricing\SaleableInterface;
- use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
- use Magento\Framework\Pricing\Amount\AmountInterface;
- /**
- * Class OptionPrice
- *
- */
- class CustomOptionPrice extends AbstractPrice implements CustomOptionPriceInterface
- {
- /**
- * Price model code
- */
- const PRICE_CODE = 'custom_option_price';
- /**
- * @var array
- */
- protected $priceOptions;
- /**
- * Code of parent adjustment to be skipped from calculation
- *
- * @var string
- */
- protected $excludeAdjustment = null;
- /**
- * @var CustomOptionPriceCalculator
- */
- private $customOptionPriceCalculator;
- /**
- * @param SaleableInterface $saleableItem
- * @param float $quantity
- * @param CalculatorInterface $calculator
- * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
- * @param array|null $excludeAdjustment
- * @param CustomOptionPriceCalculator|null $customOptionPriceCalculator
- */
- public function __construct(
- SaleableInterface $saleableItem,
- $quantity,
- CalculatorInterface $calculator,
- \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
- $excludeAdjustment = null,
- CustomOptionPriceCalculator $customOptionPriceCalculator = null
- ) {
- parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency);
- $this->excludeAdjustment = $excludeAdjustment;
- $this->customOptionPriceCalculator = $customOptionPriceCalculator
- ?? \Magento\Framework\App\ObjectManager::getInstance()->get(CustomOptionPriceCalculator::class);
- }
- /**
- * Get minimal and maximal option values.
- *
- * @param string $priceCode
- * @return array
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- public function getValue($priceCode = \Magento\Catalog\Pricing\Price\BasePrice::PRICE_CODE)
- {
- $optionValues = [];
- $options = $this->product->getOptions();
- if ($options) {
- /** @var $optionItem \Magento\Catalog\Model\Product\Option */
- foreach ($options as $optionItem) {
- $min = null;
- if (!$optionItem->getIsRequire()) {
- $min = 0.;
- }
- $max = 0.;
- if ($optionItem->getValues() === null && $optionItem->getPrice() !== null) {
- $price = $optionItem->getPrice($optionItem->getPriceType() == Value::TYPE_PERCENT);
- if ($min === null) {
- $min = $price;
- } elseif ($price < $min) {
- $min = $price;
- }
- if ($price > $max) {
- $max = $price;
- }
- } else {
- /** @var $optionValue \Magento\Catalog\Model\Product\Option\Value */
- foreach ($optionItem->getValues() as $optionValue) {
- $price =
- $this->customOptionPriceCalculator->getOptionPriceByPriceCode($optionValue, $priceCode);
- if ($min === null) {
- $min = $price;
- } elseif ($price < $min) {
- $min = $price;
- }
- $type = $optionItem->getType();
- if ($type == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX ||
- $type == \Magento\Catalog\Api\Data\ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE
- ) {
- $max += $price;
- } elseif ($price > $max) {
- $max = $price;
- }
- }
- }
- $optionValues[] = [
- 'option_id' => $optionItem->getId(),
- 'type' => $optionItem->getType(),
- 'min' => ($min === null) ? 0. : $min,
- 'max' => $max,
- ];
- }
- }
- return $optionValues;
- }
- /**
- * @param float $amount
- * @param null|bool|string|array $exclude
- * @param null|array $context
- * @return AmountInterface|bool|float
- */
- public function getCustomAmount($amount = null, $exclude = null, $context = [])
- {
- if (null !== $amount) {
- $amount = $this->priceCurrency->convertAndRound($amount);
- } else {
- $amount = $this->getValue();
- }
- $exclude = $this->excludeAdjustment;
- return $this->calculator->getAmount($amount, $this->getProduct(), $exclude, $context);
- }
- /**
- * Return the minimal or maximal price for custom options.
- *
- * @param bool $getMin
- * @param string $priceCode
- * @return float
- */
- public function getCustomOptionRange($getMin, $priceCode = \Magento\Catalog\Pricing\Price\BasePrice::PRICE_CODE)
- {
- $optionValue = 0.;
- $options = $this->getValue($priceCode);
- foreach ($options as $option) {
- if ($getMin) {
- $optionValue += $option['min'];
- } else {
- $optionValue += $option['max'];
- }
- }
- return $this->priceCurrency->convertAndRound($optionValue);
- }
- /**
- * Return price for select custom options
- *
- * @return float
- */
- public function getSelectedOptions()
- {
- if (null !== $this->value) {
- return $this->value;
- }
- $this->value = false;
- $optionIds = $this->product->getCustomOption('option_ids');
- if (!$optionIds) {
- return $this->value;
- }
- $this->value = 0.;
- if ($optionIds) {
- $values = explode(',', $optionIds->getValue());
- $values = array_filter($values);
- if (!empty($values)) {
- $this->value = $this->processOptions($values);
- }
- }
- return $this->value;
- }
- /**
- * Process Product Options
- *
- * @param array $values
- * @return float
- */
- protected function processOptions(array $values)
- {
- $value = 0.;
- foreach ($values as $optionId) {
- $option = $this->product->getOptionById($optionId);
- if (!$option) {
- continue;
- }
- $confItemOption = $this->product->getCustomOption('option_' . $option->getId());
- $group = $option->groupFactory($option->getType())
- ->setOption($option)
- ->setConfigurationItemOption($confItemOption);
- $value += $group->getOptionPrice($confItemOption->getValue(), $this->value);
- }
- return $value;
- }
- /**
- * Get Product Options
- *
- * @return array
- */
- public function getOptions()
- {
- if (null !== $this->priceOptions) {
- return $this->priceOptions;
- }
- $this->priceOptions = [];
- $options = $this->product->getOptions();
- if ($options) {
- /** @var $optionItem \Magento\Catalog\Model\Product\Option */
- foreach ($options as $optionItem) {
- /** @var $optionValue \Magento\Catalog\Model\Product\Option\Value */
- foreach ($optionItem->getValues() as $optionValue) {
- $price = $optionValue->getPrice($optionValue->getPriceType() == Value::TYPE_PERCENT);
- $this->priceOptions[$optionValue->getId()][$price] = [
- 'base_amount' => $price,
- 'adjustment' => $this->getCustomAmount($price)->getValue(),
- ];
- }
- }
- }
- return $this->priceOptions;
- }
- }
|