Skip to content

Commit

Permalink
fix(issue): sync issue fails when a ticket has several validators
Browse files Browse the repository at this point in the history
if a ticket has several validators, the sync issue fails to recreate the row
the HAVING COUNT() clause finds 2 rows instead of 1
The solution is to drop the user and group validators and find them dynamically with JOIN.
this also allows to find all ticket validators
  • Loading branch information
btry committed Oct 27, 2022
1 parent 1f526d8 commit 3f51fbd
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 65 deletions.
50 changes: 33 additions & 17 deletions hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ function plugin_formcreator_addDefaultJoin($itemtype, $ref_table, &$already_link
$join .= PluginAdvformCommon::addDefaultJoin($itemtype, $ref_table, $already_link_tables);
} else {
$issueSo = Search::getOptions($itemtype);
$join .= Search::addLeftJoin(
$itemtype,
$ref_table,
$already_link_tables,
$issueSo[9]['table'],
'users_id_validator',
0,
0,
$issueSo[9]['joinparams']
);
$join .= Search::addLeftJoin(
$itemtype,
$ref_table,
Expand All @@ -108,7 +118,16 @@ function plugin_formcreator_addDefaultJoin($itemtype, $ref_table, &$already_link
0,
$issueSo[11]['joinparams']
);

$join .= Search::addLeftJoin(
$itemtype,
$ref_table,
$already_link_tables,
$issueSo[16]['table'],
'groups_id_validator',
0,
0,
$issueSo[16]['joinparams']
);
}
break;

Expand Down Expand Up @@ -145,12 +164,11 @@ function plugin_formcreator_addDefaultWhere($itemtype) {
$condition .= ' OR ';
}
// condition where current user is a validator of the issue
if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {
$complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[9]['joinparams']);
$condition .= "`glpi_users_$complexJoinId`.`id` = '$currentUser'";
} else {
$condition .= "`glpi_plugin_formcreator_issues`.`users_id_validator` = '$currentUser'";
}
// Search optin ID 9 is either from Formcreator, either from AdvForms
$issueSearchOptions = Search::getOptions($itemtype);
$complexJoinId = Search::computeComplexJoinID($issueSearchOptions[9]['joinparams']);
$colname = $issueSearchOptions[9]['linkfield'];
$condition .= "`glpi_users_${colname}_$complexJoinId`.`id` = '$currentUser'";

// condition where current user is a member of a validator group of the issue
$groupList = [];
Expand All @@ -159,16 +177,14 @@ function plugin_formcreator_addDefaultWhere($itemtype) {
}
if (count($groupList) > 0) {
$groupList = implode("', '", $groupList);
if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {
$complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[9]['joinparams']);
$condition .= " OR `glpi_groups_$complexJoinId`.`id` IN ('$groupList')";
} else {
$condition .= " OR `glpi_plugin_formcreator_issues`.`groups_id_validator` IN ('$groupList')";
}
// Search option ID 16 is either from Formcreator, either from AdvForms
$complexJoinId = Search::computeComplexJoinID($issueSearchOptions[16]['joinparams']);
$colname = $issueSearchOptions[16]['linkfield'];
$condition .= " OR `glpi_groups_${colname}_$complexJoinId`.`id` IN ('$groupList')";
}

