Example #1
0
 /**
  * Retrieve Amount object based on given float amount, product and exclude option.
  * It is possible to pass "true" or adjustment code to exclude all or specific adjustment from an amount.
  *
  * @param float|string $amount
  * @param SaleableInterface $saleableItem
  * @param null|bool|string $exclude
  * @return \Magento\Framework\Pricing\Amount\AmountInterface
  */
 public function getAmount($amount, SaleableInterface $saleableItem, $exclude = null)
 {
     $baseAmount = $fullAmount = $amount;
     $adjustments = [];
     foreach ($saleableItem->getPriceInfo()->getAdjustments() as $adjustment) {
         $code = $adjustment->getAdjustmentCode();
         $toExclude = false;
         if ($exclude === true || $exclude !== null && $code === $exclude) {
             $toExclude = true;
         }
         if ($adjustment->isIncludedInBasePrice()) {
             $adjust = $adjustment->extractAdjustment($baseAmount, $saleableItem);
             $baseAmount -= $adjust;
             $fullAmount = $adjustment->applyAdjustment($fullAmount, $saleableItem);
             $adjust = $fullAmount - $baseAmount;
             if (!$toExclude) {
                 $adjustments[$code] = $adjust;
             }
         } elseif ($adjustment->isIncludedInDisplayPrice($saleableItem)) {
             if ($toExclude) {
                 continue;
             }
             $newAmount = $adjustment->applyAdjustment($fullAmount, $saleableItem);
             $adjust = $newAmount - $fullAmount;
             $adjustments[$code] = $adjust;
             $fullAmount = $newAmount;
         }
     }
     return $this->amountFactory->create($fullAmount, $adjustments);
 }
 /**
  * Create amount renderer
  *
  * @param AmountInterface $amount
  * @param SaleableInterface $saleableItem
  * @param PriceInterface $price
  * @param array $data
  * @return AmountRenderInterface
  * @throws \InvalidArgumentException
  */
 public function createAmountRender(AmountInterface $amount, SaleableInterface $saleableItem = null, PriceInterface $price = null, array $data = [])
 {
     $type = self::DEFAULT_PRICE_GROUP_TYPE;
     if ($saleableItem) {
         $type = $saleableItem->getTypeId();
     }
     $priceCode = null;
     $renderClassName = self::AMOUNT_RENDERER_DEFAULT;
     if ($price) {
         $priceCode = $price->getPriceCode();
         // implement class resolving fallback
         $pattern = [$type . '/prices/' . $priceCode . '/amount_render_class', $type . '/default_amount_render_class', 'default/prices/' . $priceCode . '/amount_render_class', 'default/default_amount_render_class'];
         $renderClassName = $this->findDataByPattern($pattern);
         if (!$renderClassName) {
             throw new \InvalidArgumentException('There is no amount render class for price code "' . $priceCode . '"');
         }
     }
     $arguments['data'] = $data;
     $arguments['rendererPool'] = $this;
     $arguments['amount'] = $amount;
     if ($saleableItem) {
         $arguments['saleableItem'] = $saleableItem;
         if ($price) {
             $arguments['price'] = $price;
         }
     }
     /** @var \Magento\Framework\View\Element\Template $amountBlock */
     $amountBlock = $this->getLayout()->createBlock($renderClassName, '', $arguments);
     if (!$amountBlock instanceof AmountRenderInterface) {
         throw new \InvalidArgumentException('Block "' . $renderClassName . '" must implement \\Magento\\Framework\\Pricing\\Render\\AmountRenderInterface');
     }
     $amountBlock->setTemplate($this->getAmountRenderBlockTemplate($type, $priceCode));
     return $amountBlock;
 }
