CustomerOrders.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Signifyd\Model;
  7. use Exception;
  8. use Magento\Directory\Model\Currency;
  9. use Magento\Directory\Model\CurrencyFactory;
  10. use Magento\Framework\Api\FilterBuilder;
  11. use Magento\Framework\Api\SearchCriteriaBuilder;
  12. use Magento\Sales\Api\Data\OrderInterface;
  13. use Magento\Sales\Api\OrderRepositoryInterface;
  14. use Psr\Log\LoggerInterface;
  15. /**
  16. * Provides information about customer orders.
  17. *
  18. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  19. */
  20. class CustomerOrders
  21. {
  22. /**
  23. * @var SearchCriteriaBuilder
  24. */
  25. private $searchCriteriaBuilder;
  26. /**
  27. * @var FilterBuilder
  28. */
  29. private $filterBuilder;
  30. /**
  31. * @var OrderRepositoryInterface
  32. */
  33. private $orderRepository;
  34. /**
  35. * @var LoggerInterface
  36. */
  37. private $logger;
  38. /**
  39. * @var CurrencyFactory
  40. */
  41. private $currencyFactory;
  42. /**
  43. * @var array
  44. */
  45. private $currencies = [];
  46. /**
  47. * @var string
  48. */
  49. private static $usdCurrencyCode = 'USD';
  50. /**
  51. * @param SearchCriteriaBuilder $searchCriteriaBuilder
  52. * @param FilterBuilder $filterBuilder
  53. * @param OrderRepositoryInterface $orderRepository
  54. * @param CurrencyFactory $currencyFactory
  55. * @param LoggerInterface $logger
  56. */
  57. public function __construct(
  58. SearchCriteriaBuilder $searchCriteriaBuilder,
  59. FilterBuilder $filterBuilder,
  60. OrderRepositoryInterface $orderRepository,
  61. CurrencyFactory $currencyFactory,
  62. LoggerInterface $logger
  63. ) {
  64. $this->searchCriteriaBuilder = $searchCriteriaBuilder;
  65. $this->filterBuilder = $filterBuilder;
  66. $this->orderRepository = $orderRepository;
  67. $this->currencyFactory = $currencyFactory;
  68. $this->logger = $logger;
  69. }
  70. /**
  71. * Returns aggregated customer orders count and total amount in USD.
  72. *
  73. * Returned array contains next keys:
  74. * aggregateOrderCount - total count of orders placed by this account since it was created, including the current
  75. * aggregateOrderDollars - total amount spent by this account since it was created, including the current order
  76. *
  77. * @param int $customerId
  78. * @return array
  79. */
  80. public function getAggregatedOrdersInfo($customerId)
  81. {
  82. $result = [
  83. 'aggregateOrderCount' => null,
  84. 'aggregateOrderDollars' => null
  85. ];
  86. $customerOrders = $this->getCustomerOrders($customerId);
  87. if (!empty($customerOrders)) {
  88. try {
  89. $orderTotalDollars = 0.0;
  90. foreach ($customerOrders as $order) {
  91. $orderTotalDollars += $this->getUsdOrderTotal(
  92. $order->getBaseGrandTotal(),
  93. $order->getBaseCurrencyCode()
  94. );
  95. }
  96. $result = [
  97. 'aggregateOrderCount' => count($customerOrders),
  98. 'aggregateOrderDollars' => $orderTotalDollars
  99. ];
  100. } catch (Exception $e) {
  101. $this->logger->error($e->getMessage());
  102. }
  103. }
  104. return $result;
  105. }
  106. /**
  107. * Returns customer orders.
  108. *
  109. * @param int $customerId
  110. * @return OrderInterface[]
  111. */
  112. private function getCustomerOrders($customerId)
  113. {
  114. $filters = [
  115. $this->filterBuilder->setField(OrderInterface::CUSTOMER_ID)->setValue($customerId)->create()
  116. ];
  117. $this->searchCriteriaBuilder->addFilters($filters);
  118. $searchCriteria = $this->searchCriteriaBuilder->create();
  119. $searchResults = $this->orderRepository->getList($searchCriteria);
  120. return $searchResults->getItems();
  121. }
  122. /**
  123. * Returns amount in USD.
  124. *
  125. * @param float $amount
  126. * @param string $currency
  127. * @return float
  128. */
  129. private function getUsdOrderTotal($amount, $currency)
  130. {
  131. if ($currency === self::$usdCurrencyCode) {
  132. return $amount;
  133. }
  134. $operationCurrency = $this->getCurrencyByCode($currency);
  135. return $operationCurrency->convert($amount, self::$usdCurrencyCode);
  136. }
  137. /**
  138. * Returns currency by currency code.
  139. *
  140. * @param string|null $currencyCode
  141. * @return Currency
  142. */
  143. private function getCurrencyByCode($currencyCode)
  144. {
  145. if (isset($this->currencies[$currencyCode])) {
  146. return $this->currencies[$currencyCode];
  147. }
  148. /** @var Currency $currency */
  149. $currency = $this->currencyFactory->create();
  150. $this->currencies[$currencyCode] = $currency->load($currencyCode);
  151. return $this->currencies[$currencyCode];
  152. }
  153. }