From dcac104b75fe073a467ad2f9249df909a240b61d Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 18 Apr 2014 19:52:45 +0200 Subject: [PATCH] Fixed pagination, and factorized pager --- .../Controller/Admin/CustomerController.php | 1 - .../Thelia/Core/Template/Element/BaseLoop.php | 254 +++--- .../Template/Smarty/Plugins/TheliaLoop.php | 209 +++-- .../backOffice/default/configs/variables.conf | 1 + templates/backOffice/default/customers.html | 756 +++++++++--------- templates/backOffice/default/orders.html | 440 +++++----- 6 files changed, 875 insertions(+), 786 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index f7766eac8..784790c2e 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -171,7 +171,6 @@ class CustomerController extends AbstractCrudController { return $this->render('customers', array_merge(array( 'customer_order' => $currentOrder, - 'display_customer' => 20, 'page' => $this->getRequest()->get('page', 1) ), $customParams) ); diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index df57077de..5841d8461 100644 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -14,10 +14,13 @@ namespace Thelia\Core\Template\Element; use Propel\Runtime\ActiveQuery\Criteria; use Propel\Runtime\ActiveQuery\ModelCriteria; +use Propel\Runtime\Collection\ObjectCollection; +use Propel\Runtime\Util\PropelModelPager; use Symfony\Component\DependencyInjection\ContainerInterface; use Thelia\Core\Security\SecurityContext; use Thelia\Core\Template\Element\Exception\LoopException; use Thelia\Core\Template\Loop\Argument\Argument; +use Thelia\Core\Translation\Translator; use Thelia\Type\EnumListType; use Thelia\Type\EnumType; use Thelia\Type\TypeCollection; @@ -53,8 +56,11 @@ abstract class BaseLoop protected $timestampable = false; protected $versionable = false; - private static $cacheLoopResult = array(); - private static $cacheCount = array(); + /** @var Translator */ + protected $translator = null; + + private static $cacheLoopResult = []; + private static $cacheCount = []; /** * Create a new Loop @@ -70,6 +76,7 @@ abstract class BaseLoop $this->request = $container->get('request'); $this->dispatcher = $container->get('event_dispatcher'); $this->securityContext = $container->get('thelia.securityContext'); + $this->translator = $container->get("thelia.translator"); $this->args = $this->getArgDefinitions()->addArguments($this->getDefaultArgs(), false); } @@ -81,53 +88,54 @@ abstract class BaseLoop */ protected function getDefaultArgs() { - $defaultArgs = array( + $defaultArgs = [ Argument::createBooleanTypeArgument('backend_context', false), Argument::createBooleanTypeArgument('force_return', false), Argument::createAnyTypeArgument('type'), - ); + ]; if (true === $this->countable) { - $defaultArgs = array_merge($defaultArgs, array( - Argument::createIntTypeArgument('offset', 0), - Argument::createIntTypeArgument('page'), - Argument::createIntTypeArgument('limit', PHP_INT_MAX), - )); + $defaultArgs = array_merge($defaultArgs, [ + Argument::createIntTypeArgument('offset', 0), + Argument::createIntTypeArgument('page'), + Argument::createIntTypeArgument('limit', PHP_INT_MAX), + ]); } if ($this instanceof SearchLoopInterface) { - $defaultArgs = array_merge($defaultArgs, array( - Argument::createAnyTypeArgument('search_term'), - new Argument( - 'search_in', - new TypeCollection( - new EnumListType($this->getSearchIn()) - ) - ), - new Argument( - 'search_mode', - new TypeCollection( - new EnumType(array( - SearchLoopInterface::MODE_ANY_WORD, - SearchLoopInterface::MODE_SENTENCE, - SearchLoopInterface::MODE_STRICT_SENTENCE, - )) + + $defaultArgs = array_merge($defaultArgs, [ + Argument::createAnyTypeArgument('search_term'), + new Argument( + 'search_in', + new TypeCollection( + new EnumListType($this->getSearchIn()) + ) ), - SearchLoopInterface::MODE_STRICT_SENTENCE - ) - )); + new Argument( + 'search_mode', + new TypeCollection( + new EnumType([ + SearchLoopInterface::MODE_ANY_WORD, + SearchLoopInterface::MODE_SENTENCE, + SearchLoopInterface::MODE_STRICT_SENTENCE, + ]) + ), + SearchLoopInterface::MODE_STRICT_SENTENCE + ) + ]); } return $defaultArgs; } /** - * Provides a getter to loop parameters + * Provides a getter to loop parameter values * - * @param string $name the methode name (only getArgname is supported) - * @param $arguments this parameter is ignored + * @param string $name the method name (only getArgname is supported) + * @param mixed $arguments this parameter is ignored * - * @return null + * @return mixed the argument value * @throws \InvalidArgumentException if the parameter is unknown or the method name is not supported. */ public function __call($name, $arguments) @@ -137,10 +145,12 @@ abstract class BaseLoop // camelCase to underscore: getNotEmpty -> not_empty $argName = strtolower(preg_replace('/([^A-Z])([A-Z])/', "$1_$2", substr($name, 3))); - return $this->getArg($argName)->getValue(); + return $this->getArgValue($argName); } - throw new \InvalidArgumentException(sprintf("Unsupported magic method %s. only getArgname() is supported.", $name)); + throw new \InvalidArgumentException( + $this->translator->trans("Unsupported magic method %name. only getArgname() is supported.", ['%name' => $name]) + ); } /** @@ -148,12 +158,12 @@ abstract class BaseLoop * * @param array $nameValuePairs a array of name => value pairs. The name is the name of the argument. * - * @throws \InvalidArgumentException if somùe argument values are missing, or invalid + * @throws \InvalidArgumentException if some argument values are missing, or invalid */ public function initializeArgs(array $nameValuePairs) { - $faultActor = array(); - $faultDetails = array(); + $faultActor = []; + $faultDetails = []; $loopType = isset($nameValuePairs['type']) ? $nameValuePairs['type'] : "undefined"; $loopName = isset($nameValuePairs['name']) ? $nameValuePairs['name'] : "undefined"; @@ -167,19 +177,38 @@ abstract class BaseLoop /* check if mandatory */ if ($value === null && $argument->mandatory) { $faultActor[] = $argument->name; - $faultDetails[] = sprintf('"%s" parameter is missing in loop type: %s, name: %s', $argument->name, $loopType, $loopName); + $faultDetails[] = $this->translator->trans( + '"%param" parameter is missing in loop type: %type, name: %name', [ + '%param' => $argument->name, + '%type' => $loopType, + '%name' => $loopName + ] + ); } else if ($value === '') { if (!$argument->empty) { /* check if empty */ $faultActor[] = $argument->name; - $faultDetails[] = sprintf('"%s" parameter cannot be empty in loop type: %s, name: %s', $argument->name, $loopType, $loopName); + $faultDetails[] = $this->translator->trans( + '"%param" parameter cannot be empty in loop type: %type, name: %name', [ + '%param' => $argument->name, + '%type' => $loopType, + '%name' => $loopName + ] + ); } } elseif ($value !== null && !$argument->type->isValid($value)) { /* check type */ $faultActor[] = $argument->name; - $faultDetails[] = sprintf('Invalid value "%s" for "%s" argument in loop type: %s, name: %s', $value, $argument->name, $loopType, $loopName); + $faultDetails[] = $this->translator->trans( + 'Invalid value "%value" for "%param" parameter in loop type: %type, name: %name', [ + '%value' => $value, + '%param' => $argument->name, + '%type' => $loopType, + '%name' => $loopName + ] + ); } else { - /* set default */ + /* set default value */ /* did it as last checking for we consider default value is acceptable no matter type or empty restriction */ if ($value === null) { $value = $argument->default; @@ -189,9 +218,9 @@ abstract class BaseLoop } } - if (!empty($faultActor)) { - + if (! empty($faultActor)) { $complement = sprintf('[%s]', implode(', ', $faultDetails)); + throw new \InvalidArgumentException($complement); } } @@ -201,15 +230,17 @@ abstract class BaseLoop * * @param string $argumentName the argument name * + * @return Argument the loop argument. * @throws \InvalidArgumentException if argument is not found in loop argument list - * @return Argument the loop argument. */ protected function getArg($argumentName) { $arg = $this->args->get($argumentName); if ($arg === null) - throw new \InvalidArgumentException("Undefined loop argument '$argumentName'"); + throw new \InvalidArgumentException( + $this->translator->trans('Undefined loop argument "%name"', ['%name' => $argumentName]) + ); return $arg; } @@ -220,7 +251,7 @@ abstract class BaseLoop * @param string $argumentName the argument name * * @throws \InvalidArgumentException if argument is not found in loop argument list - * @return Argument the loop argument. + * @return mixed the loop argument value */ protected function getArgValue($argumentName) { @@ -228,20 +259,24 @@ abstract class BaseLoop } /** - * @param ModelCriteria $search - * @param null $pagination + * @param ModelCriteria $search the search request + * @param PropelModelPager $pagination the pagination part * - * @return array|mixed|\PropelModelPager|\PropelObjectCollection + * @return array|PropelModelPager|ObjectCollection + * @throws \InvalidArgumentException if the search mode is undefined. */ protected function search(ModelCriteria $search, &$pagination = null) { if (false === $this->countable) { return $search->find(); } + if ($this instanceof SearchLoopInterface) { - $searchTerm = $this->getSearch_term(); - $searchIn = $this->getSearch_in(); - $searchMode = $this->getSearch_mode(); + + $searchTerm = $this->getArgValue('search_term'); + $searchIn = $this->getArgValue('search_in'); + $searchMode = $this->getArgValue('search_mode'); + if (null !== $searchTerm && null !== $searchIn) { switch ($searchMode) { @@ -256,6 +291,10 @@ abstract class BaseLoop case SearchLoopInterface::MODE_STRICT_SENTENCE: $searchCriteria = Criteria::EQUAL; break; + default: + throw new \InvalidArgumentException( + $this->translator->trans("Undefined search mode '%mode'", ['%mode' => $searchMode]) + ); } $this->doSearch($search, $searchTerm, $searchIn, $searchCriteria); @@ -269,24 +308,31 @@ abstract class BaseLoop } } - protected function searchArray(array $search, &$pagination = null) + protected function searchArray(array $search) { if (false === $this->countable) { return $search; } + + $limit = intval($this->getArgValue('limit')); + $offset = intval($this->getArgValue('offset')); + if ($this->getArgValue('page') !== null) { - $nbPage = ceil(count($search)/$this->getArgValue('limit')); - if ($this->getArgValue('page') > $nbPage || $this->getArgValue('page') <= 0) { - return array(); + $pageNum = intval($this->getArgValue('page')); + + $totalPageCount = ceil(count($search) / $limit); + + if ($pageNum > $totalPageCount || $pageNum <= 0) { + return []; } - $firstItem = ($this->getArgValue('page')-1) * $this->getArgValue('limit') + 1; + $firstItem = ($pageNum - 1) * $limit + 1; - return array_slice($search, $firstItem, $firstItem + $this->getArgValue('limit'), false); + return array_slice($search, $firstItem, $firstItem + $limit, false); } else { - return array_slice($search, $this->getArgValue('offset'), $this->getArgValue('limit'), false); + return array_slice($search, $offset, $limit, false); } } @@ -294,30 +340,36 @@ abstract class BaseLoop /** * @param ModelCriteria $search * - * @return array|mixed|\PropelObjectCollection + * @return ObjectCollection */ protected function searchWithOffset(ModelCriteria $search) { - if ($this->getArgValue('limit') >= 0) { - $search->limit($this->getArgValue('limit')); + $limit = intval($this->getArgValue('limit')); + + if ($limit >= 0) { + $search->limit($limit); } - $search->offset($this->getArgValue('offset')); + + $search->offset(intval($this->getArgValue('offset'))); return $search->find(); } /** * @param ModelCriteria $search - * @param $pagination + * @param PropelModelPager $pagination * - * @return array|\Propel\Runtime\Util\PropelModelPager + * @return array|PropelModelPager */ protected function searchWithPagination(ModelCriteria $search, &$pagination) { - $pagination = $search->paginate($this->getArgValue('page'), $this->getArgValue('limit')); + $page = intval($this->getArgValue('page')); + $limit = intval($this->getArgValue('limit')); - if ($this->getArgValue('page') > $pagination->getLastPage()) { - return array(); + $pagination = $search->paginate($page, $limit); + + if ($page > $pagination->getLastPage()) { + return []; } else { return $pagination; } @@ -350,18 +402,21 @@ abstract class BaseLoop } /** - * @param $pagination + * @param PropelModelPager $pagination + * * @return LoopResult */ public function exec(&$pagination) { $hash = $this->args->getHash(); if (false === isset(self::$cacheLoopResult[$hash])) { + + $results = []; + if ($this instanceof PropelSearchLoopInterface) { $searchModelCriteria = $this->buildModelCriteria(); - if (null === $searchModelCriteria) { - $results = array(); - } else { + + if (null !== $searchModelCriteria) { $results = $this->search( $searchModelCriteria, $pagination @@ -369,13 +424,9 @@ abstract class BaseLoop } } elseif ($this instanceof ArraySearchLoopInterface) { $searchArray = $this->buildArray(); - if (null === $searchArray) { - $results = array(); - } else { - $results = $this->searchArray( - $searchArray, - $pagination - ); + + if (null !== $searchArray) { + $results = $this->searchArray($searchArray); } } @@ -405,30 +456,49 @@ abstract class BaseLoop * - ArraySearchLoopInterface */ $searchInterface = false; + if ($this instanceof PropelSearchLoopInterface) { if (true === $searchInterface) { - throw new LoopException('Loop cannot implements multiple Search Interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`', LoopException::MULTIPLE_SEARCH_INTERFACE); + throw new LoopException( + $this->translator->trans( + 'Loop cannot implements multiple Search Interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`' + ), + LoopException::MULTIPLE_SEARCH_INTERFACE); } $searchInterface = true; } + if ($this instanceof ArraySearchLoopInterface) { if (true === $searchInterface) { - throw new LoopException('Loop cannot implements multiple Search Interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`', LoopException::MULTIPLE_SEARCH_INTERFACE); + throw new LoopException( + $this->translator->trans( + 'Loop cannot implements multiple Search Interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`' + ), + LoopException::MULTIPLE_SEARCH_INTERFACE); } $searchInterface = true; } if (false === $searchInterface) { - throw new LoopException('Loop must implements one of the following interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`', LoopException::SEARCH_INTERFACE_NOT_FOUND); + throw new LoopException( + $this->translator->trans( + 'Loop must implements one of the following interfaces : `PropelSearchLoopInterface`, `ArraySearchLoopInterface`' + ), + LoopException::SEARCH_INTERFACE_NOT_FOUND); } /* Only PropelSearch allows timestamp and version */ if (!$this instanceof PropelSearchLoopInterface) { if (true === $this->timestampable) { - throw new LoopException("Loop must implements 'PropelSearchLoopInterface' to be timestampable", LoopException::NOT_TIMESTAMPED); + throw new LoopException( + $this->translator->trans("Loop must implements 'PropelSearchLoopInterface' to be timestampable"), + LoopException::NOT_TIMESTAMPED); } + if (true === $this->versionable) { - throw new LoopException("Loop must implements 'PropelSearchLoopInterface' to be versionable", LoopException::NOT_VERSIONED); + throw new LoopException( + $this->translator->trans("Loop must implements 'PropelSearchLoopInterface' to be versionable"), + LoopException::NOT_VERSIONED); } } } @@ -441,15 +511,14 @@ abstract class BaseLoop abstract public function parseResults(LoopResult $loopResult); /** - * - * define all args used in your loop - * + * Definition of loop arguments * * example : * * public function getArgDefinitions() * { * return new ArgumentCollection( + * * Argument::createIntListTypeArgument('id'), * new Argument( * 'ref', @@ -459,14 +528,7 @@ abstract class BaseLoop * ), * Argument::createIntListTypeArgument('category'), * Argument::createBooleanTypeArgument('new'), - * Argument::createBooleanTypeArgument('promo'), - * Argument::createFloatTypeArgument('min_price'), - * Argument::createFloatTypeArgument('max_price'), - * Argument::createIntTypeArgument('min_stock'), - * Argument::createFloatTypeArgument('min_weight'), - * Argument::createFloatTypeArgument('max_weight'), - * Argument::createBooleanTypeArgument('current'), - * + * ... * ); * } * @@ -474,4 +536,4 @@ abstract class BaseLoop */ abstract protected function getArgDefinitions(); -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php index 40dd04330..3658f652b 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php @@ -12,16 +12,20 @@ namespace Thelia\Core\Template\Smarty\Plugins; +use Propel\Runtime\Util\PropelModelPager; use Symfony\Component\DependencyInjection\ContainerInterface; use Thelia\Core\Template\Element\BaseLoop; +use Thelia\Core\Template\Element\LoopResult; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; use Thelia\Core\Template\Element\Exception\ElementNotFoundException; use Thelia\Core\Template\Element\Exception\InvalidElementException; +use Thelia\Core\Translation\Translator; class TheliaLoop extends AbstractSmartyPlugin { + /** @var PropelModelPager[] */ protected static $pagination = null; protected $loopDefinition = array(); @@ -30,10 +34,15 @@ class TheliaLoop extends AbstractSmartyPlugin protected $dispatcher; protected $securityContext; + /** @var Translator */ + protected $translator; + /** @var ContainerInterface Service Container */ protected $container = null; + /** @var LoopResult[] */ protected $loopstack = array(); + protected $varstack = array(); /** @@ -46,31 +55,43 @@ class TheliaLoop extends AbstractSmartyPlugin $this->request = $container->get('request'); $this->dispatcher = $container->get('event_dispatcher'); $this->securityContext = $container->get('thelia.securityContext'); + $this->translator = $container->get("thelia.translator"); } /** - * @param $loopId - * - * @return \PropelModelPager + * @param string $loopName + * @return PropelModelPager + * @throws \InvalidArgumentException if no pagination was found for loop */ public static function getPagination($loopName) { if (array_key_exists($loopName, self::$pagination)) { return self::$pagination[$loopName]; } else { - throw new \InvalidArgumentException("Loop $loopName is not defined"); + throw new \InvalidArgumentException( + Translator::getInstance()->trans("No pagination currently defined for loop name '%name'", ['%name' => $loopName ]) + ); } } /** * Process the count function: executes a loop and return the number of items found + * + * @param array $params parameters array + * @param \Smarty_Internal_Template $template + * + * @return int the item count + * @throws \InvalidArgumentException if a parameter is missing + * */ - public function theliaCount($params, $template) + public function theliaCount($params, /** @noinspection PhpUnusedParameterInspection */ $template) { $type = $this->getParam($params, 'type'); if (null == $type) { - throw new \InvalidArgumentException("Missing 'type' parameter in count arguments"); + throw new \InvalidArgumentException( + $this->translator->trans("Missing 'type' parameter in {count} loop arguments") + ); } $loop = $this->createLoopInstance($params); @@ -83,31 +104,39 @@ class TheliaLoop extends AbstractSmartyPlugin /** * Process {loop name="loop name" type="loop type" ... } ... {/loop} block * - * @param unknown $params - * @param unknown $content - * @param unknown $template - * @param unknown $repeat + * @param array $params + * @param string $content + * @param \Smarty_Internal_Template $template + * @param boolean $repeat + * * @throws \InvalidArgumentException - * @return string + * + * @return void|string */ public function theliaLoop($params, $content, $template, &$repeat) { $name = $this->getParam($params, 'name'); if (null == $name) { - throw new \InvalidArgumentException("Missing 'name' parameter in loop arguments"); + throw new \InvalidArgumentException( + $this->translator->trans("Missing 'name' parameter in loop arguments") + ); } $type = $this->getParam($params, 'type'); if (null == $type) { - throw new \InvalidArgumentException("Missing 'type' parameter in loop arguments"); + throw new \InvalidArgumentException( + $this->translator->trans("Missing 'type' parameter in loop arguments") + ); } if ($content === null) { // Check if a loop with the same name exists in the current scope, and abort if it's the case. if (array_key_exists($name, $this->varstack)) { - throw new \InvalidArgumentException("A loop named '$name' already exists in the current scope."); + throw new \InvalidArgumentException( + $this->translator->trans("A loop named '%name' already exists in the current scope.", ['%name' => $name]) + ); } $loop = $this->createLoopInstance($params); @@ -120,7 +149,7 @@ class TheliaLoop extends AbstractSmartyPlugin $this->loopstack[$name] = $loopResults; - // Pas de résultat ? la boucle est terminée, ne pas évaluer le contenu. + // No results ? The loop is terminated, do not evaluate loop text. if ($loopResults->isEmpty()) $repeat = false; } else { @@ -173,52 +202,56 @@ class TheliaLoop extends AbstractSmartyPlugin return $content; } + + return ''; } /** * Process {elseloop rel="loopname"} ... {/elseloop} block * - * @param unknown $params - * @param unknown $content - * @param unknown $template - * @param unknown $repeat - * @return Ambigous + * @param array $params loop parameters + * @param string $content loop text content + * @param \Smarty_Internal_Template $template the Smarty object + * @param boolean $repeat repeat indicator (see Smarty doc.) + * @return string the loop output */ - public function theliaElseloop($params, $content, $template, &$repeat) + public function theliaElseloop($params, $content, /** @noinspection PhpUnusedParameterInspection */ $template, &$repeat) { - - // When encoutering close tag, check if loop has results. + // When encountering close tag, check if loop has results. if ($repeat === false) { - return $this->checkEmptyLoop($params, $template) ? $content : ''; + return $this->checkEmptyLoop($params) ? $content : ''; } + + return ''; } /** * Process {ifloop rel="loopname"} ... {/ifloop} block * - * @param unknown $params - * @param unknown $content - * @param unknown $template - * @param unknown $repeat - * @return Ambigous + * @param array $params loop parameters + * @param string $content loop text content + * @param \Smarty_Internal_Template $template the Smarty object + * @param boolean $repeat repeat indicator (see Smarty doc.) + * @return string the loop output */ - public function theliaIfLoop($params, $content, $template, &$repeat) + public function theliaIfLoop($params, $content, /** @noinspection PhpUnusedParameterInspection */ $template, &$repeat) { // When encountering close tag, check if loop has results. if ($repeat === false) { - return $this->checkEmptyLoop($params, $template) ? '' : $content; + return $this->checkEmptyLoop($params) ? '' : $content; } + + return ''; } /** * Process {pageloop rel="loopname"} ... {/pageloop} block * - * @param $params - * @param $content - * @param $template - * @param $repeat - * - * @return string + * @param array $params loop parameters + * @param string $content loop text content + * @param \Smarty_Internal_Template $template the Smarty object + * @param boolean $repeat repeat indicator (see Smarty doc.) + * @return string the loop output * @throws \InvalidArgumentException */ public function theliaPageLoop($params, $content, $template, &$repeat) @@ -226,73 +259,102 @@ class TheliaLoop extends AbstractSmartyPlugin $loopName = $this->getParam($params, 'rel'); if (null == $loopName) - throw new \InvalidArgumentException("Missing 'rel' parameter in page loop"); + throw new \InvalidArgumentException($this->translator->trans("Missing 'rel' parameter in page loop")); // Find pagination $pagination = self::getPagination($loopName); - if ($pagination === null) { // loop has no result + if ($pagination === null || $pagination->getNbResults() == 0) { + // No need to paginate return ''; } - if ($pagination->getNbResults() == 0) { - return ''; - } + $startPage = intval($this->getParam($params, 'start-page', 1)); + $displayedPageCount = intval($this->getParam($params, 'limit', 10)); - $nbPage = $this->getParam($params, 'numPage', 10); - $maxPage = $pagination->getLastPage(); + if (intval($displayedPageCount) == 0) $displayedPageCount = PHP_INT_MAX; + $totalPageCount = $pagination->getLastPage(); if ($content === null) { - $page = $pagination->getPage(); - if ($maxPage > ($page + $nbPage)) { - $end = $page + $nbPage; - } else { - $end = $maxPage; + + // The current page + $currentPage = $pagination->getPage(); + + // Get the start page. + if ($totalPageCount > $displayedPageCount) { + $startPage = $currentPage - round($displayedPageCount / 2); + + if ($startPage < 0) $startPage = 1; } - $template->assign('PREV', $page > 1 ? $page-1: $page); - $template->assign('NEXT', $page < $maxPage ? $page+1 : $maxPage); - $template->assign('END', $end); - $template->assign('LAST', $pagination->getLastPage()); + + // This is the iterative page number, the one we're going to increment in this loop + $iterationPage = $startPage; + + // The last displayed page number + $endPage = $startPage + $displayedPageCount - 1; + + if ($endPage > $totalPageCount) { + $endPage = $totalPageCount; + } + + // The first displayed page number + $template->assign('START' , $startPage); + // The previous page number + $template->assign('PREV' , $currentPage > 1 ? $currentPage-1 : $currentPage); + // The next page number + $template->assign('NEXT' , $currentPage < $totalPageCount ? $currentPage+1 : $totalPageCount); + // The last displayed page number + $template->assign('END' , $endPage); + // The overall last page + $template->assign('LAST' , $totalPageCount); } else { - $page = $template->getTemplateVars('PAGE'); - $page++; + $iterationPage = $template->getTemplateVars('PAGE'); + + $iterationPage++; } + if ($iterationPage <= $template->getTemplateVars('END')) { + // The iterative page number + $template->assign('PAGE', $iterationPage); - if ($page <= $template->getTemplateVars('END')) { - $template->assign('PAGE', $page); + // The overall current page number $template->assign('CURRENT', $pagination->getPage()); - $repeat = true; } if ($content !== null) { return $content; } + + return ''; } /** * Check if a loop has returned results. The loop shoud have been executed before, or an * InvalidArgumentException is thrown * - * @param unknown $params - * @param unknown $template + * @param array $params + * + * @return boolean true if the loop is empty * @throws \InvalidArgumentException */ - protected function checkEmptyLoop($params, $template) + protected function checkEmptyLoop($params) { $loopName = $this->getParam($params, 'rel'); if (null == $loopName) - throw new \InvalidArgumentException("Missing 'rel' parameter in ifloop/elseloop arguments"); + throw new \InvalidArgumentException( + $this->translator->trans("Missing 'rel' parameter in ifloop/elseloop arguments") + ); - if (! isset($this->loopstack[$loopName])) { - throw new \InvalidArgumentException("Loop $loopName is not defined."); - } + if (! isset($this->loopstack[$loopName])) + throw new \InvalidArgumentException( + $this->translator->trans("Related loop name '%name'' is not defined.", ['%name' => $loopName]) + ); return $this->loopstack[$loopName]->isEmpty(); } @@ -309,14 +371,16 @@ class TheliaLoop extends AbstractSmartyPlugin $type = strtolower($smartyParams['type']); if (! isset($this->loopDefinition[$type])) { - throw new ElementNotFoundException(sprintf("'%s' loop type does not exists", $type)); + throw new ElementNotFoundException( + $this->translator->trans("Loop type '%type' is not defined.", ['%type' => $type])); } $class = new \ReflectionClass($this->loopDefinition[$type]); if ($class->isSubclassOf("Thelia\Core\Template\Element\BaseLoop") === false) { - throw new InvalidElementException(sprintf("'%s' Loop class should extends Thelia\Core\Template\Element\BaseLoop", - $type)); + throw new InvalidElementException( + $this->translator->trans("'%type' loop class should extends Thelia\Core\Template\Element\BaseLoop", ['%type' => $type]) + ); } $loop = $class->newInstance( @@ -350,7 +414,12 @@ class TheliaLoop extends AbstractSmartyPlugin { foreach ($loopDefinition as $name => $className) { if (array_key_exists($name, $this->loopDefinition)) { - throw new \InvalidArgumentException(sprintf("%s loop name already exists for %s class name", $name, $className)); + throw new \InvalidArgumentException( + $this->translator->trans("The loop name '%name' is already defined in %className class", [ + '%name' => $name, + '%className' => $className + ]) + ); } $this->loopDefinition[$name] = $className; @@ -360,7 +429,7 @@ class TheliaLoop extends AbstractSmartyPlugin /** * Defines the various smarty plugins hendled by this class * - * @return an array of smarty plugin descriptors + * @return SmartyPluginDescriptor[] smarty plugin descriptors */ public function getPluginDescriptors() { diff --git a/templates/backOffice/default/configs/variables.conf b/templates/backOffice/default/configs/variables.conf index d80dba5f7..f41a1b61e 100644 --- a/templates/backOffice/default/configs/variables.conf +++ b/templates/backOffice/default/configs/variables.conf @@ -1,5 +1,6 @@ #order max_displayed_orders = 20 +max_displayed_customers = 20 #order status order_not_paid = 'warning' diff --git a/templates/backOffice/default/customers.html b/templates/backOffice/default/customers.html index 9a16031b0..ba59f4693 100644 --- a/templates/backOffice/default/customers.html +++ b/templates/backOffice/default/customers.html @@ -1,390 +1,368 @@ - -{extends file="admin-layout.tpl"} - -{block name="page-title"}{intl l='Customer'}{/block} - -{block name="check-resource"}admin.customer{/block} -{block name="check-access"}view{/block} - -{block name="main-content"} -
-
- - - - {module_include location='customer_top'} - -
-
-
- {if $removal_error } -
- - -
- {/if} -
- - - - {ifloop rel="customer_list"} - - - - - {module_include location='customer_list_header'} - - - - - - - - - - -{* TODO - - - -*} - - - - - - {loop name="customer_list" type="customer" current="false" visible="*" order=$customer_order backend_context="1" page=$page limit=$display_customer} - {assign "lastOrderDate" ''} - {assign "lastOrderAmount" ''} - {assign "lastOrderCurrency" ''} - - {loop type="order" name="last-order" customer=$ID order="create-date-reverse" limit="1"} - {assign "lastOrderDate" "{format_date date=$CREATE_DATE}"} - {assign "lastOrderAmount" "{format_number number=$TOTAL_TAXED_AMOUNT}"} - {loop type="currency" name="order-currency" id=$CURRENCY} - {assign "lastOrderCurrency" $SYMBOL} - {/loop} - {/loop} - - - - - - - - - - {module_include location='customer_list_row'} - - - - - - - - - - {/loop} - - - - - - - {/ifloop} -
- {intl l="Customers list"} - - {module_include location='customer_list_caption'} - - {loop type="auth" name="can_create" role="ADMIN" resource="admin.customer" access="CREATE"} - - - - {/loop} -
- {admin_sortable_header - current_order=$customer_order - order='reference' - reverse_order='reference_reverse' - path={url path='/admin/customers'} - request_parameter_name='customer_order' - label="{intl l='Reference'}" - } - - {admin_sortable_header - current_order=$customer_order - order='lastname' - reverse_order='lastname_reverse' - path={url path='/admin/customers'} - request_parameter_name='customer_order' - label="{intl l='Last name'}" - } - - {admin_sortable_header - current_order=$customer_order - order='firstname' - reverse_order='firstname_reverse' - path={url path='/admin/customers'} - request_parameter_name='customer_order' - label="{intl l='First name'}" - } - - {admin_sortable_header - current_order=$customer_order - order='registration_date' - reverse_order='registration_date_reverse' - path={url path='/admin/customers'} - request_parameter_name='customer_order' - label="{intl l='Registration date'}" - } - {intl l='Date of last order'}{intl l='Last order amount'} - {admin_sortable_header - current_order=$customer_order - order='last_order' - reverse_order='last_order_reverse' - path={url path='/admin/customers'} - request_parameter_name='customer_order' - label="{intl l='Date of last order'}" - } - - {admin_sortable_header - current_order=$customer_order - order='order_amount' - reverse_order='order_amount_reverse' - path={url path='/admin/customers'} - request_parameter_name='customer_order' - label="{intl l='Last order amount'}" - } - {intl l='Actions'}
{$REF} - {$LASTNAME} - - {$FIRSTNAME} - - {format_date date=$CREATE_DATE} - - {$lastOrderDate} - - {$lastOrderCurrency} {$lastOrderAmount} - -
- - {loop type="auth" name="can_change" role="ADMIN" resource="admin.customer" access="UPDATE"} - - {/loop} - {loop type="auth" name="can_send_mail" role="ADMIN" resource="admin.customer" access="VIEW"} - - {/loop} - {loop type="auth" name="can_delete" role="ADMIN" resource="admin.customer" access="DELETE"} - - {/loop} -
-
- -
-
    - - {if $page != 1} -
  • «
  • - {/if} - {pageloop rel="customer_list" numPage="20"} - {if $PAGE == $CURRENT && $PAGE > 2} -
  • - {/if} - - {if $PAGE != $CURRENT} -
  • {$PAGE}
  • - - {else} -
  • {$PAGE}
  • - {/if} - - {if $PAGE == $END && $PAGE < $LAST} -
  • - {/if} - {/pageloop} - {if $LAST > $CURRENT} -
  • »
  • - {/if} -
-
- -
-
-
-
-
- - - {module_include location='customer_bottom'} - - {* Adding a new Category *} - - - {form name="thelia.admin.customer.create"} - - {* Capture the dialog body, to pass it to the generic dialog *} - {capture "customer_creation_dialog"} - - {form_hidden_fields form=$form} - - {form_field form=$form field='success_url'} - {* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *} - - {/form_field} - - {form_field form=$form field="password"} - - {/form_field} - - {form_field form=$form field="password_confirm"} - - {/form_field} - - {form_field form=$form field="agreed"} - - {/form_field} - - {form_field form=$form field='company'} -
- - -
- {/form_field} - - {form_field form=$form field='title'} -
- - - -
- {/form_field} - - {form_field form=$form field='firstname'} -
- - -
- {/form_field} - - {form_field form=$form field='lastname'} -
- - -
- {/form_field} - - {form_field form=$form field='address1'} -
- - -
- -
- {form_field form=$form field='address2'} - - {/form_field} -
- -
- {form_field form=$form field='address3'} - - {/form_field} -
- {/form_field} - - {form_field form=$form field='zipcode'} -
- - -
- {/form_field} - - {form_field form=$form field='city'} -
- - -
- {/form_field} - - {form_field form=$form field='country'} -
- - -
- {/form_field} - - {form_field form=$form field='email'} -
- - -
- {/form_field} - - {module_include location='customer_create_form'} - - {/capture} - - {include - file = "includes/generic-create-dialog.html" - - dialog_id = "add_customer_dialog" - dialog_title = {intl l="Create a new customer"} - dialog_body = {$smarty.capture.customer_creation_dialog nofilter} - - dialog_ok_label = {intl l="Create this customer"} - dialog_cancel_label = {intl l="Cancel"} - - form_action = {url path='/admin/customer/create'} - form_enctype = {form_enctype form=$form} - form_error_message = $form_error_message - } - {/form} - - {* Delete confirmation dialog *} - - {capture "delete_customer_dialog"} - - - - {module_include location='customer_delete_form'} - {/capture} - - {include - file = "includes/generic-confirm-dialog.html" - - dialog_id = "delete_customer_dialog" - dialog_title = {intl l="Delete customer"} - dialog_message = {intl l="Do you really want to delete this customer ?"} - - form_action = {url path='/admin/customer/delete'} - form_content = {$smarty.capture.delete_customer_dialog nofilter} - form_id = "form_delete_customer" - } - -{/block} - -{block name="javascript-initialization"} - - - -{/block} - -{block name="javascript-last-call"} - {module_include location='customers-js'} + +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Customer'}{/block} + +{block name="check-resource"}admin.customer{/block} +{block name="check-access"}view{/block} + +{block name="main-content"} +
+
+ + + + {module_include location='customer_top'} + +
+
+
+ {if $removal_error } +
+ + +
+ {/if} +
+ + + + {ifloop rel="customer_list"} + + + + + {module_include location='customer_list_header'} + + + + + + + + + + +{* TODO + + + +*} + + + + + + {loop name="customer_list" type="customer" current="false" visible="*" order=$customer_order backend_context="1" page=$page limit=#max_displayed_customers#} + {assign "lastOrderDate" ''} + {assign "lastOrderAmount" ''} + {assign "lastOrderCurrency" ''} + + {loop type="order" name="last-order" customer=$ID order="create-date-reverse" limit="1"} + {assign "lastOrderDate" "{format_date date=$CREATE_DATE}"} + {assign "lastOrderAmount" "{format_number number=$TOTAL_TAXED_AMOUNT}"} + {loop type="currency" name="order-currency" id=$CURRENCY} + {assign "lastOrderCurrency" $SYMBOL} + {/loop} + {/loop} + + + + + + + + + + {module_include location='customer_list_row'} + + + + + + + + + + {/loop} + + + + + + + {/ifloop} +
+ {intl l="Customers list"} + + {module_include location='customer_list_caption'} + + {loop type="auth" name="can_create" role="ADMIN" resource="admin.customer" access="CREATE"} + + + + {/loop} +
+ {admin_sortable_header + current_order=$customer_order + order='reference' + reverse_order='reference_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Reference'}" + } + + {admin_sortable_header + current_order=$customer_order + order='lastname' + reverse_order='lastname_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Last name'}" + } + + {admin_sortable_header + current_order=$customer_order + order='firstname' + reverse_order='firstname_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='First name'}" + } + + {admin_sortable_header + current_order=$customer_order + order='registration_date' + reverse_order='registration_date_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Registration date'}" + } + {intl l='Date of last order'}{intl l='Last order amount'} + {admin_sortable_header + current_order=$customer_order + order='last_order' + reverse_order='last_order_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Date of last order'}" + } + + {admin_sortable_header + current_order=$customer_order + order='order_amount' + reverse_order='order_amount_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Last order amount'}" + } + {intl l='Actions'}
{$REF} + {$LASTNAME} + + {$FIRSTNAME} + + {format_date date=$CREATE_DATE} + + {$lastOrderDate} + + {$lastOrderCurrency} {$lastOrderAmount} + +
+ + {loop type="auth" name="can_change" role="ADMIN" resource="admin.customer" access="UPDATE"} + + {/loop} + {loop type="auth" name="can_send_mail" role="ADMIN" resource="admin.customer" access="VIEW"} + + {/loop} + {loop type="auth" name="can_delete" role="ADMIN" resource="admin.customer" access="DELETE"} + + {/loop} +
+
+ {include + file = "includes/pagination.html" + + loop_ref = "customer_list" + max_page_count = 10 + page_url = "{url path="/admin/customers" customer_order=$customer_order}" + } +
+
+
+
+
+ + + {module_include location='customer_bottom'} + + {* Adding a new Category *} + + + {form name="thelia.admin.customer.create"} + + {* Capture the dialog body, to pass it to the generic dialog *} + {capture "customer_creation_dialog"} + + {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + {* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *} + + {/form_field} + + {form_field form=$form field="password"} + + {/form_field} + + {form_field form=$form field="password_confirm"} + + {/form_field} + + {form_field form=$form field="agreed"} + + {/form_field} + + {form_field form=$form field='company'} +
+ + +
+ {/form_field} + + {form_field form=$form field='title'} +
+ + + +
+ {/form_field} + + {form_field form=$form field='firstname'} +
+ + +
+ {/form_field} + + {form_field form=$form field='lastname'} +
+ + +
+ {/form_field} + + {form_field form=$form field='address1'} +
+ + +
+ +
+ {form_field form=$form field='address2'} + + {/form_field} +
+ +
+ {form_field form=$form field='address3'} + + {/form_field} +
+ {/form_field} + + {form_field form=$form field='zipcode'} +
+ + +
+ {/form_field} + + {form_field form=$form field='city'} +
+ + +
+ {/form_field} + + {form_field form=$form field='country'} +
+ + +
+ {/form_field} + + {form_field form=$form field='email'} +
+ + +
+ {/form_field} + + {module_include location='customer_create_form'} + + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "add_customer_dialog" + dialog_title = {intl l="Create a new customer"} + dialog_body = {$smarty.capture.customer_creation_dialog nofilter} + + dialog_ok_label = {intl l="Create this customer"} + dialog_cancel_label = {intl l="Cancel"} + + form_action = {url path='/admin/customer/create'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } + {/form} + + {* Delete confirmation dialog *} + + {capture "delete_customer_dialog"} + + + + {module_include location='customer_delete_form'} + {/capture} + + {include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_customer_dialog" + dialog_title = {intl l="Delete customer"} + dialog_message = {intl l="Do you really want to delete this customer ?"} + + form_action = {url path='/admin/customer/delete'} + form_content = {$smarty.capture.delete_customer_dialog nofilter} + form_id = "form_delete_customer" + } + +{/block} + +{block name="javascript-initialization"} + + + +{/block} + +{block name="javascript-last-call"} + {module_include location='customers-js'} {/block} \ No newline at end of file diff --git a/templates/backOffice/default/orders.html b/templates/backOffice/default/orders.html index 75bc22861..5679b30e3 100644 --- a/templates/backOffice/default/orders.html +++ b/templates/backOffice/default/orders.html @@ -1,231 +1,211 @@ -{extends file="admin-layout.tpl"} - -{block name="page-title"}{intl l='Orders'}{/block} - -{block name="check-resource"}admin.order{/block} -{block name="check-access"}view{/block} - -{block name="main-content"} - {assign order_page {$smarty.get.page|default:1}} - {assign status_filter {$smarty.get.status|assertType:'IntListType'}} -
- -
- - - - {module_include location='orders_top'} - -
-
-
-
- - - - {ifloop rel="order-list"} - - - - - - - - - - - - - - - - - - {module_include location='orders_table_header'} - - - - - - - - {loop type="order" name="order-list" customer="*" order=$orders_order backend_context="1" page={$order_page} limit={#max_displayed_orders#} status=$status_filter|default:'*'} - - {loop type="currency" name="order-currency" id=$CURRENCY} - {$orderCurrency=$SYMBOL} - {/loop} - - {loop type="order_address" name="order-invoice-address" id=$INVOICE_ADDRESS} - {assign "orderInvoiceFirstName" $FIRSTNAME} - {assign "orderInvoiceLastName" $LASTNAME} - {assign "orderInvoiceCompany" $COMPANY} - {/loop} - - {loop type="order-status" name="order-status" id=$STATUS} - {assign "orderStatus" $TITLE} - {assign "orderStatusLabel" "order_$CODE"} - {/loop} - - - - - - - - - - - - {module_include location='orders_table_row'} - - - - - {/loop} - - - - - - - - - {/ifloop} - -
- {intl l='Orders'} -
- {admin_sortable_header - current_order=$orders_order - order='id' - reverse_order='id-reverse' - path={url path='/admin/orders'} - request_parameter_name='orders_order' - label="{intl l='ID'}" - } - {admin_sortable_header - current_order=$orders_order - order='reference' - reverse_order='reference-reverse' - path={url path='/admin/orders'} - request_parameter_name='orders_order' - label="{intl l='Reference'}" - } - {admin_sortable_header - current_order=$orders_order - order='create-date' - reverse_order='create-date-reverse' - path={url path='/admin/orders'} - request_parameter_name='orders_order' - label="{intl l='Date & Hour'}" - } - {admin_sortable_header - current_order=$orders_order - order='company' - reverse_order='company-reverse' - path={url path='/admin/orders'} - request_parameter_name='orders_order' - label="{intl l='Company'}" - } - {admin_sortable_header - current_order=$orders_order - order='customer-name' - reverse_order='customer-name-reverse' - path={url path='/admin/orders'} - request_parameter_name='orders_order' - label="{intl l='Cutomer Name'}" - } {intl l='Amount'} - {admin_sortable_header - current_order=$orders_order - order='status' - reverse_order='status-reverse' - path={url path='/admin/orders'} - request_parameter_name='orders_order' - label="{intl l='Status'}" - } {intl l="Actions"}
{$ID}{$REF}{format_date date=$CREATE_DATE}{$orderInvoiceCompany}{$orderInvoiceFirstName|ucwords} {$orderInvoiceLastName|upper}{format_money number=$TOTAL_TAXED_AMOUNT symbol=$orderCurrency}{$orderStatus} -
- - {loop type="auth" name="can_change" role="ADMIN" resource="admin.order" access="UPDATE"} - - {if $STATUS !== 5} - - {/if} - {/loop} -
-
- -
-
    - {if $order_page != 1} -
  • «
  • - {else} -
  • «
  • - {/if} - - {pageloop rel="order-list"} - {if $PAGE != $CURRENT} -
  • {$PAGE}
  • - - {else} -
  • {$PAGE}
  • - {/if} - - - {/pageloop} - {if $PAGE == $LAST && $LAST != $CURRENT} -
  • »
  • - {else} -
  • »
  • - {/if} -
-
- -
-
-
-
-
- - {module_include location='orders_bottom'} - -
-
- -{* Cancel order confirmation dialog *} - -{capture "cancel_order_dialog"} - - - -{/capture} - -{include - file = "includes/generic-confirm-dialog.html" - - dialog_id = "cancel_order_dialog" - dialog_title = {intl l="Delete an order"} - dialog_message = {intl l="Do you really want to cancel this order ?"} - - form_action = {url path='/admin/order/update/status'} - form_content = {$smarty.capture.cancel_order_dialog nofilter} - form_id = "cancel-order-form" -} - -{/block} - -{block name="javascript-initialization"} - - - -{/block} - -{block name="javascript-last-call"} - {module_include location='orders-js'} +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Orders'}{/block} + +{block name="check-resource"}admin.order{/block} +{block name="check-access"}view{/block} + +{block name="main-content"} + {assign order_page {$smarty.get.page|default:1}} + {assign status_filter {$smarty.get.status|assertType:'IntListType'}} +
+ +
+ + + + {module_include location='orders_top'} + +
+
+
+
+ + + + {ifloop rel="order-list"} + + + + + + + + + + + + + + + + + + {module_include location='orders_table_header'} + + + + + + + + {loop type="order" name="order-list" customer="*" order=$orders_order backend_context="1" page={$order_page} limit={#max_displayed_orders#} status=$status_filter|default:'*'} + + {loop type="currency" name="order-currency" id=$CURRENCY} + {$orderCurrency=$SYMBOL} + {/loop} + + {loop type="order_address" name="order-invoice-address" id=$INVOICE_ADDRESS} + {assign "orderInvoiceFirstName" $FIRSTNAME} + {assign "orderInvoiceLastName" $LASTNAME} + {assign "orderInvoiceCompany" $COMPANY} + {/loop} + + {loop type="order-status" name="order-status" id=$STATUS} + {assign "orderStatus" $TITLE} + {assign "orderStatusLabel" "order_$CODE"} + {/loop} + + + + + + + + + + + + {module_include location='orders_table_row'} + + + + + {/loop} + + + + + + + + + {/ifloop} + +
+ {intl l='Orders'} +
+ {admin_sortable_header + current_order=$orders_order + order='id' + reverse_order='id-reverse' + path={url path='/admin/orders'} + request_parameter_name='orders_order' + label="{intl l='ID'}" + } + {admin_sortable_header + current_order=$orders_order + order='reference' + reverse_order='reference-reverse' + path={url path='/admin/orders'} + request_parameter_name='orders_order' + label="{intl l='Reference'}" + } + {admin_sortable_header + current_order=$orders_order + order='create-date' + reverse_order='create-date-reverse' + path={url path='/admin/orders'} + request_parameter_name='orders_order' + label="{intl l='Date & Hour'}" + } + {admin_sortable_header + current_order=$orders_order + order='company' + reverse_order='company-reverse' + path={url path='/admin/orders'} + request_parameter_name='orders_order' + label="{intl l='Company'}" + } + {admin_sortable_header + current_order=$orders_order + order='customer-name' + reverse_order='customer-name-reverse' + path={url path='/admin/orders'} + request_parameter_name='orders_order' + label="{intl l='Cutomer Name'}" + } {intl l='Amount'} + {admin_sortable_header + current_order=$orders_order + order='status' + reverse_order='status-reverse' + path={url path='/admin/orders'} + request_parameter_name='orders_order' + label="{intl l='Status'}" + } {intl l="Actions"}
{$ID}{$REF}{format_date date=$CREATE_DATE}{$orderInvoiceCompany}{$orderInvoiceFirstName|ucwords} {$orderInvoiceLastName|upper}{format_money number=$TOTAL_TAXED_AMOUNT symbol=$orderCurrency}{$orderStatus} +
+ + {loop type="auth" name="can_change" role="ADMIN" resource="admin.order" access="UPDATE"} + + {if $STATUS !== 5} + + {/if} + {/loop} +
+
+ {include + file = "includes/pagination.html" + + loop_ref = "order-list" + max_page_count = 10 + page_url = "{url path="/admin/orders" orders_order=$orders_order}" + } +
+
+
+
+
+ + {module_include location='orders_bottom'} + +
+
+ +{* Cancel order confirmation dialog *} + +{capture "cancel_order_dialog"} + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "cancel_order_dialog" + dialog_title = {intl l="Delete an order"} + dialog_message = {intl l="Do you really want to cancel this order ?"} + + form_action = {url path='/admin/order/update/status'} + form_content = {$smarty.capture.cancel_order_dialog nofilter} + form_id = "cancel-order-form" +} + +{/block} + +{block name="javascript-initialization"} + + + +{/block} + +{block name="javascript-last-call"} + {module_include location='orders-js'} {/block} \ No newline at end of file