Example #3
0
 /**
  * @param $typeId
  * @param $quantity
  * @param $infoClass
  * @param $prices
  * @dataProvider createPriceInfoDataProvider
  */
 public function testCreate($typeId, $quantity, $infoClass, $prices)
 {
     $this->saleableItemMock->expects($this->once())->method('getTypeId')->will($this->returnValue($typeId));
     $this->saleableItemMock->expects($this->once())->method('getQty')->will($this->returnValue($quantity));
     $this->objectManagerMock->expects($this->exactly(2))->method('create')->will($this->returnValueMap([[$prices, ['saleableItem' => $this->saleableItemMock, 'quantity' => $quantity], $this->pricesMock], [$infoClass, ['saleableItem' => $this->saleableItemMock, 'quantity' => $quantity, 'prices' => $this->pricesMock], $this->priceInfoMock]]));
     $this->assertEquals($this->priceInfoMock, $this->factory->create($this->saleableItemMock, []));
 }
Example #4
0
 /**
  * @param SaleableInterface $saleableItem
  * @param float $quantity
  * @param CalculatorInterface $calculator
  */
 public function __construct(SaleableInterface $saleableItem, $quantity, CalculatorInterface $calculator)
 {
     $this->product = $saleableItem;
     $this->quantity = $quantity;
     $this->calculator = $calculator;
     $this->priceInfo = $saleableItem->getPriceInfo();
 }
Example #5
0
 public function testGetValue()
 {
     $resultPrice = rand(1, 9);
     $customOptionOneQty = rand(1, 9);
     $customOptionTwoQty = rand(1, 9);
     $priceInfoBase = $this->getMockBuilder('Magento\\Framework\\Pricing\\PriceInfo\\Base')->disableOriginalConstructor()->getMock();
     $priceInfoBase->expects($this->any())->method('getPrice')->with(FinalPrice::PRICE_CODE)->willReturn($this->price);
     $productOne = $this->getMockBuilder('Magento\\Catalog\\Model\\Product')->disableOriginalConstructor()->getMock();
     $productOne->expects($this->once())->method('getId')->willReturn(1);
     $productOne->expects($this->once())->method('getPriceInfo')->willReturn($priceInfoBase);
     $productTwo = $this->getMockBuilder('Magento\\Catalog\\Model\\Product')->disableOriginalConstructor()->getMock();
     $productTwo->expects($this->once())->method('getId')->willReturn(2);
     $productTwo->expects($this->once())->method('getPriceInfo')->willReturn($priceInfoBase);
     $this->price->expects($this->any())->method('getValue')->willReturn($resultPrice);
     $customOptionOne = $this->getMockBuilder('Magento\\Wishlist\\Model\\Item\\Option')->disableOriginalConstructor()->getMock();
     $customOptionOne->expects($this->any())->method('getValue')->willReturn($customOptionOneQty);
     $customOptionTwo = $this->getMockBuilder('Magento\\Wishlist\\Model\\Item\\Option')->disableOriginalConstructor()->getMock();
     $customOptionTwo->expects($this->any())->method('getValue')->willReturn($customOptionTwoQty);
     $store = $this->getMockBuilder('Magento\\Store\\Model\\Store')->disableOriginalConstructor()->getMock();
     $groupedProduct = $this->getMockBuilder('Magento\\GroupedProduct\\Model\\Product\\Type\\Grouped')->disableOriginalConstructor()->getMock();
     $groupedProduct->expects($this->once())->method('setStoreFilter')->with($store, $this->saleableItem)->willReturnSelf();
     $groupedProduct->expects($this->once())->method('getAssociatedProducts')->with($this->saleableItem)->willReturn([$productOne, $productTwo]);
     $this->saleableItem->expects($this->once())->method('getTypeInstance')->willReturn($groupedProduct);
     $this->saleableItem->expects($this->any())->method('getStore')->willReturn($store);
     $this->saleableItem->expects($this->any())->method('getCustomOption')->willReturnMap([['associated_product_' . 1, $customOptionOne], ['associated_product_' . 2, $customOptionTwo]]);
     $item = $this->getMockBuilder('Magento\\Catalog\\Model\\Product\\Configuration\\Item\\ItemInterface')->getMock();
     $this->model->setItem($item);
     $result = 0;
     foreach ([$customOptionOneQty, $customOptionTwoQty] as $qty) {
         $result += $resultPrice * $qty;
     }
     $this->assertEquals($result, $this->model->getValue());
 }
 /**
  * @param SaleableInterface $saleableItem
  * @param float $quantity
  * @param CalculatorInterface $calculator
  * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
  */
 public function __construct(SaleableInterface $saleableItem, $quantity, CalculatorInterface $calculator, \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency)
 {
     $this->product = $saleableItem;
     $this->quantity = $quantity;
     $this->calculator = $calculator;
     $this->priceCurrency = $priceCurrency;
     $this->priceInfo = $saleableItem->getPriceInfo();
 }
