From 969c077f81fee3fe48d5a8d636bf903249c6f769 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 4 Nov 2013 16:15:48 +0100 Subject: [PATCH 1/2] admin home stats and information --- .../Controller/Admin/HomeController.php | 8 +- .../Smarty/Plugins/DataAccessFunctions.php | 93 ++++++++++++ core/lib/Thelia/Model/CustomerQuery.php | 2 +- core/lib/Thelia/Model/Order.php | 15 +- core/lib/Thelia/Model/OrderQuery.php | 41 +++++- templates/admin/default/home.html | 136 +++++++++--------- 6 files changed, 220 insertions(+), 75 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php index dbd0a5d30..8679b28e6 100644 --- a/core/lib/Thelia/Controller/Admin/HomeController.php +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -48,7 +48,7 @@ class HomeController extends BaseAdminController /* sales */ $saleSeries = new \stdClass(); $saleSeries->color = $this->getRequest()->query->get('sales_color', '#adadad'); - $saleSeries->data = OrderQuery::getSaleStats( + $saleSeries->data = OrderQuery::getMonthlySaleStats( $this->getRequest()->query->get('month', date('m')), $this->getRequest()->query->get('year', date('Y')) ); @@ -56,7 +56,7 @@ class HomeController extends BaseAdminController /* new customers */ $newCustomerSeries = new \stdClass(); $newCustomerSeries->color = $this->getRequest()->query->get('customers_color', '#f39922'); - $newCustomerSeries->data = CustomerQuery::getNewCustomersStats( + $newCustomerSeries->data = CustomerQuery::getMonthlyNewCustomersStats( $this->getRequest()->query->get('month', date('m')), $this->getRequest()->query->get('year', date('Y')) ); @@ -64,7 +64,7 @@ class HomeController extends BaseAdminController /* orders */ $orderSeries = new \stdClass(); $orderSeries->color = $this->getRequest()->query->get('orders_color', '#5cb85c'); - $orderSeries->data = OrderQuery::getOrdersStats( + $orderSeries->data = OrderQuery::getMonthlyOrdersStats( $this->getRequest()->query->get('month', date('m')), $this->getRequest()->query->get('year', date('Y')) ); @@ -80,7 +80,7 @@ class HomeController extends BaseAdminController /* cancelled orders */ $cancelledOrderSeries = new \stdClass(); $cancelledOrderSeries->color = $this->getRequest()->query->get('cancelled_orders_color', '#d9534f'); - $cancelledOrderSeries->data = OrderQuery::getOrdersStats( + $cancelledOrderSeries->data = OrderQuery::getMonthlyOrdersStats( $this->getRequest()->query->get('month', date('m')), $this->getRequest()->query->get('year', date('Y')), array(5) diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php index a401755a4..df14646dc 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php @@ -36,6 +36,7 @@ use Thelia\Model\ContentQuery; use Thelia\Model\CountryQuery; use Thelia\Model\CurrencyQuery; use Thelia\Model\FolderQuery; +use Thelia\Model\OrderQuery; use Thelia\Model\Product; use Thelia\Model\ProductQuery; use Thelia\Model\Tools\ModelCriteriaTools; @@ -247,6 +248,97 @@ class DataAccessFunctions extends AbstractSmartyPlugin return ConfigQuery::read($key); } + public function StatsAccess($params, $smarty) + { + if (false === array_key_exists("key", $params)) { + throw new \InvalidArgumentException(sprintf("missing key attribute in stats access function")); + } + if (false === array_key_exists("startDate", $params) || $params['startDate'] === '') { + throw new \InvalidArgumentException(sprintf("missing startDate attribute in stats access function")); + } + if (false === array_key_exists("endDate", $params) || $params['endDate'] === '') { + throw new \InvalidArgumentException(sprintf("missing endDate attribute in stats access function")); + } + + if (false !== array_key_exists("includeShipping", $params) && $params['includeShipping'] == 'false') { + $includeShipping = false; + } else { + $includeShipping = true; + } + + if($params['startDate'] == 'today') { + $startDate = new \DateTime(); + $startDate->setTime(0, 0, 0); + } elseif($params['startDate'] == 'yesterday') { + $startDate = new \DateTime(); + $startDate->setTime(0, 0, 0); + $startDate->modify('-1 day'); + } elseif($params['startDate'] == 'this_month') { + $startDate = new \DateTime(); + $startDate->modify('first day of this month'); + $startDate->setTime(0, 0, 0); + } elseif($params['startDate'] == 'last_month') { + $startDate = new \DateTime(); + $startDate->modify('first day of last month'); + $startDate->setTime(0, 0, 0); + } elseif($params['startDate'] == 'this_year') { + $startDate = new \DateTime(); + $startDate->modify('first day of January this year'); + $startDate->setTime(0, 0, 0); + } elseif($params['startDate'] == 'last_year') { + $startDate = new \DateTime(); + $startDate->modify('first day of December last year'); + $startDate->setTime(0, 0, 0); + } else { + try { + $startDate = new \DateTime($params['startDate']); + } catch(\Exception $e) { + throw new \InvalidArgumentException(sprintf("invalid startDate attribute '%s' in stats access function", $params['startDate'])); + } + } + + if($params['endDate'] == 'today') { + $endDate = new \DateTime(); + $endDate->setTime(0, 0, 0); + } elseif($params['endDate'] == 'yesterday') { + $endDate = new \DateTime(); + $endDate->setTime(0, 0, 0); + $endDate->modify('-1 day'); + } elseif($params['endDate'] == 'this_month') { + $endDate = new \DateTime(); + $endDate->modify('last day of this month'); + $endDate->setTime(0, 0, 0); + } elseif($params['endDate'] == 'last_month') { + $endDate = new \DateTime(); + $endDate->modify('last day of last month'); + $endDate->setTime(0, 0, 0); + } elseif($params['endDate'] == 'this_year') { + $endDate = new \DateTime(); + $endDate->modify('last day of December this year'); + $endDate->setTime(0, 0, 0); + } elseif($params['endDate'] == 'last_year') { + $endDate = new \DateTime(); + $endDate->modify('last day of January last year'); + $endDate->setTime(0, 0, 0); + } else { + try { + $endDate = new \DateTime($params['endDate']); + } catch(\Exception $e) { + throw new \InvalidArgumentException(sprintf("invalid endDate attribute '%s' in stats access function", $params['endDate'])); + } + } + + switch( $params['key'] ) { + case 'sales' : + return OrderQuery::getSaleStats($startDate, $endDate, $includeShipping); + case 'orders' : + return OrderQuery::getOrderStats($startDate, $endDate, array(1,2,3,4)); + + } + + throw new \InvalidArgumentException(sprintf("invalid key attribute '%s' in stats access function", $params['key'])); + } + /** * @param $objectLabel * @param $params @@ -358,6 +450,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin new SmartyPluginDescriptor('function', 'cart', $this, 'cartDataAccess'), new SmartyPluginDescriptor('function', 'order', $this, 'orderDataAccess'), new SmartyPluginDescriptor('function', 'config', $this, 'ConfigDataAccess'), + new SmartyPluginDescriptor('function', 'stats', $this, 'StatsAccess'), ); } diff --git a/core/lib/Thelia/Model/CustomerQuery.php b/core/lib/Thelia/Model/CustomerQuery.php index 5c225510b..7a2f2c60e 100755 --- a/core/lib/Thelia/Model/CustomerQuery.php +++ b/core/lib/Thelia/Model/CustomerQuery.php @@ -23,7 +23,7 @@ class CustomerQuery extends BaseCustomerQuery { return self::create()->findOneByEmail($email); } - public static function getNewCustomersStats($month, $year) + public static function getMonthlyNewCustomersStats($month, $year) { $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); diff --git a/core/lib/Thelia/Model/Order.php b/core/lib/Thelia/Model/Order.php index 4033e5bfb..d761c3959 100755 --- a/core/lib/Thelia/Model/Order.php +++ b/core/lib/Thelia/Model/Order.php @@ -50,11 +50,12 @@ class Order extends BaseOrder /** * calculate the total amount * - * @param int $tax + * @param int $tax + * @param bool $includePostage * - * @return int|string|Base\double + * @return float|int|string */ - public function getTotalAmount(&$tax = 0) + public function getTotalAmount(&$tax = 0, $includePostage = true) { $amount = 0; $tax = 0; @@ -76,7 +77,13 @@ class Order extends BaseOrder $tax += round($taxAmount->getVirtualColumn('total_tax'), 2) * $orderProduct->getQuantity(); } - return $amount + $tax + $this->getPostage(); // @todo : manage discount + $total = $amount + $tax; + + if(false !== $includePostage) { + $total += $this->getPostage(); + } + + return $total; // @todo : manage discount } /** diff --git a/core/lib/Thelia/Model/OrderQuery.php b/core/lib/Thelia/Model/OrderQuery.php index 6eee6a81b..bbee444e7 100755 --- a/core/lib/Thelia/Model/OrderQuery.php +++ b/core/lib/Thelia/Model/OrderQuery.php @@ -55,7 +55,7 @@ class OrderQuery extends BaseOrderQuery return $obj; } - public static function getSaleStats($month, $year) + public static function getMonthlySaleStats($month, $year) { $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); @@ -75,7 +75,7 @@ class OrderQuery extends BaseOrderQuery return $stats; } - public static function getOrdersStats($month, $year, $status = null) + public static function getMonthlyOrdersStats($month, $year, $status = null) { $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); @@ -121,5 +121,42 @@ class OrderQuery extends BaseOrderQuery return $stats; } + /** + * @param \DateTime $startDate + * @param \DateTime $endDate + * @param $includeShipping + * + * @return int + */ + public static function getSaleStats(\DateTime $startDate, \DateTime $endDate, $includeShipping) + { + $amount = 0; + foreach(self::create() + ->filterByStatusId(array(2,3,4), Criteria::IN) + ->filterByCreatedAt(sprintf("%s 00:00:00", $startDate->format('Y-m-d')), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s 23:59:59", $endDate->format('Y-m-d')), Criteria::LESS_EQUAL) + ->find() as $order) { + $tax = 0; + $amount += $order->getTotalAmount($tax, $includeShipping); + } + + return $amount; + } + + /** + * @param \DateTime $startDate + * @param \DateTime $endDate + * @param $status + * + * @return int + */ + public static function getOrderStats(\DateTime $startDate, \DateTime $endDate, $status = array(1,2,3,4)) + { + return self::create() + ->filterByStatusId($status, Criteria::IN) + ->filterByCreatedAt(sprintf("%s 00:00:00", $startDate->format('Y-m-d')), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s 23:59:59", $endDate->format('Y-m-d')), Criteria::LESS_EQUAL) + ->count(); + } } // OrderQuery diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index c1fbfa7c6..dcfe59a92 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -47,43 +47,39 @@ {intl l="Customers"} - 1 + + {count type="customer" current="false" backend_context="1"} + {intl l="Categories"} - 8 + + {count type="category" visible="*" backend_context="1"} + {intl l="Products"} - 43 + + {count type="product" visible="*" backend_context="1"} + {intl l="Online products"} - 43 + + {count type="product" visible="true" backend_context="1"} + {intl l="Offline products"} - 0 + + {count type="product" visible="false" backend_context="1"} + {intl l="Orders"} - 1 - - - {intl l="Pending orders"} - 1 - - - {intl l="In process orderst"} - 0 - - - {intl l="Shipped orders"} - 0 - - - {intl l="Canceled orders"} - 0 + + {count type="order" status="*" backend_context="1"} + @@ -108,31 +104,35 @@ {intl l="Overall sales"} - 2500.00 € + {stats key="sales" startDate="today" endDate="today"} € {intl l="Sales excluding shipping"} - 2000.00 € + + {$salesNoShipping = {stats key="sales" startDate="today" endDate="today" includeShipping="false"}} + {$salesNoShipping} € + {intl l="Yesterday sales"} - 1700.00 € + {stats key="sales" startDate="yesterday" endDate="yesterday"} € - {intl l="Waiting orders"} - 4 - - - {intl l="In process orders"} - 52 - - - {intl l="Canceled orders"} - 3 + {intl l="Orders"} + + {$orderCount = {stats key="orders" startDate="today" endDate="today"}} + {$orderCount} + {intl l="Average cart"} - 25.00 € + + {if $orderCount == 0} + 0 € + {else} + {($salesNoShipping/$orderCount)|round:"2"} € + {/if} + @@ -144,31 +144,35 @@ {intl l="Overall sales"} - 2500.00 € + {stats key="sales" startDate="this_month" endDate="this_month"} € {intl l="Sales excluding shipping"} - 2000.00 € + + {$salesNoShipping = {stats key="sales" startDate="this_month" endDate="this_month" includeShipping="false"}} + {$salesNoShipping} € + {intl l="Previous month sales"} - 1700.00 € + {stats key="sales" startDate="last_month" endDate="last_month"} € - {intl l="Waiting orders"} - 4 - - - {intl l="In process orders"} - 52 - - - {intl l="Canceled orders"} - 3 + {intl l="Orders"} + + {$orderCount = {stats key="orders" startDate="this_month" endDate="this_month"}} + {$orderCount} + {intl l="Average cart"} - 25.00 € + + {if $orderCount == 0} + 0 € + {else} + {($salesNoShipping/$orderCount)|round:"2"} € + {/if} + @@ -180,31 +184,35 @@ {intl l="Overall sales"} - 2500.00 € + {stats key="sales" startDate="this_year" endDate="this_year"} € {intl l="Sales excluding shipping"} - 2000.00 € + + {$salesNoShipping = {stats key="sales" startDate="this_year" endDate="this_year" includeShipping="false"}} + {$salesNoShipping} € + {intl l="Previous year sales"} - 1700.00 € + {stats key="sales" startDate="last_year" endDate="last_year"} € - {intl l="Waiting orders"} - 4 - - - {intl l="In process orders"} - 52 - - - {intl l="Canceled orders"} - 3 + {intl l="Orders"} + + {$orderCount = {stats key="orders" startDate="this_year" endDate="this_year"}} + {$orderCount} + {intl l="Average cart"} - 25.00 € + + {if $orderCount == 0} + 0 € + {else} + {($salesNoShipping/$orderCount)|round:"2"} € + {/if} + From 3e1a08dc6c9a886558f234d340755c78254845d7 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Mon, 4 Nov 2013 17:37:23 +0100 Subject: [PATCH 2/2] Correcting some typos --- core/lib/Thelia/Command/Install.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/lib/Thelia/Command/Install.php b/core/lib/Thelia/Command/Install.php index 7b6ca31c5..21ebdcfdc 100755 --- a/core/lib/Thelia/Command/Install.php +++ b/core/lib/Thelia/Command/Install.php @@ -257,7 +257,7 @@ class Install extends ContainerAwareCommand function ($answer) { $answer = trim($answer); if (is_null($answer)) { - throw new \RuntimeException("You must specify database host"); + throw new \RuntimeException("You must specify a database host"); } return $answer; @@ -266,12 +266,12 @@ class Install extends ContainerAwareCommand $connectionInfo["dbName"] = $dialog->askAndValidate( $output, - $this->decorateInfo("Database Name (if database does not exists, Thelia will try to create it) : "), + $this->decorateInfo("Database name (if database does not exist, Thelia will try to create it) : "), function ($answer) { $answer = trim($answer); if (is_null($answer)) { - throw new \RuntimeException("You must specify database name"); + throw new \RuntimeException("You must specify a database name"); } return $answer; @@ -280,12 +280,12 @@ class Install extends ContainerAwareCommand $connectionInfo["username"] = $dialog->askAndValidate( $output, - $this->decorateInfo("Databse username : "), + $this->decorateInfo("Database username : "), function ($answer) { $answer = trim($answer); if (is_null($answer)) { - throw new \RuntimeException("You must sprcify database username"); + throw new \RuntimeException("You must specify a database username"); } return $answer;