diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php
index 5df6db52f3d..b26d45c34e2 100644
--- a/htdocs/adherents/class/adherent.class.php
+++ b/htdocs/adherents/class/adherent.class.php
@@ -2585,38 +2585,8 @@ class Adherent extends CommonObject
*/
public function setCategories($categories)
{
- // Handle single category
- if (!is_array($categories)) {
- $categories = array($categories);
- }
-
- // Get current categories
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
- $c = new Categorie($this->db);
- $existing = $c->containing($this->id, Categorie::TYPE_MEMBER, 'id');
-
- // Diff
- if (is_array($existing)) {
- $to_del = array_diff($existing, $categories);
- $to_add = array_diff($categories, $existing);
- } else {
- $to_del = array(); // Nothing to delete
- $to_add = $categories;
- }
-
- // Process
- foreach ($to_del as $del) {
- if ($c->fetch($del) > 0) {
- $c->del_type($this, Categorie::TYPE_MEMBER);
- }
- }
- foreach ($to_add as $add) {
- if ($c->fetch($add) > 0) {
- $c->add_type($this, Categorie::TYPE_MEMBER);
- }
- }
-
- return;
+ return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
}
/**
diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
index 367a2e7cd62..8fe4943d267 100644
--- a/htdocs/contact/class/contact.class.php
+++ b/htdocs/contact/class/contact.class.php
@@ -1579,38 +1579,8 @@ class Contact extends CommonObject
*/
public function setCategories($categories)
{
- // Handle single category
- if (!is_array($categories)) {
- $categories = array($categories);
- }
-
- // Get current categories
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
- $c = new Categorie($this->db);
- $existing = $c->containing($this->id, Categorie::TYPE_CONTACT, 'id');
-
- // Diff
- if (is_array($existing)) {
- $to_del = array_diff($existing, $categories);
- $to_add = array_diff($categories, $existing);
- } else {
- $to_del = array(); // Nothing to delete
- $to_add = $categories;
- }
-
- // Process
- foreach ($to_del as $del) {
- if ($c->fetch($del) > 0) {
- $c->del_type($this, Categorie::TYPE_CONTACT);
- }
- }
- foreach ($to_add as $add) {
- if ($c->fetch($add) > 0) {
- $c->add_type($this, Categorie::TYPE_CONTACT);
- }
- }
-
- return;
+ return parent::setCategoriesCommon($categories, Categorie::TYPE_CONTACT);
}
/**
diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php
index 00c74544d17..ecde0faf245 100644
--- a/htdocs/contact/list.php
+++ b/htdocs/contact/list.php
@@ -277,6 +277,7 @@ if (empty($reshook))
$objectlabel = 'Contact';
$permissiontoread = $user->rights->societe->lire;
$permissiontodelete = $user->rights->societe->supprimer;
+ $permissiontoadd = $user->rights->societe->creer;
$uploaddir = $conf->societe->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
@@ -525,6 +526,7 @@ $arrayofmassactions = array(
);
//if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
if ($user->rights->societe->supprimer) $arrayofmassactions['predelete'] = ''.$langs->trans("Delete");
+if ($user->rights->societe->creer) $arrayofmassactions['preaffecttag'] = ''.$langs->trans("AffectTag");
if (in_array($massaction, array('presend', 'predelete'))) $arrayofmassactions = array();
$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index 356eb36a04b..7331a9f40a5 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -1291,6 +1291,68 @@ if (!$error && $massaction == 'generate_doc' && $permissiontoread)
}
}
+if (!$error && ($action == 'affecttag' && $confirm == 'yes') && $permissiontoadd) {
+
+ $db->begin();
+
+ $affecttag_type=GETPOST('affecttag_type','alpha');
+ if (!empty($affecttag_type)) {
+ $affecttag_type_array=explode(',',$affecttag_type);
+ } else {
+ setEventMessage('CategTypeNotFound','errors');
+ }
+ if (!empty($affecttag_type_array)) {
+ //check if tag type submited exists into Tag Map categorie class
+ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+ $categ = new Categorie($db);
+ $to_affecttag_type_array=array();
+ $categ_type_array=$categ->getMapList();
+ foreach($categ_type_array as $categdef) {
+
+ if (in_array($categdef['code'], $affecttag_type_array)) {
+ $to_affecttag_type_array[] = $categdef['code'];
+ }
+ }
+
+ //For each valid categ type set common categ
+ $nbok = 0;
+ if (!empty($to_affecttag_type_array)) {
+ foreach ($to_affecttag_type_array as $categ_type) {
+ $contcats = GETPOST('contcats_' . $categ_type, 'array');
+var_dump($toselect);exit;
+ foreach ($toselect as $toselectid) {
+ $result = $object->fetch($toselectid);
+ var_dump($contcats);exit;
+ if ($result > 0) {
+
+ $result = $object->setCategoriesCommon($contcats, $categ_type, false);
+ if ($result > 0) {
+ $nbok++;
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ $error++;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ 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();
+ }
+}
+
$parameters['toselect'] = $toselect;
$parameters['uploaddir'] = $uploaddir;
$parameters['massaction'] = $massaction;
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index bfdea016ea6..f97f583fc87 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -8377,18 +8377,26 @@ abstract class CommonObject
/**
* Sets object to given categories.
*
- * Deletes object from existing categories not supplied.
* Adds it to non existing supplied categories.
+ * Deletes object from existing categories not supplied (if remove_existing==true).
* Existing categories are left untouch.
*
- * @param int[]|int $categories Category ID or array of Categories IDs
- * @param string $type_categ Category type ('customer', 'supplier', 'website_page', ...)
+ * @param int[]|int $categories Category ID or array of Categories IDs
+ * @param string $type_categ Category type ('customer', 'supplier', 'website_page', ...) definied into const class Categorie type
+ * @param boolean $remove_existing True: Remove existings categories from Object if not supplies by $categories, False: let them
* @return int <0 if KO, >0 if OK
*/
- public function setCategoriesCommon($categories, $type_categ)
+ public function setCategoriesCommon($categories, $type_categ='', $remove_existing=true)
{
+ dol_syslog(get_class($this)."::setCategoriesCommon Oject Id:".$this->id.' type_categ:'.$type_categ.' nb tag add:'.count($categories), LOG_DEBUG);
+
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+ if (empty($type_categ)) {
+ dol_syslog(__METHOD__.': Type '.$type_categ.'is an unknown category type. Done nothing.', LOG_ERR);
+ return -1;
+ }
+
// Handle single category
if (!is_array($categories)) {
$categories = array($categories);
@@ -8397,22 +8405,36 @@ abstract class CommonObject
// Get current categories
$c = new Categorie($this->db);
$existing = $c->containing($this->id, $type_categ, 'id');
-
- // Diff
- if (is_array($existing)) {
- $to_del = array_diff($existing, $categories);
- $to_add = array_diff($categories, $existing);
+ if ($remove_existing) {
+ // Diff
+ if (is_array($existing)) {
+ $to_del = array_diff($existing, $categories);
+ $to_add = array_diff($categories, $existing);
+ } else {
+ $to_del = array(); // Nothing to delete
+ $to_add = $categories;
+ }
} else {
$to_del = array(); // Nothing to delete
- $to_add = $categories;
+ $to_add = array_diff($categories, $existing);
}
$error = 0;
+ $ok=0;
// Process
foreach ($to_del as $del) {
if ($c->fetch($del) > 0) {
- $c->del_type($this, $type_categ);
+ $result=$c->del_type($this, $type_categ);
+ if ($result < 0)
+ {
+ $error++;
+ $this->error = $c->error;
+ $this->errors = $c->errors;
+ break;
+ } else {
+ $ok+=$result;
+ }
}
}
foreach ($to_add as $add) {
@@ -8425,11 +8447,13 @@ abstract class CommonObject
$this->error = $c->error;
$this->errors = $c->errors;
break;
+ } else {
+ $ok+=$result;
}
}
}
- return $error ? -1 : 1;
+ return $error ? -1 * $error : $ok;
}
/**
diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php
index 21070467f57..a5ce87ae932 100644
--- a/htdocs/core/tpl/massactions_pre.tpl.php
+++ b/htdocs/core/tpl/massactions_pre.tpl.php
@@ -37,6 +37,42 @@ if ($massaction == 'predelete')
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDeletion"), $langs->trans("ConfirmMassDeletionQuestion", count($toselect)), "delete", null, '', 0, 200, 500, 1);
}
+if ($massaction == 'preaffecttag')
+{
+ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+ $categ = new Categorie($db);
+ $categ_types=array();
+ $categ_type_array=$categ->getMapList();
+ foreach($categ_type_array as $categdef) {
+ if (isset($object) && $categdef['obj_table']==$object->table_element) {
+ if (!array_key_exists($categdef['code'],$categ_types)) $categ_types[$categdef['code']] = array('code'=>$categdef['code'],'label'=>$langs->trans($categdef['obj_class']));
+ }
+ if (isset($objecttmp) && $categdef['obj_table']==$objecttmp->table_element) {
+ if (!array_key_exists($categdef['code'],$categ_types)) $categ_types[$categdef['code']] = array('code'=>$categdef['code'],'label'=>$langs->trans($categdef['obj_class']));
+ }
+ }
+
+ $formquestion = array();
+ if (!empty($categ_types)) {
+ foreach($categ_types as $categ_type) {
+ $cate_arbo = $form->select_all_categories($categ_type['code'], null, 'parent', null, null, 1);
+ $formquestion[]=
+ array('type' => 'other',
+ 'name' => 'affecttag_'.$categ_type['code'],
+ 'label' => $langs->trans("Tag").' '.$categ_type['label'],
+ 'value' => $form->multiselectarray('contcats_'.$categ_type['code'], $cate_arbo, GETPOST('contcats_'.$categ_type['code'], 'array'), null, null, null, null, '60%'));
+ }
+ $formquestion[]=
+ array('type' => 'other',
+ 'name' => 'affecttag_type',
+ 'label' => '',
+ 'value' => '');
+ print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmAffectTag"), $langs->trans("ConfirmAffectTagQuestion", count($toselect)), "affecttag", $formquestion, 1, 0, 200, 500, 1);
+ } else {
+ setEventMessage('CategTypeNotFound');
+ }
+}
+
if ($massaction == 'presend')
{
$langs->load("mails");
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 7075df90783..07aafadd636 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -1112,4 +1112,7 @@ UpToDate=Up-to-date
OutOfDate=Out-of-date
EventReminder=Event Reminder
UpdateForAllLines=Update for all lines
-OnHold=On hold
\ No newline at end of file
+OnHold=On hold
+ConfirmAffectTag=Bulk Tag Affect
+ConfirmAffectTagQuestion=Are you sure you want to affect tags to the %s selected record(s)?
+CategTypeNotFound=No tag type found for type of records
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index c40ffd4e0a9..4e94380a54f 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -5497,38 +5497,9 @@ class Product extends CommonObject
*/
public function setCategories($categories)
{
- // Handle single category
- if (!is_array($categories)) {
- $categories = array($categories);
- }
- // Get current categories
- include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
- $c = new Categorie($this->db);
- $existing = $c->containing($this->id, Categorie::TYPE_PRODUCT, 'id');
-
- // Diff
- if (is_array($existing)) {
- $to_del = array_diff($existing, $categories);
- $to_add = array_diff($categories, $existing);
- } else {
- $to_del = array(); // Nothing to delete
- $to_add = $categories;
- }
-
- // Process
- foreach ($to_del as $del) {
- if ($c->fetch($del) > 0) {
- $c->del_type($this, Categorie::TYPE_PRODUCT);
- }
- }
- foreach ($to_add as $add) {
- if ($c->fetch($add) > 0) {
- $c->add_type($this, Categorie::TYPE_PRODUCT);
- }
- }
-
- return;
+ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+ return parent::setCategoriesCommon($categories, Categorie::TYPE_PRODUCT);
}
/**
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index 0aeb64aa427..70f561acf2a 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -4266,47 +4266,7 @@ class Societe extends CommonObject
return -1;
}
- // Handle single category
- if (!is_array($categories)) {
- $categories = array($categories);
- }
-
- // Get current categories
- $c = new Categorie($this->db);
- $existing = $c->containing($this->id, $type_categ, 'id');
-
- // Diff
- if (is_array($existing)) {
- $to_del = array_diff($existing, $categories);
- $to_add = array_diff($categories, $existing);
- } else {
- $to_del = array(); // Nothing to delete
- $to_add = $categories;
- }
-
- $error = 0;
-
- // Process
- foreach ($to_del as $del) {
- if ($c->fetch($del) > 0) {
- $c->del_type($this, $type_categ);
- }
- }
- foreach ($to_add as $add) {
- if ($c->fetch($add) > 0)
- {
- $result = $c->add_type($this, $type_categ);
- if ($result < 0)
- {
- $error++;
- $this->error = $c->error;
- $this->errors = $c->errors;
- break;
- }
- }
- }
-
- return $error ? -1 : 1;
+ return parent::setCategoriesCommon($categories, $type_categ);
}
/**
diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php
index 2e24f355b37..ffdba17d24d 100644
--- a/htdocs/societe/list.php
+++ b/htdocs/societe/list.php
@@ -324,6 +324,7 @@ if (empty($reshook))
$objectlabel = 'ThirdParty';
$permissiontoread = $user->rights->societe->lire;
$permissiontodelete = $user->rights->societe->supprimer;
+ $permissiontoadd = $user->rights->societe->creer;
$uploaddir = $conf->societe->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
@@ -595,6 +596,7 @@ $arrayofmassactions = array(
);
//if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
if ($user->rights->societe->supprimer) $arrayofmassactions['predelete'] = ''.$langs->trans("Delete");
+if ($user->rights->societe->creer) $arrayofmassactions['preaffecttag'] = ''.$langs->trans("AffectTag");
if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) $arrayofmassactions = array();
$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php
index eb92bd51eb9..7e0c4628250 100644
--- a/htdocs/user/class/user.class.php
+++ b/htdocs/user/class/user.class.php
@@ -1159,40 +1159,7 @@ class User extends CommonObject
public function setCategories($categories)
{
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
-
- $type_categ = Categorie::TYPE_USER;
-
- // Handle single category
- if (!is_array($categories)) {
- $categories = array($categories);
- }
-
- // Get current categories
- $c = new Categorie($this->db);
- $existing = $c->containing($this->id, $type_categ, 'id');
-
- // Diff
- if (is_array($existing)) {
- $to_del = array_diff($existing, $categories);
- $to_add = array_diff($categories, $existing);
- } else {
- $to_del = array(); // Nothing to delete
- $to_add = $categories;
- }
-
- // Process
- foreach ($to_del as $del) {
- if ($c->fetch($del) > 0) {
- $c->del_type($this, $type_categ);
- }
- }
- foreach ($to_add as $add) {
- if ($c->fetch($add) > 0) {
- $c->add_type($this, $type_categ);
- }
- }
-
- return;
+ return parent::setCategoriesCommon($categories, Categorie::TYPE_USER);
}
/**
diff --git a/htdocs/user/list.php b/htdocs/user/list.php
index e7a8a31af4e..3e486fb0c70 100644
--- a/htdocs/user/list.php
+++ b/htdocs/user/list.php
@@ -422,6 +422,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
$arrayofmassactions = array();
if ($permissiontoadd) $arrayofmassactions['disable'] = $langs->trans("DisableUser");
if ($permissiontoadd) $arrayofmassactions['reactivate'] = $langs->trans("Reactivate");
+if ($permissiontoadd) $arrayofmassactions['preaffecttag'] = ''.$langs->trans("AffectTag");
//if ($permissiontodelete) $arrayofmassactions['predelete'] = ''.$langs->trans("Delete");
if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) $arrayofmassactions = array();