Inital commit
This commit is contained in:
12
local/modules/MonthlyStats/Config/config.xml
Normal file
12
local/modules/MonthlyStats/Config/config.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<config xmlns="http://thelia.net/schema/dic/config"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
|
||||
|
||||
<hooks>
|
||||
<hook id="monthlystats.menutools.hook" class="MonthlyStats\Hook\HookManager" scope="request">
|
||||
<tag name="hook.event_listener" event="main.top-menu-tools" type="back" method="onMainTopMenuTools" />
|
||||
</hook>
|
||||
</hooks>
|
||||
</config>
|
||||
32
local/modules/MonthlyStats/Config/module.xml
Normal file
32
local/modules/MonthlyStats/Config/module.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module xmlns="http://thelia.net/schema/dic/module"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://thelia.net/schema/dic/module http://thelia.net/schema/dic/module/module-2_2.xsd">
|
||||
<fullnamespace>MonthlyStats\MonthlyStats</fullnamespace>
|
||||
<descriptive locale="en_US">
|
||||
<title>Monthly sales statistics</title>
|
||||
</descriptive>
|
||||
<descriptive locale="fr_FR">
|
||||
<title>Statistiques de vente mensuelles</title>
|
||||
</descriptive>
|
||||
<!-- <logo></logo> -->
|
||||
<!--<images-folder>images</images-folder>-->
|
||||
<languages>
|
||||
<language>en_US</language>
|
||||
<language>fr_FR</language>
|
||||
</languages>
|
||||
<version>0.5.1</version>
|
||||
<authors>
|
||||
<author>
|
||||
<name>Franck Allimant</name>
|
||||
<company>CQFDev</company>
|
||||
<email>thelia@cqfdev.fr</email>
|
||||
<website>www.cqfdev.fr</website>
|
||||
</author>
|
||||
</authors>
|
||||
<type>classic</type>
|
||||
<thelia>2.3.4</thelia>
|
||||
<stability>prod</stability>
|
||||
<mandatory>0</mandatory>
|
||||
<hidden>0</hidden>
|
||||
</module>
|
||||
14
local/modules/MonthlyStats/Config/routing.xml
Normal file
14
local/modules/MonthlyStats/Config/routing.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<routes xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||
|
||||
<route id="monthlystats.ca-par-rubrique" path="/admin/ca-par-rubrique">
|
||||
<default key="_controller">MonthlyStats\Controller\AdminCaController::caParRubrique</default>
|
||||
</route>
|
||||
|
||||
<route id="monthlystats.ca-mensuel" path="/admin/ca-mensuel">
|
||||
<default key="_controller">MonthlyStats\Controller\AdminCaController::caMensuel</default>
|
||||
</route>
|
||||
</routes>
|
||||
310
local/modules/MonthlyStats/Controller/AdminCaController.php
Normal file
310
local/modules/MonthlyStats/Controller/AdminCaController.php
Normal file
@@ -0,0 +1,310 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* Copyright (c) Franck Allimant, CQFDev */
|
||||
/* email : thelia@cqfdev.fr */
|
||||
/* web : http://www.cqfdev.fr */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
/**
|
||||
* Created by Franck Allimant, CQFDev <franck@cqfdev.fr>
|
||||
* Date: 24/01/2019 11:49
|
||||
*/
|
||||
namespace MonthlyStats\Controller;
|
||||
|
||||
use Propel\Runtime\ActiveQuery\Criteria;
|
||||
use Propel\Runtime\Connection\PdoConnection;
|
||||
use Propel\Runtime\Propel;
|
||||
use Thelia\Controller\Admin\BaseAdminController;
|
||||
use Thelia\Model\Category;
|
||||
use Thelia\Model\CategoryQuery;
|
||||
use Thelia\Model\Map\CategoryTableMap;
|
||||
use Thelia\Model\Map\OrderProductTableMap;
|
||||
use Thelia\Model\Map\OrderProductTaxTableMap;
|
||||
use Thelia\Model\Map\OrderTableMap;
|
||||
use Thelia\Model\Map\ProductCategoryTableMap;
|
||||
use Thelia\Model\Map\ProductTableMap;
|
||||
use Thelia\Model\OrderQuery;
|
||||
use Thelia\Model\OrderStatusQuery;
|
||||
|
||||
class AdminCaController extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* @return \Thelia\Core\HttpFoundation\Response
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function caParRubrique()
|
||||
{
|
||||
$moisDebut = $this->getRequest()->get('mois_debut');
|
||||
$moisFin = $this->getRequest()->get('mois_fin');
|
||||
|
||||
$anneeDebut = $this->getRequest()->get('annee_debut');
|
||||
$anneeFin = $this->getRequest()->get('annee_fin');
|
||||
|
||||
$dateDebut = new \DateTime(sprintf("%04d-%02d-01 00:00:00", $anneeDebut, $moisDebut));
|
||||
$dateFin = new \DateTime(sprintf("%04d-%02d-31 23:59:59", $anneeFin, $moisFin));
|
||||
|
||||
/** @var PdoConnection $con */
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$query = "
|
||||
SELECT
|
||||
SUM(".OrderProductTableMap::QUANTITY." * IF(".OrderProductTableMap::WAS_IN_PROMO.",".OrderProductTableMap::PROMO_PRICE.",".OrderProductTableMap::PRICE.")) as total_ht,
|
||||
SUM(".OrderProductTableMap::QUANTITY." * IF(".OrderProductTableMap::WAS_IN_PROMO.",".OrderProductTaxTableMap::PROMO_AMOUNT.",".OrderProductTaxTableMap::AMOUNT.")) as total_tva,
|
||||
".ProductCategoryTableMap::CATEGORY_ID." as cat_id,
|
||||
".CategoryTableMap::PARENT." as cat_parent
|
||||
FROM
|
||||
".OrderProductTableMap::TABLE_NAME."
|
||||
LEFT JOIN
|
||||
".OrderTableMap::TABLE_NAME." on ".OrderTableMap::ID." = ".OrderProductTableMap::ORDER_ID."
|
||||
LEFT JOIN
|
||||
".ProductTableMap::TABLE_NAME." on ".ProductTableMap::REF." = ".OrderProductTableMap::PRODUCT_REF."
|
||||
LEFT JOIN
|
||||
".OrderProductTaxTableMap::TABLE_NAME." on ".OrderProductTaxTableMap::ORDER_PRODUCT_ID." = ".OrderProductTableMap::ID."
|
||||
LEFT JOIN
|
||||
".ProductCategoryTableMap::TABLE_NAME." on ".ProductCategoryTableMap::PRODUCT_ID." = ".ProductTableMap::ID." and ".ProductCategoryTableMap::DEFAULT_CATEGORY." = 1
|
||||
LEFT JOIN
|
||||
".CategoryTableMap::TABLE_NAME." on ".CategoryTableMap::ID." = ".ProductCategoryTableMap::CATEGORY_ID."
|
||||
WHERE
|
||||
".OrderTableMap::INVOICE_DATE." >= ?
|
||||
AND
|
||||
".OrderTableMap::INVOICE_DATE." <= ?
|
||||
AND
|
||||
".OrderTableMap::STATUS_ID." not in (?, ?)
|
||||
GROUP BY
|
||||
".ProductCategoryTableMap::CATEGORY_ID."
|
||||
ORDER BY
|
||||
total_ht desc
|
||||
";
|
||||
|
||||
$query = preg_replace("/order([^_])/", "`order`$1", $query);
|
||||
|
||||
$stmt = $con->prepare($query);
|
||||
|
||||
$res = $stmt->execute([
|
||||
$dateDebut->format("Y-m-d H:i:s"),
|
||||
$dateFin->format("Y-m-d H:i:s"),
|
||||
OrderStatusQuery::getNotPaidStatus()->getId(),
|
||||
OrderStatusQuery::getCancelledStatus()->getId()
|
||||
]);
|
||||
|
||||
$catData = $topLevelData = [];
|
||||
|
||||
while ($res && $result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$catDatatId = intval($result['cat_id']);
|
||||
|
||||
if ($catDatatId > 0) {
|
||||
$tree = CategoryQuery::getPathToCategory($catDatatId);
|
||||
|
||||
$label = '';
|
||||
$locale = $this->getSession()->getLang()->getLocale();
|
||||
|
||||
/** @var Category $cat */
|
||||
foreach ($tree as $cat) {
|
||||
$title = $cat->setLocale($locale)->getTitle();
|
||||
|
||||
$label .= $title . " > ";
|
||||
|
||||
if ($cat->getParent() === 0) {
|
||||
$this->addOrder($title, $result, $topLevelData);
|
||||
}
|
||||
}
|
||||
|
||||
$label = substr($label, 0, -6);
|
||||
} else {
|
||||
$label = "Catégorie inexistante (probablement supprimée)";
|
||||
|
||||
$this->addOrder($label, $result, $topLevelData);
|
||||
}
|
||||
|
||||
$catData[] = [
|
||||
'total_ht' => $result['total_ht'],
|
||||
'total_tva' => $result['total_tva'],
|
||||
'total_ttc' => $result['total_ht'] + $result['total_tva'],
|
||||
'cat_label' => $label
|
||||
];
|
||||
}
|
||||
|
||||
//var_dump($topLevelData);
|
||||
|
||||
return $this->render("ca-par-rubrique", [
|
||||
'catData' => $catData,
|
||||
'topLevelData' => $topLevelData,
|
||||
'mois_debut' => $dateDebut->format("n"),
|
||||
'mois_fin' => $dateDebut->format("n"),
|
||||
'annee_debut' => $dateDebut->format("Y"),
|
||||
'annee_fin' => $dateDebut->format("Y"),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param \DateTime $dateDebut
|
||||
* @param \DateTime $dateFin
|
||||
* @return \PDOStatement|null
|
||||
*/
|
||||
protected function executeOrderRequest($query, \DateTime $dateDebut, \DateTime $dateFin)
|
||||
{
|
||||
/** @var PdoConnection $con */
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$query = preg_replace("/order([^_])/", "`order`$1", $query);
|
||||
|
||||
$stmt = $con->prepare($query);
|
||||
|
||||
$res = $stmt->execute([
|
||||
$dateDebut->format("Y-m-d H:i:s"),
|
||||
$dateFin->format("Y-m-d H:i:s")
|
||||
]);
|
||||
|
||||
return $res ? $stmt : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Thelia\Core\HttpFoundation\Response
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function caMensuel()
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$firstPaidOrder = OrderQuery::create()
|
||||
->orderByInvoiceDate(Criteria::ASC)
|
||||
->filterByStatusId(OrderStatusQuery::getPaidStatusIdList(), Criteria::IN)
|
||||
->findOne();
|
||||
|
||||
if (null !== $firstPaidOrder) {
|
||||
$anneeDebut = $this->getRequest()->get('annee_debut', $firstPaidOrder->getInvoiceDate('Y'));
|
||||
$anneeFin = $this->getRequest()->get('annee_fin', date('Y'));
|
||||
|
||||
$dateDebut = new \DateTime(sprintf("%04d-01-01 00:00:00", $anneeDebut));
|
||||
$dateFin = new \DateTime(sprintf("%04d-12-31 23:59:59", $anneeFin));
|
||||
|
||||
// Get monthly discount total
|
||||
$query = "
|
||||
SELECT
|
||||
SUM(" . OrderTableMap::DISCOUNT.") as discount,
|
||||
SUM(" . OrderTableMap::POSTAGE.") as postage,
|
||||
SUM(" . OrderTableMap::POSTAGE_TAX.") as postage_tax,
|
||||
" . OrderTableMap::CREATED_AT . " as invoice_date,
|
||||
MONTH(" . OrderTableMap::INVOICE_DATE . ") as mois,
|
||||
YEAR(" . OrderTableMap::INVOICE_DATE . ") as annee
|
||||
FROM
|
||||
" . OrderTableMap::TABLE_NAME . "
|
||||
WHERE
|
||||
" . OrderTableMap::INVOICE_DATE . " >= ?
|
||||
AND
|
||||
" . OrderTableMap::INVOICE_DATE . " <= ?
|
||||
AND
|
||||
" . OrderTableMap::STATUS_ID . " in (".implode(',', OrderStatusQuery::getPaidStatusIdList()).")
|
||||
GROUP BY
|
||||
annee, mois
|
||||
ORDER BY
|
||||
invoice_date desc
|
||||
";
|
||||
|
||||
$orderData = [];
|
||||
|
||||
$stmt = $this->executeOrderRequest($query, $dateDebut, $dateFin);
|
||||
|
||||
while ($stmt !== null && $result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$year = $result['annee'];
|
||||
$month = $result['mois'];
|
||||
|
||||
if (!isset($orderData[$year])) {
|
||||
$orderData[$year] = [];
|
||||
}
|
||||
|
||||
$orderData[$year][$month] = [
|
||||
'discount' => $result['discount'],
|
||||
'postage' => $result['postage'],
|
||||
'postage_tax' => $result['postage_tax']
|
||||
];
|
||||
}
|
||||
|
||||
// Get monthly sales and taxes
|
||||
$query = "
|
||||
SELECT
|
||||
SUM(" . OrderProductTableMap::QUANTITY . " * IF(" . OrderProductTableMap::WAS_IN_PROMO . "," . OrderProductTableMap::PROMO_PRICE . "," . OrderProductTableMap::PRICE . ")) as total_ht,
|
||||
SUM(" . OrderProductTableMap::QUANTITY . " * IF(" . OrderProductTableMap::WAS_IN_PROMO . "," . OrderProductTaxTableMap::PROMO_AMOUNT . "," . OrderProductTaxTableMap::AMOUNT . ")) as total_tva,
|
||||
" . OrderTableMap::INVOICE_DATE . " as invoice_date,
|
||||
MONTH(" . OrderTableMap::INVOICE_DATE . ") as mois,
|
||||
YEAR(" . OrderTableMap::INVOICE_DATE . ") as annee
|
||||
FROM
|
||||
" . OrderProductTableMap::TABLE_NAME . "
|
||||
LEFT JOIN
|
||||
" . OrderTableMap::TABLE_NAME . " on " . OrderTableMap::ID . " = " . OrderProductTableMap::ORDER_ID . "
|
||||
LEFT JOIN
|
||||
" . ProductTableMap::TABLE_NAME . " on " . ProductTableMap::REF . " = " . OrderProductTableMap::PRODUCT_REF . "
|
||||
LEFT JOIN
|
||||
" . OrderProductTaxTableMap::TABLE_NAME . " on " . OrderProductTaxTableMap::ORDER_PRODUCT_ID . " = " . OrderProductTableMap::ID . "
|
||||
LEFT JOIN
|
||||
" . ProductCategoryTableMap::TABLE_NAME . " on " . ProductCategoryTableMap::PRODUCT_ID . " = " . ProductTableMap::ID . " and " . ProductCategoryTableMap::DEFAULT_CATEGORY . " = 1
|
||||
WHERE
|
||||
" . OrderTableMap::INVOICE_DATE . " >= ?
|
||||
AND
|
||||
" . OrderTableMap::INVOICE_DATE . " <= ?
|
||||
AND
|
||||
" . OrderTableMap::STATUS_ID . " in (".implode(',', OrderStatusQuery::getPaidStatusIdList()).")
|
||||
GROUP BY
|
||||
annee, mois
|
||||
ORDER BY
|
||||
invoice_date desc
|
||||
";
|
||||
|
||||
$stmt = $this->executeOrderRequest($query, $dateDebut, $dateFin);
|
||||
|
||||
while ($stmt !== null && $result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$year = $result['annee'];
|
||||
$month = $result['mois'];
|
||||
|
||||
if (!isset($data[$year])) {
|
||||
$data[$year] = [];
|
||||
}
|
||||
|
||||
$totalHt = $result['total_ht'];
|
||||
|
||||
if (isset($orderData[$year][$month])) {
|
||||
$totalHt -= $orderData[$year][$month]['discount'];
|
||||
$postage = $orderData[$year][$month]['postage'];
|
||||
$postageTax = $orderData[$year][$month]['postage_tax'];
|
||||
} else {
|
||||
$postage = $postageTax = 0;
|
||||
}
|
||||
|
||||
$data[$year][$month] = [
|
||||
'total_ht' => $totalHt,
|
||||
'total_tva' => $result['total_tva'],
|
||||
'total_ttc' => $totalHt + $result['total_tva'],
|
||||
'postage' => $postage,
|
||||
'postage_tax' => $postageTax
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$anneeDebut = date('Y');
|
||||
}
|
||||
|
||||
return $this->render("ca-mensuel", [
|
||||
'data' => $data,
|
||||
'annee_debut' => $anneeDebut,
|
||||
'annee_fin' => $anneeFin
|
||||
]);
|
||||
}
|
||||
|
||||
protected function addOrder($label, $result, &$topLevelData)
|
||||
{
|
||||
if (!isset($topLevelData[$label])) {
|
||||
$topLevelData[$label] = [
|
||||
'total_ht' => 0,
|
||||
'total_tva' => 0,
|
||||
'total_ttc' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$topLevelData[$label]['total_ht'] += $result['total_ht'];
|
||||
$topLevelData[$label]['total_tva'] += $result['total_tva'];
|
||||
$topLevelData[$label]['total_ttc'] += $result['total_ht'] + $result['total_tva'];
|
||||
}
|
||||
}
|
||||
48
local/modules/MonthlyStats/Hook/HookManager.php
Normal file
48
local/modules/MonthlyStats/Hook/HookManager.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* Copyright (c) Franck Allimant, CQFDev */
|
||||
/* email : thelia@cqfdev.fr */
|
||||
/* web : http://www.cqfdev.fr */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
/**
|
||||
* Created by Franck Allimant, CQFDev <franck@cqfdev.fr>
|
||||
* Date: 24/01/2019 11:47
|
||||
*/
|
||||
|
||||
namespace MonthlyStats\Hook;
|
||||
|
||||
use Thelia\Core\Event\Hook\HookRenderBlockEvent;
|
||||
use Thelia\Core\Hook\BaseHook;
|
||||
use Thelia\Tools\URL;
|
||||
|
||||
class HookManager extends BaseHook
|
||||
{
|
||||
public function onMainTopMenuTools(HookRenderBlockEvent $event)
|
||||
{
|
||||
$event->add(
|
||||
[
|
||||
'id' => 'tools_menu_ca_mensuel',
|
||||
'class' => '',
|
||||
'url' => URL::getInstance()->absoluteUrl('/admin/ca-mensuel'),
|
||||
'title' => "C.A. Mensuel"
|
||||
])
|
||||
->add(
|
||||
[
|
||||
'id' => 'tools_menu_ca_par_rubrique',
|
||||
'class' => '',
|
||||
'url' => URL::getInstance()->absoluteUrl('/admin/ca-par-rubrique', [
|
||||
'mois_debut' => date('m'),
|
||||
'mois_fin' => date('m'),
|
||||
'annee_debut' => date('Y'),
|
||||
'annee_fin' => date('Y')
|
||||
|
||||
]),
|
||||
'title' => "C.A. par catégorie"
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
4
local/modules/MonthlyStats/I18n/en_US.php
Normal file
4
local/modules/MonthlyStats/I18n/en_US.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
return array(
|
||||
// 'an english string' => 'The displayed english string',
|
||||
);
|
||||
4
local/modules/MonthlyStats/I18n/fr_FR.php
Normal file
4
local/modules/MonthlyStats/I18n/fr_FR.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
return array(
|
||||
// 'an english string' => 'La traduction française de la chaine',
|
||||
);
|
||||
28
local/modules/MonthlyStats/MonthlyStats.php
Normal file
28
local/modules/MonthlyStats/MonthlyStats.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace MonthlyStats;
|
||||
|
||||
use Thelia\Module\BaseModule;
|
||||
|
||||
class MonthlyStats extends BaseModule
|
||||
{
|
||||
/** @var string */
|
||||
const DOMAIN_NAME = 'monthlystats';
|
||||
|
||||
/*
|
||||
* You may now override BaseModuleInterface methods, such as:
|
||||
* install, destroy, preActivation, postActivation, preDeactivation, postDeactivation
|
||||
*
|
||||
* Have fun !
|
||||
*/
|
||||
}
|
||||
16
local/modules/MonthlyStats/Readme.md
Normal file
16
local/modules/MonthlyStats/Readme.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Monthly Stats
|
||||
|
||||
Ce module permer d'afficher les statistiques mensuelles de vente depuis la
|
||||
première vente sur le site, ainsi que les statistiques de vente par catégorie
|
||||
entre deux dates.
|
||||
|
||||
Les statistiques sont accessibles depuis le menu Outils :
|
||||
|
||||
- C.A. Mensuel
|
||||
- C.A. par catégorie
|
||||
|
||||
## TODO :
|
||||
|
||||
- étoffer ce README
|
||||
- Mettre en place les traductions
|
||||
|
||||
11
local/modules/MonthlyStats/composer.json
Normal file
11
local/modules/MonthlyStats/composer.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "cqfdev/monthlystats",
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"type": "thelia-module",
|
||||
"require": {
|
||||
"thelia/installer": "~1.1"
|
||||
},
|
||||
"extra": {
|
||||
"installer-name": "MonthlyStats"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
{extends file="admin-layout.tpl"}
|
||||
|
||||
{block name="no-return-functions"}
|
||||
{$admin_current_location = 'tools'}
|
||||
|
||||
{loop name="currency" type="currency" default_only=1}
|
||||
{$currency=$SYMBOL}
|
||||
{/loop}
|
||||
{/block}
|
||||
|
||||
{block name="page-title"}{intl d='monthlystats.bo.default' l='Statistiques mensuelles de Chiffre d\'Affaire'}{/block}
|
||||
|
||||
{block name="check-resource"}admin.order{/block}
|
||||
{block name="check-access"}view{/block}
|
||||
|
||||
{block name="main-content"}
|
||||
{$graphData = ''}
|
||||
|
||||
<div id="wrapper" class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="general-block-decorator">
|
||||
<div class="jqplot-content" style="margin-bottom: 20px">
|
||||
<div id="jqplot"></div>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{intl d='monthlystats.bo.default' l="Mois"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total HT"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total TVA"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total TTC"}</th>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="Total port TTC"}</th>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="Total TVA port"}</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{$total_ht = 0}
|
||||
{$total_ttc = 0}
|
||||
{$total_tva = 0}
|
||||
{$total_postage = 0}
|
||||
{$total_postage_tax = 0}
|
||||
{$virg = ''}
|
||||
|
||||
{foreach $data as $annee => $monthData}
|
||||
<tr class="info">
|
||||
<th colspan="99">
|
||||
Année {$annee}
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="text-center">{intl d='monthlystats.bo.default' l="Mois"}</th>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="CA HT"}</th>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="TVA"}</th>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="CA TTC"}</th>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="Port TTC"}</th>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="TVA port"}</th>
|
||||
</tr>
|
||||
|
||||
{$total_ht_an = 0}
|
||||
{$total_ttc_an = 0}
|
||||
{$total_tva_an = 0}
|
||||
{$total_postage_an = 0}
|
||||
{$total_postage_tax_an = 0}
|
||||
|
||||
{foreach $monthData as $mois => $value}
|
||||
{$strMois = $mois|string_format:"%02d"}
|
||||
|
||||
<tr>
|
||||
<td class="text-center">{$strMois}/{$annee|string_format:"%04d"}</td>
|
||||
<td class="text-right">{format_money number=$value.total_ht symbol=$currency}</td>
|
||||
<td class="text-right">{format_money number=$value.total_tva symbol=$currency}</td>
|
||||
<td class="text-right">{format_money number=$value.total_ttc symbol=$currency}</td>
|
||||
<td class="text-right">{format_money number=$value.postage symbol=$currency}</td>
|
||||
<td class="text-right">{format_money number=$value.postage_tax symbol=$currency}</td>
|
||||
</tr>
|
||||
|
||||
{$total_ht_an = $total_ht_an + $value.total_ht}
|
||||
{$total_ttc_an = $total_ttc_an + $value.total_ttc}
|
||||
{$total_tva_an = $total_tva_an + $value.total_tva}
|
||||
{$total_postage_an = $total_postage_an + $value.postage}
|
||||
{$total_postage_tax_an = $total_postage_tax_an + $value.postage_tax}
|
||||
|
||||
{$total_ht = $total_ht + $value.total_ht}
|
||||
{$total_ttc = $total_ttc + $value.total_ttc}
|
||||
{$total_tva = $total_tva + $value.total_tva}
|
||||
{$total_postage = $total_postage + $value.postage}
|
||||
{$total_postage_tax = $total_postage_tax + $value.postage_tax}
|
||||
|
||||
{$graphData = "[ '$annee-$strMois-01', {$value.total_ht|round:2} ]$virg$graphData"}
|
||||
{$virg = ','}
|
||||
{/foreach}
|
||||
|
||||
<tr>
|
||||
<th class="text-center">{intl d='monthlystats.bo.default' l="TOTAL %total" total=$annee}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_ht_an}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_tva_an}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_ttc_an}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_postage_an}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_postage_tax_an}</th>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
{if empty($data)}
|
||||
<tr>
|
||||
<td colspan="99">
|
||||
<div class="alert alert-info">{intl d='monthlystats.bo.default' l="Aucune commande pour cette période"}</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
|
||||
<tr class="success">
|
||||
<th class="text-center">{intl d='monthlystats.bo.default' l="TOTAL GENERAL"}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_ht}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_tva}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_ttc}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_postage}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_postage_tax}</th>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/block}
|
||||
|
||||
{block name="javascript-initialization"}
|
||||
<script src="{javascript file='assets/js/jqplot/jquery.jqplot.min.js'}"></script>
|
||||
<script src="{javascript file='assets/js/jqplot/plugins/jqplot.highlighter.min.js'}"></script>
|
||||
<script src="{javascript file='assets/js/jqplot/plugins/jqplot.pointLabels.min.js'}"></script>
|
||||
<script src="{javascript file='assets/js/jqplot/plugins/jqplot.dateAxisRenderer.min.js'}"></script>
|
||||
<script src="{javascript file='assets/js/jqplot/plugins/jqplot.canvasTextRenderer.min.js'}"></script>
|
||||
<script src="{javascript file='assets/js/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js'}"></script>
|
||||
<script src="{javascript file='assets/js/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js'}"></script>
|
||||
<script src="{javascript file='assets/js/jqplot/plugins/jqplot.canvasOverlay.min.js'}"></script>
|
||||
|
||||
<script>
|
||||
var graphData = [ {$graphData nofilter} ];
|
||||
|
||||
$.jqplot.config.enablePlugins = true;
|
||||
|
||||
var jQPlotsOptions = {
|
||||
animate: false,
|
||||
axesDefaults: {
|
||||
tickOptions: {
|
||||
showMark: true,
|
||||
showGridline: true,
|
||||
}
|
||||
},
|
||||
seriesDefaults: {
|
||||
pointLabels: { show:false },
|
||||
lineWidth: 2,
|
||||
shadow: false,
|
||||
markerOptions: {
|
||||
shadow: false,
|
||||
style: 'filledCircle',
|
||||
size: 6
|
||||
}
|
||||
},
|
||||
seriesColors: ['orange'],
|
||||
axes: {
|
||||
xaxis: {
|
||||
renderer:$.jqplot.DateAxisRenderer,
|
||||
rendererOptions:{
|
||||
tickRenderer:$.jqplot.CanvasAxisTickRenderer
|
||||
},
|
||||
borderColor: '#ccc',
|
||||
ticks: [],
|
||||
tickInterval:'6 month',
|
||||
tickOptions: {
|
||||
showGridline: true,
|
||||
formatString: '%m/%Y',
|
||||
angle:-40
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
min: 0,
|
||||
tickOptions: {
|
||||
showGridline: true,
|
||||
showMark: false,
|
||||
showLabel: true,
|
||||
shadow: false
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
background: '#FFF',
|
||||
shadow: false,
|
||||
borderColor: '#FFF'
|
||||
},
|
||||
highlighter: {
|
||||
show: true,
|
||||
sizeAdjust: 7,
|
||||
tooltipLocation: 'n',
|
||||
tooltipContentEditor: function (str, seriesIndex, pointIndex, plot) {
|
||||
var date = new Date(plot.data[seriesIndex][pointIndex][0]);
|
||||
|
||||
return $.jqplot.sprintf(
|
||||
"%d/%d - %.2f {currency attr="symbol"}",
|
||||
1 + date.getMonth(),
|
||||
date.getFullYear(),
|
||||
plot.data[seriesIndex][pointIndex][1]
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$(function() {
|
||||
jQPlotInstance = $.jqplot(
|
||||
"jqplot",
|
||||
[ graphData ],
|
||||
jQPlotsOptions
|
||||
);
|
||||
|
||||
$(window).bind('resize', function (event, ui) {
|
||||
jQPlotInstance.replot({
|
||||
resetAxes: true
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{$total_ht|print_r}
|
||||
{/block}
|
||||
@@ -0,0 +1,173 @@
|
||||
lo{extends file="admin-layout.tpl"}
|
||||
|
||||
{block name="no-return-functions"}
|
||||
{$admin_current_location = 'tools'}
|
||||
|
||||
{loop name="currency" type="currency" default_only=1}
|
||||
{$currency=$SYMBOL}
|
||||
{/loop}
|
||||
{/block}
|
||||
|
||||
{block name="page-title"}{intl d='monthlystats.bo.default' l='Chiffre d\'affaire par catégorie'}{/block}
|
||||
|
||||
{block name="check-resource"}admin.order{/block}
|
||||
{block name="check-access"}view{/block}
|
||||
|
||||
{block name="main-content"}
|
||||
|
||||
{$mois = [ "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre" ]}
|
||||
|
||||
{$annee = $smarty.now|date_format:"%Y"}
|
||||
|
||||
<div id="wrapper" class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="general-block-decorator">
|
||||
<form class="form-inline" action="{url path="/admin/ca-par-rubrique"}" method="POST">
|
||||
<div class="form-group">
|
||||
<label>{intl d='monthlystats.bo.default' l='Visualiser de : '}</label>
|
||||
<select name="mois_debut" class="form-control">
|
||||
{for $idx = 0; $idx < 12; $idx++}
|
||||
<option value="{$idx+1}"{if $mois_debut == $idx+1} selected{/if}>{$mois[$idx]}</option>
|
||||
{/for}
|
||||
</select>
|
||||
<select name="annee_debut" class="form-control">
|
||||
{for $idx = 2009; $idx <= $annee; $idx++}
|
||||
<option value="{$idx}"{if $annee_debut == $idx} selected{/if}>{$idx}</option>
|
||||
{/for}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{intl d='monthlystats.bo.default' l='à : '}</label>
|
||||
<select name="mois_fin" class="form-control">
|
||||
{for $idx = 0; $idx < 12; $idx++}
|
||||
<option value="{$idx+1}"{if $mois_fin == $idx+1} selected{/if}>{$mois[$idx]}</option>
|
||||
{/for}
|
||||
</select>
|
||||
<select name="annee_fin" class="form-control">
|
||||
{for $idx = 2009; $idx <= $annee; $idx++}
|
||||
<option value="{$idx}"{if $annee_fin == $idx} selected{/if}>{$idx}</option>
|
||||
{/for}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">{intl d='monthlystats.bo.default' l='OK'}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="general-block-decorator">
|
||||
<div class="row">
|
||||
<div class="col-md-12 title title-without-tabs">
|
||||
{intl d='monthlystats.bo.default' l="TOTAL PAR CATÉGORIE"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{$total_ht = 0}
|
||||
{$total_ttc = 0}
|
||||
{$total_tva = 0}
|
||||
|
||||
<table class="table table-bordered table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{intl d='monthlystats.bo.default' l="Categorie"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total HT"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total TVA"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total TTC"}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $catData as $data}
|
||||
{$total_ht = $total_ht + $data.total_ht}
|
||||
{$total_ttc = $total_ttc + $data.total_ttc}
|
||||
{$total_tva = $total_tva + $data.total_tva}
|
||||
<tr>
|
||||
<td>{$data.cat_label nofilter}</td>
|
||||
<td class="text-right text-nowrap">{format_money number=$data.total_ht}</td>
|
||||
<td class="text-right text-nowrap">{format_money number=$data.total_tva}</td>
|
||||
<td class="text-right text-nowrap">{format_money number=$data.total_ttc}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
{if empty($catData)}
|
||||
<tr>
|
||||
<td colspan="99">
|
||||
<div class="alert alert-info">Aucune commande pour cette période</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="Total"}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_ht}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_tva}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_ttc}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="general-block-decorator">
|
||||
<div class="row">
|
||||
<div class="col-md-12 title title-without-tabs">
|
||||
{intl d='monthlystats.bo.default' l="TOTAL PAR GRANDE CATÉGORIE"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{intl d='monthlystats.bo.default' l="Categorie"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total HT"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total TVA"}</th>
|
||||
<th class="text-right text-nowrap">{intl d='monthlystats.bo.default' l="Total TTC"}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{$total_ht = 0}
|
||||
{$total_ttc = 0}
|
||||
{$total_tva = 0}
|
||||
|
||||
{foreach $topLevelData as $label => $data}
|
||||
{$total_ht = $total_ht + $data.total_ht}
|
||||
{$total_ttc = $total_ttc + $data.total_ttc}
|
||||
{$total_tva = $total_tva + $data.total_tva}
|
||||
<tr>
|
||||
<td>{$label nofilter}</td>
|
||||
<td class="text-right text-nowrap">{format_money number=$data.total_ht}</td>
|
||||
<td class="text-right text-nowrap">{format_money number=$data.total_tva}</td>
|
||||
<td class="text-right text-nowrap">{format_money number=$data.total_ttc}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
{if empty($topLevelData)}
|
||||
<tr>
|
||||
<td colspan="99">
|
||||
<div class="alert alert-info">{intl d='monthlystats.bo.default' l='Aucune commande pour cette période'}</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th class="text-right">{intl d='monthlystats.bo.default' l="Total"}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_ht}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_tva}</th>
|
||||
<th class="text-right text-nowrap">{format_money number=$total_ttc}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
Reference in New Issue
Block a user