Example #7
0
 /**
  * @dataProvider showRangePriceDataProvider
  */
 public function testShowRangePrice($value, $maxValue, $result)
 {
     $priceInfo = $this->getMock('Magento\\Framework\\Pricing\\PriceInfo\\Base', [], [], '', false);
     $optionPrice = $this->getMockBuilder('Magento\\Bundle\\Pricing\\Price\\BundleOptionPrice')->disableOriginalConstructor()->getMock();
     $this->saleableItem->expects($this->atLeastOnce())->method('getPriceInfo')->will($this->returnValue($priceInfo));
     $priceInfo->expects($this->atLeastOnce())->method('getPrice')->with(Price\BundleOptionPrice::PRICE_CODE)->will($this->returnValue($optionPrice));
     $optionPrice->expects($this->once())->method('getValue')->will($this->returnValue($value));
     $optionPrice->expects($this->once())->method('getMaxValue')->will($this->returnValue($maxValue));
     $this->assertEquals($result, $this->model->showRangePrice());
 }
Example #8
0
 /**
  * Test getMinimalPrice()
  */
 public function testGetMinimalPrice()
 {
     $basePrice = 10;
     $minimalPrice = 5;
     $this->basePriceMock->expects($this->once())->method('getValue')->will($this->returnValue($basePrice));
     $this->calculatorMock->expects($this->once())->method('getAmount')->with($this->equalTo($basePrice))->will($this->returnValue($minimalPrice));
     $this->saleableMock->expects($this->once())->method('getMinimalPrice')->will($this->returnValue(null));
     $result = $this->model->getMinimalPrice();
     $this->assertEquals($minimalPrice, $result);
 }
 public function testGetMinimalPrice()
 {
     $expectedResult = 5;
     $this->saleableInterfaceMock->expects($this->once())->method('getPrice')->will($this->returnValue($expectedResult));
     $this->priceCurrencyMock->expects($this->once())->method('convertAndRound')->will($this->returnArgument(0));
     $this->bundleCalculatorMock->expects($this->once())->method('getMinRegularAmount')->with($expectedResult, $this->saleableInterfaceMock)->will($this->returnValue($expectedResult));
     $result = $this->regularPrice->getMinimalPrice();
     $this->assertEquals($expectedResult, $result, 'Incorrect amount');
     //Calling a second time, should use cached value
     $result = $this->regularPrice->getMinimalPrice();
     $this->assertEquals($expectedResult, $result, 'Incorrect amount the second time');
 }
Example #10
0
 /**
  * @return void
  */
 protected function prepareMock()
 {
     $this->saleableInterfaceMock = $this->getMock('Magento\\Catalog\\Model\\Product', [], [], '', false);
     $this->bundleCalculatorMock = $this->getMock('Magento\\Bundle\\Pricing\\Adjustment\\BundleCalculatorInterface');
     $this->basePriceMock = $this->getMock('Magento\\Catalog\\Pricing\\Price\\BasePrice', [], [], '', false);
     $this->basePriceMock->expects($this->any())->method('getValue')->will($this->returnValue($this->baseAmount));
     $this->bundleOptionMock = $this->getMockBuilder('Magento\\Bundle\\Pricing\\Price\\BundleOptionPrice')->disableOriginalConstructor()->getMock();
     $this->priceInfoMock = $this->getMock('Magento\\Framework\\Pricing\\PriceInfo\\Base', [], [], '', false);
     $this->priceInfoMock->expects($this->atLeastOnce())->method('getPrice')->will($this->returnValueMap([[\Magento\Catalog\Pricing\Price\BasePrice::PRICE_CODE, $this->basePriceMock], [BundleOptionPrice::PRICE_CODE, $this->bundleOptionMock]]));
     $this->saleableInterfaceMock->expects($this->once())->method('getPriceInfo')->will($this->returnValue($this->priceInfoMock));
     $this->objectManagerHelper = new ObjectManagerHelper($this);
     $this->finalPrice = new \Magento\Bundle\Pricing\Price\FinalPrice($this->saleableInterfaceMock, $this->quantity, $this->bundleCalculatorMock);
 }
