Skip to content

Commit c614b9c

Browse files
Merge pull request #352 from magento-nord/develop
Bugs: MAGETWO-56534 Price in cart does not update correctly when price is changed in admin. - for Mainline MAGETWO-57135 Product import with images not working MAGETWO-56054 [GitHub] Admin >New order: 'Recently Viewed Products' has 0 price value #5810
2 parents 25ee7e2 + 32ed255 commit c614b9c

File tree

8 files changed

+215
-48
lines changed

8 files changed

+215
-48
lines changed

app/code/Magento/CatalogImportExport/Model/Import/Uploader.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ public function move($fileName, $renameFileOff = false)
155155

156156
$filePath = $this->_directory->getRelativePath($this->getTmpDir() . '/' . $fileName);
157157
$this->_setUploadFile($filePath);
158-
$result = $this->save($this->getDestDir());
158+
$destDir = $this->_directory->getAbsolutePath($this->getDestDir());
159+
$result = $this->save($destDir);
159160
$result['name'] = self::getCorrectFileName($result['name']);
160161
return $result;
161162
}
@@ -305,11 +306,10 @@ protected function _moveFile($tmpPath, $destPath)
305306
$tmpRealPath = $this->_directory->getDriver()->getRealPath(
306307
$this->_directory->getAbsolutePath($tmpPath)
307308
);
308-
$destinationRealPath = $this->_directory->getDriver()->getRealPath(
309-
$this->_directory->getAbsolutePath($destPath)
310-
);
309+
$destinationRealPath = $this->_directory->getDriver()->getRealPath($destPath);
310+
$relativeDestPath = $this->_directory->getRelativePath($destPath);
311311
$isSameFile = $tmpRealPath === $destinationRealPath;
312-
return $isSameFile ?: $this->_directory->copyFile($tmpPath, $destPath);
312+
return $isSameFile ?: $this->_directory->copyFile($tmpPath, $relativeDestPath);
313313
} else {
314314
return false;
315315
}

app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ protected function setUp()
6868

6969
$this->readFactory = $this->getMockBuilder(\Magento\Framework\Filesystem\File\ReadFactory::class)
7070
->disableOriginalConstructor()
71+
->setMethods(['create'])
7172
->getMock();
7273

7374
$this->directoryMock = $this->getMockBuilder(\Magento\Framework\Filesystem\Directory\Writer::class)
74-
->setMethods(['writeFile', 'getRelativePath'])
75+
->setMethods(['writeFile', 'getRelativePath', 'isWritable', 'getAbsolutePath'])
7576
->disableOriginalConstructor()
7677
->getMock();
7778

@@ -92,6 +93,7 @@ protected function setUp()
9293
$this->filesystem,
9394
$this->readFactory,
9495
])
96+
->setMethods(['_setUploadFile', 'save', 'getTmpDir'])
9597
->getMock();
9698
}
9799

@@ -100,10 +102,14 @@ protected function setUp()
100102
*/
101103
public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName)
102104
{
105+
$destDir = 'var/dest/dir';
103106
$expectedRelativeFilePath = $this->uploader->getTmpDir() . '/' . $expectedFileName;
107+
$this->directoryMock->expects($this->once())->method('isWritable')->with($destDir)->willReturn(true);
104108
$this->directoryMock->expects($this->any())->method('getRelativePath')->with($expectedRelativeFilePath);
109+
$this->directoryMock->expects($this->once())->method('getAbsolutePath')->with($destDir)
110+
->willReturn($destDir . '/' . $expectedFileName);
105111
// Check writeFile() method invoking.
106-
$this->directoryMock->expects($this->any())->method('writeFile')->will($this->returnValue(null));
112+
$this->directoryMock->expects($this->any())->method('writeFile')->will($this->returnValue($expectedFileName));
107113

108114
// Create adjusted reader which does not validate path.
109115
$readMock = $this->getMockBuilder(\Magento\Framework\Filesystem\File\Read::class)
@@ -113,59 +119,37 @@ public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName)
113119
// Check readAll() method invoking.
114120
$readMock->expects($this->once())->method('readAll')->will($this->returnValue(null));
115121

