Skip to content

Commit dfe42fb

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-84317' into PANDA-FIXES-2.3
2 parents 81f7b73 + 3ae3a87 commit dfe42fb

File tree

5 files changed

+110
-33
lines changed

5 files changed

+110
-33
lines changed

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -411,17 +411,24 @@ public function submit(QuoteEntity $quote, $orderData = [])
411411
*/
412412
protected function resolveItems(QuoteEntity $quote)
413413
{
414-
$quoteItems = [];
415-
foreach ($quote->getAllItems() as $quoteItem) {
416-
/** @var \Magento\Quote\Model\ResourceModel\Quote\Item $quoteItem */
417-
$quoteItems[$quoteItem->getId()] = $quoteItem;
418-
}
419414
$orderItems = [];
420-
foreach ($quoteItems as $quoteItem) {
421-
$parentItem = (isset($orderItems[$quoteItem->getParentItemId()])) ?
422-
$orderItems[$quoteItem->getParentItemId()] : null;
423-
$orderItems[$quoteItem->getId()] =
424-
$this->quoteItemToOrderItem->convert($quoteItem, ['parent_item' => $parentItem]);
415+
foreach ($quote->getAllItems() as $quoteItem) {
416+
$itemId = $quoteItem->getId();
417+
418+
if (!empty($orderItems[$itemId])) {
419+
continue;
420+
}
421+
422+
$parentItemId = $quoteItem->getParentItemId();
423+
/** @var \Magento\Quote\Model\ResourceModel\Quote\Item $parentItem */
424+
if ($parentItemId && !isset($orderItems[$parentItemId])) {
425+
$orderItems[$parentItemId] = $this->quoteItemToOrderItem->convert(
426+
$quoteItem->getParentItem(),
427+
['parent_item' => null]
428+
);
429+
}
430+
$parentItem = isset($orderItems[$parentItemId]) ? $orderItems[$parentItemId] : null;
431+
$orderItems[$itemId] = $this->quoteItemToOrderItem->convert($quoteItem, ['parent_item' => $parentItem]);
425432
}
426433
return array_values($orderItems);
427434
}

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

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -156,18 +156,20 @@ protected function _afterLoad()
156156
{
157157
parent::_afterLoad();
158158

159-
/**
160-
* Assign parent items
161-
*/
159+
$productIds = [];
162160
foreach ($this as $item) {
161+
// Assign parent items
163162
if ($item->getParentItemId()) {
164163
$item->setParentItem($this->getItemById($item->getParentItemId()));
165164
}
166165
if ($this->_quote) {
167166
$item->setQuote($this->_quote);
168167
}
168+
// Collect quote products ids
169+
$productIds[] = (int)$item->getProductId();
169170
}
170-
171+
$this->_productIds = array_merge($this->_productIds, $productIds);
172+
$this->removeItemsWithAbsentProducts();
171173
/**
172174
* Assign options and products
173175
*/
@@ -205,12 +207,6 @@ protected function _assignOptions()
205207
protected function _assignProducts()
206208
{
207209
\Magento\Framework\Profiler::start('QUOTE:' . __METHOD__, ['group' => 'QUOTE', 'method' => __METHOD__]);
208-
$productIds = [];
209-
foreach ($this as $item) {
210-
$productIds[] = (int)$item->getProductId();
211-
}
212-
$this->_productIds = array_merge($this->_productIds, $productIds);
213-
214210
$productCollection = $this->_productCollectionFactory->create()->setStoreId(
215211
$this->getStoreId()
216212
)->addIdFilter(
@@ -305,4 +301,24 @@ private function addTierPriceData(ProductCollection $productCollection)
305301
$productCollection->addTierPriceDataByGroupId($this->_quote->getCustomerGroupId());
306302
}
307303
}
304+
305+
/**
306+
* Find and remove quote items with non existing products
307+
*
308+
* @return void
309+
*/
310+
private function removeItemsWithAbsentProducts()
311+
{
312+
$productCollection = $this->_productCollectionFactory->create()->addIdFilter($this->_productIds);
313+
$existingProductsIds = $productCollection->getAllIds();
314+
$absentProductsIds = array_diff($this->_productIds, $existingProductsIds);
315+
// Remove not existing products from items collection
316+
if (!empty($absentProductsIds)) {
317+
foreach ($absentProductsIds as $productIdToExclude) {
318+
/** @var \Magento\Quote\Model\Quote\Item $quoteItem */
319+
$quoteItem = $this->getItemByColumnValue('product_id', $productIdToExclude);
320+
$this->removeItemByKey($quoteItem->getId());
321+
}
322+
}
323+
}
308324
}

dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
<group value="skip"/>
2020
<!-- Skipped; see MAGETWO-89417 -->
2121
<testCaseId value="MAGETWO-82936"/>
22+
<!--Skip because of issue MAGETWO-89417-->
23+
<group value="skip"/>
2224
</annotations>
2325
<before>
2426
<actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/>

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

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,22 @@
88
use Magento\Catalog\Model\Product\Type;
99
use Magento\TestFramework\Helper\Bootstrap;
1010

11+
/**
12+
* Class for testing QuoteManagement model
13+
*/
1114
class QuoteManagementTest extends \PHPUnit\Framework\TestCase
1215
{
1316
/**
1417
* Create order with product that has child items
1518
*
19+
* @magentoAppIsolation enabled
1620
* @magentoDataFixture Magento/Sales/_files/quote_with_bundle.php
1721
*/
1822
public function testSubmit()
1923
{
2024
/**
2125
* Preconditions:
22-
* Load quote with Bundle product that has at least to child products
26+
* Load quote with Bundle product that has at least two child products
2327
*/
2428
$objectManager = Bootstrap::getObjectManager();
2529
/** @var \Magento\Quote\Model\Quote $quote */
@@ -28,8 +32,11 @@ public function testSubmit()
2832

2933
/** Execute SUT */
3034
/** @var \Magento\Quote\Api\CartManagementInterface $model */
31-
$model = $objectManager->create(\Magento\Quote\Api\CartManagementInterface::class);
32-
$order = $model->submit($quote);
35+
$cartManagement = $objectManager->create(\Magento\Quote\Api\CartManagementInterface::class);
36+
/** @var \Magento\Sales\Api\OrderRepositoryInterface $orderRepository */
37+
$orderRepository = $objectManager->create(\Magento\Sales\Api\OrderRepositoryInterface::class);
38+
$orderId = $cartManagement->placeOrder($quote->getId());
39+
$order = $orderRepository->get($orderId);
3340

3441
/** Check if SUT caused expected effects */
3542
$orderItems = $order->getItems();
@@ -41,4 +48,45 @@ public function testSubmit()
4148
}
4249
}
4350
}
51+
52+
/**
53+
* Create order with product that has child items and one of them was deleted
54+
*
55+
* @magentoAppArea adminhtml
56+
* @magentoAppIsolation enabled
57+
* @magentoDataFixture Magento/Sales/_files/quote_with_bundle.php
58+
*/
59+
public function testSubmitWithDeletedItem()
60+
{
61+
/**
62+
* Preconditions:
63+
* Load quote with Bundle product that have at least to child products
64+
*/
65+
$objectManager = Bootstrap::getObjectManager();
66+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
67+
$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
68+
$product = $productRepository->get('simple-2');
69+
$productRepository->delete($product);
70+
/** @var \Magento\Quote\Model\Quote $quote */
71+
$quote = $objectManager->create(\Magento\Quote\Model\Quote::class);
72+
$quote->load('test01', 'reserved_order_id');
73+
74+
/** Execute SUT */
75+
/** @var \Magento\Quote\Api\CartManagementInterface $model */
76+
$cartManagement = $objectManager->create(\Magento\Quote\Api\CartManagementInterface::class);
77+
/** @var \Magento\Sales\Api\OrderRepositoryInterface $orderRepository */
78+
$orderRepository = $objectManager->create(\Magento\Sales\Api\OrderRepositoryInterface::class);
79+
$orderId = $cartManagement->placeOrder($quote->getId());
80+
$order = $orderRepository->get($orderId);
81+
82+
/** Check if SUT caused expected effects */
83+
$orderItems = $order->getItems();
84+
$this->assertCount(2, $orderItems);
85+
foreach ($orderItems as $orderItem) {
86+
if ($orderItem->getProductType() == Type::TYPE_SIMPLE) {
87+
$this->assertNotEmpty($orderItem->getParentItem(), 'Parent is not set for child product');
88+
$this->assertNotEmpty($orderItem->getParentItemId(), 'Parent is not set for child product');
89+
}
90+
}
91+
}
4492
}

