Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix update ticket status when ticket task is de-scheduled #16895

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion src/CommonITILObject.php
Expand Up @@ -3519,7 +3519,7 @@ public static function isAllowedStatus($old, $new)
if (
array_key_exists(
static::STATUS_MATRIX_FIELD,
$_SESSION['glpiactiveprofile']
$_SESSION['glpiactiveprofile'] ?? []
)
&& static::isStatusExists($new)
) { // maybe not set for post-only
Expand Down
26 changes: 1 addition & 25 deletions src/CommonITILTask.php
Expand Up @@ -441,31 +441,7 @@ public function post_updateItem($history = true)
if (!$this->input['_job']->getFromDB($this->fields[$this->input['_job']->getForeignKeyField()])) {
return false;
}
if (
isset($this->input['_status'])
&& ($this->input['_status'] != $this->input['_job']->fields['status'])
) {
$update = [
'status' => $this->input['_status'],
'id' => $this->input['_job']->fields['id'],
'_disablenotif' => true,
];
$this->input['_job']->update($update);
}

if (
!empty($this->fields['begin'])
&& $item->isStatusExists(CommonITILObject::PLANNED)
&& (($item->fields["status"] == CommonITILObject::INCOMING)
|| ($item->fields["status"] == CommonITILObject::ASSIGNED))
) {
$input2 = [
'id' => $item->getID(),
'status' => CommonITILObject::PLANNED,
'_disablenotif' => true,
];
$item->update($input2);
}
$this->updateParentStatus($this->input['_job'], $this->input);

if (!isset($this->input['_disablenotif']) && $CFG_GLPI["use_notifications"]) {
$options = ['task_id' => $this->fields["id"],
Expand Down
47 changes: 38 additions & 9 deletions src/Features/ParentStatus.php
Expand Up @@ -164,15 +164,44 @@ public function updateParentStatus(CommonITILObject $parentitem, array $input):
}
}

if (
!$is_set_pending
&& !empty($this->fields['begin'])
&& $parentitem->isStatusExists(CommonITILObject::PLANNED)
&& (($parentitem->fields["status"] == CommonITILObject::INCOMING)
|| ($parentitem->fields["status"] == CommonITILObject::ASSIGNED)
|| $needupdateparent)
) {
$input['_status'] = CommonITILObject::PLANNED;
if (!$is_set_pending) {
if (
!empty($this->fields['begin'])
&& $parentitem->isStatusExists(CommonITILObject::PLANNED)
&& (($parentitem->fields["status"] == CommonITILObject::INCOMING)
|| ($parentitem->fields["status"] == CommonITILObject::ASSIGNED)
|| $needupdateparent)
) {
$input['_status'] = CommonITILObject::PLANNED;
} elseif ($parentitem->fields["status"] == CommonITILObject::PLANNED) {
RomainLvr marked this conversation as resolved.
Show resolved Hide resolved
/** @var \DBmysql $DB */
global $DB;
$criteria = [
'DISTINCT' => true,
'FROM' => $this->getTable(),
'WHERE' => [
$parentitem->getForeignKeyField() => $parentitem->getID(),
['NOT' => ['begin' => null]]
],
];
$iterator = $DB->request($criteria);
if ($iterator->numrows() > 0) {
$input['_status'] = CommonITILObject::PLANNED;
} elseif (
$parentitem::isAllowedStatus($parentitem->fields["status"], CommonITILObject::ASSIGNED)
&& (
($parentitem->countUsers(CommonITILActor::ASSIGN) > 0)
|| ($parentitem->countGroups(CommonITILActor::ASSIGN) > 0)
|| ($parentitem->countSuppliers(CommonITILActor::ASSIGN) > 0)
)
) {
$input['_status'] = CommonITILObject::ASSIGNED;
} elseif (
$parentitem::isAllowedStatus($parentitem->fields["status"], CommonITILObject::INCOMING)
) {
$input['_status'] = CommonITILObject::INCOMING;
}
}
}

//change ITILObject status only if input change
Expand Down
100 changes: 100 additions & 0 deletions tests/functional/TicketTask.php
Expand Up @@ -36,6 +36,7 @@
namespace tests\units;

use DbTestCase;
use Toolbox;

/* Test for inc/tickettask.class.php */

Expand Down Expand Up @@ -402,6 +403,105 @@ public function testAddFromTemplate()
$this->integer($task->fields['is_private'])->isEqualTo(0);
}

/**
* Test that the ticket status is correctly updated when the task is scheduled and then unscheduled.
*
* @return void
*/
public function testDePlanifiedUpdateParentStatus()
{
$this->login();
$ticket_id = $this->getNewTicket();
$task = new \TicketTask();

$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');

$task_id = $task->add([
'pending' => 0,
'tickets_id' => $ticket_id,
'content' => "Planned Task",
'state' => \Planning::TODO,
'users_id_tech' => $uid,
'begin' => $date_begin_string,
'end' => $date_end_string,
]);
$this->integer($task_id)->isGreaterThan(0);

$this->integer(\Ticket::getById($ticket_id)->fields['status'])->isEqualTo(\Ticket::PLANNED);

$this->boolean($task->update([
'id' => $task_id,
'tickets_id' => $ticket_id,
'content' => "De-planned Task",
'begin' => null,
'end' => null,
]))->isTrue();

$this->integer(\Ticket::getById($ticket_id)->fields['status'])->isEqualTo(\Ticket::ASSIGNED);

$this->boolean($task->update([
'id' => $task_id,
'tickets_id' => $ticket_id,
'content' => "Planned Task",
'begin' => $date_begin_string,
'end' => $date_end_string,
]))->isTrue();



$this->integer(\Ticket::getById($ticket_id)->fields['status'])->isEqualTo(\Ticket::PLANNED);

$ticket = new \Ticket();
$ticket_users = new \Ticket_User();

// remove assigned user from ticket
$this->boolean($ticket_users->deleteByCriteria([
'tickets_id' => $ticket_id,
'type' => \CommonITILActor::ASSIGN,
]))->isTrue();

$this->boolean($ticket->getFromDB($ticket_id))->isTrue();

$this->integer($ticket->countUsers(\CommonITILActor::ASSIGN))->isEqualTo(0);

$this->integer(\Ticket::getById($ticket_id)->fields['status'])->isEqualTo(\Ticket::INCOMING);

$this->boolean($task->update([
'id' => $task_id,
'tickets_id' => $ticket_id,
'content' => "De-planned Task",
'begin' => null,
'end' => null,
]))->isTrue();

$this->integer(\Ticket::getById($ticket_id)->fields['status'])->isEqualTo(\Ticket::INCOMING);

$this->boolean($task->update([
'id' => $task_id,
'tickets_id' => $ticket_id,
'content' => "Planned Task",
'begin' => $date_begin_string,
'end' => $date_end_string,
]))->isTrue();

$this->integer(\Ticket::getById($ticket_id)->fields['status'])->isEqualTo(\Ticket::PLANNED);

$this->boolean($task->update([
'id' => $task_id,
'tickets_id' => $ticket_id,
'content' => "De-planned Task",
'begin' => null,
'end' => null,
]))->isTrue();

$this->integer(\Ticket::getById($ticket_id)->fields['status'])->isEqualTo(\Ticket::INCOMING);
}

public function testUpdateParentStatus()
{
$this->login();
Expand Down