Skip to content

Commit c4002b6

Browse files
author
Tang, Yu(ytang1)
committed
Merge pull request #337 from magento-fearless-kiwis/develop
[FearlessKiwis] Bug Fixes for Pricing and FPT
2 parents aeaaec5 + 2891271 commit c4002b6

File tree

23 files changed

+721
-88
lines changed

23 files changed

+721
-88
lines changed

app/code/Magento/Bundle/Pricing/Price/BundleRegularPrice.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface;
1010
use Magento\Catalog\Model\Product;
1111
use Magento\Framework\Pricing\Amount\AmountInterface;
12+
use Magento\Catalog\Pricing\Price\CustomOptionPrice;
13+
use Magento\Bundle\Model\Product\Price;
1214

1315
/**
1416
* Bundle product regular price model
@@ -48,7 +50,13 @@ public function __construct(
4850
public function getAmount()
4951
{
5052
if (null === $this->amount) {
51-
$this->amount = $this->calculator->getMinRegularAmount($this->getValue(), $this->product);
53+
$price = $this->getValue();
54+
if ($this->product->getPriceType() == Price::PRICE_TYPE_FIXED) {
55+
/** @var \Magento\Catalog\Pricing\Price\CustomOptionPrice $customOptionPrice */
56+
$customOptionPrice = $this->priceInfo->getPrice(CustomOptionPrice::PRICE_CODE);
57+
$price += $customOptionPrice->getCustomOptionRange(true);
58+
}
59+
$this->amount = $this->calculator->getMinRegularAmount($price, $this->product);
5260
}
5361
return $this->amount;
5462
}
@@ -61,7 +69,13 @@ public function getAmount()
6169
public function getMaximalPrice()
6270
{
6371
if (null === $this->maximalPrice) {
64-
$this->maximalPrice = $this->calculator->getMaxRegularAmount($this->getValue(), $this->product);
72+
$price = $this->getValue();
73+
if ($this->product->getPriceType() == Price::PRICE_TYPE_FIXED) {
74+
/** @var \Magento\Catalog\Pricing\Price\CustomOptionPrice $customOptionPrice */
75+
$customOptionPrice = $this->priceInfo->getPrice(CustomOptionPrice::PRICE_CODE);
76+
$price += $customOptionPrice->getCustomOptionRange(false);
77+
}
78+
$this->maximalPrice = $this->calculator->getMaxRegularAmount($price, $this->product);
6579
}
6680
return $this->maximalPrice;
6781
}

app/code/Magento/Bundle/Pricing/Price/FinalPrice.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
use Magento\Catalog\Model\Product;
1010
use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
11+
use Magento\Catalog\Pricing\Price\CustomOptionPrice;
12+
use Magento\Bundle\Model\Product\Price;
1113

1214
/**
1315
* Final price model
@@ -68,7 +70,13 @@ public function getValue()
6870
public function getMaximalPrice()
6971
{
7072
if (!$this->maximalPrice) {
71-
$this->maximalPrice = $this->calculator->getMaxAmount($this->getBasePrice()->getValue(), $this->product);
73+
$price = $this->getBasePrice()->getValue();
74+
if ($this->product->getPriceType() == Price::PRICE_TYPE_FIXED) {
75+
/** @var \Magento\Catalog\Pricing\Price\CustomOptionPrice $customOptionPrice */
76+
$customOptionPrice = $this->priceInfo->getPrice(CustomOptionPrice::PRICE_CODE);
77+
$price += $customOptionPrice->getCustomOptionRange(false);
78+
}
79+
$this->maximalPrice = $this->calculator->getMaxAmount($price, $this->product);
7280
}
7381
return $this->maximalPrice;
7482
}
@@ -91,7 +99,13 @@ public function getMinimalPrice()
9199
public function getAmount()
92100
{
93101
if (!$this->minimalPrice) {
94-
$this->minimalPrice = $this->calculator->getAmount(parent::getValue(), $this->product);
102+
$price = parent::getValue();
103+
if ($this->product->getPriceType() == Price::PRICE_TYPE_FIXED) {
104+
/** @var \Magento\Catalog\Pricing\Price\CustomOptionPrice $customOptionPrice */
105+
$customOptionPrice = $this->priceInfo->getPrice(CustomOptionPrice::PRICE_CODE);
106+
$price += $customOptionPrice->getCustomOptionRange(true);
107+
}
108+
$this->minimalPrice = $this->calculator->getAmount($price, $this->product);
95109
}
96110
return $this->minimalPrice;
97111
}

