From 0f68b6938363bba3829dbd3de1c493d9bef3e254 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Tue, 16 Feb 2021 14:11:21 +0100 Subject: [PATCH] NEW option to automatically close an open project when all its tasks are done (=progress 100%) --- htdocs/langs/en_US/projects.lang | 2 ++ htdocs/langs/fr_FR/projects.lang | 2 ++ htdocs/projet/admin/project.php | 16 +++++++++++++++ htdocs/projet/class/task.class.php | 32 +++++++++++++++++++++++++----- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 279bf99d162..3fbcbb0dca7 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -269,3 +269,5 @@ OneLinePerPeriod=One line per period RefTaskParent=Ref. Parent Task ProfitIsCalculatedWith=Profit is calculated using AddPersonToTask=Add also to tasks +PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE=Classify project as closed when all its tasks are completed (100%% progress) +PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Note: existing projects with all tasks at 100 %% progress won't be affected: you will have to close them manually. This option only affects open projects. diff --git a/htdocs/langs/fr_FR/projects.lang b/htdocs/langs/fr_FR/projects.lang index 1affdad0889..a963bffe13d 100644 --- a/htdocs/langs/fr_FR/projects.lang +++ b/htdocs/langs/fr_FR/projects.lang @@ -268,3 +268,5 @@ OneLinePerTask=Une ligne par tâche OneLinePerPeriod=Une ligne par période RefTaskParent=Réf. Tâche parent ProfitIsCalculatedWith=Le bénéfice est calculé sur la base de +PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE=Classer le projet à clôturé lorsque toutes les tâches de ce projet sont à 100 %% de progression +PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Non rétroactif : l’activation de cette option ne clôturera pas les projets dont les tâches sont déjà à 100 %%. Cette option ne classe que les projets ouverts. diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php index f36aae34c4f..45e62eafbe9 100644 --- a/htdocs/projet/admin/project.php +++ b/htdocs/projet/admin/project.php @@ -244,6 +244,12 @@ elseif ($action == 'setdoc') } } +// Set boolean (on/off) constants +elseif (preg_match('/^(set|del)_?([A-Z_]+)$/', $action, $reg)) { + if (!dolibarr_set_const($db, $reg[2], ($reg[1] === 'set' ? '1' : '0'), 'chaine', 0, '', $conf->entity) > 0) { + dol_print_error($db); + } +} /* * View @@ -840,6 +846,16 @@ print $form->textwithpicto('', $langs->trans('AllowToLinkFromOtherCompany')); print ''; print ''; +$key = 'PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE'; +echo '', + '', + $form->textwithpicto($langs->transnoentities($key), $langs->transnoentities($key . '_help')), + '', + '', + ajax_constantonoff($key), + '', + ''; + print ''; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index b4733de05ae..a2e670906ca 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -383,13 +383,35 @@ class Task extends CommonObject // Update extrafield if (!$error) { - if (!$error) + $result = $this->insertExtraFields(); + if ($result < 0) { - $result = $this->insertExtraFields(); - if ($result < 0) - { - $error++; + $error++; + } + } + + if (!$error && $conf->global->PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE) { + // Close the parent project if it is open (validated) and its tasks are 100% completed + $project = new Project($this->db); + if ($project->fetch($this->fk_project) > 0 && $project->statut == Project::STATUS_VALIDATED) { + $project->getLinesArray(null); // this method does not return <= 0 if fails + $projectCompleted = array_reduce( + $project->lines, + function ($allTasksCompleted, $task) { + return $allTasksCompleted && $task->progress >= 100; + }, + 1 + ); + if ($projectCompleted) { + if ($project->setClose($user) <= 0) { + $error++; + } } + } else { + $error++; + } + if ($error) { + $this->errors[] = $project->error; } }