diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 2ca43e472..9fa7d1cbf 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/Config/Resources/translation.xml b/core/lib/Thelia/Config/Resources/translation.xml new file mode 100644 index 000000000..2fdef3882 --- /dev/null +++ b/core/lib/Thelia/Config/Resources/translation.xml @@ -0,0 +1,62 @@ + + + + + + Symfony\Component\Translation\Loader\PhpFileLoader + Symfony\Component\Translation\Loader\YamlFileLoader + Symfony\Component\Translation\Loader\XliffFileLoader + Symfony\Component\Translation\Loader\PoFileLoader + Symfony\Component\Translation\Loader\MoFileLoader + Symfony\Component\Translation\Loader\QtFileLoader + Symfony\Component\Translation\Loader\CsvFileLoader + Symfony\Component\Translation\Loader\IcuResFileLoader + Symfony\Component\Translation\Loader\IcuDatFileLoader + Symfony\Component\Translation\Loader\IniFileLoader + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php new file mode 100644 index 000000000..dbd0a5d30 --- /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 " . $this->getRequest()->query->get('month', date('m')) . "/" . $this->getRequest()->query->get('year', date('Y')); + + /* sales */ + $saleSeries = new \stdClass(); + $saleSeries->color = $this->getRequest()->query->get('sales_color', '#adadad'); + $saleSeries->data = OrderQuery::getSaleStats( + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) + ); + + /* new customers */ + $newCustomerSeries = new \stdClass(); + $newCustomerSeries->color = $this->getRequest()->query->get('customers_color', '#f39922'); + $newCustomerSeries->data = CustomerQuery::getNewCustomersStats( + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) + ); + + /* orders */ + $orderSeries = new \stdClass(); + $orderSeries->color = $this->getRequest()->query->get('orders_color', '#5cb85c'); + $orderSeries->data = OrderQuery::getOrdersStats( + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) + ); + + /* first order */ + $firstOrderSeries = new \stdClass(); + $firstOrderSeries->color = $this->getRequest()->query->get('first_orders_color', '#5bc0de'); + $firstOrderSeries->data = OrderQuery::getFirstOrdersStats( + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) + ); + + /* cancelled orders */ + $cancelledOrderSeries = new \stdClass(); + $cancelledOrderSeries->color = $this->getRequest()->query->get('cancelled_orders_color', '#d9534f'); + $cancelledOrderSeries->data = OrderQuery::getOrdersStats( + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->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/Core/Bundle/TheliaBundle.php b/core/lib/Thelia/Core/Bundle/TheliaBundle.php index dcdcdd5d2..9a536f88d 100755 --- a/core/lib/Thelia/Core/Bundle/TheliaBundle.php +++ b/core/lib/Thelia/Core/Bundle/TheliaBundle.php @@ -31,6 +31,7 @@ use Thelia\Core\DependencyInjection\Compiler\RegisterListenersPass; use Thelia\Core\DependencyInjection\Compiler\RegisterParserPluginPass; use Thelia\Core\DependencyInjection\Compiler\RegisterRouterPass; use Thelia\Core\DependencyInjection\Compiler\RegisterCouponConditionPass; +use Thelia\Core\DependencyInjection\Compiler\TranslatorPass; /** * First Bundle use in Thelia @@ -63,6 +64,9 @@ class TheliaBundle extends Bundle ->addCompilerPass(new RegisterParserPluginPass()) ->addCompilerPass(new RegisterRouterPass()) ->addCompilerPass(new RegisterCouponPass()) - ->addCompilerPass(new RegisterCouponConditionPass()); + ->addCompilerPass(new RegisterCouponConditionPass()) + ->addCompilerPass(new TranslatorPass()) + + ; } } diff --git a/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php b/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php index 3bd35bb62..e007f9961 100644 --- a/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php +++ b/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php @@ -24,6 +24,7 @@ namespace Thelia\Core\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; /** @@ -49,8 +50,11 @@ class TranslatorPass implements CompilerPassInterface $translator = $container->getDefinition('thelia.translator'); - foreach($container->findTaggedServiceIds('translator.loader') as $id => $attributes) { - + foreach($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { + $translator->addMethodCall('addLoader', array($attributes[0]['alias'], new Reference($id))); + if (isset($attributes[0]['legacy-alias'])) { + $translator->addMethodCall('addLoader', array($attributes[0]['legacy-alias'], new Reference($id))); + } } } } \ No newline at end of file diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index 9b0d1402f..3d476ad30 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -47,6 +47,7 @@ use Thelia\Config\DatabaseConfiguration; use Thelia\Config\DefinePropel; use Thelia\Core\TheliaContainerBuilder; use Thelia\Core\DependencyInjection\Loader\XmlFileLoader; +use Thelia\Model\ConfigQuery; use Symfony\Component\Config\FileLocator; use Propel\Runtime\Propel; @@ -122,7 +123,8 @@ class Thelia extends Kernel if (defined("THELIA_INSTALL_MODE") === false) { $modules = \Thelia\Model\ModuleQuery::getActivated(); - + $translator = $container->getDefinition('thelia.translator'); + $dirs = array(); foreach ($modules as $module) { try { @@ -138,10 +140,38 @@ class Thelia extends Kernel $loader = new XmlFileLoader($container, new FileLocator(THELIA_MODULE_DIR . "/" . ucfirst($module->getCode()) . "/Config")); $loader->load("config.xml"); + + if (is_dir($dir = THELIA_MODULE_DIR . "/" . ucfirst($module->getCode()) . "/I18n")) { + $dirs[] = $dir; + } } catch (\InvalidArgumentException $e) { // FIXME: process module configuration exception } } + + //Load translation from templates + //admin template + if(is_dir($dir = THELIA_TEMPLATE_DIR . '/admin/default/I18n')) { + $dirs[] = $dir; + } + + //front template + $template = ConfigQuery::getActiveTemplate(); + if(is_dir($dir = THELIA_TEMPLATE_DIR . $template . "/I18n")) { + $dirs[] = $dir; + } + + if ($dirs) { + $finder = Finder::create() + ->files() + ->depth(0) + ->in($dirs); + + foreach ($finder as $file) { + list($locale, $format) = explode('.', $file->getBaseName(), 2); + $translator->addMethodCall('addResource', array($format, (string) $file, $locale)); + } + } } } 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..c1fbfa7c6 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,155 @@ {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} + + {/block} \ No newline at end of file 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"}