OrderCustomerExtractor.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\Sales\Model\Order;
  8. use Magento\Customer\Api\CustomerRepositoryInterface;
  9. use Magento\Customer\Api\Data\CustomerInterface;
  10. use Magento\Sales\Api\OrderRepositoryInterface;
  11. use Magento\Framework\DataObject\Copy as CopyService;
  12. use Magento\Customer\Api\Data\RegionInterface;
  13. use Magento\Customer\Api\Data\AddressInterfaceFactory as AddressFactory;
  14. use Magento\Customer\Api\Data\RegionInterfaceFactory as RegionFactory;
  15. use Magento\Customer\Api\Data\CustomerInterfaceFactory as CustomerFactory;
  16. use Magento\Quote\Api\Data\AddressInterfaceFactory as QuoteAddressFactory;
  17. use Magento\Sales\Model\Order\Address as OrderAddress;
  18. /**
  19. * Extract customer data from an order.
  20. */
  21. class OrderCustomerExtractor
  22. {
  23. /**
  24. * @var OrderRepositoryInterface
  25. */
  26. private $orderRepository;
  27. /**
  28. * @var CustomerRepositoryInterface
  29. */
  30. private $customerRepository;
  31. /**
  32. * @var CopyService
  33. */
  34. private $objectCopyService;
  35. /**
  36. * @var AddressFactory
  37. */
  38. private $addressFactory;
  39. /**
  40. * @var RegionFactory
  41. */
  42. private $regionFactory;
  43. /**
  44. * @var CustomerFactory
  45. */
  46. private $customerFactory;
  47. /**
  48. * @var QuoteAddressFactory
  49. */
  50. private $quoteAddressFactory;
  51. /**
  52. * @param OrderRepositoryInterface $orderRepository
  53. * @param CustomerRepositoryInterface $customerRepository
  54. * @param CopyService $objectCopyService
  55. * @param AddressFactory $addressFactory
  56. * @param RegionFactory $regionFactory
  57. * @param CustomerFactory $customerFactory
  58. * @param QuoteAddressFactory $quoteAddressFactory
  59. */
  60. public function __construct(
  61. OrderRepositoryInterface $orderRepository,
  62. CustomerRepositoryInterface $customerRepository,
  63. CopyService $objectCopyService,
  64. AddressFactory $addressFactory,
  65. RegionFactory $regionFactory,
  66. CustomerFactory $customerFactory,
  67. QuoteAddressFactory $quoteAddressFactory
  68. ) {
  69. $this->orderRepository = $orderRepository;
  70. $this->customerRepository = $customerRepository;
  71. $this->objectCopyService = $objectCopyService;
  72. $this->addressFactory = $addressFactory;
  73. $this->regionFactory = $regionFactory;
  74. $this->customerFactory = $customerFactory;
  75. $this->quoteAddressFactory = $quoteAddressFactory;
  76. }
  77. /**
  78. * Extract customer data from order.
  79. *
  80. * @param int $orderId
  81. * @return CustomerInterface
  82. */
  83. public function extract(int $orderId): CustomerInterface
  84. {
  85. $order = $this->orderRepository->get($orderId);
  86. //Simply return customer from DB.
  87. if ($order->getCustomerId()) {
  88. return $this->customerRepository->getById($order->getCustomerId());
  89. }
  90. //Prepare customer data from order data if customer doesn't exist yet.
  91. $customerData = $this->objectCopyService->copyFieldsetToTarget(
  92. 'order_address',
  93. 'to_customer',
  94. $order->getBillingAddress(),
  95. []
  96. );
  97. $processedAddressData = [];
  98. $customerAddresses = [];
  99. foreach ($order->getAddresses() as $orderAddress) {
  100. $addressData = $this->objectCopyService
  101. ->copyFieldsetToTarget('order_address', 'to_customer_address', $orderAddress, []);
  102. $index = array_search($addressData, $processedAddressData);
  103. if ($index === false) {
  104. // create new customer address only if it is unique
  105. $customerAddress = $this->addressFactory->create(['data' => $addressData]);
  106. $customerAddress->setIsDefaultBilling(false);
  107. $customerAddress->setIsDefaultShipping(false);
  108. if (is_string($orderAddress->getRegion())) {
  109. /** @var RegionInterface $region */
  110. $region = $this->regionFactory->create();
  111. $region->setRegion($orderAddress->getRegion());
  112. $region->setRegionCode($orderAddress->getRegionCode());
  113. $region->setRegionId($orderAddress->getRegionId());
  114. $customerAddress->setRegion($region);
  115. }
  116. $processedAddressData[] = $addressData;
  117. $customerAddresses[] = $customerAddress;
  118. $index = count($processedAddressData) - 1;
  119. }
  120. $customerAddress = $customerAddresses[$index];
  121. // make sure that address type flags from equal addresses are stored in one resulted address
  122. if ($orderAddress->getAddressType() == OrderAddress::TYPE_BILLING) {
  123. $customerAddress->setIsDefaultBilling(true);
  124. }
  125. if ($orderAddress->getAddressType() == OrderAddress::TYPE_SHIPPING) {
  126. $customerAddress->setIsDefaultShipping(true);
  127. }
  128. }
  129. $customerData['addresses'] = $customerAddresses;
  130. return $this->customerFactory->create(['data' => $customerData]);
  131. }
  132. }