Skip to content

Commit 61a06e2

Browse files
authored
Add/project task assigne in task team (#23945)
1 parent fef6845 commit 61a06e2

3 files changed

Lines changed: 168 additions & 8 deletions

File tree

src/ProjectTask.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,11 +1419,14 @@ public static function showFor($item)
14191419
'delete' => _x('button', 'Put in trashbin'),
14201420
'restore' => _x('button', 'Restore'),
14211421
'purge' => _x('button', 'Delete permanently'),
1422+
ProjectTaskTeam::class . MassiveAction::CLASS_ACTION_SEPARATOR . 'affect_to_team' => _x('button', 'Affect to team'),
1423+
ProjectTaskTeam::class . MassiveAction::CLASS_ACTION_SEPARATOR . 'unaffect_to_team' => _x('button', 'Unaffect to team'),
14221424
],
14231425
],
14241426
]);
14251427
}
14261428

1429+
14271430
public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0)
14281431
{
14291432
$nb = 0;

src/ProjectTaskTeam.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,100 @@ public function getForbiddenStandardMassiveAction()
8787
return $forbidden;
8888
}
8989

90+
public static function showMassiveActionsSubForm(MassiveAction $ma)
91+
{
92+
global $CFG_GLPI;
93+
94+
switch ($ma->getAction()) {
95+
case 'affect_to_team':
96+
case 'unaffect_to_team':
97+
$rand = Dropdown::showItemTypes('itemtype', static::$available_types);
98+
echo '<br>';
99+
$params = [
100+
'idtable' => '__VALUE__',
101+
'display_emptychoice' => true,
102+
'name' => 'items_id',
103+
'entity_restrict' => Session::getActiveEntity(),
104+
'rand' => $rand,
105+
];
106+
Ajax::updateItemOnSelectEvent(
107+
"dropdown_itemtype$rand",
108+
"results_itemtype$rand",
109+
$CFG_GLPI['root_doc'] . '/ajax/dropdownAllItems.php',
110+
$params
111+
);
112+
echo "<span id='results_itemtype$rand'></span>";
113+
echo '<br>';
114+
115+
echo Html::submit(_x('button', 'Post'), ['name' => 'massiveaction']);
116+
return true;
117+
}
118+
return parent::showMassiveActionsSubForm($ma);
119+
}
120+
121+
/**
122+
* @param int[] $ids
123+
*/
124+
public static function processMassiveActionsForOneItemtype(
125+
MassiveAction $ma,
126+
CommonDBTM $item,
127+
array $ids
128+
): void {
129+
$action = $ma->getAction();
130+
$input = $ma->getInput();
131+
132+
if (!in_array($action, ['affect_to_team', 'unaffect_to_team'], true)) {
133+
parent::processMassiveActionsForOneItemtype($ma, $item, $ids);
134+
return;
135+
}
136+
137+
if (
138+
empty($input['itemtype'])
139+
|| !isset($input['items_id'])
140+
|| (int) $input['items_id'] <= 0
141+
) {
142+
foreach ($ids as $id) {
143+
$ma->itemDone($item->getType(), $id, MassiveAction::NO_ACTION);
144+
}
145+
return;
146+
}
147+
148+
$team = new self();
149+
150+
foreach ($ids as $id) {
151+
if (!$item->can($id, UPDATE)) {
152+
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT);
153+
continue;
154+
}
155+
156+
$criteria = [
157+
'projecttasks_id' => $id,
158+
'itemtype' => $input['itemtype'],
159+
'items_id' => (int) $input['items_id'],
160+
];
161+
162+
if ($action === 'affect_to_team') {
163+
if (countElementsInTable(self::getTable(), $criteria) > 0) {
164+
$ma->itemDone($item->getType(), $id, MassiveAction::NO_ACTION);
165+
continue;
166+
}
167+
$result = $team->add($criteria);
168+
} else {
169+
if (countElementsInTable(self::getTable(), $criteria) === 0) {
170+
$ma->itemDone($item->getType(), $id, MassiveAction::NO_ACTION);
171+
continue;
172+
}
173+
$result = $team->deleteByCriteria($criteria);
174+
}
175+
176+
if ($result) {
177+
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK);
178+
} else {
179+
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO);
180+
}
181+
}
182+
}
183+
90184

