From 083dde5e930cd5a7c7413841f932ef00358571be Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 30 Oct 2013 16:32:24 +0100 Subject: [PATCH 1/5] admin home stats --- .../Thelia/Config/Resources/routing/admin.xml | 12 +++ .../Controller/Admin/HomeController.php | 102 ++++++++++++++++++ core/lib/Thelia/Model/CustomerQuery.php | 17 +++ core/lib/Thelia/Model/OrderQuery.php | 68 ++++++++++++ templates/admin/default/home.html | 20 ++-- 5 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 core/lib/Thelia/Controller/Admin/HomeController.php diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 046395fa9..e051fb3e5 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -9,6 +9,18 @@ Thelia\Controller\Admin\AdminController::indexAction + + + + Thelia\Controller\Admin\HomeController::defaultAction + + + + Thelia\Controller\Admin\HomeController::loadStatsAjaxAction + + + + Thelia\Controller\Admin\SessionController::showLoginAction diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php new file mode 100644 index 000000000..90b0c6655 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -0,0 +1,102 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Security\AccessManager; +use Thelia\Model\CustomerQuery; +use Thelia\Model\OrderQuery; + +class HomeController extends BaseAdminController +{ + const RESOURCE_CODE = "admin.home"; + + public function defaultAction() + { + if (null !== $response = $this->checkAuth(self::RESOURCE_CODE, AccessManager::VIEW)) return $response; + + // Render the edition template. + return $this->render('home'); + } + + public function loadStatsAjaxAction() + { + $data = new \stdClass(); + + $data->title = "Stats on [...]"; + + /* sales */ + $saleSeries = new \stdClass(); + $saleSeries->color = $this->getRequest()->request->get('sales_color', '#adadad'); + $saleSeries->data = OrderQuery::getSaleStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* new customers */ + $newCustomerSeries = new \stdClass(); + $newCustomerSeries->color = $this->getRequest()->request->get('customers_color', '#f39922'); + $newCustomerSeries->data = CustomerQuery::getNewCustomersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* orders */ + $orderSeries = new \stdClass(); + $orderSeries->color = $this->getRequest()->request->get('orders_color', '#5cb85c'); + $orderSeries->data = OrderQuery::getOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* first order */ + $firstOrderSeries = new \stdClass(); + $firstOrderSeries->color = $this->getRequest()->request->get('first_orders_color', '#5bc0de'); + $firstOrderSeries->data = OrderQuery::getFirstOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* cancelled orders */ + $cancelledOrderSeries = new \stdClass(); + $cancelledOrderSeries->color = $this->getRequest()->request->get('cancelled_orders_color', '#d9534f'); + $cancelledOrderSeries->data = OrderQuery::getOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')), + array(5) + ); + + + $data->series = array( + $saleSeries, + $newCustomerSeries, + $orderSeries, + $firstOrderSeries, + $cancelledOrderSeries, + ); + + $json = json_encode($data); + + return $this->jsonResponse($json); + } +} diff --git a/core/lib/Thelia/Model/CustomerQuery.php b/core/lib/Thelia/Model/CustomerQuery.php index 359d072bd..5c225510b 100755 --- a/core/lib/Thelia/Model/CustomerQuery.php +++ b/core/lib/Thelia/Model/CustomerQuery.php @@ -2,6 +2,7 @@ namespace Thelia\Model; +use Propel\Runtime\ActiveQuery\Criteria; use Thelia\Model\Base\CustomerQuery as BaseCustomerQuery; @@ -21,4 +22,20 @@ class CustomerQuery extends BaseCustomerQuery { { return self::create()->findOneByEmail($email); } + + public static function getNewCustomersStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayCustomers = self::create() + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL) + ->count(); + $stats[] = array($day-1, $dayCustomers); + } + + return $stats; + } } // CustomerQuery diff --git a/core/lib/Thelia/Model/OrderQuery.php b/core/lib/Thelia/Model/OrderQuery.php index 0fff5dba1..6eee6a81b 100755 --- a/core/lib/Thelia/Model/OrderQuery.php +++ b/core/lib/Thelia/Model/OrderQuery.php @@ -3,6 +3,7 @@ namespace Thelia\Model; use Propel\Runtime\ActiveQuery\Criteria; +use Propel\Runtime\ActiveQuery\Join; use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Propel; use Thelia\Model\Base\OrderQuery as BaseOrderQuery; @@ -54,4 +55,71 @@ class OrderQuery extends BaseOrderQuery return $obj; } + public static function getSaleStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayAmount = 0; + foreach(self::create() + ->filterByStatusId(array(2,3,4), Criteria::IN) + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL) + ->find() as $dayOrders) { + $dayAmount += $dayOrders->getTotalAmount(); + } + $stats[] = array($day-1, $dayAmount); + } + + return $stats; + } + + public static function getOrdersStats($month, $year, $status = null) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayOrdersQuery = self::create() + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL); + if(null !== $status) { + $dayOrdersQuery->filterByStatusId($status, Criteria::IN); + } + $dayOrders = $dayOrdersQuery->count(); + $stats[] = array($day-1, $dayOrders); + } + + return $stats; + } + + public static function getFirstOrdersStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayOrdersQuery = self::create('matching_order') + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL); + + $otherOrderJoin = new Join(); + $otherOrderJoin->addExplicitCondition(OrderTableMap::TABLE_NAME, 'CUSTOMER_ID', 'matching_order', OrderTableMap::TABLE_NAME, 'CUSTOMER_ID', 'other_order'); + $otherOrderJoin->setJoinType(Criteria::LEFT_JOIN); + + $dayOrdersQuery->addJoinObject($otherOrderJoin, 'other_order_join') + ->addJoinCondition('other_order_join', '`matching_order`.`ID` <> `other_order`.`ID`') + ->addJoinCondition('other_order_join', '`matching_order`.`CREATED_AT` > `other_order`.`CREATED_AT`'); + + $dayOrdersQuery->where('ISNULL(`other_order`.`ID`)'); + + $dayOrders = $dayOrdersQuery->count(); + $stats[] = array($day-1, $dayOrders); + } + + return $stats; + } + + } // OrderQuery diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index 22989d8fb..0081eeebf 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -274,7 +274,7 @@ var $elem = $('#jqplot'); - var url = "{url file='/test_to_remove/admin-stats.json'}", + var url = "{url path='/admin/home/stats'}", series = [], seriesColors = [], ticks = [], @@ -318,12 +318,12 @@ } }; - // Get datas Json + // Get data Json $.getJSON(url) .done(function(data) { - // Init series datas and colors - initJqplotDatas(series, seriesColors, options, data); + // Init series data and colors + initJqplotData(series, seriesColors, options, data); // Add days to xaxis for(var i = 1; i < (days+1); i++){ @@ -350,8 +350,8 @@ series = []; seriesColors = []; - // Init series datas and colors - initJqplotDatas(series, seriesColors, options, data); + // Init series data and colors + initJqplotData(series, seriesColors, options, data); // Restart jqplot jqplot.destroy(); @@ -372,15 +372,15 @@ }); - function initJqplotDatas(series, seriesColors, options, json){ + function initJqplotData(series, seriesColors, options, json){ $('[data-toggle="jqplot-serie"].active').each(function(i){ var position = $(this).index() - 1; - series.push(json.series[position].datas); + series.push(json.series[position].data); seriesColors.push(json.series[position].color); }); - // Number of days to display ( = datas.length in one serie) - days = json.series[0].datas.length; + // Number of days to display ( = data.length in one serie) + days = json.series[0].data.length; // Graph title options.title = json.title; From f90df03f7ddd0cb53cca21b40a5f67910cbeb070 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 30 Oct 2013 17:00:38 +0100 Subject: [PATCH 2/5] admin home stats --- .../Controller/Admin/HomeController.php | 2 +- templates/admin/default/home.html | 228 +++++++++--------- 2 files changed, 115 insertions(+), 115 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php index 90b0c6655..c30e61985 100644 --- a/core/lib/Thelia/Controller/Admin/HomeController.php +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -43,7 +43,7 @@ class HomeController extends BaseAdminController { $data = new \stdClass(); - $data->title = "Stats on [...]"; + $data->title = "Stats on " . $this->getRequest()->request->get('month', date('m')) . "/" . $this->getRequest()->request->get('month', date('Y')); /* sales */ $saleSeries = new \stdClass(); diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index 0081eeebf..fd6d85a4a 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -266,133 +266,133 @@ {/javascripts} - + // Init series data and colors + initJqplotData(series, seriesColors, options, data); + + // Add days to xaxis + for(var i = 1; i < (days+1); i++){ + ticks.push([i-1, i]); + } + + // Start jqplot + var elementId = $elem.attr('id'); + jqplot = $.jqplot(elementId, series, options); + + $('[data-toggle="jqplot"]').each(function(){ + + $(this).click(function(){ + + if($('[data-toggle="jqplot-serie"].active').length > 1 || !$(this).hasClass('active')){ + + // Active button and jqplot-serie management + $(this).toggleClass('active'); + + var id = $(this).data('target'); + $('[data-toggle="jqplot-serie"]#' + id).toggleClass('active'); + + // Reinit variables + series = []; + seriesColors = []; + + // Init series data and colors + initJqplotData(series, seriesColors, options, data); + + // Restart jqplot + jqplot.destroy(); + jqplot = $.jqplot(elementId, series, options); + } + + }); + + }); + + $(window).bind('resize', function(event, ui) { + jqplot.replot( { resetAxes: true } ); + }); + + } + + }); + + {/javascripts} {/block} \ No newline at end of file From 00dab8e7ec0a3bc82971a591022205e7b8e6b582 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 31 Oct 2013 11:20:51 +0100 Subject: [PATCH 3/5] review jqplot --- .../Controller/Admin/HomeController.php | 32 +-- templates/admin/default/home.html | 271 +++++++++--------- 2 files changed, 151 insertions(+), 152 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php index c30e61985..dbd0a5d30 100644 --- a/core/lib/Thelia/Controller/Admin/HomeController.php +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -43,46 +43,46 @@ class HomeController extends BaseAdminController { $data = new \stdClass(); - $data->title = "Stats on " . $this->getRequest()->request->get('month', date('m')) . "/" . $this->getRequest()->request->get('month', date('Y')); + $data->title = "Stats on " . $this->getRequest()->query->get('month', date('m')) . "/" . $this->getRequest()->query->get('year', date('Y')); /* sales */ $saleSeries = new \stdClass(); - $saleSeries->color = $this->getRequest()->request->get('sales_color', '#adadad'); + $saleSeries->color = $this->getRequest()->query->get('sales_color', '#adadad'); $saleSeries->data = OrderQuery::getSaleStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* new customers */ $newCustomerSeries = new \stdClass(); - $newCustomerSeries->color = $this->getRequest()->request->get('customers_color', '#f39922'); + $newCustomerSeries->color = $this->getRequest()->query->get('customers_color', '#f39922'); $newCustomerSeries->data = CustomerQuery::getNewCustomersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* orders */ $orderSeries = new \stdClass(); - $orderSeries->color = $this->getRequest()->request->get('orders_color', '#5cb85c'); + $orderSeries->color = $this->getRequest()->query->get('orders_color', '#5cb85c'); $orderSeries->data = OrderQuery::getOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* first order */ $firstOrderSeries = new \stdClass(); - $firstOrderSeries->color = $this->getRequest()->request->get('first_orders_color', '#5bc0de'); + $firstOrderSeries->color = $this->getRequest()->query->get('first_orders_color', '#5bc0de'); $firstOrderSeries->data = OrderQuery::getFirstOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* cancelled orders */ $cancelledOrderSeries = new \stdClass(); - $cancelledOrderSeries->color = $this->getRequest()->request->get('cancelled_orders_color', '#d9534f'); + $cancelledOrderSeries->color = $this->getRequest()->query->get('cancelled_orders_color', '#d9534f'); $cancelledOrderSeries->data = OrderQuery::getOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')), + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')), array(5) ); diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index fd6d85a4a..105c640c5 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -12,10 +12,10 @@
{intl l='Dashboard'} -
- - - +
+ + +
@@ -33,12 +33,6 @@
- -
-
-
-
-
@@ -255,144 +249,149 @@ {javascripts file='assets/js/jqplot/jquery.jqplot.min.js'} - - {javascripts file='assets/js/jqplot/plugins/jqplot.highlighter.min.js'} - - {/javascripts} - {javascripts file='assets/js/jqplot/plugins/jqplot.barRenderer.min.js'} - - {/javascripts} - {javascripts file='assets/js/jqplot/plugins/jqplot.pieRenderer.min.js'} - - {/javascripts} + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.highlighter.min.js'} + + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.barRenderer.min.js'} + + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.pieRenderer.min.js'} + + {/javascripts} - {/javascripts} {/block} \ No newline at end of file From 07c5dd4a517519283ea34b4959b8201e230b4f1f Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 31 Oct 2013 11:59:25 +0100 Subject: [PATCH 4/5] admoin home stats navigation --- templates/admin/default/home.html | 44 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index 105c640c5..c1fbfa7c6 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -13,9 +13,9 @@
{intl l='Dashboard'}
- + - +
@@ -264,6 +264,8 @@ jQuery(function($){ + var jQplotDate = new Date(); + jQplotDate.setDate(1); // Set day to 1 so we can add month without 30/31 days of month troubles. var url = "{url path='/admin/home/stats'}"; var jQplotData; // json data var jQPlotInstance; // global instance @@ -306,13 +308,10 @@ jQuery(function($){ } }; + {literal} + // Get initial data Json - $.getJSON(url) - .done(function(data) { - jQplotData = data; - jsonSuccessLoad(); - }) - .fail(jsonFailLoad); + retrieveJQPlotJson(jQplotDate.getMonth()+1, jQplotDate.getFullYear()); $('[data-toggle="jqplot"]').click(function(){ @@ -323,21 +322,26 @@ jQuery(function($){ $('.js-stats-change-month').click(function(e){ $('.js-stats-change-month').attr('disabled', true); + jQplotDate.setMonth(parseInt(jQplotDate.getMonth()) + parseInt($(this).data('month-offset'))); + retrieveJQPlotJson(jQplotDate.getMonth()+1, jQplotDate.getFullYear(), function(){$('.js-stats-change-month').attr('disabled', false);}); - $('#jqplot'); - - {literal} - $.getJSON(url, {month: 9, year: 2010}) - .done(function(data) { - jQplotData = data; - jsonSuccessLoad(); - }) - .fail(jsonFailLoad); - {/literal} }); + function retrieveJQPlotJson(month, year, callback) { + console.log(month, year); - function initJqplotData(json){ + $.getJSON(url, {month: month, year: year}) + .done(function(data) { + jQplotData = data; + jsonSuccessLoad(); + if(callback) { + callback(); + } + }) + .fail(jsonFailLoad); + } + + function initJqplotData(json) { var series = []; var seriesColors = []; $('[data-toggle="jqplot"].active').each(function(i){ @@ -391,6 +395,8 @@ jQuery(function($){ } + {/literal} + }); From 1bcec288413d6be5868abfbc71afa8cdea3e44e1 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 31 Oct 2013 16:24:57 +0100 Subject: [PATCH 5/5] remove tax js in profiles --- templates/admin/default/profile-edit.html | 146 ---------------------- templates/admin/default/profiles.html | 4 +- 2 files changed, 2 insertions(+), 148 deletions(-) diff --git a/templates/admin/default/profile-edit.html b/templates/admin/default/profile-edit.html index a7c2e0f9d..8eb104cd0 100644 --- a/templates/admin/default/profile-edit.html +++ b/templates/admin/default/profile-edit.html @@ -295,10 +295,6 @@ {block name="javascript-initialization"} - {javascripts file='assets/js/bootstrap-select/bootstrap-select.js'} - - {/javascripts} - {javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'} {/javascripts} @@ -307,146 +303,4 @@ {/javascripts} - - - - {/block} \ No newline at end of file diff --git a/templates/admin/default/profiles.html b/templates/admin/default/profiles.html index 7c4950b02..418037cc1 100644 --- a/templates/admin/default/profiles.html +++ b/templates/admin/default/profiles.html @@ -1,6 +1,6 @@ {extends file="admin-layout.tpl"} -{block name="page-title"}{intl l='Taxes rules'}{/block} +{block name="page-title"}{intl l='Administration profiles'}{/block} {block name="check-resource"}admin.configuration.profile{/block} {block name="check-access"}view{/block} @@ -27,7 +27,7 @@
- {intl l="Taxes"} + {intl l="Administration profiles"} {loop type="auth" name="can_create" role="ADMIN" resource="admin.profile" access="CREATE"}