Skip to content

Commit 86646fc

Browse files
author
Kasian,Andrii(akasian)
committed
Merge pull request #364 from magento-dragons/S69
[DRAGONS] - S69
2 parents dcda524 + 6f64661 commit 86646fc

File tree

12 files changed

+367
-35
lines changed

12 files changed

+367
-35
lines changed

app/code/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin;
77

8+
use Magento\GroupedProduct\Model\Product\Type\Grouped as TypeGrouped;
9+
810
class Grouped
911
{
1012
/**
@@ -22,8 +24,9 @@ public function beforeInitializeLinks(
2224
\Magento\Catalog\Model\Product $product,
2325
array $links
2426
) {
25-
if (isset($links['associated']) && !$product->getGroupedReadonly()) {
26-
$product->setGroupedLinkData((array)$links['associated']);
27+
if ($product->getTypeId() == TypeGrouped::TYPE_CODE && !$product->getGroupedReadonly()) {
28+
$links = isset($links['associated']) ? $links['associated'] : $product->getGroupedLinkData();
29+
$product->setGroupedLinkData((array)$links);
2730
}
2831
}
2932
}

app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77
namespace Magento\GroupedProduct\Test\Unit\Model\Product\Initialization\Helper\ProductLinks\Plugin;
88

9+
use Magento\GroupedProduct\Model\Product\Type\Grouped;
10+
use Magento\Catalog\Model\Product\Type;
911

1012
class GroupedTest extends \PHPUnit_Framework_TestCase
1113
{
@@ -15,20 +17,20 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
1517
protected $model;
1618

1719
/**
18-
* @var \PHPUnit_Framework_MockObject_MockObject
20+
* @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
1921
*/
2022
protected $productMock;
2123

2224
/**
23-
* @var \PHPUnit_Framework_MockObject_MockObject
25+
* @var \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks|\PHPUnit_Framework_MockObject_MockObject
2426
*/
2527
protected $subjectMock;
2628

2729
protected function setUp()
2830
{
2931
$this->productMock = $this->getMock(
3032
'Magento\Catalog\Model\Product',
31-
['getGroupedReadonly', 'setGroupedLinkData', '__wakeup'],
33+
['getGroupedReadonly', 'setGroupedLinkData', '__wakeup', 'getTypeId'],
3234
[],
3335
'',
3436
false
@@ -43,22 +45,49 @@ protected function setUp()
4345
$this->model = new \Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin\Grouped();
4446
}
4547

46-
public function testBeforeInitializeLinksRequestDoesNotHaveGrouped()
48+
/**
49+
* @dataProvider productTypeDataProvider
50+
*/
51+
public function testBeforeInitializeLinksRequestDoesNotHaveGrouped($productType)
4752
{
53+
$this->productMock->expects($this->once())->method('getTypeId')->will($this->returnValue($productType));
4854
$this->productMock->expects($this->never())->method('getGroupedReadonly');
4955
$this->productMock->expects($this->never())->method('setGroupedLinkData');
5056
$this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, []);
5157
}
5258

53-
public function testBeforeInitializeLinksRequestHasGrouped()
59+
public function productTypeDataProvider()
5460
{
61+
return [
62+
[Type::TYPE_SIMPLE],
63+
[Type::TYPE_BUNDLE],
64+
[Type::TYPE_VIRTUAL]
65+
];
66+
}
67+
68+
/**
69+
* @dataProvider linksDataProvider
70+
*/
71+
public function testBeforeInitializeLinksRequestHasGrouped($linksData)
72+
{
73+
$this->productMock->expects($this->once())->method('getTypeId')->will($this->returnValue(Grouped::TYPE_CODE));
5574
$this->productMock->expects($this->once())->method('getGroupedReadonly')->will($this->returnValue(false));
56-
$this->productMock->expects($this->once())->method('setGroupedLinkData')->with(['value']);
57-
$this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, ['associated' => 'value']);
75+
$this->productMock->expects($this->once())->method('setGroupedLinkData')->with($linksData);
76+
$this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, ['associated' => $linksData]);
77+
}
78+
79+
public function linksDataProvider()
80+
{
81+
return [
82+
[['associated' => [5 => ['id' => '2', 'qty' => '100', 'position' => '1']]]],
83+
[['associated' => []]],
84+
[[]]
85+
];
5886
}
5987