app/code/Magento/Bundle/Pricing/Price/TierPrice.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Magento\Bundle\Pricing\Price;
88

99
use Magento\Catalog\Pricing\Price\RegularPrice;
10+
use Magento\Framework\Pricing\Amount\AmountInterface;
1011

1112
/**
1213
* Bundle tier prices model
@@ -89,4 +90,13 @@ public function isPercentageDiscount()
8990
{
9091
return true;
9192
}
93+
94+
/**
95+
* @param AmountInterface $amount
96+
* @return float
97+
*/
98+
public function getSavePercent(AmountInterface $amount)
99+
{
100+
return round($amount->getBaseAmount());
101+
}
92102
}

app/code/Magento/Bundle/Test/Unit/Pricing/Price/BundleRegularPriceTest.php

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
namespace Magento\Bundle\Test\Unit\Pricing\Price;
88

99
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
10+
use Magento\Catalog\Pricing\Price\CustomOptionPrice;
11+
use Magento\Bundle\Model\Product\Price;
1012

1113
class BundleRegularPriceTest extends \PHPUnit_Framework_TestCase
1214
{
@@ -25,6 +27,9 @@ class BundleRegularPriceTest extends \PHPUnit_Framework_TestCase
2527
/** @var \Magento\Framework\Pricing\PriceInfo\Base |\PHPUnit_Framework_MockObject_MockObject */
2628
protected $priceInfoMock;
2729

30+
/** @var CustomOptionPrice|\PHPUnit_Framework_MockObject_MockObject */
31+
protected $customOptionPriceMock;
32+
2833
/**
2934
* @var int
3035
*/
@@ -40,11 +45,18 @@ class BundleRegularPriceTest extends \PHPUnit_Framework_TestCase
4045
*/
4146
protected function setUp()
4247
{
43-
$this->saleableInterfaceMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
48+
$this->saleableInterfaceMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
49+
->disableOriginalConstructor()
50+
->setMethods(['getPriceInfo', 'getPriceType', 'getPrice'])
51+
->getMock();
4452
$this->bundleCalculatorMock = $this->getMock('Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface');
4553

4654
$this->priceInfoMock = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
4755

56+
$this->customOptionPriceMock = $this->getMockBuilder('\Magento\Catalog\Pricing\Price\CustomOptionPrice')
57+
->disableOriginalConstructor()
58+
->getMock();
59+
4860
$this->saleableInterfaceMock->expects($this->once())
4961
->method('getPriceInfo')
5062
->will($this->returnValue($this->priceInfoMock));
@@ -110,6 +122,48 @@ public function testGetMaximalPrice()
110122
$this->assertEquals($expectedResult, $result, 'Incorrect amount the second time');
111123
}
112124

125+
public function testGetMaximalPriceForFixedPriceBundleWithOption()
126+
{
127+
$price = 5;
128+
$maxOptionPrice = 2;
129+
130+
$expectedPrice = $price + $maxOptionPrice;
131+
132+
$this->priceInfoMock->expects($this->atLeastOnce())
133+
->method('getPrice')
134+
->with(CustomOptionPrice::PRICE_CODE)
135+
->willReturn($this->customOptionPriceMock);
136+
137+
$this->customOptionPriceMock->expects($this->once())
138+
->method('getCustomOptionRange')
139+
->with(false)
140+
->willReturn($maxOptionPrice);
141+
142+
$this->saleableInterfaceMock->expects($this->once())
143+
->method('getPriceType')
144+
->willReturn(Price::PRICE_TYPE_FIXED);
145+
146+
$this->saleableInterfaceMock->expects($this->once())
147+
->method('getPrice')
148+
->will($this->returnValue($price));
149+
150+
$this->bundleCalculatorMock->expects($this->once())
151+
->method('getMaxRegularAmount')
152+
->with($expectedPrice, $this->saleableInterfaceMock)
153+
->will($this->returnValue($expectedPrice));
154+
155+
$this->priceCurrencyMock->expects($this->once())
156+
->method('convertAndRound')
157+
->will($this->returnArgument(0));
158+
159+
$result = $this->regularPrice->getMaximalPrice();
160+
$this->assertEquals($expectedPrice, $result, 'Incorrect amount');
161+
162+
//Calling a second time, should use cached value
163+
$result = $this->regularPrice->getMaximalPrice();
164+
$this->assertEquals($expectedPrice, $result, 'Incorrect amount the second time');
165+
}
166+
113167
public function testGetMinimalPrice()
114168
{
115169
$expectedResult = 5;
@@ -134,4 +188,45 @@ public function testGetMinimalPrice()
134188
$result = $this->regularPrice->getMinimalPrice();
135189
$this->assertEquals($expectedResult, $result, 'Incorrect amount the second time');
136190
}
191+
192+
public function testGetMinimalPriceForFixedPricedBundleWithOptions()
193+
{
194+
$price = 5;
195+
$minOptionPrice = 1;
196+
$expectedValue = $price + $minOptionPrice;
197+
198+
$this->saleableInterfaceMock->expects($this->once())
199+
->method('getPrice')
200+
->will($this->returnValue($price));
201+
202+
$this->saleableInterfaceMock->expects($this->once())
203+
->method('getPriceType')
204+
->willReturn(Price::PRICE_TYPE_FIXED);
205+
206+
$this->priceInfoMock->expects($this->atLeastOnce())
207+
->method('getPrice')
208+
->with(CustomOptionPrice::PRICE_CODE)
209+
->willReturn($this->customOptionPriceMock);
210+
211+
$this->customOptionPriceMock->expects($this->once())
212+
->method('getCustomOptionRange')
213+
->with(true)
214+
->willReturn($minOptionPrice);
215+
216+
$this->priceCurrencyMock->expects($this->once())
217+
->method('convertAndRound')
218+
->will($this->returnArgument(0));
219+
220+
$this->bundleCalculatorMock->expects($this->once())
221+
->method('getMinRegularAmount')
222+
->with($expectedValue, $this->saleableInterfaceMock)
223+
->will($this->returnValue($expectedValue));
224+
225+
$result = $this->regularPrice->getMinimalPrice();
226+
$this->assertEquals($expectedValue, $result, 'Incorrect amount');
227+
228+
//Calling a second time, should use cached value
229+
$result = $this->regularPrice->getMinimalPrice();
230+
$this->assertEquals($expectedValue, $result, 'Incorrect amount the second time');
231+
}
137232
}

