Skip to content

Commit c586697

Browse files
authored
Merge pull request #380 from magento-performance/MCP-595
MCP-595 [MCP-304] [QA] [BUG] Order cannot be processed if customer is deleted
2 parents b01ba7f + cef9f94 commit c586697

File tree

2 files changed

+97
-77
lines changed

2 files changed

+97
-77
lines changed

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

Lines changed: 95 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,35 @@
88
namespace Magento\Quote\Model;
99

1010
use Magento\Authorization\Model\UserContextInterface;
11+
use Magento\Checkout\Model\Session as CheckoutSession;
12+
use Magento\Customer\Api\AccountManagementInterface;
13+
use Magento\Customer\Api\AddressRepositoryInterface;
14+
use Magento\Customer\Api\CustomerRepositoryInterface;
1115
use Magento\Customer\Api\Data\GroupInterface;
16+
use Magento\Customer\Model\CustomerFactory;
17+
use Magento\Customer\Model\Session as CustomerSession;
18+
use Magento\Framework\Api\DataObjectHelper;
1219
use Magento\Framework\App\ObjectManager;
20+
use Magento\Framework\App\RequestInterface;
1321
use Magento\Framework\Event\ManagerInterface as EventManager;
1422
use Magento\Framework\Exception\CouldNotSaveException;
1523
use Magento\Framework\Exception\LocalizedException;
24+
use Magento\Framework\Exception\NoSuchEntityException;
1625
use Magento\Framework\Exception\StateException;
26+
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
27+
use Magento\Framework\Model\AbstractExtensibleModel;
28+
use Magento\Payment\Model\Method\AbstractMethod;
29+
use Magento\Quote\Api\CartManagementInterface;
30+
use Magento\Quote\Api\CartRepositoryInterface;
1731
use Magento\Quote\Api\Data\PaymentInterface;
1832
use Magento\Quote\Model\Quote\Address\ToOrder as ToOrderConverter;
1933
use Magento\Quote\Model\Quote\Address\ToOrderAddress as ToOrderAddressConverter;
2034
use Magento\Quote\Model\Quote as QuoteEntity;
35+
use Magento\Quote\Model\Quote\AddressFactory;
2136
use Magento\Quote\Model\Quote\Item\ToOrderItem as ToOrderItemConverter;
2237
use Magento\Quote\Model\Quote\Payment\ToOrderPayment as ToOrderPaymentConverter;
38+
use Magento\Quote\Model\ResourceModel\Quote\Item;
39+
use Magento\Sales\Api\Data\OrderInterface;
2340
use Magento\Sales\Api\Data\OrderInterfaceFactory as OrderFactory;
2441
use Magento\Sales\Api\OrderManagementInterface as OrderManagement;
2542
use Magento\Store\Model\StoreManagerInterface;
@@ -31,7 +48,7 @@
3148
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
3249
* @SuppressWarnings(PHPMD.TooManyFields)
3350
*/
34-
class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
51+
class QuoteManagement implements CartManagementInterface
3552
{
3653
/**
3754
* @var EventManager
@@ -84,27 +101,27 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
84101
protected $userContext;
85102

86103
/**
87-
* @var \Magento\Quote\Api\CartRepositoryInterface
104+
* @var CartRepositoryInterface
88105
*/
89106
protected $quoteRepository;
90107

91108
/**
92-
* @var \Magento\Customer\Api\CustomerRepositoryInterface
109+
* @var CustomerRepositoryInterface
93110
*/
94111
protected $customerRepository;
95112

96113
/**
97-
* @var \Magento\Customer\Model\CustomerFactory
114+
* @var CustomerFactory
98115
*/
99116
protected $customerModelFactory;
100117

101118
/**
102-
* @var \Magento\Quote\Model\Quote\AddressFactory
119+
* @var AddressFactory
103120
*/
104121
protected $quoteAddressFactory;
105122

106123
/**
107-
* @var \Magento\Framework\Api\DataObjectHelper
124+
* @var DataObjectHelper
108125
*/
109126
protected $dataObjectHelper;
110127

@@ -114,17 +131,17 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
114131
protected $storeManager;
115132

116133
/**
117-
* @var \Magento\Checkout\Model\Session
134+
* @var CheckoutSession
118135
*/
119136
protected $checkoutSession;
120137

121138
/**
122-
* @var \Magento\Customer\Model\Session
139+
* @var CustomerSession
123140
*/
124141
protected $customerSession;
125142

126143
/**
127-
* @var \Magento\Customer\Api\AccountManagementInterface
144+
* @var AccountManagementInterface
128145
*/
129146
protected $accountManagement;
130147

@@ -134,12 +151,12 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
134151
protected $quoteFactory;
135152

136153
/**
137-
* @var \Magento\Quote\Model\QuoteIdMaskFactory
154+
* @var QuoteIdMaskFactory
138155
*/
139156
private $quoteIdMaskFactory;
140157

141158
/**
142-
* @var \Magento\Customer\Api\AddressRepositoryInterface
159+
* @var AddressRepositoryInterface
143160
*/
144161
private $addressRepository;
145162

@@ -149,12 +166,12 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
149166
private $addressesToSync = [];
150167

151168
/**
152-
* @var \Magento\Framework\App\RequestInterface
169+
* @var RequestInterface
153170
*/
154171
private $request;
155172

156173
/**
157-
* @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress
174+
* @var RemoteAddress
158175
*/
159176
private $remoteAddress;
160177

@@ -169,20 +186,20 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
169186
* @param ToOrderItemConverter $quoteItemToOrderItem
170187
* @param ToOrderPaymentConverter $quotePaymentToOrderPayment
171188
* @param UserContextInterface $userContext
172-
* @param \Magento\Quote\Api\CartRepositoryInterface $quoteRepository
173-
* @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
174-
* @param \Magento\Customer\Model\CustomerFactory $customerModelFactory
175-
* @param \Magento\Quote\Model\Quote\AddressFactory $quoteAddressFactory
176-
* @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
189+
* @param CartRepositoryInterface $quoteRepository
190+
* @param CustomerRepositoryInterface $customerRepository
191+
* @param CustomerFactory $customerModelFactory
192+
* @param AddressFactory $quoteAddressFactory
193+
* @param DataObjectHelper $dataObjectHelper
177194
* @param StoreManagerInterface $storeManager
178-
* @param \Magento\Checkout\Model\Session $checkoutSession
179-
* @param \Magento\Customer\Model\Session $customerSession
180-
* @param \Magento\Customer\Api\AccountManagementInterface $accountManagement
195+
* @param CheckoutSession $checkoutSession
196+
* @param CustomerSession $customerSession
197+
* @param AccountManagementInterface $accountManagement
181198
* @param QuoteFactory $quoteFactory
182-
* @param \Magento\Quote\Model\QuoteIdMaskFactory|null $quoteIdMaskFactory
183-
* @param \Magento\Customer\Api\AddressRepositoryInterface|null $addressRepository
184-
* @param \Magento\Framework\App\RequestInterface|null $request
185-
* @param \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress
199+
* @param QuoteIdMaskFactory|null $quoteIdMaskFactory
200+
* @param AddressRepositoryInterface|null $addressRepository
201+
* @param RequestInterface|null $request
202+
* @param RemoteAddress $remoteAddress
186203
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
187204
*/
188205
public function __construct(
@@ -196,20 +213,20 @@ public function __construct(
196213
ToOrderItemConverter $quoteItemToOrderItem,
197214
ToOrderPaymentConverter $quotePaymentToOrderPayment,
198215
UserContextInterface $userContext,
199-
\Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
200-
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
201-
\Magento\Customer\Model\CustomerFactory $customerModelFactory,
202-
\Magento\Quote\Model\Quote\AddressFactory $quoteAddressFactory,
203-
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
216+
CartRepositoryInterface $quoteRepository,
217+
CustomerRepositoryInterface $customerRepository,
218+
CustomerFactory $customerModelFactory,
219+
AddressFactory $quoteAddressFactory,
220+
DataObjectHelper $dataObjectHelper,
204221
StoreManagerInterface $storeManager,
205-
\Magento\Checkout\Model\Session $checkoutSession,
206-
\Magento\Customer\Model\Session $customerSession,
207-
\Magento\Customer\Api\AccountManagementInterface $accountManagement,
208-
\Magento\Quote\Model\QuoteFactory $quoteFactory,
209-
\Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory = null,
210-
\Magento\Customer\Api\AddressRepositoryInterface $addressRepository = null,
211-
\Magento\Framework\App\RequestInterface $request = null,
212-
\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress = null
222+
CheckoutSession $checkoutSession,
223+
CustomerSession $customerSession,
224+
AccountManagementInterface $accountManagement,
225+
QuoteFactory $quoteFactory,
226+
QuoteIdMaskFactory $quoteIdMaskFactory = null,
227+
AddressRepositoryInterface $addressRepository = null,
228+
RequestInterface $request = null,
229+
RemoteAddress $remoteAddress = null
213230
) {
214231
$this->eventManager = $eventManager;
215232
$this->submitQuoteValidator = $submitQuoteValidator;
@@ -232,13 +249,13 @@ public function __construct(
232249
$this->customerSession = $customerSession;
233250
$this->quoteFactory = $quoteFactory;
234251
$this->quoteIdMaskFactory = $quoteIdMaskFactory ?: ObjectManager::getInstance()
235-
->get(\Magento\Quote\Model\QuoteIdMaskFactory::class);
252+
->get(QuoteIdMaskFactory::class);
236253
$this->addressRepository = $addressRepository ?: ObjectManager::getInstance()
237-
->get(\Magento\Customer\Api\AddressRepositoryInterface::class);
254+
->get(AddressRepositoryInterface::class);
238255
$this->request = $request ?: ObjectManager::getInstance()
239-
->get(\Magento\Framework\App\RequestInterface::class);
256+
->get(RequestInterface::class);
240257
$this->remoteAddress = $remoteAddress ?: ObjectManager::getInstance()
241-
->get(\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress::class);
258+
->get(RemoteAddress::class);
242259
}
243260

244261
/**
@@ -307,14 +324,14 @@ public function assignCustomer($cartId, $customerId, $storeId)
307324
$this->quoteRepository->save($customerActiveQuote);
308325

309326
// phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
310-
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
327+
} catch (NoSuchEntityException $e) {
311328
}
312329

313330
$quote->setCustomer($customer);
314331
$quote->setCustomerIsGuest(0);
315332
$quote->setIsActive(1);
316333

317-
/** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */
334+
/** @var QuoteIdMask $quoteIdMask */
318335
$quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'quote_id');
319336
if ($quoteIdMask->getId()) {
320337
$quoteIdMask->delete();
@@ -329,11 +346,11 @@ public function assignCustomer($cartId, $customerId, $storeId)
329346
* Creates an anonymous cart.
330347
*
331348
* @param int $storeId
332-
* @return \Magento\Quote\Model\Quote Cart object.
349+
* @return Quote Cart object.
333350
*/
334351
protected function createAnonymousCart($storeId)
335352
{
336-
/** @var \Magento\Quote\Model\Quote $quote */
353+
/** @var Quote $quote */
337354
$quote = $this->quoteFactory->create();
338355
$quote->setStoreId($storeId);
339356
return $quote;
@@ -344,16 +361,16 @@ protected function createAnonymousCart($storeId)
344361
*
345362
* @param int $customerId
346363
* @param int $storeId
347-
* @return \Magento\Quote\Model\Quote Cart object.
364+
* @return Quote Cart object.
348365
* @throws CouldNotSaveException The cart could not be created.
349366
*/
350367
protected function createCustomerCart($customerId, $storeId)
351368
{
352369
try {
353370
$quote = $this->quoteRepository->getActiveForCustomer($customerId);
354-
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
371+
} catch (NoSuchEntityException $e) {
355372
$customer = $this->customerRepository->getById($customerId);
356-
/** @var \Magento\Quote\Model\Quote $quote */
373+
/** @var Quote $quote */
357374
$quote = $this->quoteFactory->create();
358375
$quote->setStoreId($storeId);
359376
$quote->setCustomer($customer);
@@ -364,18 +381,21 @@ protected function createCustomerCart($customerId, $storeId)
364381

365382
/**
366383
* @inheritdoc
384+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
367385
*/
368386
public function placeOrder($cartId, PaymentInterface $paymentMethod = null)
369387
{
370388
$quote = $this->quoteRepository->getActive($cartId);
389+
$customer = $quote->getCustomer();
390+
371391
if ($paymentMethod) {
372392
$paymentMethod->setChecks(
373393
[
374-
\Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_CHECKOUT,
375-
\Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY,
376-
\Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY,
377-
\Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
378-
\Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL
394+
AbstractMethod::CHECK_USE_CHECKOUT,
395+
AbstractMethod::CHECK_USE_FOR_COUNTRY,
396+
AbstractMethod::CHECK_USE_FOR_CURRENCY,
397+
AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
398+
AbstractMethod::CHECK_ZERO_TOTAL
379399
]
380400
);
381401
$quote->getPayment()->setQuote($quote);
@@ -386,18 +406,22 @@ public function placeOrder($cartId, PaymentInterface $paymentMethod = null)
386406
$quote->collectTotals();
387407
}
388408

389-
if ($quote->getCheckoutMethod() === self::METHOD_GUEST) {
409+
if ($quote->getCheckoutMethod() === self::METHOD_GUEST || !$customer) {
390410
$quote->setCustomerId(null);
391-
$quote->setCustomerEmail($quote->getBillingAddress()->getEmail());
392-
if ($quote->getCustomerFirstname() === null && $quote->getCustomerLastname() === null) {
393-
$quote->setCustomerFirstname($quote->getBillingAddress()->getFirstname());
394-
$quote->setCustomerLastname($quote->getBillingAddress()->getLastname());
395-
if ($quote->getBillingAddress()->getMiddlename() === null) {
396-
$quote->setCustomerMiddlename($quote->getBillingAddress()->getMiddlename());
411+
$billingAddress = $quote->getBillingAddress();
412+
$quote->setCustomerEmail($billingAddress ? $billingAddress->getEmail() : null);
413+
if ($quote->getCustomerFirstname() === null
414+
&& $quote->getCustomerLastname() === null
415+
&& $billingAddress
416+
) {
417+
$quote->setCustomerFirstname($billingAddress->getFirstname());
418+
$quote->setCustomerLastname($billingAddress->getLastname());
419+
if ($billingAddress->getMiddlename() === null) {
420+
$quote->setCustomerMiddlename($billingAddress->getMiddlename());
397421
}
398422
}
399423
$quote->setCustomerIsGuest(true);
400-
$groupId = $quote->getCustomer()->getGroupId() ?: GroupInterface::NOT_LOGGED_IN_ID;
424+
$groupId = $customer ? $customer->getGroupId() : GroupInterface::NOT_LOGGED_IN_ID;
401425
$quote->setCustomerGroupId($groupId);
402426
}
403427

@@ -442,9 +466,9 @@ public function getCartForCustomer($customerId)
442466
*
443467
* @param Quote $quote
444468
* @param array $orderData
445-
* @return \Magento\Framework\Model\AbstractExtensibleModel|\Magento\Sales\Api\Data\OrderInterface|object|null
469+
* @return AbstractExtensibleModel|OrderInterface|object|null
446470
* @throws \Exception
447-
* @throws \Magento\Framework\Exception\LocalizedException
471+
* @throws LocalizedException
448472
*/
449473
public function submit(QuoteEntity $quote, $orderData = [])
450474
{
@@ -473,7 +497,7 @@ protected function resolveItems(QuoteEntity $quote)
473497
}
474498

475499
$parentItemId = $quoteItem->getParentItemId();
476-
/** @var \Magento\Quote\Model\ResourceModel\Quote\Item $parentItem */
500+
/** @var Item $parentItem */
477501
if ($parentItemId && !isset($orderItems[$parentItemId])) {
478502
$orderItems[$parentItemId] = $this->quoteItemToOrderItem->convert(
479503
$quoteItem->getParentItem(),
@@ -491,9 +515,9 @@ protected function resolveItems(QuoteEntity $quote)
491515
*
492516
* @param Quote $quote
493517
* @param array $orderData
494-
* @return \Magento\Framework\Model\AbstractExtensibleModel|\Magento\Sales\Api\Data\OrderInterface|object
518+
* @return AbstractExtensibleModel|OrderInterface|object
495519
* @throws \Exception
496-
* @throws \Magento\Framework\Exception\LocalizedException
520+
* @throws LocalizedException
497521
*/
498522
protected function submitQuote(QuoteEntity $quote, $orderData = [])
499523
{
@@ -510,13 +534,13 @@ protected function submitQuote(QuoteEntity $quote, $orderData = [])
510534
$quote->reserveOrderId();
511535
if ($quote->isVirtual()) {
512536
$this->dataObjectHelper->mergeDataObjects(
513-
\Magento\Sales\Api\Data\OrderInterface::class,
537+
OrderInterface::class,
514538
$order,
515539
$this->quoteAddressToOrder->convert($quote->getBillingAddress(), $orderData)
516540
);
517541
} else {
518542
$this->dataObjectHelper->mergeDataObjects(
519-
\Magento\Sales\Api\Data\OrderInterface::class,
543+
OrderInterface::class,
520544
$order,
521545
$this->quoteAddressToOrder->convert($quote->getShippingAddress(), $orderData)
522546
);
@@ -683,13 +707,13 @@ protected function _prepareCustomerQuote($quote)
683707
* Remove related to order and quote addresses and submit exception to further processing.
684708
*
685709
* @param Quote $quote
686-
* @param \Magento\Sales\Api\Data\OrderInterface $order
710+
* @param OrderInterface $order
687711
* @param \Exception $e
688712
* @throws \Exception
689713
*/
690714
private function rollbackAddresses(
691715
QuoteEntity $quote,
692-
\Magento\Sales\Api\Data\OrderInterface $order,
716+
OrderInterface $order,
693717
\Exception $e
694718
): void {
695719
try {

0 commit comments

Comments
 (0)