Skip to content

Commit

Permalink
fix(formanswer): status update on ticket change
Browse files Browse the repository at this point in the history
  • Loading branch information
btry committed Sep 25, 2023
1 parent 6af1766 commit 079a120
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 128 deletions.
1 change: 0 additions & 1 deletion hook.php
Expand Up @@ -489,7 +489,6 @@ function plugin_formcreator_hook_update_ticket(CommonDBTM $item) {
'requester_id' => $requester,
'comment' => addslashes($item->fields['content']),
]);
return;
}

// No issue linked to the ticket,
Expand Down
85 changes: 43 additions & 42 deletions inc/formanswer.class.php
Expand Up @@ -1945,76 +1945,77 @@ public function getGeneratedTargets($itemtypes = []): array {
}

/**
* Get the lowest status among the associated tickets
* Get the most appropriate status among the associated tickets
*
* Conversion matrix between the temporary status of the form answer
* and the status of the ticket under process. The matrix below is subjective
* and is designed in a way to give priority to requester's action.
*
* Status of the ticket under process
* +----------+-- -------+---------+---------+--------+--------+
* | INCOMING | ASSIGNED | PLANNED | WAITING | SOLVED | CLOSED
* + ---------+----------+----------+---------+---------+--------+--------+
* | (null) | INCOMING ASSIGNED PLANNED WAITING SOLVED CLOSED
* S | INCOMING | INCOMING ASSIGNED PLANNED WAITING INCOMING INCOMING
* T t | ASSIGNED | ASSIGNED ASSIGNED PLANNED WAITING ASSIGNED ASSIGNED
* e a | PLANNED | PLANNED PLANNED PLANNED WAITING PLANNED PLANNED
* m t | WAITING | WAITING WAITING WAITING WAITING WAITING WAITING
* p u | SOLVED | INCOMING ASSIGNED PLANNED WAITING SOLVED SOLVED
* s | CLOSED | INCOMING ASSIGNED PLANNED WAITING SOLVED CLOSED
*
* T = status picked from Ticket
* V = status picked from Validation
*
* @return null|int
*/
public function getAggregatedStatus(): ?int {
$generatedTargets = $this->getGeneratedTargets([PluginFormcreatorTargetTicket::getType()]);

$isWaiting = false;
$isAssigned = false;
$isProcessing = false;

// Find the minimal status of the first generated tickets in the array (deleted items excluded)
$generatedTarget = array_shift($generatedTargets);
while ($generatedTarget!== null && $generatedTarget->fields['is_deleted']) {
$generatedTarget = array_shift($generatedTargets);
}
if ($generatedTarget === null) {
if (count($generatedTargets) === 0) {
// No target found, nothing to do
return null;
}

// Find status of the first ticket in the array
$aggregatedStatus = PluginFormcreatorCommon::getTicketStatusForIssue($generatedTarget);
if ($aggregatedStatus == CommonITILObject::ASSIGNED) {
$isAssigned = true;
}
if ($aggregatedStatus == CommonITILObject::PLANNED) {
$isProcessing = true;
}
if ($aggregatedStatus == CommonITILObject::WAITING) {
$isWaiting = true;
}
$aggregatedStatus = null;

// Traverse all other tickets and set the minimal status
// Traverse all tickets and set the minimal status
foreach ($generatedTargets as $generatedTarget) {
/** @var Ticket $generatedTarget */
if ($generatedTarget::getType() != Ticket::getType()) {
continue;
}
if ($generatedTarget->isDeleted()) {
// Ignore deleted tickets
continue;
}
$ticketStatus = PluginFormcreatorCommon::getTicketStatusForIssue($generatedTarget);
if ($ticketStatus >= PluginFormcreatorFormAnswer::STATUS_WAITING) {
// Ignore tickets refused or pending for validation
// getTicketStatusForIssue() does not returns STATUS_ACCEPTED
continue;
}

if ($ticketStatus == CommonITILObject::ASSIGNED) {
$isAssigned = true;
if ($ticketStatus == CommonITILObject::WAITING) {
$aggregatedStatus = CommonITILObject::WAITING;
break;
}
if ($ticketStatus == CommonITILObject::PLANNED) {
$isProcessing = true;
$aggregatedStatus = CommonITILObject::PLANNED;
continue;
}
if ($ticketStatus == CommonITILObject::WAITING) {
$isWaiting = true;
if ($ticketStatus == CommonITILObject::ASSIGNED) {
$aggregatedStatus = CommonITILObject::ASSIGNED;
continue;
}
if ($ticketStatus == CommonITILObject::INCOMING) {
$aggregatedStatus = CommonITILObject::INCOMING;
continue;
}
if ($aggregatedStatus === null) {
$aggregatedStatus = $ticketStatus;
continue;
}
$aggregatedStatus = min($aggregatedStatus, $ticketStatus);
}

// Assigned status takes precedence
if ($isAssigned) {
$aggregatedStatus = CommonITILObject::ASSIGNED;
}
// Planned status takes precedence
if ($isProcessing) {
$aggregatedStatus = CommonITILObject::PLANNED;
}
// Waiting status takes precedence to inform the requester his feedback is required
if ($isWaiting) {
$aggregatedStatus = CommonITILObject::WAITING;
$aggregatedStatus = min($aggregatedStatus, $ticketStatus);
}

return $aggregatedStatus;
Expand Down
17 changes: 2 additions & 15 deletions tests/3-unit/PluginFormcreatorFormAnswer.php
Expand Up @@ -69,6 +69,7 @@ public function beforeTestMethod($method) {
case 'testGetTargets':
case 'testGetGeneratedTargets':
case 'testGetAggregatedStatus':
case 'testStatus':
$this->login('glpi', 'glpi');
}
}
Expand Down Expand Up @@ -613,20 +614,6 @@ public function testGetTargets() {
]);
}

public function testUpdateStatus() {
global $CFG_GLPI;

$CFG_GLPI['use_notifications'] = 0;

// Prepare test context
$form = $this->getForm();

$formAnswer = $this->newTestedInstance();
$formAnswer->add([
'plugin_formcreator_forms_id' => $form->getID(),
]);
}

public function testGetGeneratedTargets() {
$form = $this->getForm();
$targets = [];
Expand Down Expand Up @@ -720,7 +707,7 @@ public function testGetAggregatedStatus() {
'status' => CommonITILObject::INCOMING,
]);
$output = $instance->getAggregatedStatus();
$this->integer($output)->isEqualTo(CommonITILObject::ASSIGNED);
$this->integer($output)->isEqualTo(CommonITILObject::INCOMING);

$tickets[0]->update([
'id' => $tickets[0]->getID(),
Expand Down
61 changes: 14 additions & 47 deletions tests/3-unit/PluginFormcreatorIssue.php
Expand Up @@ -32,6 +32,9 @@
namespace tests\units;
use GlpiPlugin\Formcreator\Tests\CommonTestCase;
use PluginFormcreatorFormAnswer;
use PluginFormcreatorTargetTicket;
use PluginFormcreatorTarget_Actor;
use CommonITILActor;
use RuleAction;
use User;
use Rule;
Expand Down Expand Up @@ -153,7 +156,7 @@ public function providerGetsyncIssuesRequest_simpleFormanswers() {
public function providerGetSyncIssuesRequest_formAnswerWithOneTicket() {
// case 1
$form = $this->getForm();
$targetTicket1 = new \PluginFormcreatorTargetTicket();
$targetTicket1 = new PluginFormcreatorTargetTicket();
$targetTicket1->add([
'plugin_formcreator_forms_id' => $form->getID(),
'name' => 'foo',
Expand Down Expand Up @@ -207,7 +210,7 @@ public function providerGetSyncIssuesRequest_formAnswerWithOneTicket() {
$this->boolean($formAnswer->isNewItem())->isFalse();
$formAnswer->getFromDB($formAnswer->getID());
$ticket2 = array_shift($formAnswer->targetList);
$this->object($ticket)->isInstanceOf(Ticket::getType());
$this->object($ticket2)->isInstanceOf(Ticket::getType());

return [
'formAnswerWithOneTicket' => [
Expand Down Expand Up @@ -241,13 +244,13 @@ public function providerGetSyncIssuesRequest_formAnswerWithOneTicket() {

public function providerGetSyncIssuesRequest_formAnswerWithSeveralTickets() {
$form = $this->getForm();
$targetTicket1 = new \PluginFormcreatorTargetTicket();
$targetTicket1 = new PluginFormcreatorTargetTicket();
$targetTicket1->add([
'plugin_formcreator_forms_id' => $form->getID(),
'name' => 'foo',
]);
$this->boolean($targetTicket1->isNewItem())->isFalse();
$targetTicket2 = new \PluginFormcreatorTargetTicket();
$targetTicket2 = new PluginFormcreatorTargetTicket();
$targetTicket2->add([
'plugin_formcreator_forms_id' => $form->getID(),
'name' => 'bar',
Expand Down Expand Up @@ -277,42 +280,6 @@ public function providerGetSyncIssuesRequest_formAnswerWithSeveralTickets() {
];
}

public function providerGetSyncIssuesRequest_formAnswerWithOneTickets() {
$form = $this->getForm();
$targetTicket1 = new \PluginFormcreatorTargetTicket();
$targetTicket1->add([
'plugin_formcreator_forms_id' => $form->getID(),
'name' => 'foo',
]);
$this->boolean($targetTicket1->isNewItem())->isFalse();

$formAnswer = new PluginFormcreatorFormAnswer();
$formAnswer->add([
'plugin_formcreator_forms_id' => $form->getID(),
]);
$this->boolean($formAnswer->isNewItem())->isFalse();
$formAnswer->getFromDB($formAnswer->getID());

/** @var Ticket */
$ticket = array_pop($formAnswer->targetList);
$this->object($ticket)->isInstanceOf(Ticket::class);
return [
'formAnswerWithOneTickets' => [
'item' => $formAnswer,
'expected' => [
'itemtype' => PluginFormcreatorFormAnswer::getType(),
'items_id' => $ticket->getID(),
'display_id' => 't_' . $ticket->getID(),
'name' => $formAnswer->fields['name'],
'status' => $formAnswer->fields['status'],
'requester_id' => $formAnswer->fields['requester_id'],
'date_creation' => $formAnswer->fields['request_date'],
'date_mod' => $formAnswer->fields['request_date'],
],
],
];
}

public function providerGetSyncIssuesRequest_formanswerUnderValidation() {
$form = $this->getForm([
'validation_required' => PluginFormcreatorForm::VALIDATION_USER,
Expand Down Expand Up @@ -466,29 +433,29 @@ public function providerGetsyncIssuesRequest_validatedTicket() {

public function providerGetSyncIssuesRequest_FormAnswerWithSeveralRequesters() {
$form = $this->getForm();
$targetTicket1 = new \PluginFormcreatorTargetTicket();
$targetTicket1 = new PluginFormcreatorTargetTicket();
$targetTicket1->add([
'plugin_formcreator_forms_id' => $form->getID(),
'name' => 'foo',
]);
$this->boolean($targetTicket1->isNewItem())->isFalse();

$actor1 = new \PluginFormcreatorTarget_Actor();
$actor1 = new PluginFormcreatorTarget_Actor();
$actor1->add([
'itemtype' => $targetTicket1->getType(),
'items_id' => $targetTicket1->getID(),
'actor_role' => \PluginFormcreatorTarget_Actor::ACTOR_TYPE_PERSON,
'actor_type' => \CommonITILActor::REQUESTER,
'actor_role' => PluginFormcreatorTarget_Actor::ACTOR_TYPE_PERSON,
'actor_type' => CommonITILActor::REQUESTER,
'actor_value' => 3,
'use_notification' => '1',
]);
$this->boolean($actor1->isNewItem())->isFalse();
$actor2 = new \PluginFormcreatorTarget_Actor();
$actor2 = new PluginFormcreatorTarget_Actor();
$actor2->add([
'itemtype' => $targetTicket1->getType(),
'items_id' => $targetTicket1->getID(),
'actor_role' => \PluginFormcreatorTarget_Actor::ACTOR_TYPE_PERSON,
'actor_type' => \CommonITILActor::REQUESTER,
'actor_role' => PluginFormcreatorTarget_Actor::ACTOR_TYPE_PERSON,
'actor_type' => CommonITILActor::REQUESTER,
'actor_value' => 5,
'use_notification' => '1',
]);
Expand Down

0 comments on commit 079a120

Please sign in to comment.