app/code/Magento/Bundle/Test/Unit/Pricing/Price/FinalPriceTest.php

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
*/
66

77
namespace Magento\Bundle\Test\Unit\Pricing\Price;
8+
89
use Magento\Bundle\Pricing\Price\BundleOptionPrice;
10+
use Magento\Catalog\Pricing\Price\CustomOptionPrice;
11+
use Magento\Bundle\Model\Product\Price;
912

1013
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
1114

@@ -38,6 +41,9 @@ class FinalPriceTest extends \PHPUnit_Framework_TestCase
3841
/** @var BundleOptionPrice|\PHPUnit_Framework_MockObject_MockObject */
3942
protected $bundleOptionMock;
4043

44+
/** @var CustomOptionPrice|\PHPUnit_Framework_MockObject_MockObject */
45+
protected $customOptionPriceMock;
46+
4147
/**
4248
* @var \Magento\Framework\Pricing\PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject
4349
*/
@@ -48,7 +54,10 @@ class FinalPriceTest extends \PHPUnit_Framework_TestCase
4854
*/
4955
protected function prepareMock()
5056
{
51-
$this->saleableInterfaceMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
57+
$this->saleableInterfaceMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
58+
->disableOriginalConstructor()
59+
->setMethods(['getPriceType', 'getPriceInfo'])
60+
->getMock();
5261
$this->bundleCalculatorMock = $this->getMock('Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface');
5362

5463
$this->basePriceMock = $this->getMock('Magento\Catalog\Pricing\Price\BasePrice', [], [], '', false);
@@ -60,13 +69,18 @@ protected function prepareMock()
6069
->disableOriginalConstructor()
6170
->getMock();
6271

72+
$this->customOptionPriceMock = $this->getMockBuilder('\Magento\Catalog\Pricing\Price\CustomOptionPrice')
73+
->disableOriginalConstructor()
74+
->getMock();
75+
6376
$this->priceInfoMock = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
6477

6578
$this->priceInfoMock->expects($this->atLeastOnce())
6679
->method('getPrice')
6780
->will($this->returnValueMap([
6881
[\Magento\Catalog\Pricing\Price\BasePrice::PRICE_CODE, $this->basePriceMock],
6982
[BundleOptionPrice::PRICE_CODE, $this->bundleOptionMock],
83+
[CustomOptionPrice::PRICE_CODE, $this->customOptionPriceMock],
7084
]));
7185

7286
$this->saleableInterfaceMock->expects($this->once())
@@ -128,6 +142,54 @@ public function testGetMaximalPrice($baseAmount)
128142
$this->assertSame($result, $this->finalPrice->getMaximalPrice());
129143
}
130144

