Skip to content

Commit 29c17ce

Browse files
author
Yaroslav Onischenko
authored
Merge pull request #631 from magento-dragons/dragons-pr-2.0
[DRAGONS] Bugfixes for 2.0.11
2 parents 8a1974f + ac89cd0 commit 29c17ce

File tree

30 files changed

+1228
-288
lines changed

30 files changed

+1228
-288
lines changed

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,26 +232,28 @@ public function getJsonConfig()
232232
foreach ($tierPricesList as $tierPrice) {
233233
$tierPrices[] = $this->priceCurrency->convert($tierPrice['price']->getValue());
234234
}
235+
$regularPriceAmount = $product->getPriceInfo()->getPrice('regular_price')->getAmount();
236+
$finalPriceAmount = $product->getPriceInfo()->getPrice('final_price')->getAmount();
235237
$config = [
236238
'productId' => $product->getId(),
237239
'priceFormat' => $this->_localeFormat->getPriceFormat(),
238240
'prices' => [
239241
'oldPrice' => [
240-
'amount' => $this->priceCurrency->convert(
241-
$product->getPriceInfo()->getPrice('regular_price')->getAmount()->getValue()
242-
),
242+
'amount' => $regularPriceAmount
243+
? $this->priceCurrency->convert($regularPriceAmount->getValue())
244+
: null,
243245
'adjustments' => []
244246
],
245247
'basePrice' => [
246-
'amount' => $this->priceCurrency->convert(
247-
$product->getPriceInfo()->getPrice('final_price')->getAmount()->getBaseAmount()
248-
),
248+
'amount' => $finalPriceAmount
249+
? $this->priceCurrency->convert($finalPriceAmount->getBaseAmount())
250+
: null,
249251
'adjustments' => []
250252
],
251253
'finalPrice' => [
252-
'amount' => $this->priceCurrency->convert(
253-
$product->getPriceInfo()->getPrice('final_price')->getAmount()->getValue()
254-
),
254+
'amount' => $finalPriceAmount
255+
? $this->priceCurrency->convert($finalPriceAmount->getValue())
256+
: null,
255257
'adjustments' => []
256258
]
257259
],
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Model\Product\Pricing\Renderer;
8+
9+
/**
10+
* Resolver provided to check is product available for sale
11+
*/
12+
class SalableResolver implements SalableResolverInterface
13+
{
14+
/**
15+
* Check is product available for sale
16+
*
17+
* @param \Magento\Framework\Pricing\SaleableInterface $salableItem
18+
* @return boolean
19+
*/
20+
public function isSalable(\Magento\Framework\Pricing\SaleableInterface $salableItem)
21+
{
22+
return $salableItem->getCanShowPrice() !== false && $salableItem->isSalable();
23+
}
24+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Model\Product\Pricing\Renderer;
8+
9+
/**
10+
* Interface resolver provided to check is product available for sale
11+
*/
12+
interface SalableResolverInterface
13+
{
14+
/**
15+
* Check is product available for sale
16+
*
17+
* @param \Magento\Framework\Pricing\SaleableInterface $salableItem
18+
* @return boolean
19+
*/
20+
public function isSalable(\Magento\Framework\Pricing\SaleableInterface $salableItem);
21+
}

app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
use Magento\Framework\Pricing\Render;
1111
use Magento\Framework\Pricing\Render\PriceBox as BasePriceBox;
1212
use Magento\Msrp\Pricing\Price\MsrpPrice;
13+
use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface;
14+
use Magento\Framework\View\Element\Template\Context;
15+
use Magento\Framework\Pricing\SaleableInterface;
16+
use Magento\Framework\Pricing\Price\PriceInterface;
17+
use Magento\Framework\Pricing\Render\RendererPool;
1318

1419
/**
1520
* Class for final_price rendering
@@ -19,12 +24,38 @@
1924
*/
2025
class FinalPriceBox extends BasePriceBox
2126
{
27+
/**
28+
* @var SalableResolverInterface
29+
*/
30+
private $salableResolver;
31+
32+
/**
33+
* @param Context $context
34+
* @param SaleableInterface $saleableItem
35+
* @param PriceInterface $price
36+
* @param RendererPool $rendererPool
37+
* @param array $data
38+
* @param SalableResolverInterface $salableResolver
39+
*/
40+
public function __construct(
41+
Context $context,
42+
SaleableInterface $saleableItem,
43+
PriceInterface $price,
44+
RendererPool $rendererPool,
45+
array $data = [],
46+
SalableResolverInterface $salableResolver = null
47+
) {
48+
parent::__construct($context, $saleableItem, $price, $rendererPool, $data);
49+
$this->salableResolver = $salableResolver ?: \Magento\Framework\App\ObjectManager::getInstance()
50+
->get(SalableResolverInterface::class);
51+
}
52+
2253
/**
2354
* @return string
2455
*/
2556
protected function _toHtml()
2657
{
27-
if (!$this->getSaleableItem() || $this->getSaleableItem()->getCanShowPrice() === false) {
58+
if (!$this->salableResolver->isSalable($this->getSaleableItem())) {
2859
return '';
2960
}
3061

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Test\Unit\Model\Product\Pricing\Renderer;
8+
9+
class SalableResolverTest extends \PHPUnit_Framework_TestCase
10+
{
11+
/**
12+
* @var \Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver
13+
*/
14+
protected $object;
15+
16+
/**
17+
* @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
18+
*/
19+
protected $product;
20+
21+
protected function setUp()
22+
{
23+
$this->product = $this->getMock(
24+
'Magento\Catalog\Model\Product',
25+
['__wakeup', 'getCanShowPrice', 'isSalable'],
26+
[],
27+
'',
28+
false
29+
);
30+
31+
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
32+
$this->object = $objectManager->getObject(
33+
'Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver'
34+
);
35+
}
36+
37+
public function testSalableItem()
38+
{
39+
$this->product->expects($this->any())
40+
->method('getCanShowPrice')
41+
->willReturn(true);
42+
43+
$this->product->expects($this->any())->method('isSalable')->willReturn(true);
44+
45+
$result = $this->object->isSalable($this->product);
46+
$this->assertTrue($result);
47+
}
48+
49+
public function testNotSalableItem()
50+
{
51+
$this->product->expects($this->any())
52+
->method('getCanShowPrice')
53+
->willReturn(true);
54+
55+
$this->product->expects($this->any())->method('isSalable')->willReturn(false);
56+
57+
$result = $this->object->isSalable($this->product);
58+
$this->assertFalse($result);
59+
}
60+
}

app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Magento\Catalog\Test\Unit\Pricing\Render;
88

9+
use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface;
10+
911
/**
1012
* Class FinalPriceBoxTest
1113
*/
@@ -44,7 +46,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
4446
/**
4547
* @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
4648
*/
47-
protected $loggerMock;
49+
protected $logger;
4850

4951
/**
5052
* @var \Magento\Framework\Pricing\Render\RendererPool|\PHPUnit_Framework_MockObject_MockObject
@@ -56,12 +58,17 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
5658
*/
5759
protected $price;
5860

61+
/**
62+
* @var SalableResolverInterface|\PHPUnit_Framework_MockObject_MockObject
63+
*/
64+
private $salableResolverMock;
65+
5966
protected function setUp()
6067
{
6168
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
6269
$this->product = $this->getMock(
6370
'Magento\Catalog\Model\Product',
64-
['getPriceInfo', '__wakeup', 'getCanShowPrice'],
71+
['getPriceInfo', '__wakeup', 'getCanShowPrice', 'isSalable'],
6572
[],
6673
'',
6774
false
@@ -74,11 +81,9 @@ protected function setUp()
7481
$this->layout = $this->getMock('Magento\Framework\View\Layout', [], [], '', false);
7582

7683
$this->priceBox = $this->getMock('Magento\Framework\Pricing\Render\PriceBox', [], [], '', false);
77-
$this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
84+
$this->logger = $this->getMock('Psr\Log\LoggerInterface');
7885

79-
$this->layout->expects($this->any())
80-
->method('getBlock')
81-
->will($this->returnValue($this->priceBox));
86+
$this->layout->expects($this->any())->method('getBlock')->willReturn($this->priceBox);
8287

8388
$store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
8489
->getMockForAbstractClass();
@@ -92,7 +97,7 @@ protected function setUp()
9297
'Magento\Framework\View\Element\Template\Context',
9398
[
9499
'storeManager' => $storeManagerMock,
95-
'logger' => $this->loggerMock
100+
'logger' => $this->logger
96101
]
97102
);
98103

@@ -105,14 +110,21 @@ protected function setUp()
105110
->method('getPriceCode')
106111
->will($this->returnValue(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE));
107112

113+
$this->salableResolverMock = $this->getMockBuilder(
114+
'Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface'
115+
)
116+
->disableOriginalConstructor()
117+
->getMockForAbstractClass();
118+
108119
$this->object = $objectManager->getObject(
109120
'Magento\Catalog\Pricing\Render\FinalPriceBox',
110121
[
111122
'context' => $context,
112123
'saleableItem' => $this->product,
113124
'rendererPool' => $this->rendererPool,
114125
'price' => $this->price,
115-
'data' => ['zone' => 'test_zone', 'list_category_page' => true]
126+
'data' => ['zone' => 'test_zone', 'list_category_page' => true],
127+
'salableResolver' => $this->salableResolverMock
116128
]
117129
);
118130
}
@@ -130,6 +142,8 @@ public function testRenderMsrpDisabled()
130142
->with($this->equalTo($this->product))
131143
->will($this->returnValue(false));
132144

145+
$this->salableResolverMock->expects($this->once())->method('isSalable')->with($this->product)->willReturn(true);
146+
133147
$result = $this->object->toHtml();
134148

135149
//assert price wrapper
@@ -138,6 +152,18 @@ public function testRenderMsrpDisabled()
138152
$this->assertRegExp('/[final_price]/', $result);
139153
}
140154

155+
public function testNotSalableItem()
156+
{
157+
$this->salableResolverMock
158+
->expects($this->once())
159+
->method('isSalable')
160+
->with($this->product)
161+
->willReturn(false);
162+
$result = $this->object->toHtml();
163+
164+
$this->assertEmpty($result);
165+
}
166+
141167
public function testRenderMsrpEnabled()
142168
{
143169
$priceType = $this->getMock('Magento\Msrp\Pricing\Price\MsrpPrice', [], [], '', false);
@@ -172,6 +198,8 @@ public function testRenderMsrpEnabled()
172198
->with('msrp_price', $this->product, $arguments)
173199
->will($this->returnValue($priceBoxRender));
174200

201+
$this->salableResolverMock->expects($this->once())->method('isSalable')->with($this->product)->willReturn(true);
202+
175203
$result = $this->object->toHtml();
176204

177205
//assert price wrapper
@@ -183,14 +211,16 @@ public function testRenderMsrpEnabled()
183211

184212
public function testRenderMsrpNotRegisteredException()
185213
{
186-
$this->loggerMock->expects($this->once())
214+
$this->logger->expects($this->once())
187215
->method('critical');
188216

189217
$this->priceInfo->expects($this->once())
190218
->method('getPrice')
191219
->with($this->equalTo('msrp_price'))
192220
->will($this->throwException(new \InvalidArgumentException()));
193221

222+
$this->salableResolverMock->expects($this->once())->method('isSalable')->with($this->product)->willReturn(true);
223+
194224
$result = $this->object->toHtml();
195225

196226
//assert price wrapper

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<preference for="Magento\Catalog\Api\AttributeSetManagementInterface" type="Magento\Catalog\Model\Product\Attribute\SetManagement" />
4444
<preference for="Magento\Catalog\Api\AttributeSetRepositoryInterface" type="Magento\Catalog\Model\Product\Attribute\SetRepository" />
4545
<preference for="Magento\Catalog\Api\ProductManagementInterface" type="Magento\Catalog\Model\ProductManagement" />
46+
<preference for="Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface" type="Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver" />
4647
<type name="Magento\Customer\Model\ResourceModel\Visitor">
4748
<plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" />
4849
</type>

app/code/Magento/CatalogInventory/etc/events.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@
3333
<event name="sales_order_item_cancel">
3434
<observer name="inventory" instance="Magento\CatalogInventory\Observer\CancelOrderItemObserver"/>
3535
</event>
36-
<event name="sales_order_creditmemo_save_after">
37-
<observer name="inventory" instance="Magento\CatalogInventory\Observer\RefundOrderInventoryObserver"/>
38-
</event>
3936
<event name="catalog_product_save_after">
4037
<observer name="inventory" instance="Magento\CatalogInventory\Observer\SaveInventoryDataObserver"/>
4138
</event>

app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@ public function resolvePrice(\Magento\Framework\Pricing\SaleableInterface $produ
6464
$productPrice = $this->priceResolver->resolvePrice($subProduct);
6565
$price = $price ? min($price, $productPrice) : $productPrice;
6666
}
67-
if ($price === null) {
68-
throw new \Magento\Framework\Exception\LocalizedException(
69-
__('Configurable product "%1" does not have sub-products', $product->getSku())
70-
);
71-
}
7267

7368
return (float)$price;
7469
}

app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\ConfigurableProduct\Pricing\Render;
77

8+
use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface;
89
use Magento\Catalog\Pricing\Price\FinalPrice;
910
use Magento\Catalog\Pricing\Price\RegularPrice;
1011
use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface;
@@ -30,6 +31,7 @@ class FinalPriceBox extends \Magento\Catalog\Pricing\Render\FinalPriceBox
3031
* @param ConfigurableOptionsProviderInterface $configurableOptionsProvider
3132
* @param array $data
3233
* @param LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider
34+
* @param SalableResolverInterface $salableResolver
3335
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
3436
*/
3537
public function __construct(
@@ -39,9 +41,10 @@ public function __construct(
3941
RendererPool $rendererPool,
4042
ConfigurableOptionsProviderInterface $configurableOptionsProvider,
4143
array $data = [],
42-
LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider = null
44+
LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider = null,
45+
SalableResolverInterface $salableResolver = null
4346
) {
44-
parent::__construct($context, $saleableItem, $price, $rendererPool, $data);
47+
parent::__construct($context, $saleableItem, $price, $rendererPool, $data, $salableResolver);
4548
$this->lowestPriceOptionsProvider = $lowestPriceOptionsProvider ?:
4649
ObjectManager::getInstance()->get(LowestPriceOptionsProviderInterface::class);
4750
}

0 commit comments

Comments
 (0)