Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit da2b1d1

Browse files
committed
MAGETWO-89990: Extract order creation cycle into a separate service (MAGETWO-84696)
1 parent 8e9879f commit da2b1d1

File tree

8 files changed

+392
-6
lines changed

8 files changed

+392
-6
lines changed

app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ class Multishipping extends \Magento\Framework\DataObject
157157
*/
158158
private $shippingAssignmentProcessor;
159159

160+
/**
161+
* @var Multishipping\PlaceOrderFactory
162+
*/
163+
private $placeOrderFactory;
164+
160165
/**
161166
* Constructor
162167
*
@@ -184,6 +189,7 @@ class Multishipping extends \Magento\Framework\DataObject
184189
* @param array $data
185190
* @param \Magento\Quote\Api\Data\CartExtensionFactory|null $cartExtensionFactory
186191
* @param AllowedCountries|null $allowedCountryReader
192+
* @param Multishipping\PlaceOrderFactory $placeOrderFactory
187193
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
188194
*/
189195
public function __construct(
@@ -210,7 +216,8 @@ public function __construct(
210216
\Magento\Quote\Model\Quote\TotalsCollector $totalsCollector,
211217
array $data = [],
212218
\Magento\Quote\Api\Data\CartExtensionFactory $cartExtensionFactory = null,
213-
AllowedCountries $allowedCountryReader = null
219+
AllowedCountries $allowedCountryReader = null,
220+
Multishipping\PlaceOrderFactory $placeOrderFactory = null
214221
) {
215222
$this->_eventManager = $eventManager;
216223
$this->_scopeConfig = $scopeConfig;
@@ -237,6 +244,8 @@ public function __construct(
237244
->get(\Magento\Quote\Api\Data\CartExtensionFactory::class);
238245
$this->allowedCountryReader = $allowedCountryReader ?: ObjectManager::getInstance()
239246
->get(AllowedCountries::class);
247+
$this->placeOrderFactory = $placeOrderFactory ?: ObjectManager::getInstance()
248+
->get(Multishipping\PlaceOrderFactory::class);
240249
parent::__construct($data);
241250
$this->_init();
242251
}
@@ -764,13 +773,23 @@ public function createOrders()
764773
);
765774
}
766775