145+
public function testGetMaximalPriceFixedBundleWithOption()
146+
{
147+
$optionMaxPrice = 2;
148+
$this->baseAmount = 5;
149+
$result = 7;
150+
$this->prepareMock();
151+
152+
$this->saleableInterfaceMock->expects($this->once())
153+
->method('getPriceType')
154+
->willReturn(Price::PRICE_TYPE_FIXED);
155+
$this->customOptionPriceMock->expects($this->once())
156+
->method('getCustomOptionRange')
157+
->with(false)
158+
->willReturn($optionMaxPrice);
159+
160+
$this->bundleCalculatorMock->expects($this->once())
161+
->method('getMaxAmount')
162+
->with($this->equalTo($this->baseAmount + $optionMaxPrice), $this->equalTo($this->saleableInterfaceMock))
163+
->will($this->returnValue($result));
164+
$this->assertSame($result, $this->finalPrice->getMaximalPrice());
165+
//The second call should use cached value
166+
$this->assertSame($result, $this->finalPrice->getMaximalPrice());
167+
}
168+
169+
public function testGetMinimalPriceFixedBundleWithOption()
170+
{
171+
$optionMaxPrice = 2;
172+
$this->baseAmount = 5;
173+
$result = 7;
174+
$this->prepareMock();
175+
176+
$this->saleableInterfaceMock->expects($this->once())
177+
->method('getPriceType')
178+
->willReturn(Price::PRICE_TYPE_FIXED);
179+
$this->customOptionPriceMock->expects($this->once())
180+
->method('getCustomOptionRange')
181+
->with(true)
182+
->willReturn($optionMaxPrice);
183+
184+
$this->bundleCalculatorMock->expects($this->once())
185+
->method('getAmount')
186+
->with($this->equalTo($this->baseAmount + $optionMaxPrice), $this->equalTo($this->saleableInterfaceMock))
187+
->will($this->returnValue($result));
188+
$this->assertSame($result, $this->finalPrice->getMinimalPrice());
189+
//The second call should use cached value
190+
$this->assertSame($result, $this->finalPrice->getMinimalPrice());
191+
}
192+
131193
/**
132194
* @dataProvider getValueDataProvider
133195
*/

app/code/Magento/Bundle/Test/Unit/Pricing/Price/TierPriceTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,28 @@ public function providerForGetterTierPriceList()
183183
]
184184
];
185185
}
186+
187+
/**
188+
* @dataProvider providerForTestGetSavePercent
189+
*/
190+
public function testGetSavePercent($baseAmount, $savePercent)
191+
{
192+
$amount = $this->getMockForAbstractClass('Magento\Framework\Pricing\Amount\AmountInterface');
193+
$amount->expects($this->once())->method('getBaseAmount')->willReturn($baseAmount);
194+
195+
$this->assertEquals($savePercent, $this->model->getSavePercent($amount));
196+
}
197+
198+
/**
199+
* @return array
200+
*/
201+
public function providerForTestGetSavePercent()
202+
{
203+
return [
204+
'no fraction' => [10.0000, 10],
205+
'lower half' => [10.1234, 10],
206+
'half way' => [10.5000, 11],
207+
'upper half' => [10.6789, 11],
208+
];
209+
}
186210
}

app/code/Magento/Bundle/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
<item name="base_price" xsi:type="string">Magento\Catalog\Pricing\Price\BasePrice</item>
5151
<item name="configured_price" xsi:type="string">Magento\Bundle\Pricing\Price\ConfiguredPrice</item>
5252
<item name="bundle_option" xsi:type="string">Magento\Bundle\Pricing\Price\BundleOptionPrice</item>
53+
<item name="catalog_rule_price" xsi:type="string">Magento\CatalogRule\Pricing\Price\CatalogRulePrice</item>
5354
</argument>
5455
</arguments>
5556
</virtualType>

app/code/Magento/Bundle/view/base/templates/product/price/tier_prices.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ $tierPrices = $tierPriceModel->getTierPriceList();
2222
<?php echo __(
2323
'Buy %1 with %2 discount each',
2424
$price['price_qty'],
25-
'<strong class="benefit">' . $price['price']->getBaseAmount() . '%</strong>'
25+
'<strong class="benefit">' . $tierPriceModel->getSavePercent($price['price']) . '%</strong>'
2626
); ?>
2727
</li>
2828
<?php endforeach; ?>

0 commit comments

Comments
 (0)