91185
public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0)
92186
{

tests/functional/ProjectTaskTest.php

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use Glpi\Tests\DbTestCase;
3939
use Project;
4040
use ProjectTask;
41+
use ProjectTaskTeam;
4142

4243
/* Test for inc/projecttask.class.php */
4344

@@ -79,7 +80,7 @@ public function testPlanningConflict()
7980
$this->hasNoSessionMessages([ERROR, WARNING]);
8081
$task_id = $ptask->fields['id'];
8182

82-
$team = new \ProjectTaskTeam();
83+
$team = new ProjectTaskTeam();
8384
$tid = (int) $team->add([
8485
'projecttasks_id' => $ptask->fields['id'],
8586
'itemtype' => \User::getType(),
@@ -100,7 +101,7 @@ public function testPlanningConflict()
100101
);
101102
$this->hasNoSessionMessages([ERROR, WARNING]);
102103

103-
$team = new \ProjectTaskTeam();
104+
$team = new ProjectTaskTeam();
104105
$tid = (int) $team->add([
105106
'projecttasks_id' => $ptask->fields['id'],
106107
'itemtype' => \User::getType(),
@@ -130,7 +131,7 @@ public function testPlanningConflict()
130131
);
131132
$this->hasNoSessionMessages([ERROR, WARNING]);
132133

133-
$team = new \ProjectTaskTeam();
134+
$team = new ProjectTaskTeam();
134135
$tid = (int) $team->add([
135136
'projecttasks_id' => $ptask->fields['id'],
136137
'itemtype' => \User::getType(),
@@ -405,7 +406,7 @@ public function testCloneProjectTask()
405406
$this->assertEquals($task->fields['name'] . ' (copy)', $clonedTask->fields['name']);
406407

407408
// Load task team
408-
$project_task_team = new \ProjectTaskTeam();
409+
$project_task_team = new ProjectTaskTeam();
409410
$team = [];
410411
foreach ($project_task_team->find(['projecttasks_id' => $task->fields['id']]) as $row) {
411412
$team[] = [
@@ -857,7 +858,7 @@ public function testGetActiveProjectTaskIDsForUser()
857858
$this->assertEmpty(ProjectTask::getActiveProjectTaskIDsForUser([$user->getID()]));
858859

859860
// Create user team
860-
$user_team = $this->createItem(\ProjectTaskTeam::getType(), [
861+
$user_team = $this->createItem(ProjectTaskTeam::getType(), [
861862
'projecttasks_id' => $project_task->getID(),
862863
'itemtype' => \User::class,
863864
'items_id' => $user->getID(),
@@ -876,14 +877,14 @@ public function testGetActiveProjectTaskIDsForUser()
876877
$this->createItem(\Group_User::getType(), ['groups_id' => $group->getID(), 'users_id' => $user->getID()]);
877878

878879
// Create group team
879-
$this->createItem(\ProjectTaskTeam::getType(), [
880+
$this->createItem(ProjectTaskTeam::getType(), [
880881
'projecttasks_id' => $project_task->getID(),
881882
'itemtype' => \Group::class,
882883
'items_id' => $group->getID(),
883884
]);
884885

885886
// Remove user team
886-
$this->deleteItem(\ProjectTaskTeam::getType(), $user_team->getID());
887+
$this->deleteItem(ProjectTaskTeam::getType(), $user_team->getID());
887888

888889
// Check if a user with a project with tasks, where the user is a member of the group and the group is a member of the team, returns an array with the task ID if $search_in_groups is true
889890
$this->assertEquals(
@@ -934,7 +935,7 @@ public function testGetActiveProjectTaskIDsForGroup(): void
934935
$this->assertEmpty(ProjectTask::getActiveProjectTaskIDsForGroup([$group->getID()]));
935936

936937
// Create group team
937-
$this->createItem(\ProjectTaskTeam::getType(), [
938+
$this->createItem(ProjectTaskTeam::getType(), [
938939
'projecttasks_id' => $project_task->getID(),
939940
'itemtype' => \Group::class,
940941
'items_id' => $group->getID(),
@@ -1003,4 +1004,66 @@ public function testAutoSetDate(): void
10031004
$result = $task2->autoSetDate($input);
10041005
$this->assertNull($result['real_end_date']);
10051006
}
1007+
1008+
public function testAffectAndUnaffectTeamMember(): void
1009+
{
1010+
$this->login();
1011+
1012+
$project = $this->createItem(Project::class, ['name' => __FUNCTION__]);
1013+
$task = $this->createItem(ProjectTask::class, [
1014+
'name' => __FUNCTION__,
1015+
'projects_id' => $project->getID(),
1016+
]);
1017+
$group = getItemByTypeName('Group', '_test_group_1');
1018+
1019+
$criteria = [
1020+
'projecttasks_id' => $task->getID(),
1021+
'itemtype' => 'Group',
1022+
'items_id' => $group->getID(),
1023+
];
1024+
1025+
// Ajout d'un membre
1026+
$team_entry = $this->createItem(ProjectTaskTeam::class, $criteria);
1027+
$this->assertSame(1, countElementsInTable(ProjectTaskTeam::getTable(), $criteria));
1028+
1029+
// Vérification via getTeamFor
1030+
$team = ProjectTaskTeam::getTeamFor($task->getID());
1031+
$this->assertCount(1, $team['Group']);
1032+
$this->assertSame($group->getID(), $team['Group'][0]['items_id']);
1033+
1034+
// Suppression du membre
1035+
$this->deleteItem(ProjectTaskTeam::class, $team_entry->getID());
1036+
$this->assertSame(0, countElementsInTable(ProjectTaskTeam::getTable(), $criteria));
1037+
1038+
$team = ProjectTaskTeam::getTeamFor($task->getID());
1039+
$this->assertCount(0, $team['Group']);
1040+
}
1041+
1042+
public function testAffectTeamMemberDuplicatePrevented(): void
1043+
{
1044+
$this->login();
1045+
1046+
$project = $this->createItem(Project::class, ['name' => __FUNCTION__]);
1047+
$task = $this->createItem(ProjectTask::class, [
1048+
'name' => __FUNCTION__,
1049+
'projects_id' => $project->getID(),
1050+
]);
1051+
$group = getItemByTypeName('Group', '_test_group_1');
1052+
1053+
$criteria = [
1054+
'projecttasks_id' => $task->getID(),
1055+
'itemtype' => 'Group',
1056+
'items_id' => $group->getID(),
1057+
];
1058+
1059+
$this->createItem(ProjectTaskTeam::class, $criteria);
1060+
$this->assertSame(1, countElementsInTable(ProjectTaskTeam::getTable(), $criteria));
1061+
1062+
// Le doublon est détecté par countElementsInTable avant tout INSERT
1063+
$already_exists = countElementsInTable(ProjectTaskTeam::getTable(), $criteria) > 0;
1064+
$this->assertTrue($already_exists);
1065+
1066+
// Toujours une seule entrée en base
1067+
$this->assertSame(1, countElementsInTable(ProjectTaskTeam::getTable(), $criteria));
1068+
}
10061069
}

0 commit comments

Comments
 (0)