PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/dashtrends/dashtrends.php

https://bitbucket.org/Yanachkov/updatepanda18
PHP | 351 lines | 272 code | 44 blank | 35 comment | 28 complexity | 49eabf70302b2d75a434c796ee6a24fe MD5 | raw file
Possible License(s): LGPL-3.0, MPL-2.0, JSON, MIT, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /*
  3. * 2007-2016 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Academic Free License (AFL 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/afl-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@prestashop.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 PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2016 PrestaShop SA
  23. * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. if (!defined('_PS_VERSION_'))
  27. exit;
  28. class Dashtrends extends Module
  29. {
  30. protected $dashboard_data;
  31. protected $dashboard_data_compare;
  32. protected $dashboard_data_sum;
  33. protected $dashboard_data_sum_compare;
  34. protected $data_trends;
  35. public function __construct()
  36. {
  37. $this->name = 'dashtrends';
  38. $this->tab = 'dashboard';
  39. $this->version = '1.0.0';
  40. $this->author = 'PrestaShop';
  41. $this->push_filename = _PS_CACHE_DIR_.'push/trends';
  42. $this->allow_push = true;
  43. parent::__construct();
  44. $this->displayName = $this->l('Dashboard Trends');
  45. $this->description = $this->l('Adds a block with a graphical representation of the development of your store(s) based on selected key data.');
  46. $this->ps_versions_compliancy = array('min' => '1.6', 'max' => '1.7.0.99');
  47. }
  48. public function install()
  49. {
  50. return (parent::install()
  51. && $this->registerHook('dashboardZoneTwo')
  52. && $this->registerHook('dashboardData')
  53. && $this->registerHook('actionAdminControllerSetMedia')
  54. && $this->registerHook('actionOrderStatusPostUpdate')
  55. );
  56. }
  57. public function hookActionAdminControllerSetMedia()
  58. {
  59. if (get_class($this->context->controller) == 'AdminDashboardController')
  60. $this->context->controller->addJs($this->_path.'views/js/'.$this->name.'.js');
  61. }
  62. public function hookDashboardZoneTwo($params)
  63. {
  64. $this->context->smarty->assign(array(
  65. 'currency' => $this->context->currency,
  66. '_PS_PRICE_DISPLAY_PRECISION_' => _PS_PRICE_DISPLAY_PRECISION_
  67. ));
  68. return $this->display(__FILE__, 'dashboard_zone_two.tpl');
  69. }
  70. protected function getData($date_from, $date_to)
  71. {
  72. // We need the following figures to calculate our stats
  73. $tmp_data = array(
  74. 'visits' => array(),
  75. 'orders' => array(),
  76. 'total_paid_tax_excl' => array(),
  77. 'total_purchases' => array(),
  78. 'total_expenses' => array()
  79. );
  80. if (Configuration::get('PS_DASHBOARD_SIMULATION'))
  81. {
  82. $from = strtotime($date_from.' 00:00:00');
  83. $to = min(time(), strtotime($date_to.' 23:59:59'));
  84. for ($date = $from; $date <= $to; $date = strtotime('+1 day', $date))
  85. {
  86. $tmp_data['visits'][$date] = round(rand(2000, 20000));
  87. $tmp_data['conversion_rate'][$date] = rand(80, 250) / 100;
  88. $tmp_data['average_cart_value'][$date] = round(rand(60, 200), 2);
  89. $tmp_data['orders'][$date] = round($tmp_data['visits'][$date] * $tmp_data['conversion_rate'][$date] / 100);
  90. $tmp_data['total_paid_tax_excl'][$date] = $tmp_data['orders'][$date] * $tmp_data['average_cart_value'][$date];
  91. $tmp_data['total_purchases'][$date] = $tmp_data['total_paid_tax_excl'][$date] * rand(50, 70) / 100;
  92. $tmp_data['total_expenses'][$date] = $tmp_data['total_paid_tax_excl'][$date] * rand(0, 10) / 100;
  93. }
  94. }
  95. else
  96. {
  97. $tmp_data['visits'] = AdminStatsController::getVisits(false, $date_from, $date_to, 'day');
  98. $tmp_data['orders'] = AdminStatsController::getOrders($date_from, $date_to, 'day');
  99. $tmp_data['total_paid_tax_excl'] = AdminStatsController::getTotalSales($date_from, $date_to, 'day');
  100. $tmp_data['total_purchases'] = AdminStatsController::getPurchases($date_from, $date_to, 'day');
  101. $tmp_data['total_expenses'] = AdminStatsController::getExpenses($date_from, $date_to, 'day');
  102. }
  103. return $tmp_data;
  104. }
  105. protected function refineData($date_from, $date_to, $gross_data)
  106. {
  107. $refined_data = array(
  108. 'sales' => array(),
  109. 'orders' => array(),
  110. 'average_cart_value' => array(),
  111. 'visits' => array(),
  112. 'conversion_rate' => array(),
  113. 'net_profits' => array()
  114. );
  115. $from = strtotime($date_from.' 00:00:00');
  116. $to = min(time(), strtotime($date_to.' 23:59:59'));
  117. for ($date = $from; $date <= $to; $date = strtotime('+1 day', $date))
  118. {
  119. $refined_data['sales'][$date] = 0;
  120. if (isset($gross_data['total_paid_tax_excl'][$date]))
  121. $refined_data['sales'][$date] += $gross_data['total_paid_tax_excl'][$date];
  122. $refined_data['orders'][$date] = isset($gross_data['orders'][$date]) ? $gross_data['orders'][$date] : 0;
  123. $refined_data['average_cart_value'][$date] = $refined_data['orders'][$date] ? $refined_data['sales'][$date] / $refined_data['orders'][$date] : 0;
  124. $refined_data['visits'][$date] = isset($gross_data['visits'][$date]) ? $gross_data['visits'][$date] : 0;
  125. $refined_data['conversion_rate'][$date] = $refined_data['visits'][$date] ? $refined_data['orders'][$date] / $refined_data['visits'][$date] : 0;
  126. $refined_data['net_profits'][$date] = 0;
  127. if (isset($gross_data['total_paid_tax_excl'][$date]))
  128. $refined_data['net_profits'][$date] += $gross_data['total_paid_tax_excl'][$date];
  129. if (isset($gross_data['total_purchases'][$date]))
  130. $refined_data['net_profits'][$date] -= $gross_data['total_purchases'][$date];
  131. if (isset($gross_data['total_expenses'][$date]))
  132. $refined_data['net_profits'][$date] -= $gross_data['total_expenses'][$date];
  133. }
  134. return $refined_data;
  135. }
  136. protected function addupData($data)
  137. {
  138. $summing = array(
  139. 'sales' => 0,
  140. 'orders' => 0,
  141. 'average_cart_value' => 0,
  142. 'visits' => 0,
  143. 'conversion_rate' => 0,
  144. 'net_profits' => 0
  145. );
  146. $summing['sales'] = array_sum($data['sales']);
  147. $summing['orders'] = array_sum($data['orders']);
  148. $summing['average_cart_value'] = $summing['sales'] ? $summing['sales'] / $summing['orders'] : 0;
  149. $summing['visits'] = array_sum($data['visits']);
  150. $summing['conversion_rate'] = $summing['visits'] ? $summing['orders'] / $summing['visits'] : 0;
  151. $summing['net_profits'] = array_sum($data['net_profits']);
  152. return $summing;
  153. }
  154. protected function compareData($data1, $data2)
  155. {
  156. return array(
  157. 'sales_score_trends' => array(
  158. 'way' => ($data1['sales'] == $data2['sales'] ? 'right' : ($data1['sales'] > $data2['sales'] ? 'up' : 'down')),
  159. 'value' => ($data1['sales'] > $data2['sales'] ? '+' : '').($data2['sales'] ? round(100 * $data1['sales'] / $data2['sales'] - 100, 2).'%' : '&infin;')
  160. ),
  161. 'orders_score_trends' => array(
  162. 'way' => ($data1['orders'] == $data2['orders'] ? 'right' : ($data1['orders'] > $data2['orders'] ? 'up' : 'down')),
  163. 'value' => ($data1['orders'] > $data2['orders'] ? '+' : '').($data2['orders'] ? round(100 * $data1['orders'] / $data2['orders'] - 100, 2).'%' : '&infin;')
  164. ),
  165. 'cart_value_score_trends' => array(
  166. 'way' => ($data1['average_cart_value'] == $data2['average_cart_value'] ? 'right' : ($data1['average_cart_value'] > $data2['average_cart_value'] ? 'up' : 'down')),
  167. 'value' => ($data1['average_cart_value'] > $data2['average_cart_value'] ? '+' : '').($data2['average_cart_value'] ? round(100 * $data1['average_cart_value'] / $data2['average_cart_value'] - 100, 2).'%' : '&infin;')
  168. ),
  169. 'visits_score_trends' => array(
  170. 'way' => ($data1['visits'] == $data2['visits'] ? 'right' : ($data1['visits'] > $data2['visits'] ? 'up' : 'down')),
  171. 'value' => ($data1['visits'] > $data2['visits'] ? '+' : '').($data2['visits'] ? round(100 * $data1['visits'] / $data2['visits'] - 100, 2).'%' : '&infin;')
  172. ),
  173. 'conversion_rate_score_trends' => array(
  174. 'way' => ($data1['conversion_rate'] == $data2['conversion_rate'] ? 'right' : ($data1['conversion_rate'] > $data2['conversion_rate'] ? 'up' : 'down')),
  175. 'value' => ($data1['conversion_rate'] > $data2['conversion_rate'] ? '+' : '') . ($data2['conversion_rate'] ? sprintf($this->l('%s points'), round(100 * ($data1['conversion_rate'] - $data2['conversion_rate']), 2)) : '&infin;')
  176. ),
  177. 'net_profits_score_trends' => array(
  178. 'way' => ($data1['net_profits'] == $data2['net_profits'] ? 'right' : ($data1['net_profits'] > $data2['net_profits'] ? 'up' : 'down')),
  179. 'value' => ($data1['net_profits'] > $data2['net_profits'] ? '+' : '').($data2['net_profits'] ? round(100 * $data1['net_profits'] / $data2['net_profits'] - 100, 2).'%' : '&infin;')
  180. )
  181. );
  182. }
  183. public function hookDashboardData($params)
  184. {
  185. $this->currency = clone $this->context->currency;
  186. // Retrieve, refine and add up data for the selected period
  187. $tmp_data = $this->getData($params['date_from'], $params['date_to']);
  188. $this->dashboard_data = $this->refineData($params['date_from'], $params['date_to'], $tmp_data);
  189. $this->dashboard_data_sum = $this->addupData($this->dashboard_data);
  190. if ($params['compare_from'] && $params['compare_from'] != '0000-00-00')
  191. {
  192. // Retrieve, refine and add up data for the comparison period
  193. $tmp_data_compare = $this->getData($params['compare_from'], $params['compare_to']);
  194. $this->dashboard_data_compare = $this->refineData($params['compare_from'], $params['compare_to'], $tmp_data_compare);
  195. $this->dashboard_data_sum_compare = $this->addupData($this->dashboard_data_compare);
  196. $this->data_trends = $this->compareData($this->dashboard_data_sum, $this->dashboard_data_sum_compare);
  197. $this->dashboard_data_compare = $this->translateCompareData($this->dashboard_data, $this->dashboard_data_compare);
  198. }
  199. $sales_score = Tools::displayPrice($this->dashboard_data_sum['sales'], $this->currency).
  200. $this->addTaxSuffix();
  201. $cart_value_score = Tools::displayPrice($this->dashboard_data_sum['average_cart_value'], $this->currency).
  202. $this->addTaxSuffix();
  203. $net_profit_score = Tools::displayPrice($this->dashboard_data_sum['net_profits'], $this->currency).
  204. $this->addTaxSuffix();
  205. return array(
  206. 'data_value' => array(
  207. 'sales_score' => $sales_score,
  208. 'orders_score' => Tools::displayNumber($this->dashboard_data_sum['orders'], $this->currency),
  209. 'cart_value_score' => $cart_value_score,
  210. 'visits_score' => Tools::displayNumber($this->dashboard_data_sum['visits'], $this->currency),
  211. 'conversion_rate_score' => round(100 * $this->dashboard_data_sum['conversion_rate'], 2).'%',
  212. 'net_profits_score' => $net_profit_score,
  213. ),
  214. 'data_trends' => $this->data_trends,
  215. 'data_chart' => array('dash_trends_chart1' => $this->getChartTrends()),
  216. );
  217. }
  218. protected function addTaxSuffix()
  219. {
  220. return ' <small>'.$this->l('tax excl.').'</small>';
  221. }
  222. protected function translateCompareData($normal, $compare)
  223. {
  224. $translated_array = array();
  225. foreach ($compare as $key => $date_array)
  226. {
  227. $normal_min = key($normal[$key]);
  228. end($normal[$key]); // move the internal pointer to the end of the array
  229. $normal_max = key($normal[$key]);
  230. reset($normal[$key]);
  231. $normal_size = $normal_max - $normal_min;
  232. $compare_min = key($compare[$key]);
  233. end($compare[$key]); // move the internal pointer to the end of the array
  234. $compare_max = key($compare[$key]);
  235. reset($compare[$key]);
  236. $compare_size = $compare_max - $compare_min;
  237. $translated_array[$key] = array();
  238. foreach ($date_array as $compare_date => $value)
  239. {
  240. $translation = $normal_min + ($compare_date - $compare_min) * ($normal_size / $compare_size);
  241. $translated_array[$key][number_format($translation, 0, '', '')] = $value;
  242. }
  243. }
  244. return $translated_array;
  245. }
  246. public function getChartTrends()
  247. {
  248. $chart_data = array();
  249. $chart_data_compare = array();
  250. foreach (array_keys($this->dashboard_data) as $chart_key)
  251. {
  252. $chart_data[$chart_key] = $chart_data_compare[$chart_key] = array();
  253. if (!$count = count($this->dashboard_data[$chart_key]))
  254. continue;
  255. // We calibrate 100% to the mean
  256. $calibration = array_sum($this->dashboard_data[$chart_key]) / $count;
  257. foreach ($this->dashboard_data[$chart_key] as $key => $value)
  258. $chart_data[$chart_key][] = array($key, $value);
  259. // min(10) is there to limit the growth to 1000%, beyond this limit it becomes unreadable
  260. //$chart_data[$chart_key][] = array(1000 * $key, $calibration ? min(10, $value / $calibration) : 0);
  261. if ($this->dashboard_data_compare)
  262. foreach ($this->dashboard_data_compare[$chart_key] as $key => $value)
  263. $chart_data_compare[$chart_key][] = array($key, $value);
  264. // min(10) is there to limit the growth to 1000%, beyond this limit it becomes unreadable
  265. /*$chart_data_compare[$chart_key][] = array(
  266. 1000 * $key,
  267. $calibration ? min(10, $value / $calibration) : 0
  268. );*/
  269. }
  270. $charts = array(
  271. 'sales' => $this->l('Sales'),
  272. 'orders' => $this->l('Orders'),
  273. 'average_cart_value' => $this->l('Average Cart Value'),
  274. 'visits' => $this->l('Visits'),
  275. 'conversion_rate' => $this->l('Conversion Rate'),
  276. 'net_profits' => $this->l('Net Profit')
  277. );
  278. $gfx_color = array('#1777B6','#2CA121','#E61409','#FF7F00','#6B399C','#B3591F');
  279. $gfx_color_compare = array('#A5CEE4','#B1E086','#FD9997','#FFC068','#CAB1D7','#D2A689');
  280. $i = 0;
  281. $data = array('chart_type' => 'line_chart_trends', 'date_format' => $this->context->language->date_format_lite, 'data' => array());
  282. foreach ($charts as $key => $title)
  283. {
  284. $data['data'][] = array(
  285. 'id' => $key,
  286. 'key' => $title,
  287. 'color' => $gfx_color[$i],
  288. 'values' => $chart_data[$key],
  289. 'disabled' => ($key == 'sales' ? false : true)
  290. );
  291. if ($this->dashboard_data_compare)
  292. $data['data'][] = array(
  293. 'id' => $key.'_compare',
  294. 'color' => $gfx_color_compare[$i],
  295. 'key' => sprintf($this->l('%s (previous period)'), $title),
  296. 'values' => $chart_data_compare[$key],
  297. 'disabled' => ($key == 'sales' ? false : true)
  298. );
  299. $i++;
  300. }
  301. return $data;
  302. }
  303. public function hookActionOrderStatusPostUpdate($params)
  304. {
  305. Tools::changeFileMTime($this->push_filename);
  306. }
  307. }