diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index 3cdcf70cf2426..f84ca33b436f9 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -2157,6 +2157,12 @@ public function reserveOrderId() { if (!$this->getReservedOrderId()) { $this->setReservedOrderId($this->_getResource()->getReservedOrderId($this)); + } else { + //checking if reserved order id was already used for some order + //if yes reserving new one if not using old one + if ($this->_getResource()->isOrderIncrementIdUsed($this->getReservedOrderId())) { + $this->setReservedOrderId($this->_getResource()->getReservedOrderId($this)); + } } return $this; } diff --git a/app/code/Magento/Quote/Model/ResourceModel/Quote.php b/app/code/Magento/Quote/Model/ResourceModel/Quote.php index 241f0d6b272fc..72172c128c58c 100644 --- a/app/code/Magento/Quote/Model/ResourceModel/Quote.php +++ b/app/code/Magento/Quote/Model/ResourceModel/Quote.php @@ -172,6 +172,28 @@ public function getReservedOrderId($quote) ->getNextValue(); } + /** + * Check is order increment id use in sales/order table + * + * @param int $orderIncrementId + * @return bool + */ + public function isOrderIncrementIdUsed($orderIncrementId) + { + /** @var \Magento\Framework\DB\Adapter\AdapterInterface $adapter */ + $adapter = $this->getConnection(); + $bind = [':increment_id' => $orderIncrementId]; + /** @var \Magento\Framework\DB\Select $select */ + $select = $adapter->select(); + $select->from($this->getTable('sales_order'), 'entity_id')->where('increment_id = :increment_id'); + $entity_id = $adapter->fetchOne($select, $bind); + if ($entity_id > 0) { + return true; + } + + return false; + } + /** * Mark quotes - that depend on catalog price rules - to be recollected on demand * diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php index 5165f299d45a9..b54ce84fe1ac4 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php @@ -314,7 +314,10 @@ protected function setUp() 'customerRepository' => $this->customerRepositoryMock, 'objectCopyService' => $this->objectCopyServiceMock, 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock, - 'customerDataFactory' => $this->customerDataFactoryMock + 'customerDataFactory' => $this->customerDataFactoryMock, + 'data' => [ + 'reserved_order_id' => 1000001 + ] ] ); } @@ -1237,4 +1240,30 @@ public function testGetAllItems() $this->assertEquals($itemResult, $this->quote->getAllItems()); } + + /** + * Test to verify if existing reserved_order_id in use + * + * @param bool $isReservedOrderIdExist + * @param int $reservedOrderId + * @dataProvider reservedOrderIdDataProvider + */ + public function testReserveOrderId($isReservedOrderIdExist, $reservedOrderId) + { + $this->resourceMock + ->expects($this->once()) + ->method('isOrderIncrementIdUsed') + ->with(1000001)->willReturn($isReservedOrderIdExist); + $this->resourceMock->expects($this->any())->method('getReservedOrderId')->willReturn($reservedOrderId); + $this->quote->reserveOrderId(); + $this->assertEquals($reservedOrderId, $this->quote->getReservedOrderId()); + } + + public function reservedOrderIdDataProvider() + { + return [ + 'id_already_in_use' => [true, 100002], + 'id_not_in_use' => [false, 1000001] + ]; + } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php new file mode 100644 index 0000000000000..102e3471063f1 --- /dev/null +++ b/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php @@ -0,0 +1,85 @@ +selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + ->disableOriginalConstructor() + ->getMock(); + $this->selectMock->expects($this->any())->method('from')->will($this->returnSelf()); + $this->selectMock->expects($this->any())->method('where'); + + $this->adapterMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\Pdo\Mysql::class) + ->disableOriginalConstructor() + ->getMock(); + $this->adapterMock->expects($this->any())->method('select')->will($this->returnValue($this->selectMock)); + + $this->resourceMock = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resourceMock->expects( + $this->any() + )->method( + 'getConnection' + )->will( + $this->returnValue($this->adapterMock) + ); + + $this->model = $objectManagerHelper->getObject( + \Magento\Quote\Model\ResourceModel\Quote::class, + [ + 'resource' => $this->resourceMock + ] + ); + } + + /** + * Unit test to verify if isOrderIncrementIdUsed method works with different types increment ids + * + * @param array $value + * @dataProvider isOrderIncrementIdUsedDataProvider + */ + public function testIsOrderIncrementIdUsed($value) + { + $expectedBind = [':increment_id' => $value]; + $this->adapterMock->expects($this->once())->method('fetchOne')->with($this->selectMock, $expectedBind); + $this->model->isOrderIncrementIdUsed($value); + } + + /** + * @return array + */ + public function isOrderIncrementIdUsedDataProvider() + { + return [[100000001], ['10000000001'], ['M10000000001']]; + } +} diff --git a/dev/tests/integration/etc/install-config-mysql.php.dist b/dev/tests/integration/etc/install-config-mysql.php.dist index 6fffcb22b5000..967914e238251 100644 --- a/dev/tests/integration/etc/install-config-mysql.php.dist +++ b/dev/tests/integration/etc/install-config-mysql.php.dist @@ -7,7 +7,7 @@ return [ 'db-host' => 'localhost', 'db-user' => 'root', - 'db-password' => '123123q', + 'db-password' => '', 'db-name' => 'magento_integration_tests', 'db-prefix' => '', 'backend-frontname' => 'backend', diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php index da035c8eec78f..8f295077afe33 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php @@ -404,4 +404,23 @@ protected function _getCustomerDataArray() \Magento\Customer\Model\Data\Customer::WEBSITE_ID => 1 ]; } + + /** + * Test to verify that reserved_order_id will be changed if it already in used + * + * @magentoDataFixture Magento/Sales/_files/order.php + * @magentoDataFixture Magento/Quote/_files/empty_quote.php + */ + public function testReserveOrderId() + { + $objectManager = Bootstrap::getObjectManager(); + /** @var \Magento\Quote\Model\Quote $quote */ + $quote = $objectManager->create(\Magento\Quote\Model\Quote::class); + $quote->load('reserved_order_id', 'reserved_order_id'); + $quote->reserveOrderId(); + $this->assertEquals('reserved_order_id', $quote->getReservedOrderId()); + $quote->setReservedOrderId('100000001'); + $quote->reserveOrderId(); + $this->assertNotEquals('100000001', $quote->getReservedOrderId()); + } } diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/ResourceModel/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/ResourceModel/QuoteTest.php new file mode 100644 index 0000000000000..43ee0893b75f9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/ResourceModel/QuoteTest.php @@ -0,0 +1,45 @@ +_resourceModel = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Quote\Model\ResourceModel\Quote::class + ); + } + + /** + * Test to verify if isOrderIncrementIdUsed method works with numeric increment ids + * + * @magentoDataFixture Magento/Sales/_files/order.php + */ + public function testIsOrderIncrementIdUsedNumericIncrementId() + { + $this->assertTrue($this->_resourceModel->isOrderIncrementIdUsed('100000001')); + } + + /** + * Test to verify if isOrderIncrementIdUsed method works with alphanumeric increment ids + * + * @magentoDataFixture Magento/Sales/_files/order_alphanumeric_id.php + */ + public function testIsOrderIncrementIdUsedAlphanumericIncrementId() + { + $this->assertTrue($this->_resourceModel->isOrderIncrementIdUsed('M00000001')); + } +} diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php index bc49ab15a7d54..2ce1bf02bf389 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php @@ -2155,7 +2155,6 @@ ['addOrderedQty', 'Magento\Reports\Model\ResourceModel\Product\Collection'], ['prepareForProductsInCarts', 'Magento\Reports\Model\ResourceModel\Quote\Collection'], ['getOrdersSubSelect', 'Magento\Reports\Model\ResourceModel\Quote\Collection'], - ['isOrderIncrementIdUsed', 'Magento\Quote\Model\ResourceModel\Quote'], ['isStateProtected', 'Magento\Sales\Model\Order'], ['_getBundleOptions', 'Magento\Bundle\Block\Checkout\Cart\Item\Renderer'], ['_getSelectionFinalPrice', 'Magento\Bundle\Block\Checkout\Cart\Item\Renderer'],