Example #11
0
 /**
  * @param $regularPrice
  * @param $specialPrice
  * @param $isScopeDateInInterval
  * @param $value
  * @param $percent
  * @dataProvider getValueDataProvider
  */
 public function testGetValue($regularPrice, $specialPrice, $isScopeDateInInterval, $value, $percent)
 {
     $specialFromDate = 'some date from';
     $specialToDate = 'some date to';
     $this->saleable->expects($this->once())->method('getSpecialPrice')->will($this->returnValue($specialPrice));
     $store = $this->getMockBuilder('Magento\\Store\\Model\\Store')->disableOriginalConstructor()->getMock();
     $this->saleable->expects($this->once())->method('getStore')->will($this->returnValue($store));
     $this->saleable->expects($this->once())->method('getSpecialFromDate')->will($this->returnValue($specialFromDate));
     $this->saleable->expects($this->once())->method('getSpecialToDate')->will($this->returnValue($specialToDate));
     $this->localeDate->expects($this->once())->method('isScopeDateInInterval')->with($store, $specialFromDate, $specialToDate)->will($this->returnValue($isScopeDateInInterval));
     if ($isScopeDateInInterval) {
         $price = $this->getMock('Magento\\Framework\\Pricing\\Price\\PriceInterface');
         $this->priceInfo->expects($this->once())->method('getPrice')->with(\Magento\Catalog\Pricing\Price\RegularPrice::PRICE_CODE)->will($this->returnValue($price));
         $price->expects($this->once())->method('getValue')->will($this->returnValue($regularPrice));
     }
     $this->assertEquals($value, $this->model->getValue());
     //check that the second call will get data from cache the same as in first call
     $this->assertEquals($value, $this->model->getValue());
     $this->assertEquals($percent, $this->model->getDiscountPercent());
 }
Example #12
0
 /**
  * Create Price Info object for particular product
  *
  * @param SaleableInterface $saleableItem
  * @param array $arguments
  * @return \Magento\Framework\Pricing\PriceInfoInterface
  * @throws \InvalidArgumentException
  */
 public function create(SaleableInterface $saleableItem, array $arguments = [])
 {
     $type = $saleableItem->getTypeId();
     if (isset($this->types[$type]['infoClass'])) {
         $priceInfo = $this->types[$type]['infoClass'];
     } else {
         $priceInfo = $this->types['default']['infoClass'];
     }
     if (isset($this->types[$type]['prices'])) {
         $priceCollection = $this->types[$type]['prices'];
     } else {
         $priceCollection = $this->types['default']['prices'];
     }
     $arguments['saleableItem'] = $saleableItem;
     $quantity = $saleableItem->getQty();
     if ($quantity) {
         $arguments['quantity'] = $quantity;
     }
     $arguments['prices'] = $this->objectManager->create($priceCollection, ['saleableItem' => $arguments['saleableItem'], 'quantity' => $quantity]);
     return $this->objectManager->create($priceInfo, $arguments);
 }
Example #13
0
 public function testGetMinimalPriceFixedBundleWithOption()
 {
     $optionMaxPrice = 2;
     $this->baseAmount = 5;
     $result = 7;
     $this->prepareMock();
     $this->saleableInterfaceMock->expects($this->once())->method('getPriceType')->willReturn(Price::PRICE_TYPE_FIXED);
     $this->customOptionPriceMock->expects($this->once())->method('getCustomOptionRange')->with(true)->willReturn($optionMaxPrice);
     $this->bundleCalculatorMock->expects($this->once())->method('getAmount')->with($this->equalTo($this->baseAmount + $optionMaxPrice), $this->equalTo($this->saleableInterfaceMock))->will($this->returnValue($result));
     $this->assertSame($result, $this->finalPrice->getMinimalPrice());
     //The second call should use cached value
     $this->assertSame($result, $this->finalPrice->getMinimalPrice());
 }