6088
public function testBeforeInitializeLinksProductIsReadonly()
6189
{
90+
$this->productMock->expects($this->once())->method('getTypeId')->will($this->returnValue(Grouped::TYPE_CODE));
6291
$this->productMock->expects($this->once())->method('getGroupedReadonly')->will($this->returnValue(true));
6392
$this->productMock->expects($this->never())->method('setGroupedLinkData');
6493
$this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, ['associated' => 'value']);

app/code/Magento/Quote/Model/Quote.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1337,8 +1337,9 @@ public function getAllItems()
13371337
{
13381338
$items = [];
13391339
foreach ($this->getItemsCollection() as $item) {
1340+
/** @var \Magento\Quote\Model\Resource\Quote\Item $item */
13401341
if (!$item->isDeleted()) {
1341-
$items[] = $item;
1342+
$items[$item->getId()] = $item;
13421343
}
13431344
}
13441345
return $items;

app/code/Magento/Quote/Model/Quote/Item.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,16 +318,14 @@ protected function _prepareQty($qty)
318318
*/
319319
public function addQty($qty)
320320
{
321-
$oldQty = $this->getQty();
322-
$qty = $this->_prepareQty($qty);
323-
324321
/**
325322
* We can't modify quantity of existing items which have parent
326323
* This qty declared just once during add process and is not editable
327324
*/
328325
if (!$this->getParentItem() || !$this->getId()) {
326+
$qty = $this->_prepareQty($qty);
329327
$this->setQtyToAdd($qty);
330-
$this->setQty($oldQty + $qty);
328+
$this->setQty($this->getQty() + $qty);
331329
}
332330
return $this;
333331
}

app/code/Magento/Quote/Model/Quote/Item/Processor.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Magento\Store\Model\StoreManagerInterface;
1212
use Magento\Framework\App\State;
1313
use Magento\Framework\Object;
14+
use Magento\Quote\Api\Data\CartItemInterface;
1415

1516
/**
1617
* Class Processor
@@ -74,7 +75,7 @@ public function init(Product $product, $request)
7475
$item->setProduct($product);
7576

7677
if ($request->getResetCount() && !$product->getStickWithinParent() && $item->getId() === $request->getId()) {
77-
$item->setData('qty', 0);
78+
$item->setData(CartItemInterface::KEY_QTY, 0);
7879
}
7980

8081
return $item;
@@ -84,7 +85,7 @@ public function init(Product $product, $request)
8485
* Set qty and custom price for quote item
8586
*
8687
* @param Item $item
87-
* @param Object $request
88+
* @param \Magento\Framework\Object $request
8889
* @param Product $candidate
8990
* @return void
9091
*/
@@ -93,6 +94,9 @@ public function prepare(Item $item, Object $request, Product $candidate)
9394
/**
9495
* We specify qty after we know about parent (for stock)
9596
*/
97+
if ($request->getResetCount()) {
98+
$item->setData(CartItemInterface::KEY_QTY, 0);
99+
}
96100
$item->addQty($candidate->getCartQty());
97101

98102
$customPrice = $request->getCustomPrice();

app/code/Magento/Quote/Model/QuoteManagement.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -372,15 +372,6 @@ public function submit(QuoteEntity $quote, $orderData = [])
372372
protected function resolveItems(QuoteEntity $quote)
373373
{
374374
$quoteItems = $quote->getAllItems();
375-
for ($i = 0; $i < count($quoteItems) - 1; $i++) {
376-
for ($j = 0; $j < count($quoteItems) - $i - 1; $j++) {
377-
if ($quoteItems[$i]->getParentItemId() == $quoteItems[$j]->getId()) {
378-
$tempItem = $quoteItems[$i];
379-
$quoteItems[$i] = $quoteItems[$j];
380-
$quoteItems[$j] = $tempItem;
381-
}
382-
}
383-
}
384375
$orderItems = [];
385376
foreach ($quoteItems as $quoteItem) {
386377
$parentItem = (isset($orderItems[$quoteItem->getParentItemId()])) ?

app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
*/
66
namespace Magento\Quote\Test\Unit\Model\Quote\Item;
77

8-
use \Magento\Quote\Model\Quote\Item\Processor;
9-
10-
use \Magento\Catalog\Model\Product;
8+
use Magento\Catalog\Model\Product;
9+
use Magento\Quote\Api\Data\CartItemInterface;
10+
use Magento\Quote\Model\Quote\Item\Processor;
1111
use Magento\Quote\Model\Quote\ItemFactory;
1212
use Magento\Quote\Model\Quote\Item;
1313
use Magento\Store\Model\StoreManagerInterface;
@@ -109,7 +109,7 @@ protected function setUp()
109109

110110
$this->productMock = $this->getMock(
111111
'Magento\Catalog\Model\Product',
112-
['getCustomOptions', '__wakeup', 'getParentProductId'],
112+
['getCustomOptions', '__wakeup', 'getParentProductId', 'getCartQty'],
113113
[],
114114
'',
115115
false
@@ -239,31 +239,60 @@ public function testPrepare()
239239
$qty = 3000000000;
240240
$customPrice = 400000000;
241241

242+
$this->productMock->expects($this->any())
243+
->method('getCartQty')
244+
->will($this->returnValue($qty));
245+
242246
$this->itemMock->expects($this->any())
243247
->method('addQty')
244-
->will($this->returnValue($qty));
248+
->with($qty);
249+
250+
$this->objectMock->expects($this->any())
251+
->method('getCustomPrice')
252+
->will($this->returnValue($customPrice));
245253

246254
$this->itemMock->expects($this->any())
247255
->method('setCustomPrice')
248256
->will($this->returnValue($customPrice));
249-
250257
$this->itemMock->expects($this->any())
251258
->method('setOriginalCustomPrice')
252259
->will($this->returnValue($customPrice));
253260

254-
$this->itemMock->expects($this->any())
255-
->method('addQty')
256-
->will($this->returnValue($qty));
261+
$this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock);
262+
}
263+
264+
public function testPrepareResetCount()
265+
{
266+
$qty = 3000000000;
267+
$customPrice = 400000000;
257268

269+
$this->objectMock->expects($this->any())
270+
->method('getResetCount')
271+
->will($this->returnValue(true));
272+
273+
$this->itemMock->expects($this->any())
274+
->method('setData')
275+
->with(CartItemInterface::KEY_QTY, 0);
258276

259277
$this->productMock->expects($this->any())
260278
->method('getCartQty')
261279
->will($this->returnValue($qty));
262280

281+
$this->itemMock->expects($this->any())
282+
->method('addQty')
283+
->with($qty);
284+
263285
$this->objectMock->expects($this->any())
264286
->method('getCustomPrice')
265287
->will($this->returnValue($customPrice));
266288

289+
$this->itemMock->expects($this->any())
290+
->method('setCustomPrice')
291+
->will($this->returnValue($customPrice));
292+
$this->itemMock->expects($this->any())
293+
->method('setOriginalCustomPrice')
294+
->will($this->returnValue($customPrice));
295+
267296
$this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock);
268297
}
269298
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Quote\Model;
7+
8+
use Magento\Catalog\Model\Product\Type;
9+
use Magento\TestFramework\Helper\Bootstrap;
10+
11+
class QuoteManagementTest extends \PHPUnit_Framework_TestCase
12+
{
13+
/**
14+
* Create order with product that has child items
15+
*
16+
* @magentoDataFixture Magento/Sales/_files/quote_with_bundle.php
17+
*/
18+
public function testSubmit()
19+
{
20+
/**
21+
* Preconditions:
22+
* Load quote with Bundle product that has at least to child products
23+
*/
24+
$objectManager = Bootstrap::getObjectManager();
25+
/** @var \Magento\Quote\Model\Quote $quote */
26+
$quote = $objectManager->create('\Magento\Quote\Model\Quote');
27+
$quote->load('test01', 'reserved_order_id');
28+
29+
/** Execute SUT */
30+
/** @var \Magento\Quote\Model\QuoteManagement $model */
31+
$model = $objectManager->create('\Magento\Quote\Model\QuoteManagement');
32+
$order = $model->submit($quote);
33+
34+
/** Check if SUT caused expected effects */
35+
$orderItems = $order->getItems();
36+
$this->assertCount(3, $orderItems);
37+
foreach ($orderItems as $orderItem) {
38+
if ($orderItem->getProductType() == Type::TYPE_SIMPLE) {
39+
$this->assertNotEmpty($orderItem->getParentItem(), 'Parent is not set for child product');
40+
$this->assertNotEmpty($orderItem->getParentItemId(), 'Parent is not set for child product');
41+
}
42+
}
43+
}
44+
}

dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ private function convertToArray($entity)
1616
->create('Magento\Framework\Api\ExtensibleDataObjectConverter')
1717
->toFlatArray($entity);
1818
}
19+
1920
/**
2021
* @magentoDataFixture Magento/Catalog/_files/product_virtual.php
2122
* @magentoDataFixture Magento/Sales/_files/quote.php
@@ -277,6 +278,44 @@ public function testAssignCustomerWithAddressChange()
277278
}
278279
}
279280

281+
/**
282+
* @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php
283+
*/
284+
public function testAddProductUpdateItem()
285+
{
286+
/** @var \Magento\Quote\Model\Quote $quote */
287+
$quote = Bootstrap::getObjectManager()->create('Magento\Quote\Model\Quote');
288+
$quote->load('test01', 'reserved_order_id');
289+
290+
$productStockQty = 100;
291+
/** @var \Magento\Catalog\Model\Product $product */
292+
$product = Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
293+
$product->load(2);
294+
$quote->addProduct($product, 50);
295+
$quote->setTotalsCollectedFlag(false)->collectTotals();
296+
$this->assertEquals(50, $quote->getItemsQty());
297+
$quote->addProduct($product, 50);
298+
$quote->setTotalsCollectedFlag(false)->collectTotals();
299+
$this->assertEquals(100, $quote->getItemsQty());
300+
$params = [
301+
'related_product' => '',
302+
'product' => $product->getId(),
303+
'qty' => 1,
304+
'id' => 0
305+
];
306+
$updateParams = new \Magento\Framework\Object($params);
307+
$quote->updateItem($updateParams['id'], $updateParams);
308+
$quote->setTotalsCollectedFlag(false)->collectTotals();
309+
$this->assertEquals(1, $quote->getItemsQty());
310+
311+
$this->setExpectedException(
312+
'\Magento\Framework\Exception\LocalizedException',
313+
'We don\'t have as many "Simple Product" as you requested.'
314+
);
315+
$updateParams['qty'] = $productStockQty + 1;
316+
$quote->updateItem($updateParams['id'], $updateParams);
317+
}
318+
280319
/**
281320
* Prepare quote for testing assignCustomerWithAddressChange method.
282321
*

dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ protected function _preparePreconditionsForCreateOrder(
550550
);
551551
$this->assertEquals(
552552
'Simple Product',
553-
$this->_model->getQuote()->getAllItems()[0]->getData('name'),
553+
$this->_model->getQuote()->getItemByProduct($product)->getData('name'),
554554
'Precondition failed: Quote items data is invalid in create order model'
555555
);
556556
$this->assertEquals(

0 commit comments

Comments
 (0)