dev/tests/integration/testsuite/Magento/Sales/_files/quote_with_bundle_rollback.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,29 @@
44
* See COPYING.txt for license details.
55
*/
66

7+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
78
/** @var \Magento\Framework\Registry $registry */
8-
$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
9+
$registry = $objectManager->get(\Magento\Framework\Registry::class);
910
$registry->unregister('isSecureArea');
1011
$registry->register('isSecureArea', true);
1112

13+
// Delete quote
1214
/** @var $quote \Magento\Quote\Model\Quote */
13-
$quote = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Quote\Model\Quote::class);
15+
$quote = $objectManager->create(\Magento\Quote\Model\Quote::class);
1416
$quote->load('test01', 'reserved_order_id');
1517
if ($quote->getId()) {
1618
$quote->delete();
1719
}
18-
19-
/** @var $product \Magento\Catalog\Model\Product */
20-
$productIds = [1, 2, 3];
21-
$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class);
22-
foreach ($productIds as $productId) {
23-
$product->load($productId);
24-
if ($product->getId()) {
25-
$product->delete();
20+
// Delete products
21+
$productSkus = ['simple-1', 'simple-2', 'bundle-product'];
22+
/** @var Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
23+
$productRepository = $objectManager->get(Magento\Catalog\Api\ProductRepositoryInterface::class);
24+
foreach ($productSkus as $sku) {
25+
try {
26+
$product = $productRepository->get($sku, false, null, true);
27+
$productRepository->delete($product);
28+
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
29+
//Product already removed
2630
}
2731
}
2832

0 commit comments

Comments
 (0)