Refunded.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\Model\ResourceModel\Report;
  7. /**
  8. * Refund report resource model
  9. *
  10. * @author Magento Core Team <core@magentocommerce.com>
  11. */
  12. class Refunded extends AbstractReport
  13. {
  14. /**
  15. * Model initialization
  16. *
  17. * @return void
  18. */
  19. protected function _construct()
  20. {
  21. $this->_setResource('sales');
  22. }
  23. /**
  24. * Aggregate Refunded data
  25. *
  26. * @param string|int|\DateTime|array|null $from
  27. * @param string|int|\DateTime|array|null $to
  28. * @return $this
  29. */
  30. public function aggregate($from = null, $to = null)
  31. {
  32. $this->_aggregateByOrderCreatedAt($from, $to);
  33. $this->_aggregateByRefundCreatedAt($from, $to);
  34. $this->_setFlagData(\Magento\Reports\Model\Flag::REPORT_REFUNDED_FLAG_CODE);
  35. return $this;
  36. }
  37. /**
  38. * Aggregate refunded data by order created at as period
  39. *
  40. * @param string|null $from
  41. * @param string|null $to
  42. * @return $this
  43. * @throws \Exception
  44. */
  45. protected function _aggregateByOrderCreatedAt($from, $to)
  46. {
  47. $table = $this->getTable('sales_refunded_aggregated_order');
  48. $sourceTable = $this->getTable('sales_order');
  49. $connection = $this->getConnection();
  50. $connection->beginTransaction();
  51. try {
  52. if ($from !== null || $to !== null) {
  53. $subSelect = $this->_getTableDateRangeSelect($sourceTable, 'created_at', 'updated_at', $from, $to);
  54. } else {
  55. $subSelect = null;
  56. }
  57. $this->_clearTableByDateRange($table, $from, $to, $subSelect);
  58. // convert dates to current admin timezone
  59. $periodExpr = $connection->getDatePartSql(
  60. $this->getStoreTZOffsetQuery($sourceTable, 'created_at', $from, $to)
  61. );
  62. $columns = [
  63. 'period' => $periodExpr,
  64. 'store_id' => 'store_id',
  65. 'order_status' => 'status',
  66. 'orders_count' => new \Zend_Db_Expr('COUNT(total_refunded)'),
  67. 'refunded' => new \Zend_Db_Expr('SUM(base_total_refunded * base_to_global_rate)'),
  68. 'online_refunded' => new \Zend_Db_Expr('SUM(base_total_online_refunded * base_to_global_rate)'),
  69. 'offline_refunded' => new \Zend_Db_Expr('SUM(base_total_offline_refunded * base_to_global_rate)'),
  70. ];
  71. $select = $connection->select();
  72. $select->from(
  73. $sourceTable,
  74. $columns
  75. )->where(
  76. 'state != ?',
  77. \Magento\Sales\Model\Order::STATE_CANCELED
  78. )->where(
  79. 'base_total_refunded > ?',
  80. 0
  81. );
  82. if ($subSelect !== null) {
  83. $select->having($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
  84. }
  85. $select->group([$periodExpr, 'store_id', 'status']);
  86. $select->having('orders_count > 0');
  87. $insertQuery = $select->insertFromSelect($table, array_keys($columns));
  88. $connection->query($insertQuery);
  89. $select->reset();
  90. $columns = [
  91. 'period' => 'period',
  92. 'store_id' => new \Zend_Db_Expr('0'),
  93. 'order_status' => 'order_status',
  94. 'orders_count' => new \Zend_Db_Expr('SUM(orders_count)'),
  95. 'refunded' => new \Zend_Db_Expr('SUM(refunded)'),
  96. 'online_refunded' => new \Zend_Db_Expr('SUM(online_refunded)'),
  97. 'offline_refunded' => new \Zend_Db_Expr('SUM(offline_refunded)'),
  98. ];
  99. $select->from($table, $columns)->where('store_id != ?', 0);
  100. if ($subSelect !== null) {
  101. $select->where($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
  102. }
  103. $select->group(['period', 'order_status']);
  104. $insertQuery = $select->insertFromSelect($table, array_keys($columns));
  105. $connection->query($insertQuery);
  106. $connection->commit();
  107. } catch (\Exception $e) {
  108. $connection->rollBack();
  109. throw $e;
  110. }
  111. return $this;
  112. }
  113. /**
  114. * Aggregate refunded data by creditmemo created at as period
  115. *
  116. * @param string|null $from
  117. * @param string|null $to
  118. * @return $this
  119. * @throws \Exception
  120. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  121. */
  122. protected function _aggregateByRefundCreatedAt($from, $to)
  123. {
  124. $table = $this->getTable('sales_refunded_aggregated');
  125. $sourceTable = $this->getTable('sales_creditmemo');
  126. $orderTable = $this->getTable('sales_order');
  127. $connection = $this->getConnection();
  128. $connection->beginTransaction();
  129. try {
  130. if ($from !== null || $to !== null) {
  131. $subSelect = $this->_getTableDateRangeRelatedSelect(
  132. $sourceTable,
  133. $orderTable,
  134. ['order_id' => 'entity_id'],
  135. 'created_at',
  136. 'updated_at',
  137. $from,
  138. $to
  139. );
  140. } else {
  141. $subSelect = null;
  142. }
  143. $this->_clearTableByDateRange($table, $from, $to, $subSelect);
  144. // convert dates to current admin timezone
  145. $periodExpr = $connection->getDatePartSql(
  146. $this->getStoreTZOffsetQuery(
  147. ['source_table' => $sourceTable],
  148. 'source_table.created_at',
  149. $from,
  150. $to
  151. )
  152. );
  153. $columns = [
  154. 'period' => $periodExpr,
  155. 'store_id' => 'order_table.store_id',
  156. 'order_status' => 'order_table.status',
  157. 'orders_count' => new \Zend_Db_Expr('COUNT(order_table.entity_id)'),
  158. 'refunded' => new \Zend_Db_Expr(
  159. 'SUM(order_table.base_total_refunded * order_table.base_to_global_rate)'
  160. ),
  161. 'online_refunded' => new \Zend_Db_Expr(
  162. 'SUM(order_table.base_total_online_refunded * order_table.base_to_global_rate)'
  163. ),
  164. 'offline_refunded' => new \Zend_Db_Expr(
  165. 'SUM(order_table.base_total_offline_refunded * order_table.base_to_global_rate)'
  166. ),
  167. ];
  168. $select = $connection->select();
  169. $select->from(
  170. ['source_table' => $sourceTable],
  171. $columns
  172. )->joinInner(
  173. ['order_table' => $orderTable],
  174. 'source_table.order_id = order_table.entity_id AND ' . $connection->quoteInto(
  175. 'order_table.state != ?',
  176. \Magento\Sales\Model\Order::STATE_CANCELED
  177. ) . ' AND order_table.base_total_refunded > 0',
  178. []
  179. );
  180. $filterSubSelect = $connection->select();
  181. $filterSubSelect->from(
  182. ['filter_source_table' => $sourceTable],
  183. new \Zend_Db_Expr('MAX(filter_source_table.entity_id)')
  184. )->where(
  185. 'filter_source_table.order_id = source_table.order_id'
  186. );
  187. if ($subSelect !== null) {
  188. $select->having($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
  189. }
  190. $select->where('source_table.entity_id = (?)', new \Zend_Db_Expr($filterSubSelect));
  191. unset($filterSubSelect);
  192. $select->group([$periodExpr, 'order_table.store_id', 'order_table.status']);
  193. $select->having('orders_count > 0');
  194. $insertQuery = $select->insertFromSelect($table, array_keys($columns));
  195. $connection->query($insertQuery);
  196. $select->reset();
  197. $columns = [
  198. 'period' => 'period',
  199. 'store_id' => new \Zend_Db_Expr('0'),
  200. 'order_status' => 'order_status',
  201. 'orders_count' => new \Zend_Db_Expr('SUM(orders_count)'),
  202. 'refunded' => new \Zend_Db_Expr('SUM(refunded)'),
  203. 'online_refunded' => new \Zend_Db_Expr('SUM(online_refunded)'),
  204. 'offline_refunded' => new \Zend_Db_Expr('SUM(offline_refunded)'),
  205. ];
  206. $select->from($table, $columns)->where('store_id != ?', 0);
  207. if ($subSelect !== null) {
  208. $select->where($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
  209. }
  210. $select->group(['period', 'order_status']);
  211. $insertQuery = $select->insertFromSelect($table, array_keys($columns));
  212. $connection->query($insertQuery);
  213. } catch (\Exception $e) {
  214. $connection->rollBack();
  215. throw $e;
  216. }
  217. $connection->commit();
  218. return $this;
  219. }
  220. }