Skip to content

Commit 5453402

Browse files
committed
MAGETWO-75125: Unable to place order on environment with split database within PayPal Express Checkout
1 parent a902370 commit 5453402

File tree

9 files changed

+232
-179
lines changed

9 files changed

+232
-179
lines changed

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Magento\Quote\Model\Quote\Address;
1515
use Magento\Quote\Model\Quote\Address\Total as AddressTotal;
1616
use Magento\Sales\Model\Status;
17+
use Magento\Framework\App\ObjectManager;
1718

1819
/**
1920
* Quote model
@@ -353,6 +354,11 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
353354
*/
354355
protected $shippingAddressesItems;
355356

357+
/**
358+
* @var \Magento\Sales\Model\OrderIncrementIdChecker
359+
*/
360+
private $orderIncrementIdChecker;
361+
356362
/**
357363
* @param \Magento\Framework\Model\Context $context
358364
* @param \Magento\Framework\Registry $registry
@@ -394,6 +400,7 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
394400
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
395401
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
396402
* @param array $data
403+
* @param \Magento\Sales\Model\OrderIncrementIdChecker|null $orderIncrementIdChecker
397404
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
398405
*/
399406
public function __construct(
@@ -436,7 +443,8 @@ public function __construct(
436443
\Magento\Quote\Model\ShippingAssignmentFactory $shippingAssignmentFactory,
437444
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
438445
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
439-
array $data = []
446+
array $data = [],
447+
\Magento\Sales\Model\OrderIncrementIdChecker $orderIncrementIdChecker = null
440448
) {
441449
$this->quoteValidator = $quoteValidator;
442450
$this->_catalogProduct = $catalogProduct;
@@ -471,6 +479,8 @@ public function __construct(
471479
$this->totalsReader = $totalsReader;
472480
$this->shippingFactory = $shippingFactory;
473481
$this->shippingAssignmentFactory = $shippingAssignmentFactory;
482+
$this->orderIncrementIdChecker = $orderIncrementIdChecker ?: ObjectManager::getInstance()
483+
->get(\Magento\Sales\Model\OrderIncrementIdChecker::class);
474484
parent::__construct(
475485
$context,
476486
$registry,
@@ -2184,7 +2194,7 @@ public function reserveOrderId()
21842194
} else {
21852195
//checking if reserved order id was already used for some order
21862196
//if yes reserving new one if not using old one
2187-
if ($this->_getResource()->isOrderIncrementIdUsed($this->getReservedOrderId())) {
2197+
if ($this->orderIncrementIdChecker->isIncrementIdUsed($this->getReservedOrderId())) {
21882198
$this->setReservedOrderId($this->_getResource()->getReservedOrderId($this));
21892199
}
21902200
}

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

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -170,29 +170,6 @@ public function getReservedOrderId($quote)
170170
->getNextValue();
171171
}
172172

173-
/**
174-
* Check if order increment ID is already used.
175-
* Method can be used to avoid collisions of order IDs.
176-
*
177-
* @param int $orderIncrementId
178-
* @return bool
179-
*/
180-
public function isOrderIncrementIdUsed($orderIncrementId)
181-
{
182-
/** @var \Magento\Framework\DB\Adapter\AdapterInterface $adapter */
183-
$adapter = $this->_resources->getConnection('sales');
184-
$bind = [':increment_id' => $orderIncrementId];
185-
/** @var \Magento\Framework\DB\Select $select */
186-
$select = $adapter->select();
187-
$select->from($this->getTable('sales_order'), 'entity_id')->where('increment_id = :increment_id');
188-
$entity_id = $adapter->fetchOne($select, $bind);
189-
if ($entity_id > 0) {
190-
return true;
191-
}
192-
193-
return false;
194-
}
195-
196173
/**
197174
* Mark quotes - that depend on catalog price rules - to be recollected on demand
198175
*

app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ class QuoteTest extends \PHPUnit\Framework\TestCase
145145
*/
146146
private $itemProcessor;
147147

148+
/**
149+
* @var \Magento\Sales\Model\OrderIncrementIdChecker|\PHPUnit_Framework_MockObject_MockObject
150+
*/
151+
private $orderIncrementIdChecker;
152+
148153
/**
149154
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
150155
*/
@@ -256,6 +261,7 @@ protected function setUp()
256261
\Magento\Customer\Api\Data\CustomerInterfaceFactory::class,
257262
['create']
258263
);
264+
$this->orderIncrementIdChecker = $this->createMock(\Magento\Sales\Model\OrderIncrementIdChecker::class);
259265
$this->quote = (new ObjectManager($this))
260266
->getObject(
261267
\Magento\Quote\Model\Quote::class,
@@ -280,9 +286,10 @@ protected function setUp()
280286
'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock,
281287
'customerDataFactory' => $this->customerDataFactoryMock,
282288
'itemProcessor' => $this->itemProcessor,
289+
'orderIncrementIdChecker' => $this->orderIncrementIdChecker,
283290
'data' => [
284-
'reserved_order_id' => 1000001
285-
]
291+
'reserved_order_id' => 1000001,
292+
],
286293
]
287294
);
288295
}
@@ -1222,28 +1229,32 @@ public function testGetAllItems()
12221229
}
12231230