776+
$paymentProviderCode = $this->getQuote()->getPayment()->getMethod();
777+
$placeOrderService = $this->placeOrderFactory->create($paymentProviderCode);
778+
$errorList = $placeOrderService->place($orders);
767779
foreach ($orders as $order) {
768-
$order->place();
769-
$order->save();
770-
if ($order->getCanSendNewEmailFlag()) {
771-
$this->orderSender->send($order);
780+
$incrementId = $order->getIncrementId();
781+
if (!isset($errorList[$incrementId])) {
782+
if ($order->getCanSendNewEmailFlag()) {
783+
$this->orderSender->send($order);
784+
}
785+
$orderIds[$order->getId()] = $order->getIncrementId();
772786
}
773-
$orderIds[$order->getId()] = $order->getIncrementId();
787+
}
788+
789+
if (!empty($errorList)) {
790+
throw new LocalizedException(
791+
__('An error occurred on the server. Please try to place the order again.')
792+
);
774793
}
775794

776795
$this->_session->setOrderIds($orderIds);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Multishipping\Model\Checkout\Type\Multishipping;
7+
8+
use Magento\Sales\Api\OrderManagementInterface;
9+
10+
/**
11+
* Default implementation for OrderPlaceInterface.
12+
*/
13+
class PlaceOrderDefault implements PlaceOrderInterface
14+
{
15+
/**
16+
* @var OrderManagementInterface
17+
*/
18+
private $orderManagement;
19+
20+
/**
21+
* @param OrderManagementInterface $orderManagement
22+
*/
23+
public function __construct(
24+
OrderManagementInterface $orderManagement
25+
) {
26+
$this->orderManagement = $orderManagement;
27+
}
28+
29+
/**
30+
* {@inheritdoc}
31+
*/
32+
public function place(array $orderList): array
33+
{
34+
$errorList = [];
35+
foreach ($orderList as $order) {
36+
try {
37+
$this->orderManagement->place($order);
38+
} catch (\Exception $e) {
39+
$incrementId = $order->getIncrementId();
40+
$errorList[$incrementId] = $e;
41+
}
42+
}
43+
44+
return $errorList;
45+
}
46+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Multishipping\Model\Checkout\Type\Multishipping;
7+
8+
use Magento\Framework\ObjectManagerInterface;
9+
10+
/**
11+
* Creates instance of place order service according to payment provider.
12+
*/
13+
class PlaceOrderFactory
14+
{
15+
/**
16+
* @var ObjectManagerInterface
17+
*/
18+
private $objectManager;
19+
20+
/**
21+
* @var PlaceOrderPool
22+
*/
23+
private $placeOrderPool;
24+
25+
/**
26+
* @param ObjectManagerInterface $objectManager
27+
* @param PlaceOrderPool $placeOrderPool
28+
*/
29+
public function __construct(
30+
ObjectManagerInterface $objectManager,
31+
PlaceOrderPool $placeOrderPool
32+
) {
33+
$this->objectManager = $objectManager;
34+
$this->placeOrderPool = $placeOrderPool;
35+
}
36+
37+
/**
38+
* @param string $paymentProviderCode
39+
* @return PlaceOrderInterface
40+
*/
41+
public function create(string $paymentProviderCode): PlaceOrderInterface
42+
{
43+
$service = $this->placeOrderPool->get($paymentProviderCode);
44+
if ($service === null) {
45+
$service = $this->objectManager->get(PlaceOrderDefault::class);
46+
}
47+
48+
return $service;
49+
}
50+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Multishipping\Model\Checkout\Type\Multishipping;
7+
8+
use Magento\Sales\Api\Data\OrderInterface;
9+
10+
/**
11+
* Place orders during multishipping checkout flow.
12+
*/
13+
interface PlaceOrderInterface
14+
{
15+
/**
16+
* Place orders.
17+
*
18+
* @param OrderInterface[] $orderList
19+
* @return array
20+
*/
21+
public function place(array $orderList): array;
22+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Multishipping\Model\Checkout\Type\Multishipping;
7+
8+
use Magento\Framework\ObjectManager\TMap;
9+
use Magento\Framework\ObjectManager\TMapFactory;
10+
11+
/**
12+
* Contains place order services according to payment provider.
13+
*
14+
* Can be used as extension point for changing order placing logic during multishipping checkout flow.
15+
*/
16+
class PlaceOrderPool
17+
{
18+
/**
19+
* @var PlaceOrderInterface[] | TMap
20+
*/
21+
private $services;
22+
23+
/**
24+
* @param TMapFactory $tmapFactory
25+
* @param array $services
26+
*/
27+
public function __construct(
28+
TMapFactory $tmapFactory,
29+
array $services = []
30+
) {
31+
$this->services = $tmapFactory->createSharedObjectsMap(
32+
[
33+
'array' => $services,
34+
'type' => PlaceOrderInterface::class
35+
]
36+
);
37+
}
38+
39+
/**
40+
* Returns place order service for defined payment provider.
41+
*
42+
* @param string $paymentProviderCode
43+
* @return PlaceOrderInterface|null
44+
*/
45+
public function get(string $paymentProviderCode)
46+
{
47+
if (!isset($this->services[$paymentProviderCode])) {
48+
return null;
49+
}
50+
51+
return $this->services[$paymentProviderCode];
52+
}
53+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Multishipping\Test\Unit\Model\Checkout\Type\Multishipping;
7+
8+
use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderDefault;
9+
use Magento\Sales\Api\Data\OrderInterface;
10+
use Magento\Sales\Api\OrderManagementInterface;
11+
12+
class PlaceOrderDefaultTest extends \PHPUnit\Framework\TestCase
13+
{
14+
/**
15+
* @var OrderManagementInterface|\PHPUnit_Framework_MockObject_MockObject
16+
*/
17+
private $orderManagement;
18+
19+
/**
20+
* @var PlaceOrderDefault
21+
*/
22+
private $placeOrderDefault;
23+
24+
/**
25+
* @inheritdoc
26+
*/
27+
protected function setUp()
28+
{
29+
$this->orderManagement = $this->getMockForAbstractClass(OrderManagementInterface::class);
30+
31+
$this->placeOrderDefault = new PlaceOrderDefault($this->orderManagement);
32+
}
33+
34+
public function testPlace()
35+
{
36+
$incrementId = '000000001';
37+
38+
$order = $this->getMockForAbstractClass(OrderInterface::class);
39+
$order->method('getIncrementId')->willReturn($incrementId);
40+
$orderList = [$order];
41+
42+
$this->orderManagement->expects($this->once())
43+
->method('place')
44+
->with($order)
45+
->willReturn($order);
46+
$errors = $this->placeOrderDefault->place($orderList);
47+
48+
$this->assertEmpty($errors);
49+
}
50+
51+
public function testPlaceWithErrors()
52+
{
53+
$incrementId = '000000001';
54+
55+
$order = $this->getMockForAbstractClass(OrderInterface::class);
56+
$order->method('getIncrementId')->willReturn($incrementId);
57+
$orderList = [$order];
58+
59+
$exception = new \Exception('error');
60+
$this->orderManagement->method('place')->willThrowException($exception);
61+
$errors = $this->placeOrderDefault->place($orderList);
62+
63+
$this->assertEquals(
64+
[$incrementId => $exception],
65+
$errors
66+
);
67+
}
68+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Multishipping\Test\Unit\Model\Checkout\Type\Multishipping;
7+
8+
use Magento\Framework\ObjectManagerInterface;
9+
use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderDefault;
10+
use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderFactory;
11+
use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderInterface;
12+
use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderPool;
13+
14+
class PlaceOrderFactoryTest extends \PHPUnit\Framework\TestCase
15+
{
16+
/**
17+
* @var ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
18+
*/
19+
private $objectManager;
20+
21+
/**
22+
* @var PlaceOrderPool|\PHPUnit_Framework_MockObject_MockObject
23+
*/
24+
private $placeOrderPool;
25+
26+
/**
27+
* @var PlaceOrderFactory
28+
*/
29+
private $placeOrderFactory;
30+
31+
/**
32+
* @inheritdoc
33+
*/
34+
protected function setUp()
35+
{
36+
$this->objectManager = $this->getMockForAbstractClass(ObjectManagerInterface::class);
37+
38+
$this->placeOrderPool = $this->getMockBuilder(PlaceOrderPool::class)
39+
->disableOriginalConstructor()
40+
->getMock();
41+
42+
$this->placeOrderFactory = new PlaceOrderFactory($this->objectManager, $this->placeOrderPool);
43+
}
44+
45+
public function testCreate()
46+
{
47+
$paymentProviderCode = 'code';
48+
49+
$placeOrder = $this->getMockForAbstractClass(PlaceOrderInterface::class);
50+
$this->placeOrderPool->method('get')
51+
->with($paymentProviderCode)
52+
->willReturn($placeOrder);
53+
54+
$instance = $this->placeOrderFactory->create($paymentProviderCode);
55+
56+
$this->assertInstanceOf(PlaceOrderInterface::class, $instance);
57+
}
58+
59+
/**
60+
* Checks that default place order service is created when place order pull returns null.
61+
*/
62+
public function testCreateWithDefault()
63+
{
64+
$paymentProviderCode = 'code';
65+
66+
$this->placeOrderPool->method('get')
67+
->with($paymentProviderCode)
68+
->willReturn(null);
69+
$placeOrder = $this->getMockBuilder(PlaceOrderDefault::class)
70+
->disableOriginalConstructor()
71+
->getMock();
72+
$this->objectManager->method('get')
73+
->with(PlaceOrderDefault::class)
74+
->willReturn($placeOrder);
75+
76+
$instance = $this->placeOrderFactory->create($paymentProviderCode);
77+
78+
$this->assertInstanceOf(PlaceOrderDefault::class, $instance);
79+
}
80+
}

0 commit comments

Comments
 (0)