From ff969cb16b86f2f75e7c350d36db231298f878c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Cailly?= <42278610+ccailly@users.noreply.github.com> Date: Tue, 31 Oct 2023 11:14:20 +0100 Subject: [PATCH] Fix Task Duration Update Behavior in CommonITILTask fixes #15650 --- src/CommonITILTask.php | 29 +++++++++++++- tests/functional/TicketTask.php | 70 +++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/CommonITILTask.php b/src/CommonITILTask.php index af31276a81f..8ac45d04f4f 100644 --- a/src/CommonITILTask.php +++ b/src/CommonITILTask.php @@ -266,6 +266,29 @@ public function post_deleteFromDB() } } + /** + * Handle the task duration and planned duration logic. + * + * This function ensures a bi-directional link between the task duration and the planned duration. + * These two fields can be a bit redundant when task planning is enabled. + * + * @param array $input The input array, passed by reference. + * @param int $timestart The start time of the task. + * @param int $timeend The end time of the task. + * @return void + */ + private function handleTaskDuration(array &$input, int $timestart, int $timeend): void + { + // If 'actiontime' is set and different from the current 'actiontime' + if (isset($input['actiontime']) && $this->fields['actiontime'] != $input['actiontime']) { + // Compute the end date based on 'actiontime' + $input["end"] = date("Y-m-d H:i:s", $timestart + $input['actiontime']); + } else { + // If 'actiontime' is not set, compute it based on the start and end times + $input["actiontime"] = $timeend - $timestart; + } + } + public function prepareInputForUpdate($input) { @@ -309,7 +332,8 @@ public function prepareInputForUpdate($input) $timestart = strtotime($input["begin"]); $timeend = strtotime($input["end"]); - $input["actiontime"] = $timeend - $timestart; + + $this->handleTaskDuration($input, $timestart, $timeend); unset($input["plan"]); @@ -523,7 +547,8 @@ public function prepareInputForAdd($input) $timestart = strtotime($input["begin"]); $timeend = strtotime($input["end"]); - $input["actiontime"] = $timeend - $timestart; + + $this->handleTaskDuration($input, $timestart, $timeend); unset($input["plan"]); if (!$this->test_valid_date($input)) { diff --git a/tests/functional/TicketTask.php b/tests/functional/TicketTask.php index ebbe1ea0f2f..3c6c7ea01bf 100644 --- a/tests/functional/TicketTask.php +++ b/tests/functional/TicketTask.php @@ -465,4 +465,74 @@ public function testUpdateParentStatus() $this->integer(\Ticket::getById($ticket_id)->fields['status'])->isEqualTo(\Ticket::WAITING); } + + /** + * Test that the task duration is correctly updated + * + * @return void + */ + public function testTaskDurationUpdate() + { + $this->login(); + $ticketId = $this->getNewTicket(); + $uid = getItemByTypeName('User', TU_USER, true); + + $date_begin = new \DateTime(); // ==> now + $date_begin_string = $date_begin->format('Y-m-d H:i:s'); + + $date_end = new \DateTime(); // ==> +2days + $date_end->add(new \DateInterval('P2D')); + $date_end_string = $date_end->format('Y-m-d H:i:s'); + + // Create task with actiontime and without schedule + $task = new \TicketTask(); + $task_id = $task->add([ + 'state' => \Planning::TODO, + 'tickets_id' => $ticketId, + 'tasktemplates_id' => '0', + 'taskcategories_id' => '0', + 'content' => "Task with schedule and recall", + 'users_id_tech' => $uid, + 'actiontime' => 3600, + ]); + $this->integer($task_id)->isGreaterThan(0); + + // Check that the task duration is correctly updated + $this->integer($task->fields['actiontime'])->isEqualTo(3600); + $this->variable($task->fields['begin'])->isEqualTo(null); + $this->variable($task->fields['end'])->isEqualTo(null); + + // Schedule the task + $this->boolean($task->update([ + 'id' => $task_id, + 'tickets_id' => $ticketId, + 'users_id_tech' => $uid, + 'plan' => [ + 'begin' => $date_begin_string, + 'end' => $date_end_string, + ] + ]))->isTrue(); + + // Check that the task duration is correctly updated + $this->integer($task->fields['actiontime'])->isEqualTo(172800); + $this->string($task->fields['begin'])->isEqualTo($date_begin_string); + $this->string($task->fields['end'])->isEqualTo($date_end_string); + + // Update the task duration with actiontime + $this->boolean($task->update([ + 'id' => $task_id, + 'tickets_id' => $ticketId, + 'users_id_tech' => $uid, + 'actiontime' => 7200, + 'plan' => [ + 'begin' => $date_begin_string, + 'end' => $date_end_string, + ] + ]))->isTrue(); + + // Check that the task duration is correctly updated + $this->integer($task->fields['actiontime'])->isEqualTo(7200); + $this->string($task->fields['begin'])->isEqualTo($date_begin_string); + $this->string($task->fields['end'])->isEqualTo($date_begin->add(new \DateInterval('PT2H'))->format('Y-m-d H:i:s')); + } }