diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index 02d4215b963..b83c30d15b6 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -1323,6 +1323,60 @@ if (!$error && ($action == 'setsupervisor' && $confirm == 'yes') && $permissiont
}
}
+if (!$error && ($action == 'affectuser' && $confirm == 'yes') && $permissiontoadd) {
+ $db->begin();
+
+ $usertoaffect=GETPOST('usertoaffect');
+ $projectrole=GETPOST('projectrole');
+ $tasksrole=GETPOST('tasksrole');
+ if (!empty($usertoaffect)) {
+ foreach ($toselect as $toselectid) {
+ $result = $object->fetch($toselectid);
+ //var_dump($contcats);exit;
+ if ($result > 0) {
+ $res = $object->add_contact($usertoaffect, $projectrole, 'internal');
+ if ($res >= 0) {
+ $taskstatic = new Task($db);
+ $task_array = $taskstatic->getTasksArray(0, 0, $object->id, 0, 0);
+
+ foreach ($task_array as $task) {
+ $tasksToAffect = new Task($db);
+ $result = $tasksToAffect->fetch($task->id);
+ if ($result > 0) {
+ $res = $tasksToAffect->add_contact($usertoaffect, $tasksrole, 'internal');
+ if ($res < 0) {
+ setEventMessages($tasksToAffect->error, $tasksToAffect->errors, 'errors');
+ }
+ }
+ }
+ $nbok++;
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ $error++;
+ break;
+ }
+ }
+ } else {
+ setEventMessage('UserNotFound', 'errors');
+ $error++;
+ }
+
+ if (!$error) {
+ if ($nbok > 1) {
+ setEventMessages($langs->trans("RecordsModified", $nbok), null);
+ } else {
+ setEventMessages($langs->trans("RecordsModified", $nbok), null);
+ }
+ $db->commit();
+ $toselect=array();
+ } else {
+ $db->rollback();
+ }
+}
+
if (!$error && ($massaction == 'enable' || ($action == 'enable' && $confirm == 'yes')) && $permissiontoadd) {
$db->begin();
diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php
index 1e48fc4d5a0..7657fe21e96 100644
--- a/htdocs/core/tpl/massactions_pre.tpl.php
+++ b/htdocs/core/tpl/massactions_pre.tpl.php
@@ -113,6 +113,44 @@ if ($massaction == 'presetsupervisor') {
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmSetSupervisor"), $langs->trans("ConfirmSetSupervisorQuestion", count($toselect)), "setsupervisor", $formquestion, 1, 0, 200, 500, 1);
}
+if ($massaction == 'preaffectuser') {
+ $formquestion = array();
+
+ $valuefielduser = '
';
+ $valuefielduser .= img_picto('', 'user').' ';
+ $valuefielduser .= $form->select_dolusers('', 'usertoaffect', 1, $arrayofselected, 0, '', 0, $object->entity, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
+ $valuefielduser .= '
';
+
+ $valuefieldprojrole = '';
+ $valuefieldprojrole .= $formcompany->selectTypeContact($object, '', 'projectrole', 'internal', 'position', 0, 'widthcentpercentminusx maxwidth300', 0);
+ $valuefieldprojrole .= '
';
+
+ $valuefieldtasksrole = '';
+ $valuefieldtasksrole .= $formcompany->selectTypeContact($taskstatic, '', 'tasksrole', 'internal', 'position', 0, 'widthcentpercentminusx maxwidth300', 0);
+ $valuefieldtasksrole .= '
';
+
+ $formquestion[] = array(
+ 'type' => 'other',
+ 'name' => 'usertoaffect',
+ 'label' => $langs->trans("User"),
+ 'value' => $valuefielduser
+ );
+ $formquestion[] = array(
+ 'type' => 'other',
+ 'name' => 'projectrole',
+ 'label' => $langs->trans("ProjectRole"),
+ 'value' => $valuefieldprojrole
+ );
+
+ $formquestion[] = array(
+ 'type' => 'other',
+ 'name' => 'tasksrole',
+ 'label' => $langs->trans("TasksRole"),
+ 'value' => $valuefieldtasksrole
+ );
+
+ print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmAffectUser"), $langs->trans("ConfirmAffectUserQuestion", count($toselect)), "affectuser", $formquestion, 1, 0, 200, 500, 1);
+}
if ($massaction == 'presend') {
$langs->load("mails");
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 6f849e39be1..2b86c2d3e65 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -1146,12 +1146,17 @@ UpdateForAllLines=Update for all lines
OnHold=On hold
Civility=Civility
AffectTag=Affect Tag
+AffectUser=Affect User
SetSupervisor=Set Supervisor
CreateExternalUser=Create external user
ConfirmAffectTag=Bulk Tag Affect
+ConfirmAffectUser=Bulk User Affect
+ProjectRole=Role assigned on each project
+TasksRole=Role assigned on each task of each project
ConfirmSetSupervisor=Bulk Supervisor Set
ConfirmUpdatePrice=Choose a increase/decrease price rate
ConfirmAffectTagQuestion=Are you sure you want to affect tags to the %s selected record(s)?
+ConfirmAffectUserQuestion=Are you sure you want to affect users to the %s selected record(s)?
ConfirmSetSupervisorQuestion=Are you sure you want to set supervisor to the %s selected record(s)?
ConfirmUpdatePriceQuestion=Are you sure you want to update the price of the %s selected record(s)?
CategTypeNotFound=No tag type found for type of records
diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang
index 39d857ae0e8..eb787cb279d 100644
--- a/htdocs/langs/fr_FR/main.lang
+++ b/htdocs/langs/fr_FR/main.lang
@@ -1146,13 +1146,18 @@ UpdateForAllLines=Mise à jour de toutes les lignes
OnHold=En attente
Civility=Civilité
AffectTag=Affecter un tag/catégorie
+AffectUser=Affecter un utilisateur
SetSupervisor=Choisir un superviseur
CreateExternalUser=Créer utilisateur externe
ConfirmAffectTag=Affecter les tags en masse
ConfirmSetSupervisor=Choisir un superviseur en masse
+ConfirmAffectUser=Affecter les utilisateurs en masse
+ProjectRole=Role attribué pour chaque projet
+TasksRole=Role attribué pour chaque tâche de chaque projet
ConfirmUpdatePrice=Choisir un pourcentage de hausse/baisse des prix
ConfirmAffectTagQuestion=Êtes-vous sur de vouloir affecter ces catégories aux %s lignes sélectionnées ?
ConfirmSetSupervisorQuestion=Êtes-vous sur de vouloir affecter ce superviseur aux %s lignes sélectionnées ?
+ConfirmAffectUserQuestion=Êtes-vous sur de vouloir affecter cet utilisateur aux %s lignes sélectionnées ?
ConfirmUpdatePriceQuestion=Êtes-vous sur de vouloir mettre à jour les prix des %s lignes sélectionnées ?
CategTypeNotFound=Aucun type de tag trouvé pour ce type d'enregistrements
Rate=Taux
diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php
index d3a5a203487..dd184bb1f3d 100644
--- a/htdocs/projet/list.php
+++ b/htdocs/projet/list.php
@@ -35,6 +35,8 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
if (isModEnabled('categorie')) {
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
@@ -355,8 +357,10 @@ if (empty($reshook)) {
*/
$form = new Form($db);
+$formcompany = new FormCompany($db);
$companystatic = new Societe($db);
+$taskstatic = new Task($db);
$formother = new FormOther($db);
$formproject = new FormProjets($db);
@@ -802,6 +806,7 @@ $arrayofmassactions = array(
//if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
if ($user->rights->projet->creer) {
$arrayofmassactions['close'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Close");
+ $arrayofmassactions['preaffectuser'] = img_picto('', 'user', 'class="pictofixedwidth"').$langs->trans("AffectUser");
}
if ($user->rights->projet->supprimer) {
$arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
@@ -809,7 +814,7 @@ if ($user->rights->projet->supprimer) {
if (isModEnabled('category') && $user->rights->projet->creer) {
$arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
}
-if (in_array($massaction, array('presend', 'predelete', 'preaffecttag'))) {
+if (in_array($massaction, array('presend', 'predelete', 'preaffecttag', 'preaffectuser'))) {
$arrayofmassactions = array();
}