from = DateTime::createFromFormat(Settings::getDateFormat(), $from); $this->to = DateTime::createFromFormat(Settings::getDateFormat(), $to); } public function getGraph($json = true) { $chart = new Highchart(Highchart::HIGHCHART, -1); $chart->chart = [ 'type' => 'line', 'marginRight' => 130, 'marginBottom' => 25, ]; $chart->subtitle = [ 'x' => -20, ]; $chart->xAxis->categories = []; $chart->yAxis = [ 'plotLines' => [ [ 'value' => 0, 'width' => 1, 'color' => '#808080', ], ], ]; if ($this->type_graph == 'count_order') { $chart->chart['renderTo'] = 'count_orders'; $chart->yAxis['title']['text'] = translate('amount', 'stats'); $chart->title['text'] = translate('ordersAmount', 'stats'); $chart->series[0]['name'] = translate('ordersTotal', 'stats'); $chart->tooltip->formatter = new HighchartJsExpr( "function() { return ''+ this.series.name +'
'+ this.x +': '+ this.y;}"); } elseif ($this->type_graph == 'sales') { global $dbcfg; $chart->chart['renderTo'] = 'sales'; $chart->yAxis['title']['text'] = translate('orderValue', 'stats')."({$dbcfg->currency})"; $chart->title['text'] = translate('revenue', 'stats'); $chart->series[0]['name'] = translate('revenue', 'stats'); $chart->tooltip->formatter = new HighchartJsExpr( "function() { return ''+ this.series.name +'
'+ this.x +': '+ this.y.toString().replace(/\B(?=(\d{3})+(?!\d))/g, \" \") +' {$dbcfg->currency}';}"); } elseif ($this->type_graph == 'product') { $chart->chart['renderTo'] = 'product-graph'; $chart->yAxis['title']['text'] = translate('pcsSold', 'stats'); $chart->title['text'] = $this->getProductName(); $chart->series[0]['name'] = translate('pcsSold', 'stats'); $chart->tooltip->formatter = new HighchartJsExpr( "function() { return ''+ this.series.name +'
'+ this.x +': '+ this.y;}"); } $chart->title['x'] = -20; $chart->legend = [ 'layout' => 'vertical', 'align' => 'right', 'verticalAlign' => 'top', 'x' => -5, 'y' => 100, 'borderWidth' => 0, ]; switch ($this->interval) { case 'day': $chart->subtitle->text = translate('intervalDaily', 'stats'); $data = $this->getDaysData(); break; case 'month': $chart->subtitle->text = translate('intervalMonthly', 'stats'); $data = $this->getMonthsData(); break; case 'year': default: $chart->subtitle->text = translate('intervalYearly', 'stats'); $data = $this->getYearsData(); break; } $chart->series[0]['data'] = $data['data']; $chart->xAxis->categories = $data['x']; if ($json) { return $chart->renderOptions(); } else { return $chart; } } public function getProductName() { $id_product = getVal('id_product'); $id_variation = getVal('id_variation'); if (empty($id_product)) { return ''; } $join = ''; $fields = 'p.title as product_name'; if (!empty($id_variation)) { $fields .= ', pv.title as variation_name'; $join = 'LEFT JOIN '.getTableName('products_variations')." as pv ON pv.id={$id_variation} AND pv.id_product={$id_product}"; } $SQL = sqlQuery("SELECT {$fields} FROM ".getTableName('products')." AS p {$join} WHERE p.id={$id_product}"); $names = sqlFetchAssoc($SQL); if (!empty($names)) { $name = $names['product_name']; if (!empty($id_variation)) { $name .= " ({$names['variation_name']})"; } return $name; } else { return ''; } } public function countDays() { $d1 = $this->from; $d2 = $this->to; return $d1->diff($d2)->days + 1; } public function countMonths() { $d1 = $this->from; $d2 = $this->to; return ($d1->diff($d2)->m + ($d1->diff($d2)->y * 12)) + 1; } public function countYears() { $d1 = $this->from; $d2 = $this->to; return $d1->diff($d2)->y + 1; } public function getDaysData() { $DBData = $this->getDBData(); $startDay = $this->from->format('j'); $startMonth = $this->from->format('n'); $startYear = $this->from->format('Y'); $endDay = $this->from->format('j'); $endMonth = $this->to->format('n'); $endYear = $this->to->format('Y'); $countMonths = $this->countMonths(); $countDays = $this->countDays(); $x = []; $data = []; for ($year = 0; $year <= ($endYear - $startYear); $year++) { for ($month = $startMonth; $month <= 12; $month++) { $days = cal_days_in_month(CAL_GREGORIAN, $month, $startYear + $year); for ($day = $startDay; $day <= $days; $day++) { if ($countDays == 0) { break; } else { $countDays--; } $data[] = (!empty($DBData[$year][$month][$day])) ? round($DBData[$year][$month][$day], 2) : 0; $x[] = $day.'.'; } $startDay = 1; if ($countMonths == 0) { break; } else { $countMonths--; } } $startMonth = 1; } return ['x' => $x, 'data' => $data]; } public function getMonthsData() { $DBData = $this->getDBData(); $startMonth = $this->from->format('n'); $startYear = $this->from->format('Y'); $endMonth = $this->to->format('n'); $endYear = $this->to->format('Y'); $countMonths = $this->countMonths(); $x = []; $data = []; for ($year = 0; $year <= ($endYear - $startYear); $year++) { for ($month = $startMonth; $month <= 12; $month++) { if ($countMonths == 0) { break; } else { $countMonths--; } $data[] = (!empty($DBData[$year][$month])) ? round($DBData[$year][$month], 2) : 0; $x[] = translate($this->months[$month], 'timedate'); } $startMonth = 1; } return ['x' => $x, 'data' => $data]; } public function getYearsData() { $DBData = $this->getDBData(); $startYear = $this->from->format('Y'); $endYear = $this->to->format('Y'); $x = []; $data = []; for ($year = 0; $year <= $endYear - $startYear; $year++) { $data[] = (!empty($DBData[$year])) ? round($DBData[$year], 2) : 0; $x[] = $startYear + $year; } return ['x' => $x, 'data' => $data]; } public function getDBData() { if ($this->type_graph == 'sales') { $sum = (findModule('currencies')) ? ' * o.currency_rate' : ''; $sum = ' SUM(o.total_price'.$sum.') as sum'; } elseif ($this->type_graph == 'product') { $sum = ' SUM(oi.pieces) as sum'; } else { $sum = ' COUNT(*) as sum'; } $what = ''; $group = ''; $order = ''; switch ($this->interval) { case 'month': $what = 'MONTH(o.date_created) as month,'; $group = ', MONTH(o.date_created)'; $order = ',month'; break; case 'year': break; case 'day': default: $what = 'DAY(o.date_created) as day, MONTH(o.date_created) as month,'; $group = ', MONTH(o.date_created), DAY(o.date_created)'; $order = ',month,day'; break; } $format = 'Y-m-d'; if ($this->type_graph == 'product') { $id_product = getVal('id_product'); $id_variation = getVal('id_variation'); if (empty($id_product)) { exit; } $variation = ''; if (!empty($id_variation) && $id_variation != '-1') { $variation = " AND oi.id_variation={$id_variation}"; } $what = str_replace('date_created', 'date_handle', $what); $group = str_replace('date_created', 'date_handle', $group); $SQL = sqlQuery("SELECT {$what} (YEAR(o.date_handle)- YEAR('{$this->from->format($format)}')) as year,{$sum} FROM order_items AS oi LEFT JOIN orders as o ON o.id=oi.id_order WHERE oi.id_product={$id_product}{$variation} AND o.date_handle >='{$this->from->format($format)}' AND o.date_handle <= '{$this->to->format($format)}' GROUP BY YEAR(o.date_handle){$group} ORDER BY year{$order} ASC"); } else { $SQL = sqlQuery("SELECT {$what} (YEAR(o.date_created)- YEAR('{$this->from->format($format)} 00:00:00')) as year,{$sum} FROM orders AS o WHERE o.status_storno=0 AND o.date_created >='{$this->from->format($format)} 00:00:00' AND o.date_created <= '{$this->to->format($format)} 23:59:59' GROUP BY YEAR(o.date_created){$group} ORDER BY year{$order} ASC"); } $data = []; if ($this->interval == 'year') { foreach ($SQL as $row) { $data[$row['year']] = $row['sum']; } } elseif ($this->interval == 'month') { foreach ($SQL as $row) { $data[$row['year']][$row['month']] = $row['sum']; } } elseif ($this->interval == 'day') { foreach ($SQL as $row) { $data[$row['year']][$row['month']][$row['day']] = $row['sum']; } } return $data; } public function getProductsSelling($page = null, $limit = null) { $limit = (!is_null($page) && !is_null($limit)) ? "LIMIT {$page}, {$limit}" : ''; $sql_products = sqlQuery("SELECT p.id, p.title, SUM(oi.pieces) AS sold, p.price FROM products AS p, order_items AS oi LEFT JOIN orders AS o ON o.id=oi.id_order WHERE p.id = oi.id_product AND o.status_storno=0 AND o.date_handle >=:time_from AND o.date_handle <= :time_to GROUP BY oi.id_product ORDER BY sold DESC {$limit}", ['time_from' => $this->prepareDate($this->from).' 00:00:00', 'time_to' => $this->prepareDate($this->to).' 23:59:59']); $products = []; foreach ($sql_products as $product) { $product['variations'] = []; $sql_variations = sqlQuery('SELECT pv.id, pv.title, SUM(oi.pieces) AS sold, pvcv.value as variation_value, pvcl.label as variation_label, pv.price FROM products_variations AS pv LEFT JOIN order_items AS oi ON oi.id_product = pv.id_product AND oi.id_variation = pv.id LEFT JOIN orders AS o ON o.id=oi.id_order LEFT JOIN products_variations_combination pvc ON pvc.id_variation = pv.id LEFT JOIN products_variations_choices_values pvcv ON pvcv.id = pvc.id_value LEFT JOIN products_variations_choices_labels pvcl ON pvcl.id = pvc.id_label WHERE o.status_storno = 0 AND o.date_handle >=:time_from AND o.date_handle <= :time_to AND pv.id_product = :id_product GROUP BY oi.id_variation ORDER BY sold DESC ', ['time_from' => $this->prepareDate($this->from).' 00:00:00', 'time_to' => $this->prepareDate($this->to).' 23:59:59', 'id_product' => $product['id'], ]); foreach ($sql_variations as $variation) { $product['variations'][] = $variation; } $products[$product['id']] = $product; } return $products; } } if (empty($subclass)) { class StatsGraph extends StatsGraphBase { } }