From 165d34ec56d12e29b79ab12235d7ca9bffcd9dbb Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Fri, 29 Oct 2021 12:49:27 +0200 Subject: [PATCH 01/82] Fix: Import don't work if extrafield is separator --- htdocs/core/modules/modAdherent.class.php | 2 +- htdocs/core/modules/modBom.class.php | 4 ++-- htdocs/core/modules/modCommande.class.php | 4 ++-- htdocs/core/modules/modFournisseur.class.php | 8 ++++---- htdocs/core/modules/modProduct.class.php | 4 ++-- htdocs/core/modules/modProjet.class.php | 2 +- htdocs/core/modules/modPropale.class.php | 4 ++-- htdocs/core/modules/modResource.class.php | 2 +- htdocs/core/modules/modService.class.php | 2 +- htdocs/core/modules/modSociete.class.php | 4 ++-- htdocs/core/modules/modUser.class.php | 2 +- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php index 074969451c1..a3942220286 100644 --- a/htdocs/core/modules/modAdherent.class.php +++ b/htdocs/core/modules/modAdherent.class.php @@ -349,7 +349,7 @@ class modAdherent extends DolibarrModules $this->import_fields_array[$r]['a.fk_soc'] = "ThirdParty"; } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'adherent' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'adherent' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modBom.class.php b/htdocs/core/modules/modBom.class.php index 18f46fda70f..febc6135fab 100644 --- a/htdocs/core/modules/modBom.class.php +++ b/htdocs/core/modules/modBom.class.php @@ -352,7 +352,7 @@ class modBom extends DolibarrModules // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'bom_bom' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'bom_bom' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { @@ -422,7 +422,7 @@ class modBom extends DolibarrModules ]; // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'bom_bomline' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'bom_bomline' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modCommande.class.php b/htdocs/core/modules/modCommande.class.php index 4275d806d40..6e486420328 100644 --- a/htdocs/core/modules/modCommande.class.php +++ b/htdocs/core/modules/modCommande.class.php @@ -322,7 +322,7 @@ class modCommande extends DolibarrModules // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'commande' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { @@ -404,7 +404,7 @@ class modCommande extends DolibarrModules } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commandedet' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'commandedet' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 5d71a5abdc8..4150ab019b3 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -541,7 +541,7 @@ class modFournisseur extends DolibarrModules } // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { @@ -628,7 +628,7 @@ class modFournisseur extends DolibarrModules } // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { @@ -717,7 +717,7 @@ class modFournisseur extends DolibarrModules // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { @@ -794,7 +794,7 @@ class modFournisseur extends DolibarrModules } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 37cda4b7b30..1736abef905 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -636,7 +636,7 @@ class modProduct extends DolibarrModules // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'product' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { @@ -797,7 +797,7 @@ class modProduct extends DolibarrModules // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product_fournisseur_price' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'product_fournisseur_price' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index 7acbb2bfb68..621d799d4f6 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -296,7 +296,7 @@ class modProjet extends DolibarrModules $this->import_tables_array[$r] = array('t'=>MAIN_DB_PREFIX.'projet_task', 'extra'=>MAIN_DB_PREFIX.'projet_task_extrafields'); // List of tables to insert into (insert done in same order) $this->import_fields_array[$r] = array('t.fk_projet'=>'ProjectRef*', 't.ref'=>'RefTask*', 't.label'=>'LabelTask*', 't.dateo'=>"DateStart", 't.datee'=>"DateEnd", 't.planned_workload'=>"PlannedWorkload", 't.progress'=>"Progress", 't.note_private'=>"NotePrivate", 't.note_public'=>"NotePublic", 't.datec'=>"DateCreation"); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php index eb589fc1759..becab61f862 100644 --- a/htdocs/core/modules/modPropale.class.php +++ b/htdocs/core/modules/modPropale.class.php @@ -302,7 +302,7 @@ class modPropale extends DolibarrModules } // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'propal' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'propal' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { @@ -386,7 +386,7 @@ class modPropale extends DolibarrModules } // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'propaldet' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'propaldet' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php index 6f2d3f8d409..7a042cf5ff7 100644 --- a/htdocs/core/modules/modResource.class.php +++ b/htdocs/core/modules/modResource.class.php @@ -268,7 +268,7 @@ class modResource extends DolibarrModules $this->import_tables_array[$r] = array('r'=>MAIN_DB_PREFIX.'resource', 'extra'=>MAIN_DB_PREFIX.'resource_extrafields'); // List of tables to insert into (insert done in same order) $this->import_fields_array[$r] = array('r.ref'=>"ResourceFormLabel_ref*", 'r.fk_code_type_resource'=>'ResourceTypeCode', 'r.description'=>'ResourceFormLabel_description', 'r.note_private'=>"NotePrivate", 'r.note_public'=>"NotePublic", 'r.asset_number'=>'AssetNumber', 'r.datec'=>'DateCreation'); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'resource' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'resource' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 21a26bdc750..60383bf3bea 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -584,7 +584,7 @@ class modService extends DolibarrModules } // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'product' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 7c3d93499e4..41d21874c31 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -496,7 +496,7 @@ class modSociete extends DolibarrModules $this->import_fields_array[$r] += array('s.accountancy_code_sell'=>'ProductAccountancySellCode', 's.accountancy_code_buy'=>'ProductAccountancyBuyCode'); } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { @@ -674,7 +674,7 @@ class modSociete extends DolibarrModules 's.note_public' => "NotePublic" ); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on an old database (during a migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php index e54ac7bd440..47cd04ecd26 100644 --- a/htdocs/core/modules/modUser.class.php +++ b/htdocs/core/modules/modUser.class.php @@ -298,7 +298,7 @@ class modUser extends DolibarrModules 'u.statut'=>'Status' ); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'user' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'user' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { From 95aabd6ae3aa0c2b1eac72ec908a6b20190b82e8 Mon Sep 17 00:00:00 2001 From: iouston <4319513+iouston@users.noreply.github.com> Date: Fri, 4 Feb 2022 14:38:34 +0100 Subject: [PATCH 02/82] add target attribute on getNomUrl --- htdocs/commande/class/commande.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index c315a4fcd61..52938320bd6 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3659,9 +3659,10 @@ class Commande extends CommonOrder * @param int $notooltip 1=Disable tooltip * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @param int $addlinktonotes Add link to notes + * @param string target attribute target for link * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0) + public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target='_self') { global $conf, $langs, $user; @@ -3730,6 +3731,11 @@ class Commande extends CommonOrder } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip"'; + + $target_value=array('_self','_blank','_parent','_top',); + if(in_array($target,$target_value)){ + $linkclose .= ' target="'.$target.'"'; + } } $linkstart = ' Date: Fri, 4 Feb 2022 13:42:07 +0000 Subject: [PATCH 03/82] Fixing style errors. --- htdocs/commande/class/commande.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 52938320bd6..42dad969086 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3662,7 +3662,7 @@ class Commande extends CommonOrder * @param string target attribute target for link * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target='_self') + public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target = '_self') { global $conf, $langs, $user; @@ -3731,10 +3731,10 @@ class Commande extends CommonOrder } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip"'; - + $target_value=array('_self','_blank','_parent','_top',); - if(in_array($target,$target_value)){ - $linkclose .= ' target="'.$target.'"'; + if (in_array($target, $target_value)) { + $linkclose .= ' target="'.$target.'"'; } } From 0cc8e6873ffd10bd679e4c976e2979f59feb0b72 Mon Sep 17 00:00:00 2001 From: iouston <4319513+iouston@users.noreply.github.com> Date: Fri, 4 Feb 2022 14:44:47 +0100 Subject: [PATCH 04/82] add attribute target on getNomurl() --- htdocs/societe/class/societe.class.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index a49bf478763..319c4dbfa46 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2529,9 +2529,10 @@ class Societe extends CommonObject * @param int $notooltip 1=Disable tooltip * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @param int $noaliasinname 1=Do not add alias into the link ref + * @param string $target add attribute target * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0) + public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target='_self') { global $conf, $langs, $hookmanager; @@ -2703,6 +2704,10 @@ class Societe extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip refurl"'; + $target_value=array('_self','_blank','_parent','_top',); + if(in_array($target,$target_value)){ + $linkclose .= ' target="'.$target.'"'; + } /* $hookmanager->initHooks(array('thirdpartydao')); From 7e6279e94236d9c6e1b0a249f4c0bcf55bf99989 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 4 Feb 2022 13:48:25 +0000 Subject: [PATCH 05/82] Fixing style errors. --- htdocs/societe/class/societe.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 319c4dbfa46..48d43a34a4f 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2532,7 +2532,7 @@ class Societe extends CommonObject * @param string $target add attribute target * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target='_self') + public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target = '_self') { global $conf, $langs, $hookmanager; @@ -2705,8 +2705,8 @@ class Societe extends CommonObject $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip refurl"'; $target_value=array('_self','_blank','_parent','_top',); - if(in_array($target,$target_value)){ - $linkclose .= ' target="'.$target.'"'; + if (in_array($target, $target_value)) { + $linkclose .= ' target="'.$target.'"'; } /* From 993e0d852c45b62a81eb0fbab551a65fac013c38 Mon Sep 17 00:00:00 2001 From: iouston <4319513+iouston@users.noreply.github.com> Date: Fri, 4 Feb 2022 15:01:32 +0100 Subject: [PATCH 06/82] fix parameter name --- htdocs/commande/class/commande.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 42dad969086..cae5b638a0b 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3659,7 +3659,7 @@ class Commande extends CommonOrder * @param int $notooltip 1=Disable tooltip * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @param int $addlinktonotes Add link to notes - * @param string target attribute target for link + * @param string $target attribute target for link * @return string String with URL */ public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target = '_self') From 1bc80df6438a3a4433f2e42afce85fa7cf073920 Mon Sep 17 00:00:00 2001 From: iouston <4319513+iouston@users.noreply.github.com> Date: Tue, 15 Feb 2022 09:32:27 +0100 Subject: [PATCH 07/82] keep the default value for target in getnomurl to '' --- htdocs/societe/class/societe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 48d43a34a4f..bb475a03fdd 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2532,7 +2532,7 @@ class Societe extends CommonObject * @param string $target add attribute target * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target = '_self') + public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target = '') { global $conf, $langs, $hookmanager; From 4808442bc8325dd37daf9b91023ce4e78a099a76 Mon Sep 17 00:00:00 2001 From: iouston <4319513+iouston@users.noreply.github.com> Date: Tue, 15 Feb 2022 09:34:51 +0100 Subject: [PATCH 08/82] keep the default value for target in getnomurl to '' --- htdocs/commande/class/commande.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index cae5b638a0b..c0f460935e6 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3662,7 +3662,7 @@ class Commande extends CommonOrder * @param string $target attribute target for link * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target = '_self') + public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target = '') { global $conf, $langs, $user; From 2595f1f9ee46938f9e1d165c3fcd64c0d8d61297 Mon Sep 17 00:00:00 2001 From: BB2A Anthony Berton Date: Mon, 21 Feb 2022 15:56:09 +0100 Subject: [PATCH 09/82] sens dump --- htdocs/core/class/utils.class.php | 93 +++++++++++++++++++++++++++ htdocs/core/modules/modCron.class.php | 2 + htdocs/langs/en_US/cron.lang | 2 + 3 files changed, 97 insertions(+) diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 2fa329406fb..81859c94604 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2021 Regis Houssin + * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1176,4 +1177,96 @@ class Utils return 1; } + + /** + * Make a send last backup of database or fil in param + * CAN BE A CRON TASK + * + * @param string $sendto Recipients emails + * @param string $from Sender email + * @param string $subject Topic/Subject of mail + * @param string $message Message + * @param string $filename List of files to attach (full path of filename on file system) + * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) + */ + public function sendDumpDatabase($sendto = '', $from = '', $subject = '', $message = '', $filename = '') + { + global $conf, $langs; + + $output = ''; + + if (!empty($from)) { + $from = dol_escape_htmltag($from); + } elseif (!empty($conf->global->MAIN_INFO_SOCIETE_MAIL)) { + $from = dol_escape_htmltag($conf->global->MAIN_INFO_SOCIETE_MAIL); + } else { + $error++; + } + + if (!empty($sendto)) { + $sendto = dol_escape_htmltag($sendto); + } else { + $error++; + } + + if (!empty($subject)) { + $subject = dol_escape_htmltag($subject); + } else { + $subject = dol_escape_htmltag($langs->trans('MakeSendLocalDatabaseDumpShort')); + } + + if (empty($message)) { + $message = dol_escape_htmltag($langs->trans('MakeSendLocalDatabaseDumpShort')); + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + if ($filename) { + if (dol_is_file($conf->admin->dir_output.'/backup/'.$filename)) { + $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup', $filename); + } + } else { + $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup'); + } + if ($tmpfiles) { + foreach ($tmpfiles as $key => $val) { + if ($key == 'fullname') { + $filepath = array($val); + $filesize = dol_filesize($val); + } + if ($key == 'type') { + $mimetype = array($val); + } + if ($key == 'relativename') { + $filename = array($val); + } + } + } + if ($filepath) { + if ($filesize > 100000000) { + $error++; + } + } else { + $error++; + } + if (!$error) { + include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1); + if ($mailfile->error) { + $error++; + } else { + $result = $mailfile->sendfile(); + } + } + + dol_syslog(__METHOD__, LOG_DEBUG); + + $this->error = $error; + $this->output = $output; + + if ($result == true) { + return 0; + } else { + return $result; + } + } } diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index 60d713d5fc4..f15c74f21f2 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -1,6 +1,7 @@ + * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -99,6 +100,7 @@ class modCron extends DolibarrModules $this->cronjobs = array( 0=>array('entity'=>0, 'label'=>'PurgeDeleteTemporaryFilesShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'purgeFiles', 'parameters'=>'tempfilesold+logfiles', 'comment'=>'PurgeDeleteTemporaryFiles', 'frequency'=>2, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>50, 'status'=>1, 'test'=>true), 1=>array('entity'=>0, 'label'=>'MakeLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'dumpDatabase', 'parameters'=>'none,auto,1,auto,10', 'comment'=>'MakeLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>90, 'status'=>0, 'test'=>in_array($this->db->type, array('mysql', 'mysqli'))), + 2=>array('entity'=>0, 'label'=>'MakeSendLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'sendDumpDatabase', 'parameters'=>'', 'comment'=>'MakeSendLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>604800, 'priority'=>91, 'status'=>0, 'test'=>in_array($this->db->type, array('mysql', 'mysqli'))), // 1=>array('entity'=>0, 'label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24) ); diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang index 4fd2220dea6..da5888adf83 100644 --- a/htdocs/langs/en_US/cron.lang +++ b/htdocs/langs/en_US/cron.lang @@ -82,6 +82,8 @@ UseMenuModuleToolsToAddCronJobs=Go into menu "Home - Admin tools - JobDisabled=Job disabled MakeLocalDatabaseDumpShort=Local database backup MakeLocalDatabaseDump=Create a local database dump. Parameters are: compression ('gz' or 'bz' or 'none'), backup type ('mysql', 'pgsql', 'auto'), 1, 'auto' or filename to build, number of backup files to keep +MakeSendLocalDatabaseDumpShort=Send local database backup +MakeSendLocalDatabaseDump=Send local datebase backup to mail. Parameters are: to, from, subject, message , filename WarningCronDelayed=Attention, for performance purpose, whatever is next date of execution of enabled jobs, your jobs may be delayed to a maximum of %s hours, before being run. DATAPOLICYJob=Data cleaner and anonymizer JobXMustBeEnabled=Job %s must be enabled From d28ba84cb3ed7ea39469595a614178e1970d54ac Mon Sep 17 00:00:00 2001 From: BB2A Anthony Berton Date: Mon, 21 Feb 2022 16:15:40 +0100 Subject: [PATCH 10/82] Mail sendto default and add filter --- htdocs/core/class/utils.class.php | 7 +++++-- htdocs/core/modules/modCron.class.php | 2 +- htdocs/langs/en_US/cron.lang | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 81859c94604..da3b775f4db 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -1187,9 +1187,10 @@ class Utils * @param string $subject Topic/Subject of mail * @param string $message Message * @param string $filename List of files to attach (full path of filename on file system) + * @param string $filter Filter file send * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ - public function sendDumpDatabase($sendto = '', $from = '', $subject = '', $message = '', $filename = '') + public function sendBackup($sendto = '', $from = '', $subject = '', $message = '', $filename = '', $filter = '') { global $conf, $langs; @@ -1205,6 +1206,8 @@ class Utils if (!empty($sendto)) { $sendto = dol_escape_htmltag($sendto); + } elseif (!empty($conf->global->MAIN_INFO_SOCIETE_MAIL)) { + $from = dol_escape_htmltag($conf->global->MAIN_INFO_SOCIETE_MAIL); } else { $error++; } @@ -1225,7 +1228,7 @@ class Utils $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup', $filename); } } else { - $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup'); + $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup', $filter); } if ($tmpfiles) { foreach ($tmpfiles as $key => $val) { diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index f15c74f21f2..fb852af19fd 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -100,7 +100,7 @@ class modCron extends DolibarrModules $this->cronjobs = array( 0=>array('entity'=>0, 'label'=>'PurgeDeleteTemporaryFilesShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'purgeFiles', 'parameters'=>'tempfilesold+logfiles', 'comment'=>'PurgeDeleteTemporaryFiles', 'frequency'=>2, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>50, 'status'=>1, 'test'=>true), 1=>array('entity'=>0, 'label'=>'MakeLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'dumpDatabase', 'parameters'=>'none,auto,1,auto,10', 'comment'=>'MakeLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>90, 'status'=>0, 'test'=>in_array($this->db->type, array('mysql', 'mysqli'))), - 2=>array('entity'=>0, 'label'=>'MakeSendLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'sendDumpDatabase', 'parameters'=>'', 'comment'=>'MakeSendLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>604800, 'priority'=>91, 'status'=>0, 'test'=>in_array($this->db->type, array('mysql', 'mysqli'))), + 2=>array('entity'=>0, 'label'=>'MakeSendLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'sendDumpDatabase', 'parameters'=>',,,,,sql', 'comment'=>'MakeSendLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>604800, 'priority'=>91, 'status'=>0, 'test'=>in_array($this->db->type, array('mysql', 'mysqli'))), // 1=>array('entity'=>0, 'label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24) ); diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang index da5888adf83..978188a3199 100644 --- a/htdocs/langs/en_US/cron.lang +++ b/htdocs/langs/en_US/cron.lang @@ -83,7 +83,7 @@ JobDisabled=Job disabled MakeLocalDatabaseDumpShort=Local database backup MakeLocalDatabaseDump=Create a local database dump. Parameters are: compression ('gz' or 'bz' or 'none'), backup type ('mysql', 'pgsql', 'auto'), 1, 'auto' or filename to build, number of backup files to keep MakeSendLocalDatabaseDumpShort=Send local database backup -MakeSendLocalDatabaseDump=Send local datebase backup to mail. Parameters are: to, from, subject, message , filename +MakeSendLocalDatabaseDump=Send local datebase backup to mail. Parameters are: to, from, subject, message , filename (Name file send), filter (sql for only database) WarningCronDelayed=Attention, for performance purpose, whatever is next date of execution of enabled jobs, your jobs may be delayed to a maximum of %s hours, before being run. DATAPOLICYJob=Data cleaner and anonymizer JobXMustBeEnabled=Job %s must be enabled From e107423c2199823f4f602120087e05e317dcb55d Mon Sep 17 00:00:00 2001 From: GregM Date: Tue, 22 Feb 2022 12:25:30 +0100 Subject: [PATCH 11/82] fix : change title if html not set --- htdocs/core/lib/functions.lib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7be3f5e3351..9a866303eb3 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9965,6 +9965,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = if (empty($html)) { $html = $label; + $attr['title'] = ''; // if html not set, leave label on title is redundant } else { $attr['aria-label'] = $label; } From 3edd478a467903452f6153372b2f2beae0345993 Mon Sep 17 00:00:00 2001 From: GregM Date: Wed, 23 Feb 2022 15:36:43 +0100 Subject: [PATCH 12/82] Fix empty url : dont add token --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 9a866303eb3..b1f99d6f3f3 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9954,7 +9954,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = $class = 'butAction'; if ($actionType == 'danger' || $actionType == 'delete') { $class = 'butActionDelete'; - if (strpos($url, 'token=') === false) $url .= '&token='.newToken(); + if (!empty($url) && strpos($url, 'token=') === false) $url .= '&token='.newToken(); } $attr = array( From cf470c23061b1f6165774e47ad30458ddbd4b8ec Mon Sep 17 00:00:00 2001 From: GregM Date: Wed, 23 Feb 2022 16:01:07 +0100 Subject: [PATCH 13/82] Add auto tooltip --- htdocs/core/lib/functions.lib.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b1f99d6f3f3..0ad9c638cd6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9979,6 +9979,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = $attr['id'] = $id; } + // Override attr if (!empty($params['attr']) && is_array($params['attr'])) { foreach ($params['attr'] as $key => $value) { @@ -9992,6 +9993,11 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = } } + // automatic add tooltip when title is detected + if (!empty($attr['title']) && !empty($attr['class']) && strpos($attr['class'], 'classfortooltip') === false) { + $attr['class'].= ' classfortooltip'; + } + // Js Confirm button if ($userRight && !empty($params['confirm'])) { if (!is_array($params['confirm'])) { From d2cbead2039465f53348631e5d2880bd6bef8cd5 Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 25 Feb 2022 09:17:18 +0100 Subject: [PATCH 14/82] Add an ID into formproject method to be able to target --- htdocs/core/class/html.form.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 6e5c0a572d2..7bc80ae6107 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5199,13 +5199,17 @@ class Form $out .= ''; $out .= ''; } else { + $out .= ''; if ($selected) { $projet = new Project($this->db); $projet->fetch($selected); - $out .= $projet->getNomUrl(1, '', 1); + + $out .= $projet->getNomUrl(1, '', 1); + } else { $out .= " "; } + $out .= ''; } if (empty($nooutput)) { From aabfdfa21239789d52df9a0c9630704566ed14d7 Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 25 Feb 2022 09:20:36 +0100 Subject: [PATCH 15/82] Format code --- htdocs/core/class/html.form.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 7bc80ae6107..2d5146ced91 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5203,9 +5203,7 @@ class Form if ($selected) { $projet = new Project($this->db); $projet->fetch($selected); - $out .= $projet->getNomUrl(1, '', 1); - } else { $out .= " "; } From 24be13160060c7b95759185ce11e03f07a3f62ec Mon Sep 17 00:00:00 2001 From: Anthony Berton <34568357+bb2a@users.noreply.github.com> Date: Fri, 25 Feb 2022 14:51:40 +0100 Subject: [PATCH 16/82] Update 14.0.0-15.0.0.sql --- htdocs/install/mysql/migration/14.0.0-15.0.0.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 4d4248c1ac0..1f9825b0f69 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -503,3 +503,5 @@ INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) value INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_APPROVE','Holiday aprouved','Executed when a holiday is aprouved','holiday',803); INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_CANCEL','Holiday canceled','Executed when a holiday is canceled','holiday',802); INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_DELETE','Holiday deleted','Executed when a holiday is deleted','holiday',804); + +ALTER TABLE llx_propal ADD last_main_doc VARCHAR(255) NULL AFTER model_pdf; From 647104cbb66b692596bd6597232c3b303114f4f7 Mon Sep 17 00:00:00 2001 From: Anthony Berton <34568357+bb2a@users.noreply.github.com> Date: Fri, 25 Feb 2022 14:54:21 +0100 Subject: [PATCH 17/82] Update llx_societe.sql --- htdocs/install/mysql/tables/llx_societe.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index c8b78d42fae..c27a0fb2910 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -77,7 +77,8 @@ create table llx_societe fk_stcomm integer DEFAULT 0 NOT NULL, -- commercial status note_private text, -- note_public text, -- - model_pdf varchar(255), + model_pdf varchar(255), + last_main_doc varchar(255), -- relative filepath+filename of last main generated document prefix_comm varchar(5), -- prefix commercial (deprecated) client tinyint DEFAULT 0, -- client 0/1/2 fournisseur tinyint DEFAULT 0, -- fournisseur 0/1 From e1e643efba9edf44469aefb066101128b409acd5 Mon Sep 17 00:00:00 2001 From: Thomas Negre Date: Tue, 8 Feb 2022 16:32:02 +0100 Subject: [PATCH 18/82] Ticket : add option TICKET_NOTIFY_AT_CLOSING to ticket config panel --- htdocs/admin/ticket.php | 21 +++++++++++++++++++++ htdocs/core/modules/modTicket.class.php | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index c36f6ae1d1b..68f256e2009 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -203,6 +203,12 @@ if ($action == 'setvarother') { if (!($res > 0)) { $error++; } + + $param_auto_notify_close = GETPOST('TICKET_NOTIFY_AT_CLOSING', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_NOTIFY_AT_CLOSING', $param_auto_notify_close, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } } @@ -530,6 +536,21 @@ print $form->textwithpicto('', $langs->trans("TicketsAutoAssignTicketHelp"), 1, print ''; print ''; +// Auto notify contacts when closing the ticket +print ''.$langs->trans("TicketsAutoNotifyClose").''; +print ''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_NOTIFY_AT_CLOSING'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("TICKET_NOTIFY_AT_CLOSING", $arrval, $conf->global->TICKET_NOTIFY_AT_CLOSING); +} +print ''; +print ''; +print $form->textwithpicto('', $langs->trans("TicketsAutoNotifyCloseHelp"), 1, 'help'); +print ''; +print ''; + if (!$conf->use_javascript_ajax) { print ''; } diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 0ae6b00b1c3..86841ce5932 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -109,7 +109,8 @@ class modTicket extends DolibarrModules 3 => array('TICKET_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/tickets', 'Ticket templates ODT/ODS directory for templates', 0), 4 => array('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND', 'chaine', 0, 'Automatically mark ticket as read when created from backend', 0), 5 => array('TICKET_DELAY_BEFORE_FIRST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time before a first answer to a ticket (in hours). Display a warning in tickets list if not respected.', 0), - 6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0) + 6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0), + 7 => array('TICKET_NOTIFY_AT_CLOSING', 'chaine', '0', 'Default notify contacts when closing a module', 0), ); From 5b1b862687cd43513af6a5cd727b436807c80c11 Mon Sep 17 00:00:00 2001 From: Thomas Negre Date: Wed, 9 Feb 2022 11:25:31 +0100 Subject: [PATCH 19/82] reformat trigger/interface_50_modTicket_TicketEmail.class.php to create methods for email composition and sending --- ...terface_50_modTicket_TicketEmail.class.php | 269 +++++++++--------- 1 file changed, 141 insertions(+), 128 deletions(-) diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index dfd83022393..4b155082453 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -133,71 +133,21 @@ class InterfaceTicketEmail extends DolibarrTriggers $langs->load('ticket'); + $subject_admin = 'TicketNewEmailSubjectAdmin'; + $body_admin = 'TicketNewEmailBodyAdmin'; + $subject_customer = 'TicketNewEmailSubjectCustomer'; + $body_customer = 'TicketNewEmailBodyCustomer'; + $see_ticket_customer = 'TicketNewEmailBodyInfosTrackUrlCustomer'; + // Send email to notification email if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && empty($object->context['disableticketemail'])) { $sendto = empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; - if ($sendto) { - // Init to avoid errors - $filepath = array(); - $filename = array(); - $mimetype = array(); - - /* Send email to admin */ - $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectAdmin'); - $message_admin = $langs->transnoentities('TicketNewEmailBodyAdmin', $object->track_id).'