116-
$this->readFactory = $this->getMockBuilder(\Magento\Framework\Filesystem\File\ReadFactory::class)
117-
->disableOriginalConstructor()
118-
->setMethods(['create'])
119-
->getMock();
120122
// Check create() method invoking with expected argument.
121123
$this->readFactory->expects($this->once())
122124
->method('create')
123125
->will($this->returnValue($readMock))->with($expectedHost);
124-
125-
$uploaderMock = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Uploader::class)
126-
->setConstructorArgs([
127-
$this->coreFileStorageDb,
128-
$this->coreFileStorage,
129-
$this->imageFactory,
130-
$this->validator,
131-
$this->filesystem,
132-
$this->readFactory,
133-
])
134-
->setMethods(['_setUploadFile', 'save', 'getTmpDir'])
135-
->getMock();
136-
137126
//Check invoking of getTmpDir(), _setUploadFile(), save() methods.
138-
$uploaderMock->expects($this->any())->method('getTmpDir')->will($this->returnValue(''));
139-
$uploaderMock->expects($this->once())->method('_setUploadFile')->will($this->returnSelf());
140-
$uploaderMock->expects($this->once())->method('save')->will($this->returnValue(['name' => null]));
127+
$this->uploader->expects($this->any())->method('getTmpDir')->will($this->returnValue(''));
128+
$this->uploader->expects($this->once())->method('_setUploadFile')->will($this->returnSelf());
129+
$this->uploader->expects($this->once())->method('save')->with($destDir . '/' . $expectedFileName)
130+
->willReturn(['name' => $expectedFileName]);
141131

142-
$uploaderMock->move($fileUrl);
132+
$this->uploader->setDestDir($destDir);
133+
$this->assertEquals(['name' => $expectedFileName], $this->uploader->move($fileUrl));
143134
}
144135

145136
public function testMoveFileName()
146137
{
138+
$destDir = 'var/dest/dir';
147139
$fileName = 'test_uploader_file';
148140
$expectedRelativeFilePath = $this->uploader->getTmpDir() . '/' . $fileName;
141+
$this->directoryMock->expects($this->once())->method('isWritable')->with($destDir)->willReturn(true);
149142
$this->directoryMock->expects($this->any())->method('getRelativePath')->with($expectedRelativeFilePath);
150-
151-
$uploaderMock = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Uploader::class)
152-
->setConstructorArgs([
153-
$this->coreFileStorageDb,
154-
$this->coreFileStorage,
155-
$this->imageFactory,
156-
$this->validator,
157-
$this->filesystem,
158-
$this->readFactory,
159-
])
160-
->setMethods(['_setUploadFile', 'save', 'getTmpDir'])
161-
->getMock();
162-
143+
$this->directoryMock->expects($this->once())->method('getAbsolutePath')->with($destDir)
144+
->willReturn($destDir . '/' . $fileName);
163145
//Check invoking of getTmpDir(), _setUploadFile(), save() methods.
164-
$uploaderMock->expects($this->once())->method('getTmpDir')->will($this->returnValue(''));
165-
$uploaderMock->expects($this->once())->method('_setUploadFile')->will($this->returnSelf());
166-
$uploaderMock->expects($this->once())->method('save')->will($this->returnValue(['name' => null]));
146+
$this->uploader->expects($this->once())->method('getTmpDir')->will($this->returnValue(''));
147+
$this->uploader->expects($this->once())->method('_setUploadFile')->will($this->returnSelf());
148+
$this->uploader->expects($this->once())->method('save')->with($destDir . '/' . $fileName)
149+
->willReturn(['name' => $fileName]);
167150

168-
$uploaderMock->move($fileName);
151+
$this->uploader->setDestDir($destDir);
152+
$this->assertEquals(['name' => $fileName], $this->uploader->move($fileName));
169153
}
170154