Example #14
0
 /**
  * Test getMinimalPrice()
  */
 public function testGetMinimalPriceWithMinimalPrice()
 {
     $minimalPrice = 5.234;
     $convertedPrice = 3.98;
     $finalPrice = 3.89;
     $this->priceCurrencyMock->expects($this->once())->method('convertAndRound')->with($minimalPrice)->will($this->returnValue($convertedPrice));
     $this->basePriceMock->expects($this->never())->method('getValue');
     $this->calculatorMock->expects($this->once())->method('getAmount')->with($this->equalTo($convertedPrice))->will($this->returnValue($finalPrice));
     $this->saleableMock->expects($this->once())->method('getMinimalPrice')->will($this->returnValue($minimalPrice));
     $result = $this->model->getMinimalPrice();
     $this->assertEquals($finalPrice, $result);
     //The second time will return cached value
     $result = $this->model->getMinimalPrice();
     $this->assertEquals($finalPrice, $result);
 }
Example #15
0
 /**
  * Test get Value
  */
 public function testGetValue()
 {
     $coreStoreId = 1;
     $coreWebsiteId = 1;
     $productId = 1;
     $customerGroupId = 1;
     $dateTime = time();
     $expectedValue = 55.12;
     $this->coreStoreMock->expects($this->once())->method('getId')->will($this->returnValue($coreStoreId));
     $this->coreStoreMock->expects($this->once())->method('getWebsiteId')->will($this->returnValue($coreWebsiteId));
     $this->dataTimeMock->expects($this->once())->method('scopeTimeStamp')->with($this->equalTo($coreStoreId))->will($this->returnValue($dateTime));
     $this->customerSessionMock->expects($this->once())->method('getCustomerGroupId')->will($this->returnValue($customerGroupId));
     $this->catalogRuleResourceMock->expects($this->once())->method('getRulePrice')->will($this->returnValue($expectedValue));
     $this->saleableItemMock->expects($this->any())->method('getId')->will($this->returnValue($productId));
     $this->assertEquals($expectedValue, $this->object->getValue());
 }
Example #16
0
 public function testGetMinimalPriceForFixedPricedBundleWithOptions()
 {
     $price = 5;
     $minOptionPrice = 1;
     $expectedValue = $price + $minOptionPrice;
     $this->saleableInterfaceMock->expects($this->once())->method('getPrice')->will($this->returnValue($price));
     $this->saleableInterfaceMock->expects($this->once())->method('getPriceType')->willReturn(Price::PRICE_TYPE_FIXED);
     $this->priceInfoMock->expects($this->atLeastOnce())->method('getPrice')->with(CustomOptionPrice::PRICE_CODE)->willReturn($this->customOptionPriceMock);
     $this->customOptionPriceMock->expects($this->once())->method('getCustomOptionRange')->with(true)->willReturn($minOptionPrice);
     $this->priceCurrencyMock->expects($this->once())->method('convertAndRound')->will($this->returnArgument(0));
     $this->bundleCalculatorMock->expects($this->once())->method('getMinRegularAmount')->with($expectedValue, $this->saleableInterfaceMock)->will($this->returnValue($expectedValue));
     $result = $this->regularPrice->getMinimalPrice();
     $this->assertEquals($expectedValue, $result, 'Incorrect amount');
     //Calling a second time, should use cached value
     $result = $this->regularPrice->getMinimalPrice();
     $this->assertEquals($expectedValue, $result, 'Incorrect amount the second time');
 }