'; - $message_admin .= '
  • '.$langs->trans('Title').' : '.$object->subject.'
  • '; - $message_admin .= '
  • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
  • '; - $message_admin .= '
  • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
  • '; - $message_admin .= '
  • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
  • '; - $message_admin .= '
  • '.$langs->trans('From').' : '.($object->email_from ? $object->email_from : ($object->fk_user_create > 0 ? $langs->trans('Internal') : '')).'
  • '; - // Extrafields - $extraFields = new ExtraFields($this->db); - $extraFields->fetch_name_optionals_label($object->table_element); - if (is_array($object->array_options) && count($object->array_options) > 0) { - foreach ($object->array_options as $key => $value) { - $key = substr($key, 8); // remove "options_" - $message_admin .= '
  • '.$langs->trans($extraFields->attributes[$object->element]['label'][$key]).' : '.$extraFields->showOutputField($key, $value, '', $object->table_element).'
  • '; - } - } - $message_admin .= '
'; - - if ($object->fk_soc > 0) { - $object->fetch_thirdparty(); - $message_admin .= '

'.$langs->trans('Company').' : '.$object->thirdparty->name.'

'; - } - - $message = $object->message; - if (!dol_textishtml($message)) { - $message = dol_nl2br($message); - } - $message_admin .= '

