BundleOptions.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\Bundle\Pricing\Price;
  8. use Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface;
  9. use Magento\Framework\Pricing\SaleableInterface;
  10. use Magento\Framework\Pricing\Amount\AmountInterface;
  11. use Magento\Catalog\Model\Product;
  12. /**
  13. * Bundle option price calculation model.
  14. */
  15. class BundleOptions
  16. {
  17. /**
  18. * @var BundleCalculatorInterface
  19. */
  20. private $calculator;
  21. /**
  22. * @var BundleSelectionFactory
  23. */
  24. private $selectionFactory;
  25. /**
  26. * @var AmountInterface[]
  27. */
  28. private $optionSelectionAmountCache = [];
  29. /**
  30. * @param BundleCalculatorInterface $calculator
  31. * @param BundleSelectionFactory $bundleSelectionFactory
  32. */
  33. public function __construct(
  34. BundleCalculatorInterface $calculator,
  35. BundleSelectionFactory $bundleSelectionFactory
  36. ) {
  37. $this->calculator = $calculator;
  38. $this->selectionFactory = $bundleSelectionFactory;
  39. }
  40. /**
  41. * Get Options with attached Selections collection.
  42. *
  43. * @param SaleableInterface $bundleProduct
  44. * @return \Magento\Bundle\Model\ResourceModel\Option\Collection|array
  45. */
  46. public function getOptions(SaleableInterface $bundleProduct)
  47. {
  48. /** @var \Magento\Bundle\Model\Product\Type $typeInstance */
  49. $typeInstance = $bundleProduct->getTypeInstance();
  50. $typeInstance->setStoreFilter($bundleProduct->getStoreId(), $bundleProduct);
  51. /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionCollection */
  52. $optionCollection = $typeInstance->getOptionsCollection($bundleProduct);
  53. /** @var \Magento\Bundle\Model\ResourceModel\Selection\Collection $selectionCollection */
  54. $selectionCollection = $typeInstance->getSelectionsCollection(
  55. $typeInstance->getOptionsIds($bundleProduct),
  56. $bundleProduct
  57. );
  58. $priceOptions = $optionCollection->appendSelections($selectionCollection, true, false);
  59. return $priceOptions;
  60. }
  61. /**
  62. * Calculate maximal or minimal options value.
  63. *
  64. * @param SaleableInterface $bundleProduct
  65. * @param bool $searchMin
  66. *
  67. * @return float
  68. */
  69. public function calculateOptions(
  70. SaleableInterface $bundleProduct,
  71. bool $searchMin = true
  72. ) : float {
  73. $priceList = [];
  74. /* @var \Magento\Bundle\Model\Option $option */
  75. foreach ($this->getOptions($bundleProduct) as $option) {
  76. if ($searchMin && !$option->getRequired()) {
  77. continue;
  78. }
  79. /** @var \Magento\Bundle\Pricing\Price\BundleSelectionPrice $selectionPriceList */
  80. $selectionPriceList = $this->calculator->createSelectionPriceList($option, $bundleProduct);
  81. $selectionPriceList = $this->calculator->processOptions($option, $selectionPriceList, $searchMin);
  82. $priceList = array_merge($priceList, $selectionPriceList);
  83. }
  84. $amount = $this->calculator->calculateBundleAmount(0., $bundleProduct, $priceList);
  85. return $amount->getValue();
  86. }
  87. /**
  88. * Get selection amount.
  89. *
  90. * @param Product $bundleProduct
  91. * @param \Magento\Bundle\Model\Selection|Product $selection
  92. * @param bool $useRegularPrice
  93. *
  94. * @return AmountInterface
  95. */
  96. public function getOptionSelectionAmount(
  97. Product $bundleProduct,
  98. $selection,
  99. bool $useRegularPrice = false
  100. ) : AmountInterface {
  101. $cacheKey = implode(
  102. '_',
  103. [
  104. $bundleProduct->getId(),
  105. $selection->getOptionId(),
  106. $selection->getSelectionId(),
  107. $useRegularPrice ? 1 : 0,
  108. ]
  109. );
  110. if (!isset($this->optionSelectionAmountCache[$cacheKey])) {
  111. $selectionPrice = $this->selectionFactory
  112. ->create(
  113. $bundleProduct,
  114. $selection,
  115. $selection->getSelectionQty(),
  116. ['useRegularPrice' => $useRegularPrice]
  117. );
  118. $this->optionSelectionAmountCache[$cacheKey] = $selectionPrice->getAmount();
  119. }
  120. return $this->optionSelectionAmountCache[$cacheKey];
  121. }
  122. }