CustomerManagement.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\Model\Order;
  7. use Magento\Customer\Api\Data\AddressInterface;
  8. use Magento\Framework\App\ObjectManager;
  9. use Magento\Framework\Exception\AlreadyExistsException;
  10. use Magento\Sales\Api\Data\OrderAddressInterface;
  11. use Magento\Quote\Model\Quote\Address as QuoteAddress;
  12. use Magento\Quote\Model\Quote\AddressFactory as QuoteAddressFactory;
  13. use Magento\Sales\Api\Data\OrderInterface;
  14. /**
  15. * Class CustomerManagement
  16. *
  17. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  18. */
  19. class CustomerManagement implements \Magento\Sales\Api\OrderCustomerManagementInterface
  20. {
  21. /**
  22. * @var \Magento\Customer\Api\AccountManagementInterface
  23. */
  24. protected $accountManagement;
  25. /**
  26. * @deprecated 101.0.4
  27. */
  28. protected $customerFactory;
  29. /**
  30. * @deprecated 101.0.4
  31. */
  32. protected $addressFactory;
  33. /**
  34. * @deprecated 101.0.4
  35. */
  36. protected $regionFactory;
  37. /**
  38. * @var \Magento\Sales\Api\OrderRepositoryInterface
  39. */
  40. protected $orderRepository;
  41. /**
  42. * @deprecated 101.0.4
  43. */
  44. protected $objectCopyService;
  45. /**
  46. * @var QuoteAddressFactory
  47. */
  48. private $quoteAddressFactory;
  49. /**
  50. * @var OrderCustomerExtractor
  51. */
  52. private $customerExtractor;
  53. /**
  54. * @param \Magento\Framework\DataObject\Copy $objectCopyService
  55. * @param \Magento\Customer\Api\AccountManagementInterface $accountManagement
  56. * @param \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory
  57. * @param \Magento\Customer\Api\Data\AddressInterfaceFactory $addressFactory
  58. * @param \Magento\Customer\Api\Data\RegionInterfaceFactory $regionFactory
  59. * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
  60. * @param QuoteAddressFactory|null $quoteAddressFactory
  61. * @param OrderCustomerExtractor|null $orderCustomerExtractor
  62. */
  63. public function __construct(
  64. \Magento\Framework\DataObject\Copy $objectCopyService,
  65. \Magento\Customer\Api\AccountManagementInterface $accountManagement,
  66. \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory,
  67. \Magento\Customer\Api\Data\AddressInterfaceFactory $addressFactory,
  68. \Magento\Customer\Api\Data\RegionInterfaceFactory $regionFactory,
  69. \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
  70. QuoteAddressFactory $quoteAddressFactory = null,
  71. OrderCustomerExtractor $orderCustomerExtractor = null
  72. ) {
  73. $this->objectCopyService = $objectCopyService;
  74. $this->accountManagement = $accountManagement;
  75. $this->orderRepository = $orderRepository;
  76. $this->customerFactory = $customerFactory;
  77. $this->addressFactory = $addressFactory;
  78. $this->regionFactory = $regionFactory;
  79. $this->quoteAddressFactory = $quoteAddressFactory
  80. ?: ObjectManager::getInstance()->get(QuoteAddressFactory::class);
  81. $this->customerExtractor = $orderCustomerExtractor
  82. ?? ObjectManager::getInstance()->get(OrderCustomerExtractor::class);
  83. }
  84. /**
  85. * {@inheritdoc}
  86. */
  87. public function create($orderId)
  88. {
  89. $order = $this->orderRepository->get($orderId);
  90. if ($order->getCustomerId()) {
  91. throw new AlreadyExistsException(
  92. __('This order already has associated customer account')
  93. );
  94. }
  95. $customer = $this->customerExtractor->extract($orderId);
  96. /** @var AddressInterface[] $filteredAddresses */
  97. $filteredAddresses = [];
  98. foreach ($customer->getAddresses() as $address) {
  99. if ($this->needToSaveAddress($order, $address)) {
  100. $filteredAddresses[] = $address;
  101. }
  102. }
  103. $customer->setAddresses($filteredAddresses);
  104. $account = $this->accountManagement->createAccount($customer);
  105. $order = $this->orderRepository->get($orderId);
  106. $order->setCustomerId($account->getId());
  107. $order->setCustomerIsGuest(0);
  108. $this->orderRepository->save($order);
  109. return $account;
  110. }
  111. /**
  112. * @param OrderInterface $order
  113. * @param AddressInterface $address
  114. *
  115. * @return bool
  116. */
  117. private function needToSaveAddress(
  118. OrderInterface $order,
  119. AddressInterface $address
  120. ): bool {
  121. /** @var OrderAddressInterface|null $orderAddress */
  122. $orderAddress = null;
  123. if ($address->isDefaultBilling()) {
  124. $orderAddress = $order->getBillingAddress();
  125. } elseif ($address->isDefaultShipping()) {
  126. $orderAddress = $order->getShippingAddress();
  127. }
  128. if ($orderAddress) {
  129. $quoteAddressId = $orderAddress->getData('quote_address_id');
  130. if ($quoteAddressId) {
  131. /** @var QuoteAddress $quote */
  132. $quote = $this->quoteAddressFactory->create()
  133. ->load($quoteAddressId);
  134. if ($quote && $quote->getId()) {
  135. return (bool)(int)$quote->getData('save_in_address_book');
  136. }
  137. }
  138. return true;
  139. }
  140. return false;
  141. }
  142. }