171155
public function moveFileUrlDataProvider()
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Quote\Model\Product\Plugin;
7+
8+
class UpdateQuoteItems
9+
{
10+
/**
11+
* @var \Magento\Quote\Model\ResourceModel\Quote
12+
*/
13+
private $resource;
14+
15+
/**
16+
* @param \Magento\Quote\Model\ResourceModel\Quote $resource
17+
*/
18+
public function __construct(
19+
\Magento\Quote\Model\ResourceModel\Quote $resource
20+
) {
21+
$this->resource = $resource;
22+
}
23+
24+
/**
25+
* @param \Magento\Catalog\Model\ResourceModel\Product $subject
26+
* @param \Magento\Catalog\Model\ResourceModel\Product $result
27+
* @param \Magento\Framework\Model\AbstractModel $product
28+
* @return \Magento\Catalog\Model\ResourceModel\Product
29+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
30+
*/
31+
public function afterSave(
32+
\Magento\Catalog\Model\ResourceModel\Product $subject,
33+
\Magento\Catalog\Model\ResourceModel\Product $result,
34+
\Magento\Framework\Model\AbstractModel $product
35+
) {
36+
$originalPrice = $product->getOrigData('price');
37+
if (!empty($originalPrice) && ($originalPrice != $product->getPrice())) {
38+
$this->resource->markQuotesRecollect($product->getId());
39+
}
40+
return $result;
41+
}
42+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Quote\Test\Unit\Model\Product\Plugin;
7+
8+
class UpdateQuoteItemsTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @var \Magento\Quote\Model\Product\Plugin\UpdateQuoteItems
12+
*/
13+
private $model;
14+
15+
/**
16+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Quote\Model\ResourceModel\Quote
17+
*/
18+
private $quoteResource ;
19+
20+
protected function setUp()
21+
{
22+
$this->quoteResource = $this->getMockBuilder(\Magento\Quote\Model\ResourceModel\Quote::class)
23+
->disableOriginalConstructor()
24+
->getMock();
25+
$this->model = new \Magento\Quote\Model\Product\Plugin\UpdateQuoteItems($this->quoteResource);
26+
}
27+
28+
/**
29+
* @dataProvider aroundUpdateDataProvider
30+
* @param int $originalPrice
31+
* @param int $newPrice
32+
* @param bool $callMethod
33+
*/
34+
public function testAfterUpdate($originalPrice, $newPrice, $callMethod)
35+
{
36+
$productResourceMock = $this->getMock(\Magento\Catalog\Model\ResourceModel\Product::class, [], [], '', false);
37+
$productMock = $this->getMockBuilder(\Magento\Framework\Model\AbstractModel::class)
38+
->disableOriginalConstructor()
39+
->setMethods(['getOrigData', 'getPrice', 'getId'])
40+
->getMockForAbstractClass();
41+
$productId = 1;
42+
$productMock->expects($this->any())->method('getOrigData')->with('price')->willReturn($originalPrice);
43+
$productMock->expects($this->any())->method('getPrice')->willReturn($newPrice);
44+
$productMock->expects($this->any())->method('getId')->willReturn($productId);
45+
$this->quoteResource->expects($this->$callMethod())->method('markQuotesRecollect')->with($productId);
46+
$result = $this->model->afterSave($productResourceMock, $productResourceMock, $productMock);
47+
$this->assertEquals($result, $productResourceMock);
48+
}
49+
50+
public function aroundUpdateDataProvider()
51+
{
52+
return [
53+
[10, 20, 'once'],
54+
[null, 10, 'never'],
55+
[10, 10, 'never']
56+
];
57+
}
58+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,6 @@
9292
<preference for="Magento\Quote\Model\Product\QuoteItemsCleanerInterface" type="Magento\Quote\Model\Product\QuoteItemsCleaner" />
9393
<type name="Magento\Catalog\Model\ResourceModel\Product">
9494
<plugin name="clean_quote_items_after_product_delete" type="Magento\Quote\Model\Product\Plugin\RemoveQuoteItems"/>
95+
<plugin name="update_quote_items_after_product_save" type="Magento\Quote\Model\Product\Plugin\UpdateQuoteItems"/>
9596
</type>
9697
</config>

app/code/Magento/Sales/Block/Adminhtml/Order/Create/AbstractCreate.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
namespace Magento\Sales\Block\Adminhtml\Order\Create;
77

88
use Magento\Framework\Pricing\PriceCurrencyInterface;
9+
use Magento\Catalog\Model\Product;
10+
use Magento\Catalog\Pricing\Price\FinalPrice;
911

1012
/**
1113
* Adminhtml sales order create abstract block
@@ -130,12 +132,22 @@ public function formatPrice($value)
130132
);
131133
}
132134

135+
/**
136+
* @param Product $product
137+
* @return string
138+
*/
139+
public function getItemPrice(Product $product)
140+
{
141+
$price = $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue();
142+
return $this->convertPrice($price);
143+
}
144+
133145
/**
134146
* Convert price
135147
*
136-
* @param float $value
148+
* @param int|float $value
137149
* @param bool $format
138-
* @return float
150+
* @return string|int|float
139151
*/
140152
public function convertPrice($value, $format = true)
141153
{
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Sales\Test\Unit\Block\Adminhtml\Order\Create;
7+
8+
use Magento\Catalog\Pricing\Price\FinalPrice;
9+
10+
class AbstractCreateTest extends \PHPUnit_Framework_TestCase
11+
{
12+
/**
13+
* @var \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate|\PHPUnit_Framework_MockObject_MockObject
14+
*/
15+
protected $model;
16+
17+
/**
18+
* @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
19+
*/
20+
protected $productMock;
21+
22+
/**
23+
* @var \Magento\Framework\Pricing\PriceInfo\Base|\PHPUnit_Framework_MockObject_MockObject
24+
*/
25+
protected $priceInfoMock;
26+
27+
/**
28+
* @var \Magento\Downloadable\Pricing\Price\LinkPrice|\PHPUnit_Framework_MockObject_MockObject
29+
*/
30+
protected $linkPriceMock;
31+
32+
protected function setUp()
33+
{
34+
$this->model = $this->getMockBuilder(\Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate::class)
35+
->setMethods(['convertPrice'])
36+
->disableOriginalConstructor()
37+
->getMockForAbstractClass();
38+
$this->priceInfoMock = $this->getMockBuilder(\Magento\Framework\Pricing\PriceInfo\Base::class)
39+
->disableOriginalConstructor()
40+
->getMock();
41+
$this->productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
42+
->disableOriginalConstructor()
43+
->getMock();
44+
$this->linkPriceMock = $this->getMockBuilder(\Magento\Downloadable\Pricing\Price\LinkPrice::class)
45+
->disableOriginalConstructor()
46+
->getMock();
47+
$this->productMock->expects($this->any())
48+
->method('getPriceInfo')
49+
->willReturn($this->priceInfoMock);
50+
}
51+
52+
public function testGetItemPrice()
53+
{
54+
$price = 5.6;
55+
$resultPrice = 9.3;
56+
57+
$this->linkPriceMock->expects($this->once())
58+
->method('getValue')
59+
->willReturn($price);
60+
$this->priceInfoMock->expects($this->once())
61+
->method('getPrice')
62+
->with(FinalPrice::PRICE_CODE)
63+
->willReturn($this->linkPriceMock);
64+
$this->model->expects($this->once())
65+
->method('convertPrice')
66+
->with($price)
67+
->willReturn($resultPrice);
68+
$this->assertEquals($resultPrice, $this->model->getItemPrice($this->productMock));
69+
}
70+
}

app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
<?php endif; ?>
6767

6868
<?php if ($block->canDisplayPrice()): ?>
69-
<td class="col-price"><?php /* @escapeNotVerified */ echo $block->convertPrice($_item->getPrice()) ?></td>
69+
<td class="col-price"><?php /* @noEscape */ echo $block->getItemPrice($_item) ?></td>
7070
<?php endif; ?>
7171

7272
<?php if ($block->canRemoveItems()): ?>

0 commit comments

Comments
 (0)