12241231
/**
1225-
* Test to verify if existing reserved_order_id in use
1232+
* Test to verify if existing reserved_order_id in use.
12261233
*
12271234
* @param bool $isReservedOrderIdExist
12281235
* @param int $reservedOrderId
1236+
* @return void
12291237
* @dataProvider reservedOrderIdDataProvider
12301238
*/
1231-
public function testReserveOrderId($isReservedOrderIdExist, $reservedOrderId)
1239+
public function testReserveOrderId(bool $isReservedOrderIdExist, int $reservedOrderId): void
12321240
{
1233-
$this->resourceMock
1241+
$this->orderIncrementIdChecker
12341242
->expects($this->once())
1235-
->method('isOrderIncrementIdUsed')
1243+
->method('isIncrementIdUsed')
12361244
->with(1000001)->willReturn($isReservedOrderIdExist);
12371245
$this->resourceMock->expects($this->any())->method('getReservedOrderId')->willReturn($reservedOrderId);
12381246
$this->quote->reserveOrderId();
12391247
$this->assertEquals($reservedOrderId, $this->quote->getReservedOrderId());
12401248
}
12411249

1242-
public function reservedOrderIdDataProvider()
1250+
/**
1251+
* @return array
1252+
*/
1253+
public function reservedOrderIdDataProvider(): array
12431254
{
12441255
return [
12451256
'id_already_in_use' => [true, 100002],
1246-
'id_not_in_use' => [false, 1000001]
1257+
'id_not_in_use' => [false, 1000001],
12471258
];
12481259
}
12491260
}

app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php

Lines changed: 15 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,17 @@
66

77
namespace Magento\Quote\Test\Unit\Model\ResourceModel;
88

9-
use Magento\Framework\App\ResourceConnection;
10-
use Magento\Framework\DB\Adapter\Pdo\Mysql;
11-
use Magento\Framework\DB\Select;
129
use Magento\Framework\DB\Sequence\SequenceInterface;
13-
use Magento\Framework\Model\ResourceModel\Db\Context;
14-
use Magento\Framework\Model\ResourceModel\Db\VersionControl\RelationComposite;
15-
use Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot;
1610
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1711
use Magento\Quote\Model\Quote;
1812
use Magento\Quote\Model\ResourceModel\Quote as QuoteResource;
1913
use Magento\SalesSequence\Model\Manager;
2014

