mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
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
This commit is contained in:
parent
d251074430
commit
eadaeaef35
@ -298,39 +298,42 @@ class SingleTaskController extends Controller
|
|||||||
$viewParams['person'] = $person;
|
$viewParams['person'] = $person;
|
||||||
// collect parameters for filter
|
// collect parameters for filter
|
||||||
$params['person'] = $person;
|
$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 statuses
|
||||||
// check for invalid parameters
|
$diff = \array_diff($statuses, $possibleStatuses);
|
||||||
$diff = \array_diff(
|
if (count($diff) > 0) {
|
||||||
$statuses,
|
return new Response(
|
||||||
SingleTaskRepository::DATE_STATUSES)
|
'date_status not allowed: '. \implode(', ', $diff),
|
||||||
;
|
Response::HTTP_BAD_REQUEST
|
||||||
|
);
|
||||||
if (count($diff) > 0) {
|
|
||||||
return new Response(
|
|
||||||
'date_status not allowed: '. \implode(', ', $diff),
|
|
||||||
Response::HTTP_BAD_REQUEST
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$viewParams['isSingleStatus'] = $singleStatus = count($statuses) === 1;
|
$viewParams['isSingleStatus'] = $singleStatus = count($statuses) === 1;
|
||||||
|
|
||||||
foreach(SingleTaskRepository::DATE_STATUSES as $type) {
|
foreach($statuses as $status) {
|
||||||
if($request->query->has('date_status')
|
if($request->query->has('status')
|
||||||
&& FALSE === \in_array($type, $statuses ?? [])) {
|
&& FALSE === \in_array($status, $statuses)) {
|
||||||
continue;
|
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
|
$count = $taskRepository
|
||||||
->countByParameters($params, $this->getUser())
|
->countByParameters($params, $this->getUser())
|
||||||
;
|
;
|
||||||
$paginator = $paginatorFactory->create($count);
|
$paginator = $paginatorFactory->create($count);
|
||||||
$viewParams['single_task_'.$type.'_count'] = $count;
|
$viewParams['single_task_'.$status.'_count'] = $count;
|
||||||
$viewParams['single_task_'.$type.'_paginator'] = $paginator;
|
$viewParams['single_task_'.$status.'_paginator'] = $paginator;
|
||||||
$viewParams['single_task_'.$type.'_tasks'] = $taskRepository
|
$viewParams['single_task_'.$status.'_tasks'] = $taskRepository
|
||||||
->findByParameters($params, $this->getUser(),
|
->findByParameters($params, $this->getUser(),
|
||||||
$singleStatus ? $paginator->getCurrentPage()->getFirstItemNumber() : 0,
|
$singleStatus ? $paginator->getCurrentPage()->getFirstItemNumber() : 0,
|
||||||
$singleStatus ? $paginator->getItemsPerPage() : 10)
|
$singleStatus ? $paginator->getItemsPerPage() : 10)
|
||||||
|
@ -71,10 +71,10 @@ class TaskController extends Controller
|
|||||||
|
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
$this->addFlash('success', 'The transition is sucessfully applyed');
|
$this->addFlash('success', 'The transition is sucessfully appliyed');
|
||||||
|
|
||||||
} else {
|
} 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));
|
return $this->redirect($request->query->get('return_path', $defaultReturnPath));
|
||||||
|
@ -39,8 +39,17 @@ class TaskWorkflowDefinitionCompilerPass implements CompilerPassInterface
|
|||||||
$workflowManagerDefinition = $container->getDefinition(TaskWorkflowManager::class);
|
$workflowManagerDefinition = $container->getDefinition(TaskWorkflowManager::class);
|
||||||
|
|
||||||
foreach ($container->findTaggedServiceIds('chill_task.workflow_definition') as $id => $tags) {
|
foreach ($container->findTaggedServiceIds('chill_task.workflow_definition') as $id => $tags) {
|
||||||
|
// registering the definition to manager
|
||||||
$workflowManagerDefinition
|
$workflowManagerDefinition
|
||||||
->addMethodCall('addDefinition', [new Reference($id)]);
|
->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
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,12 @@ abstract class AbstractTask implements HasScopeInterface, HasCenterInterface
|
|||||||
* @Assert\NotNull()
|
* @Assert\NotNull()
|
||||||
*/
|
*/
|
||||||
private $circle;
|
private $circle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var boolean
|
||||||
|
* @ORM\Column(name="closed", type="boolean", options={ "default"=false })
|
||||||
|
*/
|
||||||
|
private $closed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set type
|
* Set type
|
||||||
@ -229,6 +235,21 @@ abstract class AbstractTask implements HasScopeInterface, HasCenterInterface
|
|||||||
return $this->getCircle();
|
return $this->getCircle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isClosed(): bool
|
||||||
|
{
|
||||||
|
return $this->closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param bool $closed
|
||||||
|
*/
|
||||||
|
public function setClosed(bool $closed)
|
||||||
|
{
|
||||||
|
$this->closed = $closed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,8 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
|
|||||||
* - `person` : filter by person associated with the task ;
|
* - `person` : filter by person associated with the task ;
|
||||||
* - `date_status`: type of task. To choose between :
|
* - `date_status`: type of task. To choose between :
|
||||||
* `ended`, `warning`, `current`, `not_started`
|
* `ended`, `warning`, `current`, `not_started`
|
||||||
|
* - `is_closed`: boolean. Indicate if the tasks must be closed (true) or
|
||||||
|
* opened
|
||||||
*
|
*
|
||||||
* @param type $params
|
* @param type $params
|
||||||
* @param User $currentUser
|
* @param User $currentUser
|
||||||
@ -90,14 +92,18 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
|
|||||||
{
|
{
|
||||||
$this->buildACLQuery($qb, $currentUser);
|
$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->andWhere($qb->expr()->eq('st.person', ':person'));
|
||||||
$qb->setParameter('person', $params['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);
|
$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)
|
protected function addTypeFilter(QueryBuilder $qb, $params)
|
||||||
@ -106,7 +112,9 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
|
|||||||
|
|
||||||
switch ($params['date_status']) {
|
switch ($params['date_status']) {
|
||||||
case self::DATE_STATUS_ENDED:
|
case self::DATE_STATUS_ENDED:
|
||||||
$andWhere->add($this->buildNowIsAfterEndDate($qb));
|
$andWhere
|
||||||
|
->add($this->buildNowIsAfterEndDate($qb))
|
||||||
|
;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case self::DATE_STATUS_WARNING:
|
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) {
|
if ($negative === false) {
|
||||||
return $qb->expr()->andX()
|
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) {
|
if ($negative === false) {
|
||||||
return $qb->expr()->orX()
|
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)
|
protected function buildACLQuery(QueryBuilder $qb, User $currentUser)
|
||||||
{
|
{
|
||||||
|
28
Resources/migrations/Version20180426093011.php
Normal file
28
Resources/migrations/Version20180426093011.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Application\Migrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a column 'closed' on tasks
|
||||||
|
*/
|
||||||
|
class Version20180426093011 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function up(Schema $schema)
|
||||||
|
{
|
||||||
|
$this->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');
|
||||||
|
}
|
||||||
|
}
|
@ -100,7 +100,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ path('chill_task_task_list_by_person', {'personId': person.id, 'date_status' : [ status ] }) }}" class="sc-button bt-cancel">
|
<a href="{{ path('chill_task_task_list_by_person', {'personId': person.id, 'status' : [ status ] }) }}" class="sc-button bt-cancel">
|
||||||
{{ 'See more' | trans }}
|
{{ 'See more' | trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -132,6 +132,10 @@
|
|||||||
{% if single_task_not_started_tasks is defined %}
|
{% if single_task_not_started_tasks is defined %}
|
||||||
{{ helper.date_status('Tasks not started', single_task_not_started_tasks, single_task_not_started_count, single_task_not_started_paginator, 'not_started', isSingleStatus, person) }}
|
{{ helper.date_status('Tasks not started', single_task_not_started_tasks, single_task_not_started_count, single_task_not_started_paginator, 'not_started', isSingleStatus, person) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if single_task_closed_tasks is defined %}
|
||||||
|
{{ helper.date_status('Closed', single_task_closed_tasks, single_task_closed_count, single_task_closed_paginator, 'closed', isSingleStatus, person) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if isSingleStatus == false %}
|
{% if isSingleStatus == false %}
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
|
@ -53,7 +53,7 @@ class DefaultTaskDefinition implements \Chill\TaskBundle\Workflow\TaskWorkflowDe
|
|||||||
&& $task->getType() === 'task_default';
|
&& $task->getType() === 'task_default';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAssociatedWorkflowName()
|
public static function getAssociatedWorkflowName()
|
||||||
{
|
{
|
||||||
return 'task_default';
|
return 'task_default';
|
||||||
}
|
}
|
||||||
@ -89,4 +89,10 @@ class DefaultTaskDefinition implements \Chill\TaskBundle\Workflow\TaskWorkflowDe
|
|||||||
|
|
||||||
return self::TRANSITION_METADATA[$transition->getName()][$key];
|
return self::TRANSITION_METADATA[$transition->getName()][$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isClosed(AbstractTask $task)
|
||||||
|
{
|
||||||
|
return \array_key_exists('closed', $task->getCurrentStates())
|
||||||
|
|| \array_key_exists('canceled', $task->getCurrentStates());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ namespace Chill\TaskBundle\Workflow;
|
|||||||
use Chill\TaskBundle\Entity\AbstractTask;
|
use Chill\TaskBundle\Entity\AbstractTask;
|
||||||
use Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface;
|
use Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface;
|
||||||
use Symfony\Component\Workflow\Workflow;
|
use Symfony\Component\Workflow\Workflow;
|
||||||
|
use Symfony\Component\Workflow\Event\Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -80,4 +81,15 @@ class TaskWorkflowManager implements SupportStrategyInterface
|
|||||||
return $this->getTaskWorkflowDefinition($task)
|
return $this->getTaskWorkflowDefinition($task)
|
||||||
->getWorkflowMetadata($key, $metadataSubject);
|
->getWorkflowMetadata($key, $metadataSubject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onTaskStateEntered(Event $e)
|
||||||
|
{
|
||||||
|
$task = $e->getSubject();
|
||||||
|
|
||||||
|
$definition = $this->getTaskWorkflowDefinition($task);
|
||||||
|
|
||||||
|
$task->setClosed($definition->isClosed($task));
|
||||||
|
|
||||||
|
dump($task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user