Collection.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\Model\ResourceModel\Sale;
  7. use Magento\Framework\Data\Collection\EntityFactory;
  8. use Magento\Store\Model\StoreManagerInterface;
  9. use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
  10. use Magento\Framework\Event\ManagerInterface;
  11. use Psr\Log\LoggerInterface as Logger;
  12. /**
  13. * Sales Collection
  14. */
  15. class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
  16. {
  17. /**
  18. * Totals data
  19. *
  20. * @var array
  21. */
  22. protected $_totals = ['lifetime' => 0, 'base_lifetime' => 0, 'base_avgsale' => 0, 'num_orders' => 0];
  23. /**
  24. * Customer Id
  25. *
  26. * @var int
  27. */
  28. protected $_customerId;
  29. /**
  30. * Order state value
  31. *
  32. * @var null|string|array
  33. */
  34. protected $_state = null;
  35. /**
  36. * Order state condition
  37. *
  38. * @var string
  39. */
  40. protected $_orderStateCondition = null;
  41. /**
  42. * @var \Magento\Store\Model\ResourceModel\Store\CollectionFactory
  43. */
  44. protected $_storeCollectionFactory;
  45. /**
  46. * @var StoreManagerInterface
  47. */
  48. protected $_storeManager;
  49. /**
  50. * @param EntityFactory $entityFactory
  51. * @param Logger $logger
  52. * @param FetchStrategyInterface $fetchStrategy
  53. * @param ManagerInterface $eventManager
  54. * @param \Magento\Store\Model\ResourceModel\Store\CollectionFactory $storeCollectionFactory
  55. * @param StoreManagerInterface $storeManager
  56. */
  57. public function __construct(
  58. EntityFactory $entityFactory,
  59. Logger $logger,
  60. FetchStrategyInterface $fetchStrategy,
  61. ManagerInterface $eventManager,
  62. \Magento\Store\Model\ResourceModel\Store\CollectionFactory $storeCollectionFactory,
  63. StoreManagerInterface $storeManager
  64. ) {
  65. $this->_storeCollectionFactory = $storeCollectionFactory;
  66. $this->_storeManager = $storeManager;
  67. parent::__construct(
  68. $entityFactory,
  69. $logger,
  70. $fetchStrategy,
  71. $eventManager
  72. );
  73. }
  74. /**
  75. * {@inheritdoc}
  76. */
  77. protected function _construct()
  78. {
  79. parent::_construct();
  80. $this->_init(\Magento\Sales\Model\Order::class, \Magento\Sales\Model\ResourceModel\Order::class);
  81. }
  82. /**
  83. * Set filter by customer Id
  84. *
  85. * @param int $customerId
  86. * @return $this
  87. */
  88. public function setCustomerIdFilter($customerId)
  89. {
  90. $this->_customerId = (int)$customerId;
  91. return $this;
  92. }
  93. /**
  94. * Add filter by stores
  95. *
  96. * @param array $storeIds
  97. * @return $this
  98. */
  99. public function addStoreFilter($storeIds)
  100. {
  101. return $this->addFieldToFilter('store_id', ['in' => $storeIds]);
  102. }
  103. /**
  104. * Set filter by order state
  105. *
  106. * @param string|array $state
  107. * @param bool $exclude
  108. * @return $this
  109. */
  110. public function setOrderStateFilter($state, $exclude = false)
  111. {
  112. $this->_orderStateCondition = $exclude ? 'NOT IN' : 'IN';
  113. $this->_state = !is_array($state) ? [$state] : $state;
  114. return $this;
  115. }
  116. /**
  117. * Before load action
  118. *
  119. * @return $this
  120. */
  121. protected function _beforeLoad()
  122. {
  123. $this->getSelect()
  124. ->columns(
  125. [
  126. 'store_id',
  127. 'lifetime' => new \Zend_Db_Expr('SUM(base_grand_total)'),
  128. 'base_lifetime' => new \Zend_Db_Expr('SUM(base_grand_total * base_to_global_rate)'),
  129. 'avgsale' => new \Zend_Db_Expr('AVG(base_grand_total)'),
  130. 'base_avgsale' => new \Zend_Db_Expr('AVG(base_grand_total * base_to_global_rate)'),
  131. 'num_orders' => new \Zend_Db_Expr('COUNT(base_grand_total)')
  132. ]
  133. )
  134. ->group('store_id');
  135. if ($this->_customerId) {
  136. $this->addFieldToFilter('customer_id', $this->_customerId);
  137. }
  138. if ($this->_state !== null) {
  139. $condition = '';
  140. switch ($this->_orderStateCondition) {
  141. case 'IN':
  142. $condition = 'in';
  143. break;
  144. case 'NOT IN':
  145. $condition = 'nin';
  146. break;
  147. }
  148. $this->addFieldToFilter('state', [$condition => $this->_state]);
  149. }
  150. $this->_eventManager->dispatch('sales_sale_collection_query_before', ['collection' => $this]);
  151. return $this;
  152. }
  153. /**
  154. * Load data
  155. *
  156. * @param bool $printQuery
  157. * @param bool $logQuery
  158. * @return $this
  159. */
  160. public function load($printQuery = false, $logQuery = false)
  161. {
  162. if ($this->isLoaded()) {
  163. return $this;
  164. }
  165. $this->_beforeLoad();
  166. $this->_renderFilters()->_renderOrders()->_renderLimit();
  167. $this->printLogQuery($printQuery, $logQuery);
  168. $data = $this->getData();
  169. $this->resetData();
  170. $stores = $this->_storeCollectionFactory->create()->setWithoutDefaultFilter()->load()->toOptionHash();
  171. $this->_items = [];
  172. foreach ($data as $v) {
  173. $storeObject = new \Magento\Framework\DataObject($v);
  174. $storeId = $v['store_id'];
  175. $storeName = isset($stores[$storeId]) ? $stores[$storeId] : null;
  176. $storeObject->setStoreName(
  177. $storeName
  178. )->setWebsiteId(
  179. $this->_storeManager->getStore($storeId)->getWebsiteId()
  180. )->setAvgNormalized(
  181. $v['avgsale'] * $v['num_orders']
  182. );
  183. $this->_items[$storeId] = $storeObject;
  184. foreach (array_keys($this->_totals) as $key) {
  185. $this->_totals[$key] += $storeObject->getData($key);
  186. }
  187. }
  188. if ($this->_totals['num_orders']) {
  189. $this->_totals['avgsale'] = $this->_totals['base_lifetime'] / $this->_totals['num_orders'];
  190. }
  191. $this->_setIsLoaded();
  192. $this->_afterLoad();
  193. return $this;
  194. }
  195. /**
  196. * Retrieve totals data converted into \Magento\Framework\DataObject
  197. *
  198. * @return \Magento\Framework\DataObject
  199. */
  200. public function getTotals()
  201. {
  202. return new \Magento\Framework\DataObject($this->_totals);
  203. }
  204. }