15+
/**
16+
* Unit test for \Magento\Quote\Model\ResourceModel\Quote.
17+
*/
2118
class QuoteTest extends \PHPUnit\Framework\TestCase
2219
{
23-
/**
24-
* @var ResourceConnection
25-
*/
26-
private $resourceMock;
27-
28-
/**
29-
* @var Mysql
30-
*/
31-
private $adapterMock;
32-
33-
/**
34-
* @var Select
35-
*/
36-
private $selectMock;
37-
3820
/**
3921
* @var Quote|\PHPUnit_Framework_MockObject_MockObject
4022
*/
@@ -55,98 +37,31 @@ class QuoteTest extends \PHPUnit\Framework\TestCase
5537
*/
5638
private $model;
5739

40+
/**
41+
* @inheritdoc
42+
*/
5843
protected function setUp()
5944
{
6045
$objectManagerHelper = new ObjectManager($this);
61-
$this->selectMock = $this->getMockBuilder(Select::class)
62-
->disableOriginalConstructor()
63-
->getMock();
64-
$this->selectMock->expects($this->any())->method('from')->will($this->returnSelf());
65-
$this->selectMock->expects($this->any())->method('where');
66-
67-
$this->adapterMock = $this->getMockBuilder(Mysql::class)
68-
->disableOriginalConstructor()
69-
->getMock();
70-
$this->adapterMock->expects($this->any())->method('select')->will($this->returnValue($this->selectMock));
71-
72-
$this->resourceMock = $this->getMockBuilder(ResourceConnection::class)
73-
->disableOriginalConstructor()
74-
->getMock();
75-
$this->resourceMock->expects(
76-
$this->any()
77-
)->method(
78-
'getConnection'
79-
)->will(
80-
$this->returnValue($this->adapterMock)
81-
);
82-
83-
$context = $this->getMockBuilder(Context::class)
84-
->disableOriginalConstructor()
85-
->getMock();
86-
$context->expects(
87-
$this->once()
88-
)->method(
89-
'getResources'
90-
)->will(
91-
$this->returnValue($this->resourceMock)
92-
);
93-
94-
$snapshot = $this->getMockBuilder(Snapshot::class)
95-
->disableOriginalConstructor()
96-
->getMock();
97-
$relationComposite = $this->getMockBuilder(RelationComposite::class)
98-
->disableOriginalConstructor()
99-
->getMock();
100-
$this->quoteMock = $this->getMockBuilder(Quote::class)
101-
->disableOriginalConstructor()
102-
->getMock();
103-
$this->sequenceManagerMock = $this->getMockBuilder(Manager::class)
104-
->disableOriginalConstructor()
105-
->getMock();
106-
$this->sequenceMock = $this->getMockBuilder(SequenceInterface::class)
107-
->disableOriginalConstructor()
108-
->getMock();
46+
$this->quoteMock = $this->createMock(Quote::class);
47+
$this->sequenceManagerMock = $this->createMock(Manager::class);
48+
$this->sequenceMock = $this->createMock(SequenceInterface::class);
10949
$this->model = $objectManagerHelper->getObject(
11050
QuoteResource::class,
11151
[
112-
'context' => $context,
113-
'entitySnapshot' => $snapshot,
114-
'entityRelationComposite' => $relationComposite,
11552
'sequenceManager' => $this->sequenceManagerMock,
116-
'connectionName' => null,
11753
]
11854
);
11955
}
12056

12157
/**
122-
* Unit test to verify if isOrderIncrementIdUsed method works with different types increment ids
123-
*
124-
* @param array $value
125-
* @dataProvider isOrderIncrementIdUsedDataProvider
126-
*/
127-
public function testIsOrderIncrementIdUsed($value)
128-
{
129-
$expectedBind = [':increment_id' => $value];
130-
$this->adapterMock->expects($this->once())->method('fetchOne')->with($this->selectMock, $expectedBind);
131-
$this->model->isOrderIncrementIdUsed($value);
132-
}
133-
134-
/**
135-
* @return array
136-
*/
137-
public function isOrderIncrementIdUsedDataProvider()
138-
{
139-
return [[100000001], ['10000000001'], ['M10000000001']];
140-
}
141-
142-
/**
143-
* /**
144-
* @param $entityType
145-
* @param $storeId
146-
* @param $reservedOrderId
58+
* @param string $entityType
59+
* @param int $storeId
60+
* @param string $reservedOrderId
61+
* @return void
14762
* @dataProvider getReservedOrderIdDataProvider
14863
*/
149-
public function testGetReservedOrderId($entityType, $storeId, $reservedOrderId)
64+
public function testGetReservedOrderId(string $entityType, int $storeId, string $reservedOrderId): void
15065
{
15166
$this->sequenceManagerMock->expects($this->once())
15267
->method('getSequence')
@@ -170,7 +85,7 @@ public function getReservedOrderIdDataProvider(): array
17085
return [
17186
[\Magento\Sales\Model\Order::ENTITY, 1, '1000000001'],
17287
[\Magento\Sales\Model\Order::ENTITY, 2, '2000000001'],
173-
[\Magento\Sales\Model\Order::ENTITY, 3, '3000000001']
88+
[\Magento\Sales\Model\Order::ENTITY, 3, '3000000001'],
17489
];
17590
}
17691
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Sales\Model;
9+
10+
/**
11+
* This class uses for checking if reserved order id was already used for some order.
12+
*/
13+
class OrderIncrementIdChecker
14+
{
15+
/**
16+
* @var ResourceModel\Order
17+
*/
18+
private $resourceModel;
19+
20+
/**
21+
* @param ResourceModel\Order $resourceModel
22+
*/
23+
public function __construct(ResourceModel\Order $resourceModel)
24+
{
25+
$this->resourceModel = $resourceModel;
26+
}
27+
28+
/**
29+
* Check if order increment ID is already used.
30+
*
31+
* Method can be used to avoid collisions of order IDs.
32+
*
33+
* @param string|int $orderIncrementId
34+
* @return bool
35+
*/
36+
public function isIncrementIdUsed($orderIncrementId): bool
37+
{
38+
/** @var \Magento\Framework\DB\Adapter\AdapterInterface $adapter */
39+
$adapter = $this->resourceModel->getConnection();
40+
$bind = [':increment_id' => $orderIncrementId];
41+
/** @var \Magento\Framework\DB\Select $select */
42+
$select = $adapter->select();
43+
$select->from($this->resourceModel->getMainTable(), $this->resourceModel->getIdFieldName())
44+
->where('increment_id = :increment_id');
45+
$entity_id = $adapter->fetchOne($select, $bind);
46+
if ($entity_id > 0) {
47+
return true;
48+
}
49+
50+
return false;
51+
}
52+
}

0 commit comments

Comments
 (0)