Example #17
0
 /**
  * @dataProvider getPriceIdProvider
  * @param string $prefix
  * @param string $suffix
  * @param string $defaultPrefix
  * @param string $defaultSuffix
  */
 public function testGetPriceId($prefix, $suffix, $defaultPrefix, $defaultSuffix)
 {
     $priceId = 'price_id';
     $this->saleable->expects($this->once())->method('getId')->will($this->returnValue($priceId));
     if (!empty($prefix)) {
         $this->model->setData('price_id_prefix', $prefix);
         $expectedPriceId = $prefix . $priceId;
     } else {
         $expectedPriceId = $defaultPrefix . $priceId;
     }
     if (!empty($suffix)) {
         $this->model->setData('price_id_suffix', $suffix);
         $expectedPriceId = $expectedPriceId . $suffix;
     } else {
         $expectedPriceId = $expectedPriceId . $defaultSuffix;
     }
     $this->assertEquals($expectedPriceId, $this->model->getPriceId($defaultPrefix, $defaultSuffix));
 }
Example #18
0
 /**
  * @dataProvider dataProviderForGetterAmount
  */
 public function testGetterAmount($amountForBundle, $optionList, $expectedResult)
 {
     $this->baseCalculator->expects($this->atLeastOnce())->method('getAmount')->with($this->baseAmount, $this->saleableItem)->will($this->returnValue($this->createAmountMock($amountForBundle)));
     $options = [];
     foreach ($optionList as $optionData) {
         $options[] = $this->createOptionMock($optionData);
     }
     $price = $this->getMock('Magento\\Bundle\\Pricing\\Price\\BundleOptionPrice', [], [], '', false);
     $price->expects($this->atLeastOnce())->method('getOptions')->will($this->returnValue($options));
     $this->priceMocks[Price\BundleOptionPrice::PRICE_CODE] = $price;
     // Price type of saleable items
     $this->saleableItem->expects($this->any())->method('getPriceType')->will($this->returnValue(ProductPrice::PRICE_TYPE_DYNAMIC));
     $this->amountFactory->expects($this->atLeastOnce())->method('create')->with($expectedResult['fullAmount'], $expectedResult['adjustments']);
     if ($expectedResult['isMinAmount']) {
         $this->model->getAmount($this->baseAmount, $this->saleableItem);
     } else {
         $this->model->getMaxAmount($this->baseAmount, $this->saleableItem);
     }
 }
Example #19
0
 /**
  * @dataProvider getTestDataForCalculation
  */
 public function testCalculation($optionList, $expected)
 {
     $storeId = 1;
     $this->saleableItemMock->expects($this->any())->method('getStoreId')->will($this->returnValue($storeId));
     $this->selectionFactoryMock->expects($this->any())->method('create')->will($this->returnArgument(1));
     $this->baseCalculator->expects($this->atLeastOnce())->method('getAmount')->will($this->returnValue($this->createAmountMock(['amount' => 0.0])));
     $options = [];
     foreach ($optionList as $optionData) {
         $options[] = $this->createOptionMock($optionData);
     }
     /** @var \PHPUnit_Framework_MockObject_MockObject $optionsCollection */
     $optionsCollection = $this->getMock('Magento\\Bundle\\Model\\Resource\\Option\\Collection', [], [], '', false);
     $optionsCollection->expects($this->atLeastOnce())->method('appendSelections')->will($this->returnSelf());
     $optionsCollection->expects($this->atLeastOnce())->method('getIterator')->will($this->returnValue(new \ArrayIterator($options)));
     /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product\Type\AbstractType $typeMock */
     $typeMock = $this->getMock('Magento\\Bundle\\Model\\Product\\Type', [], [], '', false);
     $typeMock->expects($this->any())->method('setStoreFilter')->with($storeId, $this->saleableItemMock);
     $typeMock->expects($this->any())->method('getOptionsCollection')->with($this->saleableItemMock)->will($this->returnValue($optionsCollection));
     $this->saleableItemMock->expects($this->any())->method('getTypeInstance')->will($this->returnValue($typeMock));
     $this->assertEquals($expected['min'], $this->bundleOptionPrice->getValue());
     $this->assertEquals($expected['max'], $this->bundleOptionPrice->getMaxValue());
 }
Example #20
0
 /**
  * Retrieve price object of given type and quantity
  *
  * @param string $priceCode
  * @return PriceInterface
  */
 public function getPriceType($priceCode)
 {
     return $this->saleableItem->getPriceInfo()->getPrice($priceCode);
 }