diff --git a/app/code/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php index 474c903e0df58c3237d796d50cfa7d128f65990f..7aa7ccba11758bf7841dfdd735563b95501cd7a2 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php @@ -5,6 +5,8 @@ */ namespace Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin; +use Magento\GroupedProduct\Model\Product\Type\Grouped as TypeGrouped; + class Grouped { /** @@ -22,8 +24,9 @@ class Grouped \Magento\Catalog\Model\Product $product, array $links ) { - if (isset($links['associated']) && !$product->getGroupedReadonly()) { - $product->setGroupedLinkData((array)$links['associated']); + if ($product->getTypeId() == TypeGrouped::TYPE_CODE && !$product->getGroupedReadonly()) { + $links = isset($links['associated']) ? $links['associated'] : $product->getGroupedLinkData(); + $product->setGroupedLinkData((array)$links); } } } diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php index 97ae5e92e936756064e1d94101565765dc9718bc..985ca564579493494f778b40910bb04f09f29bd6 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php @@ -6,6 +6,8 @@ */ namespace Magento\GroupedProduct\Test\Unit\Model\Product\Initialization\Helper\ProductLinks\Plugin; +use Magento\GroupedProduct\Model\Product\Type\Grouped; +use Magento\Catalog\Model\Product\Type; class GroupedTest extends \PHPUnit_Framework_TestCase { @@ -15,12 +17,12 @@ class GroupedTest extends \PHPUnit_Framework_TestCase protected $model; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */ protected $productMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks|\PHPUnit_Framework_MockObject_MockObject */ protected $subjectMock; @@ -28,7 +30,7 @@ class GroupedTest extends \PHPUnit_Framework_TestCase { $this->productMock = $this->getMock( 'Magento\Catalog\Model\Product', - ['getGroupedReadonly', 'setGroupedLinkData', '__wakeup'], + ['getGroupedReadonly', 'setGroupedLinkData', '__wakeup', 'getTypeId'], [], '', false @@ -43,22 +45,49 @@ class GroupedTest extends \PHPUnit_Framework_TestCase $this->model = new \Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin\Grouped(); } - public function testBeforeInitializeLinksRequestDoesNotHaveGrouped() + /** + * @dataProvider productTypeDataProvider + */ + public function testBeforeInitializeLinksRequestDoesNotHaveGrouped($productType) { + $this->productMock->expects($this->once())->method('getTypeId')->will($this->returnValue($productType)); $this->productMock->expects($this->never())->method('getGroupedReadonly'); $this->productMock->expects($this->never())->method('setGroupedLinkData'); $this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, []); } - public function testBeforeInitializeLinksRequestHasGrouped() + public function productTypeDataProvider() { + return [ + [Type::TYPE_SIMPLE], + [Type::TYPE_BUNDLE], + [Type::TYPE_VIRTUAL] + ]; + } + + /** + * @dataProvider linksDataProvider + */ + public function testBeforeInitializeLinksRequestHasGrouped($linksData) + { + $this->productMock->expects($this->once())->method('getTypeId')->will($this->returnValue(Grouped::TYPE_CODE)); $this->productMock->expects($this->once())->method('getGroupedReadonly')->will($this->returnValue(false)); - $this->productMock->expects($this->once())->method('setGroupedLinkData')->with(['value']); - $this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, ['associated' => 'value']); + $this->productMock->expects($this->once())->method('setGroupedLinkData')->with($linksData); + $this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, ['associated' => $linksData]); + } + + public function linksDataProvider() + { + return [ + [['associated' => [5 => ['id' => '2', 'qty' => '100', 'position' => '1']]]], + [['associated' => []]], + [[]] + ]; } public function testBeforeInitializeLinksProductIsReadonly() { + $this->productMock->expects($this->once())->method('getTypeId')->will($this->returnValue(Grouped::TYPE_CODE)); $this->productMock->expects($this->once())->method('getGroupedReadonly')->will($this->returnValue(true)); $this->productMock->expects($this->never())->method('setGroupedLinkData'); $this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, ['associated' => 'value']); diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index 01f201fd24f92568387fdfa99ae37e8064677737..9cc216d09012c88f121e7e80c35db7e165e505b5 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -1337,8 +1337,9 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C { $items = []; foreach ($this->getItemsCollection() as $item) { + /** @var \Magento\Quote\Model\Resource\Quote\Item $item */ if (!$item->isDeleted()) { - $items[] = $item; + $items[$item->getId()] = $item; } } return $items; diff --git a/app/code/Magento/Quote/Model/Quote/Item.php b/app/code/Magento/Quote/Model/Quote/Item.php index 4c82166493d5bfe5720a0353b78216bb368209ee..56ea708036533251670e39c59ed59569732de0b2 100644 --- a/app/code/Magento/Quote/Model/Quote/Item.php +++ b/app/code/Magento/Quote/Model/Quote/Item.php @@ -318,16 +318,14 @@ class Item extends \Magento\Quote\Model\Quote\Item\AbstractItem implements \Mage */ public function addQty($qty) { - $oldQty = $this->getQty(); - $qty = $this->_prepareQty($qty); - /** * We can't modify quantity of existing items which have parent * This qty declared just once during add process and is not editable */ if (!$this->getParentItem() || !$this->getId()) { + $qty = $this->_prepareQty($qty); $this->setQtyToAdd($qty); - $this->setQty($oldQty + $qty); + $this->setQty($this->getQty() + $qty); } return $this; } diff --git a/app/code/Magento/Quote/Model/Quote/Item/Processor.php b/app/code/Magento/Quote/Model/Quote/Item/Processor.php index 3e62bc5cc8c499376c94d4089c5d61a51304508b..9c0894a785ef5b343be81f6d03b95e221bb6139e 100644 --- a/app/code/Magento/Quote/Model/Quote/Item/Processor.php +++ b/app/code/Magento/Quote/Model/Quote/Item/Processor.php @@ -11,6 +11,7 @@ use Magento\Quote\Model\Quote\Item; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\State; use Magento\Framework\Object; +use Magento\Quote\Api\Data\CartItemInterface; /** * Class Processor @@ -74,7 +75,7 @@ class Processor $item->setProduct($product); if ($request->getResetCount() && !$product->getStickWithinParent() && $item->getId() === $request->getId()) { - $item->setData('qty', 0); + $item->setData(CartItemInterface::KEY_QTY, 0); } return $item; @@ -84,7 +85,7 @@ class Processor * Set qty and custom price for quote item * * @param Item $item - * @param Object $request + * @param \Magento\Framework\Object $request * @param Product $candidate * @return void */ @@ -93,6 +94,9 @@ class Processor /** * We specify qty after we know about parent (for stock) */ + if ($request->getResetCount()) { + $item->setData(CartItemInterface::KEY_QTY, 0); + } $item->addQty($candidate->getCartQty()); $customPrice = $request->getCustomPrice(); diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index dd4c469fb27149009eb95e864e4364d8c55fecb1..f341b5894b9fb0a5a5da68f92c6a5b04e79fe2ca 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -372,15 +372,6 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface protected function resolveItems(QuoteEntity $quote) { $quoteItems = $quote->getAllItems(); - for ($i = 0; $i < count($quoteItems) - 1; $i++) { - for ($j = 0; $j < count($quoteItems) - $i - 1; $j++) { - if ($quoteItems[$i]->getParentItemId() == $quoteItems[$j]->getId()) { - $tempItem = $quoteItems[$i]; - $quoteItems[$i] = $quoteItems[$j]; - $quoteItems[$j] = $tempItem; - } - } - } $orderItems = []; foreach ($quoteItems as $quoteItem) { $parentItem = (isset($orderItems[$quoteItem->getParentItemId()])) ? diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php index 809a16cc5339f42b05cc92340b617991ff9ba841..b27d2ca465a3ed917f61c7973ae980f9619ada18 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php @@ -5,9 +5,9 @@ */ namespace Magento\Quote\Test\Unit\Model\Quote\Item; -use \Magento\Quote\Model\Quote\Item\Processor; - -use \Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product; +use Magento\Quote\Api\Data\CartItemInterface; +use Magento\Quote\Model\Quote\Item\Processor; use Magento\Quote\Model\Quote\ItemFactory; use Magento\Quote\Model\Quote\Item; use Magento\Store\Model\StoreManagerInterface; @@ -109,7 +109,7 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase $this->productMock = $this->getMock( 'Magento\Catalog\Model\Product', - ['getCustomOptions', '__wakeup', 'getParentProductId'], + ['getCustomOptions', '__wakeup', 'getParentProductId', 'getCartQty'], [], '', false @@ -239,31 +239,60 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase $qty = 3000000000; $customPrice = 400000000; + $this->productMock->expects($this->any()) + ->method('getCartQty') + ->will($this->returnValue($qty)); + $this->itemMock->expects($this->any()) ->method('addQty') - ->will($this->returnValue($qty)); + ->with($qty); + + $this->objectMock->expects($this->any()) + ->method('getCustomPrice') + ->will($this->returnValue($customPrice)); $this->itemMock->expects($this->any()) ->method('setCustomPrice') ->will($this->returnValue($customPrice)); - $this->itemMock->expects($this->any()) ->method('setOriginalCustomPrice') ->will($this->returnValue($customPrice)); - $this->itemMock->expects($this->any()) - ->method('addQty') - ->will($this->returnValue($qty)); + $this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock); + } + + public function testPrepareResetCount() + { + $qty = 3000000000; + $customPrice = 400000000; + $this->objectMock->expects($this->any()) + ->method('getResetCount') + ->will($this->returnValue(true)); + + $this->itemMock->expects($this->any()) + ->method('setData') + ->with(CartItemInterface::KEY_QTY, 0); $this->productMock->expects($this->any()) ->method('getCartQty') ->will($this->returnValue($qty)); + $this->itemMock->expects($this->any()) + ->method('addQty') + ->with($qty); + $this->objectMock->expects($this->any()) ->method('getCustomPrice') ->will($this->returnValue($customPrice)); + $this->itemMock->expects($this->any()) + ->method('setCustomPrice') + ->will($this->returnValue($customPrice)); + $this->itemMock->expects($this->any()) + ->method('setOriginalCustomPrice') + ->will($this->returnValue($customPrice)); + $this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock); } } diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php new file mode 100644 index 0000000000000000000000000000000000000000..68635c4369b3c313ebe6c2ef561242bb4763b06a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Quote\Model; + +use Magento\Catalog\Model\Product\Type; +use Magento\TestFramework\Helper\Bootstrap; + +class QuoteManagementTest extends \PHPUnit_Framework_TestCase +{ + /** + * Create order with product that has child items + * + * @magentoDataFixture Magento/Sales/_files/quote_with_bundle.php + */ + public function testSubmit() + { + /** + * Preconditions: + * Load quote with Bundle product that has at least to child products + */ + $objectManager = Bootstrap::getObjectManager(); + /** @var \Magento\Quote\Model\Quote $quote */ + $quote = $objectManager->create('\Magento\Quote\Model\Quote'); + $quote->load('test01', 'reserved_order_id'); + + /** Execute SUT */ + /** @var \Magento\Quote\Model\QuoteManagement $model */ + $model = $objectManager->create('\Magento\Quote\Model\QuoteManagement'); + $order = $model->submit($quote); + + /** Check if SUT caused expected effects */ + $orderItems = $order->getItems(); + $this->assertCount(3, $orderItems); + foreach ($orderItems as $orderItem) { + if ($orderItem->getProductType() == Type::TYPE_SIMPLE) { + $this->assertNotEmpty($orderItem->getParentItem(), 'Parent is not set for child product'); + $this->assertNotEmpty($orderItem->getParentItemId(), 'Parent is not set for child product'); + } + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php index 92fc68dbe396734fa7d87b5803f7ecbb8c830e1c..c3cb9184d214ab5cdd403e493b4ea9eab8a8ad72 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php @@ -16,6 +16,7 @@ class QuoteTest extends \PHPUnit_Framework_TestCase ->create('Magento\Framework\Api\ExtensibleDataObjectConverter') ->toFlatArray($entity); } + /** * @magentoDataFixture Magento/Catalog/_files/product_virtual.php * @magentoDataFixture Magento/Sales/_files/quote.php @@ -277,6 +278,44 @@ class QuoteTest extends \PHPUnit_Framework_TestCase } } + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php + */ + public function testAddProductUpdateItem() + { + /** @var \Magento\Quote\Model\Quote $quote */ + $quote = Bootstrap::getObjectManager()->create('Magento\Quote\Model\Quote'); + $quote->load('test01', 'reserved_order_id'); + + $productStockQty = 100; + /** @var \Magento\Catalog\Model\Product $product */ + $product = Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); + $product->load(2); + $quote->addProduct($product, 50); + $quote->setTotalsCollectedFlag(false)->collectTotals(); + $this->assertEquals(50, $quote->getItemsQty()); + $quote->addProduct($product, 50); + $quote->setTotalsCollectedFlag(false)->collectTotals(); + $this->assertEquals(100, $quote->getItemsQty()); + $params = [ + 'related_product' => '', + 'product' => $product->getId(), + 'qty' => 1, + 'id' => 0 + ]; + $updateParams = new \Magento\Framework\Object($params); + $quote->updateItem($updateParams['id'], $updateParams); + $quote->setTotalsCollectedFlag(false)->collectTotals(); + $this->assertEquals(1, $quote->getItemsQty()); + + $this->setExpectedException( + '\Magento\Framework\Exception\LocalizedException', + 'We don\'t have as many "Simple Product" as you requested.' + ); + $updateParams['qty'] = $productStockQty + 1; + $quote->updateItem($updateParams['id'], $updateParams); + } + /** * Prepare quote for testing assignCustomerWithAddressChange method. * diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php index 1f4bf7f64d165cd6b26fa17f580a283626d5c778..028610784b91e0530aead51d9bbb0be94b0c93a3 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php @@ -550,7 +550,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase ); $this->assertEquals( 'Simple Product', - $this->_model->getQuote()->getAllItems()[0]->getData('name'), + $this->_model->getQuote()->getItemByProduct($product)->getData('name'), 'Precondition failed: Quote items data is invalid in create order model' ); $this->assertEquals( diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quote_with_bundle.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quote_with_bundle.php new file mode 100644 index 0000000000000000000000000000000000000000..f80113ad1119427ff2d5002b914b2f121b1fe503 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quote_with_bundle.php @@ -0,0 +1,164 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +\Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea('frontend'); +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +/** Create simple and bundle products for quote*/ +$simpleProducts[] = $objectManager->create('Magento\Catalog\Model\Product') + ->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Simple Product 1') + ->setSku('simple-1') + ->setPrice(10) + ->setDescription('Description with <b>html tag</b>') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setCategoryIds([2]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->save(); + +$simpleProducts[] = $objectManager->create('Magento\Catalog\Model\Product') + ->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(2) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Simple Product 2') + ->setSku('simple-2') + ->setPrice(10) + ->setDescription('Description with <b>html tag</b>') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setCategoryIds([2]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->save(); + +$product = $objectManager->create('Magento\Catalog\Model\Product'); +$product + ->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) + ->setId(3) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Bundle Product') + ->setSku('bundle-product') + ->setDescription('Description with <b>html tag</b>') + ->setShortDescription('Bundle') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData( + [ + 'use_config_manage_stock' => 0, + 'manage_stock' => 0, + 'use_config_enable_qty_increments' => 1, + 'use_config_qty_increments' => 1, + 'is_in_stock' => 0, + ] + ) + ->setBundleOptionsData( + [ + [ + 'title' => 'Bundle Product Items', + 'default_title' => 'Bundle Product Items', + 'type' => 'checkbox', + 'required' => 1, + 'delete' => '', + 'position' => 0, + 'option_id' => '', + ], + ] + ) + ->setBundleSelectionsData( + [ + [ + [ + 'product_id' => $simpleProducts[0]->getId(), + 'selection_qty' => 1, + 'selection_can_change_qty' => 1, + 'delete' => '', + 'position' => 0, + 'selection_price_type' => 0, + 'selection_price_value' => 0.0, + 'option_id' => '', + 'selection_id' => '', + 'is_default' => 1, + ], + [ + 'product_id' => $simpleProducts[1]->getId(), + 'selection_qty' => 1, + 'selection_can_change_qty' => 1, + 'delete' => '', + 'position' => 0, + 'selection_price_type' => 0, + 'selection_price_value' => 0.0, + 'option_id' => '', + 'selection_id' => '', + 'is_default' => 1, + ] + ], + ] + ) + ->setCanSaveBundleSelections(true) + ->setAffectBundleProductSelections(true) + ->save(); + +//Load options +$typeInstance = $product->getTypeInstance(); +$typeInstance->setStoreFilter($product->getStoreId(), $product); +$optionCollection = $typeInstance->getOptionsCollection($product); +$selectionCollection = $typeInstance->getSelectionsCollection($typeInstance->getOptionsIds($product), $product); + +$bundleOptions = []; +$bundleOptionsQty = []; +/** @var $option \Magento\Bundle\Model\Option */ +foreach ($optionCollection as $option) { + /** @var $selection \Magento\Bundle\Model\Selection */ + foreach ($selectionCollection as $selection) { + $bundleOptions[$option->getId()][] = $selection->getSelectionId(); + $bundleOptionsQty[$option->getId()][] = 1; + } +} + +$buyRequest = new \Magento\Framework\Object( + ['qty' => 1, 'bundle_option' => $bundleOptions, 'bundle_option_qty' => $bundleOptionsQty] +); +$product->setSkipCheckRequiredOption(true); + +$addressData = include __DIR__ . '/address_data.php'; +$billingAddress = $objectManager->create('Magento\Quote\Model\Quote\Address', ['data' => $addressData]); +$billingAddress->setAddressType('billing'); + +/** @var Magento\Quote\Model\Quote\Address $shippingAddress */ +$shippingAddress = clone $billingAddress; +$shippingAddress->setId(null)->setAddressType('shipping'); + +/** @var \Magento\Quote\Model\Quote $quote */ +$quote = $objectManager->create('Magento\Quote\Model\Quote'); +$quote + ->setCustomerIsGuest(true) + ->setStoreId($objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getId()) + ->setReservedOrderId('test01') + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress) + ->setCustomerEmail('test@test.magento.com') + ->addProduct($product, $buyRequest); + +/** @var $rate \Magento\Quote\Model\Quote\Address\Rate */ +$rate = $objectManager->create('Magento\Quote\Model\Quote\Address\Rate'); +$rate + ->setCode('freeshipping_freeshipping') + ->getPrice(1); + +$quote->getShippingAddress()->setShippingMethod('freeshipping_freeshipping'); +$quote->getShippingAddress()->addShippingRate($rate); +$quote->getPayment()->setMethod('checkmo'); +$quote->collectTotals(); +$quote->save(); + +/** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */ +$quoteIdMask = $objectManager->create('Magento\Quote\Model\QuoteIdMaskFactory')->create(); +$quoteIdMask->setQuoteId($quote->getId()); +$quoteIdMask->setDataChanges(true); +$quoteIdMask->save(); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quote_with_bundle_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quote_with_bundle_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..8808f9c1efe204fbaa33d9f5bf44e2992f188983 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quote_with_bundle_rollback.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $quote \Magento\Quote\Model\Quote */ +$quote = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Quote\Model\Quote'); +$quote->load('test01', 'reserved_order_id'); +if ($quote->getId()) { + $quote->delete(); +} + +/** @var $product \Magento\Catalog\Model\Product */ +$productIds = [1, 2, 3]; +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +foreach ($productIds as $productId) { + $product->load($productId); + if ($product->getId()) { + $product->delete(); + } +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false);