'.$langs->trans('Message').' :
'.$message.'

'; - $message_admin .= '

'.$langs->trans('SeeThisTicketIntomanagementInterface').'

'; - - $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; - $replyto = $from; - - $trackid = 'tic'.$object->id; - - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; - $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; - } - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); - if ($mailfile->error) { - dol_syslog($mailfile->error, LOG_DEBUG); - } else { - $result = $mailfile->sendfile(); - } - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; - } + $this->ComposeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs, $conf); } } // Send email to customer - if (empty($conf->global->TICKET_DISABLE_CUSTOMER_MAILS) && empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) { $sendto = ''; @@ -218,77 +168,7 @@ class InterfaceTicketEmail extends DolibarrTriggers } if ($sendto) { - // Init to avoid errors - $filepath = array(); - $filename = array(); - $mimetype = array(); - - $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectCustomer'); - $message_customer = $langs->transnoentities('TicketNewEmailBodyCustomer', $object->track_id).'

'; - $message_customer .= ''; - - $message = $object->message; - if (!dol_textishtml($message)) { - $message = dol_nl2br($message); - } - $message_customer .= '

'.$langs->trans('Message').' :
'.$message.'

'; - $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id; - $message_customer .= '

'.$langs->trans('TicketNewEmailBodyInfosTrackUrlCustomer').' : '.$url_public_ticket.'