// condition where current user is a validator of a issue of type ticket
$complexJoinId = Search::computeComplexJoinID(Search::getOptions($itemtype)[11]['joinparams']);
$complexJoinId = Search::computeComplexJoinID($issueSearchOptions[11]['joinparams']);
$condition .= " OR `glpi_users_users_id_validate_$complexJoinId`.`id` = '$currentUser'";
// Add users_id_recipient
$condition .= " OR `glpi_plugin_formcreator_issues`.`users_id_recipient` = $currentUser ";
Expand Down Expand Up @@ -368,7 +384,7 @@ function plugin_formcreator_hook_add_ticket(CommonDBTM $item) {
'name' => $issueName,
'display_id' => 't_' . $item->getID(),
'items_id' => $item->getID(),
'itemtype' => 'Ticket',
'itemtype' => Ticket::class,
'status' => $validationStatus,
'date_creation' => $item->fields['date'],
'date_mod' => $item->fields['date_mod'],
Expand Down Expand Up @@ -417,7 +433,7 @@ function plugin_formcreator_hook_update_ticket(CommonDBTM $item) {
'id' => $issue->getID(),
'items_id' => $id,
'display_id' => "t_$id",
'itemtype' => 'Ticket',
'itemtype' => Ticket::class,
'name' => $issueName,
'status' => $validationStatus,
'date_creation' => $item->fields['date'],
Expand Down Expand Up @@ -581,7 +597,7 @@ function plugin_formcreator_dynamicReport($params) {
case PluginFormcreatorFormAnswer::class;
if ($url = parse_url($_SERVER['HTTP_REFERER'])) {
if (strpos($url['path'],
Toolbox::getItemTypeFormURL("PluginFormcreatorForm")) !== false) {
Toolbox::getItemTypeFormURL(PluginFormcreatorForm::class)) !== false) {
parse_str($url['query'], $query);
if (isset($query['id'])) {
$item = PluginFormcreatorCommon::getForm();
Expand Down
4 changes: 0 additions & 4 deletions inc/formanswer.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1418,8 +1418,6 @@ public function createIssue() {
'entities_id' => $this->fields['entities_id'],
'is_recursive' => $this->fields['is_recursive'],
'requester_id' => $this->fields['requester_id'],
'users_id_validator' => $this->fields['users_id_validator'],
'groups_id_validator'=> $this->fields['groups_id_validator'],
'comment' => '',
]);

Expand Down Expand Up @@ -1522,8 +1520,6 @@ private function updateIssue() {
'entities_id' => $this->fields['entities_id'],
'is_recursive' => $this->fields['is_recursive'],
'requester_id' => $this->fields['requester_id'],
'users_id_validator' => $this->fields['users_id_validator'],
'groups_id_validator'=> $this->fields['groups_id_validator'],
'comment' => '',
]);

Expand Down
109 changes: 78 additions & 31 deletions inc/issue.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ public static function getSyncIssuesRequest() : AbstractQuery {
'entities_id as entities_d',
'is_recursive as is_recursive',
'requester_id as requester_id',
'users_id_validator as users_id_validator',
'groups_id_validator as groups_id_validator',
'comment as comment',
'requester_id as users_id_recipient'
],
Expand Down Expand Up @@ -145,16 +143,13 @@ public static function getSyncIssuesRequest() : AbstractQuery {
new QueryExpression("CONCAT('t_', `$ticketTable`.`id`) as `display_id`"),
"$ticketTable.id as items_id",
new QueryExpression("'" . Ticket::getType() . "' as `itemtype`"),
new QueryExpression("IF(`$ticketValidationTable`.`status` IS NULL,
new QueryExpression("IF(`$ticketTable`.`global_validation` IN ('" . CommonITILValidation::NONE . "', '" . CommonITILValidation::ACCEPTED . "'),
`$ticketTable`.`status`,
IF(`$ticketTable`.`global_validation` IN ('" . CommonITILValidation::NONE . "', '" . CommonITILValidation::ACCEPTED . "'),
IF(`$ticketTable`.`status` IN ('" . CommonITILObject::SOLVED . "', '" . CommonITILObject::CLOSED . "'),
`$ticketTable`.`status`,
IF(`$ticketTable`.`status` IN ('" . CommonITILObject::SOLVED . "', '" . CommonITILObject::CLOSED . "'),
`$ticketTable`.`status`,
IF(`$ticketTable`.`global_validation` = '" . CommonITILValidation::WAITING . "',
'" . PluginFormcreatorFormAnswer::STATUS_WAITING . "',
'" . PluginFormcreatorFormAnswer::STATUS_REFUSED . "'
)
IF(`$ticketTable`.`global_validation` = '" . CommonITILValidation::WAITING . "',
'" . PluginFormcreatorFormAnswer::STATUS_WAITING . "',
'" . PluginFormcreatorFormAnswer::STATUS_REFUSED . "'
)
)
) AS `status`"),
Expand All @@ -165,8 +160,6 @@ public static function getSyncIssuesRequest() : AbstractQuery {
],
new QueryExpression('0 as is_recursive'),
new QueryExpression("COALESCE(`$ticketUserTable`.`users_id`, 0) as `requester_id`"),
new QueryExpression("COALESCE(`$ticketValidationTable`.`users_id_validate`, 0) as `users_id_validator`"),
new QueryExpression('0 as groups_id_validator'),
"$ticketTable.content as comment",
'users_id_recipient as users_id_recipient'
],
Expand Down Expand Up @@ -198,12 +191,6 @@ public static function getSyncIssuesRequest() : AbstractQuery {
$ticketUserTable => $ticketFk,
],
],
$ticketValidationTable => [
'FKEY' => [
$ticketTable => 'id',
$ticketValidationTable => $ticketFk,
],
],
],
'WHERE' => [
"$ticketTable.is_deleted" => 0,
Expand All @@ -219,7 +206,7 @@ public static function getSyncIssuesRequest() : AbstractQuery {
'INNER JOIN' => [$itemTicketTable => $query2['LEFT JOIN'][$itemTicketTable]],
'LEFT JOIN' => [
$query2['LEFT JOIN'][0], // This is the TABLE => [...] subquery
$ticketValidationTable => $query2['LEFT JOIN'][$ticketValidationTable],
// $ticketValidationTable => $query2['LEFT JOIN'][$ticketValidationTable],
],
'WHERE' => $query2['WHERE'],
'GROUPBY' => ["$itemTicketTable.items_id"],
Expand Down Expand Up @@ -521,7 +508,6 @@ public function rawSearchOptions() {
'name' => __('Name'),
'datatype' => 'itemlink',
'massiveaction' => false,
'forcegroupby' => true,
'additionalfields' => [
'0' => 'display_id'
]
Expand Down Expand Up @@ -608,14 +594,22 @@ public function rawSearchOptions() {
} else {
$newtab = [
'id' => '9',
'table' => 'glpi_users',
'table' => User::getTable(),
'field' => 'name',
'linkfield' => 'users_id_validator',
'name' => __('Form approver', 'formcreator'),
'datatype' => 'dropdown',
'massiveaction' => false
'massiveaction' => false,
'joinparams' => [
'beforejoin' => [
'table' => PluginFormcreatorFormAnswer::getTable(),
'joinparams' => [
'jointype' => 'itemtype_item_revert',
'specific_itemtype' => PluginFormcreatorFormAnswer::class,
]
],
],
];

}
if (!Session::isCron() // no filter for cron
&& Session::getCurrentInterface() == 'helpdesk') {
Expand All @@ -640,12 +634,12 @@ public function rawSearchOptions() {
'field' => 'name',
'linkfield' => 'users_id_validate',
'name' => __('Ticket approver', 'formcreator'),
'datatype' => 'dropdown',
'datatype' => 'itemlink',
'right' => [
'0' => 'validate_request',
'1' => 'validate_incident'
],
'forcegroupby' => false,
'forcegroupby' => true,
'massiveaction' => false,
'joinparams' => [
'beforejoin' => [
Expand All @@ -663,6 +657,12 @@ public function rawSearchOptions() {
],
]
];
if (version_compare(GLPI_VERSION, '10.1') >= 0) {
$newtab['linkfield'] = 'items_id_target';
$newtab['condition'] = [
'REFTABLE.itemtype_target' => User::class,
];
}
if (!Session::isCron() // no filter for cron
&& Session::getCurrentInterface() == 'helpdesk') {
$newtab['right'] = 'id';
Expand All @@ -675,7 +675,6 @@ public function rawSearchOptions() {
'field' => 'name',
'name' => __('Technician'),
'datatype' => 'dropdown',
'forcegroupby' => true,
'massiveaction' => false,
'nodisplay' => $hide_technician,
'nosearch' => $hide_technician,
Expand Down Expand Up @@ -716,7 +715,9 @@ public function rawSearchOptions() {
'beforejoin' => [
'table' => Group_Ticket::getTable(),
'joinparams' => [
'condition' => "AND NEWTABLE.`type` = '2'", // Assign
'condition' => [
'NEWTABLE.type' => CommonITILActor::ASSIGN,
],
'jointype' => 'child',
'beforejoin' => [
'table' => Ticket::getTable(),
Expand All @@ -732,17 +733,63 @@ public function rawSearchOptions() {
}

if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {
$tab[] = PluginAdvformIssue::rawSearchOptionFormApproverGroup();
$newtab = PluginAdvformIssue::rawSearchOptionFormApproverGroup();
} else {
$tab[] = [
$newtab = [
'id' => '16',
'table' => 'glpi_groups',
'table' => Group::getTable(),
'field' => 'completename',
'linkfield' => 'groups_id_validator',
'name' => __('Form approver group', 'formcreator'),
'datatype' => 'itemlink',
'massiveaction' => false,
'linkfield' => 'groups_id_validator',
'joinparams' => [
'beforejoin' => [
'table' => PluginFormcreatorFormAnswer::getTable(),
'joinparams' => [
'jointype' => 'itemtype_item_revert',
'specific_itemtype' => PluginFormcreatorFormAnswer::class,
]
],
],
];
}
$tab[] = $newtab;

if (version_compare(GLPI_VERSION, '10.1') >= 0) {
$newtab = [
'id' => '17',
'table' => Group::getTable(),
'field' => 'name',
'linkfield' => 'items_id_target',
'name' => __('Ticket approver group', 'formcreator'),
'datatype' => 'itemlink',
'condition' => [
'REFTABLE.itemtype_target' => User::class,
],
'right' => [
'0' => 'validate_request',
'1' => 'validate_incident'
],
'forcegroupby' => true,
'massiveaction' => false,
'joinparams' => [
'beforejoin' => [
'table' => TicketValidation::getTable(),
'joinparams' => [
'jointype' => 'child',
'beforejoin' => [
'table' => Ticket::getTable(),
'joinparams' => [
'jointype' => 'itemtype_item_revert',
'specific_itemtype' => Ticket::class,
]
]
]
],
]
];
$tab[] = $newtab;
}

if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {
Expand Down
1 change: 1 addition & 0 deletions install/install.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class PluginFormcreatorInstall {
'2.12.1' => '2.12.5',
'2.12.5' => '2.13',
'2.13' => '2.13.1',
'2.13.1' => '2.13.3',
];

protected bool $resyncIssues = false;
Expand Down
6 changes: 1 addition & 5 deletions install/mysql/plugin_formcreator_2.13.3_empty.sql
Original file line number Diff line number Diff line change
Expand Up @@ -294,16 +294,12 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_issues` (
`entities_id` int unsigned NOT NULL DEFAULT '0',
`is_recursive` tinyint(1) NOT NULL DEFAULT '0',
`requester_id` int unsigned NOT NULL DEFAULT '0',
`users_id_validator` int unsigned NOT NULL DEFAULT '0',
`groups_id_validator` int unsigned NOT NULL DEFAULT '0',
`comment` longtext,
`users_id_recipient` int unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
INDEX `item` (`itemtype`, `items_id`),
INDEX `entities_id` (`entities_id`),
INDEX `requester_id` (`requester_id`),
INDEX `users_id_validator` (`users_id_validator`),
INDEX `groups_id_validator` (`groups_id_validator`)
INDEX `requester_id` (`requester_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `glpi_plugin_formcreator_items_targettickets` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
Expand Down
Loading

0 comments on commit 3f51fbd

Please sign in to comment.