LastOrderedItems.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\CustomerData;
  7. use Magento\Customer\CustomerData\SectionSourceInterface;
  8. use Magento\Catalog\Api\ProductRepositoryInterface;
  9. use Magento\Framework\Exception\NoSuchEntityException;
  10. use Psr\Log\LoggerInterface;
  11. /**
  12. * Returns information for "Recently Ordered" widget.
  13. * It contains list of 5 salable products from the last placed order.
  14. * Qty of products to display is limited by LastOrderedItems::SIDEBAR_ORDER_LIMIT constant.
  15. */
  16. class LastOrderedItems implements SectionSourceInterface
  17. {
  18. /**
  19. * Limit of orders in side bar
  20. */
  21. const SIDEBAR_ORDER_LIMIT = 5;
  22. /**
  23. * @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory
  24. */
  25. protected $_orderCollectionFactory;
  26. /**
  27. * @var \Magento\Sales\Model\Order\Config
  28. */
  29. protected $_orderConfig;
  30. /**
  31. * @var \Magento\Customer\Model\Session
  32. */
  33. protected $_customerSession;
  34. /**
  35. * @var \Magento\Framework\App\Http\Context
  36. */
  37. protected $httpContext;
  38. /**
  39. * @var \Magento\Sales\Model\ResourceModel\Order\Collection
  40. */
  41. protected $orders;
  42. /**
  43. * @var \Magento\CatalogInventory\Api\StockRegistryInterface
  44. */
  45. protected $stockRegistry;
  46. /**
  47. * @var \Magento\Store\Model\StoreManagerInterface
  48. */
  49. private $_storeManager;
  50. /**
  51. * @var \Magento\Catalog\Api\ProductRepositoryInterface
  52. */
  53. private $productRepository;
  54. /**
  55. * @var LoggerInterface
  56. */
  57. private $logger;
  58. /**
  59. * @param \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory
  60. * @param \Magento\Sales\Model\Order\Config $orderConfig
  61. * @param \Magento\Customer\Model\Session $customerSession
  62. * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
  63. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  64. * @param ProductRepositoryInterface $productRepository
  65. * @param LoggerInterface $logger
  66. */
  67. public function __construct(
  68. \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
  69. \Magento\Sales\Model\Order\Config $orderConfig,
  70. \Magento\Customer\Model\Session $customerSession,
  71. \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
  72. \Magento\Store\Model\StoreManagerInterface $storeManager,
  73. ProductRepositoryInterface $productRepository,
  74. LoggerInterface $logger
  75. ) {
  76. $this->_orderCollectionFactory = $orderCollectionFactory;
  77. $this->_orderConfig = $orderConfig;
  78. $this->_customerSession = $customerSession;
  79. $this->stockRegistry = $stockRegistry;
  80. $this->_storeManager = $storeManager;
  81. $this->productRepository = $productRepository;
  82. $this->logger = $logger;
  83. }
  84. /**
  85. * Init last placed customer order for display on front
  86. *
  87. * @return void
  88. */
  89. protected function initOrders()
  90. {
  91. $customerId = $this->_customerSession->getCustomerId();
  92. $orders = $this->_orderCollectionFactory->create()
  93. ->addAttributeToFilter('customer_id', $customerId)
  94. ->addAttributeToFilter('status', ['in' => $this->_orderConfig->getVisibleOnFrontStatuses()])
  95. ->addAttributeToSort('created_at', 'desc')
  96. ->setPage(1, 1);
  97. //TODO: add filter by current website
  98. $this->orders = $orders;
  99. }
  100. /**
  101. * Get list of last ordered products
  102. *
  103. * @return array
  104. */
  105. protected function getItems()
  106. {
  107. $items = [];
  108. $order = $this->getLastOrder();
  109. $limit = self::SIDEBAR_ORDER_LIMIT;
  110. if ($order) {
  111. $website = $this->_storeManager->getStore()->getWebsiteId();
  112. /** @var \Magento\Sales\Model\Order\Item $item */
  113. foreach ($order->getParentItemsRandomCollection($limit) as $item) {
  114. /** @var \Magento\Catalog\Model\Product $product */
  115. try {
  116. $product = $this->productRepository->getById(
  117. $item->getProductId(),
  118. false,
  119. $this->_storeManager->getStore()->getId()
  120. );
  121. } catch (NoSuchEntityException $noEntityException) {
  122. $this->logger->critical($noEntityException);
  123. continue;
  124. }
  125. if (isset($product) && in_array($website, $product->getWebsiteIds())) {
  126. $url = $product->isVisibleInSiteVisibility() ? $product->getProductUrl() : null;
  127. $items[] = [
  128. 'id' => $item->getId(),
  129. 'name' => $item->getName(),
  130. 'url' => $url,
  131. 'is_saleable' => $this->isItemAvailableForReorder($item),
  132. ];
  133. }
  134. }
  135. }
  136. return $items;
  137. }
  138. /**
  139. * Check item product availability for reorder
  140. *
  141. * @param \Magento\Sales\Model\Order\Item $orderItem
  142. * @return boolean
  143. */
  144. protected function isItemAvailableForReorder(\Magento\Sales\Model\Order\Item $orderItem)
  145. {
  146. try {
  147. $stockItem = $this->stockRegistry->getStockItem(
  148. $orderItem->getProduct()->getId(),
  149. $orderItem->getStore()->getWebsiteId()
  150. );
  151. return $stockItem->getIsInStock();
  152. } catch (NoSuchEntityException $noEntityException) {
  153. return false;
  154. }
  155. }
  156. /**
  157. * Last order getter
  158. *
  159. * @return \Magento\Sales\Model\Order|void
  160. */
  161. protected function getLastOrder()
  162. {
  163. if (!$this->orders) {
  164. $this->initOrders();
  165. }
  166. foreach ($this->orders as $order) {
  167. return $order;
  168. }
  169. }
  170. /**
  171. * {@inheritdoc}
  172. */
  173. public function getSectionData()
  174. {
  175. return ['items' => $this->getItems()];
  176. }
  177. }