'; - $message_customer .= '

'.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'

'; - - $from = (empty($conf->global->MAIN_INFO_SOCIETE_NOM) ? '' : $conf->global->MAIN_INFO_SOCIETE_NOM.' ').'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; - $replyto = $from; - - $trackid = 'tic'.$object->id; - - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; - $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; - } - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); - if ($mailfile->error) { - dol_syslog($mailfile->error, LOG_DEBUG); - } else { - $result = $mailfile->sendfile(); - if ($result) { - // update last_msg_sent date - $object->date_last_msg_sent = dol_now(); - $object->update($user); - } - } - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; - } + $this->ComposeAndSendCustomerMessage($sendto, $subject_customer, $body_customer, $see_ticket_customer, $object, $langs, $conf); } } @@ -311,4 +191,137 @@ class InterfaceTicketEmail extends DolibarrTriggers return $ok; } + + private function ComposeAndSendAdminMessage($sendto, $base_subject, $body, Ticket $object, Translate $langs, $conf) + { + // Init to avoid errors + $filepath = array(); + $filename = array(); + $mimetype = array(); + + /* Send email to admin */ + $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject); + $message_admin = $langs->transnoentities($body, $object->track_id).'

'; + $message_admin .= ''; + + if ($object->fk_soc > 0) { + $object->fetch_thirdparty(); + $message_admin .= '

'.$langs->trans('Company').' : '.$object->thirdparty->name.'

'; + } + + $message = $object->message; + if (!dol_textishtml($message)) { + $message = dol_nl2br($message); + } + $message_admin .= '

'.$langs->trans('Message').' :
'.$message.'

'; + $message_admin .= '

'.$langs->trans('SeeThisTicketIntomanagementInterface').'

'; + + $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; + + $trackid = 'tic'.$object->id; + + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; + $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; + } + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); + if ($mailfile->error) { + dol_syslog($mailfile->error, LOG_DEBUG); + } else { + $result = $mailfile->sendfile(); + } + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; + } + } + + private function ComposeAndSendCustomerMessage ($sendto, $base_subject, $body, $see_ticket, Ticket $object, Translate $langs, $conf) + { + // Init to avoid errors + $filepath = array(); + $filename = array(); + $mimetype = array(); + + $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject); + $message_customer = $langs->transnoentities($body, $object->track_id).'

'; + $message_customer .= ''; + + $message = $object->message; + if (!dol_textishtml($message)) { + $message = dol_nl2br($message); + } + $message_customer .= '

'.$langs->trans('Message').' :
'.$message.'

'; + $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id; + $message_customer .= '

'.$langs->trans($see_ticket).' : '.$url_public_ticket.'

'; + $message_customer .= '

'.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'

'; + + $from = (empty($conf->global->MAIN_INFO_SOCIETE_NOM) ? '' : $conf->global->MAIN_INFO_SOCIETE_NOM.' ').'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; + + $trackid = 'tic'.$object->id; + + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; + $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; + } + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); + if ($mailfile->error) { + dol_syslog($mailfile->error, LOG_DEBUG); + } else { + $result = $mailfile->sendfile(); + if ($result) { + // update last_msg_sent date + $object->date_last_msg_sent = dol_now(); + $object->update($user); + } + } + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; + } + } + } From dcc41d0ab70aebe19dd61abaedcab443f5a8811d Mon Sep 17 00:00:00 2001 From: Thomas Negre Date: Mon, 28 Feb 2022 15:09:58 +0100 Subject: [PATCH 20/82] Ticket triggers: allow to automatically send messages on TICKET_CLOSE event --- ...terface_50_modTicket_TicketEmail.class.php | 111 +++++++++++++----- 1 file changed, 84 insertions(+), 27 deletions(-) diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index 4b155082453..0816657fa13 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -185,10 +185,65 @@ class InterfaceTicketEmail extends DolibarrTriggers case 'TICKET_CLOSE': dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + $langs->load('ticket'); + + $subject_admin = 'TicketCloseEmailSubjectAdmin'; + $body_admin = 'TicketCloseEmailBodyAdmin'; + $subject_customer = 'TicketCloseEmailSubjectCustomer'; + $body_customer = 'TicketCloseEmailBodyCustomer'; + $see_ticket_customer = 'TicketCloseEmailBodyInfosTrackUrlCustomer'; + + // Send email to notification email + if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && empty($object->context['disableticketemail'])) { + $sendto = empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + if ($sendto) { + $this->ComposeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs, $conf); + } + } + + // Send email to customer. + if (empty($conf->global->TICKET_DISABLE_CUSTOMER_MAILS) && empty($object->context['disableticketemail'])) { + $linked_contacts = $object->listeContact(-1, 'thirdparty'); + $linked_contacts = array_merge($linked_contacts, $object->listeContact(-1, 'internal')); + if (empty($linked_contacts) && !empty($conf->global->TICKET_NOTIFY_AT_CLOSING) && !empty($object->fk_soc)) { + $object->fetch_thirdparty(); + $linked_contacts[] = $object->thirdparty->email; + } + + $contactid = GETPOST('contactid', 'int'); + if ($contactid > 0) { + $contact = new Contact($this->db); + $res = $contact->fetch($contactid); + if (! in_array($contact, $linked_contacts)) { + $error_msg = $langs->trans('Error'). ': '; + $error_msg .= $langs->transnoentities('TicketWrongContact'); + setEventMessages($error_msg, [], 'errors'); + $ok = 0; + break; + } + } + + $sendto = ''; + if ($res > 0 && !empty($contact->email) && !empty($contact->statut)) { + $sendto = $contact->email; + // if sending to all contacts or sending to contacts while mass closing + } elseif ( !empty($linked_contacts) && ($contactid == -2 || (GETPOST('massaction', 'alpha') == 'close' && GETPOST('confirm', 'alpha') == 'yes'))) { + $temp_emails = []; + foreach($linked_contacts as $contact) { + $temp_emails[] = $contact['email']; + } + $sendto = implode(", ", $temp_emails); + unset($temp_emails); + unset($linked_contacts); + } + if ($sendto) { + $this->ComposeAndSendCustomerMessage($sendto, $subject_customer, $body_customer, $see_ticket_customer, $object, $langs, $conf); + } + } + $ok = 1; break; } - return $ok; } @@ -200,8 +255,8 @@ class InterfaceTicketEmail extends DolibarrTriggers $mimetype = array(); /* Send email to admin */ - $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject); - $message_admin = $langs->transnoentities($body, $object->track_id).'

'; + $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject, $object->ref, $object->track_id); + $message_admin = $langs->transnoentities($body, $object->track_id).'
'; $message_admin .= ''; - if ($object->fk_soc > 0) { $object->fetch_thirdparty(); - $message_admin .= '

'.$langs->trans('Company').' : '.$object->thirdparty->name.'

'; + $message_admin .= '
  • '.$langs->trans('Company').' : '.$object->thirdparty->name.'
  • '; } + $message_admin .= ''; $message = $object->message; if (!dol_textishtml($message)) { $message = dol_nl2br($message); } - $message_admin .= '

    '.$langs->trans('Message').' :
    '.$message.'

    '; + $message_admin .= '

    '.$langs->trans('Message').' :

    '.$message.'


    '; $message_admin .= '

    '.$langs->trans('SeeThisTicketIntomanagementInterface').'

    '; $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; @@ -258,33 +312,35 @@ class InterfaceTicketEmail extends DolibarrTriggers $mimetype = array(); $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject); - $message_customer = $langs->transnoentities($body, $object->track_id).'

    '; + $message_customer = $langs->transnoentities($body, $object->track_id).'
    '; $message_customer .= '