diff --git a/Controller/TaskController.php b/Controller/TaskController.php
index decb68944..91094c480 100644
--- a/Controller/TaskController.php
+++ b/Controller/TaskController.php
@@ -9,29 +9,68 @@ use Chill\PersonBundle\Entity\Person;
use Chill\TaskBundle\Entity\SingleTask;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
+use Chill\TaskBundle\Repository\SingleTaskRepository;
+use Symfony\Component\HttpFoundation\Response;
class TaskController extends Controller
{
/**
- * @Route("/{_locale}/task/task/list/{personId}")
+ * @Route(
+ * "/{_locale}/task/task/list/{personId}",
+ * name="chill_task_task_list"
+ * )
*/
public function listAction(Request $request, Person $personId)
{
$person = $personId;
- $em = $this->getDoctrine()
- ->getManager();
- // collect parameters for filter
- $params = [];
+ /* @var $taskRepository SingleTaskRepository */
+ $taskRepository = $this->get('chill_task.single_task_repository');
+ /* @var $paginatorFactory \Chill\MainBundle\Pagination\PaginatorFactory */
+ $paginatorFactory = $this->get('chill_main.paginator_factory');
+ /* @var $viewParams array The parameters for the view */
+ $viewParams['person'] = $person;
+ // collect parameters for filter
$params['person'] = $person;
- $singleTasks = $this->get('chill_task.single_task_repository')
- ->findByParameters($params, $this->getUser());
+ if ($request->query->has('date_status')) {
+ $statuses = $request->query->get('date_status');
+ $singleStatus = count($statuses) === 1;
+ // check for invalid parameters
+ $diff = \array_diff(
+ $statuses,
+ SingleTaskRepository::DATE_STATUSES)
+ ;
+
+ if (count($diff) > 0) {
+ return new Response(
+ 'date_status not allowed: '. \implode(', ', $diff),
+ Response::HTTP_BAD_REQUEST
+ );
+ }
+ }
+
+ foreach(SingleTaskRepository::DATE_STATUSES as $type) {
+ if($request->query->has('date_status')
+ && FALSE === \in_array($type, $statuses ?? [])) {
+ continue;
+ }
+
+ $params['date_status'] = $type;
+ $count = $taskRepository
+ ->countByParameters($params, $this->getUser())
+ ;
+ $paginator = $paginatorFactory->create($count);
+ $viewParams['single_task_'.$type.'_count'] = $count;
+ $viewParams['single_task_'.$type.'_paginator'] = $paginator;
+ $viewParams['single_task_'.$type.'_tasks'] = $taskRepository
+ ->findByParameters($params, $this->getUser(),
+ $singleStatus ? $paginator->getCurrentPage()->getFirstItemNumber() : 0,
+ $singleStatus ? $paginator->getItemsPerPage() : 10)
+ ;
+ }
- return $this->render('ChillTaskBundle:Task:index.html.twig', [
- 'single_tasks' => $singleTasks,
- 'person' => $person
- ]);
+ return $this->render('ChillTaskBundle:Task:index.html.twig', $viewParams);
}
protected function getPersonParam(Request $request, EntityManagerInterface $em)
diff --git a/Repository/SingleTaskRepository.php b/Repository/SingleTaskRepository.php
index 26583bd8f..67a26fcf6 100644
--- a/Repository/SingleTaskRepository.php
+++ b/Repository/SingleTaskRepository.php
@@ -7,12 +7,26 @@ use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Role\Role;
use Chill\TaskBundle\Security\Authorization\TaskVoter;
+use Doctrine\DBAL\Types\Type;
/**
* SingleTaskRepository
*/
class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
{
+
+ const DATE_STATUS_ENDED = 'ended';
+ const DATE_STATUS_WARNING = 'warning';
+ const DATE_STATUS_CURRENT = 'current';
+ const DATE_STATUS_NOT_STARTED = 'not_started';
+
+ const DATE_STATUSES = [
+ self::DATE_STATUS_ENDED,
+ self::DATE_STATUS_WARNING,
+ self::DATE_STATUS_CURRENT,
+ self::DATE_STATUS_NOT_STARTED
+ ];
+
/**
*
* @var AuthorizationHelper
@@ -24,6 +38,42 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
$this->authorizationHelper = $authorizationHelper;
}
+ /**
+ * Count the tasks for given parameters.
+ *
+ * The parameters are describe in @see SingleTaskRepository::filterByParameters.
+ *
+ * @see SingleTaskRepository::filterByParameters
+ * @param array $params
+ * @param User $currentUser
+ * @return int
+ */
+ public function countByParameters($params, User $currentUser)
+ {
+ $qb = $this->createQueryBuilder('st')
+ ->select('COUNT(st)');
+
+ $this->buildQuery($qb, $params, $currentUser);
+
+ return (int) $qb
+ ->getQuery()
+ ->getSingleScalarResult()
+ ;
+ }
+
+ /**
+ * Find task for given parameters.
+ *
+ * Available parameters:
+ *
+ * - `person` : filter by person associated with the task ;
+ * - `date_status`: type of task. To choose between :
+ * `ended`, `warning`, `current`, `not_started`
+ *
+ * @param type $params
+ * @param User $currentUser
+ * @return type
+ */
public function findByParameters($params, User $currentUser)
{
$qb = $this->createQueryBuilder('st');
@@ -44,8 +94,110 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
$qb->andWhere($qb->expr()->eq('st.person', ':person'));
$qb->setParameter('person', $params['person']);
}
+
+ if (\array_key_exists('date_status', $params)) {
+ $this->addTypeFilter($qb, $params);
+ }
}
+ protected function addTypeFilter(QueryBuilder $qb, $params)
+ {
+ $andWhere = $qb->expr()->andX();
+
+ switch ($params['date_status']) {
+ case self::DATE_STATUS_ENDED:
+ $andWhere->add($this->buildNowIsAfterEndDate($qb));
+ break;
+
+ case self::DATE_STATUS_WARNING:
+ $andWhere
+ ->add($this->buildNowIsAfterEndDate($qb, true))
+ ->add($this->buildNowIsAfterWarningDate($qb))
+ ;
+ break;
+
+ case self::DATE_STATUS_CURRENT:
+ // st.endDate is NULL or (st.endDate is not null and st.endDate < now))
+ $andWhere
+ ->add($this->buildNowIsAfterEndDate($qb, true))
+ ->add($this->buildNowIsAfterWarningDate($qb, true))
+ ->add($this->buildNowIsAfterStartDate($qb, false))
+ ;
+ break;
+
+ case self::DATE_STATUS_NOT_STARTED:
+ $andWhere
+ ->add($this->buildNowIsAfterEndDate($qb, true))
+ ->add($this->buildNowIsAfterWarningDate($qb, true))
+ ->add($this->buildNowIsAfterStartDate($qb, true))
+ ;
+ }
+ $qb->setParameter('now', new \DateTime('today'), Type::DATE);
+ $qb->andWhere($andWhere);
+ }
+
+ private function buildNowIsAfterEndDate(QueryBuilder $qb, $negative = false)
+ {
+ if ($negative === false) {
+ return $qb->expr()->andX()
+ ->add($qb->expr()->isNotNull('st.endDate'))
+ ->add($qb->expr()->lt('st.endDate', ':now'))
+ ;
+ } else {
+ return $qb->expr()->orX()
+ ->add(
+ $qb->expr()->andX()
+ ->add($qb->expr()->isNotNull('st.endDate'))
+ ->add($qb->expr()->gt('st.endDate', ':now'))
+ )
+ ->add($qb->expr()->isNull('st.endDate'))
+ ;
+ }
+ }
+
+ private function buildNowIsAfterWarningDate(QueryBuilder $qb, $negative = false)
+ {
+ if ($negative === false) {
+ return $qb->expr()->andX()
+ ->add($qb->expr()->lt(
+ $qb->expr()->diff('st.endDate', 'st.warningInterval'), ':now'
+ )
+ );
+ } else {
+ return $qb->expr()->orX()
+ ->add(
+ $qb->expr()->andX()
+ ->add($qb->expr()->isNotNull('st.endDate'))
+ ->add($qb->expr()->isNotNull('st.warningInterval'))
+ ->add($qb->expr()->gt(
+ $qb->expr()->diff('st.endDate', 'st.warningInterval'),
+ ':now'
+ )
+ )
+ )
+ ->add($qb->expr()->isNull('st.endDate'))
+ ->add($qb->expr()->isNull('st.warningInterval'))
+ ;
+ }
+ }
+
+ private function buildNowIsAfterStartDate(QueryBuilder $qb, $negative = false)
+ {
+ if ($negative === false) {
+ return $qb->expr()->orX()
+ ->add($qb->expr()->lt('st.startDate', ':now'))
+ ->add($qb->expr()->isNull('st.startDate'))
+ ;
+ } else {
+ return
+ $qb->expr()->andX()
+ ->add($qb->expr()->gt('st.startDate', ':now'))
+ ->add($qb->expr()->isNotNull('st.startDate'))
+ ;
+ }
+ }
+
+
protected function buildACLQuery(QueryBuilder $qb, User $currentUser)
{
if (NULL === $this->authorizationHelper) {
diff --git a/Resources/views/Task/index.html.twig b/Resources/views/Task/index.html.twig
index c5de9e688..e379ea44d 100644
--- a/Resources/views/Task/index.html.twig
+++ b/Resources/views/Task/index.html.twig
@@ -21,85 +21,70 @@
{% block title %}{{ 'Task list'|trans }}{% endblock %}
{% macro thead() %}
-
-
-
-
+
{% endmacro %}
{% macro row(task) %}
- {{ 'Title'|trans }}
- {{ 'Task type'|trans }}
- {{ 'Task status'|trans }}
- {{ 'Task start date'|trans }}
- {{ 'Task warning date'|trans }}
- {{ 'Task end date'|trans }}
-
{{ 'Title'|trans }} | +{{ 'Task type'|trans }} | +{{ 'Task status'|trans }} | +{{ 'Task start date'|trans }} | +{{ 'Task warning date'|trans }} | +{{ 'Task end date'|trans }} | +
---|---|---|---|---|---|
{{ task.title }} | +{{ task.type }} | +todo | +{% if task.startDate is not null %}{{ task.startDate|localizeddate('medium', 'none') }}{% endif %} | +{% if task.warningDate is not null %}{{ task.warningDate|localizeddate('medium', 'none') }}{% endif %} | +{% if task.endDate is not null %}{{ task.endDate|localizeddate('medium', 'none') }}{% endif %} | +