From eadaeaef35ddf2f7cf1ac767f99e1b7ff2054d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 26 Apr 2018 12:11:06 +0200 Subject: [PATCH] add closed tasks - the entity has a new column / property "closed" (boolean) - An event listener in created during container compilation, which listen on tasks status changed - The taskworkflow manager and task workflow definition indicate if the tasks is closed ; - Add list for closed tasks in controller, and change parameter 'date_status' to 'status'; - and change query to allow to filter on closed tasks --- Controller/SingleTaskController.php | 45 ++++++++++--------- Controller/TaskController.php | 4 +- .../TaskWorkflowDefinitionCompilerPass.php | 9 ++++ Entity/AbstractTask.php | 23 +++++++++- Repository/SingleTaskRepository.php | 27 ++++++++--- .../migrations/Version20180426093011.php | 28 ++++++++++++ Resources/views/Task/index.html.twig | 6 ++- Workflow/Definition/DefaultTaskDefinition.php | 8 +++- Workflow/TaskWorkflowManager.php | 12 +++++ 9 files changed, 131 insertions(+), 31 deletions(-) create mode 100644 Resources/migrations/Version20180426093011.php diff --git a/Controller/SingleTaskController.php b/Controller/SingleTaskController.php index 521647546..a887b0b01 100644 --- a/Controller/SingleTaskController.php +++ b/Controller/SingleTaskController.php @@ -298,39 +298,42 @@ class SingleTaskController extends Controller $viewParams['person'] = $person; // collect parameters for filter $params['person'] = $person; - $statuses = $request->query->get('date_status', []); + $possibleStatuses = \array_merge(SingleTaskRepository::DATE_STATUSES, [ 'closed' ]); + $statuses = $request->query->get('status', $possibleStatuses); - if ($statuses) { - // 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 - ); - } + // check for invalid statuses + $diff = \array_diff($statuses, $possibleStatuses); + if (count($diff) > 0) { + return new Response( + 'date_status not allowed: '. \implode(', ', $diff), + Response::HTTP_BAD_REQUEST + ); } $viewParams['isSingleStatus'] = $singleStatus = count($statuses) === 1; - foreach(SingleTaskRepository::DATE_STATUSES as $type) { - if($request->query->has('date_status') - && FALSE === \in_array($type, $statuses ?? [])) { + foreach($statuses as $status) { + if($request->query->has('status') + && FALSE === \in_array($status, $statuses)) { continue; } - $params['date_status'] = $type; + // different query if regarding to date or 'closed' + if (in_array($status, SingleTaskRepository::DATE_STATUSES)) { + $params['date_status'] = $status; + $params['is_closed'] = false; + } else { + $params['date_status'] = null; + $params['is_closed'] = true; + } + $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 + $viewParams['single_task_'.$status.'_count'] = $count; + $viewParams['single_task_'.$status.'_paginator'] = $paginator; + $viewParams['single_task_'.$status.'_tasks'] = $taskRepository ->findByParameters($params, $this->getUser(), $singleStatus ? $paginator->getCurrentPage()->getFirstItemNumber() : 0, $singleStatus ? $paginator->getItemsPerPage() : 10) diff --git a/Controller/TaskController.php b/Controller/TaskController.php index 94e356941..d90ddf08c 100644 --- a/Controller/TaskController.php +++ b/Controller/TaskController.php @@ -71,10 +71,10 @@ class TaskController extends Controller $em->flush(); - $this->addFlash('success', 'The transition is sucessfully applyed'); + $this->addFlash('success', 'The transition is sucessfully appliyed'); } else { - $this->addFlash('error', 'The transition could not be applyed'); + $this->addFlash('error', 'The transition could not be appliyed'); } return $this->redirect($request->query->get('return_path', $defaultReturnPath)); diff --git a/DependencyInjection/Compiler/TaskWorkflowDefinitionCompilerPass.php b/DependencyInjection/Compiler/TaskWorkflowDefinitionCompilerPass.php index d52e5484d..fb1a9e2aa 100644 --- a/DependencyInjection/Compiler/TaskWorkflowDefinitionCompilerPass.php +++ b/DependencyInjection/Compiler/TaskWorkflowDefinitionCompilerPass.php @@ -39,8 +39,17 @@ class TaskWorkflowDefinitionCompilerPass implements CompilerPassInterface $workflowManagerDefinition = $container->getDefinition(TaskWorkflowManager::class); foreach ($container->findTaggedServiceIds('chill_task.workflow_definition') as $id => $tags) { + // registering the definition to manager $workflowManagerDefinition ->addMethodCall('addDefinition', [new Reference($id)]); + // adding a listener for currentStatus changes + $definition = $container->getDefinition($id); + $workflowManagerDefinition + ->addTag('kernel.event_listener', [ + 'event' => sprintf('workflow.%s.entered', $definition->getClass()::getAssociatedWorkflowName()), + 'method' => 'onTaskStateEntered', + 'priority' => -255 + ]); } } } diff --git a/Entity/AbstractTask.php b/Entity/AbstractTask.php index d9d59c7b6..401891e12 100644 --- a/Entity/AbstractTask.php +++ b/Entity/AbstractTask.php @@ -80,6 +80,12 @@ abstract class AbstractTask implements HasScopeInterface, HasCenterInterface * @Assert\NotNull() */ private $circle; + + /** + * @var boolean + * @ORM\Column(name="closed", type="boolean", options={ "default"=false }) + */ + private $closed = false; /** * Set type @@ -229,6 +235,21 @@ abstract class AbstractTask implements HasScopeInterface, HasCenterInterface return $this->getCircle(); } - + /** + * @return bool + */ + public function isClosed(): bool + { + return $this->closed; + } + + /** + * + * @param bool $closed + */ + public function setClosed(bool $closed) + { + $this->closed = $closed; + } } diff --git a/Repository/SingleTaskRepository.php b/Repository/SingleTaskRepository.php index 67a26fcf6..648484e87 100644 --- a/Repository/SingleTaskRepository.php +++ b/Repository/SingleTaskRepository.php @@ -69,6 +69,8 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository * - `person` : filter by person associated with the task ; * - `date_status`: type of task. To choose between : * `ended`, `warning`, `current`, `not_started` + * - `is_closed`: boolean. Indicate if the tasks must be closed (true) or + * opened * * @param type $params * @param User $currentUser @@ -90,14 +92,18 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository { $this->buildACLQuery($qb, $currentUser); - if (\array_key_exists('person', $params)) { + if (\array_key_exists('person', $params) and !empty($params['person'])) { $qb->andWhere($qb->expr()->eq('st.person', ':person')); $qb->setParameter('person', $params['person']); } - if (\array_key_exists('date_status', $params)) { + if (\array_key_exists('date_status', $params) and !empty($params['date_status'])) { $this->addTypeFilter($qb, $params); } + + if (\array_key_exists('is_closed', $params)) { + $qb->andWhere($this->buildIsClosed($qb, !$params['is_closed'])); + } } protected function addTypeFilter(QueryBuilder $qb, $params) @@ -106,7 +112,9 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository switch ($params['date_status']) { case self::DATE_STATUS_ENDED: - $andWhere->add($this->buildNowIsAfterEndDate($qb)); + $andWhere + ->add($this->buildNowIsAfterEndDate($qb)) + ; break; case self::DATE_STATUS_WARNING: @@ -155,7 +163,7 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository } } - private function buildNowIsAfterWarningDate(QueryBuilder $qb, $negative = false) + private function buildNowIsAfterWarningDate(QueryBuilder $qb, bool $negative = false) { if ($negative === false) { return $qb->expr()->andX() @@ -181,7 +189,7 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository } } - private function buildNowIsAfterStartDate(QueryBuilder $qb, $negative = false) + private function buildNowIsAfterStartDate(QueryBuilder $qb, bool $negative = false) { if ($negative === false) { return $qb->expr()->orX() @@ -197,6 +205,15 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository } } + private function buildIsClosed(QueryBuilder $qb, bool $negative = false) + { + if ($negative === false) { + return $qb->expr()->eq('st.closed', "'TRUE'"); + } else { + return $qb->expr()->eq('st.closed', "'FALSE'"); + } + } + protected function buildACLQuery(QueryBuilder $qb, User $currentUser) { diff --git a/Resources/migrations/Version20180426093011.php b/Resources/migrations/Version20180426093011.php new file mode 100644 index 000000000..286d4e3d1 --- /dev/null +++ b/Resources/migrations/Version20180426093011.php @@ -0,0 +1,28 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('ALTER TABLE chill_task.single_task ADD closed BOOLEAN DEFAULT \'false\' NOT NULL'); + $this->addSql('ALTER TABLE chill_task.recurring_task ADD closed BOOLEAN DEFAULT \'false\' NOT NULL'); + } + + public function down(Schema $schema) + { + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('ALTER TABLE chill_task.recurring_task DROP closed'); + $this->addSql('ALTER TABLE chill_task.single_task DROP closed'); + } +} diff --git a/Resources/views/Task/index.html.twig b/Resources/views/Task/index.html.twig index e37535395..dbeae6786 100644 --- a/Resources/views/Task/index.html.twig +++ b/Resources/views/Task/index.html.twig @@ -100,7 +100,7 @@ {% else %}