Skip to content

Commit c77be76

Browse files
committed
fix(issue): answers with multiple tickets
Signed-off-by: Thierry Bugier <[email protected]>
1 parent 677e2b8 commit c77be76

File tree

4 files changed

+118
-15
lines changed

4 files changed

+118
-15
lines changed

hook.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -333,11 +333,12 @@ function plugin_formcreator_hook_add_ticket(CommonDBTM $item) {
333333

334334
$validationStatus = PluginFormcreatorCommon::getTicketStatusForIssue($item);
335335

336+
$issueName = $item->fields['name'] != '' ? addslashes($item->fields['name']) : '(' . $item->getID() . ')';
336337
$issue = new PluginFormcreatorIssue();
337338
$issue->add([
338339
'items_id' => $item->getID(),
339340
'itemtype' => 'Ticket',
340-
'name' => addslashes($item->fields['name']),
341+
'name' => $issueName,
341342
'status' => $validationStatus['status'],
342343
'date_creation' => $item->fields['date'],
343344
'date_mod' => $item->fields['date_mod'],
@@ -358,6 +359,7 @@ function plugin_formcreator_hook_update_ticket(CommonDBTM $item) {
358359

359360
$validationStatus = PluginFormcreatorCommon::getTicketStatusForIssue($item);
360361

362+
$issueName = $item->fields['name'] != '' ? addslashes($item->fields['name']) : '(' . $item->getID() . ')';
361363
$issue = new PluginFormcreatorIssue();
362364
$issue->getFromDBByCrit([
363365
'AND' => [
@@ -370,7 +372,7 @@ function plugin_formcreator_hook_update_ticket(CommonDBTM $item) {
370372
'items_id' => $id,
371373
'display_id' => "t_$id",
372374
'itemtype' => 'Ticket',
373-
'name' => addslashes($item->fields['name']),
375+
'name' => $issueName,
374376
'status' => $validationStatus['status'],
375377
'date_creation' => $item->fields['date'],
376378
'date_mod' => $item->fields['date_mod'],

inc/formanswer.class.php

+8-4
Original file line numberDiff line numberDiff line change
@@ -1239,10 +1239,11 @@ private function createIssue() {
12391239
if ($rows->count() != 1) {
12401240
// There are several tickets for this form answer
12411241
// The issue must be created from this form answer
1242+
$issueName = $this->fields['name'] != '' ? addslashes($this->fields['name']) : '(' . $this->getID() . ')';
12421243
$issue->add([
12431244
'items_id' => $this->getID(),
12441245
'itemtype' => PluginFormcreatorFormAnswer::class,
1245-
'name' => addslashes($this->fields['name']),
1246+
'name' => $issueName,
12461247
'status' => $this->fields['status'],
12471248
'date_creation' => $this->fields['request_date'],
12481249
'date_mod' => $this->fields['request_date'],
@@ -1280,10 +1281,11 @@ private function createIssue() {
12801281
$validationStatus = PluginFormcreatorCommon::getTicketStatusForIssue($ticket);
12811282

12821283
$ticketUserRow = array_pop($ticketUserRow);
1284+
$issueName = $ticket->fields['name'] != '' ? addslashes($ticket->fields['name']) : '(' . $ticket->getID() . ')';
12831285
$issue->add([
12841286
'items_id' => $ticketId,
12851287
'itemtype' => Ticket::class,
1286-
'name' => addslashes($ticket->fields['name']),
1288+
'name' => $issueName,
12871289
'status' => $validationStatus['status'],
12881290
'date_creation' => $ticket->fields['date'],
12891291
'date_mod' => $ticket->fields['date_mod'],
@@ -1333,11 +1335,12 @@ private function updateIssue() {
13331335
'items_id' => $this->getID()
13341336
]
13351337
]);
1338+
$issueName = $this->fields['name'] != '' ? addslashes($this->fields['name']) : '(' . $this->getID() . ')';
13361339
$issue->update([
13371340
'id' => $issue->getID(),
13381341
'items_id' => $this->getID(),
13391342
'itemtype' => PluginFormcreatorFormAnswer::class,
1340-
'name' => addslashes($this->fields['name']),
1343+
'name' => $issueName,
13411344
'status' => $this->fields['status'],
13421345
'date_creation' => $this->fields['request_date'],
13431346
'date_mod' => $this->fields['request_date'],
@@ -1377,11 +1380,12 @@ private function updateIssue() {
13771380
'items_id' => $this->getID()
13781381
]
13791382
]);
1383+
$issueName = $ticket->fields['name'] != '' ? addslashes($ticket->fields['name']) : '(' . $ticket->getID() . ')';
13801384
$issue->update([
13811385
'id' => $issue->getID(),
13821386
'items_id' => $ticketId,
13831387
'itemtype' => Ticket::class,
1384-
'name' => addslashes($ticket->fields['name']),
1388+
'name' => $issueName,
13851389
'status' => $ticket->fields['status'],
13861390
'date_creation' => $ticket->fields['date'],
13871391
'date_mod' => $ticket->fields['date_mod'],

inc/issue.class.php

+26-8
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,12 @@ public static function getSyncIssuesRequest() : AbstractQuery {
8686
// The columns status of the 2nd part of the UNNION statement
8787
// must match the same logic as PluginFormcreatorCommon::getTicketStatusForIssue()
8888
// @see PluginFormcreatorCommon::getTicketStatusForIssue()
89-
$query1 = new QuerySubQuery([
89+
90+
// assistance requests having no or deveral tickets
91+
$query1 = [
9092
'SELECT' => [
9193
new QueryExpression('NULL as `id`'),
92-
$formTable => ['name as name'],
94+
new QueryExpression("IF(`$formAnswerTable`.`name` = '', CONCAT('(', `$formAnswerTable`.`id`, ')'), `$formAnswerTable`.`name`) as `name`"),
9395
new QueryExpression("CONCAT('f_', `$formAnswerTable`.`id`) as `display_id`"),
9496
"$formAnswerTable.id as items_id",
9597
new QueryExpression("'" . PluginFormcreatorFormAnswer::getType() . "' as `itemtype`"),
@@ -126,15 +128,16 @@ public static function getSyncIssuesRequest() : AbstractQuery {
126128
],
127129
'GROUPBY' => ["$formAnswerTable.id"],
128130
'HAVING' => new QueryExpression("COUNT(`$itemTicketTable`.`$ticketFk`) != 1"),
129-
]);
131+
];
130132

133+
// tickets not generated by Formcreator
131134
$ticketTable = Ticket::getTable();
132135
$ticketValidationTable = TicketValidation::getTable();
133136
$ticketUserTable = Ticket_User::getTable();
134-
$query2 = new QuerySubquery([
137+
$query2 = [
135138
'SELECT' => [
136139
new QueryExpression('NULL as `id`'),
137-
"$ticketTable.name as name",
140+
new QueryExpression("IF(`$ticketTable`.`name` = '', CONCAT('(', `$ticketTable`.`id`, ')'), `$ticketTable`.`name`) as `name`"),
138141
new QueryExpression("CONCAT('t_', `$ticketTable`.`id`) as `display_id`"),
139142
"$ticketTable.id as items_id",
140143
new QueryExpression("'" . Ticket::getType() . "' as `itemtype`"),
@@ -204,10 +207,25 @@ public static function getSyncIssuesRequest() : AbstractQuery {
204207
"$ticketTable.is_deleted" => 0,
205208
],
206209
'GROUPBY' => ["$ticketTable.id"],
207-
'HAVING' => new QueryExpression("COUNT(`$itemTicketTable`.`items_id`) <= 1")
208-
]);
210+
'HAVING' => new QueryExpression("COUNT(`$itemTicketTable`.`items_id`) = 0")
211+
];
212+
213+
// assistance requests having only one generated ticket (use query2)
214+
$query3 = $query2;
215+
// replace LEFT JOIN with INNER JOIN to exclude tickets not linked to a Formanswer object
216+
$query3['INNER JOIN'][$itemTicketTable] = $query3['LEFT JOIN'][$itemTicketTable];
217+
unset($query3['LEFT JOIN'][$itemTicketTable]);
218+
// Only 1 relation to a Formanswer object
219+
$query3['GROUPBY'] = ["$itemTicketTable.items_id"];
220+
$query3['HAVING'] = new QueryExpression("COUNT(`$itemTicketTable`.`items_id`) = 1");
221+
222+
// Union of the 3 previous queries
223+
$union = new QueryUnion([
224+
new QuerySubquery($query1),
225+
new QuerySubquery($query2),
226+
new QuerySubquery($query3)
227+
], true);
209228

210-
$union = new QueryUnion([$query1, $query2], true);
211229
return $union;
212230
}
213231

tests/3-unit/PluginFormcreatorIssue.php

+80-1
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,26 @@ public function beforeTestMethod($method) {
4747
public function providerGetsyncIssuesRequest_simpleTicket() {
4848
$ticket = new \Ticket();
4949
$ticket->add([
50-
'name' => 'a ticket',
50+
'name' => 'simple ticket',
5151
'content' => 'foo',
5252
'status' => \Ticket::INCOMING
5353
]);
5454
$this->boolean($ticket->isNewItem())->isFalse();
5555
$ticket->getFromDB($ticket->getID());
5656

57+
$ticket2 = new \Ticket();
58+
$ticket2->add([
59+
'name' => '',
60+
'content' => 'foo',
61+
'status' => \Ticket::INCOMING
62+
]);
63+
$this->boolean($ticket2->isNewItem())->isFalse();
64+
$ticket2->getFromDB($ticket2->getID());
65+
$ticket2->update([
66+
'id' => $ticket2->getID(),
67+
'name' => '',
68+
]);
69+
5770
return [
5871
'simpleTicket' => [
5972
'item' => $ticket,
@@ -70,6 +83,21 @@ public function providerGetsyncIssuesRequest_simpleTicket() {
7083
'groups_id_validator' => '0',
7184
],
7285
],
86+
'simpleTicket_without_name' => [
87+
'item' => $ticket2,
88+
'expected' => [
89+
'itemtype' => \Ticket::getType(),
90+
'items_id' => $ticket2->getID(),
91+
'display_id' => 't_' . $ticket2->getID(),
92+
'name' => '(' . $ticket2->getID() . ')',
93+
'status' => $ticket2->fields['status'],
94+
'requester_id' => $ticket2->fields['users_id_recipient'],
95+
'date_creation' => $ticket2->fields['date'],
96+
'date_mod' => $ticket2->fields['date_mod'],
97+
'users_id_validator' => '0',
98+
'groups_id_validator' => '0',
99+
]
100+
]
73101
];
74102
}
75103

@@ -81,6 +109,7 @@ public function providerGetsyncIssuesRequest_simpleFormanswers() {
81109
]);
82110
$this->boolean($formAnswer->isNewItem())->isFalse();
83111
$formAnswer->getFromDB($formAnswer->getID());
112+
84113
return [
85114
'simpleFormanswers' => [
86115
'item' => $formAnswer,
@@ -420,6 +449,56 @@ public function testGetSyncIssuesRequest($item, $expected) {
420449
foreach ($expected as $key => $field) {
421450
$this->variable($row[$key])->isEqualTo($field, "mismatch in field '$key'");
422451
}
452+
453+
// Test there are no other rows matching the form answer or ticket
454+
if ($item->getType() == \Ticket::class) {
455+
$unwantedItems = $DB->request([
456+
'SELECT' => ['items_id'],
457+
'FROM' => \Item_Ticket::getTable(),
458+
'WHERE' => [
459+
'itemtype' => \PluginFormcreatorFormAnswer::getType(),
460+
'tickets_id' => $item->getID(),
461+
],
462+
]);
463+
if (count($unwantedItems) > 0) {
464+
$unwantedWhere = [
465+
'itemtype' => \PluginFormcreatorFormAnswer::getType(),
466+
];
467+
foreach ($unwantedItems as $row) {
468+
$unwantedWhere['items_id'][] = $row['items_id'];
469+
}
470+
// WHERE itemtype = 'PluginFormcreatorFormAnswer' AND items_id IN ( <list of numbers> )
471+
$result = $DB->request([
472+
'FROM' => $request,
473+
'WHERE' => $unwantedWhere,
474+
]);
475+
$this->integer(count($result))->isEqualTo(0);
476+
}
477+
}
478+
if ($item->getType() == \PluginFormcreatorFormAnswer::class) {
479+
$unwantedItems = $DB->request([
480+
'SELECT' => ['tickets_id'],
481+
'FROM' => \Item_Ticket::getTable(),
482+
'WHERE' => [
483+
'itemtype' => \PluginFormcreatorFormAnswer::getType(),
484+
'items_id' => $item->getID(),
485+
],
486+
]);
487+
if (count($unwantedItems) > 0) {
488+
$unwantedWhere = [
489+
'itemtype' => \Ticket::getType(),
490+
];
491+
foreach ($unwantedItems as $row) {
492+
$unwantedWhere['items_id'][] = $row['tickets_id'];
493+
}
494+
// WHERE itemtype = 'Ticket' AND items_id IN ( <list of numbers> )
495+
$result = $DB->request([
496+
'FROM' => $request,
497+
'WHERE' => $unwantedWhere,
498+
]);
499+
$this->integer(count($result))->isEqualTo(0);
500+
}
501+
}
423502
}
424503

425504
public function testUpdateDateModOnNewFollowup() {

0 commit comments

Comments
 (0)