PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/app/code/core/Mage/Sales/Model/Resource/Report/Bestsellers.php

https://gitlab.com/LisovyiEvhenii/ismextensions
PHP | 324 lines | 224 code | 37 blank | 63 comment | 5 complexity | 75048327f74601773dbc6528968c2dbb MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magento.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magento.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Sales
  23. * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Bestsellers report resource model
  28. *
  29. * @category Mage
  30. * @package Mage_Sales
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Sales_Model_Resource_Report_Bestsellers extends Mage_Sales_Model_Resource_Report_Abstract
  34. {
  35. const AGGREGATION_DAILY = 'daily';
  36. const AGGREGATION_MONTHLY = 'monthly';
  37. const AGGREGATION_YEARLY = 'yearly';
  38. /**
  39. * Model initialization
  40. *
  41. */
  42. protected function _construct()
  43. {
  44. $this->_init('sales/bestsellers_aggregated_' . self::AGGREGATION_DAILY, 'id');
  45. }
  46. /**
  47. * Aggregate Orders data by order created at
  48. *
  49. * @param mixed $from
  50. * @param mixed $to
  51. * @return Mage_Sales_Model_Resource_Report_Bestsellers
  52. */
  53. public function aggregate($from = null, $to = null)
  54. {
  55. // convert input dates to UTC to be comparable with DATETIME fields in DB
  56. $from = $this->_dateToUtc($from);
  57. $to = $this->_dateToUtc($to);
  58. $this->_checkDates($from, $to);
  59. $adapter = $this->_getWriteAdapter();
  60. //$this->_getWriteAdapter()->beginTransaction();
  61. try {
  62. if ($from !== null || $to !== null) {
  63. $subSelect = $this->_getTableDateRangeSelect(
  64. $this->getTable('sales/order'),
  65. 'created_at', 'updated_at', $from, $to
  66. );
  67. } else {
  68. $subSelect = null;
  69. }
  70. $this->_clearTableByDateRange($this->getMainTable(), $from, $to, $subSelect);
  71. // convert dates from UTC to current admin timezone
  72. $periodExpr = $adapter->getDatePartSql(
  73. $this->getStoreTZOffsetQuery(
  74. array('source_table' => $this->getTable('sales/order')),
  75. 'source_table.created_at', $from, $to
  76. )
  77. );
  78. $helper = Mage::getResourceHelper('core');
  79. $select = $adapter->select();
  80. $select->group(array(
  81. $periodExpr,
  82. 'source_table.store_id',
  83. 'order_item.product_id'
  84. ));
  85. $columns = array(
  86. 'period' => $periodExpr,
  87. 'store_id' => 'source_table.store_id',
  88. 'product_id' => 'order_item.product_id',
  89. 'product_name' => new Zend_Db_Expr(
  90. sprintf('MIN(%s)',
  91. $adapter->getIfNullSql('product_name.value','product_default_name.value')
  92. )
  93. ),
  94. 'product_price' => new Zend_Db_Expr(
  95. sprintf('%s',
  96. $helper->prepareColumn(
  97. sprintf('MIN(%s)',
  98. $adapter->getIfNullSql(
  99. $adapter->getIfNullSql('product_price.value','product_default_price.value'), 0)
  100. ),
  101. $select->getPart(Zend_Db_Select::GROUP)
  102. )
  103. )
  104. ),
  105. 'qty_ordered' => new Zend_Db_Expr('SUM(order_item.qty_ordered)')
  106. );
  107. $select
  108. ->from(
  109. array(
  110. 'source_table' => $this->getTable('sales/order')),
  111. $columns)
  112. ->joinInner(
  113. array(
  114. 'order_item' => $this->getTable('sales/order_item')),
  115. 'order_item.order_id = source_table.entity_id',
  116. array()
  117. )
  118. ->where('source_table.state != ?', Mage_Sales_Model_Order::STATE_CANCELED);
  119. /** @var Mage_Catalog_Model_Resource_Product $product */
  120. $product = Mage::getResourceSingleton('catalog/product');
  121. $productTypes = array(
  122. Mage_Catalog_Model_Product_Type::TYPE_GROUPED,
  123. Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE,
  124. Mage_Catalog_Model_Product_Type::TYPE_BUNDLE,
  125. );
  126. $joinExpr = array(
  127. 'product.entity_id = order_item.product_id',
  128. $adapter->quoteInto('product.entity_type_id = ?', $product->getTypeId()),
  129. $adapter->quoteInto('product.type_id NOT IN(?)', $productTypes)
  130. );
  131. $joinExpr = implode(' AND ', $joinExpr);
  132. $select->joinInner(
  133. array(
  134. 'product' => $this->getTable('catalog/product')),
  135. $joinExpr,
  136. array()
  137. );
  138. // join product attributes Name & Price
  139. $attr = $product->getAttribute('name');
  140. $joinExprProductName = array(
  141. 'product_name.entity_id = product.entity_id',
  142. 'product_name.store_id = source_table.store_id',
  143. $adapter->quoteInto('product_name.entity_type_id = ?', $product->getTypeId()),
  144. $adapter->quoteInto('product_name.attribute_id = ?', $attr->getAttributeId())
  145. );
  146. $joinExprProductName = implode(' AND ', $joinExprProductName);
  147. $joinExprProductDefaultName = array(
  148. 'product_default_name.entity_id = product.entity_id',
  149. 'product_default_name.store_id = 0',
  150. $adapter->quoteInto('product_default_name.entity_type_id = ?', $product->getTypeId()),
  151. $adapter->quoteInto('product_default_name.attribute_id = ?', $attr->getAttributeId())
  152. );
  153. $joinExprProductDefaultName = implode(' AND ', $joinExprProductDefaultName);
  154. $select->joinLeft(
  155. array(
  156. 'product_name' => $attr->getBackend()->getTable()),
  157. $joinExprProductName,
  158. array()
  159. )
  160. ->joinLeft(
  161. array(
  162. 'product_default_name' => $attr->getBackend()->getTable()),
  163. $joinExprProductDefaultName,
  164. array()
  165. );
  166. $attr = $product->getAttribute('price');
  167. $joinExprProductPrice = array(
  168. 'product_price.entity_id = product.entity_id',
  169. 'product_price.store_id = source_table.store_id',
  170. $adapter->quoteInto('product_price.entity_type_id = ?', $product->getTypeId()),
  171. $adapter->quoteInto('product_price.attribute_id = ?', $attr->getAttributeId())
  172. );
  173. $joinExprProductPrice = implode(' AND ', $joinExprProductPrice);
  174. $joinExprProductDefPrice = array(
  175. 'product_default_price.entity_id = product.entity_id',
  176. 'product_default_price.store_id = 0',
  177. $adapter->quoteInto('product_default_price.entity_type_id = ?', $product->getTypeId()),
  178. $adapter->quoteInto('product_default_price.attribute_id = ?', $attr->getAttributeId())
  179. );
  180. $joinExprProductDefPrice = implode(' AND ', $joinExprProductDefPrice);
  181. $select->joinLeft(
  182. array('product_price' => $attr->getBackend()->getTable()),
  183. $joinExprProductPrice,
  184. array()
  185. )
  186. ->joinLeft(
  187. array('product_default_price' => $attr->getBackend()->getTable()),
  188. $joinExprProductDefPrice,
  189. array()
  190. );
  191. if ($subSelect !== null) {
  192. $select->having($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
  193. }
  194. $select->useStraightJoin(); // important!
  195. $insertQuery = $helper->getInsertFromSelectUsingAnalytic($select, $this->getMainTable(),
  196. array_keys($columns));
  197. $adapter->query($insertQuery);
  198. $this->_aggregateDefault($subSelect);
  199. // update rating
  200. $this->_updateRatingPos(self::AGGREGATION_DAILY);
  201. $this->_updateRatingPos(self::AGGREGATION_MONTHLY);
  202. $this->_updateRatingPos(self::AGGREGATION_YEARLY);
  203. $this->_setFlagData(Mage_Reports_Model_Flag::REPORT_BESTSELLERS_FLAG_CODE);
  204. } catch (Exception $e) {
  205. //$this->_getWriteAdapter()->rollBack();
  206. throw $e;
  207. }
  208. //$this->_getWriteAdapter()->commit();
  209. return $this;
  210. }
  211. /**
  212. * Aggregate Orders data for default store
  213. *
  214. * @param object Varien_Db_Select|null $subSelect
  215. * @return Mage_Sales_Model_Resource_Report_Bestsellers
  216. */
  217. protected function _aggregateDefault($subSelect = null)
  218. {
  219. $adapter = $this->_getWriteAdapter();
  220. $select = $adapter->select();
  221. /** @var Mage_Catalog_Model_Resource_Product $product */
  222. $product = Mage::getResourceSingleton('catalog/product');
  223. $attr = $product->getAttribute('price');
  224. $helper = Mage::getResourceHelper('core');
  225. $columns = array(
  226. 'period' => 'period',
  227. 'store_id' => new Zend_Db_Expr(Mage_Core_Model_App::ADMIN_STORE_ID),
  228. 'product_id' => 'product_id',
  229. 'product_name' => new Zend_Db_Expr('MIN(product_name)'),
  230. 'product_price' => new Zend_Db_Expr(
  231. sprintf('%s',
  232. $helper->prepareColumn(
  233. sprintf('MIN(%s)',
  234. $adapter->getIfNullSql('product_default_price.value', 0)
  235. ),
  236. $select->getPart(Zend_Db_Select::GROUP)
  237. )
  238. )
  239. ),
  240. 'qty_ordered' => new Zend_Db_Expr('SUM(qty_ordered)'),
  241. );
  242. $select->from($this->getMainTable(), $columns)
  243. ->where($this->getMainTable() . '.store_id <> ?', 0);
  244. $joinExprProductDefPrice = array(
  245. 'product_default_price.entity_id = ' . $this->getMainTable() . '.product_id',
  246. 'product_default_price.store_id = 0',
  247. $adapter->quoteInto('product_default_price.entity_type_id = ?', $product->getTypeId()),
  248. $adapter->quoteInto('product_default_price.attribute_id = ?', $attr->getAttributeId())
  249. );
  250. $joinExprProductDefPrice = implode(' AND ', $joinExprProductDefPrice);
  251. $select->joinLeft(
  252. array('product_default_price' => $attr->getBackend()->getTable()),
  253. $joinExprProductDefPrice,
  254. array()
  255. );
  256. if ($subSelect !== null) {
  257. $select->where($this->_makeConditionFromDateRangeSelect($subSelect, 'period'));
  258. }
  259. $select->group(array(
  260. 'period',
  261. 'product_id'
  262. ));
  263. $insertQuery = $helper->getInsertFromSelectUsingAnalytic($select, $this->getMainTable(),
  264. array_keys($columns));
  265. $adapter->query($insertQuery);
  266. return $this;
  267. }
  268. /**
  269. * Update rating position
  270. *
  271. * @param string $aggregation One of Mage_Sales_Model_Resource_Report_Bestsellers::AGGREGATION_XXX constants
  272. * @return Mage_Sales_Model_Resource_Report_Bestsellers
  273. */
  274. protected function _updateRatingPos($aggregation)
  275. {
  276. $aggregationTable = $this->getTable('sales/bestsellers_aggregated_' . $aggregation);
  277. $aggregationAliases = array(
  278. 'daily' => self::AGGREGATION_DAILY,
  279. 'monthly' => self::AGGREGATION_MONTHLY,
  280. 'yearly' => self::AGGREGATION_YEARLY
  281. );
  282. Mage::getResourceHelper('sales')
  283. ->getBestsellersReportUpdateRatingPos($aggregation, $aggregationAliases,
  284. $this->getMainTable(), $aggregationTable);
  285. return $this;
  286. }
  287. }