From ba7b6a8d5146ba0d7f077701a8e8aae1b3acba2b Mon Sep 17 00:00:00 2001 From: kamel Date: Mon, 21 Jun 2021 16:38:36 +0200 Subject: [PATCH 001/195] FIX: Reload values of the specified entity when change entity in the execution of cron job --- htdocs/core/class/conf.class.php | 67 +++++++++++++++++++++++++++++ htdocs/cron/class/cronjob.class.php | 16 +++---- 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 8766d68c25b..ed919be568c 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -151,6 +151,19 @@ class Conf $this->productbatch = new stdClass(); } + /** + * Load setup values into conf object (read llx_const) for a specified entity + * Note that this->db->xxx, this->file->xxx and this->multicompany have been already loaded when setValues is called. + * + * @param DoliDB $db Database handler + * @param int $entity Entity to get + * @return int < 0 if KO, >= 0 if OK + */ + function setEntityValues($db, $entity) + { + $this->entity = $entity; + $this->setValues($db); + } /** * Load setup values into conf object (read llx_const) @@ -161,6 +174,60 @@ class Conf */ public function setValues($db) { + global $conf; + + // Unset all old modules values + if (!empty($this->modules)) { + foreach ($this->modules as $m) { + if (isset($this->$m)) unset($this->$m); + } + } + + // Properly declare multi-modules objects. + $this->global = new stdClass(); + $this->multicompany = new stdClass(); + + // First level object + // TODO Remove this part. + $this->expedition_bon = new stdClass(); + $this->delivery_note = new stdClass(); + $this->fournisseur = new stdClass(); + $this->product = new stdClass(); + $this->service = new stdClass(); + $this->contrat = new stdClass(); + $this->actions = new stdClass(); + $this->agenda = new stdClass(); + $this->commande = new stdClass(); + $this->propal = new stdClass(); + $this->facture = new stdClass(); + $this->contrat = new stdClass(); + $this->usergroup = new stdClass(); + $this->adherent = new stdClass(); + $this->bank = new stdClass(); + $this->notification = new stdClass(); + $this->mailing = new stdClass(); + $this->expensereport = new stdClass(); + $this->productbatch = new stdClass(); + $this->modules = array();; + $this->modules_parts = array( + 'css' => array(), + 'js' => array(), + 'tabs' => array(), + 'triggers' => array(), + 'login' => array(), + 'substitutions' => array(), + 'menus' => array(), + 'theme' => array(), + 'sms' => array(), + 'tpl' => array(), + 'barcode' => array(), + 'models' => array(), + 'societe' => array(), + 'hooks' => array(), + 'dir' => array(), + 'syslog' => array(), + ); + dol_syslog(get_class($this)."::setValues"); //Define all global constants into $this->global->key=value diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 2ffce20a924..e2b7c2da47b 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1081,7 +1081,7 @@ class Cronjob extends CommonObject dol_syslog("We try to run a job in entity ".$this->entity." when we are in entity ".$conf->entity, LOG_WARNING); } $savcurrententity = $conf->entity; - $conf->entity = $this->entity; + $conf->setEntityValues($this->db, $this->entity); dol_syslog(get_class($this)."::run_jobs entity for running job is ".$conf->entity); require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; @@ -1090,13 +1090,13 @@ class Cronjob extends CommonObject if ($result < 0) { $this->error = "User Error:".$user->error; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->entity = $savcurrententity; + $conf->setEntityValues($this->db, $savcurrententity); return -1; } else { if (empty($user->id)) { $this->error = " User user login:".$userlogin." do not exists"; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->entity = $savcurrententity; + $conf->setEntityValues($this->db, $savcurrententity); return -1; } } @@ -1126,7 +1126,7 @@ class Cronjob extends CommonObject $result = $this->update($user); // This include begin/commit if ($result < 0) { dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->entity = $savcurrententity; + $conf->setEntityValues($this->db, $savcurrententity); return -1; } @@ -1241,7 +1241,7 @@ class Cronjob extends CommonObject if ($ret === false) { $this->error = $langs->trans('CronCannotLoadLib').': '.$libpath; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->entity = $savcurrententity; + $conf->setEntityValues($this->db, $savcurrententity); return -1; } @@ -1250,7 +1250,7 @@ class Cronjob extends CommonObject $result = $langs->load($this->module_name.'@'.$this->module_name); // If this->module_name was an existing language file, this will make nothing if ($result < 0) { // If technical error dol_syslog(get_class($this)."::run_jobs Cannot load module langs".$langs->error, LOG_ERR); - $conf->entity = $savcurrententity; + $conf->setEntityValues($this->db, $savcurrententity); return -1; } @@ -1316,11 +1316,11 @@ class Cronjob extends CommonObject $result = $this->update($user); // This include begin/commit if ($result < 0) { dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->entity = $savcurrententity; + $conf->setEntityValues($this->db, $savcurrententity); return -1; } - $conf->entity = $savcurrententity; + $conf->setEntityValues($this->db, $savcurrententity); return $error ?-1 : 1; } From dd61c497228aac8685dcd5774d7531a21c5fcf0f Mon Sep 17 00:00:00 2001 From: kamel Date: Mon, 21 Jun 2021 16:44:31 +0200 Subject: [PATCH 002/195] Correction --- htdocs/core/class/conf.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index ed919be568c..bc953faab2e 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -174,8 +174,6 @@ class Conf */ public function setValues($db) { - global $conf; - // Unset all old modules values if (!empty($this->modules)) { foreach ($this->modules as $m) { From 488d875854b29791e3a66dcddb372a506ffc0655 Mon Sep 17 00:00:00 2001 From: kamel Date: Mon, 21 Jun 2021 16:51:54 +0200 Subject: [PATCH 003/195] Correction --- htdocs/core/class/conf.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index bc953faab2e..4000dc4d6f1 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -159,7 +159,7 @@ class Conf * @param int $entity Entity to get * @return int < 0 if KO, >= 0 if OK */ - function setEntityValues($db, $entity) + public function setEntityValues($db, $entity) { $this->entity = $entity; $this->setValues($db); From 65c0167d077605451f37351d94ef76cd8113fc69 Mon Sep 17 00:00:00 2001 From: Benjamin Chantalat <74144396+PyroShape@users.noreply.github.com> Date: Sun, 10 Oct 2021 20:50:51 +0200 Subject: [PATCH 004/195] ADD : info of number of product still to dispatched in a supplier order --- htdocs/core/lib/fourn.lib.php | 4 ++ .../class/fournisseur.commande.class.php | 43 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php index efc9f60147c..e81bdb5e9d0 100644 --- a/htdocs/core/lib/fourn.lib.php +++ b/htdocs/core/lib/fourn.lib.php @@ -157,8 +157,12 @@ function ordersupplier_prepare_head($object) if (!empty($conf->stock->enabled) && (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE))) { $langs->load("stocks"); + $nbLineToDispatch = count($object->getNotCompletlyDispatchedLines()); $head[$h][0] = DOL_URL_ROOT.'/fourn/commande/dispatch.php?id='.$object->id; $head[$h][1] = $langs->trans("OrderDispatch"); + if ($nbLineToDispatch > 0) { + $head[$h][1] .= ''.$nbLineToDispatch.''; + } $head[$h][2] = 'dispatch'; $h++; } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 99ef4e54e87..5277f5b1d34 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2274,6 +2274,49 @@ class CommandeFournisseur extends CommonOrder return $ret; } + /** + * Return array of the lines that are waiting to be dispatched + * + * @return array Array of lines + */ + public function getNotCompletlyDispatchedLines() + { + $ret = array(); + + $sql = "SELECT supplierOrderDet.fk_product as product_id, supplierOrderDet.qty as qty_ordered, supplierOrderDet.fk_commande,"; + $sql .= " dispatch.rowid as dispatchedlineid, sum(dispatch.qty) as qty_dispatched"; + $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as supplierOrderDet"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as dispatch ON supplierOrderDet.rowid = dispatch.fk_commandefourndet"; + $sql .= " WHERE supplierOrderDet.fk_commande = ".$this->id; + $sql .= " GROUP BY supplierOrderDet.fk_product"; + + $resql = $this->db->query($sql); + + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + + while ($i < $num) { + $objp = $this->db->fetch_object($resql); + + if ($objp) { + // If product not completly dispatched + if (is_null($objp->qty_dispatched) OR ($objp->qty_dispatched < $objp->qty_ordered)){ + $ret[] = array( + 'product_id' => $objp->product_id, + 'qty_ordered' => $objp->qty_ordered, + 'qty_dispatched' => $objp->qty_dispatched, + ); + } + } + $i++; + } + } else { + dol_print_error($this->db, 'Failed to execute request to get not completly dispatched lines'); + } + + return $ret; + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** From 73bd05606c554802d3371cfb7235e365e8f0fff2 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sun, 10 Oct 2021 18:53:22 +0000 Subject: [PATCH 005/195] Fixing style errors. --- htdocs/fourn/class/fournisseur.commande.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 5277f5b1d34..a9d3cbdcac5 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2289,7 +2289,7 @@ class CommandeFournisseur extends CommonOrder $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as dispatch ON supplierOrderDet.rowid = dispatch.fk_commandefourndet"; $sql .= " WHERE supplierOrderDet.fk_commande = ".$this->id; $sql .= " GROUP BY supplierOrderDet.fk_product"; - + $resql = $this->db->query($sql); if ($resql) { @@ -2301,7 +2301,7 @@ class CommandeFournisseur extends CommonOrder if ($objp) { // If product not completly dispatched - if (is_null($objp->qty_dispatched) OR ($objp->qty_dispatched < $objp->qty_ordered)){ + if (is_null($objp->qty_dispatched) OR ($objp->qty_dispatched < $objp->qty_ordered)) { $ret[] = array( 'product_id' => $objp->product_id, 'qty_ordered' => $objp->qty_ordered, From a7563ff62e1fbef41f99bbb679674f0ef2cce67c Mon Sep 17 00:00:00 2001 From: Benjamin Chantalat <74144396+PyroShape@users.noreply.github.com> Date: Sun, 10 Oct 2021 21:15:14 +0200 Subject: [PATCH 006/195] Fix : Found non quoted or not casted var into sql request --- htdocs/fourn/class/fournisseur.commande.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index a9d3cbdcac5..787d9ee321b 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2287,7 +2287,7 @@ class CommandeFournisseur extends CommonOrder $sql .= " dispatch.rowid as dispatchedlineid, sum(dispatch.qty) as qty_dispatched"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as supplierOrderDet"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as dispatch ON supplierOrderDet.rowid = dispatch.fk_commandefourndet"; - $sql .= " WHERE supplierOrderDet.fk_commande = ".$this->id; + $sql .= " WHERE supplierOrderDet.fk_commande = ".((int) $this->id); $sql .= " GROUP BY supplierOrderDet.fk_product"; $resql = $this->db->query($sql); From 152aab4903afa548d25874c34d404a36bad9d0b9 Mon Sep 17 00:00:00 2001 From: kamel Date: Mon, 18 Oct 2021 10:10:31 +0200 Subject: [PATCH 007/195] Add test if actual entity is different to the entity provided --- htdocs/core/class/conf.class.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 4000dc4d6f1..3f938fe778c 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -161,8 +161,10 @@ class Conf */ public function setEntityValues($db, $entity) { - $this->entity = $entity; - $this->setValues($db); + if ($this->entity != $entity) { + $this->entity = $entity; + $this->setValues($db); + } } /** From f328bb32f6ab545c1b98c8be47c9daa5dbdf04c0 Mon Sep 17 00:00:00 2001 From: kamel Date: Tue, 19 Oct 2021 17:34:03 +0200 Subject: [PATCH 008/195] Corrections --- htdocs/core/class/conf.class.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 3f938fe778c..7b35aad3075 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -163,8 +163,10 @@ class Conf { if ($this->entity != $entity) { $this->entity = $entity; - $this->setValues($db); + return $this->setValues($db); } + + return 0; } /** @@ -176,6 +178,8 @@ class Conf */ public function setValues($db) { + dol_syslog(get_class($this)."::setValues"); + // Unset all old modules values if (!empty($this->modules)) { foreach ($this->modules as $m) { @@ -228,8 +232,6 @@ class Conf 'syslog' => array(), ); - dol_syslog(get_class($this)."::setValues"); - //Define all global constants into $this->global->key=value $sql = "SELECT ".$db->decrypt('name')." as name,"; $sql .= " ".$db->decrypt('value')." as value, entity"; From a58f713f6d64c9aa8f60a47914faf40a9278752a Mon Sep 17 00:00:00 2001 From: Polkiko Date: Sat, 23 Oct 2021 23:12:23 +0200 Subject: [PATCH 009/195] NEW Canceled purchase orders do not qualify for total in project overview (and are hidden) If purchase order has been canceled then it does not qualify for total amount and is not shown in table. It can be seen by clicking on the "show/hide" button. --- htdocs/langs/en_US/projects.lang | 4 +++- htdocs/langs/es_ES/projects.lang | 2 ++ htdocs/projet/element.php | 27 ++++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 2fda7e1df0e..570caef7f95 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -37,6 +37,8 @@ OpportunitiesStatusForOpenedProjects=Leads amount of open projects by status OpportunitiesStatusForProjects=Leads amount of projects by status ShowProject=Show project ShowTask=Show task +ShowCanceled=Show canceled +HideCanceled=Hide canceled SetProject=Set project NoProject=No project defined or owned NbOfProjects=Number of projects @@ -274,4 +276,4 @@ AddPersonToTask=Add also to tasks UsageOrganizeEvent=Usage: Event Organization PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE=Classify project as closed when all its tasks are completed (100%% progress) PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Note: existing projects with all tasks at 100 %% progress won't be affected: you will have to close them manually. This option only affects open projects. -SelectLinesOfTimeSpentToInvoice=Select lines of time spent that are unbilled, then bulk action "Generate Invoice" to bill them \ No newline at end of file +SelectLinesOfTimeSpentToInvoice=Select lines of time spent that are unbilled, then bulk action "Generate Invoice" to bill them diff --git a/htdocs/langs/es_ES/projects.lang b/htdocs/langs/es_ES/projects.lang index 6beabd61c1c..01aad98a391 100644 --- a/htdocs/langs/es_ES/projects.lang +++ b/htdocs/langs/es_ES/projects.lang @@ -37,6 +37,8 @@ OpportunitiesStatusForOpenedProjects=Importe oportunidades de proyectos por esta OpportunitiesStatusForProjects=Importe oportunidades de proyectos por estado ShowProject=Ver proyecto ShowTask=Ver tarea +ShowCanceled=Mostrar cancelados +HideCanceled=Ocultar cancelados SetProject=Definir proyecto NoProject=Ningún proyecto definido NbOfProjects=Numero de proyectos diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 9e14a53e7ea..0002da42a82 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -1048,6 +1048,24 @@ foreach ($listofreferent as $key => $value) { } $addform .= '
'; } + if ($key == "order_supplier") { + $addform .= ' + '.$langs->trans("ShowCanceled").' + + '; + } print load_fiche_titre($langs->trans($title), $addform, ''); @@ -1170,9 +1188,16 @@ foreach ($listofreferent as $key => $value) { if (!empty($element->close_code) && $element->close_code == 'replaced') { $qualifiedfortotal = false; // Replacement invoice, do not include into total } + } elseif (($key == 'order_supplier') && ($element->status == 7)) { + $qualifiedfortotal = false; // It makes no sense to include canceled orders in the total + } + + if (($key == "order_supplier") && ($element->status == 7)) { + print ''; + } else { + print ''; } - print ''; // Remove link print ''; From d3d3a87ce9ca1ee8eb9328f87a367dd9c5625210 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Sun, 24 Oct 2021 01:38:13 +0200 Subject: [PATCH 010/195] Add new class to help setup generation --- htdocs/core/class/html.formsetup.class.php | 403 ++++++++++++++++++ htdocs/modulebuilder/template/admin/setup.php | 157 +------ 2 files changed, 410 insertions(+), 150 deletions(-) create mode 100644 htdocs/core/class/html.formsetup.class.php diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php new file mode 100644 index 00000000000..095cf0d8887 --- /dev/null +++ b/htdocs/core/class/html.formsetup.class.php @@ -0,0 +1,403 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +/** + * This class help you create setup render + */ +class formSetup{ + + /** + * @var DoliDB Database handler. + */ + public $db; + + /** @var formSetupItem[] */ + public $arrayOfParameters = array(); + + public $setupNotEmpty = 0; + + /** @var Translate */ + public $langs; + + /** @var Form */ + public $form; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db, $outputLangs = false) + { + global $langs; + $this->db = $db; + $this->form = new Form($this->db); + + if($outputLangs){ + $this->langs = $outputLangs; + } + else{ + $this->langs = $langs; + } + } + + /** + * @return string + */ + public function generateOutput($edit = false){ + + require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + + $out = ''; + $out.= ''; + $out.= ' '; + $out.= ' '; + $out.= ''; + + foreach ($this->arrayOfParameters as $const => $item) { + $out.= $this->generateLineOutput($item, $edit); + } + + $out.= '
'.$this->langs->trans("Parameter").''.$this->langs->trans("Value").'
'; + return $out; + } + + /** + * @param formSetupItem $item + * @param bool $edit + * @return string + */ + public function generateLineOutput($item, $edit = false){ + + $out = ''; + if ($item->enabled==1) { + $this->setupNotEmpty++; + $out.= ''; + + $out.= ''; + $out.= ''; + $out.= $this->form->textwithpicto($item->getNameText(), $item->getHelpText(), 1, 'info', '', 0, 3, 'tootips'.$item->confKey); + $out.= ''; + $out.= ''; + + $out.= ''; + + if($edit){ + $item->generateInputField(); + } + else{ + $item->generateOutputField(); + } + + if(!empty($item->errors)){ + // TODO : move set event message in a methode to be called by cards not by this class + setEventMessages(null, $item->errors, 'errors'); + } + + $out.= ''; + $out.= ''; + } + + return $out; + } + + + /** + * @param string $confKey + * @param array $params + * @ + */ + public function addItemsFromParamsArray($params){ + + if(!array($params)){ return false; } + + foreach ($params as $confKey => $param){ + $this->addItemFromParams($confKey, $param); // todo manage error + } + } + + + /** + * From old + * @param string $confKey + * @param array $params + */ + public function addItemFromParams($confKey, $params){ + + if(empty($confKey) || !empty($params['type'])){ return false; } + + /* + * Exemple from old module builder setup page + * // 'MYMODULE_MYPARAM1'=>array('type'=>'string', 'css'=>'minwidth500' ,'enabled'=>1), + // 'MYMODULE_MYPARAM2'=>array('type'=>'textarea','enabled'=>1), + //'MYMODULE_MYPARAM3'=>array('type'=>'category:'.Categorie::TYPE_CUSTOMER, 'enabled'=>1), + //'MYMODULE_MYPARAM4'=>array('type'=>'emailtemplate:thirdparty', 'enabled'=>1), + //'MYMODULE_MYPARAM5'=>array('type'=>'yesno', 'enabled'=>1), + //'MYMODULE_MYPARAM5'=>array('type'=>'thirdparty_type', 'enabled'=>1), + //'MYMODULE_MYPARAM6'=>array('type'=>'securekey', 'enabled'=>1), + //'MYMODULE_MYPARAM7'=>array('type'=>'product', 'enabled'=>1), + */ + + $item = new formSetupItem($this->db); + $item->type = $params['type']; + + if(!empty($params['enabled'])) { + $item->enabled = $params['enabled']; + } + + if(!empty($params['css'])){ + $item->enabled = $params['css']; + } + + $this->arrayOfParameters[$item->confKey] = $item; + + return true; + } + +} + + +class formSetupItem +{ + /** + * @var DoliDB Database handler. + */ + public $db; + + /** @var Translate */ + public $langs; + + /** @var Form */ + public $form; + + /** @var string $confKey the conf key used in database */ + public $confKey; + + /** @var string|false $nameText */ + public $nameText = false; + + /** @var string $helpText */ + public $helpText = ''; + + /** @var bool|string set this var to override field output */ + public $fieldOverride = false; + + /** + * @var string $errors + */ + public $errors = array(); + + /** + * @var string $type 'string', 'textarea', 'category:'.Categorie::TYPE_CUSTOMER', 'emailtemplate', 'thirdparty_type' + */ + public $type; + + public $enabled = 0; + + public $cssClass = ''; + + /** + * Constructor + * + * @param $confKey + */ + public function __construct($confKey) + { + global $langs, $db; + $this->db = $db; + $this->form = new Form($this->db); + $this->langs = $langs; + + $this->confKey = $confKey; + } + + public function getHelpText(){ + if(!empty($this->helpText)){ return $this->helpText; } + return (($this->langs->trans($this->confKey . 'Tooltip') != $this->confKey . 'Tooltip') ? $this->langs->trans($this->confKey . 'Tooltip') : ''); + } + + public function getNameText(){ + if(!empty($this->nameText)){ return $this->nameText; } + return (($this->langs->trans($this->confKey) != $this->confKey) ? $this->langs->trans($this->confKey) : ''); + } + + public function generateInputField(){ + global $conf, $user; + + if(!empty($this->fieldOverride)){ + return $this->fieldOverride; + } + + $out = ''; + + if ($this->type == 'textarea') { + $out.= '\n"; + } elseif ($this->type== 'html') { + require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; + $doleditor = new DolEditor($this->confKey, $conf->global->{$this->confKey}, '', 160, 'dolibarr_notes', '', false, false, $conf->fckeditor->enabled, ROWS_5, '90%'); + $doleditor->Create(); + } elseif ($this->type == 'yesno') { + $out.= $this->form->selectyesno($this->confKey, $conf->global->{$this->confKey}, 1); + } elseif (preg_match('/emailtemplate:/', $this->type)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($this->db); + + $tmp = explode(':', $this->type); + $nboftemplates = $formmail->fetchAllEMailTemplate($tmp[1], $user, null, 1); // We set lang=null to get in priority record with no lang + //$arraydefaultmessage = $formmail->getEMailTemplate($db, $tmp[1], $user, null, 0, 1, ''); + $arrayOfMessageName = array(); + if (is_array($formmail->lines_model)) { + foreach ($formmail->lines_model as $modelMail) { + //var_dump($modelmail); + $moreonlabel = ''; + if (!empty($arrayOfMessageName[$modelMail->label])) { + $moreonlabel = ' (' . $this->langs->trans("SeveralLangugeVariatFound") . ')'; + } + // The 'label' is the key that is unique if we exclude the language + $arrayOfMessageName[$modelMail->id] = $this->langs->trans(preg_replace('/\(|\)/', '', $modelMail->label)) . $moreonlabel; + } + } + $out.= $this->form->selectarray($this->confKey, $arrayOfMessageName, $conf->global->{$this->confKey}, 'None', 0, 0, '', 0, 0, 0, '', '', 1); + } elseif (preg_match('/category:/', $this->type)) { + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + $formother = new FormOther($this->db); + + $tmp = explode(':', $this->type); + $out.= img_picto('', 'category', 'class="pictofixedwidth"'); + $out.= $formother->select_categories($tmp[1], $conf->global->{$this->confKey}, $this->confKey, 0, $this->langs->trans('CustomersProspectsCategoriesShort')); + } elseif (preg_match('/thirdparty_type/', $this->type)) { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; + $formcompany = new FormCompany($this->db); + $out.= $formcompany->selectProspectCustomerType($conf->global->{$this->confKey}, $this->confKey); + } elseif ($this->type == 'securekey') { + $out.= ''; + if (!empty($conf->use_javascript_ajax)) { + $out.= ' '.img_picto($this->langs->trans('Generate'), 'refresh', 'id="generate_token'.$this->confKey.'" class="linkobject"'); + } + if (!empty($conf->use_javascript_ajax)) { + $out.= "\n".''; + } + } elseif ($this->type == 'product') { + if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { + $selected = (empty($conf->global->{$this->confKey}) ? '' : $conf->global->{$this->confKey}); + $this->form->select_produits($selected, $this->confKey, '', 0); + } + } else { + $out.= ''; + } + + return $out; + } + + + /** + * add error + * @param array|string $errors + */ + public function setErrors($errors){ + if(is_array($errors)){ + if(!empty($errors)){ + foreach ($errors as $error){ + $this->setErrors($error); + } + } + } + elseif(!empty($errors)){ + $this->errors[] = $errors; + } + } + + public function generateOutputField(){ + global $conf, $user; + + if(!empty($this->fieldOverride)){ + return $this->fieldOverride; + } + + $out = ''; + + if ($this->type == 'textarea') { + print dol_nl2br($conf->global->{$this->confKey}); + } elseif ($this->type== 'html') { + print $conf->global->{$this->confKey}; + } elseif ($this->type == 'yesno') { + print ajax_constantonoff($this->confKey); + } elseif (preg_match('/emailtemplate:/', $this->type)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($this->db); + + $tmp = explode(':', $this->type); + + $template = $formmail->getEMailTemplate($this->db, $tmp[1], $user, $this->langs, $conf->global->{$this->confKey}); + if ($template<0) { + $this->setErrors($formmail->errors); + } + print $this->langs->trans($template->label); + } elseif (preg_match('/category:/', $this->type)) { + $c = new Categorie($this->db); + $result = $c->fetch($conf->global->{$this->confKey}); + if ($result < 0) { + $this->setErrors($c->errors); + } + $ways = $c->print_all_ways(' >> ', 'none', 0, 1); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text + $toprint = array(); + foreach ($ways as $way) { + $toprint[] = '
  • color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . $way . '
  • '; + } + print '
      ' . implode(' ', $toprint) . '
    '; + } elseif (preg_match('/thirdparty_type/', $this->type)) { + if ($conf->global->{$this->confKey}==2) { + print $this->langs->trans("Prospect"); + } elseif ($conf->global->{$this->confKey}==3) { + print $this->langs->trans("ProspectCustomer"); + } elseif ($conf->global->{$this->confKey}==1) { + print $this->langs->trans("Customer"); + } elseif ($conf->global->{$this->confKey}==0) { + print $this->langs->trans("NorProspectNorCustomer"); + } + } elseif ($this->type == 'product') { + $product = new Product($this->db); + $resprod = $product->fetch($conf->global->{$this->confKey}); + if ($resprod > 0) { + print $product->ref; + } elseif ($resprod < 0) { + $this->setErrors($product->errors); + } + } else { + print $conf->global->{$this->confKey}; + } + + return $out; + } + +} diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 7c6c6b2c04e..390f45d955c 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -222,96 +222,17 @@ print dol_get_fiche_head($head, 'settings', $langs->trans($page_name), -1, "mymo echo ''.$langs->trans("MyModuleSetupPage").'

    '; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php'; +$formSetup = new formSetup($db); + +$formSetup->addItemsFromParamsArray($arrayofparameters); + if ($action == 'edit') { print '
    '; print ''; print ''; - print ''; - print ''; - - foreach ($arrayofparameters as $constname => $val) { - if ($val['enabled']==1) { - $setupnotempty++; - print ''; - } - } - print '
    '.$langs->trans("Parameter").''.$langs->trans("Value").'
    '; - $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); - print ''.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).''; - print ''; - - if ($val['type'] == 'textarea') { - print '\n"; - } elseif ($val['type']== 'html') { - require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; - $doleditor = new DolEditor($constname, $conf->global->{$constname}, '', 160, 'dolibarr_notes', '', false, false, $conf->fckeditor->enabled, ROWS_5, '90%'); - $doleditor->Create(); - } elseif ($val['type'] == 'yesno') { - print $form->selectyesno($constname, $conf->global->{$constname}, 1); - } elseif (preg_match('/emailtemplate:/', $val['type'])) { - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - - $tmp = explode(':', $val['type']); - $nboftemplates = $formmail->fetchAllEMailTemplate($tmp[1], $user, null, 1); // We set lang=null to get in priority record with no lang - //$arraydefaultmessage = $formmail->getEMailTemplate($db, $tmp[1], $user, null, 0, 1, ''); - $arrayofmessagename = array(); - if (is_array($formmail->lines_model)) { - foreach ($formmail->lines_model as $modelmail) { - //var_dump($modelmail); - $moreonlabel = ''; - if (!empty($arrayofmessagename[$modelmail->label])) { - $moreonlabel = ' (' . $langs->trans("SeveralLangugeVariatFound") . ')'; - } - // The 'label' is the key that is unique if we exclude the language - $arrayofmessagename[$modelmail->id] = $langs->trans(preg_replace('/\(|\)/', '', $modelmail->label)) . $moreonlabel; - } - } - print $form->selectarray($constname, $arrayofmessagename, $conf->global->{$constname}, 'None', 0, 0, '', 0, 0, 0, '', '', 1); - } elseif (preg_match('/category:/', $val['type'])) { - require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; - $formother = new FormOther($db); - - $tmp = explode(':', $val['type']); - print img_picto('', 'category', 'class="pictofixedwidth"'); - print $formother->select_categories($tmp[1], $conf->global->{$constname}, $constname, 0, $langs->trans('CustomersProspectsCategoriesShort')); - } elseif (preg_match('/thirdparty_type/', $val['type'])) { - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; - $formcompany = new FormCompany($db); - print $formcompany->selectProspectCustomerType($conf->global->{$constname}, $constname); - } elseif ($val['type'] == 'securekey') { - print ''; - if (!empty($conf->use_javascript_ajax)) { - print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token'.$constname.'" class="linkobject"'); - } - if (!empty($conf->use_javascript_ajax)) { - print "\n".''; - } - } elseif ($val['type'] == 'product') { - if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { - $selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname); - $form->select_produits($selected, $constname, '', 0); - } - } else { - print ''; - } - print '
    '; + print $formSetup->generateOutput(true); print '
    '; print ''; @@ -321,72 +242,8 @@ if ($action == 'edit') { print '
    '; } else { if (!empty($arrayofparameters)) { - print ''; - print ''; - foreach ($arrayofparameters as $constname => $val) { - if ($val['enabled']==1) { - $setupnotempty++; - print ''; - } - } - - print '
    '.$langs->trans("Parameter").''.$langs->trans("Value").'
    '; - $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); - print $form->textwithpicto($langs->trans($constname), $tooltiphelp); - print ''; - - if ($val['type'] == 'textarea') { - print dol_nl2br($conf->global->{$constname}); - } elseif ($val['type']== 'html') { - print $conf->global->{$constname}; - } elseif ($val['type'] == 'yesno') { - print ajax_constantonoff($constname); - } elseif (preg_match('/emailtemplate:/', $val['type'])) { - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - - $tmp = explode(':', $val['type']); - - $template = $formmail->getEMailTemplate($db, $tmp[1], $user, $langs, $conf->global->{$constname}); - if ($template<0) { - setEventMessages(null, $formmail->errors, 'errors'); - } - print $langs->trans($template->label); - } elseif (preg_match('/category:/', $val['type'])) { - $c = new Categorie($db); - $result = $c->fetch($conf->global->{$constname}); - if ($result < 0) { - setEventMessages(null, $c->errors, 'errors'); - } - $ways = $c->print_all_ways(' >> ', 'none', 0, 1); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text - $toprint = array(); - foreach ($ways as $way) { - $toprint[] = '
  • color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . $way . '
  • '; - } - print '
      ' . implode(' ', $toprint) . '
    '; - } elseif (preg_match('/thirdparty_type/', $val['type'])) { - if ($conf->global->{$constname}==2) { - print $langs->trans("Prospect"); - } elseif ($conf->global->{$constname}==3) { - print $langs->trans("ProspectCustomer"); - } elseif ($conf->global->{$constname}==1) { - print $langs->trans("Customer"); - } elseif ($conf->global->{$constname}==0) { - print $langs->trans("NorProspectNorCustomer"); - } - } elseif ($val['type'] == 'product') { - $product = new Product($db); - $resprod = $product->fetch($conf->global->{$constname}); - if ($resprod > 0) { - print $product->ref; - } elseif ($resprod < 0) { - setEventMessages(null, $object->errors, "errors"); - } - } else { - print $conf->global->{$constname}; - } - print '
    '; + print $formSetup->generateOutput(); print '
    '; print ''.$langs->trans("Modify").''; From fdcb9674d8470419daddb3c1b970113117f6a46b Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Sun, 24 Oct 2021 02:09:49 +0200 Subject: [PATCH 011/195] Remove prints --- htdocs/core/class/html.formsetup.class.php | 38 +++++++++++----------- htdocs/langs/en_US/admin.lang | 1 + 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index 095cf0d8887..27b0e3fb615 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -69,7 +69,7 @@ class formSetup{ $out.= ' '.$this->langs->trans("Value").''; $out.= ''; - foreach ($this->arrayOfParameters as $const => $item) { + foreach ($this->arrayOfParameters as $item) { $out.= $this->generateLineOutput($item, $edit); } @@ -98,10 +98,10 @@ class formSetup{ $out.= ''; if($edit){ - $item->generateInputField(); + $out.= $item->generateInputField(); } else{ - $item->generateOutputField(); + $out.= $item->generateOutputField(); } if(!empty($item->errors)){ @@ -125,7 +125,6 @@ class formSetup{ public function addItemsFromParamsArray($params){ if(!array($params)){ return false; } - foreach ($params as $confKey => $param){ $this->addItemFromParams($confKey, $param); // todo manage error } @@ -139,7 +138,7 @@ class formSetup{ */ public function addItemFromParams($confKey, $params){ - if(empty($confKey) || !empty($params['type'])){ return false; } + if(empty($confKey) || empty($params['type'])){ return false; } /* * Exemple from old module builder setup page @@ -155,13 +154,14 @@ class formSetup{ $item = new formSetupItem($this->db); $item->type = $params['type']; + $item->confKey = $confKey; if(!empty($params['enabled'])) { $item->enabled = $params['enabled']; } if(!empty($params['css'])){ - $item->enabled = $params['css']; + $item->cssClass = $params['css']; } $this->arrayOfParameters[$item->confKey] = $item; @@ -233,7 +233,7 @@ class formSetupItem public function getNameText(){ if(!empty($this->nameText)){ return $this->nameText; } - return (($this->langs->trans($this->confKey) != $this->confKey) ? $this->langs->trans($this->confKey) : ''); + return (($this->langs->trans($this->confKey) != $this->confKey) ? $this->langs->trans($this->confKey) : $this->langs->trans('MissingTranslationForConfKey',$this->confKey)); } public function generateInputField(){ @@ -313,7 +313,7 @@ class formSetupItem $this->form->select_produits($selected, $this->confKey, '', 0); } } else { - $out.= ''; + $out.= ''; } return $out; @@ -347,11 +347,11 @@ class formSetupItem $out = ''; if ($this->type == 'textarea') { - print dol_nl2br($conf->global->{$this->confKey}); + $out.= dol_nl2br($conf->global->{$this->confKey}); } elseif ($this->type== 'html') { - print $conf->global->{$this->confKey}; + $out.= $conf->global->{$this->confKey}; } elseif ($this->type == 'yesno') { - print ajax_constantonoff($this->confKey); + $out.= ajax_constantonoff($this->confKey); } elseif (preg_match('/emailtemplate:/', $this->type)) { include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; $formmail = new FormMail($this->db); @@ -362,7 +362,7 @@ class formSetupItem if ($template<0) { $this->setErrors($formmail->errors); } - print $this->langs->trans($template->label); + $out.= $this->langs->trans($template->label); } elseif (preg_match('/category:/', $this->type)) { $c = new Categorie($this->db); $result = $c->fetch($conf->global->{$this->confKey}); @@ -374,27 +374,27 @@ class formSetupItem foreach ($ways as $way) { $toprint[] = '
  • color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . $way . '
  • '; } - print '
      ' . implode(' ', $toprint) . '
    '; + $out.= '
      ' . implode(' ', $toprint) . '
    '; } elseif (preg_match('/thirdparty_type/', $this->type)) { if ($conf->global->{$this->confKey}==2) { - print $this->langs->trans("Prospect"); + $out.= $this->langs->trans("Prospect"); } elseif ($conf->global->{$this->confKey}==3) { - print $this->langs->trans("ProspectCustomer"); + $out.= $this->langs->trans("ProspectCustomer"); } elseif ($conf->global->{$this->confKey}==1) { - print $this->langs->trans("Customer"); + $out.= $this->langs->trans("Customer"); } elseif ($conf->global->{$this->confKey}==0) { - print $this->langs->trans("NorProspectNorCustomer"); + $out.= $this->langs->trans("NorProspectNorCustomer"); } } elseif ($this->type == 'product') { $product = new Product($this->db); $resprod = $product->fetch($conf->global->{$this->confKey}); if ($resprod > 0) { - print $product->ref; + $out.= $product->ref; } elseif ($resprod < 0) { $this->setErrors($product->errors); } } else { - print $conf->global->{$this->confKey}; + $out.= $conf->global->{$this->confKey}; } return $out; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index f75ba12abe5..96fba681373 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2198,3 +2198,4 @@ SkinAndColors=Skin and colors IfYouUseASecondTaxYouMustSetYouUseTheMainTax=If you want to use a second tax, you must enable also the first sales tax IfYouUseAThirdTaxYouMustSetYouUseTheMainTax=If you want to use a third tax, you must enable also the first sales tax PDF_USE_1A=Generate PDF with PDF/A-1b format +MissingTranslationForConfKey = Missing translation for %s From 61576dad539cc363fa3efdfbb55e9f9512cb5cf7 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sun, 24 Oct 2021 00:17:18 +0000 Subject: [PATCH 012/195] Fixing style errors. --- htdocs/core/class/html.formsetup.class.php | 73 ++++++++++++---------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index 27b0e3fb615..70dd11e47ae 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -19,7 +19,8 @@ /** * This class help you create setup render */ -class formSetup{ +class formSetup +{ /** * @var DoliDB Database handler. @@ -48,10 +49,9 @@ class formSetup{ $this->db = $db; $this->form = new Form($this->db); - if($outputLangs){ + if ($outputLangs) { $this->langs = $outputLangs; - } - else{ + } else { $this->langs = $langs; } } @@ -59,7 +59,8 @@ class formSetup{ /** * @return string */ - public function generateOutput($edit = false){ + public function generateOutput($edit = false) + { require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; @@ -82,7 +83,8 @@ class formSetup{ * @param bool $edit * @return string */ - public function generateLineOutput($item, $edit = false){ + public function generateLineOutput($item, $edit = false) + { $out = ''; if ($item->enabled==1) { @@ -97,14 +99,13 @@ class formSetup{ $out.= ''; - if($edit){ + if ($edit) { $out.= $item->generateInputField(); - } - else{ + } else { $out.= $item->generateOutputField(); } - if(!empty($item->errors)){ + if (!empty($item->errors)) { // TODO : move set event message in a methode to be called by cards not by this class setEventMessages(null, $item->errors, 'errors'); } @@ -122,10 +123,11 @@ class formSetup{ * @param array $params * @ */ - public function addItemsFromParamsArray($params){ + public function addItemsFromParamsArray($params) + { - if(!array($params)){ return false; } - foreach ($params as $confKey => $param){ + if (!array($params)) { return false; } + foreach ($params as $confKey => $param) { $this->addItemFromParams($confKey, $param); // todo manage error } } @@ -136,9 +138,10 @@ class formSetup{ * @param string $confKey * @param array $params */ - public function addItemFromParams($confKey, $params){ + public function addItemFromParams($confKey, $params) + { - if(empty($confKey) || empty($params['type'])){ return false; } + if (empty($confKey) || empty($params['type'])) { return false; } /* * Exemple from old module builder setup page @@ -156,11 +159,11 @@ class formSetup{ $item->type = $params['type']; $item->confKey = $confKey; - if(!empty($params['enabled'])) { + if (!empty($params['enabled'])) { $item->enabled = $params['enabled']; } - if(!empty($params['css'])){ + if (!empty($params['css'])) { $item->cssClass = $params['css']; } @@ -168,7 +171,6 @@ class formSetup{ return true; } - } @@ -226,20 +228,23 @@ class formSetupItem $this->confKey = $confKey; } - public function getHelpText(){ - if(!empty($this->helpText)){ return $this->helpText; } + public function getHelpText() + { + if (!empty($this->helpText)) { return $this->helpText; } return (($this->langs->trans($this->confKey . 'Tooltip') != $this->confKey . 'Tooltip') ? $this->langs->trans($this->confKey . 'Tooltip') : ''); } - public function getNameText(){ - if(!empty($this->nameText)){ return $this->nameText; } - return (($this->langs->trans($this->confKey) != $this->confKey) ? $this->langs->trans($this->confKey) : $this->langs->trans('MissingTranslationForConfKey',$this->confKey)); + public function getNameText() + { + if (!empty($this->nameText)) { return $this->nameText; } + return (($this->langs->trans($this->confKey) != $this->confKey) ? $this->langs->trans($this->confKey) : $this->langs->trans('MissingTranslationForConfKey', $this->confKey)); } - public function generateInputField(){ + public function generateInputField() + { global $conf, $user; - if(!empty($this->fieldOverride)){ + if (!empty($this->fieldOverride)) { return $this->fieldOverride; } @@ -324,23 +329,24 @@ class formSetupItem * add error * @param array|string $errors */ - public function setErrors($errors){ - if(is_array($errors)){ - if(!empty($errors)){ - foreach ($errors as $error){ + public function setErrors($errors) + { + if (is_array($errors)) { + if (!empty($errors)) { + foreach ($errors as $error) { $this->setErrors($error); } } - } - elseif(!empty($errors)){ + } elseif (!empty($errors)) { $this->errors[] = $errors; } } - public function generateOutputField(){ + public function generateOutputField() + { global $conf, $user; - if(!empty($this->fieldOverride)){ + if (!empty($this->fieldOverride)) { return $this->fieldOverride; } @@ -399,5 +405,4 @@ class formSetupItem return $out; } - } From 595760e97d2aab20baf82299c484063ff5ab231a Mon Sep 17 00:00:00 2001 From: MOREAU FRANCK Date: Mon, 25 Oct 2021 09:36:12 +0200 Subject: [PATCH 013/195] Lib Modif --- .../emailcollector/lib/emailcollector.lib.php | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/htdocs/emailcollector/lib/emailcollector.lib.php b/htdocs/emailcollector/lib/emailcollector.lib.php index fe4a5f1b19c..9b63bbea66a 100644 --- a/htdocs/emailcollector/lib/emailcollector.lib.php +++ b/htdocs/emailcollector/lib/emailcollector.lib.php @@ -85,3 +85,132 @@ function emailcollectorPrepareHead($object) return $head; } + +/** + * Récupère les parties d'un message + * @param object $structure structure du message + * @return object|boolean parties du message|false en cas d'erreur + */ +function getParts($structure) +{ + return isset($structure->parts) ? $structure->parts : false; +} + +/** + * Tableau définissant la pièce jointe + * @param object $part partie du message + * @return object|boolean définition du message|false en cas d'erreur + */ +function getDParameters($part) +{ + return $part->ifdparameters ? $part->dparameters : false; +} + +/** + * Récupère les pièces d'un mail donné + * @param integer $jk numéro du mail + * @param object $mbox object connection imaap + * @return array type, filename, pos + */ +function getAttachments($jk, $mbox) +{ + $structure = imap_fetchstructure($mbox, $jk); + $parts = getParts($structure); + $fpos = 2; + $attachments = array(); + $nb = count($parts); + if ($parts && $nb) { + for ($i = 1; $i < $nb; $i++) { + $part = $parts[$i]; + + if ($part->ifdisposition && strtolower($part->disposition) == "attachment") { + $ext = $part->subtype; + $params = getDParameters($part); + + if ($params) { + $filename = $part->dparameters[0]->value; + $filename = imap_utf8($filename); + $attachments[] = array('type' => $part->type, 'filename' => $filename, 'pos' => $fpos); + } + } + $fpos++; + } + } + return $attachments; +} + +/** + * Récupère la contenu de la pièce jointe par rapport a sa position dans un mail donné + * @param integer $jk numéro du mail + * @param integer $fpos position de la pièce jointe + * @param integer $type type de la pièce jointe + * @param object $mbox object connection imaap + * @return mixed data + */ +function getFileData($jk, $fpos, $type, $mbox) +{ + $mege = imap_fetchbody($mbox, $jk, $fpos); + $data = getDecodeValue($mege, $type); + + return $data; +} + +/** + * Sauvegarde de la pièce jointe dans le dossier défini avec un nom unique + * @param string $path chemin de sauvegarde dui fichier + * @param string $filename nom du fichier + * @param mixed $data contenu à sauvegarder + * @return string emplacement du fichier + **/ +function saveAttachment($path, $filename, $data) +{ + global $lang; + $tmp = explode('.', $filename); + $ext = array_pop($tmp); + $filename = implode('.', $tmp); + if (!file_exists($path)) { + if (dol_mkdir($path) < 0) { + return -1; + } + } + + $i = 1; + $filepath = $path . $filename . '.' . $ext; + + while (file_exists($filepath)) { + $filepath = $path . $filename . '(' . $i . ').' . $ext; + $i++; + } + file_put_contents($filepath, $data); + return $filepath; +} + +/** + * Décode le contenu du message + * @param string $message message + * @param integer $coding type de contenu + * @return message décodé + **/ +function getDecodeValue($message, $coding) +{ + switch ($coding) { + case 0: //text + case 1: //multipart + $message = imap_8bit($message); + break; + case 2: //message + $message = imap_binary($message); + break; + case 3: //application + case 5: //image + case 6: //video + case 7: //other + $message = imap_base64($message); + break; + case 4: //audio + $message = imap_qprint($message); + break; + } + + return $message; +} From bba6daf98404e41dc35cd5bab47d047269782b00 Mon Sep 17 00:00:00 2001 From: MOREAU FRANCK Date: Mon, 25 Oct 2021 09:37:10 +0200 Subject: [PATCH 014/195] class Modif --- .../class/emailcollector.class.php | 160 +++++++++++++++++- 1 file changed, 159 insertions(+), 1 deletion(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 0a52969f9f6..050a6ca1ae2 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1897,7 +1897,165 @@ class EmailCollector extends CommonObject } } } - } elseif ($operation['type'] == 'project') { + } elseif ($operation['type'] == 'recordjoinpiece') { + $pj = getAttachments($imapemail, $connection); + foreach ($pj as $key => $val) { + $data[$val['filename']] = getFileData($imapemail, $val['pos'], $val['type'], $connection); + } + if (count($pj) > 0) { + $sql = "SELECT rowid as id FROM " . MAIN_DB_PREFIX . "user WHERE email LIKE '%" . $from . "%'"; + $resql = $this->db->query($sql); + if ($resql->num_rows == 0) { + $this->errors = 'User Not allowed to add documents'; + } + $arrayobject = array( + 'propale' => array('table' => 'propal', + 'fields' => array('ref'), + 'class' => 'comm/propal/class/propal.class.php', + 'object' => 'Propal'), + 'holiday' => array('table' => 'holiday', + 'fields' => array('ref'), + 'class' => 'holiday/class/holiday.class.php', + 'object' => 'Holiday'), + 'expensereport' => array('table' => 'expensereport', + 'fields' => array('ref'), + 'class' => 'expensereport/class/expensereport.class.php', + 'object' => 'ExpenseReport'), + 'recruitment/recruitmentjobposition' => array('table' => 'recruitment_recruitmentjobposition', + 'fields' => array('ref'), + 'class' => 'recruitment/class/recruitmentjobposition.class.php', + 'object' => 'RecruitmentJobPosition'), + 'recruitment/recruitmentjobposition' => array('table' => 'recruitment_recruitmentcandidature', + 'fields' => array('ref'), + 'class' => 'recruitment/class/recruitmentcandidature.class.php', + 'object' => ' RecruitmentCandidature'), + 'societe' => array('table' => 'societe', + 'fields' => array('code_client', 'code_fournisseur'), + 'class' => 'societe/class/societe.class.php', + 'object' => 'Societe'), + 'commande' => array('table' => 'commande', + 'fields' => array('ref'), + 'class' => 'commande/class/commande.class.php', + 'object' => 'Commande'), + 'expedition' => array('table' => 'expedition', + 'fields' => array('ref'), + 'class' => 'expedition/class/expedition.class.php', + 'object' => 'Expedition'), + 'contract' => array('table' => 'contrat', + 'fields' => array('ref'), + 'class' => 'contrat/class/contrat.class.php', + 'object' => 'Contrat'), + 'fichinter' => array('table' => 'fichinter', + 'fields' => array('ref'), + 'class' => 'fichinter/class/fichinter.class.php', + 'object' => 'Fichinter'), + 'ticket' => array('table' => 'ticket', + 'fields' => array('ref'), + 'class' => 'ticket/class/ticket.class.php', + 'object' => ' Ticket'), + 'knowledgemanagement' => array('table' => 'knowledgemanagement_knowledgerecord', + 'fields' => array('ref'), + 'class' => 'knowledgemanagement/class/knowledgemanagement.class.php', + 'object' => 'KnowledgeRecord'), + 'supplier_proposal' => array('table' => 'supplier_proposal', + 'fields' => array('ref'), + 'class' => 'supplier_proposal/class/supplier_proposal.class.php', + 'object' => 'SupplierProposal'), + 'fournisseur/commande' => array('table' => 'commande_fournisseur', + 'fields' => array('ref', 'ref_supplier'), + 'class' => 'fourn/class/fournisseur.commande.class.php', + 'object' => 'SupplierProposal'), + 'facture' => array('table' => 'facture', + 'fields' => array('ref'), + 'class' => 'compta/facture/class/facture.class.php', + 'object' => 'Facture'), + 'fournisseur/facture' => array('table' => 'facture_fourn', + 'fields' => array('ref', ref_client), + 'class' => 'fourn/class/fournisseur.facture.class.php', + 'object' => 'FactureFournisseur'), + 'produit' => array('table' => 'product', + 'fields' => array('ref'), + 'class' => 'product/class/product.class.php', + 'object' => 'Product'), + 'productlot' => array('table' => 'product_lot', + 'fields' => array('batch'), + 'class' => 'product/stock/class/productlot.class.php', + 'object' => 'Productlot'), + 'projet' => array('table' => 'projet', + 'fields' => array('ref'), + 'class' => 'projet/class/projet.class.php', + 'object' => 'Project'), + 'projet_task' => array('table' => 'projet_task', + 'fields' => array('ref'), + 'class' => 'projet/class/task.class.php', + 'object' => 'Task'), + 'ressource' => array('table' => 'resource', + 'fields' => array('ref'), + 'class' => 'ressource/class/dolressource.class.php', + 'object' => 'Dolresource'), + 'bom' => array('table' => 'bom_bom', + 'fields' => array('ref'), + 'class' => 'bom/class/bom.class.php', + 'object' => 'BOM'), + 'mrp' => array('table' => 'mrp_mo', + 'fields' => array('ref'), + 'class' => 'mrp/class/mo.class.php', + 'object' => 'Mo'), + ); + + $hookmanager->initHooks(array('emailcolector')); + $parameters = array('arrayobject' => $arrayobject); + $reshook = $hookmanager->executeHooks('addmoduletoeamailcollectorjoinpiece', $parameters); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) $arrayobject = $hookmanager->resArray; + + $resultobj = array(); + + foreach ($arrayobject as $key => $objectdesc) { + $sql = 'SELECT DISTINCT t.rowid '; + $sql .= ' FROM ' . MAIN_DB_PREFIX . $objectdesc['table'] . ' AS t'; + $sql .= ' WHERE '; + foreach ($objectdesc['fields'] as $field) { + $sql .= "'" .$this->db->escape($subject) . "' LIKE CONCAT('%', t." . $field . ", '%') OR "; + } + $sql = substr($sql, 0, -4); + + $ressqlobj = $this->db->query($sql); + if ($ressqlobj) { + while ($obj = $this->db->fetch_object($ressqlobj)) { + $resultobj[$key][] = $obj->rowid; + } + } + } + $dirs = array(); + foreach ($resultobj as $mod => $ids) { + $moddesc = $arrayobject[$mod]; + $elementpath = $mod; + dol_include_once($moddesc['class']); + $objectmanaged = new $moddesc['object']($this->db); + foreach ($ids as $val) { + $res = $objectmanaged->fetch($val); + if ($res) { + $path = ($objectmanaged->entity > 1 ? "/" . $objectmanaged->entity : ''); + $dirs[] = DOL_DATA_ROOT . $path . "/" . $elementpath . '/' . dol_sanitizeFileName($objectmanaged->ref) . '/'; + } else { + $this->errors = 'object not found'; + } + } + } + foreach ($dirs as $target) { + foreach ($data as $filename => $content) { + $prefix = $this->actions[$this->id]['actionparam']; + + $resr = saveAttachment($target, $prefix . '_' . $filename, $content); + if ($resr == -1) { + $this->errors = 'Doc not saved'; + } + } + } + } else { + $this->errors = 'no joined piece'; + } + }elseif ($operation['type'] == 'project') { // Create project / lead $projecttocreate = new Project($this->db); From 74ec7c68a29e98a1cd0d0337abb8c7435da670ac Mon Sep 17 00:00:00 2001 From: MOREAU FRANCK Date: Mon, 25 Oct 2021 09:37:51 +0200 Subject: [PATCH 015/195] card Modif --- htdocs/admin/emailcollector_card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index be3ab2d63c1..dca93b9a506 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -583,6 +583,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $arrayoftypes = array( 'loadthirdparty'=>$langs->trans('LoadThirdPartyFromName', $langs->transnoentities("ThirdPartyName")), 'loadandcreatethirdparty'=>$langs->trans('LoadThirdPartyFromNameOrCreate', $langs->transnoentities("ThirdPartyName")), + 'recordjoinpiece'=>$langs->trans('recordjoinpieceonobject'), 'recordevent'=>'RecordEvent'); if ($conf->projet->enabled) { $arrayoftypes['project'] = 'CreateLeadAndThirdParty'; From 3236d04ca46e457646e628955df579c4d5dd3917 Mon Sep 17 00:00:00 2001 From: MOREAU FRANCK Date: Mon, 25 Oct 2021 09:44:21 +0200 Subject: [PATCH 016/195] card Modif --- htdocs/emailcollector/class/emailcollector.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 050a6ca1ae2..729762be327 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -2055,7 +2055,7 @@ class EmailCollector extends CommonObject } else { $this->errors = 'no joined piece'; } - }elseif ($operation['type'] == 'project') { + } elseif ($operation['type'] == 'project') { // Create project / lead $projecttocreate = new Project($this->db); From 3a862212905ceebf3a1de29b33dd1abede9ae25f Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Sat, 30 Oct 2021 12:54:13 +0200 Subject: [PATCH 017/195] add more customisation --- htdocs/core/class/html.formsetup.class.php | 327 +++++++++++++----- htdocs/modulebuilder/template/admin/setup.php | 28 +- 2 files changed, 272 insertions(+), 83 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index 27b0e3fb615..f781afe0079 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -19,7 +19,8 @@ /** * This class help you create setup render */ -class formSetup{ +class formSetup +{ /** * @var DoliDB Database handler. @@ -27,7 +28,7 @@ class formSetup{ public $db; /** @var formSetupItem[] */ - public $arrayOfParameters = array(); + public $params = array(); public $setupNotEmpty = 0; @@ -37,10 +38,12 @@ class formSetup{ /** @var Form */ public $form; + /** * Constructor * - * @param DoliDB $db Database handler + * @param DoliDB $db Database handler + * @param Translate $outputLangs if needed can use another lang */ public function __construct($db, $outputLangs = false) { @@ -48,41 +51,53 @@ class formSetup{ $this->db = $db; $this->form = new Form($this->db); - if($outputLangs){ + if ($outputLangs) { $this->langs = $outputLangs; - } - else{ + } else { $this->langs = $langs; } } /** + * @param bool $editMode true will display output on edit mod * @return string */ - public function generateOutput($edit = false){ + public function generateOutput($editMode = false) + { + $out = ''; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; - $out = ''; + $out.= ''; + if ($editMode) { + $out .= ''; + } + + $out.= '
    '; + $out.= ''; $out.= ''; $out.= ' '; $out.= ' '; $out.= ''; + $out.= ''; - foreach ($this->arrayOfParameters as $item) { - $out.= $this->generateLineOutput($item, $edit); + $out.= ''; + foreach ($this->params as $item) { + $out.= $this->generateLineOutput($item, $editMode); } + $out.= ''; $out.= '
    '.$this->langs->trans("Parameter").''.$this->langs->trans("Value").'
    '; return $out; } /** - * @param formSetupItem $item - * @param bool $edit - * @return string + * @param formSetupItem $item the setup item + * @param bool $editMode Display as edit mod + * @return string the html output for an setup item */ - public function generateLineOutput($item, $edit = false){ + public function generateLineOutput($item, $editMode = false) + { $out = ''; if ($item->enabled==1) { @@ -97,14 +112,13 @@ class formSetup{ $out.= ''; - if($edit){ + if ($editMode) { $out.= $item->generateInputField(); - } - else{ + } else { $out.= $item->generateOutputField(); } - if(!empty($item->errors)){ + if (!empty($item->errors)) { // TODO : move set event message in a methode to be called by cards not by this class setEventMessages(null, $item->errors, 'errors'); } @@ -118,14 +132,14 @@ class formSetup{ /** - * @param string $confKey - * @param array $params - * @ + * @param array $params an array of arrays of params from old modulBuilder params + * @deprecated was used to test module builder convertion to this form usage + * @return null */ - public function addItemsFromParamsArray($params){ - - if(!array($params)){ return false; } - foreach ($params as $confKey => $param){ + public function addItemsFromParamsArray($params) + { + if (!array($params)) { return false; } + foreach ($params as $confKey => $param) { $this->addItemFromParams($confKey, $param); // todo manage error } } @@ -133,12 +147,14 @@ class formSetup{ /** * From old - * @param string $confKey - * @param array $params + * @param string $confKey the conf name to store + * @param array $params an array of params from old modulBuilder params + * @deprecated was used to test module builder convertion to this form usage + * @return bool */ - public function addItemFromParams($confKey, $params){ - - if(empty($confKey) || empty($params['type'])){ return false; } + public function addItemFromParams($confKey, $params) + { + if (empty($confKey) || empty($params['type'])) { return false; } /* * Exemple from old module builder setup page @@ -152,26 +168,56 @@ class formSetup{ //'MYMODULE_MYPARAM7'=>array('type'=>'product', 'enabled'=>1), */ - $item = new formSetupItem($this->db); + $item = new formSetupItem($confKey); $item->type = $params['type']; - $item->confKey = $confKey; - if(!empty($params['enabled'])) { + if (!empty($params['enabled'])) { $item->enabled = $params['enabled']; } - if(!empty($params['css'])){ + if (!empty($params['css'])) { $item->cssClass = $params['css']; } - $this->arrayOfParameters[$item->confKey] = $item; + $this->params[$item->confKey] = $item; return true; } + /** + * Reload for each item default conf + * note: this will override custom configuration + * @return bool + */ + public function reloadConfs() + { + + if (!array($this->params)) { return false; } + foreach ($this->params as $item) { + $item->reloadConf(); + } + + return true; + } + + + + /** + * Create a new item + * @param $confKey the conf key used in database + * @return formSetupItem the new setup item created + */ + public function newItem($confKey) + { + $item = new formSetupItem($confKey); + $this->params[$item->confKey] = $item; + return $this->params[$item->confKey]; + } } - +/** + * This class help to create item for class formSetup + */ class formSetupItem { /** @@ -194,67 +240,108 @@ class formSetupItem /** @var string $helpText */ public $helpText = ''; - /** @var bool|string set this var to override field output */ + /** @var string $value */ + public $fieldValue; + + /** @var bool|string set this var to override field output will override $fieldInputOverride and $fieldOutputOverride too */ public $fieldOverride = false; + /** @var bool|string set this var to override field output */ + public $fieldInputOverride = false; + + /** @var bool|string set this var to override field output */ + public $fieldOutputOverride = false; + /** * @var string $errors */ public $errors = array(); /** + * TODO each type must have setAs{type} method to help configuration + * And set var as protected when its done configuration must be done by method * @var string $type 'string', 'textarea', 'category:'.Categorie::TYPE_CUSTOMER', 'emailtemplate', 'thirdparty_type' */ - public $type; + public $type = 'string'; - public $enabled = 0; + public $enabled = 1; public $cssClass = ''; /** * Constructor * - * @param $confKey + * @param $confKey the conf key used in database */ public function __construct($confKey) { - global $langs, $db; + global $langs, $db, $conf; $this->db = $db; $this->form = new Form($this->db); $this->langs = $langs; $this->confKey = $confKey; + $this->fieldValue = $conf->global->{$this->confKey}; } - public function getHelpText(){ - if(!empty($this->helpText)){ return $this->helpText; } + /** + * reload conf value from databases + * @return null + */ + public function reloadConf() + { + global $conf; + $this->fieldValue = $conf->global->{$this->confKey}; + } + + /** + * Get help text or generate it + * @return int|string + */ + public function getHelpText() + { + if (!empty($this->helpText)) { return $this->helpText; } return (($this->langs->trans($this->confKey . 'Tooltip') != $this->confKey . 'Tooltip') ? $this->langs->trans($this->confKey . 'Tooltip') : ''); } - public function getNameText(){ - if(!empty($this->nameText)){ return $this->nameText; } - return (($this->langs->trans($this->confKey) != $this->confKey) ? $this->langs->trans($this->confKey) : $this->langs->trans('MissingTranslationForConfKey',$this->confKey)); + /** + * Get field name text or generate it + * @return false|int|string + */ + public function getNameText() + { + if (!empty($this->nameText)) { return $this->nameText; } + return (($this->langs->trans($this->confKey) != $this->confKey) ? $this->langs->trans($this->confKey) : $this->langs->trans('MissingTranslationForConfKey', $this->confKey)); } - public function generateInputField(){ + /** + * generate input field + * @return bool|string + */ + public function generateInputField() + { global $conf, $user; - if(!empty($this->fieldOverride)){ + if (!empty($this->fieldOverride)) { return $this->fieldOverride; } + if (!empty($this->fieldInputOverride)) { + return $this->fieldInputOverride; + } + $out = ''; if ($this->type == 'textarea') { $out.= '\n"; } elseif ($this->type== 'html') { require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; - $doleditor = new DolEditor($this->confKey, $conf->global->{$this->confKey}, '', 160, 'dolibarr_notes', '', false, false, $conf->fckeditor->enabled, ROWS_5, '90%'); + $doleditor = new DolEditor($this->confKey, $this->fieldValue, '', 160, 'dolibarr_notes', '', false, false, $conf->fckeditor->enabled, ROWS_5, '90%'); $doleditor->Create(); } elseif ($this->type == 'yesno') { - $out.= $this->form->selectyesno($this->confKey, $conf->global->{$this->confKey}, 1); + $out.= $this->form->selectyesno($this->confKey, $this->fieldValue, 1); } elseif (preg_match('/emailtemplate:/', $this->type)) { include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; $formmail = new FormMail($this->db); @@ -274,7 +361,7 @@ class formSetupItem $arrayOfMessageName[$modelMail->id] = $this->langs->trans(preg_replace('/\(|\)/', '', $modelMail->label)) . $moreonlabel; } } - $out.= $this->form->selectarray($this->confKey, $arrayOfMessageName, $conf->global->{$this->confKey}, 'None', 0, 0, '', 0, 0, 0, '', '', 1); + $out.= $this->form->selectarray($this->confKey, $arrayOfMessageName, $this->fieldValue, 'None', 0, 0, '', 0, 0, 0, '', '', 1); } elseif (preg_match('/category:/', $this->type)) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; @@ -282,13 +369,13 @@ class formSetupItem $tmp = explode(':', $this->type); $out.= img_picto('', 'category', 'class="pictofixedwidth"'); - $out.= $formother->select_categories($tmp[1], $conf->global->{$this->confKey}, $this->confKey, 0, $this->langs->trans('CustomersProspectsCategoriesShort')); + $out.= $formother->select_categories($tmp[1], $this->fieldValue, $this->confKey, 0, $this->langs->trans('CustomersProspectsCategoriesShort')); } elseif (preg_match('/thirdparty_type/', $this->type)) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; $formcompany = new FormCompany($this->db); - $out.= $formcompany->selectProspectCustomerType($conf->global->{$this->confKey}, $this->confKey); + $out.= $formcompany->selectProspectCustomerType($this->fieldValue, $this->confKey); } elseif ($this->type == 'securekey') { - $out.= ''; + $out.= ''; if (!empty($conf->use_javascript_ajax)) { $out.= ' '.img_picto($this->langs->trans('Generate'), 'refresh', 'id="generate_token'.$this->confKey.'" class="linkobject"'); } @@ -309,11 +396,11 @@ class formSetupItem } } elseif ($this->type == 'product') { if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { - $selected = (empty($conf->global->{$this->confKey}) ? '' : $conf->global->{$this->confKey}); + $selected = (empty($this->fieldValue) ? '' : $this->fieldValue); $this->form->select_produits($selected, $this->confKey, '', 0); } } else { - $out.= ''; + $out.= ''; } return $out; @@ -321,35 +408,44 @@ class formSetupItem /** - * add error - * @param array|string $errors + * Add error + * @param array|string $errors the error text + * @return null */ - public function setErrors($errors){ - if(is_array($errors)){ - if(!empty($errors)){ - foreach ($errors as $error){ + public function setErrors($errors) + { + if (is_array($errors)) { + if (!empty($errors)) { + foreach ($errors as $error) { $this->setErrors($error); } } - } - elseif(!empty($errors)){ + } elseif (!empty($errors)) { $this->errors[] = $errors; } } - public function generateOutputField(){ + /** + * @return bool|string Generate the output html for this item + */ + public function generateOutputField() + { global $conf, $user; - if(!empty($this->fieldOverride)){ + if (!empty($this->fieldOverride)) { return $this->fieldOverride; } + if (!empty($this->fieldOutputOverride)) { + return $this->fieldOutputOverride; + } + $out = ''; if ($this->type == 'textarea') { - $out.= dol_nl2br($conf->global->{$this->confKey}); + $out.= dol_nl2br($this->fieldValue); } elseif ($this->type== 'html') { - $out.= $conf->global->{$this->confKey}; + $out.= $this->fieldValue; } elseif ($this->type == 'yesno') { $out.= ajax_constantonoff($this->confKey); } elseif (preg_match('/emailtemplate:/', $this->type)) { @@ -358,14 +454,14 @@ class formSetupItem $tmp = explode(':', $this->type); - $template = $formmail->getEMailTemplate($this->db, $tmp[1], $user, $this->langs, $conf->global->{$this->confKey}); + $template = $formmail->getEMailTemplate($this->db, $tmp[1], $user, $this->langs, $this->fieldValue); if ($template<0) { $this->setErrors($formmail->errors); } $out.= $this->langs->trans($template->label); } elseif (preg_match('/category:/', $this->type)) { $c = new Categorie($this->db); - $result = $c->fetch($conf->global->{$this->confKey}); + $result = $c->fetch($this->fieldValue); if ($result < 0) { $this->setErrors($c->errors); } @@ -376,28 +472,105 @@ class formSetupItem } $out.= '
      ' . implode(' ', $toprint) . '
    '; } elseif (preg_match('/thirdparty_type/', $this->type)) { - if ($conf->global->{$this->confKey}==2) { + if ($this->fieldValue==2) { $out.= $this->langs->trans("Prospect"); - } elseif ($conf->global->{$this->confKey}==3) { + } elseif ($this->fieldValue==3) { $out.= $this->langs->trans("ProspectCustomer"); - } elseif ($conf->global->{$this->confKey}==1) { + } elseif ($this->fieldValue==1) { $out.= $this->langs->trans("Customer"); - } elseif ($conf->global->{$this->confKey}==0) { + } elseif ($this->fieldValue==0) { $out.= $this->langs->trans("NorProspectNorCustomer"); } } elseif ($this->type == 'product') { $product = new Product($this->db); - $resprod = $product->fetch($conf->global->{$this->confKey}); + $resprod = $product->fetch($this->fieldValue); if ($resprod > 0) { $out.= $product->ref; } elseif ($resprod < 0) { $this->setErrors($product->errors); } } else { - $out.= $conf->global->{$this->confKey}; + $out.= $this->fieldValue; } return $out; } + /* + * METHODS FOR SETTING DISPLAY TYPE + */ + + /** + * Set type of input as string + * @return null + */ + public function setAsString() + { + $this->type = 'string'; + } + + /** + * Set type of input as textarea + * @return null + */ + public function setAsTextarea() + { + $this->type = 'textarea'; + } + + /** + * Set type of input as html editor + * @return null + */ + public function setAsHtml() + { + $this->type = 'html'; + } + + /** + * Set type of input as emailtemplate selector + * @return null + */ + public function setAsEmailTemplate() + { + $this->type = 'emailtemplate'; + } + + /** + * Set type of input as thirdparty_type selector + * @return null + */ + public function setAsThirdpartyType() + { + $this->type = 'thirdparty_type'; + } + + /** + * Set type of input as Yes + * @return null + */ + public function setAsYesNo() + { + $this->type = 'yesno'; + } + + /** + * Set type of input as secure key + * @return null + */ + public function setAsSecureKey() + { + $this->type = 'securekey'; + } + + /** + * Set type of input as a category selector + * TODO add default value + * @param int $catType Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated. + * @return null + */ + public function setAsCategory($catType) + { + $this->type = 'category:'.$catType; + } } diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 390f45d955c..e3e32cf6f6b 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -85,6 +85,27 @@ $arrayofparameters = array( //'MYMODULE_MYPARAM7'=>array('type'=>'product', 'enabled'=>1), ); +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php'; +$formSetup = new formSetup($db); + +$formSetup->addItemsFromParamsArray($arrayofparameters); + +// Hôte +$item = $formSetup->newItem('GPC_HOST'); +$item->fieldOverride = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST']; + +// Setup conf MYMODULE_MYPARAM1 as a simple string input +$item = $formSetup->newItem('MYMODULE_MYPARAM1'); + +// // Setup conf MYMODULE_MYPARAM1 as a simple textarea input but we replace the text of field title +$item = $formSetup->newItem('MYMODULE_MYPARAM2'); +$item->nameText = $item->getNameText().' https://console.developers.google.com/apis/credentials'; + +// Clé pour API : Client Secret +$formSetup->newItem('GPC_GOOGLE_CLIENT_SECRET'); + + + $error = 0; $setupnotempty = 0; @@ -97,6 +118,7 @@ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); if ((float) DOL_VERSION >= 6) { include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + $formSetup->reloadConfs(); } if ($action == 'updateMask') { @@ -222,11 +244,6 @@ print dol_get_fiche_head($head, 'settings', $langs->trans($page_name), -1, "mymo echo ''.$langs->trans("MyModuleSetupPage").'

    '; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php'; -$formSetup = new formSetup($db); - -$formSetup->addItemsFromParamsArray($arrayofparameters); - if ($action == 'edit') { print ''; print ''; @@ -242,7 +259,6 @@ if ($action == 'edit') { print '
    '; } else { if (!empty($arrayofparameters)) { - print $formSetup->generateOutput(); print '
    '; From 5179f2c90b26fab6bbd0ed121ff68f3ff7d7b22f Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Sat, 30 Oct 2021 13:03:23 +0200 Subject: [PATCH 018/195] Add demo data --- htdocs/modulebuilder/template/admin/setup.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index e3e32cf6f6b..f7f30c19228 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -90,8 +90,9 @@ $formSetup = new formSetup($db); $formSetup->addItemsFromParamsArray($arrayofparameters); + // Hôte -$item = $formSetup->newItem('GPC_HOST'); +$item = $formSetup->newItem('NO_PARAM_JUST_TEXT'); $item->fieldOverride = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST']; // Setup conf MYMODULE_MYPARAM1 as a simple string input @@ -99,12 +100,15 @@ $item = $formSetup->newItem('MYMODULE_MYPARAM1'); // // Setup conf MYMODULE_MYPARAM1 as a simple textarea input but we replace the text of field title $item = $formSetup->newItem('MYMODULE_MYPARAM2'); -$item->nameText = $item->getNameText().' https://console.developers.google.com/apis/credentials'; - -// Clé pour API : Client Secret -$formSetup->newItem('GPC_GOOGLE_CLIENT_SECRET'); +$item->nameText = $item->getNameText().' more html text '; +// Setup conf MYMODULE_MYPARAM3 +$item = $formSetup->newItem('MYMODULE_MYPARAM3'); +$item->setAsThirdpartyType(); + +// Setup conf MYMODULE_MYPARAM4 : quick define write style +$formSetup->newItem('MYMODULE_MYPARAM4')->setAsYesNo(); $error = 0; $setupnotempty = 0; From cdf1538ffacac651367a423cffce3b83d0c93ec9 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Sat, 30 Oct 2021 16:36:51 +0200 Subject: [PATCH 019/195] fix save using template --- htdocs/core/class/html.formsetup.class.php | 59 +++++++++++++++---- htdocs/modulebuilder/template/admin/setup.php | 19 +++++- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index f229d12101d..eb5a9710da1 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -183,6 +183,24 @@ class formSetup return true; } + /** + * used to export param array for /core/actions_setmoduleoptions.inc.php template + * @return array $arrayofparameters for /core/actions_setmoduleoptions.inc.php + * @deprecated + */ + public function exportItemsAsParamsArray() + { + $arrayofparameters = array(); + foreach ($this->params as $key => $item) { + $arrayofparameters[$item->confKey] = array( + 'type' => $item->type, + 'enabled' => $item->enabled + ); + } + + return $arrayofparameters; + } + /** * Reload for each item default conf * note: this will override custom configuration @@ -396,7 +414,7 @@ class formSetupItem } elseif ($this->type == 'product') { if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { $selected = (empty($this->fieldValue) ? '' : $this->fieldValue); - $this->form->select_produits($selected, $this->confKey, '', 0); + $out.= $this->form->select_produits($selected, $this->confKey, '', 0, 0, 1, 2, '', 0, array(), 0, '1', 0, $this->cssClass, 0, '', null, 1); } } else { $out.= ''; @@ -501,75 +519,94 @@ class formSetupItem /** * Set type of input as string - * @return null + * @return self */ public function setAsString() { $this->type = 'string'; + return $this; } /** * Set type of input as textarea - * @return null + * @return self */ public function setAsTextarea() { $this->type = 'textarea'; + return $this; } /** * Set type of input as html editor - * @return null + * @return self */ public function setAsHtml() { $this->type = 'html'; + return $this; } /** * Set type of input as emailtemplate selector - * @return null + * @param string $templateType email template type + * @return self */ - public function setAsEmailTemplate() + public function setAsEmailTemplate($templateType) { - $this->type = 'emailtemplate'; + $this->type = 'emailtemplate:'.$templateType; + return $this; } /** * Set type of input as thirdparty_type selector - * @return null + * @return self */ public function setAsThirdpartyType() { $this->type = 'thirdparty_type'; + return $this; } /** * Set type of input as Yes - * @return null + * @return self */ public function setAsYesNo() { $this->type = 'yesno'; + return $this; } /** * Set type of input as secure key - * @return null + * @return self */ public function setAsSecureKey() { $this->type = 'securekey'; + return $this; + } + + /** + * Set type of input as product + * @return self + */ + public function setAsProduct() + { + $this->type = 'product'; + return $this; } /** * Set type of input as a category selector * TODO add default value * @param int $catType Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated. - * @return null + * @return self */ public function setAsCategory($catType) { $this->type = 'category:'.$catType; + return $this; } } diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index f7f30c19228..007e9d84b12 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -94,22 +94,33 @@ $formSetup->addItemsFromParamsArray($arrayofparameters); // Hôte $item = $formSetup->newItem('NO_PARAM_JUST_TEXT'); $item->fieldOverride = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST']; +$item->cssClass = 'minwidth500'; + // Setup conf MYMODULE_MYPARAM1 as a simple string input $item = $formSetup->newItem('MYMODULE_MYPARAM1'); -// // Setup conf MYMODULE_MYPARAM1 as a simple textarea input but we replace the text of field title +// Setup conf MYMODULE_MYPARAM1 as a simple textarea input but we replace the text of field title $item = $formSetup->newItem('MYMODULE_MYPARAM2'); $item->nameText = $item->getNameText().' more html text '; - // Setup conf MYMODULE_MYPARAM3 $item = $formSetup->newItem('MYMODULE_MYPARAM3'); $item->setAsThirdpartyType(); -// Setup conf MYMODULE_MYPARAM4 : quick define write style +// Setup conf MYMODULE_MYPARAM4 : exemple of quick define write style $formSetup->newItem('MYMODULE_MYPARAM4')->setAsYesNo(); +// Setup conf MYMODULE_MYPARAM5 +$formSetup->newItem('MYMODULE_MYPARAM5')->setAsEmailTemplate('thirdparty'); + +// Setup conf MYMODULE_MYPARAM6 +$formSetup->newItem('MYMODULE_MYPARAM6')->setAsSecureKey()->enabled = 0; // disabled + +// Setup conf MYMODULE_MYPARAM7 +$formSetup->newItem('MYMODULE_MYPARAM7')->setAsProduct(); + + $error = 0; $setupnotempty = 0; @@ -121,6 +132,8 @@ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); */ if ((float) DOL_VERSION >= 6) { + // TODO Add save setup by formSetup + $arrayofparameters = $formSetup->exportItemsAsParamsArray(); include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; $formSetup->reloadConfs(); } From ca766c2e712a2e6e50b1e078541da8e0b70ee642 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Sun, 31 Oct 2021 09:29:20 +0100 Subject: [PATCH 020/195] Factoring --- htdocs/core/class/html.formsetup.class.php | 73 +++++++++++++++++----- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index eb5a9710da1..219308bd5e6 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -63,11 +63,9 @@ class formSetup */ public function generateOutput($editMode = false) { - - $out = ''; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; - $out.= ''; + $out = ''; if ($editMode) { $out .= ''; } @@ -168,7 +166,7 @@ class formSetup */ $item = new formSetupItem($confKey); - $item->type = $params['type']; + $item->setTypeFromTypeString($params['type']); if (!empty($params['enabled'])) { $item->enabled = $params['enabled']; @@ -186,7 +184,7 @@ class formSetup /** * used to export param array for /core/actions_setmoduleoptions.inc.php template * @return array $arrayofparameters for /core/actions_setmoduleoptions.inc.php - * @deprecated + * @deprecated yes this method came deprecated because it exists only for manage setup convertion */ public function exportItemsAsParamsArray() { @@ -279,7 +277,7 @@ class formSetupItem * And set var as protected when its done configuration must be done by method * @var string $type 'string', 'textarea', 'category:'.Categorie::TYPE_CUSTOMER', 'emailtemplate', 'thirdparty_type' */ - public $type = 'string'; + protected $type = 'string'; public $enabled = 1; @@ -349,14 +347,12 @@ class formSetupItem $out = ''; - if ($this->type == 'textarea') { - $out.= '\n"; + if ($this->type == 'title') { + $out.= $this->generateOutputField(); // title have no input + } elseif ($this->type == 'textarea') { + $out.= $this->generateInputFieldTextarea(); } elseif ($this->type== 'html') { - require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; - $doleditor = new DolEditor($this->confKey, $this->fieldValue, '', 160, 'dolibarr_notes', '', false, false, $conf->fckeditor->enabled, ROWS_5, '90%'); - $doleditor->Create(); + $out.= $this->generateInputFieldHtml(); } elseif ($this->type == 'yesno') { $out.= $this->form->selectyesno($this->confKey, $this->fieldValue, 1); } elseif (preg_match('/emailtemplate:/', $this->type)) { @@ -423,6 +419,42 @@ class formSetupItem return $out; } + /** + * generate input field for textarea + * @return string + */ + public function generateInputFieldTextarea() + { + $out = '\n"; + return $out; + } + /** + * generate input field for html + * @return string + */ + public function generateInputFieldHtml() + { + global $conf; + require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; + $doleditor = new DolEditor($this->confKey, $this->fieldValue, '', 160, 'dolibarr_notes', '', false, false, $conf->fckeditor->enabled, ROWS_5, '90%'); + return $doleditor->Create(1); + } + + /** + * set the type from string : used for old module builder setup conf style conversion and tests + * because this two class will quickly evolve it's important to not set directly $this->type (will be protected) so this method exist + * to be sure we can manage evolution easily + * @param string $type possible values based on old module builder setup : 'string', 'textarea', 'category:'.Categorie::TYPE_CUSTOMER', 'emailtemplate', 'thirdparty_type' + * @deprecated yes this method came deprecated because it exists only for manage setup convertion + * @return bool + */ + public function setTypeFromTypeString($type) + { + $this->type = $type; + return true; + } /** * Add error @@ -459,7 +491,9 @@ class formSetupItem $out = ''; - if ($this->type == 'textarea') { + if ($this->type == 'title') { + // nothing to do + } elseif ($this->type == 'textarea') { $out.= dol_nl2br($this->fieldValue); } elseif ($this->type== 'html') { $out.= $this->fieldValue; @@ -609,4 +643,15 @@ class formSetupItem $this->type = 'category:'.$catType; return $this; } + + /** + * Set type of input as a simple title + * no data to store + * @return self + */ + public function setAsTitle() + { + $this->type = 'title'; + return $this; + } } From 39777d4cc5a589c2028bfb56d1a4f00296d36f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 1 Nov 2021 09:37:07 +0100 Subject: [PATCH 021/195] fix error --- htdocs/core/modules/printing/modules_printing.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/printing/modules_printing.php b/htdocs/core/modules/printing/modules_printing.php index 41a87cb2704..1bbf78df022 100644 --- a/htdocs/core/modules/printing/modules_printing.php +++ b/htdocs/core/modules/printing/modules_printing.php @@ -69,7 +69,7 @@ class PrintingDriver $listoffiles = array(); $dirmodels = array_merge(array('/core/modules/printing/'), (array) $conf->modules_parts['printing']); foreach ($dirmodels as $dir) { - $tmpfiles = dol_dir_list(dol_buildpath($dir, 0), 'all', 0, '\modules.php', '', 'name', SORT_ASC, 0); + $tmpfiles = dol_dir_list(dol_buildpath($dir, 0), 'all', 0, '.modules.php', '', 'name', SORT_ASC, 0); if (!empty($tmpfiles)) { $listoffiles = array_merge($listoffiles, $tmpfiles); } From 4c016cc3be9fe59716d703c415648728711bc192 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Mon, 1 Nov 2021 10:11:43 +0100 Subject: [PATCH 022/195] integrate fix from V14 --- htdocs/core/class/html.formsetup.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index 219308bd5e6..a7df249e44c 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -447,7 +447,7 @@ class formSetupItem * because this two class will quickly evolve it's important to not set directly $this->type (will be protected) so this method exist * to be sure we can manage evolution easily * @param string $type possible values based on old module builder setup : 'string', 'textarea', 'category:'.Categorie::TYPE_CUSTOMER', 'emailtemplate', 'thirdparty_type' - * @deprecated yes this method came deprecated because it exists only for manage setup convertion + * @deprecated yes this setTypeFromTypeString came deprecated because it exists only for manage setup convertion * @return bool */ public function setTypeFromTypeString($type) @@ -521,7 +521,7 @@ class formSetupItem foreach ($ways as $way) { $toprint[] = '
  • color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . $way . '
  • '; } - $out.= '
      ' . implode(' ', $toprint) . '
    '; + $out.='
      ' . implode(' ', $toprint) . '
    '; } elseif (preg_match('/thirdparty_type/', $this->type)) { if ($this->fieldValue==2) { $out.= $this->langs->trans("Prospect"); From ea641b707d17a0ca44c2aefc4838453e0e7eee9f Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Mon, 1 Nov 2021 10:32:37 +0100 Subject: [PATCH 023/195] Factoring --- htdocs/core/class/html.formsetup.class.php | 141 ++++++++++++++------- 1 file changed, 95 insertions(+), 46 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index a7df249e44c..df99b6cdbbb 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -191,7 +191,7 @@ class formSetup $arrayofparameters = array(); foreach ($this->params as $key => $item) { $arrayofparameters[$item->confKey] = array( - 'type' => $item->type, + 'type' => $item->getType(), 'enabled' => $item->enabled ); } @@ -356,57 +356,15 @@ class formSetupItem } elseif ($this->type == 'yesno') { $out.= $this->form->selectyesno($this->confKey, $this->fieldValue, 1); } elseif (preg_match('/emailtemplate:/', $this->type)) { - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($this->db); - - $tmp = explode(':', $this->type); - $nboftemplates = $formmail->fetchAllEMailTemplate($tmp[1], $user, null, 1); // We set lang=null to get in priority record with no lang - //$arraydefaultmessage = $formmail->getEMailTemplate($db, $tmp[1], $user, null, 0, 1, ''); - $arrayOfMessageName = array(); - if (is_array($formmail->lines_model)) { - foreach ($formmail->lines_model as $modelMail) { - //var_dump($modelmail); - $moreonlabel = ''; - if (!empty($arrayOfMessageName[$modelMail->label])) { - $moreonlabel = ' (' . $this->langs->trans("SeveralLangugeVariatFound") . ')'; - } - // The 'label' is the key that is unique if we exclude the language - $arrayOfMessageName[$modelMail->id] = $this->langs->trans(preg_replace('/\(|\)/', '', $modelMail->label)) . $moreonlabel; - } - } - $out.= $this->form->selectarray($this->confKey, $arrayOfMessageName, $this->fieldValue, 'None', 0, 0, '', 0, 0, 0, '', '', 1); + $out.= $this->generateInputFieldEmailTemplate(); } elseif (preg_match('/category:/', $this->type)) { - require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; - $formother = new FormOther($this->db); - - $tmp = explode(':', $this->type); - $out.= img_picto('', 'category', 'class="pictofixedwidth"'); - $out.= $formother->select_categories($tmp[1], $this->fieldValue, $this->confKey, 0, $this->langs->trans('CustomersProspectsCategoriesShort')); + $out.=$this->generateInputFieldCategories(); } elseif (preg_match('/thirdparty_type/', $this->type)) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; $formcompany = new FormCompany($this->db); $out.= $formcompany->selectProspectCustomerType($this->fieldValue, $this->confKey); } elseif ($this->type == 'securekey') { - $out.= ''; - if (!empty($conf->use_javascript_ajax)) { - $out.= ' '.img_picto($this->langs->trans('Generate'), 'refresh', 'id="generate_token'.$this->confKey.'" class="linkobject"'); - } - if (!empty($conf->use_javascript_ajax)) { - $out.= "\n".''; - } + $out.= $this->generateInputFieldSecureKey(); } elseif ($this->type == 'product') { if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { $selected = (empty($this->fieldValue) ? '' : $this->fieldValue); @@ -430,6 +388,7 @@ class formSetupItem $out.= "\n"; return $out; } + /** * generate input field for html * @return string @@ -442,6 +401,96 @@ class formSetupItem return $doleditor->Create(1); } + /** + * generate input field for categories + * @return string + */ + public function generateInputFieldCategories() + { + global $conf; + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + $formother = new FormOther($this->db); + + $tmp = explode(':', $this->type); + $out= img_picto('', 'category', 'class="pictofixedwidth"'); + $out.= $formother->select_categories($tmp[1], $this->fieldValue, $this->confKey, 0, $this->langs->trans('CustomersProspectsCategoriesShort')); + return $out; + } + + /** + * generate input field for email template selector + * @return string + */ + public function generateInputFieldEmailTemplate() + { + global $conf, $user; + $out = ''; + if (preg_match('/emailtemplate:/', $this->type)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($this->db); + + $tmp = explode(':', $this->type); + $nboftemplates = $formmail->fetchAllEMailTemplate($tmp[1], $user, null, 1); // We set lang=null to get in priority record with no lang + $arrayOfMessageName = array(); + if (is_array($formmail->lines_model)) { + foreach ($formmail->lines_model as $modelMail) { + $moreonlabel = ''; + if (!empty($arrayOfMessageName[$modelMail->label])) { + $moreonlabel = ' (' . $this->langs->trans("SeveralLangugeVariatFound") . ')'; + } + // The 'label' is the key that is unique if we exclude the language + $arrayOfMessageName[$modelMail->id] = $this->langs->trans(preg_replace('/\(|\)/', '', $modelMail->label)) . $moreonlabel; + } + } + $out .= $this->form->selectarray($this->confKey, $arrayOfMessageName, $this->fieldValue, 'None', 0, 0, '', 0, 0, 0, '', '', 1); + } + + return $out; + } + + + /** + * generate input field for secure key + * @return string + */ + public function generateInputFieldSecureKey() + { + global $conf; + $out = ''; + if (!empty($conf->use_javascript_ajax)) { + $out.= ' '.img_picto($this->langs->trans('Generate'), 'refresh', 'id="generate_token'.$this->confKey.'" class="linkobject"'); + } + if (!empty($conf->use_javascript_ajax)) { + $out .= "\n" . ''; + } + return $out; + } + + /** + * get the type : used for old module builder setup conf style conversion and tests + * because this two class will quickly evolve it's important to not set or get directly $this->type (will be protected) so this method exist + * to be sure we can manage evolution easily + * + * @return string + */ + public function getType() + { + return $this->type; + } + /** * set the type from string : used for old module builder setup conf style conversion and tests * because this two class will quickly evolve it's important to not set directly $this->type (will be protected) so this method exist From 772c3eb43ab784f9154bd57cab7b180a89dc2148 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 1 Nov 2021 11:13:44 +0100 Subject: [PATCH 024/195] Works on ldap password hash type --- htdocs/admin/ldap.php | 15 ++++++++++++--- htdocs/core/class/ldap.class.php | 13 +++++-------- htdocs/langs/en_US/ldap.lang | 2 ++ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index 4010d724c1a..1b93ada1119 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -2,7 +2,7 @@ /* Copyright (C) 2004 Rodolphe Quiedeville * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2005-2021 Regis Houssin * Copyright (C) 2006-2020 Laurent Destailleur * Copyright (C) 2011-2013 Juanjo Menent * @@ -29,10 +29,11 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formldap.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; // Load translation files required by the page -$langs->load("admin"); +$langs->loadLangs(array("admin", "ldap")); if (!$user->admin) { accessforbidden(); @@ -99,6 +100,9 @@ if (empty($reshook)) { if (!dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_ACTIVE', GETPOST("activememberstypes", 'aZ09'), 'chaine', 0, '', $conf->entity)) { $error++; } + if (!dolibarr_set_const($db, 'LDAP_PASSWORD_HASH_TYPE', GETPOST("'LDAP_PASSWORD_HASH_TYPE'", 'aZ09'), 'chaine', 0, '', $conf->entity)) { + $error++; + } if (!$error) { $db->commit(); @@ -129,7 +133,7 @@ if (!function_exists("ldap_connect")) { $form = new Form($db); - +$formldap = new FormLdap($db); print ''; print ''; @@ -251,6 +255,11 @@ $arraylist['1'] = $langs->trans("Yes"); print $form->selectarray('usetls', $arraylist, $conf->global->LDAP_SERVER_USE_TLS); print ''.$langs->trans("LDAPServerUseTLSExample").''; +// Password hash type +print ''.$langs->trans("LDAPPasswordHashType").''; +print $formldap->selectLdapPasswordHashType(getDolGlobalString('LDAP_PASSWORD_HASH_TYPE'), 'LDAP_PASSWORD_HASH_TYPE'); +print ''.$langs->trans("LDAPPasswordHashTypeExample").''; + print ''; print ''.$langs->trans("ForANonAnonymousAccess").''; print "\n"; diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index e2ce33cc45f..0815874d71c 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -159,8 +159,6 @@ class Ldap $this->attr_mobile = $conf->global->LDAP_FIELD_MOBILE; } - - // Connection handling methods ------------------------------------------- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -218,8 +216,9 @@ class Ldap // Upgrade connexion to TLS, if requested by the configuration if (!empty($conf->global->LDAP_SERVER_USE_TLS)) { // For test/debug - //ldap_set_option($this->connection, LDAP_OPT_DEBUG_LEVEL, 7); - //ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_set_option($this->connection, LDAP_OPT_DEBUG_LEVEL, 7); + ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0); $resulttls = ldap_start_tls($this->connection); if (!$resulttls) { @@ -291,8 +290,6 @@ class Ldap return $return; } - - /** * Simply closes the connection set up earlier. * Returns true if OK, false if there was an error. @@ -906,10 +903,10 @@ class Ldap return -3; } - $search = ldap_search($this->connection, $dn, $filter); + $search = @ldap_search($this->connection, $dn, $filter); // Only one entry should ever be returned - $entry = ldap_first_entry($this->connection, $search); + $entry = @ldap_first_entry($this->connection, $search); if (!$entry) { $this->ldapErrorCode = -1; diff --git a/htdocs/langs/en_US/ldap.lang b/htdocs/langs/en_US/ldap.lang index 8b6f0864215..b13e454159d 100644 --- a/htdocs/langs/en_US/ldap.lang +++ b/htdocs/langs/en_US/ldap.lang @@ -25,3 +25,5 @@ ContactSynchronized=Contact synchronized ForceSynchronize=Force synchronizing Dolibarr -> LDAP ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility. PasswordOfUserInLDAP=Password of user in LDAP +LDAPPasswordHashType=Password hash type +LDAPPasswordHashTypeExample=Type of password hash used on the server \ No newline at end of file From 5be40b926b6198e638dba1e796c2114417cd75c9 Mon Sep 17 00:00:00 2001 From: Benjamin Chantalat <74144396+PyroShape@users.noreply.github.com> Date: Mon, 1 Nov 2021 19:56:24 +0100 Subject: [PATCH 025/195] Clean function not use anymore --- .../class/fournisseur.commande.class.php | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 787d9ee321b..9cf3c74e967 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2274,50 +2274,6 @@ class CommandeFournisseur extends CommonOrder return $ret; } - /** - * Return array of the lines that are waiting to be dispatched - * - * @return array Array of lines - */ - public function getNotCompletlyDispatchedLines() - { - $ret = array(); - - $sql = "SELECT supplierOrderDet.fk_product as product_id, supplierOrderDet.qty as qty_ordered, supplierOrderDet.fk_commande,"; - $sql .= " dispatch.rowid as dispatchedlineid, sum(dispatch.qty) as qty_dispatched"; - $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as supplierOrderDet"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as dispatch ON supplierOrderDet.rowid = dispatch.fk_commandefourndet"; - $sql .= " WHERE supplierOrderDet.fk_commande = ".((int) $this->id); - $sql .= " GROUP BY supplierOrderDet.fk_product"; - - $resql = $this->db->query($sql); - - if ($resql) { - $num = $this->db->num_rows($resql); - $i = 0; - - while ($i < $num) { - $objp = $this->db->fetch_object($resql); - - if ($objp) { - // If product not completly dispatched - if (is_null($objp->qty_dispatched) OR ($objp->qty_dispatched < $objp->qty_ordered)) { - $ret[] = array( - 'product_id' => $objp->product_id, - 'qty_ordered' => $objp->qty_ordered, - 'qty_dispatched' => $objp->qty_dispatched, - ); - } - } - $i++; - } - } else { - dol_print_error($this->db, 'Failed to execute request to get not completly dispatched lines'); - } - - return $ret; - } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Set a delivery in database for this supplier order From 7b88f1da3fea112919f0c61bf9cb894323cbfbab Mon Sep 17 00:00:00 2001 From: Benjamin Chantalat <74144396+PyroShape@users.noreply.github.com> Date: Mon, 1 Nov 2021 19:56:55 +0100 Subject: [PATCH 026/195] Change to have number of item dispached on number of total item --- htdocs/core/lib/fourn.lib.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php index e81bdb5e9d0..7fc903db72b 100644 --- a/htdocs/core/lib/fourn.lib.php +++ b/htdocs/core/lib/fourn.lib.php @@ -157,12 +157,24 @@ function ordersupplier_prepare_head($object) if (!empty($conf->stock->enabled) && (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE))) { $langs->load("stocks"); - $nbLineToDispatch = count($object->getNotCompletlyDispatchedLines()); $head[$h][0] = DOL_URL_ROOT.'/fourn/commande/dispatch.php?id='.$object->id; $head[$h][1] = $langs->trans("OrderDispatch"); - if ($nbLineToDispatch > 0) { - $head[$h][1] .= ''.$nbLineToDispatch.''; + + //If dispach process running we add the number of item to dispatch into the head + if ($object->statut == '3' OR $object->statut == '4' OR $object->statut == '5') { + $lines = $object->fetch_lines(); + $dispachedLines = $object->getDispachedLines(1); + $sumQtyAllreadyDispatched = 0; + for ($line = 0 ; $line < count($dispachedLines) ; $line++) { + $sumQtyAllreadyDispatched = $sumQtyAllreadyDispatched + $dispachedLines[$line]['qty']; + } + $sumQtyOrdered = 0; + for ($line = 0 ; $line < count($object->lines) ; $line++) { + $sumQtyOrdered = $sumQtyOrdered + $object->lines[$line]->qty; + } + $head[$h][1] .= ''.$sumQtyAllreadyDispatched.' / '.$sumQtyOrdered.''; } + $head[$h][2] = 'dispatch'; $h++; } From 85372a70836d2d9cdb003cc490bd8fa17c73fc46 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 1 Nov 2021 18:57:35 +0000 Subject: [PATCH 027/195] Fixing style errors. --- htdocs/core/lib/fourn.lib.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php index 7fc903db72b..27ebc98635d 100644 --- a/htdocs/core/lib/fourn.lib.php +++ b/htdocs/core/lib/fourn.lib.php @@ -159,22 +159,22 @@ function ordersupplier_prepare_head($object) $langs->load("stocks"); $head[$h][0] = DOL_URL_ROOT.'/fourn/commande/dispatch.php?id='.$object->id; $head[$h][1] = $langs->trans("OrderDispatch"); - + //If dispach process running we add the number of item to dispatch into the head if ($object->statut == '3' OR $object->statut == '4' OR $object->statut == '5') { $lines = $object->fetch_lines(); $dispachedLines = $object->getDispachedLines(1); $sumQtyAllreadyDispatched = 0; - for ($line = 0 ; $line < count($dispachedLines) ; $line++) { + for ($line = 0 ; $line < count($dispachedLines); $line++) { $sumQtyAllreadyDispatched = $sumQtyAllreadyDispatched + $dispachedLines[$line]['qty']; } $sumQtyOrdered = 0; - for ($line = 0 ; $line < count($object->lines) ; $line++) { + for ($line = 0 ; $line < count($object->lines); $line++) { $sumQtyOrdered = $sumQtyOrdered + $object->lines[$line]->qty; - } + } $head[$h][1] .= ''.$sumQtyAllreadyDispatched.' / '.$sumQtyOrdered.''; } - + $head[$h][2] = 'dispatch'; $h++; } From 85776f7529dbc3d969e827a82d6fcf1c1b168159 Mon Sep 17 00:00:00 2001 From: Benjamin Chantalat <74144396+PyroShape@users.noreply.github.com> Date: Mon, 1 Nov 2021 20:08:00 +0100 Subject: [PATCH 028/195] Avoid function calls in a FOR loop test part --- htdocs/core/lib/fourn.lib.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php index 27ebc98635d..25bbd52e413 100644 --- a/htdocs/core/lib/fourn.lib.php +++ b/htdocs/core/lib/fourn.lib.php @@ -162,14 +162,17 @@ function ordersupplier_prepare_head($object) //If dispach process running we add the number of item to dispatch into the head if ($object->statut == '3' OR $object->statut == '4' OR $object->statut == '5') { - $lines = $object->fetch_lines(); + $object->fetch_lines(); + $nbLinesOrdered = count($object->lines); $dispachedLines = $object->getDispachedLines(1); + $nbDispachedLines = count($dispachedLines); + $sumQtyAllreadyDispatched = 0; - for ($line = 0 ; $line < count($dispachedLines); $line++) { + for ($line = 0 ; $line < $nbDispachedLines; $line++) { $sumQtyAllreadyDispatched = $sumQtyAllreadyDispatched + $dispachedLines[$line]['qty']; } $sumQtyOrdered = 0; - for ($line = 0 ; $line < count($object->lines); $line++) { + for ($line = 0 ; $line < $nbLinesOrdered; $line++) { $sumQtyOrdered = $sumQtyOrdered + $object->lines[$line]->qty; } $head[$h][1] .= ''.$sumQtyAllreadyDispatched.' / '.$sumQtyOrdered.''; From f73f3cd55f271a43d8bdca2e9d8dae9911b4caee Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 2 Nov 2021 04:50:29 +0100 Subject: [PATCH 029/195] typo --- htdocs/core/lib/company.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index ddaf1d320c3..313dd5d8fbe 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -295,7 +295,7 @@ function societe_prepare_head(Societe $object) // Notifications if (!empty($conf->notification->enabled)) { $nbNotif = 0; - // Enable caching of thirdrparty count notifications + // Enable caching of thirdparty count notifications require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php'; $cachekey = 'count_notifications_thirdparty_'.$object->id; $dataretrieved = dol_getcache($cachekey); From fb0002a38ee7efdbbf35791f4bbeb2098aa1097e Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 2 Nov 2021 04:51:18 +0100 Subject: [PATCH 030/195] Factorize user rights --- htdocs/societe/paymentmodes.php | 61 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 9cb0eadecf5..18d560f6d9f 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -1,12 +1,13 @@ - * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2004-2018 Laurent Destailleur - * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2013 Peter Fontaine - * Copyright (C) 2015-2016 Marcos García - * Copyright (C) 2017 Ferran Marcet - * Copyright (C) 2018 -2021Thibault FOUCART +/* Copyright (C) 2002-2004 Rodolphe Quiedeville + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2018 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2013 Peter Fontaine + * Copyright (C) 2015-2016 Marcos García + * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018-2021 Thibault FOUCART + * Copyright (C) 2021 Alexandre Spangaro * * 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 @@ -41,7 +42,6 @@ require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; $langs->loadLangs(array("companies", "commercial", "banks", "bills", 'paypal', 'stripe', 'withdrawals')); - // Security check $socid = GETPOST("socid", "int"); if ($user->socid) { @@ -70,6 +70,10 @@ $extrafields->fetch_name_optionals_label($object->table_element); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('thirdpartybancard', 'globalcard')); +$permissiontoread = $user->rights->societe->lire; +$permissiontoadd = $user->rights->societe->creer; // Used by the include of actions_addupdatedelete.inc.php and actions_builddoc.inc.php + +$permissiontoaddupdatepaymentinformation = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $permissiontoadd) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->societe->addupdate_thirdparty_payment_information->write))); if (!empty($conf->stripe->enabled)) { $service = 'StripeTest'; @@ -455,7 +459,6 @@ if (empty($reshook)) { $id = $socid; $upload_dir = $conf->societe->multidir_output[$object->entity]; - $permissiontoadd = $user->rights->societe->creer; include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; $id = $savid; @@ -703,7 +706,7 @@ if (empty($companybankaccount->socid)) { $companybankaccount->socid = $object->id; } -if ($socid && ($action == 'edit' || $action == 'editcard') && $user->rights->societe->creer) { +if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoadd) { print ''; print ''; $actionforadd = 'update'; @@ -713,7 +716,7 @@ if ($socid && ($action == 'edit' || $action == 'editcard') && $user->rights->soc print ''; print ''; } -if ($socid && ($action == 'create' || $action == 'createcard') && $user->rights->societe->creer) { +if ($socid && ($action == 'create' || $action == 'createcard') && $permissiontoadd) { print ''; print ''; $actionforadd = 'add'; @@ -787,12 +790,11 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' } if (!empty($conf->stripe->enabled)) { - $permissiontowrite = $user->rights->societe->creer; // Stripe customer key 'cu_....' stored into llx_societe_account print ''; - print $form->editfieldkey("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontowrite, 'string', '', 0, 2, 'socid'); + print $form->editfieldkey("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontoadd, 'string', '', 0, 2, 'socid'); print ''; - print $form->editfieldval("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontowrite, 'string', '', null, null, '', 2, '', 'socid'); + print $form->editfieldval("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontoadd, 'string', '', null, null, '', 2, '', 'socid'); if (!empty($conf->stripe->enabled) && $stripecu && $action != 'editkey_account') { $connect = ''; if (!empty($stripeacc)) { @@ -849,14 +851,13 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' } if (!empty($conf->stripe->enabled) && !empty($conf->stripeconnect->enabled) && $conf->global->MAIN_FEATURES_LEVEL >= 2) { - $permissiontowrite = $user->rights->societe->creer; $stripesupplieracc = $stripe->getStripeAccount($service, $object->id); // Get Stripe OAuth connect account (no network access here) // Stripe customer key 'cu_....' stored into llx_societe_account print ''; - print $form->editfieldkey("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontowrite, 'string', '', 0, 2, 'socid'); + print $form->editfieldkey("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontoadd, 'string', '', 0, 2, 'socid'); print ''; - print $form->editfieldval("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontowrite, 'string', '', null, null, '', 2, '', 'socid'); + print $form->editfieldval("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontoadd, 'string', '', null, null, '', 2, '', 'socid'); if (!empty($conf->stripe->enabled) && $stripesupplieracc && $action != 'editkey_account_supplier') { $connect = ''; @@ -1061,7 +1062,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print $hookmanager->resPrint; // Action column print ''; - if ($user->rights->societe->creer) { + if ($permissiontoadd) { if ($stripecu && empty($companypaymentmodetemp->stripe_card_ref)) { print ''.$langs->trans("CreateCardOnStripe").''; } @@ -1214,7 +1215,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print $hookmanager->resPrint; // Action column print ''; - if ($user->rights->societe->creer) { + if ($permissiontoadd) { print ''; print img_picto($langs->trans("Delete"), 'delete'); print ''; @@ -1288,7 +1289,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' $rib_list = $object->get_all_rib(); if (is_array($rib_list)) { - print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table + print '
    '; // You can use div-table-responsive-no-min if you don't need reserved height for your table print ''; print ''; @@ -1446,7 +1447,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' // Edit/Delete print ''; print ''; print ''; + print ''; } print ''; print ''; print ''; print ''; - if (!empty($conf->multicurrency->enabled)) { - print ''; - } print ''; $total = 0; @@ -657,8 +655,26 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print price($sign * $multicurrency_remaintopay); } print ''; - } - + + print '"; + } + print ''; print '"; - // Multicurrency Price - if (!empty($conf->multicurrency->enabled)) { - print '"; - } - print "\n"; $total += $objp->total_ht; $total_ttc += $objp->total_ttc; @@ -730,6 +723,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print ''; print ''; print ''; + print ''; } print ''; print ''; print ''; print ''; // Autofilled - if (!empty($conf->multicurrency->enabled)) { - print ''; - } print "\n"; } print "
    '; - if ($user->rights->societe->creer) { + if ($permissiontoadd) { print ''; print img_picto($langs->trans("Modify"), 'edit'); print ''; @@ -1486,10 +1487,8 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' */ $filedir = $conf->societe->multidir_output[$object->entity].'/'.$object->id; $urlsource = $_SERVER["PHP_SELF"]."?socid=".$object->id; - $genallowed = $user->rights->societe->lire; - $delallowed = $user->rights->societe->creer; - print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang); + print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $permissiontoread, $permissiontoadd, $object->model_pdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang); // Show direct download link if (!empty($conf->global->BANK_ACCOUNT_ALLOW_EXTERNAL_DOWNLOAD)) { @@ -1536,7 +1535,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' } // Edit BAN -if ($socid && $action == 'edit' && $user->rights->societe->creer) { +if ($socid && $action == 'edit' && $permissiontoadd) { print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1655,7 +1654,7 @@ if ($socid && $action == 'edit' && $user->rights->societe->creer) { } // Edit Card -if ($socid && $action == 'editcard' && $user->rights->societe->creer) { +if ($socid && $action == 'editcard' && $permissiontoadd) { print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1698,7 +1697,7 @@ if ($socid && $action == 'editcard' && $user->rights->societe->creer) { // Create BAN -if ($socid && $action == 'create' && $user->rights->societe->creer) { +if ($socid && $action == 'create' && $permissiontoadd) { print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1813,7 +1812,7 @@ if ($socid && $action == 'create' && $user->rights->societe->creer) { } // Create Card -if ($socid && $action == 'createcard' && $user->rights->societe->creer) { +if ($socid && $action == 'createcard' && $permissiontoadd) { print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1857,10 +1856,10 @@ if ($socid && $action == 'createcard' && $user->rights->societe->creer) { print $form->buttonsSaveCancel("Add"); } -if ($socid && ($action == 'edit' || $action == 'editcard') && $user->rights->societe->creer) { +if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoadd) { print ''; } -if ($socid && ($action == 'create' || $action == 'createcard') && $user->rights->societe->creer) { +if ($socid && ($action == 'create' || $action == 'createcard') && $permissiontoadd) { print ''; } From 155eae1772e6f2fa647b8d31704bc20cc4a1e1f3 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 2 Nov 2021 04:52:16 +0100 Subject: [PATCH 031/195] Add advanced right to add / update thirdparty payment information --- htdocs/core/modules/modSociete.class.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index c3eba65673b..a177f367c23 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -197,6 +197,13 @@ class modSociete extends DolibarrModules $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'export'; + $r++; + $this->rights[$r][0] = 130; + $this->rights[$r][1] = 'Modify thirdparty information payment'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'addupdate_thirdparty_payment_information'; // Visible if option MAIN_USE_ADVANCED_PERMS is on + $this->rights[$r][5] = 'write'; + // 262 : Restrict access to sales representative $r++; $this->rights[$r][0] = 262; From b128fb5ad9887c949ab321f49bd216ff884ffe53 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 2 Nov 2021 04:55:20 +0100 Subject: [PATCH 032/195] Add advanced right to add / update thirdparty payment information --- htdocs/societe/paymentmodes.php | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 07f0193359c..fa4b6069430 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -706,7 +706,7 @@ if (empty($companybankaccount->socid)) { $companybankaccount->socid = $object->id; } -if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoadd) { +if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoaddupdatepaymentinformation) { print '
    '; print ''; $actionforadd = 'update'; @@ -716,7 +716,7 @@ if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoadd) print ''; print ''; } -if ($socid && ($action == 'create' || $action == 'createcard') && $permissiontoadd) { +if ($socid && ($action == 'create' || $action == 'createcard') && $permissiontoaddupdatepaymentinformation) { print ''; print ''; $actionforadd = 'add'; @@ -792,9 +792,9 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' if (!empty($conf->stripe->enabled)) { // Stripe customer key 'cu_....' stored into llx_societe_account print '
    '; - print $form->editfieldkey("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontoadd, 'string', '', 0, 2, 'socid'); + print $form->editfieldkey("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontoaddupdatepaymentinformation, 'string', '', 0, 2, 'socid'); print ''; - print $form->editfieldval("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontoadd, 'string', '', null, null, '', 2, '', 'socid'); + print $form->editfieldval("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontoaddupdatepaymentinformation, 'string', '', null, null, '', 2, '', 'socid'); if (!empty($conf->stripe->enabled) && $stripecu && $action != 'editkey_account') { $connect = ''; if (!empty($stripeacc)) { @@ -855,9 +855,9 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' // Stripe customer key 'cu_....' stored into llx_societe_account print '
    '; - print $form->editfieldkey("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontoadd, 'string', '', 0, 2, 'socid'); + print $form->editfieldkey("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontoaddupdatepaymentinformation, 'string', '', 0, 2, 'socid'); print ''; - print $form->editfieldval("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontoadd, 'string', '', null, null, '', 2, '', 'socid'); + print $form->editfieldval("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontoaddupdatepaymentinformation, 'string', '', null, null, '', 2, '', 'socid'); if (!empty($conf->stripe->enabled) && $stripesupplieracc && $action != 'editkey_account_supplier') { $connect = ''; @@ -1062,7 +1062,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print $hookmanager->resPrint; // Action column print ''; - if ($permissiontoadd) { + if ($permissiontoaddupdatepaymentinformation) { if ($stripecu && empty($companypaymentmodetemp->stripe_card_ref)) { print ''.$langs->trans("CreateCardOnStripe").''; } @@ -1215,7 +1215,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print $hookmanager->resPrint; // Action column print ''; - if ($permissiontoadd) { + if ($permissiontoaddupdatepaymentinformation) { print ''; print img_picto($langs->trans("Delete"), 'delete'); print ''; @@ -1449,7 +1449,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' // Edit/Delete print ''; - if ($permissiontoadd) { + if ($permissiontoaddupdatepaymentinformation) { print ''; print img_picto($langs->trans("Modify"), 'edit'); print ''; @@ -1490,7 +1490,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' $filedir = $conf->societe->multidir_output[$object->entity].'/'.$object->id; $urlsource = $_SERVER["PHP_SELF"]."?socid=".$object->id; - print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $permissiontoread, $permissiontoadd, $object->model_pdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang); + print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $permissiontoread, $permissiontoaddupdatepaymentinformation, $object->model_pdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang); // Show direct download link if (!empty($conf->global->BANK_ACCOUNT_ALLOW_EXTERNAL_DOWNLOAD)) { @@ -1537,7 +1537,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' } // Edit BAN -if ($socid && $action == 'edit' && $permissiontoadd) { +if ($socid && $action == 'edit' && $permissiontoaddupdatepaymentinformation) { print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1656,7 +1656,7 @@ if ($socid && $action == 'edit' && $permissiontoadd) { } // Edit Card -if ($socid && $action == 'editcard' && $permissiontoadd) { +if ($socid && $action == 'editcard' && $permissiontoaddupdatepaymentinformation) { print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1699,7 +1699,7 @@ if ($socid && $action == 'editcard' && $permissiontoadd) { // Create BAN -if ($socid && $action == 'create' && $permissiontoadd) { +if ($socid && $action == 'create' && $permissiontoaddupdatepaymentinformation) { print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1814,7 +1814,7 @@ if ($socid && $action == 'create' && $permissiontoadd) { } // Create Card -if ($socid && $action == 'createcard' && $permissiontoadd) { +if ($socid && $action == 'createcard' && $permissiontoaddupdatepaymentinformation) { print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; @@ -1858,10 +1858,10 @@ if ($socid && $action == 'createcard' && $permissiontoadd) { print $form->buttonsSaveCancel("Add"); } -if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoadd) { +if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoaddupdatepaymentinformation) { print ''; } -if ($socid && ($action == 'create' || $action == 'createcard') && $permissiontoadd) { +if ($socid && ($action == 'create' || $action == 'createcard') && $permissiontoaddupdatepaymentinformation) { print ''; } From 8992276e25bc1fab93059730c01b8d2cfbdcb9e9 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 2 Nov 2021 05:18:32 +0100 Subject: [PATCH 033/195] Hidden button without specific advancedright --- htdocs/societe/paymentmodes.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index fa4b6069430..b278c7c6da3 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -1282,8 +1282,9 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' } // List of bank accounts - - $morehtmlright = dolGetButtonTitle($langs->trans('Add'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?socid='.$object->id.'&action=create'); + if ($permissiontoaddupdatepaymentinformation) { + $morehtmlright = dolGetButtonTitle($langs->trans('Add'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&action=create'); + } print load_fiche_titre($langs->trans("BankAccounts"), $morehtmlright, 'bank'); From 13123c3370d352625dccdb54f1ecaba87e74a491 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 2 Nov 2021 05:31:51 +0100 Subject: [PATCH 034/195] Permission language key --- htdocs/langs/en_US/admin.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 7ffbe0328c1..9e5cefe79a3 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -762,6 +762,7 @@ Permission121=Read third parties linked to user Permission122=Create/modify third parties linked to user Permission125=Delete third parties linked to user Permission126=Export third parties +Permission130=Create/modify third parties payment information Permission141=Read all projects and tasks (also private projects for which I am not a contact) Permission142=Create/modify all projects and tasks (also private projects for which I am not a contact) Permission144=Delete all projects and tasks (also private projects i am not contact for) From b56eaf91e892f39252b1d431fd71eb082002fa85 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 2 Nov 2021 20:53:00 +0800 Subject: [PATCH 035/195] Update paiement.php --- htdocs/fourn/facture/paiement.php | 53 +++++++++++++------------------ 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index 1dd6f0a0f12..cdd73b5ef70 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -555,14 +555,12 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print ''.$langs->trans('MulticurrencyAmountTTC').''.$langs->trans('MulticurrencyAlreadyPaid').''.$langs->trans('MulticurrencyRemainderToPay').''.$langs->trans('MulticurrencyPaymentAmount').''.$langs->trans('AmountTTC').''.$langs->trans('AlreadyPaid').''.$langs->trans('RemainderToPay').''.$langs->trans('PaymentAmount').''.$langs->trans('MulticurrencyPaymentAmount').'
    '; + // Add remind multicurrency amount + $namef = 'multicurrency_amount_'.$objp->facid; + $nameRemain = 'multicurrency_remain_'.$objp->facid; + if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) { + if ($action != 'add_paiement') { + if (!empty($conf->use_javascript_ajax)) { + print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'"); + } + print ''; + print ''; + } else { + print ''; + print ''; + } + } + print "'.price($sign * $objp->total_ttc).''.price($sign * $objp->am); @@ -690,29 +706,6 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie } print "'; - - // Add remind multicurrency amount - $namef = 'multicurrency_amount_'.$objp->facid; - $nameRemain = 'multicurrency_remain_'.$objp->facid; - - if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) { - if ($action != 'add_paiement') { - if (!empty($conf->use_javascript_ajax)) { - print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'"); - } - print ''; - print ''; - } else { - print ''; - print ''; - } - } - print "
       '.price($sign * $total_ttc).''.price($sign * $totalrecu); @@ -742,9 +736,6 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print ''.price($sign * price2num($total_ttc - $totalrecu - $totalrecucreditnote - $totalrecudeposits, 'MT')).'
    \n"; From b98efd7e44085ff4f7bb0e9ac056139994bb7c4a Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Tue, 2 Nov 2021 13:55:12 +0100 Subject: [PATCH 036/195] Add rank item management and add Hook --- htdocs/core/class/html.formsetup.class.php | 258 ++++++++++++++++-- htdocs/modulebuilder/template/admin/setup.php | 27 +- 2 files changed, 248 insertions(+), 37 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index df99b6cdbbb..cbf8cbd37ba 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -30,6 +30,9 @@ class formSetup /** @var formSetupItem[] */ public $params = array(); + /** + * @var int + */ public $setupNotEmpty = 0; /** @var Translate */ @@ -38,6 +41,9 @@ class formSetup /** @var Form */ public $form; + /** @var int */ + protected $maxItemRank; + /** * Constructor * @@ -63,29 +69,81 @@ class formSetup */ public function generateOutput($editMode = false) { + global $hookmanager, $action; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; - $out = ''; - if ($editMode) { - $out .= ''; + $parameters = array( + 'editMode' => $editMode + ); + $reshook = $hookmanager->executeHooks('formSetupBeforeGenerateOutput', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } - $out.= ''; - $out.= ''; - $out.= ''; - $out.= ' '; - $out.= ' '; - $out.= ''; - $out.= ''; + if ($reshook > 0) { + return $hookmanager->resPrint; + } else { + $out = ''; + if ($editMode) { + $out .= ''; + } - $out.= ''; + $out .= '
    '.$this->langs->trans("Parameter").''.$this->langs->trans("Value").'
    '; + $out .= ''; + $out .= ''; + $out .= ' '; + $out .= ' '; + $out .= ''; + $out .= ''; + + // Sort items before render + $this->sortingItems(); + + $out .= ''; + foreach ($this->params as $item) { + $out .= $this->generateLineOutput($item, $editMode); + } + $out .= ''; + + $out .= '
    ' . $this->langs->trans("Parameter") . '' . $this->langs->trans("Value") . '
    '; + return $out; + } + } + + /** + * @param bool $noMessageInUpdate display event message on errors and success + * @return void|null + */ + public function saveConfFromPost($noMessageInUpdate = false) + { + + if (empty($this->params)) { + return null; + } + + $this->db->begin(); + $error = 0; foreach ($this->params as $item) { - $out.= $this->generateLineOutput($item, $editMode); + $res = $item->setValueFromPost(); + if ($res > 0) { + $item->saveConfValue(); + } elseif ($res < 0) { + $error++; + break; + } } - $out.= ''; - $out.= ''; - return $out; + if (!$error) { + $this->db->commit(); + if (empty($noMessageInUpdate)) { + setEventMessages($this->langs->trans("SetupSaved"), null); + } + } else { + $this->db->rollback(); + if (empty($noMessageInUpdate)) { + setEventMessages($this->langs->trans("SetupNotSaved"), null, 'errors'); + } + } } /** @@ -209,25 +267,133 @@ class formSetup if (!array($this->params)) { return false; } foreach ($this->params as $item) { - $item->reloadConf(); + $item->reloadValueFromConf(); } return true; } - /** * Create a new item + * the tagret is useful with hooks : that allow externals modules to add setup items on good place * @param $confKey the conf key used in database + * @param string $targetItemKey target item used to place the new item beside + * @param bool $insertAfterTarget insert before or after target item ? * @return formSetupItem the new setup item created */ - public function newItem($confKey) + public function newItem($confKey, $targetItemKey = false, $insertAfterTarget = false) { $item = new formSetupItem($confKey); + + // set item rank if not defined as last item + if (empty($item->rank)) { + $item->rank = $this->getCurentItemMaxRank() + 1; + $this->setItemMaxRank($item->rank); // set new max rank if needed + } + + // try to get rank from target column, this will override item->rank + if (!empty($targetItemKey)) { + if (isset($this->params[$targetItemKey])) { + $targetItem = $this->params[$targetItemKey]; + $item->rank = $targetItem->rank; // $targetItem->rank will be increase after + if ($targetItem->rank >= 0 && $insertAfterTarget) { + $item->rank++; + } + } + + // calc new rank for each item to make place for new item + foreach ($this->params as $fItem) { + if ($item->rank <= $fItem->rank) { + $fItem->rank = $fItem->rank + 1; + $this->setItemMaxRank($fItem->rank); // set new max rank if needed + } + } + } + $this->params[$item->confKey] = $item; return $this->params[$item->confKey]; } + + /** + * Sort items according to rank + * @return bool + */ + public function sortingItems() + { + // Sorting + return uasort($this->params, array($this, 'itemSort')); + } + + /** + * @param bool $cache To use cache or not + * @return int + */ + public function getCurentItemMaxRank($cache = true) + { + if (empty($this->params)) { + return 0; + } + + if ($cache && $this->maxItemRank > 0) { + return $this->maxItemRank; + } + + $this->maxItemRank = 0; + foreach ($this->params as $item) { + $this->maxItemRank = max($this->maxItemRank, $item->rank); + } + + return $this->maxItemRank; + } + + + /** + * set new max rank if needed + * @param int $rank the item rank + * @return int|void + */ + public function setItemMaxRank($rank) + { + $this->maxItemRank = max($this->maxItemRank, $rank); + } + + + /** + * get item position rank from item key + * + * @param string $itemKey the item key + * @return int rank on success and -1 on error + */ + public function getLineRank($itemKey) + { + if (!isset($this->params[$itemKey]->rank)) { + return -1; + } + return $this->params[$itemKey]->rank; + } + + + /** + * uasort callback function to Sort params items + * + * @param formSetupItem $a formSetup item + * @param formSetupItem $b formSetup item + * @return int Return compare result + */ + public function itemSort(formSetupItem $a, formSetupItem $b) + { + if (empty($a->rank)) { + $a->rank = 0; + } + if (empty($b->rank)) { + $b->rank = 0; + } + if ($a->rank == $b->rank) { + return 0; + } + return ($a->rank < $b->rank) ? -1 : 1; + } } /** @@ -243,6 +409,9 @@ class formSetupItem /** @var Translate */ public $langs; + /** @var int */ + public $entity; + /** @var Form */ public $form; @@ -267,6 +436,9 @@ class formSetupItem /** @var bool|string set this var to override field output */ public $fieldOutputOverride = false; + /** @var int $rank */ + public $rank = 0; + /** * @var string $errors */ @@ -294,6 +466,7 @@ class formSetupItem $this->db = $db; $this->form = new Form($this->db); $this->langs = $langs; + $this->entity = $conf->entity; $this->confKey = $confKey; $this->fieldValue = $conf->global->{$this->confKey}; @@ -303,12 +476,58 @@ class formSetupItem * reload conf value from databases * @return null */ - public function reloadConf() + public function reloadValueFromConf() { global $conf; $this->fieldValue = $conf->global->{$this->confKey}; } + + /** + * Save const value based on htdocs/core/actions_setmoduleoptions.inc.php + * @return int -1 if KO, 1 if OK + */ + public function saveConfValue() + { + // Modify constant only if key was posted (avoid resetting key to the null value) + if ($this->type != 'title') { + $result = dolibarr_set_const($this->db, $this->confKey, $this->fieldValue, 'chaine', 0, '', $this->entity); + if ($result < 0) { + return -1; + } else { + return 1; + } + } + } + + + /** + * Save const value based on htdocs/core/actions_setmoduleoptions.inc.php + * @return int -1 if KO, 0 nothing to do , 1 if OK + */ + public function setValueFromPost() + { + // Modify constant only if key was posted (avoid resetting key to the null value) + if ($this->type != 'title') { + if (preg_match('/category:/', $this->type)) { + if (GETPOST($this->confKey, 'int') == '-1') { + $val_const = ''; + } else { + $val_const = GETPOST($this->confKey, 'int'); + } + } else { + $val_const = GETPOST($this->confKey, 'alpha'); + } + + // TODO add value check with class validate + $this->fieldValue = $val_const; + + return 1; + } + + return 0; + } + /** * Get help text or generate it * @return int|string @@ -596,6 +815,7 @@ class formSetupItem return $out; } + /* * METHODS FOR SETTING DISPLAY TYPE */ diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 007e9d84b12..527ea8eb32d 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -60,6 +60,9 @@ require_once '../lib/mymodule.lib.php'; // Translations $langs->loadLangs(array("admin", "mymodule@mymodule")); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('mymodulesetup', 'globalsetup')); + // Access control if (!$user->admin) { accessforbidden(); @@ -74,22 +77,10 @@ $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'myobject'; -$arrayofparameters = array( - 'MYMODULE_MYPARAM1'=>array('type'=>'string', 'css'=>'minwidth500' ,'enabled'=>1), - 'MYMODULE_MYPARAM2'=>array('type'=>'textarea','enabled'=>1), - //'MYMODULE_MYPARAM3'=>array('type'=>'category:'.Categorie::TYPE_CUSTOMER, 'enabled'=>1), - //'MYMODULE_MYPARAM4'=>array('type'=>'emailtemplate:thirdparty', 'enabled'=>1), - //'MYMODULE_MYPARAM5'=>array('type'=>'yesno', 'enabled'=>1), - //'MYMODULE_MYPARAM5'=>array('type'=>'thirdparty_type', 'enabled'=>1), - //'MYMODULE_MYPARAM6'=>array('type'=>'securekey', 'enabled'=>1), - //'MYMODULE_MYPARAM7'=>array('type'=>'product', 'enabled'=>1), -); require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php'; $formSetup = new formSetup($db); -$formSetup->addItemsFromParamsArray($arrayofparameters); - // Hôte $item = $formSetup->newItem('NO_PARAM_JUST_TEXT'); @@ -131,11 +122,10 @@ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); * Actions */ -if ((float) DOL_VERSION >= 6) { - // TODO Add save setup by formSetup - $arrayofparameters = $formSetup->exportItemsAsParamsArray(); - include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; - $formSetup->reloadConfs(); +if ((float) DOL_VERSION >= 15) { + if ($action == 'update') { + $formSetup->saveConfFromPost(); + } } if ($action == 'updateMask') { @@ -275,8 +265,9 @@ if ($action == 'edit') { print ''; print '
    '; } else { - if (!empty($arrayofparameters)) { + if (!empty($formSetup->params)) { print $formSetup->generateOutput(); + $setupnotempty++; print '
    '; print ''.$langs->trans("Modify").''; From 899f0bee9a191a699104ee60dad8b35bb5aa639f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 2 Nov 2021 12:59:38 +0000 Subject: [PATCH 037/195] Fixing style errors. --- htdocs/fourn/facture/paiement.php | 40 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index cdd73b5ef70..76e15127098 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -655,26 +655,26 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print price($sign * $multicurrency_remaintopay); } print ''; - - print ''; - // Add remind multicurrency amount - $namef = 'multicurrency_amount_'.$objp->facid; - $nameRemain = 'multicurrency_remain_'.$objp->facid; - if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) { - if ($action != 'add_paiement') { - if (!empty($conf->use_javascript_ajax)) { - print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'"); - } - print ''; - print ''; - } else { - print ''; - print ''; - } - } - print ""; - } - + + print ''; + // Add remind multicurrency amount + $namef = 'multicurrency_amount_'.$objp->facid; + $nameRemain = 'multicurrency_remain_'.$objp->facid; + if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) { + if ($action != 'add_paiement') { + if (!empty($conf->use_javascript_ajax)) { + print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'"); + } + print ''; + print ''; + } else { + print ''; + print ''; + } + } + print ""; + } + print ''.price($sign * $objp->total_ttc).''; print ''.price($sign * $objp->am); From bbe71c9c32d792a3fd0cfe56b37394d9af6f4942 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Tue, 2 Nov 2021 14:07:36 +0100 Subject: [PATCH 038/195] Rename var --- htdocs/core/class/html.formsetup.class.php | 36 +++++++++---------- htdocs/modulebuilder/template/admin/setup.php | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index cbf8cbd37ba..8f9d3af0528 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -28,7 +28,7 @@ class formSetup public $db; /** @var formSetupItem[] */ - public $params = array(); + public $items = array(); /** * @var int @@ -100,7 +100,7 @@ class formSetup $this->sortingItems(); $out .= ''; - foreach ($this->params as $item) { + foreach ($this->items as $item) { $out .= $this->generateLineOutput($item, $editMode); } $out .= ''; @@ -117,13 +117,13 @@ class formSetup public function saveConfFromPost($noMessageInUpdate = false) { - if (empty($this->params)) { + if (empty($this->items)) { return null; } $this->db->begin(); $error = 0; - foreach ($this->params as $item) { + foreach ($this->items as $item) { $res = $item->setValueFromPost(); if ($res > 0) { $item->saveConfValue(); @@ -234,7 +234,7 @@ class formSetup $item->cssClass = $params['css']; } - $this->params[$item->confKey] = $item; + $this->items[$item->confKey] = $item; return true; } @@ -247,7 +247,7 @@ class formSetup public function exportItemsAsParamsArray() { $arrayofparameters = array(); - foreach ($this->params as $key => $item) { + foreach ($this->items as $key => $item) { $arrayofparameters[$item->confKey] = array( 'type' => $item->getType(), 'enabled' => $item->enabled @@ -265,8 +265,8 @@ class formSetup public function reloadConfs() { - if (!array($this->params)) { return false; } - foreach ($this->params as $item) { + if (!array($this->items)) { return false; } + foreach ($this->items as $item) { $item->reloadValueFromConf(); } @@ -294,8 +294,8 @@ class formSetup // try to get rank from target column, this will override item->rank if (!empty($targetItemKey)) { - if (isset($this->params[$targetItemKey])) { - $targetItem = $this->params[$targetItemKey]; + if (isset($this->items[$targetItemKey])) { + $targetItem = $this->items[$targetItemKey]; $item->rank = $targetItem->rank; // $targetItem->rank will be increase after if ($targetItem->rank >= 0 && $insertAfterTarget) { $item->rank++; @@ -303,7 +303,7 @@ class formSetup } // calc new rank for each item to make place for new item - foreach ($this->params as $fItem) { + foreach ($this->items as $fItem) { if ($item->rank <= $fItem->rank) { $fItem->rank = $fItem->rank + 1; $this->setItemMaxRank($fItem->rank); // set new max rank if needed @@ -311,8 +311,8 @@ class formSetup } } - $this->params[$item->confKey] = $item; - return $this->params[$item->confKey]; + $this->items[$item->confKey] = $item; + return $this->items[$item->confKey]; } /** @@ -322,7 +322,7 @@ class formSetup public function sortingItems() { // Sorting - return uasort($this->params, array($this, 'itemSort')); + return uasort($this->items, array($this, 'itemSort')); } /** @@ -331,7 +331,7 @@ class formSetup */ public function getCurentItemMaxRank($cache = true) { - if (empty($this->params)) { + if (empty($this->items)) { return 0; } @@ -340,7 +340,7 @@ class formSetup } $this->maxItemRank = 0; - foreach ($this->params as $item) { + foreach ($this->items as $item) { $this->maxItemRank = max($this->maxItemRank, $item->rank); } @@ -367,10 +367,10 @@ class formSetup */ public function getLineRank($itemKey) { - if (!isset($this->params[$itemKey]->rank)) { + if (!isset($this->items[$itemKey]->rank)) { return -1; } - return $this->params[$itemKey]->rank; + return $this->items[$itemKey]->rank; } diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 527ea8eb32d..417c28f30a2 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -265,7 +265,7 @@ if ($action == 'edit') { print ''; print '
    '; } else { - if (!empty($formSetup->params)) { + if (!empty($formSetup->items)) { print $formSetup->generateOutput(); $setupnotempty++; From 12b046cb68a41ace480a519d366f3243b03144d6 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Tue, 2 Nov 2021 14:11:36 +0100 Subject: [PATCH 039/195] Fix class name --- htdocs/core/class/html.formsetup.class.php | 20 +++++++++---------- htdocs/modulebuilder/template/admin/setup.php | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index 8f9d3af0528..6f2ec2acfb6 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -19,7 +19,7 @@ /** * This class help you create setup render */ -class formSetup +class FormSetup { /** @@ -27,7 +27,7 @@ class formSetup */ public $db; - /** @var formSetupItem[] */ + /** @var FormSetupItem[] */ public $items = array(); /** @@ -147,7 +147,7 @@ class formSetup } /** - * @param formSetupItem $item the setup item + * @param FormSetupItem $item the setup item * @param bool $editMode Display as edit mod * @return string the html output for an setup item */ @@ -223,7 +223,7 @@ class formSetup //'MYMODULE_MYPARAM7'=>array('type'=>'product', 'enabled'=>1), */ - $item = new formSetupItem($confKey); + $item = new FormSetupItem($confKey); $item->setTypeFromTypeString($params['type']); if (!empty($params['enabled'])) { @@ -280,11 +280,11 @@ class formSetup * @param $confKey the conf key used in database * @param string $targetItemKey target item used to place the new item beside * @param bool $insertAfterTarget insert before or after target item ? - * @return formSetupItem the new setup item created + * @return FormSetupItem the new setup item created */ public function newItem($confKey, $targetItemKey = false, $insertAfterTarget = false) { - $item = new formSetupItem($confKey); + $item = new FormSetupItem($confKey); // set item rank if not defined as last item if (empty($item->rank)) { @@ -377,11 +377,11 @@ class formSetup /** * uasort callback function to Sort params items * - * @param formSetupItem $a formSetup item - * @param formSetupItem $b formSetup item + * @param FormSetupItem $a formSetup item + * @param FormSetupItem $b formSetup item * @return int Return compare result */ - public function itemSort(formSetupItem $a, formSetupItem $b) + public function itemSort(FormSetupItem $a, FormSetupItem $b) { if (empty($a->rank)) { $a->rank = 0; @@ -399,7 +399,7 @@ class formSetup /** * This class help to create item for class formSetup */ -class formSetupItem +class FormSetupItem { /** * @var DoliDB Database handler. diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 417c28f30a2..206cca0ff52 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -79,7 +79,7 @@ $type = 'myobject'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php'; -$formSetup = new formSetup($db); +$formSetup = new FormSetup($db); // Hôte From 3fb0e3c5ad4789209478f43ff65716edc358c93c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 3 Nov 2021 22:56:15 +0100 Subject: [PATCH 040/195] NEW add html.formldap.class.php --- htdocs/adherents/ldap.php | 4 +- htdocs/adherents/type_ldap.php | 4 +- htdocs/admin/ldap.php | 67 ++---- htdocs/admin/ldap_groups.php | 4 +- htdocs/admin/ldap_members_types.php | 2 +- htdocs/admin/ldap_users.php | 4 +- htdocs/contact/ldap.php | 4 +- htdocs/core/class/conf.class.php | 21 +- htdocs/core/class/html.formldap.class.php | 196 ++++++++++++++++++ htdocs/core/class/ldap.class.php | 19 +- htdocs/core/login/functions_ldap.php | 2 +- ...interface_50_modLdap_Ldapsynchro.class.php | 44 ++-- htdocs/langs/en_US/ldap.lang | 4 +- htdocs/user/card.php | 2 +- htdocs/user/group/ldap.php | 4 +- htdocs/user/ldap.php | 4 +- 16 files changed, 293 insertions(+), 92 deletions(-) create mode 100644 htdocs/core/class/html.formldap.class.php diff --git a/htdocs/adherents/ldap.php b/htdocs/adherents/ldap.php index 4b64290f107..70624983815 100644 --- a/htdocs/adherents/ldap.php +++ b/htdocs/adherents/ldap.php @@ -158,13 +158,13 @@ print dol_get_fiche_end(); */ print '
    '; -if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && $conf->global->LDAP_MEMBER_ACTIVE != 'ldap2dolibarr') { +if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && $conf->global->LDAP_MEMBER_ACTIVE != Ldap::SYNCHRO_LDAP_TO_DOLIBARR) { print ''; } print "
    \n"; -if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && $conf->global->LDAP_MEMBER_ACTIVE != 'ldap2dolibarr') { +if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && $conf->global->LDAP_MEMBER_ACTIVE != Ldap::SYNCHRO_LDAP_TO_DOLIBARR) { print "
    \n"; } diff --git a/htdocs/adherents/type_ldap.php b/htdocs/adherents/type_ldap.php index 43902a5e1bf..d7650a8de2b 100644 --- a/htdocs/adherents/type_ldap.php +++ b/htdocs/adherents/type_ldap.php @@ -124,13 +124,13 @@ print dol_get_fiche_end(); print '
    '; -if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) { +if (getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { print ''.$langs->trans("ForceSynchronize").''; } print "
    \n"; -if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) { +if (getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { print "
    \n"; } diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index 167c48d84c0..99c86f783fc 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -100,7 +100,7 @@ if (empty($reshook)) { if (!dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_ACTIVE', GETPOST("activememberstypes", 'aZ09'), 'chaine', 0, '', $conf->entity)) { $error++; } - if (!dolibarr_set_const($db, 'LDAP_PASSWORD_HASH_TYPE', GETPOST("'LDAP_PASSWORD_HASH_TYPE'", 'aZ09'), 'chaine', 0, '', $conf->entity)) { + if (!dolibarr_set_const($db, 'LDAP_PASSWORD_HASH_TYPE', GETPOST("LDAP_PASSWORD_HASH_TYPE", 'aZ09'), 'chaine', 0, '', $conf->entity)) { $error++; } @@ -150,13 +150,9 @@ print "\n"; // Synchro utilisateurs/groupes active print ''.$langs->trans("LDAPDnSynchroActive").''; -$arraylist = array(); -$arraylist['0'] = $langs->trans("No"); -$arraylist['ldap2dolibarr'] = $langs->trans("LDAPToDolibarr"); -$arraylist['dolibarr2ldap'] = $langs->trans("DolibarrToLDAP"); -print $form->selectarray('activesynchro', $arraylist, $conf->global->LDAP_SYNCHRO_ACTIVE); +print $formldap->selectLdapDnSynchroActive(getDolGlobalInt('LDAP_SYNCHRO_ACTIVE'), 'activesynchro'); print ''.$langs->trans("LDAPDnSynchroActiveExample").''; -if ($conf->global->LDAP_SYNCHRO_ACTIVE && !$conf->global->LDAP_USER_DN) { +if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && empty($conf->global->LDAP_USER_DN)) { print '
    '.$langs->trans("LDAPSetupNotComplete").''; } print ''; @@ -164,32 +160,21 @@ print ''; // Synchro contact active if (!empty($conf->societe->enabled)) { print ''.$langs->trans("LDAPDnContactActive").''; - $arraylist = array(); - $arraylist['0'] = $langs->trans("No"); - $arraylist['1'] = $langs->trans("DolibarrToLDAP"); - print $form->selectarray('activecontact', $arraylist, $conf->global->LDAP_CONTACT_ACTIVE); + print $formldap->selectLdapDnSynchroActive(getDolGlobalInt('LDAP_CONTACT_ACTIVE'), 'activecontact', array(Ldap::SYNCHRO_LDAP_TO_DOLIBARR)); print ''.$langs->trans("LDAPDnContactActiveExample").''; } // Synchro member active if (!empty($conf->adherent->enabled)) { print ''.$langs->trans("LDAPDnMemberActive").''; - $arraylist = array(); - $arraylist['0'] = $langs->trans("No"); - $arraylist['1'] = $langs->trans("DolibarrToLDAP"); - $arraylist['ldap2dolibarr'] = $langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; - print $form->selectarray('activemembers', $arraylist, $conf->global->LDAP_MEMBER_ACTIVE); + print $formldap->selectLdapDnSynchroActive(getDolGlobalInt('LDAP_MEMBER_ACTIVE'), 'activemembers', array(), 2); print ''.$langs->trans("LDAPDnMemberActiveExample").''; } // Synchro member type active if (!empty($conf->adherent->enabled)) { print ''.$langs->trans("LDAPDnMemberTypeActive").''; - $arraylist = array(); - $arraylist['0'] = $langs->trans("No"); - $arraylist['1'] = $langs->trans("DolibarrToLDAP"); - $arraylist['ldap2dolibarr'] = $langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; - print $form->selectarray('activememberstypes', $arraylist, $conf->global->LDAP_MEMBER_TYPE_ACTIVE); + print $formldap->selectLdapDnSynchroActive(getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE'), 'activememberstypes', array(), 2); print ''.$langs->trans("LDAPDnMemberTypeActiveExample").''; } @@ -206,53 +191,39 @@ print "\n"; // Type print ''.$langs->trans("Type").''; -$arraylist = array(); -$arraylist['activedirectory'] = 'Active Directory'; -$arraylist['openldap'] = 'OpenLdap'; -$arraylist['egroupware'] = 'Egroupware'; -print $form->selectarray('type', $arraylist, $conf->global->LDAP_SERVER_TYPE); +print $formldap->selectLdapServerType(getDolGlobalString('LDAP_SERVER_TYPE'), 'type'); print ' '; // Version print ''.$langs->trans("Version").''; -$arraylist = array(); -$arraylist['3'] = 'Version 3'; -$arraylist['2'] = 'Version 2'; -print $form->selectarray('LDAP_SERVER_PROTOCOLVERSION', $arraylist, $conf->global->LDAP_SERVER_PROTOCOLVERSION); +print $formldap->selectLdapServerProtocolVersion(getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION'), 'LDAP_SERVER_PROTOCOLVERSION'); print ''.$langs->trans("LDAPServerProtocolVersion").''; // Serveur primaire print ''; print $langs->trans("LDAPPrimaryServer").''; -print ''; +print ''; print ''.$langs->trans("LDAPServerExample").''; // Serveur secondaire print ''; print $langs->trans("LDAPSecondaryServer").''; -print ''; +print ''; print ''.$langs->trans("LDAPServerExample").''; // Port print ''.$langs->trans("LDAPServerPort").''; -if (!empty($conf->global->LDAP_SERVER_PORT)) { - print ''; -} else { - print ''; -} +print ''; print ''.$langs->trans("LDAPServerPortExample").''; // DNserver print ''.$langs->trans("LDAPServerDn").''; -print ''; +print ''; print ''.$langs->trans("LDAPServerDnExample").''; // Utiliser TLS print ''.$langs->trans("LDAPServerUseTLS").''; -$arraylist = array(); -$arraylist['0'] = $langs->trans("No"); -$arraylist['1'] = $langs->trans("Yes"); -print $form->selectarray('usetls', $arraylist, $conf->global->LDAP_SERVER_USE_TLS); +print $form->selectyesno('usetls', getDolGlobalInt('LDAP_SERVER_USE_TLS'), 1); print ''.$langs->trans("LDAPServerUseTLSExample").''; // Password hash type @@ -267,7 +238,7 @@ print "\n"; // DNAdmin print ''; print ''.$langs->trans("LDAPAdminDn").''; -print ''; +print ''; print ''.$langs->trans("LDAPAdminDnExample").''; // Pass @@ -276,7 +247,7 @@ print ''.$langs->trans("LDAPPassword").''; if (!empty($conf->global->LDAP_ADMIN_PASS)) { print ''; // je le met en visible pour test } else { - print ''; + print ''; } print ''.$langs->trans('Password').' (ex: secret)'; @@ -306,17 +277,17 @@ if (function_exists("ldap_connect")) { if ($result > 0) { // Test ldap connect and bind print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPTCPConnectOK", $ldap->connectedServer, $conf->global->LDAP_SERVER_PORT).''; + print ''.$langs->trans("LDAPTCPConnectOK", $ldap->connectedServer, getDolGlobalString('LDAP_SERVER_PORT')).''; print '
    '; if (!empty($conf->global->LDAP_ADMIN_DN) && !empty($conf->global->LDAP_ADMIN_PASS)) { if ($result == 2) { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPBindOK", $ldap->connectedServer, $conf->global->LDAP_SERVER_PORT, $conf->global->LDAP_ADMIN_DN, preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)).''; + print ''.$langs->trans("LDAPBindOK", $ldap->connectedServer, getDolGlobalString('LDAP_SERVER_PORT'), $conf->global->LDAP_ADMIN_DN, preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)).''; print '
    '; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPBindKO", $ldap->connectedServer, $conf->global->LDAP_SERVER_PORT, $conf->global->LDAP_ADMIN_DN, preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)).''; + print ''.$langs->trans("LDAPBindKO", $ldap->connectedServer, getDolGlobalString('LDAP_SERVER_PORT'), $conf->global->LDAP_ADMIN_DN, preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)).''; print '
    '; print $langs->trans("Error").' '.$ldap->error; print '
    '; @@ -342,7 +313,7 @@ if (function_exists("ldap_connect")) { $ldap->unbind(); } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPTCPConnectKO", $ldap->connectedServer, $conf->global->LDAP_SERVER_PORT).''; + print ''.$langs->trans("LDAPTCPConnectKO", $ldap->connectedServer, getDolGlobalString('LDAP_SERVER_PORT')).''; print '
    '; print $langs->trans("Error").' '.$ldap->error; print '
    '; diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 82ee85b9a20..5723183735e 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -218,7 +218,7 @@ print ''; /* * Test de la connexion */ -if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { +if (getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $butlabel = $langs->trans("LDAPTestSynchroGroup"); $testlabel = 'testgroup'; $key = $conf->global->LDAP_KEY_GROUPS; @@ -226,7 +226,7 @@ if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { $objectclass = $conf->global->LDAP_GROUP_OBJECT_CLASS; show_ldap_test_button($butlabel, $testlabel, $key, $dn, $objectclass); -} elseif ($conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') { +} elseif (getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR) { $butlabel = $langs->trans("LDAPTestSearch"); $testlabel = 'testsearchgroup'; $key = $conf->global->LDAP_KEY_GROUPS; diff --git a/htdocs/admin/ldap_members_types.php b/htdocs/admin/ldap_members_types.php index 05572dc8bbf..7933b59d5e0 100644 --- a/htdocs/admin/ldap_members_types.php +++ b/htdocs/admin/ldap_members_types.php @@ -188,7 +188,7 @@ print ''; /* * Test de la connexion */ -if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { +if (getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $butlabel = $langs->trans("LDAPTestSynchroMemberType"); $testlabel = 'testmembertype'; $key = $conf->global->LDAP_KEY_MEMBERS_TYPES; diff --git a/htdocs/admin/ldap_users.php b/htdocs/admin/ldap_users.php index 33bec1cb2e8..f395eb88fb4 100644 --- a/htdocs/admin/ldap_users.php +++ b/htdocs/admin/ldap_users.php @@ -405,7 +405,7 @@ print ''; /* * Test de la connexion */ -if (getDolGlobalString('LDAP_SYNCHRO_ACTIVE') == 'dolibarr2ldap') { +if (getDolGlobalString('LDAP_SYNCHRO_ACTIVE') == Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $butlabel = $langs->trans("LDAPTestSynchroUser"); $testlabel = 'testuser'; $key = getDolGlobalString('LDAP_KEY_USERS'); @@ -413,7 +413,7 @@ if (getDolGlobalString('LDAP_SYNCHRO_ACTIVE') == 'dolibarr2ldap') { $objectclass = getDolGlobalString('LDAP_USER_OBJECT_CLASS'); show_ldap_test_button($butlabel, $testlabel, $key, $dn, $objectclass); -} elseif (getDolGlobalString('LDAP_SYNCHRO_ACTIVE') == 'ldap2dolibarr') { +} elseif (getDolGlobalString('LDAP_SYNCHRO_ACTIVE') == Ldap::SYNCHRO_LDAP_TO_DOLIBARR) { $butlabel = $langs->trans("LDAPTestSearch"); $testlabel = 'testsearchuser'; $key = getDolGlobalString('LDAP_KEY_USERS'); diff --git a/htdocs/contact/ldap.php b/htdocs/contact/ldap.php index d29aab0386b..92b9c1ad337 100644 --- a/htdocs/contact/ldap.php +++ b/htdocs/contact/ldap.php @@ -136,13 +136,13 @@ print dol_get_fiche_end(); */ print '
    '; -if (!empty($conf->global->LDAP_CONTACT_ACTIVE) && $conf->global->LDAP_CONTACT_ACTIVE != 'ldap2dolibarr') { +if (!empty($conf->global->LDAP_CONTACT_ACTIVE) && $conf->global->LDAP_CONTACT_ACTIVE != Ldap::SYNCHRO_LDAP_TO_DOLIBARR) { print ''.$langs->trans("ForceSynchronize").''; } print "
    \n"; -if (!empty($conf->global->LDAP_CONTACT_ACTIVE) && $conf->global->LDAP_CONTACT_ACTIVE != 'ldap2dolibarr') { +if (!empty($conf->global->LDAP_CONTACT_ACTIVE) && $conf->global->LDAP_CONTACT_ACTIVE != Ldap::SYNCHRO_LDAP_TO_DOLIBARR) { print "
    \n"; } diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 044dc192426..cf54151d2d6 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -775,8 +775,8 @@ class Conf $this->contrat->services->expires->warning_delay = (isset($this->global->MAIN_DELAY_RUNNING_SERVICES) ? $this->global->MAIN_DELAY_RUNNING_SERVICES : 0) * 86400; } if (isset($this->commande)) { - $this->bank->rappro = new stdClass(); - $this->bank->cheque = new stdClass(); + $this->bank->rappro = new stdClass(); + $this->bank->cheque = new stdClass(); $this->bank->rappro->warning_delay = (isset($this->global->MAIN_DELAY_TRANSACTIONS_TO_CONCILIATE) ? $this->global->MAIN_DELAY_TRANSACTIONS_TO_CONCILIATE : 0) * 86400; $this->bank->cheque->warning_delay = (isset($this->global->MAIN_DELAY_CHEQUES_TO_DEPOSIT) ? $this->global->MAIN_DELAY_CHEQUES_TO_DEPOSIT : 0) * 86400; } @@ -845,6 +845,23 @@ class Conf } } + // For backward compatibility + if (!empty($this->global->LDAP_SYNCHRO_ACTIVE)) { + if ($this->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { + $this->global->LDAP_SYNCHRO_ACTIVE = 1; + } else if ($this->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') { + $this->global->LDAP_SYNCHRO_ACTIVE = 2; + } + } + // For backward compatibility + if (!empty($this->global->LDAP_MEMBER_ACTIVE) && $this->global->LDAP_MEMBER_ACTIVE == 'ldap2dolibarr') { + $this->global->LDAP_MEMBER_ACTIVE = 2; + } + // For backward compatibility + if (!empty($this->global->LDAP_MEMBER_TYPE_ACTIVE) && $this->global->LDAP_MEMBER_TYPE_ACTIVE == 'ldap2dolibarr') { + $this->global->LDAP_MEMBER_TYPE_ACTIVE = 2; + } + if (!empty($this->global->MAIN_TZUSERINPUTKEY)) { $this->tzuserinputkey = $this->global->MAIN_TZUSERINPUTKEY; // 'tzserver' or 'tzuserrel' } diff --git a/htdocs/core/class/html.formldap.class.php b/htdocs/core/class/html.formldap.class.php new file mode 100644 index 00000000000..acee0bbbea7 --- /dev/null +++ b/htdocs/core/class/html.formldap.class.php @@ -0,0 +1,196 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/html.formldap.class.php + * \ingroup core + * \brief File of class with ldap html predefined components + */ +require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + +/** + * Class to manage generation of HTML components for ldap module + */ +class FormLdap +{ + /** + * @var DoliDB Database handler. + */ + public $db; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string[] Array of error strings + */ + public $errors = array(); + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $langs, $form; + + if (!is_object($form)) { + $form = new Form($this->db); + } + + $langs->loadLangs(array("admin", "ldap")); + + $this->db = $db; + } + + /** + * Return list of types of hash + * + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param int $showempty Add an empty field + * @return string HTML select string + */ + public function selectLdapPasswordHashType($selected = 'md5', $htmlname = 'ldaphashtype', $showempty = 0) + { + global $form; + + if (empty($selected)) { + $selected = 'md5'; + } + if (empty($htmlname)) { + $htmlname = 'ldaphashtype'; + } + + $arraylist = array( + "pbkdf2sha256" => "PBKDF2_SHA256", + "ssha512" => "SSHA512", + "ssha256" => "SSHA256", + "ssha" => "SSHA", + "sha" => "SHA", + "md5" => "MD5", + "smd5" => "SMD5", + "cryptmd5" => "CRYPT-MD5", + "cryptsha512" => "CRYPT-SHA512", + "cryptsha256" => "CRYPT-SHA256", + "crypt" => "CRYPT", + "clear" => "CLEAR" + ); + + return $form->selectarray($htmlname, $arraylist, $selected, $showempty); + } + + /** + * Return list of type of synchronization + * + * @param int $selected Preselected type + * @param string $htmlname Name of field in form + * @param array $exclude Exclude values from the list + * @param int $scriptonly Add warning if synchro only work with a script (0 = disable, 1 = Dolibarr2ldap, 2 = ldap2dolibarr, 3 = all) + * @param int $showempty Add an empty field + * @return string HTML select string + */ + public function selectLdapDnSynchroActive($selected = 0, $htmlname = 'activesynchro', $exclude = array(), $scriptonly = 0, $showempty = 0) + { + global $langs, $form; + + if (empty($selected)) { + $selected = Ldap::SYNCHRO_NONE; + } + if (empty($htmlname)) { + $htmlname = 'activesynchro'; + } + + $dolibarr2ldaplabel = $langs->trans("DolibarrToLDAP") . (($scriptonly == 1 || $scriptonly == 3) ? " (".$langs->trans("SupportedForLDAPExportScriptOnly").")" : ""); + $ldap2dolibarrlabel = $langs->trans("LDAPToDolibarr") . (($scriptonly == 2 || $scriptonly == 3) ? " (".$langs->trans("SupportedForLDAPImportScriptOnly").")" : ""); + + $arraylist = array( + Ldap::SYNCHRO_NONE => $langs->trans("No"), + Ldap::SYNCHRO_DOLIBARR_TO_LDAP => $dolibarr2ldaplabel, + Ldap::SYNCHRO_LDAP_TO_DOLIBARR => $ldap2dolibarrlabel + ); + + if (is_array($exclude) && !empty($exclude)) { + foreach($exclude as $value) { + if (array_key_exists($value, $arraylist)) { + unset($arraylist[$value]); + } + } + } + + return $form->selectarray($htmlname, $arraylist, $selected, $showempty); + } + + /** + * Return list of ldap server types + * + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param int $showempty Add an empty field + * @return string HTML select string + */ + public function selectLdapServerType($selected = 'openldap', $htmlname = 'type', $showempty = 0) + { + global $form; + + if (empty($selected)) { + $selected = 'openldap'; + } + if (empty($htmlname)) { + $htmlname = 'type'; + } + + $arraylist = array( + 'activedirectory' => 'Active Directory', + 'openldap' => 'OpenLdap', + 'egroupware' => 'Egroupware' + ); + + return $form->selectarray($htmlname, $arraylist, $selected, $showempty); + } + + /** + * Return list of ldap server protocol version + * + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param int $showempty Add an empty field + * @return string HTML select string + */ + public function selectLdapServerProtocolVersion($selected = '3', $htmlname = 'ldapprotocolversion', $showempty = 0) + { + global $form; + + if (empty($selected)) { + $selected = '3'; + } + if (empty($htmlname)) { + $htmlname = 'ldapprotocolversion'; + } + + $arraylist = array( + '3' => 'Version 3', + '2' => 'Version 2' + ); + + return $form->selectarray($htmlname, $arraylist, $selected, $showempty); + } +} diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index a1921ea2217..bd0ccbee5ac 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -122,6 +122,21 @@ class Ldap */ public $result; + /** + * No Ldap synchronization + */ + const SYNCHRO_NONE = 0; + + /** + * Dolibarr to Ldap synchronization + */ + const SYNCHRO_DOLIBARR_TO_LDAP = 1; + + /** + * Ldap to Dolibarr synchronization + */ + const SYNCHRO_LDAP_TO_DOLIBARR = 2; + /** * Constructor @@ -230,7 +245,7 @@ class Ldap dol_syslog(get_class($this)."::connect_bind failed to start tls", LOG_WARNING); $this->error = 'ldap_start_tls Failed to start TLS '.ldap_errno($this->connection).' '.ldap_error($this->connection); $connected = 0; - $this->close(); + $this->unbind(); } } @@ -279,7 +294,7 @@ class Ldap } if (!$connected) { - $this->close(); + $this->unbind(); } } } diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php index 2d55ca2815b..5ae3af3f008 100644 --- a/htdocs/core/login/functions_ldap.php +++ b/htdocs/core/login/functions_ldap.php @@ -181,7 +181,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) } // ldap2dolibarr synchronisation - if ($login && !empty($conf->ldap->enabled) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') { // ldap2dolibarr synchronisation + if ($login && !empty($conf->ldap->enabled) && $conf->global->LDAP_SYNCHRO_ACTIVE == Ldap::SYNCHRO_LDAP_TO_DOLIBARR) { // ldap2dolibarr synchronization dol_syslog("functions_ldap::check_user_password_ldap Sync ldap2dolibarr"); // On charge les attributs du user ldap diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php index d4db5ebccfc..24df646efd6 100644 --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php @@ -81,7 +81,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers // Users if ($action == 'USER_CREATE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -98,7 +98,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'USER_MODIFY') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -177,7 +177,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'USER_NEW_PASSWORD') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -212,7 +212,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); } elseif ($action == 'USER_DELETE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -229,7 +229,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } /*} elseif ($action == 'USER_SETINGROUP') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -263,7 +263,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'USER_REMOVEFROMGROUP') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -298,7 +298,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } elseif ($action == 'USERGROUP_CREATE') { // Groupes dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -320,7 +320,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'USERGROUP_MODIFY') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -353,7 +353,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'USERGROUP_DELETE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { + if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -439,7 +439,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } elseif ($action == 'MEMBER_CREATE') { // Members dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && $conf->global->LDAP_MEMBER_ACTIVE == Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -450,7 +450,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers $result = $ldap->add($dn, $info, $user); // For member type - if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { if ($object->typeid > 0) { require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"; $membertype = new AdherentType($this->db); @@ -482,7 +482,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'MEMBER_VALIDATE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { // If status field is setup to be synchronized if (!empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) { $ldap = new Ldap(); @@ -503,7 +503,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'MEMBER_SUBSCRIPTION') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { // If subscriptions fields are setup to be synchronized if ($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE || $conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT @@ -528,7 +528,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'MEMBER_MODIFY') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -557,7 +557,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers $result = $ldap->update($dn, $info, $user, $olddn, $newrdn, $newparent); // For member type - if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"; /* @@ -616,7 +616,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'MEMBER_NEW_PASSWORD') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { // If password field is setup to be synchronized if ($conf->global->LDAP_FIELD_PASSWORD || $conf->global->LDAP_FIELD_PASSWORD_CRYPTED) { $ldap = new Ldap(); @@ -637,7 +637,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'MEMBER_RESILIATE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { // If status field is setup to be synchronized if (!empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) { $ldap = new Ldap(); @@ -658,7 +658,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'MEMBER_DELETE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -669,7 +669,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers $result = $ldap->delete($dn); // For member type - if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { if ($object->typeid > 0) { require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"; @@ -706,7 +706,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } elseif ($action == 'MEMBER_TYPE_CREATE') { // Members types dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -728,7 +728,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'MEMBER_TYPE_MODIFY') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); @@ -765,7 +765,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers } } elseif ($action == 'MEMBER_TYPE_DELETE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') { + if (!empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { $ldap = new Ldap(); $result = $ldap->connect_bind(); diff --git a/htdocs/langs/en_US/ldap.lang b/htdocs/langs/en_US/ldap.lang index b13e454159d..19dd29e0a51 100644 --- a/htdocs/langs/en_US/ldap.lang +++ b/htdocs/langs/en_US/ldap.lang @@ -26,4 +26,6 @@ ForceSynchronize=Force synchronizing Dolibarr -> LDAP ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility. PasswordOfUserInLDAP=Password of user in LDAP LDAPPasswordHashType=Password hash type -LDAPPasswordHashTypeExample=Type of password hash used on the server \ No newline at end of file +LDAPPasswordHashTypeExample=Type of password hash used on the server +SupportedForLDAPExportScriptOnly=Only supported by an ldap export script +SupportedForLDAPImportScriptOnly=Only supported by an ldap import script \ No newline at end of file diff --git a/htdocs/user/card.php b/htdocs/user/card.php index e3a72384050..da4cbf5fac0 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -731,7 +731,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "
    "; - if (!empty($conf->ldap->enabled) && (isset($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr')) { + if (!empty($conf->ldap->enabled) && (isset($conf->global->LDAP_SYNCHRO_ACTIVE) && getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_LDAP_TO_DOLIBARR)) { // Show form to add an account from LDAP if sync LDAP -> Dolibarr is set $ldap = new Ldap(); $result = $ldap->connect_bind(); diff --git a/htdocs/user/group/ldap.php b/htdocs/user/group/ldap.php index d8d1995a847..e3a01f27731 100644 --- a/htdocs/user/group/ldap.php +++ b/htdocs/user/group/ldap.php @@ -147,13 +147,13 @@ print dol_get_fiche_end(); */ print '
    '; -if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { +if (getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { print ''.$langs->trans("ForceSynchronize").''; } print "
    \n"; -if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { +if (getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { print "
    \n"; } diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php index 8e12bf1b461..66199e9b3f6 100644 --- a/htdocs/user/ldap.php +++ b/htdocs/user/ldap.php @@ -153,13 +153,13 @@ print dol_get_fiche_end(); */ print '
    '; -if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { +if (getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { print ''.$langs->trans("ForceSynchronize").''; } print "
    \n"; -if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { +if (getDolGlobalInt('LDAP_SYNCHRO_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDAP) { print "
    \n"; } From b34fb95f4f8163ebc7287587803502054f4fba8f Mon Sep 17 00:00:00 2001 From: Gerhard Stephan Date: Mon, 8 Nov 2021 10:59:04 +0100 Subject: [PATCH 041/195] Load product data optional fields to the line -> enables to use "line_options_{extrafield}" --- htdocs/core/class/commondocgenerator.class.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index a92179e7b6a..e5a2ef4c9db 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -559,6 +559,15 @@ abstract class CommonDocGenerator $resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs); } + // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" + if (isset($line->fk_product) && $line->fk_product > 0) + { + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($line->fk_product); + foreach($tmpproduct->array_options as $key=>$label) + $resarray["line_".$key] = $label; + } + return $resarray; } From 0a3a0862ffaf4c63396f4d96f765238e9f3e92cf Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 8 Nov 2021 13:33:24 +0100 Subject: [PATCH 042/195] fixes to be pure markdown --- SECURITY.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 427b1cc7ae2..9c28e2874b9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,8 +12,7 @@ This file contains some policies about the security reports on Dolibarr ERP CRM ## Reporting a Vulnerability -To report a vulnerability, please use GitHub security advisory at https://github.com/Dolibarr/dolibarr/security/advisories/new (if you have permissions) or alternatively send an email to security@dolibarr.org (for everybody) - +To report a vulnerability, please use GitHub security advisory at [https://github.com/Dolibarr/dolibarr/security/advisories/new](https://github.com/Dolibarr/dolibarr/security/advisories/new) (if you have permissions) or alternatively send an email to security@dolibarr.org (for everybody) ## Hunting vulnerabilities on Dolibarr @@ -23,7 +22,7 @@ If you believe you've found a security bug in our service, we are happy to work Any type of denial of service attacks is strictly forbidden, as well as any interference with network equipment and Dolibarr infrastructure. -We recommand to install Dolibarr ERP CRM on your own server (as most Open Source software, download and use is free: https://www.dolibarr.org/download) to get access on every side of application. +We recommand to install Dolibarr ERP CRM on your own server (as most Open Source software, download and use is free: [https://www.dolibarr.org/download](https://www.dolibarr.org/download)) to get access on every side of application. ### User Agent @@ -31,8 +30,7 @@ If you try to find bug on Dolibarr, we recommend to append to your user-agent he ### Account access -You can install the web application yourself on your own platform/server so you get full access to application and sources. Download the zip of the files to put into your own web server virtual host from https://www.dolibarr.org/download - +You can install the web application yourself on your own platform/server so you get full access to application and sources. Download the zip of the files to put into your own web server virtual host from [https://www.dolibarr.org/download](https://www.dolibarr.org/download) ## Eligibility and Responsible Disclosure @@ -46,7 +44,6 @@ You must avoid tests that could cause degradation or interruption of our service You must not leak, manipulate, or destroy any user data of third parties to find your vulnerability. - ## Scope for qualified vulnerabilities ONLY vulnerabilities discovered, when the following setup on test platform is used, are "valid": @@ -64,7 +61,6 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us Scope is the web application (back office) and the APIs. - ## Qualifying vulnerabilities for reporting * Remote code execution (RCE) @@ -81,7 +77,6 @@ Scope is the web application (back office) and the APIs. * Software version disclosure (for non admin users only) * Stack traces or path disclosure (for non admin users only) - ## Non-qualifying vulnerabilities for reporting * "Self" XSS @@ -99,4 +94,3 @@ Scope is the web application (back office) and the APIs. * Software version or private IP disclosure when logged user is admin * Stack traces or path disclosure when logged user is admin * Any vulnerabilities due to a configuration different than the one defined into chapter "Scope for qualified vulnerabilities". - From d06d6c51cd7ca5802bcac3047386e9011e0fb14a Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 8 Nov 2021 13:44:46 +0100 Subject: [PATCH 043/195] MD041 - First line in a file should be a top-level heading --- htdocs/modulebuilder/template/core/boxes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/core/boxes/README.md b/htdocs/modulebuilder/template/core/boxes/README.md index b641e7136bc..3989bca5847 100644 --- a/htdocs/modulebuilder/template/core/boxes/README.md +++ b/htdocs/modulebuilder/template/core/boxes/README.md @@ -1 +1 @@ -Directory where widgets files are stored. \ No newline at end of file +# Directory where widgets files are stored From 85a3bbba3d9fc491b16ba761ce82afdef42b7af8 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 8 Nov 2021 13:51:03 +0100 Subject: [PATCH 044/195] Translations --- .../mailings/mailinglist_mymodule_myobject.modules.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php index dc797b99a94..b50f4acf741 100644 --- a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php @@ -55,9 +55,9 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets /** - * Affiche formulaire de filtre qui apparait dans page de selection des destinataires de mailings + * Displays the filter form that appears in the mailing recipient selection page * - * @return string Retourne zone select + * @return string Return select zone */ public function formFilter() { @@ -83,7 +83,7 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets /** - * Renvoie url lien vers fiche de la source du destinataire du mailing + * Returns url link to file of the source of the recipient of the mailing * * @param int $id ID * @return string Url lien @@ -115,7 +115,7 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets } $sql .= " ORDER BY email"; - // Stocke destinataires dans target + // Store recipients in target $result = $this->db->query($sql); if ($result) { $num = $this->db->num_rows($result); From c1a2e7b12e1706f02dd9f5df50256cc7f0c1fc2b Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com> Date: Mon, 8 Nov 2021 17:51:19 +0100 Subject: [PATCH 045/195] FIX: project task list: extrafields could not be displayed --- htdocs/projet/tasks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index d61dffeee3c..03816ff91df 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -135,6 +135,7 @@ if ($object->usage_bill_time) { } // Extra fields +$extrafieldsobjectkey = $taskstatic->table_element; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; $arrayfields = dol_sort_array($arrayfields, 'position'); @@ -774,7 +775,6 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) print ''; - $extrafieldsobjectkey = $taskstatic->table_element; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Action column From ebdcff3b49e6bc76c8e519f784864b15fe6465eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Nov 2021 20:07:03 +0100 Subject: [PATCH 046/195] FIX filter for export of accounting documents --- htdocs/compta/accounting-files.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 2c94cea750c..791da74b030 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -610,8 +610,12 @@ if (!empty($date_start) && !empty($date_stop)) { echo dol_print_date($date_start, 'day')." - ".dol_print_date($date_stop, 'day'); - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; foreach ($listofchoices as $choice => $val) { print ''; } From d28edae46009f9ca0f01042946e0fcf905b10263 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Nov 2021 20:11:32 +0100 Subject: [PATCH 047/195] Fix idate must be jdate --- htdocs/compta/accounting-files.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 791da74b030..15096e28b4f 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -348,8 +348,8 @@ if (($action == 'searchfiles' || $action == 'dl')) { $nofile = array(); $nofile['id'] = $objd->id; $nofile['entity'] = $objd->entity; - $nofile['date'] = $db->idate($objd->date); - $nofile['date_due'] = $db->idate($objd->date_due); + $nofile['date'] = $db->jdate($objd->date); + $nofile['date_due'] = $db->jdate($objd->date_due); $nofile['paid'] = $objd->paid; $nofile['amount_ht'] = $objd->total_ht; $nofile['amount_ttc'] = $objd->total_ttc; @@ -368,8 +368,8 @@ if (($action == 'searchfiles' || $action == 'dl')) { foreach ($files as $key => $file) { $file['id'] = $objd->id; $file['entity'] = $objd->entity; - $file['date'] = $db->idate($objd->date); - $file['date_due'] = $db->idate($objd->date_due); + $file['date'] = $db->jdate($objd->date); + $file['date_due'] = $db->jdate($objd->date_due); $file['paid'] = $objd->paid; $file['amount_ht'] = $objd->total_ht; $file['amount_ttc'] = $objd->total_ttc; From 9f8e21bc2cd3f0a2e6edffdd33a53c162a9b9a23 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Nov 2021 20:39:52 +0100 Subject: [PATCH 048/195] Fix filter on dates --- htdocs/compta/accounting-files.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 15096e28b4f..a06dd8dacaf 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -57,12 +57,12 @@ $date_start = GETPOST('date_start', 'alpha'); $date_startDay = GETPOST('date_startday', 'int'); $date_startMonth = GETPOST('date_startmonth', 'int'); $date_startYear = GETPOST('date_startyear', 'int'); -$date_start = ($date_startDay ? dol_mktime(0, 0, 0, $date_startMonth, $date_startDay, $date_startYear, 'tzuserrel') : dol_stringtotime($date_start)); +$date_start = dol_mktime(0, 0, 0, $date_startMonth, $date_startDay, $date_startYear, 'tzuserrel'); $date_stop = GETPOST('date_stop', 'alpha'); $date_stopDay = GETPOST('date_stopday', 'int'); $date_stopMonth = GETPOST('date_stopmonth', 'int'); $date_stopYear = GETPOST('date_stopyear', 'int'); -$date_stop = ($date_stopDay ? dol_mktime(23, 59, 59, $date_stopMonth, $date_stopDay, $date_stopYear, 'tzuserrel') : dol_stringtotime($date_stop)); +$date_stop = dol_mktime(23, 59, 59, $date_stopMonth, $date_stopDay, $date_stopYear, 'tzuserrel'); $action = GETPOST('action', 'aZ09'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context @@ -460,7 +460,7 @@ if ($result && $action == "dl" && !$error) { $log .= ','.$langs->transnoentitiesnoconv("Country"); $log .= ','.$langs->transnoentitiesnoconv("VATIntra"); $log .= ','.$langs->transnoentitiesnoconv("Sens")."\n"; - $zipname = $dirfortmpfile.'/'.dol_print_date($date_start, 'dayrfc')."-".dol_print_date($date_stop, 'dayrfc').'_export.zip'; + $zipname = $dirfortmpfile.'/'.dol_print_date($date_start, 'dayrfc', 'tzuserrel')."-".dol_print_date($date_stop, 'dayrfc', 'tzuserrel').'_export.zip'; dol_delete_file($zipname); @@ -608,7 +608,7 @@ if (!empty($date_start) && !empty($date_stop)) { print '
    '."\n"; print ''; - echo dol_print_date($date_start, 'day')." - ".dol_print_date($date_stop, 'day'); + echo dol_print_date($date_start, 'day', 'tzuserrel')." - ".dol_print_date($date_stop, 'day', 'tzuserrel'); print ''; print ''; @@ -745,19 +745,19 @@ if (!empty($date_start) && !empty($date_stop)) { print ''.$data['paid'].''; // Total ET - print ''.price($data['sens'] ? $data['amount_ht'] : -$data['amount_ht'])."\n"; + print ''.price(price2num($data['sens'] ? $data['amount_ht'] : -$data['amount_ht'], 'MT'))."\n"; // Total IT - print ''.price($data['sens'] ? $data['amount_ttc'] : -$data['amount_ttc'])."\n"; + print ''.price(price2num($data['sens'] ? $data['amount_ttc'] : -$data['amount_ttc'], 'MT'))."\n"; // Total VAT - print ''.price($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'])."\n"; + print ''.price(price2num($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'], 'MT'))."\n"; - print ''.$data['thirdparty_name']."\n"; + print ''.dol_escape_htmltag($data['thirdparty_name'])."\n"; print ''.$data['thirdparty_code']."\n"; print ''.$data['country_code']."\n"; - print ''.$data['vatnum']."\n"; + print ''.dol_escape_htmltag($data['vatnum'])."\n"; if ($data['sens']) { $totalET_credit += $data['amount_ht']; From d611b99d958a0404c9d97e3193cdbc43a609d4f7 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 9 Nov 2021 03:01:48 +0100 Subject: [PATCH 049/195] GNU version 3 --- dev/initdemo/sftpget_and_loaddump.php | 2 +- dev/initdemo/updatedemo.php | 2 +- dev/translation/sanity_check_en_langfiles.php | 2 +- dev/translation/strip_language_file.php | 2 +- htdocs/accountancy/class/lettering.class.php | 2 +- htdocs/admin/expensereport_ik.php | 2 +- htdocs/admin/expensereport_rules.php | 2 +- htdocs/compta/bank/account_statement_document.php | 2 +- htdocs/compta/bank/document.php | 2 +- htdocs/fourn/commande/dispatch.php | 11 +++++------ htdocs/holiday/month_report.php | 2 +- htdocs/install/mysql/data/llx_c_units.sql | 2 +- htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql | 2 +- htdocs/install/mysql/tables/llx_c_exp_tax_range.sql | 2 +- .../mysql/tables/llx_c_ticket_category.key.sql | 2 +- htdocs/install/mysql/tables/llx_c_ticket_category.sql | 2 +- .../mysql/tables/llx_c_ticket_resolution.key.sql | 2 +- .../install/mysql/tables/llx_c_ticket_resolution.sql | 2 +- .../mysql/tables/llx_c_ticket_severity.key.sql | 2 +- htdocs/install/mysql/tables/llx_c_ticket_severity.sql | 2 +- htdocs/install/mysql/tables/llx_c_ticket_type.key.sql | 2 +- htdocs/install/mysql/tables/llx_c_ticket_type.sql | 2 +- htdocs/install/mysql/tables/llx_c_units.key.sql | 2 +- htdocs/install/mysql/tables/llx_c_units.sql | 2 +- htdocs/install/mysql/tables/llx_expensereport_ik.sql | 2 +- .../install/mysql/tables/llx_expensereport_rules.sql | 2 +- .../install/mysql/tables/llx_facturedet_rec.key.sql | 2 +- .../install/mysql/tables/llx_ticket_extrafields.sql | 2 +- htdocs/loan/calcmens.php | 5 ++--- htdocs/public/ticket/create_ticket.php | 2 +- 30 files changed, 35 insertions(+), 37 deletions(-) diff --git a/dev/initdemo/sftpget_and_loaddump.php b/dev/initdemo/sftpget_and_loaddump.php index 7d781fe5b0c..63b5ac65054 100755 --- a/dev/initdemo/sftpget_and_loaddump.php +++ b/dev/initdemo/sftpget_and_loaddump.php @@ -4,7 +4,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/dev/initdemo/updatedemo.php b/dev/initdemo/updatedemo.php index 4dd98451823..4ee2032c7cf 100755 --- a/dev/initdemo/updatedemo.php +++ b/dev/initdemo/updatedemo.php @@ -4,7 +4,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/dev/translation/sanity_check_en_langfiles.php b/dev/translation/sanity_check_en_langfiles.php index 39db0a55764..840f09a0adb 100755 --- a/dev/translation/sanity_check_en_langfiles.php +++ b/dev/translation/sanity_check_en_langfiles.php @@ -6,7 +6,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/dev/translation/strip_language_file.php b/dev/translation/strip_language_file.php index 3467b648457..f0a0397cd6e 100755 --- a/dev/translation/strip_language_file.php +++ b/dev/translation/strip_language_file.php @@ -5,7 +5,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php index 1dd4c4df3e5..f722a716b79 100644 --- a/htdocs/accountancy/class/lettering.class.php +++ b/htdocs/accountancy/class/lettering.class.php @@ -6,7 +6,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/htdocs/admin/expensereport_ik.php b/htdocs/admin/expensereport_ik.php index d32ef64aebc..900754ef4b4 100644 --- a/htdocs/admin/expensereport_ik.php +++ b/htdocs/admin/expensereport_ik.php @@ -5,7 +5,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php index bddaf58475a..77fb8f24f82 100644 --- a/htdocs/admin/expensereport_rules.php +++ b/htdocs/admin/expensereport_rules.php @@ -6,7 +6,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/htdocs/compta/bank/account_statement_document.php b/htdocs/compta/bank/account_statement_document.php index 0a979e01d39..f36d455dc74 100644 --- a/htdocs/compta/bank/account_statement_document.php +++ b/htdocs/compta/bank/account_statement_document.php @@ -8,7 +8,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/htdocs/compta/bank/document.php b/htdocs/compta/bank/document.php index 7dce00005f3..389c8195f37 100644 --- a/htdocs/compta/bank/document.php +++ b/htdocs/compta/bank/document.php @@ -7,7 +7,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 170785c0118..547abd33b4b 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -10,19 +10,18 @@ * Copyright (C) 2018 Frédéric France * Copyright (C) 2019-2020 Christophe Battarel * - * 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 - * the Free Software Foundation; either version 2 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * or see https://www.gnu.org/ */ /** diff --git a/htdocs/holiday/month_report.php b/htdocs/holiday/month_report.php index 1bb58ca98b0..ad9b0295b2d 100644 --- a/htdocs/holiday/month_report.php +++ b/htdocs/holiday/month_report.php @@ -6,7 +6,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/data/llx_c_units.sql b/htdocs/install/mysql/data/llx_c_units.sql index 59692793fe2..475020aabaf 100644 --- a/htdocs/install/mysql/data/llx_c_units.sql +++ b/htdocs/install/mysql/data/llx_c_units.sql @@ -6,7 +6,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql b/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql index 15d89c4747c..90c60d87b97 100644 --- a/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql +++ b/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql @@ -5,7 +5,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql b/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql index e80eeb15d50..0d996df7033 100644 --- a/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql +++ b/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql @@ -5,7 +5,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_category.key.sql b/htdocs/install/mysql/tables/llx_c_ticket_category.key.sql index 3afa9b5be1d..d5917ce1f5d 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_category.key.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_category.key.sql @@ -2,7 +2,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_category.sql b/htdocs/install/mysql/tables/llx_c_ticket_category.sql index 57bd15f2c23..8477b455796 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_category.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_category.sql @@ -3,7 +3,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_resolution.key.sql b/htdocs/install/mysql/tables/llx_c_ticket_resolution.key.sql index ac3690b70bb..472a4f4ca30 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_resolution.key.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_resolution.key.sql @@ -2,7 +2,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_resolution.sql b/htdocs/install/mysql/tables/llx_c_ticket_resolution.sql index 2f6d0d1d3da..d935d9556a4 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_resolution.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_resolution.sql @@ -2,7 +2,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_severity.key.sql b/htdocs/install/mysql/tables/llx_c_ticket_severity.key.sql index a564f0059d2..fbe3e9e7de1 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_severity.key.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_severity.key.sql @@ -2,7 +2,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_severity.sql b/htdocs/install/mysql/tables/llx_c_ticket_severity.sql index b9f565c4395..c87c258faa6 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_severity.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_severity.sql @@ -2,7 +2,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_type.key.sql b/htdocs/install/mysql/tables/llx_c_ticket_type.key.sql index 7a4374e35fa..c912c3da835 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_type.key.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_type.key.sql @@ -2,7 +2,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_type.sql b/htdocs/install/mysql/tables/llx_c_ticket_type.sql index 462d1a71535..3c476ff848b 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_type.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_type.sql @@ -2,7 +2,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_units.key.sql b/htdocs/install/mysql/tables/llx_c_units.key.sql index d3e1d40e50a..93c8b9600d2 100644 --- a/htdocs/install/mysql/tables/llx_c_units.key.sql +++ b/htdocs/install/mysql/tables/llx_c_units.key.sql @@ -4,7 +4,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_c_units.sql b/htdocs/install/mysql/tables/llx_c_units.sql index ef77703ae6e..7b2424a8f54 100644 --- a/htdocs/install/mysql/tables/llx_c_units.sql +++ b/htdocs/install/mysql/tables/llx_c_units.sql @@ -5,7 +5,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_expensereport_ik.sql b/htdocs/install/mysql/tables/llx_expensereport_ik.sql index 839fbac8e9a..d2b1fd80815 100644 --- a/htdocs/install/mysql/tables/llx_expensereport_ik.sql +++ b/htdocs/install/mysql/tables/llx_expensereport_ik.sql @@ -5,7 +5,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_expensereport_rules.sql b/htdocs/install/mysql/tables/llx_expensereport_rules.sql index ae8f9b09496..1892ead3500 100644 --- a/htdocs/install/mysql/tables/llx_expensereport_rules.sql +++ b/htdocs/install/mysql/tables/llx_expensereport_rules.sql @@ -4,7 +4,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_facturedet_rec.key.sql b/htdocs/install/mysql/tables/llx_facturedet_rec.key.sql index 2580c33a7ab..616df5ec148 100644 --- a/htdocs/install/mysql/tables/llx_facturedet_rec.key.sql +++ b/htdocs/install/mysql/tables/llx_facturedet_rec.key.sql @@ -5,7 +5,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/install/mysql/tables/llx_ticket_extrafields.sql b/htdocs/install/mysql/tables/llx_ticket_extrafields.sql index 31f82064461..5131150649a 100644 --- a/htdocs/install/mysql/tables/llx_ticket_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_ticket_extrafields.sql @@ -2,7 +2,7 @@ -- -- 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 --- the Free Software Foundation; either version 2 of the License, or +-- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, diff --git a/htdocs/loan/calcmens.php b/htdocs/loan/calcmens.php index 19763c0a924..cc6debab86c 100644 --- a/htdocs/loan/calcmens.php +++ b/htdocs/loan/calcmens.php @@ -5,7 +5,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program. If not, see . */ /** diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index e621feb6653..00eff71da78 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -4,7 +4,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, From 33e40c12c8e5552f568f8c70f620b53f2dfa168a Mon Sep 17 00:00:00 2001 From: lvessiller Date: Tue, 9 Nov 2021 14:12:28 +0100 Subject: [PATCH 050/195] FIX close cash with some terminals in TakePOS --- htdocs/takepos/index.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 344955a9167..f3b9991061e 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -732,6 +732,7 @@ $( document ).ready(function() { if ($conf->global->TAKEPOS_CONTROL_CASH_OPENING) { $sql = "SELECT rowid, status FROM ".MAIN_DB_PREFIX."pos_cash_fence WHERE"; $sql .= " entity = ".$conf->entity." AND "; + $sql .= " posnumber = ".$_SESSION["takeposterminal"]." AND "; $sql .= " date(date_creation) = CURDATE()"; $resql = $db->query($sql); if ($resql) { @@ -918,6 +919,7 @@ if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter") { $sql = "SELECT rowid, status, entity FROM ".MAIN_DB_PREFIX."pos_cash_fence WHERE"; $sql .= " entity = ".$conf->entity." AND "; +$sql .= " posnumber = ".$_SESSION["takeposterminal"]." AND "; $sql .= " date(date_creation) = CURDATE()"; $resql = $db->query($sql); if ($resql) From 1e20e082fe355d822a98ccc467767ea02171e571 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 9 Nov 2021 18:36:04 +0100 Subject: [PATCH 051/195] FIX lost superadmin grade after edit user card ! --- htdocs/user/card.php | 8 ++++++-- htdocs/user/class/user.class.php | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 8622e293906..cfa89120053 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -450,11 +450,15 @@ if (empty($reshook)) { // Do we update also ->entity ? if (!empty($conf->multicompany->enabled)) { // If multicompany is not enabled, we never update the entity of a user. if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { - $object->entity = 1; // all users are in master entity + if (GETPOST('superadmin', 'int') === 1) { + $object->entity = 0; + } else { + $object->entity = 1; // all users are in master entity + } } else { // A user should not be able to move a user into another entity. Only superadmin should be able to do this. if ($user->entity == 0 && $user->admin) { - if (GETPOST("superadmin")) { + if (GETPOST('superadmin', 'int')) { // We try to set the user as superadmin. $object->entity = 0; } else { diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 9540f082a4c..09bb34ddef3 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1773,7 +1773,9 @@ class User extends CommonObject $sql .= ", salaryextra= ".($this->salaryextra != '' ? "'".$this->db->escape($this->salaryextra)."'" : "null"); } $sql .= ", weeklyhours= ".($this->weeklyhours != '' ? "'".$this->db->escape($this->weeklyhours)."'" : "null"); - $sql .= ", entity = ".((int) $this->entity); + if (!empty($user->admin) && empty($user->entity) && $user->id != $this->id) { + $sql .= ", entity = ".((int) $this->entity); // entity flag can be set/unset only by an another superadmin user + } $sql .= ", default_range = ".($this->default_range > 0 ? $this->default_range : 'null'); $sql .= ", default_c_exp_tax_cat = ".($this->default_c_exp_tax_cat > 0 ? $this->default_c_exp_tax_cat : 'null'); $sql .= ", fk_warehouse = ".($this->fk_warehouse > 0 ? $this->fk_warehouse : "null"); From 5649e865c3e6cefa8e324769d663c1225a1125ef Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 9 Nov 2021 18:38:29 +0100 Subject: [PATCH 052/195] FIX wrong check --- htdocs/user/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index cfa89120053..dec885e11eb 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -450,7 +450,7 @@ if (empty($reshook)) { // Do we update also ->entity ? if (!empty($conf->multicompany->enabled)) { // If multicompany is not enabled, we never update the entity of a user. if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { - if (GETPOST('superadmin', 'int') === 1) { + if (GETPOST('superadmin', 'int')) { $object->entity = 0; } else { $object->entity = 1; // all users are in master entity From cea3d93b91c3eaa829f34ae73aa9ee2d8bed676a Mon Sep 17 00:00:00 2001 From: daraelmin Date: Tue, 9 Nov 2021 20:51:27 +0100 Subject: [PATCH 053/195] Fix wrong sign in test --- htdocs/adherents/subscription.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 05e55206c02..d9ab62336a1 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -943,7 +943,7 @@ if ($rowid > 0) { } if (!$datefrom) { $datefrom = $object->datevalid; - if ($object->datefin > 0 && dol_time_plus_duree($object->datefin, $defaultdelay, $defaultdelayunit) < dol_now()) { + if ($object->datefin > 0 && dol_time_plus_duree($object->datefin, $defaultdelay, $defaultdelayunit) > dol_now()) { $datefrom = dol_time_plus_duree($object->datefin, 1, 'd'); } else { $datefrom = dol_get_first_day(dol_print_date(time(), "%Y")); From e5d40bf464894bb815a7032590f72373fd0afbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 10 Nov 2021 12:06:39 +0100 Subject: [PATCH 054/195] error display --- htdocs/compta/cashcontrol/cashcontrol_card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index c7b74abfc39..4e82aa12686 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -128,7 +128,7 @@ if (GETPOST('cancel', 'alpha')) { if ($action == "reopen") { $result = $object->setStatut($object::STATUS_DRAFT, null, '', 'CASHFENCE_REOPEN'); if ($result < 0) { - dol_print_error($db, $object->error, $object->error); + setEventMessages($object->error, $object->error, 'errors'); } $action = 'view'; From 005254ad3438ce400c6136d88b56eb0b0f626e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 10 Nov 2021 12:21:03 +0100 Subject: [PATCH 055/195] Update cashcontrol_card.php --- htdocs/compta/cashcontrol/cashcontrol_card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index 4e82aa12686..2cb658f135f 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -356,7 +356,7 @@ if ($action == "create" || $action == "start" || $action == 'close') { } elseif ($syear && $smonth && $sday) { $sql .= " AND datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $smonth, $sday, $syear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $smonth, $sday, $syear))."'"; } else { - dol_print_error('', 'Year not defined'); + setEventMessages($langs->trans('Year not defined'), null, 'errors'); } $resql = $db->query($sql); From 06e6479a123c74b11cf732814077e485b8cb184a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 10 Nov 2021 12:24:53 +0100 Subject: [PATCH 056/195] Update cashcontrol_card.php --- htdocs/compta/cashcontrol/cashcontrol_card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index 2cb658f135f..1950cdb5392 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -312,7 +312,7 @@ if ($action == "create" || $action == "start" || $action == 'close') { } elseif ($syear && $smonth && $sday) { $sql .= " AND dateo < '".$db->idate(dol_mktime(0, 0, 0, $smonth, $sday, $syear))."'"; } else { - dol_print_error('', 'Year not defined'); + setEventMessages($langs->trans('YearNotDefined'), null, 'errors'); } $resql = $db->query($sql); @@ -356,7 +356,7 @@ if ($action == "create" || $action == "start" || $action == 'close') { } elseif ($syear && $smonth && $sday) { $sql .= " AND datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $smonth, $sday, $syear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $smonth, $sday, $syear))."'"; } else { - setEventMessages($langs->trans('Year not defined'), null, 'errors'); + setEventMessages($langs->trans('YearNotDefined'), null, 'errors'); } $resql = $db->query($sql); From c9517db43badbc80b514d35625358cad2efe63a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 10 Nov 2021 12:26:28 +0100 Subject: [PATCH 057/195] Update cashdesk.lang --- htdocs/langs/en_US/cashdesk.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index 22d5afed2fc..5792e015040 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -133,3 +133,4 @@ SplitSale=Split sale PrintWithoutDetailsButton=Add "Print without details" button PrintWithoutDetailsLabelDefault=Line label by default on printing without details PrintWithoutDetails=Print without details +YearNotDefined=Year is not defined From 0afaf080ee0bb5f94458427eb2bfe24f66b79c5c Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Wed, 10 Nov 2021 14:53:17 +0100 Subject: [PATCH 058/195] FIX bug if multicompany disabled avoid bad constantes --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 56f7c41994b..fb0bba95ac4 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1926,7 +1926,7 @@ class Form $sql .= " WHERE u.entity IS NOT NULL"; } } else { - if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ug"; $sql .= " ON ug.fk_user = u.rowid"; $sql .= " WHERE ug.entity = ".$conf->entity; From 285bd67d90d60743124bf7f81e6f699b3a0c6b21 Mon Sep 17 00:00:00 2001 From: Gerhard Stephan Date: Wed, 10 Nov 2021 15:16:36 +0100 Subject: [PATCH 059/195] Added -Propal- as a missing class name to the commondocgenerator.class.php --- htdocs/core/class/commondocgenerator.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index e5a2ef4c9db..544a08198f8 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -492,7 +492,7 @@ abstract class CommonDocGenerator $array_key.'_remain_to_pay'=>price2num($object->total_ttc - $already_payed_all, 'MT') ); - if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { + if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Propal', 'Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { $resarray[$array_key.'_total_discount_ht_locale'] = price($object->getTotalDiscount(), 0, $outputlangs); $resarray[$array_key.'_total_discount_ht'] = price2num($object->getTotalDiscount()); } else { @@ -538,7 +538,7 @@ abstract class CommonDocGenerator // Note that this added fields does not match a field into database in Dolibarr (Dolibarr manage discount on lines not as a global property of object) $resarray['object_total_up'] = $totalUp; $resarray['object_total_up_locale'] = price($resarray['object_total_up'], 0, $outputlangs); - if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { + if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Propal', 'Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { $totalDiscount = $object->getTotalDiscount(); } else { $totalDiscount = 0; From 7c5810dee61f7416521e3e157dfc9e5d06824702 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 10 Nov 2021 14:19:14 +0000 Subject: [PATCH 060/195] Fixing style errors. --- htdocs/core/class/commondocgenerator.class.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 544a08198f8..a0f3f311ed4 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -560,14 +560,13 @@ abstract class CommonDocGenerator } // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" - if (isset($line->fk_product) && $line->fk_product > 0) - { + if (isset($line->fk_product) && $line->fk_product > 0) { $tmpproduct = new Product($this->db); $result = $tmpproduct->fetch($line->fk_product); - foreach($tmpproduct->array_options as $key=>$label) + foreach ($tmpproduct->array_options as $key=>$label) $resarray["line_".$key] = $label; } - + return $resarray; } From 6a216e520f202142e93c4f9f21099ef527cd9003 Mon Sep 17 00:00:00 2001 From: Christian Foellmann Date: Thu, 11 Nov 2021 11:06:05 +0100 Subject: [PATCH 061/195] block deletion of items not free to delete (is_deletable) --- htdocs/core/actions_massactions.inc.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 8ccff0eb017..7c24257594f 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1295,7 +1295,14 @@ if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == ' if ($objectclass == 'Facture' && empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED) && $objecttmp->status != Facture::STATUS_DRAFT) { $langs->load("errors"); $nbignored++; - $resaction .= '
    '.$langs->trans('ErrorOnlyDraftStatusCanBeDeletedInMassAction', $objecttmp->ref).'

    '; + $TMsg[] = '
    '.$langs->trans('ErrorOnlyDraftStatusCanBeDeletedInMassAction', $objecttmp->ref).'

    '; + continue; + } + + if ($objecttmp->is_erasable() <= 0) { + $langs->load("errors"); + $nbignored++; + $TMsg[] = '
    '.$langs->trans('ErrorRecordHasChildren').' '.$objecttmp->ref.'

    '; continue; } From 28e14ac336f16610449c3de73c84934d6c97f845 Mon Sep 17 00:00:00 2001 From: Christian Foellmann Date: Thu, 11 Nov 2021 13:28:33 +0100 Subject: [PATCH 062/195] fix permission on supplier_order document upload --- htdocs/supplier_proposal/document.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/supplier_proposal/document.php b/htdocs/supplier_proposal/document.php index a8b85fc25b5..884519a4f9a 100644 --- a/htdocs/supplier_proposal/document.php +++ b/htdocs/supplier_proposal/document.php @@ -75,7 +75,7 @@ if ($object->id > 0) { $upload_dir = $conf->supplier_proposal->dir_output.'/'.dol_sanitizeFileName($object->ref); } - +$permissiontoadd = $user->rights->supplier_proposal->creer; /* * Actions From bbd97c6e16a42d3e57c4df7c7680d95236a90df6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 13:36:04 +0100 Subject: [PATCH 063/195] Code comment --- htdocs/core/db/DoliDB.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 1aecd205da3..1ebea289470 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -233,7 +233,7 @@ abstract class DoliDB implements Database * Define sort criteria of request * * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb' - * @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC'; + * @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC'. Note: If the quantity fo sortorder values is lower than sortfield, we used the last value for missing values. * @return string String to provide syntax of a sort sql string */ public function order($sortfield = null, $sortorder = null) From fd3fd9d945f51a14146df69be9e60baf2f755946 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 13:46:58 +0100 Subject: [PATCH 064/195] Fix getpost --- htdocs/compta/bank/transfer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php index 9665a8a2b1f..f728dc74f4e 100644 --- a/htdocs/compta/bank/transfer.php +++ b/htdocs/compta/bank/transfer.php @@ -61,8 +61,8 @@ if ($action == 'add') { $dateo = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); $label = GETPOST('label', 'alpha'); - $amount = price2num(GETPOST('amount', 'alpha'), 'MT'); - $amountto = price2num(GETPOST('amountto', 'alpha'), 'MT'); + $amount = price2num(GETPOST('amount', 'alpha'), 'MT', 2); + $amountto = price2num(GETPOST('amountto', 'alpha'), 'MT', 2); if (!$label) { $error++; From 0443302c3d5fb814eb6e813c1bafe27393730c08 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 13:49:21 +0100 Subject: [PATCH 065/195] FIX calculation of balance in conciliation page on desc sorting. --- htdocs/compta/bank/bankentries_list.php | 13 ++++++------- htdocs/core/lib/functions.lib.php | 8 +++++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 8628e287bd0..00a61a7ce7e 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -178,7 +178,6 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); - /* * Actions */ @@ -270,13 +269,15 @@ if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', ' if (!$error) { $param = 'action=reconcile&contextpage=banktransactionlist&id='.$id.'&search_account='.$id; - $param .= '&search_conciliated='.urlencode($search_conciliated); if ($page) { $param .= '&page='.urlencode($page); } if ($offset) { $param .= '&offset='.urlencode($offset); } + if ($search_conciliated != '' && $search_conciliated != '-1') { + $param .= '&search_conciliated='.urlencode($search_conciliated); + } if ($search_thirdparty_user) { $param .= '&search_thirdparty='.urlencode($search_thirdparty_user); } @@ -419,7 +420,6 @@ $banklinestatic = new AccountLine($db); $now = dol_now(); - // Must be before button action $param = ''; if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { @@ -757,7 +757,7 @@ if ($resql) { // Confirmation delete if ($action == 'delete') { $text = $langs->trans('ConfirmDeleteTransaction'); - print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&rowid='.GETPOST("rowid"), $langs->trans('DeleteTransaction'), $text, 'confirm_delete', null, '', 1); + print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&rowid='.GETPOST("rowid", 'int'), $langs->trans('DeleteTransaction'), $text, 'confirm_delete', null, '', 1); } // Lines of title fields @@ -1200,7 +1200,7 @@ if ($resql) { $objforbalance = $db->fetch_object($resqlforbalance); if ($objforbalance) { // If sort is desc,desc,desc then total of previous date + amount is the balancebefore of the previous line before the line to show - if ($sortfield == 'b.datev,b.dateo,b.rowid' && $sortorder == 'desc,desc,desc') { + if ($sortfield == 'b.datev,b.dateo,b.rowid' && ($sortorder == 'desc' || $sortorder == 'desc,desc' || $sortorder == 'desc,desc,desc')) { $balancebefore = $objforbalance->previoustotal + ($sign * $objp->amount); } else { // If sort is asc,asc,asc then total of previous date is balance of line before the next line to show @@ -1285,8 +1285,7 @@ if ($resql) { } } - - if ($sortfield == 'b.datev,b.dateo,b.rowid' && $sortorder == 'desc,desc,desc') { + if ($sortfield == 'b.datev,b.dateo,b.rowid' && ($sortorder == 'desc' || $sortorder == 'desc,desc' || $sortorder == 'desc,desc,desc')) { $balance = price2num($balancebefore, 'MT'); // balance = balancebefore of previous line (sort is desc) $balancebefore = price2num($balancebefore - ($sign * $objp->amount), 'MT'); } else { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 81a5413182e..54a44753513 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5378,13 +5378,16 @@ function price2num($amount, $rounding = '', $option = 0) if ($thousand != ',' && $thousand != '.') { $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users } + $amount = str_replace(' ', '', $amount); // To avoid spaces $amount = str_replace($thousand, '', $amount); // Replace of thousand before replace of dec to avoid pb if thousand is . $amount = str_replace($dec, '.', $amount); + + $amount = preg_replace('/[^0-9\-\.]/', '', $amount); // Clean non numeric chars (so it clean some UTF8 spaces for example. } //print ' XX'.$amount.' '.$rounding; - // Now, make a rounding if required + // Now, $amount is a real PHP float number. We make a rounding if required. if ($rounding) { $nbofdectoround = ''; if ($rounding == 'MU') { @@ -5424,9 +5427,12 @@ function price2num($amount, $rounding = '', $option = 0) if ($thousand != ',' && $thousand != '.') { $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users } + $amount = str_replace(' ', '', $amount); // To avoid spaces $amount = str_replace($thousand, '', $amount); // Replace of thousand before replace of dec to avoid pb if thousand is . $amount = str_replace($dec, '.', $amount); + + $amount = preg_replace('/[^0-9\-\.]/', '', $amount); // Clean non numeric chars (so it clean some UTF8 spaces for example. } return $amount; From 28aa17e4fd5d17511f1646021ebf98b397990903 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 13:49:21 +0100 Subject: [PATCH 066/195] FIX calculation of balance in conciliation page on desc sorting. --- htdocs/compta/bank/bankentries_list.php | 13 ++++++------- htdocs/core/lib/functions.lib.php | 8 +++++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 14aeee29d69..84938f24dbc 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -175,7 +175,6 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); - /* * Actions */ @@ -266,13 +265,15 @@ if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', ' if (!$error) { $param = 'action=reconcile&contextpage=banktransactionlist&id='.$id.'&search_account='.$id; - $param .= '&search_conciliated='.urlencode($search_conciliated); if ($page) { $param .= '&page='.urlencode($page); } if ($offset) { $param .= '&offset='.urlencode($offset); } + if ($search_conciliated != '' && $search_conciliated != '-1') { + $param .= '&search_conciliated='.urlencode($search_conciliated); + } if ($search_thirdparty_user) { $param .= '&search_thirdparty='.urlencode($search_thirdparty_user); } @@ -415,7 +416,6 @@ $banklinestatic = new AccountLine($db); $now = dol_now(); - // Must be before button action $param = ''; if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { @@ -748,7 +748,7 @@ if ($resql) { // Confirmation delete if ($action == 'delete') { $text = $langs->trans('ConfirmDeleteTransaction'); - print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&rowid='.GETPOST("rowid"), $langs->trans('DeleteTransaction'), $text, 'confirm_delete', null, '', 1); + print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&rowid='.GETPOST("rowid", 'int'), $langs->trans('DeleteTransaction'), $text, 'confirm_delete', null, '', 1); } // Lines of title fields @@ -1189,7 +1189,7 @@ if ($resql) { $objforbalance = $db->fetch_object($resqlforbalance); if ($objforbalance) { // If sort is desc,desc,desc then total of previous date + amount is the balancebefore of the previous line before the line to show - if ($sortfield == 'b.datev,b.dateo,b.rowid' && $sortorder == 'desc,desc,desc') { + if ($sortfield == 'b.datev,b.dateo,b.rowid' && ($sortorder == 'desc' || $sortorder == 'desc,desc' || $sortorder == 'desc,desc,desc')) { $balancebefore = $objforbalance->previoustotal + ($sign * $objp->amount); } else { // If sort is asc,asc,asc then total of previous date is balance of line before the next line to show @@ -1274,8 +1274,7 @@ if ($resql) { } } - - if ($sortfield == 'b.datev,b.dateo,b.rowid' && $sortorder == 'desc,desc,desc') { + if ($sortfield == 'b.datev,b.dateo,b.rowid' && ($sortorder == 'desc' || $sortorder == 'desc,desc' || $sortorder == 'desc,desc,desc')) { $balance = price2num($balancebefore, 'MT'); // balance = balancebefore of previous line (sort is desc) $balancebefore = price2num($balancebefore - ($sign * $objp->amount), 'MT'); } else { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index eae8546a338..07ff2930f0f 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5329,13 +5329,16 @@ function price2num($amount, $rounding = '', $option = 0) if ($thousand != ',' && $thousand != '.') { $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users } + $amount = str_replace(' ', '', $amount); // To avoid spaces $amount = str_replace($thousand, '', $amount); // Replace of thousand before replace of dec to avoid pb if thousand is . $amount = str_replace($dec, '.', $amount); + + $amount = preg_replace('/[^0-9\-\.]/', '', $amount); // Clean non numeric chars (so it clean some UTF8 spaces for example. } //print ' XX'.$amount.' '.$rounding; - // Now, make a rounding if required + // Now, $amount is a real PHP float number. We make a rounding if required. if ($rounding) { $nbofdectoround = ''; if ($rounding == 'MU') { @@ -5375,9 +5378,12 @@ function price2num($amount, $rounding = '', $option = 0) if ($thousand != ',' && $thousand != '.') { $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users } + $amount = str_replace(' ', '', $amount); // To avoid spaces $amount = str_replace($thousand, '', $amount); // Replace of thousand before replace of dec to avoid pb if thousand is . $amount = str_replace($dec, '.', $amount); + + $amount = preg_replace('/[^0-9\-\.]/', '', $amount); // Clean non numeric chars (so it clean some UTF8 spaces for example. } return $amount; From 9cb094b46638fe37b8028084214a6525650686c5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 14:37:25 +0100 Subject: [PATCH 067/195] Fix error method not defined --- htdocs/core/actions_massactions.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 7c24257594f..80ba0b671eb 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1299,7 +1299,7 @@ if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == ' continue; } - if ($objecttmp->is_erasable() <= 0) { + if (method_exists($objecttmp, 'is_erasable') && $objecttmp->is_erasable() <= 0) { $langs->load("errors"); $nbignored++; $TMsg[] = '
    '.$langs->trans('ErrorRecordHasChildren').' '.$objecttmp->ref.'

    '; From da2f3e7b406fdcfa76be9651b7d54a7ad6c1b51f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 14:55:59 +0100 Subject: [PATCH 068/195] Code comment --- htdocs/core/class/commondocgenerator.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index a92179e7b6a..e5d8db4cb53 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -516,8 +516,9 @@ abstract class CommonDocGenerator // Add vat by rates if (is_array($object->lines) && count($object->lines) > 0) { $totalUp = 0; + // Set substitution keys for different VAT rates foreach ($object->lines as $line) { - // $line->tva_tx format depends on database field accuraty, no reliable. This is kept for backward compatibility + // $line->tva_tx format depends on database field accuracy, no reliable. This is kept for backward compatibility if (empty($resarray[$array_key.'_total_vat_'.$line->tva_tx])) { $resarray[$array_key.'_total_vat_'.$line->tva_tx] = 0; } From c6ecf87a8a8ee583cb99264f70c03d0e9778a189 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 15:02:51 +0100 Subject: [PATCH 069/195] Update commondocgenerator.class.php --- htdocs/core/class/commondocgenerator.class.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index a0f3f311ed4..0f962a9ca09 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -559,14 +559,6 @@ abstract class CommonDocGenerator $resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs); } - // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" - if (isset($line->fk_product) && $line->fk_product > 0) { - $tmpproduct = new Product($this->db); - $result = $tmpproduct->fetch($line->fk_product); - foreach ($tmpproduct->array_options as $key=>$label) - $resarray["line_".$key] = $label; - } - return $resarray; } From 66f1dd854584717bfbaa95002e3d933da8abc20f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 15:12:31 +0100 Subject: [PATCH 070/195] Fix avoid too large PDF --- htdocs/core/lib/pdf.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index dda52e653fe..255d4dcf453 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -2247,7 +2247,7 @@ function pdf_getLinkedObjects(&$object, $outputlangs) } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') { $outputlangs->load('orders'); - if (count($objects) > 1) { + if (count($objects) > 1 && count($objects) <= (getDolGlobalInt("MAXREFONDOC") ? getDolGlobalInt("MAXREFONDOC") : 5)) { $object->note_public .= dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefOrder").' :
    '); foreach ($objects as $elementobject) { $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).($elementobject->ref_client ? ' ('.$elementobject->ref_client.')' : '').($elementobject->ref_supplier ? ' ('.$elementobject->ref_supplier.')' : '').' '); From 436dbcd81d176737fe6a6a4f8288d38b0d5eb16a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 15:22:54 +0100 Subject: [PATCH 071/195] Shorter pdf label --- htdocs/langs/en_US/propal.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index ed07831fcba..db7b559a8a7 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -5,7 +5,7 @@ ProposalShort=Proposal ProposalsDraft=Draft commercial proposals ProposalsOpened=Open commercial proposals CommercialProposal=Commercial proposal -PdfCommercialProposalTitle=Commercial proposal +PdfCommercialProposalTitle=Proposal ProposalCard=Proposal card NewProp=New commercial proposal NewPropal=New proposal From 06f378db18d4dfb18956c04b822c630ce48cbbaf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 15:31:19 +0100 Subject: [PATCH 072/195] FIX Bad use of dol_concatdesc() --- htdocs/core/lib/pdf.lib.php | 27 ++++++++++---------- htdocs/datapolicy/class/datapolicy.class.php | 16 ++++++------ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 255d4dcf453..873b375496e 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -2247,13 +2247,11 @@ function pdf_getLinkedObjects(&$object, $outputlangs) } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') { $outputlangs->load('orders'); - if (count($objects) > 1 && count($objects) <= (getDolGlobalInt("MAXREFONDOC") ? getDolGlobalInt("MAXREFONDOC") : 5)) { - $object->note_public .= dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefOrder").' :
    '); + if (count($objects) > 1 && count($objects) <= (getDolGlobalInt("MAXREFONDOC") ? getDolGlobalInt("MAXREFONDOC") : 10)) { + $object->note_public = dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefOrder").' :
    '); foreach ($objects as $elementobject) { - $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).($elementobject->ref_client ? ' ('.$elementobject->ref_client.')' : '').($elementobject->ref_supplier ? ' ('.$elementobject->ref_supplier.')' : '').' '); - $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '); - $object->note_public .= dol_concatdesc($object->note_public, dol_print_date($elementobject->date, 'day', '', $outputlangs)); - $object->note_public .= dol_concatdesc($object->note_public, '
    '); + $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).($elementobject->ref_client ? ' ('.$elementobject->ref_client.')' : '').($elementobject->ref_supplier ? ' ('.$elementobject->ref_supplier.')' : '').' '); + $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '.dol_print_date($elementobject->date, 'day', '', $outputlangs).'
    '); } } elseif (count($objects) == 1) { $elementobject = array_shift($objects); @@ -2283,8 +2281,11 @@ function pdf_getLinkedObjects(&$object, $outputlangs) if (count($objects) > 1) { $order = null; - if (empty($object->linkedObjects['commande']) && $object->element != 'commande') $object->note_public .= dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :
    '); - else $object->note_public .= dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefSending").' :
    '); + if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { + $object->note_public = dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :
    '); + } else { + $object->note_public = dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefSending").' :
    '); + } // We concat this record info into fields xxx_value. title is overwrote. foreach ($objects as $elementobject) { if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { // There is not already a link to order and object is not the order, so we show also info with order @@ -2300,12 +2301,12 @@ function pdf_getLinkedObjects(&$object, $outputlangs) } if (! is_object($order)) { - $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref)); - $object->note_public .= dol_concatdesc($object->note_public, '
    '); + $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref)); + $object->note_public = dol_concatdesc($object->note_public, '
    '); } else { - $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '')); - $object->note_public .= dol_concatdesc($object->note_public, ' / '.$outputlangs->transnoentities($elementobject->ref)); - $object->note_public .= dol_concatdesc($object->note_public, '
    '); + $object->note_public = dol_concatdesc($object->note_public, $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '')); + $object->note_public = dol_concatdesc($object->note_public, ' / '.$outputlangs->transnoentities($elementobject->ref)); + $object->note_public = dol_concatdesc($object->note_public, '
    '); } } } elseif (count($objects) == 1) { diff --git a/htdocs/datapolicy/class/datapolicy.class.php b/htdocs/datapolicy/class/datapolicy.class.php index a7ed08d7e6f..7d53020ce3a 100644 --- a/htdocs/datapolicy/class/datapolicy.class.php +++ b/htdocs/datapolicy/class/datapolicy.class.php @@ -269,11 +269,11 @@ class DataPolicy $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; if ($message) { if ($sendtocc) { - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); } - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); - $actionmsg .= dol_concatdesc($actionmsg, $message); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); + $actionmsg = dol_concatdesc($actionmsg, $message); } // Send mail @@ -343,11 +343,11 @@ class DataPolicy $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; if ($message) { if ($sendtocc) { - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); } - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); - $actionmsg .= dol_concatdesc($actionmsg, $message); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); + $actionmsg = dol_concatdesc($actionmsg, $message); } From fa4b5d99c0f728c66238e1da52694190af5c7bd0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 15:35:34 +0100 Subject: [PATCH 073/195] FIX Bad use of dol_concatdesc() --- htdocs/datapolicy/class/datapolicy.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/datapolicy/class/datapolicy.class.php b/htdocs/datapolicy/class/datapolicy.class.php index a7ed08d7e6f..7d53020ce3a 100644 --- a/htdocs/datapolicy/class/datapolicy.class.php +++ b/htdocs/datapolicy/class/datapolicy.class.php @@ -269,11 +269,11 @@ class DataPolicy $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; if ($message) { if ($sendtocc) { - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); } - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); - $actionmsg .= dol_concatdesc($actionmsg, $message); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); + $actionmsg = dol_concatdesc($actionmsg, $message); } // Send mail @@ -343,11 +343,11 @@ class DataPolicy $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; if ($message) { if ($sendtocc) { - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".$sendtocc); } - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); - $actionmsg .= dol_concatdesc($actionmsg, $message); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); + $actionmsg = dol_concatdesc($actionmsg, $message); } From ba724204a430cc841a068b777ebf1d6e2ca727cc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 15:50:32 +0100 Subject: [PATCH 074/195] FIX Bad use of dol_concatdesc() --- htdocs/datapolicy/class/datapolicy.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/datapolicy/class/datapolicy.class.php b/htdocs/datapolicy/class/datapolicy.class.php index bf1033084d5..7383e059ae3 100644 --- a/htdocs/datapolicy/class/datapolicy.class.php +++ b/htdocs/datapolicy/class/datapolicy.class.php @@ -259,11 +259,11 @@ class DataPolicy { if ($sendtocc) { - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); } - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); - $actionmsg .= dol_concatdesc($actionmsg, $message); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); + $actionmsg = dol_concatdesc($actionmsg, $message); } // Send mail @@ -329,11 +329,11 @@ class DataPolicy $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto; if ($message) { if ($sendtocc) { - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); } - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); - $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); - $actionmsg .= dol_concatdesc($actionmsg, $message); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); + $actionmsg = dol_concatdesc($actionmsg, $message); } From 38d3b9ca71a8a8d55ebf591539c71c0ee444be7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 11 Nov 2021 16:54:20 +0100 Subject: [PATCH 075/195] fix regex --- htdocs/core/modules/printing/modules_printing.php | 2 +- htdocs/core/modules/printing/printipp.modules.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/printing/modules_printing.php b/htdocs/core/modules/printing/modules_printing.php index 1bbf78df022..fa86d832b73 100644 --- a/htdocs/core/modules/printing/modules_printing.php +++ b/htdocs/core/modules/printing/modules_printing.php @@ -69,7 +69,7 @@ class PrintingDriver $listoffiles = array(); $dirmodels = array_merge(array('/core/modules/printing/'), (array) $conf->modules_parts['printing']); foreach ($dirmodels as $dir) { - $tmpfiles = dol_dir_list(dol_buildpath($dir, 0), 'all', 0, '.modules.php', '', 'name', SORT_ASC, 0); + $tmpfiles = dol_dir_list(dol_buildpath($dir, 0), 'all', 0, '\.modules.php', '', 'name', SORT_ASC, 0); if (!empty($tmpfiles)) { $listoffiles = array_merge($listoffiles, $tmpfiles); } diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php index f290b2b4e90..584e7751fd7 100644 --- a/htdocs/core/modules/printing/printipp.modules.php +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -108,10 +108,10 @@ class printing_printipp extends PrintingDriver global $conf; $this->db = $db; - $this->host = $conf->global->PRINTIPP_HOST; - $this->port = $conf->global->PRINTIPP_PORT; - $this->user = $conf->global->PRINTIPP_USER; - $this->password = $conf->global->PRINTIPP_PASSWORD; + $this->host = getDolGlobalString('PRINTIPP_HOST'); + $this->port = getDolGlobalString('PRINTIPP_PORT'); + $this->user = getDolGlobalString('PRINTIPP_USER'); + $this->password = getDolGlobalString('PRINTIPP_PASSWORD'); $this->conf[] = array('varname'=>'PRINTIPP_HOST', 'required'=>1, 'example'=>'localhost', 'type'=>'text'); $this->conf[] = array('varname'=>'PRINTIPP_PORT', 'required'=>1, 'example'=>'631', 'type'=>'text'); $this->conf[] = array('varname'=>'PRINTIPP_USER', 'required'=>0, 'example'=>'', 'type'=>'text', 'moreattributes'=>'autocomplete="off"'); From 00213812010a43454ab7a61558f67009cdd638da Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 17:08:35 +0100 Subject: [PATCH 076/195] Fix #yogosha7605 --- htdocs/core/db/mysqli.class.php | 16 ++++++++++++---- htdocs/core/db/pgsql.class.php | 12 ++++++++---- htdocs/core/db/sqlite3.class.php | 16 ++++++++++++---- htdocs/install/upgrade.php | 1 + test/phpunit/CodingPhpTest.php | 4 ++-- test/phpunit/CodingSqlTest.php | 2 +- 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 0db4e16a897..b64ec0708e2 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -663,9 +663,13 @@ class DoliDBMysqli extends DoliDB $like = ''; if ($table) { - $like = "LIKE '".$table."'"; + $tmptable = preg_replace('/[^a-z0-9\.\-\_%]/i', '', $table); + + $like = "LIKE '".$this->escape($tmptable)."'"; } - $sql = "SHOW TABLES FROM ".$database." ".$like.";"; + $tmpdatabase = preg_replace('/[^a-z0-9\.\-\_]/i', '', $database); + + $sql = "SHOW TABLES FROM ".$tmpdatabase." ".$like.";"; //print $sql; $result = $this->query($sql); if ($result) { @@ -688,7 +692,9 @@ class DoliDBMysqli extends DoliDB // phpcs:enable $infotables = array(); - $sql = "SHOW FULL COLUMNS FROM ".$table.";"; + $tmptable = preg_replace('/[^a-z0-9\.\-\_]/i', '', $table); + + $sql = "SHOW FULL COLUMNS FROM ".$tmptable.";"; dol_syslog($sql, LOG_DEBUG); $result = $this->query($sql); @@ -794,7 +800,9 @@ class DoliDBMysqli extends DoliDB public function DDLDropTable($table) { // phpcs:enable - $sql = "DROP TABLE ".$table; + $tmptable = preg_replace('/[^a-z0-9\.\-\_]/i', '', $table); + + $sql = "DROP TABLE ".$tmptable; if (!$this->query($sql)) { return -1; diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index 5997349d0c5..ac6b8de33f3 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -937,7 +937,9 @@ class DoliDBPgsql extends DoliDB $escapedlike = ''; if ($table) { - $escapedlike = " AND table_name LIKE '".$this->escape($table)."'"; + $tmptable = preg_replace('/[^a-z0-9\.\-\_%]/i', '', $table); + + $escapedlike = " AND table_name LIKE '".$this->escape($tmptable)."'"; } $result = pg_query($this->db, "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'".$escapedlike." ORDER BY table_name"); if ($result) { @@ -973,8 +975,8 @@ class DoliDBPgsql extends DoliDB $sql .= " '' as \"Extra\","; $sql .= " '' as \"Privileges\""; $sql .= " FROM information_schema.columns infcol"; - $sql .= " WHERE table_schema='public' "; - $sql .= " AND table_name='".$this->escape($table)."'"; + $sql .= " WHERE table_schema = 'public' "; + $sql .= " AND table_name = '".$this->escape($table)."'"; $sql .= " ORDER BY ordinal_position;"; dol_syslog($sql, LOG_DEBUG); @@ -1078,7 +1080,9 @@ class DoliDBPgsql extends DoliDB public function DDLDropTable($table) { // phpcs:enable - $sql = "DROP TABLE ".$table; + $tmptable = preg_replace('/[^a-z0-9\.\-\_]/i', '', $table); + + $sql = "DROP TABLE ".$tmptable; if (!$this->query($sql)) { return -1; diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index c03d2a5ee04..bc01ee7a535 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -875,9 +875,13 @@ class DoliDBSqlite3 extends DoliDB $like = ''; if ($table) { - $like = "LIKE '".$table."'"; + $tmptable = preg_replace('/[^a-z0-9\.\-\_%]/i', '', $table); + + $like = "LIKE '".$this->escape($tmptable)."'"; } - $sql = "SHOW TABLES FROM ".$database." ".$like.";"; + $tmpdatabase = preg_replace('/[^a-z0-9\.\-\_]/i', '', $database); + + $sql = "SHOW TABLES FROM ".$tmpdatabase." ".$like.";"; //print $sql; $result = $this->query($sql); if ($result) { @@ -901,7 +905,9 @@ class DoliDBSqlite3 extends DoliDB // phpcs:enable $infotables = array(); - $sql = "SHOW FULL COLUMNS FROM ".$table.";"; + $tmptable = preg_replace('/[^a-z0-9\.\-\_]/i', '', $table); + + $sql = "SHOW FULL COLUMNS FROM ".$tmptable.";"; dol_syslog($sql, LOG_DEBUG); $result = $this->query($sql); @@ -1002,7 +1008,9 @@ class DoliDBSqlite3 extends DoliDB public function DDLDropTable($table) { // phpcs:enable - $sql = "DROP TABLE ".$table; + $tmptable = preg_replace('/[^a-z0-9\.\-\_]/i', '', $table); + + $sql = "DROP TABLE ".$tmptable; if (!$this->query($sql)) { return -1; diff --git a/htdocs/install/upgrade.php b/htdocs/install/upgrade.php index b36914ad36b..c03678151fc 100644 --- a/htdocs/install/upgrade.php +++ b/htdocs/install/upgrade.php @@ -260,6 +260,7 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ ); $listtables = $db->DDLListTables($conf->db->name, ''); + foreach ($listtables as $val) { // Database prefix filter if (preg_match('/^'.MAIN_DB_PREFIX.'/', $val)) { diff --git a/test/phpunit/CodingPhpTest.php b/test/phpunit/CodingPhpTest.php index 2681164c857..383c37e95e5 100644 --- a/test/phpunit/CodingPhpTest.php +++ b/test/phpunit/CodingPhpTest.php @@ -17,7 +17,7 @@ */ /** - * \file test/phpunit/SqlTest.php + * \file test/phpunit/CodingPhpTest.php * \ingroup test * \brief PHPUnit test * \remarks To run this script as CLI: phpunit filename.php @@ -363,7 +363,7 @@ class CodingPhpTest extends PHPUnit\Framework\TestCase // Check string sql|set|WHERE|...'".$yyy->xxx with xxx that is not 'escape', 'idate', .... It means we forget a db->escape when forging sql request. $ok=true; $matches=array(); - preg_match_all('/(sql|SET|WHERE|INSERT|VALUES).+\s*\'"\s*\.\s*\$(.......)/', $filecontent, $matches, PREG_SET_ORDER); + preg_match_all('/(sql|SET|WHERE|INSERT|VALUES|LIKE).+\s*\'"\s*\.\s*\$(.......)/', $filecontent, $matches, PREG_SET_ORDER); foreach ($matches as $key => $val) { if (! in_array($val[2], array('this->d', 'this->e', 'db->esc', 'dbs->es', 'mydb->e', 'dbsessi', 'db->ida', 'escaped', 'exclude', 'include'))) { $ok=false; // This will generate error diff --git a/test/phpunit/CodingSqlTest.php b/test/phpunit/CodingSqlTest.php index 9217ebbe7f6..f79205a0443 100644 --- a/test/phpunit/CodingSqlTest.php +++ b/test/phpunit/CodingSqlTest.php @@ -17,7 +17,7 @@ */ /** - * \file test/phpunit/SqlTest.php + * \file test/phpunit/CodingSqlTest.php * \ingroup test * \brief PHPUnit test * \remarks To run this script as CLI: phpunit filename.php From 5eff0e7a0c996a16bb5b2805f77bcec9bfb814c6 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 11 Nov 2021 17:48:23 +0100 Subject: [PATCH 077/195] FIX only a superadmin can modify entity --- htdocs/user/card.php | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index dec885e11eb..68218ab16bd 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -448,23 +448,15 @@ if (empty($reshook)) { $object->lang = GETPOST('default_lang', 'aZ09'); // Do we update also ->entity ? - if (!empty($conf->multicompany->enabled)) { // If multicompany is not enabled, we never update the entity of a user. - if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { - if (GETPOST('superadmin', 'int')) { - $object->entity = 0; - } else { - $object->entity = 1; // all users are in master entity - } + if (!empty($conf->multicompany->enabled && $user->entity == 0 && !empty($user->admin))) { // If multicompany is not enabled, we never update the entity of a user. + if (GETPOST('superadmin', 'int')) { + $object->entity = 0; } else { - // A user should not be able to move a user into another entity. Only superadmin should be able to do this. - if ($user->entity == 0 && $user->admin) { - if (GETPOST('superadmin', 'int')) { - // We try to set the user as superadmin. - $object->entity = 0; - } else { - // We try to change the entity of user - $object->entity = (GETPOSTISSET('entity') ? GETPOSTINT('entity') : $object->entity); - } + if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + $object->entity = 1; // all users are in master entity + } else { + // We try to change the entity of user + $object->entity = (GETPOSTISSET('entity') ? GETPOSTINT('entity') : $object->entity); } } } From e98cfb3ef1b5af51acef2c529d7ae1e48dfa104b Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Thu, 11 Nov 2021 18:02:56 +0100 Subject: [PATCH 078/195] FIX Save TakePOS credit note as a pos sale --- htdocs/takepos/invoice.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 660b6cbb18f..2a951a505ae 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -330,6 +330,8 @@ if ($action == 'creditnote' && $user->rights->facture->creer) { $creditnote = new Facture($db); $creditnote->socid = $invoice->socid; $creditnote->date = dol_now(); + $creditnote->module_source = 'takepos'; + $creditnote->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ; $creditnote->type = Facture::TYPE_CREDIT_NOTE; $creditnote->fk_facture_source = $placeid; $creditnote->remise_absolue = $invoice->remise_absolue; From aab9c2e6cacb0ca194d028481645c236be4652f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 18:20:31 +0100 Subject: [PATCH 079/195] Fix #yogosha7605 --- htdocs/core/db/mysqli.class.php | 5 +++-- htdocs/core/db/pgsql.class.php | 5 +++-- htdocs/core/db/sqlite3.class.php | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index b64ec0708e2..4dd71f0e351 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -933,8 +933,9 @@ class DoliDBMysqli extends DoliDB public function DDLDropField($table, $field_name) { // phpcs:enable - $sql = "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`"; - dol_syslog(get_class($this)."::DDLDropField ".$sql, LOG_DEBUG); + $tmp_field_name = preg_replace('/[^a-z0-9\.\-\_]/i', '', $field_name); + + $sql = "ALTER TABLE ".$table." DROP COLUMN `".$tmp_field_name."`"; if ($this->query($sql)) { return 1; } diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index ac6b8de33f3..7cf0a5d905a 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -1240,8 +1240,9 @@ class DoliDBPgsql extends DoliDB public function DDLDropField($table, $field_name) { // phpcs:enable - $sql = "ALTER TABLE ".$table." DROP COLUMN ".$field_name; - dol_syslog($sql, LOG_DEBUG); + $tmp_field_name = preg_replace('/[^a-z0-9\.\-\_]/i', '', $field_name); + + $sql = "ALTER TABLE ".$table." DROP COLUMN ".$tmp_field_name; if (!$this->query($sql)) { $this->error = $this->lasterror(); return -1; diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index bc01ee7a535..d1d6a4b680a 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -1120,8 +1120,9 @@ class DoliDBSqlite3 extends DoliDB public function DDLDropField($table, $field_name) { // phpcs:enable - $sql = "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`"; - dol_syslog(get_class($this)."::DDLDropField ".$sql, LOG_DEBUG); + $tmp_field_name = preg_replace('/[^a-z0-9\.\-\_]/i', '', $field_name); + + $sql = "ALTER TABLE ".$table." DROP COLUMN `".$tmp_field_name."`"; if (!$this->query($sql)) { $this->error = $this->lasterror(); return -1; From fd1585eda07ad2e2459fbbb486a91a1e150dc7b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 11 Nov 2021 18:23:34 +0100 Subject: [PATCH 080/195] add load langs --- htdocs/core/lib/functions2.lib.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 26c56d45463..fe6e8e0fa40 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -2131,30 +2131,38 @@ function dolGetElementUrl($objectid, $objecttype, $withpicto = 0, $option = '') // Special cases, to work with non standard path if ($objecttype == 'facture' || $objecttype == 'invoice') { + $langs->load('bills'); $classpath = 'compta/facture/class'; $module = 'facture'; $myobject = 'facture'; } elseif ($objecttype == 'commande' || $objecttype == 'order') { + $langs->load('orders'); $classpath = 'commande/class'; $module = 'commande'; $myobject = 'commande'; } elseif ($objecttype == 'propal') { + $langs->load('propal'); $classpath = 'comm/propal/class'; } elseif ($objecttype == 'supplier_proposal') { + $langs->load('supplier_proposal'); $classpath = 'supplier_proposal/class'; } elseif ($objecttype == 'shipping') { + $langs->load('sendings'); $classpath = 'expedition/class'; $myobject = 'expedition'; $module = 'expedition_bon'; } elseif ($objecttype == 'delivery') { + $langs->load('deliveries'); $classpath = 'delivery/class'; $myobject = 'delivery'; $module = 'delivery_note'; } elseif ($objecttype == 'contract') { + $langs->load('contracts'); $classpath = 'contrat/class'; $module = 'contrat'; $myobject = 'contrat'; } elseif ($objecttype == 'member') { + $langs->load('members'); $classpath = 'adherents/class'; $module = 'adherent'; $myobject = 'adherent'; @@ -2163,13 +2171,16 @@ function dolGetElementUrl($objectid, $objecttype, $withpicto = 0, $option = '') $module = 'cabinetmed'; $myobject = 'cabinetmedcons'; } elseif ($objecttype == 'fichinter') { + $langs->load('interventions'); $classpath = 'fichinter/class'; $module = 'ficheinter'; $myobject = 'fichinter'; } elseif ($objecttype == 'project') { + $langs->load('projects'); $classpath = 'projet/class'; $module = 'projet'; } elseif ($objecttype == 'task') { + $langs->load('projects'); $classpath = 'projet/class'; $module = 'projet'; $myobject = 'task'; From a725ffefdd80286502770c9eddfda64d69f30aa4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 18:30:17 +0100 Subject: [PATCH 081/195] Fix sql error --- htdocs/takepos/index.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 4d729bde2fa..1ec50dd3799 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -1037,13 +1037,10 @@ if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter") { } $sql = "SELECT rowid, status, entity FROM ".MAIN_DB_PREFIX."pos_cash_fence WHERE"; -$sql .= " entity = ".$conf->entity." AND "; -<<<<<<< HEAD +$sql .= " entity = ".((int) $conf->entity)." AND "; +$sql .= " posnumber = ".((int) $_SESSION["takeposterminal"])." AND "; $sql .= " date_creation > '".$db->idate(dol_get_first_hour(dol_now()))."'"; -======= -$sql .= " posnumber = ".$_SESSION["takeposterminal"]." AND "; -$sql .= " date(date_creation) = CURDATE()"; ->>>>>>> branch '12.0' of git@github.com:Dolibarr/dolibarr.git + $resql = $db->query($sql); if ($resql) { From 21c2dba9222913883e3aa46d6ea0af9ef007a64b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Nov 2021 19:06:55 +0100 Subject: [PATCH 082/195] Fix phpcs --- htdocs/compta/facture/card.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index d9be7ff3f1c..e01d71a1020 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -5118,7 +5118,6 @@ if ($action == 'create') { print ' :'.price($retainedWarranty).' '; } } else { // Credit note - $resteapayeraffiche = $resteapayer; $cssforamountpaymentcomplete = 'amountpaymentneutral'; From 53b565ec1d8324f4289b2b5f5462ed62b2a5668c Mon Sep 17 00:00:00 2001 From: daraelmin Date: Thu, 11 Nov 2021 20:06:21 +0100 Subject: [PATCH 083/195] Fix date_select go away when sorting subscription --- htdocs/adherents/subscription/list.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index 7146e89648e..4c9935b76a8 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -311,6 +311,7 @@ print ''; print ''; print ''; print ''; +print ''; print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $subscription->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); From 3b21fc2d37e71f057a0f971a5ac233e5a00a7127 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 12 Nov 2021 10:50:19 +0100 Subject: [PATCH 084/195] Better way to report value of stock when PRODUIT_MULTIPRICES is on --- htdocs/langs/en_US/stocks.lang | 2 +- htdocs/product/stock/product.php | 69 +++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 8c0cc76f075..19875f55148 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -96,7 +96,7 @@ RealStock=Real Stock RealStockDesc=Physical/real stock is the stock currently in the warehouses. RealStockWillAutomaticallyWhen=The real stock will be modified according to this rule (as defined in the Stock module): VirtualStock=Virtual stock -VirtualStockAtDate=Virtual stock at date +VirtualStockAtDate=Virtual stock at a future date VirtualStockAtDateDesc=Virtual stock once all the pending orders that are planned to be processed before the chosen date will be finished VirtualStockDesc=Virtual stock is the calculated stock available once all open/pending actions (that affect stocks) are closed (purchase orders received, sales orders shipped, manufacturing orders produced, etc) AtDate=At date diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 23900c85c0b..247d11d00c6 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -763,7 +763,7 @@ if ($id > 0 || $ref) { if ($result < 0) { dol_print_error($db, $object->error); } - $helpondiff .= ' ('.$langs->trans("ProductQtyInDraft").': '.$object->stats_commande['qty'].')'; + $helpondiff .= ' ('.$langs->trans("ProductQtyInDraft").': '.$object->stats_commande['qty'].')'; } // Number of product from customer order already sent (partial shipping) @@ -797,7 +797,7 @@ if ($id > 0 || $ref) { if ($result < 0) { dol_print_error($db, $object->error); } - $helpondiff .= ' ('.$langs->trans("ProductQtyInDraftOrWaitingApproved").': '.$object->stats_commande_fournisseur['qty'].')'; + $helpondiff .= ' ('.$langs->trans("ProductQtyInDraftOrWaitingApproved").': '.$object->stats_commande_fournisseur['qty'].')'; } // Number of product from supplier order already received (partial receipt) @@ -983,6 +983,7 @@ if (!$variants) { $entrepotstatic = new Entrepot($db); $product_lot_static = new Productlot($db); + $num = 0; $total = 0; $totalvalue = $totalvaluesell = 0; @@ -1025,18 +1026,45 @@ if (!$variants) { print ''.(price2num($object->pmp) ? price(price2num($object->pmp * $obj->reel, 'MT')) : '').''; // Sell price + $minsellprice = null; $maxsellprice = null; print ''; - print price(price2num($object->price, 'MU'), 1); if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + foreach ($object->multiprices as $priceforlevel) { + if (is_numeric($priceforlevel)) { + if (is_null($maxsellprice) || $priceforlevel > $maxsellprice) { + $maxsellprice = $priceforlevel; + } + if (is_null($minsellprice) || $priceforlevel < $minsellprice) { + $minsellprice = $priceforlevel; + } + } + } + print ''; + if ($minsellprice != $maxsellprice) { + print price(price2num($minsellprice, 'MU'), 1).' - '.price(price2num($maxsellprice, 'MU'), 1); + } else { + print price(price2num($minsellprice, 'MU'), 1); + } + print ''; print $form->textwithpicto('', $langs->trans("Variable")); + } else { + print price(price2num($object->price, 'MU'), 1); } print ''; // Value sell print ''; - print price(price2num($object->price * $obj->reel, 'MT'), 1); if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + print ''; + if ($minsellprice != $maxsellprice) { + print price(price2num($minsellprice * $obj->reel, 'MT'), 1).' - '.price(price2num($maxsellprice * $obj->reel, 'MT'), 1); + } else { + print price(price2num($minsellprice * $obj->reel, 'MT'), 1); + } + print ''; print $form->textwithpicto('', $langs->trans("Variable")); + } else { + print price(price2num($object->price * $obj->reel, 'MT'), 1); } print ''; print ''; @@ -1148,17 +1176,28 @@ if (!$variants) { print $totalvalue ? price(price2num($totalvalue, 'MT'), 1) : ' '; print ''; print ''; - print ($total ? price($totalvaluesell / $total, 1) : ' '); - if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - print $form->textwithpicto('', $langs->trans("Variable")); + if ($num) { + if ($total) { + print ''; + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + print $form->textwithpicto('', $langs->trans("Variable")); + } else { + print price($totalvaluesell / $total, 1); + } + print ''; + } } print ''; // Value to sell - print ''; - if (empty($conf->global->PRODUIT_MULTIPRICES)) { - print price(price2num($totalvaluesell, 'MT'), 1); - } else { - print $langs->trans("Variable"); + print ''; + if ($num) { + print ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) { + print price(price2num($totalvaluesell, 'MT'), 1); + } else { + print $form->textwithpicto('', $langs->trans("Variable")); + } + print ''; } print ''; print ''; @@ -1180,13 +1219,13 @@ if (!$variants) { } print ''; if (!empty($user->rights->produit->creer)) { - print ''; + print ''; print ''; print ''; print ''; print ''; } else { - print ''; + print ''; print ''; print ''; print ''; @@ -1200,7 +1239,7 @@ if (!$variants) { foreach ($lines as $line) { $ent = new Entrepot($db); $ent->fetch($line['fk_entrepot']); - print ''; + print ''; print ''; print ''; if (!empty($user->rights->produit->creer)) { From 5c8d91ba6c817bd8215f935f672a38559251b20d Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Fri, 12 Nov 2021 12:46:18 +0200 Subject: [PATCH 085/195] BankAccountNumber is not required. The IBAN can contain all the needed information. So there is no reason for the account number to be required --- htdocs/core/modules/modSociete.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index ca5b484499a..60e593cf3f1 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -757,7 +757,7 @@ class modSociete extends DolibarrModules 'sr.bank' => "Bank", 'sr.code_banque' => "BankCode", 'sr.code_guichet' => "DeskCode", - 'sr.number' => "BankAccountNumber*", + 'sr.number' => "BankAccountNumber", 'sr.cle_rib' => "BankAccountNumberKey", 'sr.bic' => "BIC", 'sr.iban_prefix' => "IBAN", From de435576a988144ed9059d0d05147deea09f7d1f Mon Sep 17 00:00:00 2001 From: Yaacov Akiba Slama Date: Fri, 12 Nov 2021 12:46:37 +0200 Subject: [PATCH 086/195] Allow WithdrawMode to be imported --- htdocs/core/modules/modSociete.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 60e593cf3f1..2826091155c 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -766,6 +766,7 @@ class modSociete extends DolibarrModules 'sr.owner_address' => "BankAccountOwnerAddress", 'sr.default_rib' => 'Default', 'sr.rum' => 'RUM', + 'sr.frstrecur' => "WithdrawMode", 'sr.type' => "Type ban is defaut", ); @@ -797,6 +798,7 @@ class modSociete extends DolibarrModules 'sr.owner_address' => 'address of account holder', 'sr.default_rib' => '1 (default account) / 0 (not default)', 'sr.rum' => 'RUM code', + 'sr.frstrecur' => 'FRST', 'sr.type' => 'ban', ); From 968ffbcef0b379929c8417c9a7c14143a60a7b22 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 12 Nov 2021 13:06:41 +0100 Subject: [PATCH 087/195] FIX add ldap hash algo --- htdocs/core/class/html.formldap.class.php | 17 +++++--- htdocs/core/lib/security.lib.php | 53 +++++++++++++---------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/htdocs/core/class/html.formldap.class.php b/htdocs/core/class/html.formldap.class.php index acee0bbbea7..1f9d6591560 100644 --- a/htdocs/core/class/html.formldap.class.php +++ b/htdocs/core/class/html.formldap.class.php @@ -81,16 +81,21 @@ class FormLdap } $arraylist = array( - "pbkdf2sha256" => "PBKDF2_SHA256", - "ssha512" => "SSHA512", - "ssha256" => "SSHA256", + //"pbkdf2sha256" => "PBKDF2_SHA256", + "ssha512" => "SSHA-512", + "ssha384" => "SSHA-384", + "ssha256" => "SSHA-256", "ssha" => "SSHA", + "sha512" => "SHA-512", + "sha384" => "SHA-384", + "sha256" => "SHA-256", "sha" => "SHA", "md5" => "MD5", "smd5" => "SMD5", - "cryptmd5" => "CRYPT-MD5", - "cryptsha512" => "CRYPT-SHA512", - "cryptsha256" => "CRYPT-SHA256", + //"cryptmd5" => "CRYPT-MD5", + //"cryptsha512" => "CRYPT-SHA512", + //"cryptsha384" => "CRYPT-SHA384", + //"cryptsha256" => "CRYPT-SHA256", "crypt" => "CRYPT", "clear" => "CLEAR" ); diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 1eb737880c6..ec3d73f2f72 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -97,7 +97,7 @@ function dol_decode($chain, $key = '1') * If constant MAIN_SECURITY_SALT is defined, we use it as a salt (used only if hashing algorightm is something else than 'password_hash'). * * @param string $chain String to hash - * @param string $type Type of hash ('0':auto will use MAIN_SECURITY_HASH_ALGO else md5, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap with no salt, '5':sha256, '6':password_hash). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. + * @param string $type Type of hash ('0':auto will use MAIN_SECURITY_HASH_ALGO else md5, '1':sha1, '2':sha1+md5, '3':md5, '4': for OpenLdap, '5':sha256, '6':password_hash). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. * @return string Hash of string * @see getRandomPassword() */ @@ -122,7 +122,7 @@ function dol_hash($chain, $type = '0') } elseif ($type == '3' || $type == 'md5') { return md5($chain); } elseif ($type == '4' || $type == 'openldap') { - return dolGetLdapHash($chain, getDolGlobalString('LDAP_PASSWORD_HASH_TYPE', 'md5'), getDolGlobalString('MAIN_SECURITY_SALT')); + return dolGetLdapPasswordHash($chain, getDolGlobalString('LDAP_PASSWORD_HASH_TYPE', 'md5'), getDolGlobalString('MAIN_SECURITY_SALT')); } elseif ($type == '5' || $type == 'sha256') { return hash('sha256', $chain); } elseif ($type == '6' || $type == 'password_hash') { @@ -145,7 +145,7 @@ function dol_hash($chain, $type = '0') * * @param string $chain String to hash (not hashed string) * @param string $hash hash to compare - * @param string $type Type of hash ('0':auto, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. + * @param string $type Type of hash ('0':auto, '1':sha1, '2':sha1+md5, '3':md5, '4': for OpenLdap, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. * @return bool True if the computed hash is the same as the given one */ function dol_verifyHash($chain, $hash, $type = '0') @@ -168,41 +168,46 @@ function dol_verifyHash($chain, $hash, $type = '0') } /** - * Returns a specific ldap hash of a string. + * Returns a specific ldap hash of a password. * - * @param string $chain String to hash + * @param string $password Password to hash * @param string $type Type of hash - * @return string Hash of string + * @return string Hash of password */ -function dolGetLdapHash($chain, $type = 'md5') +function dolGetLdapPasswordHash($password, $type = 'md5') { if (empty($type)) { $type = 'md5'; } + $salt = substr(sha1(time()), 0, 8); + if ($type === 'md5') { - return '{MD5}' . base64_encode(pack("H*", md5($chain))); // For OpenLdap with md5 (based on an unencrypted password in base) + return '{MD5}' . base64_encode(hash("md5", $password, true)); //For OpenLdap with md5 (based on an unencrypted password in base) } elseif ($type === 'md5frommd5') { - return '{MD5}' . base64_encode(hex2bin($chain)); // Create OpenLDAP MD5 password from Dolibarr MD5 password + return '{MD5}' . base64_encode(hex2bin($password)); // Create OpenLDAP MD5 password from Dolibarr MD5 password } elseif ($type === 'smd5') { - mt_srand((double)microtime()*1000000); - $salt = pack("CCCC", mt_rand(), mt_rand(), mt_rand(), mt_rand()); - return "{SMD5}" . base64_encode(pack("H*", md5($chain . $salt)) . $salt); + return "{SMD5}" . base64_encode(hash("md5", $password . $salt, true) . $salt); } elseif ($type === 'sha') { - return '{SHA}' . base64_encode(sha1($chain), true); + return '{SHA}' . base64_encode(hash("sha1", $password, true)); } elseif ($type === 'ssha') { - mt_srand((double)microtime()*1000000); - $salt = pack("CCCC", mt_rand(), mt_rand(), mt_rand(), mt_rand()); - return "{SSHA}" . base64_encode(pack("H*", sha1($chain . $salt)) . $salt); + return "{SSHA}" . base64_encode(hash("sha1", $password . $salt, true) . $salt); + } elseif ($type === 'sha256') { + return "{SHA256}" . base64_encode(hash("sha256", $password, true)); + } elseif ($type === 'ssha256') { + return "{SSHA256}" . base64_encode(hash("sha256", $password . $salt, true) . $salt); + } elseif ($type === 'sha384') { + return "{SHA384}" . base64_encode(hash("sha384", $password, true)); + } elseif ($type === 'ssha384') { + return "{SSHA384}" . base64_encode(hash("sha384", $password . $salt, true) . $salt); + } elseif ($type === 'sha512') { + return "{SHA512}" . base64_encode(hash("sha512", $password, true)); + } elseif ($type === 'ssha512') { + return "{SSHA512}" . base64_encode(hash("sha512", $password . $salt, true) . $salt); } elseif ($type === 'crypt') { - // Generate salt - $salt = ""; - $pattern = '0123456789'.'abcdefghijklmnopqrstuvwxyz'.'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.'./'; - mt_srand((double)microtime() * 1000000); - while (strlen($salt) < 2) { - $salt .= substr($pattern, (rand() % strlen($pattern)), 1); - } - return '{CRYPT}' . crypt($chain, $salt); + return '{CRYPT}' . crypt($password, $salt); + } elseif ($type === 'clear') { + return '{CLEAR}' . $password; // Just for test, plain text password is not secured ! } } From 1169ae551fc2acc5d5c38ebf633e001fe3fc1ba1 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 12 Nov 2021 13:12:49 +0100 Subject: [PATCH 088/195] FIX remove debug --- htdocs/core/class/ldap.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index e4b22cc529c..120c2993801 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -238,9 +238,9 @@ class Ldap // Upgrade connexion to TLS, if requested by the configuration if (!empty($conf->global->LDAP_SERVER_USE_TLS)) { // For test/debug - ldap_set_option($this->connection, LDAP_OPT_DEBUG_LEVEL, 7); - ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3); - ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0); + //ldap_set_option($this->connection, LDAP_OPT_DEBUG_LEVEL, 7); + //ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3); + //ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0); $resulttls = ldap_start_tls($this->connection); if (!$resulttls) { From 7324375caad3b0335234db2d17c5f3d4c091924b Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 12 Nov 2021 13:15:40 +0100 Subject: [PATCH 089/195] FIX missing rename function --- htdocs/adherents/class/adherent.class.php | 2 +- htdocs/user/class/user.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index fb77b062780..0b5fddd5da4 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2714,7 +2714,7 @@ class Adherent extends CommonObject if ($this->pass_indatabase_crypted && !empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED)) { // Create OpenLDAP MD5 password from Dolibarr MD5 password // Note: This suppose that "pass_indatabase_crypted" is a md5 (guaranted by the previous test if "(empty($conf->global->MAIN_SECURITY_HASH_ALGO))" - $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = dolGetLdapHash($this->pass_indatabase_crypted, 'md5frommd5'); + $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5'); } } } elseif (!empty($this->pass_indatabase)) { diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index ae663bc9fdd..daa23328b63 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2948,7 +2948,7 @@ class User extends CommonObject // Just for the default MD5 ! if (empty($conf->global->MAIN_SECURITY_HASH_ALGO)) { if ($this->pass_indatabase_crypted && !empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) { - $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dolGetLdapHash($this->pass_indatabase_crypted, 'md5frommd5'); // Create OpenLDAP MD5 password from Dolibarr MD5 password + $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5'); // Create OpenLDAP MD5 password from Dolibarr MD5 password } } } elseif (!empty($this->pass_indatabase)) { From 991c1b4f139da7873ee85d5d0b72a9e8e862c6ff Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Fri, 12 Nov 2021 13:20:58 +0100 Subject: [PATCH 090/195] ADD Klarna provider with Stripe --- htdocs/stripe/class/stripe.class.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 9324d7d3a5d..d60b084ff39 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -409,6 +409,9 @@ class Stripe extends CommonObject if (!empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) { $paymentmethodtypes[] = "sepa_debit"; //&& ($object->thirdparty->isInEEC()) } + if (!empty($conf->global->STRIPE_KLARNA)) { + $paymentmethodtypes[] = "klarna"; + } if (!empty($conf->global->STRIPE_BANCONTACT)) { $paymentmethodtypes[] = "bancontact"; } @@ -450,7 +453,9 @@ class Stripe extends CommonObject if (!empty($conf->global->STRIPE_GIROPAY)) { unset($dataforintent['setup_future_usage']); } - + if (!empty($conf->global->STRIPE_KLARNA)) { + unset($dataforintent['setup_future_usage']); + } if (!is_null($payment_method)) { $dataforintent["payment_method"] = $payment_method; $description .= ' - '.$payment_method; @@ -602,6 +607,9 @@ class Stripe extends CommonObject if (!empty($conf->global->STRIPE_BANCONTACT)) { $paymentmethodtypes[] = "bancontact"; } + if (!empty($conf->global->STRIPE_KLARNA)) { + $paymentmethodtypes[] = "klarna"; + } if (!empty($conf->global->STRIPE_IDEAL)) { $paymentmethodtypes[] = "ideal"; } From 97d2722c4ce36f2b7a962bccb28687d8b9f2ef57 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Fri, 12 Nov 2021 13:21:40 +0100 Subject: [PATCH 091/195] Update stripe.php --- htdocs/stripe/admin/stripe.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/htdocs/stripe/admin/stripe.php b/htdocs/stripe/admin/stripe.php index 06f417e48df..77c8d9a03b2 100644 --- a/htdocs/stripe/admin/stripe.php +++ b/htdocs/stripe/admin/stripe.php @@ -390,6 +390,20 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code print ''; } +// Activate Klarna +if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code + print ''; +} + // Activate Bancontact if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code print '
    '.$formproduct->selectWarehouses('', 'fk_entrepot').'
    '.$formproduct->selectWarehouses('', 'fk_entrepot').'
    '.$langs->trans("Warehouse").'
    '.$langs->trans("Warehouse").''.$langs->trans("StockLimit").''.$langs->trans("DesiredStock").'
    '.$ent->getNomUrl(3).'
    '.$ent->getNomUrl(3).''.$line['seuil_stock_alerte'].''.$line['desiredstock'].'
    '; + print $langs->trans("STRIPE_KLARNA").''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('STRIPE_KLARNA'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("STRIPE_KLARNA", $arrval, $conf->global->STRIPE_KLARNA); + } + print '   '.$langs->trans("ExampleOnlyForKlarnaCustomers").''; + print '
    '; From 9e5a20545d0ec684de52963ff770d9213d76a8c3 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 12 Nov 2021 13:23:11 +0100 Subject: [PATCH 092/195] FIX dolGetLdapPasswordHash use your own random salt --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index ec3d73f2f72..58d69842f66 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -122,7 +122,7 @@ function dol_hash($chain, $type = '0') } elseif ($type == '3' || $type == 'md5') { return md5($chain); } elseif ($type == '4' || $type == 'openldap') { - return dolGetLdapPasswordHash($chain, getDolGlobalString('LDAP_PASSWORD_HASH_TYPE', 'md5'), getDolGlobalString('MAIN_SECURITY_SALT')); + return dolGetLdapPasswordHash($chain, getDolGlobalString('LDAP_PASSWORD_HASH_TYPE', 'md5')); } elseif ($type == '5' || $type == 'sha256') { return hash('sha256', $chain); } elseif ($type == '6' || $type == 'password_hash') { From daadcf2fc36662aeb8985771fbbe26c90aedaa2d Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 12 Nov 2021 12:23:40 +0000 Subject: [PATCH 093/195] Fixing style errors. --- htdocs/stripe/class/stripe.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index d60b084ff39..a520e83f0ee 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -411,7 +411,7 @@ class Stripe extends CommonObject } if (!empty($conf->global->STRIPE_KLARNA)) { $paymentmethodtypes[] = "klarna"; - } + } if (!empty($conf->global->STRIPE_BANCONTACT)) { $paymentmethodtypes[] = "bancontact"; } @@ -609,7 +609,7 @@ class Stripe extends CommonObject } if (!empty($conf->global->STRIPE_KLARNA)) { $paymentmethodtypes[] = "klarna"; - } + } if (!empty($conf->global->STRIPE_IDEAL)) { $paymentmethodtypes[] = "ideal"; } From 715a65eab25ef3fdb932c0c31763dc1be5bd62d1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 12 Nov 2021 13:33:59 +0100 Subject: [PATCH 094/195] Clean code for md theme --- htdocs/admin/modulehelp.php | 3 +++ htdocs/core/class/html.form.class.php | 3 ++- htdocs/main.inc.php | 2 +- htdocs/theme/md/style.css.php | 5 +++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index f0211d1b795..da76f01fd6c 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -70,6 +70,9 @@ print ''."\n".''; $arrayofnatures = array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - '.$langs->trans("AllPublishers")); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index fb0bba95ac4..92dba4d4de0 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4905,8 +4905,9 @@ class Form $formconfirm .= ($question ? '
    '.img_help('', '').' '.$question.'
    ' : ''); $formconfirm .= ''."\n"; - $formconfirm .= "\n\n"; + $formconfirm .= "\n\n"; $formconfirm .= ''; - if (!empty($hidemargininfos)) { - print ''; + if (!empty($hidemargininfos)) { + print ''; + } } - } - print '
    '; - print ''."\n"; + print '
    '; + print '' . "\n"; - print ''; - print ''; - print ''; - print ''; - if ($conf->global->MARGIN_TYPE == "1") { - print ''; - } else { - print ''; - } - print ''; - if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { - print ''; - } - if (!empty($conf->global->DISPLAY_MARK_RATES)) { - print ''; - } - print ''; - - if (!empty($conf->product->enabled)) { - //if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) { - print ''; - print ''; - print ''; - print ''; - print ''; + print '
    '.$langs->trans('Margins').''.$langs->trans('SellingPrice').''.$langs->trans('BuyingPrice').''.$langs->trans('CostPrice').''.$langs->trans('Margin').''.$langs->trans('MarginRate').''.$langs->trans('MarkRate').'
    '.$langs->trans('MarginOnProducts').''.price($marginInfo['pv_products']).''.price($marginInfo['pa_products']).''.price($marginInfo['margin_on_products']).'
    '; + print ''; + print ''; + print ''; + if ($conf->global->MARGIN_TYPE == "1") { + print ''; + } else { + print ''; + } + print ''; if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { - print ''; + print ''; } if (!empty($conf->global->DISPLAY_MARK_RATES)) { - print ''; + print ''; } print ''; - } - if (!empty($conf->service->enabled)) { - print ''; - print ''; - print ''; - print ''; - print ''; - if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { - print ''; + if (!empty($conf->product->enabled)) { + //if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) { + print ''; + print ''; + print ''; + print ''; + print ''; + if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { + print ''; + } + if (!empty($conf->global->DISPLAY_MARK_RATES)) { + print ''; + } + print ''; } - if (!empty($conf->global->DISPLAY_MARK_RATES)) { - print ''; - } - print ''; - } - if (!empty($conf->product->enabled) && !empty($conf->service->enabled)) { - print ''; - print ''; - print ''; - print ''; - print ''; - if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { - print ''; + if (!empty($conf->service->enabled)) { + print ''; + print ''; + print ''; + print ''; + print ''; + if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { + print ''; + } + if (!empty($conf->global->DISPLAY_MARK_RATES)) { + print ''; + } + print ''; } - if (!empty($conf->global->DISPLAY_MARK_RATES)) { - print ''; + + if (!empty($conf->product->enabled) && !empty($conf->service->enabled)) { + print ''; + print ''; + print ''; + print ''; + print ''; + if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { + print ''; + } + if (!empty($conf->global->DISPLAY_MARK_RATES)) { + print ''; + } + print ''; } - print ''; + print $hookmanager->resPrint; + print '
    ' . $langs->trans('Margins') . '' . $langs->trans('SellingPrice') . '' . $langs->trans('BuyingPrice') . '' . $langs->trans('CostPrice') . '' . $langs->trans('Margin') . ''.(($marginInfo['margin_rate_products'] == '') ? '' : price($marginInfo['margin_rate_products'], null, null, null, null, 2).'%').'' . $langs->trans('MarginRate') . ''.(($marginInfo['mark_rate_products'] == '') ? '' : price($marginInfo['mark_rate_products'], null, null, null, null, 2).'%').'' . $langs->trans('MarkRate') . '
    '.$langs->trans('MarginOnServices').''.price($marginInfo['pv_services']).''.price($marginInfo['pa_services']).''.price($marginInfo['margin_on_services']).''.(($marginInfo['margin_rate_services'] == '') ? '' : price($marginInfo['margin_rate_services'], null, null, null, null, 2).'%').'
    ' . $langs->trans('MarginOnProducts') . '' . price($marginInfo['pv_products']) . '' . price($marginInfo['pa_products']) . '' . price($marginInfo['margin_on_products']) . '' . (($marginInfo['margin_rate_products'] == '') ? '' : price($marginInfo['margin_rate_products'], null, null, null, null, 2) . '%') . '' . (($marginInfo['mark_rate_products'] == '') ? '' : price($marginInfo['mark_rate_products'], null, null, null, null, 2) . '%') . '
    '.(($marginInfo['mark_rate_services'] == '') ? '' : price($marginInfo['mark_rate_services'], null, null, null, null, 2).'%').'
    '.$langs->trans('TotalMargin').''.price($marginInfo['pv_total']).''.price($marginInfo['pa_total']).''.price($marginInfo['total_margin']).''.(($marginInfo['total_margin_rate'] == '') ? '' : price($marginInfo['total_margin_rate'], null, null, null, null, 2).'%').'
    ' . $langs->trans('MarginOnServices') . '' . price($marginInfo['pv_services']) . '' . price($marginInfo['pa_services']) . '' . price($marginInfo['margin_on_services']) . '' . (($marginInfo['margin_rate_services'] == '') ? '' : price($marginInfo['margin_rate_services'], null, null, null, null, 2) . '%') . '' . (($marginInfo['mark_rate_services'] == '') ? '' : price($marginInfo['mark_rate_services'], null, null, null, null, 2) . '%') . '
    '.(($marginInfo['total_mark_rate'] == '') ? '' : price($marginInfo['total_mark_rate'], null, null, null, null, 2).'%').'
    ' . $langs->trans('TotalMargin') . '' . price($marginInfo['pv_total']) . '' . price($marginInfo['pa_total']) . '' . price($marginInfo['total_margin']) . '' . (($marginInfo['total_margin_rate'] == '') ? '' : price($marginInfo['total_margin_rate'], null, null, null, null, 2) . '%') . '' . (($marginInfo['total_mark_rate'] == '') ? '' : price($marginInfo['total_mark_rate'], null, null, null, null, 2) . '%') . '
    '; + print '
    '; + } elseif ($reshook > 0) { + print $hookmanager->resPrint; } - print '
    '; - print '
    '; } } From 0f402897a47f45cb2cbe5a821dcedd79b17e7caa Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 18 Nov 2021 10:55:05 +0100 Subject: [PATCH 157/195] add add_replace --- htdocs/core/class/hookmanager.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index 691c20e10f8..c113f2c3bb9 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -230,7 +230,8 @@ class HookManager 'setContentSecurityPolicy', 'setHtmlTitle', 'completeTabsHead', - 'formDolBanner' + 'formDolBanner', + 'displayMarginInfos', ) )) { $hooktype = 'addreplace'; From ef447bacbffb5d71914ec70b7eac924b53bb7a2a Mon Sep 17 00:00:00 2001 From: lvessiller Date: Thu, 18 Nov 2021 12:12:30 +0100 Subject: [PATCH 158/195] NEW add form confirm hook in paiement card --- htdocs/compta/paiement.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index 2740b09427a..fbb6abdedae 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -802,6 +802,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie dol_print_error($db); } + $formconfirm = ''; // Save button if ($action != 'add_paiement') { @@ -840,7 +841,16 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie $text .= '
    '.$langs->trans("AllCompletelyPayedInvoiceWillBeClosed"); print ''; } - print $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$facture->id.'&socid='.$facture->socid.'&type='.$facture->type, $langs->trans('ReceivedCustomersPayments'), $text, 'confirm_paiement', $formquestion, $preselectedchoice); + $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$facture->id.'&socid='.$facture->socid.'&type='.$facture->type, $langs->trans('ReceivedCustomersPayments'), $text, 'confirm_paiement', $formquestion, $preselectedchoice); + } + + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; } print "\n"; From cdde6ecf94bd381432a4d5ce08e50040ca137e22 Mon Sep 17 00:00:00 2001 From: lvessiller Date: Thu, 18 Nov 2021 12:17:02 +0100 Subject: [PATCH 159/195] NEW add form confirm hook in paiement card --- htdocs/compta/paiement.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index fbb6abdedae..29682460d3a 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -853,6 +853,9 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie $formconfirm = $hookmanager->resPrint; } + // Print form confirm + print $formconfirm; + print "\n"; } } From e652b93878f1f5615849223615e60bd212e2617a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 12:58:31 +0100 Subject: [PATCH 160/195] Autoswitch on inventory tab on validation of inventory Fix disabled button when some data are available. --- htdocs/core/actions_addupdatedelete.inc.php | 11 ++++++ htdocs/core/class/commonobject.class.php | 6 ++- htdocs/langs/en_US/stocks.lang | 2 + htdocs/product/inventory/card.php | 7 ++++ .../inventory/class/inventory.class.php | 14 +++---- htdocs/product/inventory/inventory.php | 39 ++++++++++++------- 6 files changed, 57 insertions(+), 22 deletions(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 10d25b2aa09..4857902b8cc 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -140,6 +140,7 @@ if ($action == 'add' && !empty($permissiontoadd)) { header("Location: ".$urltogo); exit; } else { + $error++; // Creation KO if (!empty($object->errors)) { setEventMessages(null, $object->errors, 'errors'); @@ -255,6 +256,7 @@ if ($action == 'update' && !empty($permissiontoadd)) { if ($result > 0) { $action = 'view'; } else { + $error++; // Creation KO setEventMessages($object->error, $object->errors, 'errors'); $action = 'edit'; @@ -284,6 +286,7 @@ if ($action == "update_extras" && !empty($permissiontoadd)) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); $action = 'view'; } else { + $error++; setEventMessages($object->error, $object->errors, 'errors'); $action = 'edit_extras'; } @@ -301,9 +304,11 @@ if ($action == 'confirm_delete' && !empty($permissiontodelete)) { if ($result > 0) { // Delete OK setEventMessages("RecordDeleted", null, 'mesgs'); + header("Location: ".$backurlforlist); exit; } else { + $error++; if (!empty($object->errors)) { setEventMessages(null, $object->errors, 'errors'); } else { @@ -347,6 +352,7 @@ if ($action == 'confirm_deleteline' && $confirm == 'yes' && !empty($permissionto header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); exit; } else { + $error++; setEventMessages($object->error, $object->errors, 'errors'); } $action = ''; @@ -383,6 +389,7 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $permissiontoadd) { } } } else { + $error++; setEventMessages($object->error, $object->errors, 'errors'); } $action = ''; @@ -414,6 +421,7 @@ if ($action == 'confirm_close' && $confirm == 'yes' && $permissiontoadd) { } } } else { + $error++; setEventMessages($object->error, $object->errors, 'errors'); } $action = ''; @@ -425,6 +433,7 @@ if ($action == 'confirm_setdraft' && $confirm == 'yes' && $permissiontoadd) { if ($result >= 0) { // Nothing else done } else { + $error++; setEventMessages($object->error, $object->errors, 'errors'); } $action = ''; @@ -456,6 +465,7 @@ if ($action == 'confirm_reopen' && $confirm == 'yes' && $permissiontoadd) { } } } else { + $error++; setEventMessages($object->error, $object->errors, 'errors'); } $action = ''; @@ -481,6 +491,7 @@ if ($action == 'confirm_clone' && $confirm == 'yes' && !empty($permissiontoadd)) header("Location: ".$_SERVER['PHP_SELF'].'?id='.$newid); // Open record of new object exit; } else { + $error++; setEventMessages($objectutil->error, $objectutil->errors, 'errors'); $action = ''; } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 812353591ed..aed5bc9515f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8730,7 +8730,11 @@ abstract class CommonObject $res = $this->db->query($sql); if ($res === false) { $error++; - $this->errors[] = $this->db->lasterror(); + if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $this->errors[] = "ErrorRefAlreadyExists"; + } else { + $this->errors[] = $this->db->lasterror(); + } } } diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 19875f55148..2fa24d467ca 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -264,3 +264,5 @@ ProductBatchDoesNotExist=Product with batch/serial does not exist ProductBarcodeDoesNotExist=Product with barcode does not exist WarehouseId=Warehouse ID WarehouseRef=Warehouse Ref +SaveQtyFirst=Save the real inventoried quantities first, before asking creation of the stock movement. +InventoryStartedShort=Started \ No newline at end of file diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index 91edba380cd..1f036e1fa3c 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -109,6 +109,7 @@ if ($reshook < 0) { } if (empty($reshook)) { + $savaction = $action; $error = 0; $backurlforlist = DOL_URL_ROOT.'/product/inventory/list.php'; @@ -152,6 +153,12 @@ if (empty($reshook)) { $autocopy = 'MAIN_MAIL_AUTOCOPY_INVENTORY_TO'; $trackid = 'stockinv'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + + if (!$error && $savaction == 'confirm_validate' && $action == '' && $object->id > 0) { + // Switch to the tab inventory + header("Location: ".DOL_URL_ROOT.'/product/inventory/inventory.php?id='.$object->id); + exit; + } } diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index 57abc333a58..3e83d62ecf2 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -59,10 +59,10 @@ class Inventory extends CommonObject */ public $picto = 'inventory'; - const STATUS_DRAFT = 0; - const STATUS_VALIDATED = 1; - const STATUS_RECORDED = 2; - const STATUS_CANCELED = 9; + const STATUS_DRAFT = 0; // Draft + const STATUS_VALIDATED = 1; // Inventory is in process + const STATUS_RECORDED = 2; // Inventory is finisged. Stock movement has been recorded. + const STATUS_CANCELED = 9; // Canceled /** * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') @@ -368,7 +368,7 @@ class Inventory extends CommonObject } /** - * Set to Recorded + * Set to inventory to status "Closed". It means all stock movements were recorded. * * @param User $user User that creates * @param bool $notrigger false=launch triggers after, true=disable triggers @@ -616,11 +616,11 @@ class Inventory extends CommonObject $labelStatus = array(); $labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); - $labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated').' ('.$langs->transnoentitiesnoconv('Started').')'; + $labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated').' ('.$langs->transnoentitiesnoconv('InventoryStartedShort').')'; $labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled'); $labelStatus[self::STATUS_RECORDED] = $langs->transnoentitiesnoconv('Closed'); $labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); - $labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Started'); + $labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('InventoryStartedShort'); $labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled'); $labelStatusShort[self::STATUS_RECORDED] = $langs->transnoentitiesnoconv('Closed'); diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 9a4d61209ba..ce657f1c9d6 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -310,20 +310,22 @@ $help_url = ''; llxHeader('', $langs->trans('Inventory'), $help_url); -// Disable button Generate movement if data were not saved +// Disable button Generate movement if data were modified and not saved print ''; @@ -639,12 +640,14 @@ if ($object->id > 0) { //Call method to undo changes in real qty print ''; @@ -667,7 +670,7 @@ if ($object->id > 0) { print ''; } print ''.$langs->trans("ExpectedQty").''; - print ''; + print ''; print $form->textwithpicto($langs->trans("RealQty"), $langs->trans("InventoryRealQtyHelp")); print ''; if ($object->status == $object::STATUS_VALIDATED) { @@ -692,7 +695,7 @@ if ($object->id > 0) { print ''; } print ''; - print ''; + print ''; print ''; print ''; // Actions @@ -764,17 +767,22 @@ if ($object->id > 0) { print ''; // Real quantity - print ''; + print ''; if ($object->status == $object::STATUS_VALIDATED) { $qty_view = GETPOST("id_".$obj->rowid) && price2num(GETPOST("id_".$obj->rowid), 'MS') >= 0 ? GETPOST("id_".$obj->rowid) : $obj->qty_view; - if (!$hasinput && $qty_view !== null && $obj->qty_stock != $qty_view) { + + //if (!$hasinput && $qty_view !== null && $obj->qty_stock != $qty_view) { + if ($qty_view != '') { $hasinput = true; } + print ''; + print img_picto('', 'eraser', 'class="opacitymedium"'); + print ''; print ''; print ''; + print ''; - print '  '; print ''.img_delete().''; print ''; $qty_tmp = price2num(GETPOST("id_".$obj->rowid."_input_tmp", 'MS')) >= 0 ? GETPOST("id_".$obj->rowid."_input_tmp") : $qty_view; @@ -801,10 +809,13 @@ if ($object->id > 0) { print '
    '; + // Call method to disable the button if no qty entered yet for inventory + if ($object->status != $object::STATUS_VALIDATED || !$hasinput) { print ''; From 2d4f971508bc6b9d797d529ed31782d4beb5943f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 13:10:52 +0100 Subject: [PATCH 161/195] Fix verifCond must return false if string is '0' Hide a not used property. --- htdocs/core/lib/functions.lib.php | 10 +++++----- htdocs/product/inventory/class/inventory.class.php | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 48fcdaa5010..7d8d7c5bc7b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8132,10 +8132,10 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = /** * Verify if condition in string is ok or not * - * @param string $strRights String with condition to check - * @return boolean True or False. Return True if strRights is '' + * @param string $strToEvaluate String with condition to check + * @return boolean True or False. Note: It returns True if $strToEvaluate is '' */ -function verifCond($strRights) +function verifCond($strToEvaluate) { global $user, $conf, $langs; global $leftmenu; @@ -8143,8 +8143,8 @@ function verifCond($strRights) //print $strRights."
    \n"; $rights = true; - if ($strRights != '') { - $str = 'if(!('.$strRights.')) { $rights = false; }'; + if ($strToEvaluate !== '') { + $str = 'if(!('.$strToEvaluate.')) { $rights = false; }'; dol_eval($str); // The dol_eval must contains all the global $xxx used into a condition } return $rights; diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index 3e83d62ecf2..b224667f1c6 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -101,8 +101,7 @@ class Inventory extends CommonObject 'title' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>25, 'css'=>'minwidth300', 'csslist'=>'tdoverflowmax200'), 'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Warehouse', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'index'=>1, 'help'=>'InventoryForASpecificWarehouse', 'picto'=>'stock', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist'=>'tdoverflowmax200'), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'visible'=>1, 'enabled'=>1, 'position'=>32, 'index'=>1, 'help'=>'InventoryForASpecificProduct', 'picto'=>'product', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist'=>'tdoverflowmax200'), - 'date_inventory' => array('type'=>'date', 'label'=>'DateValue', 'visible'=>1, 'enabled'=>1, 'position'=>35), - + 'date_inventory' => array('type'=>'date', 'label'=>'DateValue', 'visible'=>1, 'enabled'=>0, 'position'=>35), // This date is not used so disabled. 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>500), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501), 'date_validation' => array('type'=>'datetime', 'label'=>'DateValidation', 'visible'=>-2, 'enabled'=>1, 'position'=>502), From e609622f2b7a6a6b54931ff428672f4bf543ee92 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 13:17:48 +0100 Subject: [PATCH 162/195] Fix test on verifCond for value 0 --- htdocs/core/lib/functions.lib.php | 2 +- test/phpunit/FunctionsLibTest.php | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 07ff2930f0f..869aa2343bc 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8082,7 +8082,7 @@ function verifCond($strRights) //print $strRights."
    \n"; $rights = true; - if ($strRights != '') { + if ($strRights !== '') { $str = 'if(!('.$strRights.')) { $rights = false; }'; dol_eval($str); // The dol_eval must contains all the global $xxx used into a condition } diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 5287b65b0c7..1bf3b6378fb 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1048,13 +1048,19 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $this->assertFalse($verifcond, 'Test a false comparison'); $verifcond=verifCond('$conf->facture->enabled'); - $this->assertTrue($verifcond, 'Test that conf property of a module report true when enabled'); + $this->assertTrue($verifcond, 'Test that the conf property of a module reports true when enabled'); $verifcond=verifCond('$conf->moduledummy->enabled'); - $this->assertFalse($verifcond, 'Test that conf property of a module report false when disabled'); + $this->assertFalse($verifcond, 'Test that the conf property of a module reports false when disabled'); + + $verifcond=verifCond(0); + $this->assertFalse($verifcond, 'Test that verifConf(0) return False'); + + $verifcond=verifCond("0"); + $this->assertFalse($verifcond, 'Test that verifConf("0") return False'); $verifcond=verifCond(''); - $this->assertTrue($verifcond); + $this->assertTrue($verifcond, 'Test that verifConf("") return False (special case)'); } /** From 2a39a1dc9382262653b5ef7651c8533dd3cf2f90 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 13:55:55 +0100 Subject: [PATCH 163/195] Keep option to enable field --- htdocs/product/inventory/class/inventory.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index b224667f1c6..b972e44245b 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -101,7 +101,7 @@ class Inventory extends CommonObject 'title' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>25, 'css'=>'minwidth300', 'csslist'=>'tdoverflowmax200'), 'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Warehouse', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'index'=>1, 'help'=>'InventoryForASpecificWarehouse', 'picto'=>'stock', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist'=>'tdoverflowmax200'), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'visible'=>1, 'enabled'=>1, 'position'=>32, 'index'=>1, 'help'=>'InventoryForASpecificProduct', 'picto'=>'product', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist'=>'tdoverflowmax200'), - 'date_inventory' => array('type'=>'date', 'label'=>'DateValue', 'visible'=>1, 'enabled'=>0, 'position'=>35), // This date is not used so disabled. + 'date_inventory' => array('type'=>'date', 'label'=>'DateValue', 'visible'=>1, 'enabled'=>'$conf->global->STOCK_INVENTORY_ADD_A_VALUE_DATE', 'position'=>35), // This date is not used so disabled by default. 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>500), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501), 'date_validation' => array('type'=>'datetime', 'label'=>'DateValidation', 'visible'=>-2, 'enabled'=>1, 'position'=>502), From db975bbcc2847d0f7853fd5ee3af4722f1d14f87 Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Thu, 18 Nov 2021 17:17:00 +0100 Subject: [PATCH 164/195] Fix: The error not correctly collected on insertation line failure --- htdocs/expedition/class/expedition.class.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index d14a34515c4..845aaa194fa 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -9,7 +9,7 @@ * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2014-2017 Francis Appels * Copyright (C) 2015 Claudio Aschieri - * Copyright (C) 2016 Ferran Marcet + * Copyright (C) 2016-2021 Ferran Marcet * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018 Frédéric France * Copyright (C) 2020 Lenin Rivas @@ -364,14 +364,14 @@ class Expedition extends CommonObject { if (!isset($this->lines[$i]->detail_batch)) { // no batch management - if (!$this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) > 0) + if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) < 0) { $error++; } } else { // with batch management - if (!$this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) > 0) + if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) < 0) { $error++; } @@ -423,7 +423,6 @@ class Expedition extends CommonObject else { $error++; - $this->error = $this->db->lasterror()." - sql=$sql"; $this->db->rollback(); return -3; } From 0649dc598dd4dc77204f33d3448ef1ed4a6f5a8f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 19:25:07 +0100 Subject: [PATCH 165/195] Clean code --- htdocs/core/class/conf.class.php | 49 ++++++++++--------- .../doc/doc_generic_usergroup_odt.modules.php | 2 +- htdocs/cron/class/cronjob.class.php | 16 +++--- htdocs/user/group/card.php | 4 +- 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 59045725d06..be4006f1fca 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -110,10 +110,12 @@ class Conf // Common objects that are not modules $this->mycompany = new stdClass(); $this->admin = new stdClass(); - $this->browser = new stdClass(); $this->medias = new stdClass(); $this->global = new stdClass(); + // Common objects that are not modules and set by the main and not into the this->setValues() + $this->browser = new stdClass(); + $this->cache = array(); $this->modules = array(); $this->modules_parts = array( @@ -152,7 +154,6 @@ class Conf $this->facture = new stdClass(); $this->contrat = new stdClass(); $this->user = new stdClass(); - $this->usergroup = new stdClass(); $this->adherent = new stdClass(); $this->bank = new stdClass(); $this->notification = new stdClass(); @@ -162,18 +163,18 @@ class Conf } /** - * Load setup values into conf object (read llx_const) for a specified entity - * Note that this->db->xxx, this->file->xxx and this->multicompany have been already loaded when setValues is called. + * Load setup values into conf object (read llx_const) for a specified entity + * Note that this->db->xxx, this->file->xxx and this->multicompany have been already loaded when setValues is called. * - * @param DoliDB $db Database handler * @param int $entity Entity to get * @return int < 0 if KO, >= 0 if OK */ - public function setEntityValues($db, $entity) + public function setEntityValues($entity) { if ($this->entity != $entity) { + // If we ask to reload setup for a new entity $this->entity = $entity; - return $this->setValues($db); + return $this->setValues($this->db); } return 0; @@ -197,31 +198,39 @@ class Conf } } - // Properly declare multi-modules objects. - $this->global = new stdClass(); - $this->multicompany = new stdClass(); + // Common objects that are not modules + $this->mycompany = new stdClass(); + $this->admin = new stdClass(); + $this->medias = new stdClass(); + $this->global = new stdClass(); + + // Common objects that are not modules and set by the main and not into the this->setValues() + //$this->browser = new stdClass(); // This is set by main and not into this setValues(), so we keep it intact. // First level object // TODO Remove this part. - $this->expedition_bon = new stdClass(); - $this->delivery_note = new stdClass(); - $this->fournisseur = new stdClass(); + $this->syslog = new stdClass(); + $this->expedition_bon = new stdClass(); + $this->delivery_note = new stdClass(); + $this->fournisseur = new stdClass(); $this->product = new stdClass(); $this->service = new stdClass(); $this->contrat = new stdClass(); $this->actions = new stdClass(); $this->agenda = new stdClass(); - $this->commande = new stdClass(); - $this->propal = new stdClass(); + $this->commande = new stdClass(); + $this->propal = new stdClass(); $this->facture = new stdClass(); $this->contrat = new stdClass(); - $this->usergroup = new stdClass(); + $this->user = new stdClass(); $this->adherent = new stdClass(); - $this->bank = new stdClass(); + $this->bank = new stdClass(); $this->notification = new stdClass(); - $this->mailing = new stdClass(); + $this->mailing = new stdClass(); $this->expensereport = new stdClass(); $this->productbatch = new stdClass(); + + $this->cache = array(); $this->modules = array();; $this->modules_parts = array( 'css' => array(), @@ -470,10 +479,6 @@ class Conf $this->user->dir_output = $rootforuser."/users"; $this->user->dir_temp = $rootfortemp."/users/temp"; - // For usergroup storage - $this->usergroup->dir_output = $rootforuser."/usergroups"; - $this->usergroup->dir_temp = $rootfortemp."/usergroups/temp"; - // For proposal storage $this->propal->multidir_output = array($this->entity => $rootfordata."/propale"); $this->propal->multidir_temp = array($this->entity => $rootfortemp."/propale/temp"); diff --git a/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php b/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php index 134c5e00362..a934c7a50d9 100644 --- a/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php +++ b/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php @@ -258,7 +258,7 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup } } - $dir = $conf->usergroup->dir_output; + $dir = $conf->user->dir_output.'/usergroups'; $objectref = dol_sanitizeFileName($object->ref); if (!preg_match('/specimen/i', $objectref)) { $dir .= "/".$objectref; diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 44564e1b0ab..34fe7b6cd58 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1081,7 +1081,7 @@ class Cronjob extends CommonObject dol_syslog("We try to run a job in entity ".$this->entity." when we are in entity ".$conf->entity, LOG_WARNING); } $savcurrententity = $conf->entity; - $conf->setEntityValues($this->db, $this->entity); + $conf->setEntityValues($this->entity); dol_syslog(get_class($this)."::run_jobs entity for running job is ".$conf->entity); require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; @@ -1090,13 +1090,13 @@ class Cronjob extends CommonObject if ($result < 0) { $this->error = "User Error:".$user->error; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->setEntityValues($this->db, $savcurrententity); + $conf->setEntityValues($savcurrententity); return -1; } else { if (empty($user->id)) { $this->error = " User user login:".$userlogin." do not exists"; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->setEntityValues($this->db, $savcurrententity); + $conf->setEntityValues($savcurrententity); return -1; } } @@ -1126,7 +1126,7 @@ class Cronjob extends CommonObject $result = $this->update($user); // This include begin/commit if ($result < 0) { dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->setEntityValues($this->db, $savcurrententity); + $conf->setEntityValues($savcurrententity); return -1; } @@ -1241,7 +1241,7 @@ class Cronjob extends CommonObject if ($ret === false) { $this->error = $langs->trans('CronCannotLoadLib').': '.$libpath; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->setEntityValues($this->db, $savcurrententity); + $conf->setEntityValues($savcurrententity); return -1; } @@ -1250,7 +1250,7 @@ class Cronjob extends CommonObject $result = $langs->load($this->module_name.'@'.$this->module_name); // If this->module_name was an existing language file, this will make nothing if ($result < 0) { // If technical error dol_syslog(get_class($this)."::run_jobs Cannot load module langs".$langs->error, LOG_ERR); - $conf->setEntityValues($this->db, $savcurrententity); + $conf->setEntityValues($savcurrententity); return -1; } @@ -1316,11 +1316,11 @@ class Cronjob extends CommonObject $result = $this->update($user); // This include begin/commit if ($result < 0) { dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - $conf->setEntityValues($this->db, $savcurrententity); + $conf->setEntityValues($savcurrententity); return -1; } - $conf->setEntityValues($this->db, $savcurrententity); + $conf->setEntityValues($savcurrententity); return $error ?-1 : 1; } diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index 3e1f31602b2..f24c4232a8e 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -237,7 +237,7 @@ if (empty($reshook)) { } // Actions to build doc - $upload_dir = $conf->usergroup->dir_output; + $upload_dir = $conf->user->dir_output.'/usergroups'; $permissiontoadd = $user->rights->user->user->creer; include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -478,7 +478,7 @@ if ($action == 'create') { */ $filename = dol_sanitizeFileName($object->ref); - $filedir = $conf->usergroup->dir_output."/".dol_sanitizeFileName($object->ref); + $filedir = $conf->user->dir_output."/usergroups/".dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed = $user->rights->user->user->creer; $delallowed = $user->rights->user->user->supprimer; From d24120d6f9e6cb2d0927035fe4cab16b144e57e5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 19:27:40 +0100 Subject: [PATCH 166/195] Clean code --- htdocs/core/class/conf.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index be4006f1fca..8776060b60f 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -116,6 +116,7 @@ class Conf // Common objects that are not modules and set by the main and not into the this->setValues() $this->browser = new stdClass(); + // Common arrays $this->cache = array(); $this->modules = array(); $this->modules_parts = array( @@ -230,6 +231,7 @@ class Conf $this->expensereport = new stdClass(); $this->productbatch = new stdClass(); + // Common arrays $this->cache = array(); $this->modules = array();; $this->modules_parts = array( From e81c118a27233a40de22919863b37c26ba34b660 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 19:38:56 +0100 Subject: [PATCH 167/195] FIX Use the SQL standard for the if confition --- htdocs/core/db/DoliDB.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 1ebea289470..daa5f657549 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -77,7 +77,8 @@ abstract class DoliDB implements Database */ public function ifsql($test, $resok, $resko) { - return 'IF('.$test.','.$resok.','.$resko.')'; + //return 'IF('.$test.','.$resok.','.$resko.')'; // Not sql standard + return '(CASE WHEN '.$test.' THEN '.$resok.' ELSE '.$resko.' END)'; } /** From 8f9638318647a690fc634ceb23c26ea74cf5d628 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 20:10:04 +0100 Subject: [PATCH 168/195] Update expedition.class.php --- htdocs/expedition/class/expedition.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 845aaa194fa..bcccd2aee2a 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -364,14 +364,14 @@ class Expedition extends CommonObject { if (!isset($this->lines[$i]->detail_batch)) { // no batch management - if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) < 0) + if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) <= 0) { $error++; } } else { // with batch management - if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) < 0) + if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) <= 0) { $error++; } From 9789ae23d78f5b6a1090259be7800761954d0b2b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 20:12:46 +0100 Subject: [PATCH 169/195] Update llx_c_paiement.sql --- htdocs/install/mysql/data/llx_c_paiement.sql | 30 ++++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_paiement.sql b/htdocs/install/mysql/data/llx_c_paiement.sql index a7156b6d6da..e29b47639f2 100644 --- a/htdocs/install/mysql/data/llx_c_paiement.sql +++ b/htdocs/install/mysql/data/llx_c_paiement.sql @@ -30,18 +30,18 @@ -- Types paiement -- -insert into llx_c_paiement (id,code,libelle,type,active) values ( 1, 'TIP', 'TIP', 2,0); -insert into llx_c_paiement (id,code,libelle,type,active) values ( 2, 'VIR', 'Transfer', 2,1); -insert into llx_c_paiement (id,code,libelle,type,active) values ( 3, 'PRE', 'Debit order', 2,1); -insert into llx_c_paiement (id,code,libelle,type,active) values ( 4, 'LIQ', 'Cash', 2,1); -insert into llx_c_paiement (id,code,libelle,type,active) values ( 6, 'CB', 'Credit card', 2,1); -insert into llx_c_paiement (id,code,libelle,type,active) values ( 7, 'CHQ', 'Cheque', 2,1); -insert into llx_c_paiement (id,code,libelle,type,active) values (50, 'VAD', 'Online payment', 2,0); -insert into llx_c_paiement (id,code,libelle,type,active) values (51, 'TRA', 'Traite', 2,0); -insert into llx_c_paiement (id,code,libelle,type,active) values (52, 'LCR', 'LCR', 2,0); -insert into llx_c_paiement (id,code,libelle,type,active) values (53, 'FAC', 'Factor', 2,0); -INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (100, 'KLA', 'Klarna', 1,1); -INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (101, 'SOF', 'Sofort', 1,1); -INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (102, 'BAN', 'Bancontact', 1,1); -INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (103, 'IDE', 'iDeal', 1,1); -INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (104, 'GIR', 'Giropay', 1,1); +insert into llx_c_paiement (id,code,libelle,type,active) values ( 1, 'TIP', 'TIP', 2, 0); +insert into llx_c_paiement (id,code,libelle,type,active) values ( 2, 'VIR', 'Transfer', 2, 1); +insert into llx_c_paiement (id,code,libelle,type,active) values ( 3, 'PRE', 'Debit order', 2, 1); +insert into llx_c_paiement (id,code,libelle,type,active) values ( 4, 'LIQ', 'Cash', 2, 1); +insert into llx_c_paiement (id,code,libelle,type,active) values ( 6, 'CB', 'Credit card', 2, 1); +insert into llx_c_paiement (id,code,libelle,type,active) values ( 7, 'CHQ', 'Cheque', 2, 1); +insert into llx_c_paiement (id,code,libelle,type,active) values (50, 'VAD', 'Online payment', 2, 0); +insert into llx_c_paiement (id,code,libelle,type,active) values (51, 'TRA', 'Traite', 2, 0); +insert into llx_c_paiement (id,code,libelle,type,active) values (52, 'LCR', 'LCR', 2, 0); +insert into llx_c_paiement (id,code,libelle,type,active) values (53, 'FAC', 'Factor', 2, 0); +INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (100, 'KLA', 'Klarna', 1, 0); +INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (101, 'SOF', 'Sofort', 1, 0); +INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (102, 'BAN', 'Bancontact', 1, 0); +INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (103, 'IDE', 'iDeal', 1, 0); +INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (104, 'GIR', 'Giropay', 1, 0); From 2afe6ccb4b4b5e5736a3a9bdd056576199179a99 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 21:26:35 +0100 Subject: [PATCH 170/195] Debug feature shown/hide canceled orders --- htdocs/langs/en_US/main.lang | 4 +++- htdocs/langs/en_US/projects.lang | 2 -- htdocs/projet/element.php | 38 +++++++++++++++++++------------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index a0b9fda9f64..f765340af4f 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -1158,4 +1158,6 @@ Properties=Properties hasBeenValidated=%s has been validated ClientTZ=Client Time Zone (user) NotClosedYet=Not yet closed -ClearSignature=Signature reset \ No newline at end of file +ClearSignature=Signature reset +CanceledHidden=Canceled hidden +CanceledShown=Canceled shown diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index e9e626dd7fc..c19f32a0396 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -37,8 +37,6 @@ OpportunitiesStatusForOpenedProjects=Leads amount of open projects by status OpportunitiesStatusForProjects=Leads amount of projects by status ShowProject=Show project ShowTask=Show task -ShowCanceled=Show canceled -HideCanceled=Hide canceled SetProject=Set project NoProject=No project defined or owned NbOfProjects=Number of projects diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 05b7f962509..e455d6f599f 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -1016,6 +1016,9 @@ foreach ($listofreferent as $key => $value) { } } + $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet'); + + if (empty($conf->global->PROJECT_LINK_ON_OVERWIEW_DISABLED) && $idtofilterthirdparty && !in_array($tablename, $exclude_select_element)) { $selectList = $formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300 minwidth75imp', -2, !empty($project_field) ? $project_field : 'fk_projet'); if ($selectList < 0) { @@ -1046,23 +1049,29 @@ foreach ($listofreferent as $key => $value) { } $addform .= '
    '; } - if ($key == "order_supplier") { - $addform .= ' - '.$langs->trans("ShowCanceled").' + if (is_array($elementarray) && !count($elementarray) > 0 && $key == "order_supplier") { + $addform = '
    + '.$langs->trans("CanceledShown").' '; +
    '.$addform; } print load_fiche_titre($langs->trans($title), $addform, ''); @@ -1131,7 +1140,6 @@ foreach ($listofreferent as $key => $value) { } print ''; - $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet'); if (is_array($elementarray) && count($elementarray) > 0) { $total_ht = 0; $total_ttc = 0; @@ -1186,12 +1194,12 @@ foreach ($listofreferent as $key => $value) { if (!empty($element->close_code) && $element->close_code == 'replaced') { $qualifiedfortotal = false; // Replacement invoice, do not include into total } - } elseif (($key == 'order_supplier') && ($element->status == 7)) { + } elseif ($key == 'order_supplier' && $element->status == 7) { $qualifiedfortotal = false; // It makes no sense to include canceled orders in the total } - if (($key == "order_supplier") && ($element->status == 7)) { - print ''; + if ($key == "order_supplier" && $element->status == 7) { + print ''; } else { print ''; } From 92b0fde4ca1da50cd9d86c27283710ac7599bb02 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 18 Nov 2021 21:37:33 +0100 Subject: [PATCH 171/195] Debug v15 --- htdocs/langs/en_US/salaries.lang | 1 + htdocs/salaries/ajax/ajaxsalaries.php | 8 ++++++- htdocs/salaries/card.php | 2 +- htdocs/theme/md/style.css.php | 30 ++++++++++++++++----------- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang index c0e115a20df..20a10694500 100644 --- a/htdocs/langs/en_US/salaries.lang +++ b/htdocs/langs/en_US/salaries.lang @@ -24,3 +24,4 @@ SalariesStatistics=Salary statistics SalariesAndPayments=Salaries and payments ConfirmDeleteSalaryPayment=Do you want to delete this salary payment ? FillFieldFirst=Fill employee field first +UpdateAmountWithLastSalary=Set amount with last salary diff --git a/htdocs/salaries/ajax/ajaxsalaries.php b/htdocs/salaries/ajax/ajaxsalaries.php index dc7715ff6ba..adea28ee8ce 100644 --- a/htdocs/salaries/ajax/ajaxsalaries.php +++ b/htdocs/salaries/ajax/ajaxsalaries.php @@ -47,8 +47,14 @@ require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php'; restrictedArea($user, 'salaries'); + +/* + * View + */ + $fk_user = GETPOST('fk_user', 'int'); $return_arr = array(); + if (!empty(GETPOST('fk_user', 'int'))) { $sql = "SELECT s.amount, s.rowid FROM ".MAIN_DB_PREFIX."salary as s"; $sql .= " WHERE s.fk_user = ".((int) $fk_user); @@ -60,7 +66,7 @@ if (!empty(GETPOST('fk_user', 'int'))) { $obj = $db->fetch_object($resql); $label = "Salary amount"; $row_array['label'] = $label; - $row_array['value'] = $obj->amount; + $row_array['value'] = price2num($obj->amount, 'MT'); $row_array['key'] = "Amount"; array_push($return_arr, $row_array); diff --git a/htdocs/salaries/card.php b/htdocs/salaries/card.php index 3caf2afa7bd..b0abeeb134a 100755 --- a/htdocs/salaries/card.php +++ b/htdocs/salaries/card.php @@ -668,7 +668,7 @@ if ($action == 'create') { ); } else { - alert("'.$langs->trans("FillFieldFirst").'"); + alert("'.dol_escape_js($langs->trans("FillFieldFirst")).'"); } }); diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 5ea2e6c0529..a2d912d46e6 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -657,6 +657,10 @@ input:-webkit-autofill { -webkit-box-shadow: 0 0 0 50px #FBFFEA inset; } +input[type=checkbox], input[type=radio] { + margin: 0 3px 0 3px; +} + /* CSS for placeholder */ .placeholder { color: #ccc; } ::-webkit-input-placeholder { color:#ccc; } @@ -922,6 +926,19 @@ textarea.centpercent { .marginright2 { margin-: 2px; } +.paddingtop { + padding-top: 4px; +} +.paddingtop2 { + padding-top: 2px; +} +.paddingbottom { + padding-bottom: 4px; +} +.paddingbottom2 { + padding-bottom: 2px; +} + .cursordefault { cursor: default; } @@ -3324,18 +3341,7 @@ tr.nocellnopadd td.nobordernopadding, tr.nocellnopadd td.nocellnopadd .smallpaddingimp { padding: 4px !important; } -.nopaddingleft { - padding-: 0px; -} -.nopaddingright { - padding-: 0px; -} -.nopaddingtopimp { - padding-top: 0px !important; -} -.nopaddingbottomimp { - padding-bottom: 0px !important; -} + .notopnoleft { border-collapse: collapse; border: 0px; From cdc160b9a9d036b2af0da760c1e78d3a64946e22 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Nov 2021 11:12:53 +0100 Subject: [PATCH 172/195] FIX column alignement on valid confirm page of shipment --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 888d9f66114..e8a8eb2843e 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7522,7 +7522,7 @@ abstract class CommonObject if ($display_type == 'card') { $out .= ''; - if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER) && ($action == 'view' || $action == 'editline')) { + if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER) && ($action == 'view' || $action == 'valid' || $action == 'editline')) { $out .= ''; } $out .= 'db->idate($now)."', ".$this->product_id.", "; + $sql .= " VALUES ('".$this->db->idate($this->datem)."', ".$this->product_id.", "; $sql .= " ".($batch ? "'".$this->db->escape($batch)."'" : "null").", "; $sql .= " ".($eatby ? "'".$this->db->idate($eatby)."'" : "null").", "; $sql .= " ".($sellby ? "'".$this->db->idate($sellby)."'" : "null").", "; @@ -755,19 +755,19 @@ class MouvementStock extends CommonObject /** * Decrease stock for product and subproducts * - * @param User $user Object user - * @param int $fk_product Id product - * @param int $entrepot_id Warehouse id - * @param int $qty Quantity - * @param int $price Price - * @param string $label Label of stock movement - * @param string $datem Force date of movement - * @param integer $eatby eat-by date - * @param integer $sellby sell-by date - * @param string $batch batch number - * @param int $id_product_batch Id product_batch - * @param string $inventorycode Inventory code - * @return int <0 if KO, >0 if OK + * @param User $user Object user + * @param int $fk_product Id product + * @param int $entrepot_id Warehouse id + * @param int $qty Quantity + * @param int $price Price + * @param string $label Label of stock movement + * @param integer|string $datem Force date of movement + * @param integer $eatby eat-by date + * @param integer $sellby sell-by date + * @param string $batch batch number + * @param int $id_product_batch Id product_batch + * @param string $inventorycode Inventory code + * @return int <0 if KO, >0 if OK */ public function livraison($user, $fk_product, $entrepot_id, $qty, $price = 0, $label = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $id_product_batch = 0, $inventorycode = '') { @@ -790,7 +790,7 @@ class MouvementStock extends CommonObject * @param integer|string $eatby eat-by date * @param integer|string $sellby sell-by date * @param string $batch batch number - * @param string $datem Force date of movement + * @param integer|string $datem Force date of movement * @param int $id_product_batch Id product_batch * @param string $inventorycode Inventory code * @return int <0 if KO, >0 if OK @@ -804,28 +804,6 @@ class MouvementStock extends CommonObject return $this->_create($user, $fk_product, $entrepot_id, $qty, 3, $price, $label, $inventorycode, $datem, $eatby, $sellby, $batch, $skip_batch, $id_product_batch); } - - // /** - // * Return nb of subproducts lines for a product - // * - // * @param int $id Id of product - // * @return int <0 if KO, nb of subproducts if OK - // * @deprecated A count($product->getChildsArbo($id,1)) is same. No reason to have this in this class. - // */ - // public function nbOfSubProducts($id) - // { - // $nbSP=0; - - // $resql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."product_association"; - // $resql.= " WHERE fk_product_pere = ".((int) $id); - // if ($this->db->query($resql)) - // { - // $obj=$this->db->fetch_object($resql); - // $nbSP=$obj->nb; - // } - // return $nbSP; - // } - /** * Count number of product in stock before a specific date * diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 644bd115d4b..1de719796d2 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -1640,7 +1640,14 @@ if ($action == 'create') { } print ''; } else { - if ($object->statut <= 1) { + $statusreceived = $object::STATUS_CLOSED; + if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION")) { + $statusreceived = $object::STATUS_VALIDATED; + } + if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION_CLOSE")) { + $statusreceived = $object::STATUS_CLOSED; + } + if ($object->statut < $statusreceived) { print ''.$langs->trans("QtyToReceive").''; } else { print ''.$langs->trans("QtyReceived").''; @@ -1979,14 +1986,14 @@ if ($action == 'create') { if ($object->statut == Reception::STATUS_DRAFT && $num_prod > 0) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->reception_advance->validate))) { - print ''.$langs->trans("Validate").''; + print ''.$langs->trans("Validate").''; } else { print ''.$langs->trans("Validate").''; } } - // Edit + // Back to draft if ($object->statut == Reception::STATUS_VALIDATED && $user->rights->reception->creer) { - print ''; + print ''; } // TODO add alternative status diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index e1e2c857bc0..540bb17b9e1 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -138,7 +138,14 @@ class Reception extends CommonObject $this->statuts = array(); $this->statuts[-1] = 'StatusReceptionCanceled'; $this->statuts[0] = 'StatusReceptionDraft'; + // product to receive if stock increase is on close or already received if stock increase is on validation $this->statuts[1] = 'StatusReceptionValidated'; + if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION")) { + $this->statuts[1] = 'StatusReceptionValidatedReceived'; + } + if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION_CLOSE")) { + $this->statuts[1] = 'StatusReceptionValidatedToReceive'; + } $this->statuts[2] = 'StatusReceptionProcessed'; // List of short language codes for status @@ -589,7 +596,8 @@ class Reception extends CommonObject // line without batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record. - $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionValidatedInDolibarr", $numref)); + $inventorycode = ''; + $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionValidatedInDolibarr", $numref), '', '', '', '', 0, $inventorycode); if ($result < 0) { $error++; $this->errors[] = $mouvS->error; @@ -601,7 +609,8 @@ class Reception extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record. // Note: ->fk_origin_stock = id into table llx_product_batch (may be rename into llx_product_stock_batch in another version) - $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionValidatedInDolibarr", $numref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch); + $inventorycode = ''; + $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionValidatedInDolibarr", $numref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, '', 0, $inventorycode); if ($result < 0) { $error++; $this->errors[] = $mouvS->error; @@ -1432,7 +1441,7 @@ class Reception extends CommonObject } /** - * Classify the reception as closed. + * Classify the reception as closed (this record also the stock movement) * * @return int <0 if KO, >0 if OK */ @@ -1514,7 +1523,8 @@ class Reception extends CommonObject // line without batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record - $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionClassifyClosedInDolibarr", $numref)); + $inventorycode = ''; + $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionClassifyClosedInDolibarr", $this->ref), '', '', '', '', 0, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; @@ -1524,7 +1534,8 @@ class Reception extends CommonObject // line with batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record - $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionClassifyClosedInDolibarr", $numref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch); + $inventorycode = ''; + $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionClassifyClosedInDolibarr", $this->ref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, '', 0, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; @@ -1676,7 +1687,8 @@ class Reception extends CommonObject // line without batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record - $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref)); + $inventorycode = ''; + $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref), '', '', '', '', 0, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; @@ -1686,7 +1698,8 @@ class Reception extends CommonObject // line with batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record - $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); + $inventorycode = ''; + $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, '', $obj->fk_origin_stock, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; @@ -1798,7 +1811,8 @@ class Reception extends CommonObject // line without batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record - $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionBackToDraftInDolibarr", $this->ref)); + $inventorycode = ''; + $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionBackToDraftInDolibarr", $this->ref), '', '', '', '', 0, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; @@ -1809,7 +1823,8 @@ class Reception extends CommonObject // line with batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record - $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionBackToDraftInDolibarr", $this->ref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch); + $inventorycode = ''; + $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionBackToDraftInDolibarr", $this->ref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, '', 0, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; From 35b1868693cdb41506f5958a58f2a77944a6cea8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Nov 2021 14:01:31 +0100 Subject: [PATCH 174/195] FIX Missing trans --- htdocs/langs/en_US/receptions.lang | 4 +++- htdocs/reception/class/reception.class.php | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/htdocs/langs/en_US/receptions.lang b/htdocs/langs/en_US/receptions.lang index ca836137226..d60487c439f 100644 --- a/htdocs/langs/en_US/receptions.lang +++ b/htdocs/langs/en_US/receptions.lang @@ -47,4 +47,6 @@ ReceptionsNumberingModules=Numbering module for receptions ReceptionsReceiptModel=Document templates for receptions NoMorePredefinedProductToDispatch=No more predefined products to dispatch ReceptionExist=A reception exists -ReceptionBackToDraftInDolibarr=Reception %s back to draft \ No newline at end of file +ReceptionBackToDraftInDolibarr=Reception %s back to draft +ReceptionClassifyClosedInDolibarr=Reception %s classified Closed +ReceptionUnClassifyCloseddInDolibarr=Reception %s re-open \ No newline at end of file diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 540bb17b9e1..5fb8e3b8af0 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1689,6 +1689,7 @@ class Reception extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record $inventorycode = ''; $result = $mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref), '', '', '', '', 0, $inventorycode); + if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; @@ -1721,10 +1722,15 @@ class Reception extends CommonObject } } - if ($this->origin == 'order_supplier') { + if (!$error && $this->origin == 'order_supplier') { $commande = new CommandeFournisseur($this->db); $commande->fetch($this->origin_id); - $commande->setStatus($user, 4); + $result = $commande->setStatus($user, 4); + if ($result < 0) { + $error++; + $this->error = $commande->error; + $this->errors = $commande->errors; + } } } else { $error++; From 3dbab220609a7e0b21875f5d8241dbd5ef8ad39f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Nov 2021 18:08:49 +0100 Subject: [PATCH 175/195] Prepare 14.0.4 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 1ac8978bbb8..40f3f124ae8 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -34,7 +34,7 @@ if (!defined('DOL_APPLICATION_TITLE')) { define('DOL_APPLICATION_TITLE', 'Dolibarr'); } if (!defined('DOL_VERSION')) { - define('DOL_VERSION', '14.0.3'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c + define('DOL_VERSION', '14.0.4'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c } if (!defined('EURO')) { From 635e9e9747957039765fdadcc315c3daa6ca9002 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Nov 2021 22:28:20 +0100 Subject: [PATCH 176/195] CSS --- .../class/fournisseur.commande.class.php | 1 + htdocs/theme/md/btn.inc.php | 20 +++++++++++++------ htdocs/theme/md/theme_vars.inc.php | 12 ++++++----- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 9e16c803b28..27f7bac5b94 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -770,6 +770,7 @@ class CommandeFournisseur extends CommonOrder if ($reshook > 0) { return $hookmanager->resPrint; } + return dolGetStatus($statusLong, $statusShort, '', $statusClass, $mode); } diff --git a/htdocs/theme/md/btn.inc.php b/htdocs/theme/md/btn.inc.php index 1bf0333e574..136af6b273e 100644 --- a/htdocs/theme/md/btn.inc.php +++ b/htdocs/theme/md/btn.inc.php @@ -44,12 +44,20 @@ if (!empty($conf->global->THEME_DARKMODEENABLED)) { /* ============================================================================== */ -div.divButAction { +/*div.divButAction { margin-bottom: 1.4em; -} +}*/ + div.tabsAction > a.butAction, div.tabsAction > a.butActionRefused, div.tabsAction > a.butActionDelete, -div.tabsAction > span.butAction, div.tabsAction > span.butActionRefused, div.tabsAction > span.butActionDelete { +div.tabsAction > span.butAction, div.tabsAction > span.butActionRefused, div.tabsAction > span.butActionDelete, +div.tabsAction > div.divButAction > span.butAction, +div.tabsAction > div.divButAction > span.butActionDelete, +div.tabsAction > div.divButAction > span.butActionRefused, +div.tabsAction > div.divButAction > a.butAction, +div.tabsAction > div.divButAction > a.butActionDelete, +div.tabsAction > div.divButAction > a.butActionRefused { margin-bottom: 1.4em !important; + margin-right: 0px !important; } div.tabsActionNoBottom > a.butAction, div.tabsActionNoBottom > a.butActionRefused { margin-bottom: 0 !important; @@ -81,9 +89,8 @@ span.butAction, span.butActionDelete { display: inline-block; text-align: center; cursor: pointer; - /* color: #fff; */ - /* background: rgb(); */ color: #444; + /* border: 1px solid #aaa; */ /* border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); */ @@ -251,6 +258,7 @@ span.butActionNewRefused>span.fa, span.butActionNewRefused>span.fa:hover text-align: center; cursor: pointer; color: #999 !important; + border: 1px solid #ccc; box-sizing: border-box; -moz-box-sizing: border-box; @@ -351,7 +359,7 @@ a.btnTitle.btnTitleSelected { } .btnTitle:hover .btnTitle-label{ - color: #ffffff; + color:var(--btncolorborderhover); } div.pagination .btnTitle:hover .btnTitle-label{ color: rgb(); diff --git a/htdocs/theme/md/theme_vars.inc.php b/htdocs/theme/md/theme_vars.inc.php index 18869ccb8c6..216a5043111 100644 --- a/htdocs/theme/md/theme_vars.inc.php +++ b/htdocs/theme/md/theme_vars.inc.php @@ -79,10 +79,10 @@ $colorblind_deuteranopes_textWarning = $textWarning; // currently not tested wit // Badges colors $badgePrimary = '#007bff'; $badgeSecondary = '#999999'; +$badgeInfo = '#17a2b8'; $badgeSuccess = '#28a745'; $badgeWarning = '#a37c0d'; // See $textWarning $badgeDanger = '#8c4446'; // See $textDanger -$badgeInfo = '#17a2b8'; $badgeDark = '#343a40'; $badgeLight = '#f8f9fa'; @@ -96,11 +96,13 @@ $colorblind_deuteranopes_badgeDanger = $badgeDanger; // currently not tested * So this badges status uses default value according to theme eldy status img * TODO: use color definition vars above for define badges color status X -> exemple $badgeStatusValidate, $badgeStatusClosed, $badgeStatusActive .... */ -$badgeStatus0 = '#cbd3d3'; -$badgeStatus1 = '#bc9526'; -$badgeStatus2 = '#e6f0f0'; +$badgeStatus0 = '#cbd3d3'; // draft +$badgeStatus1 = '#bc9526'; // validated +$badgeStatus1b = '#bc9526'; // validated +$badgeStatus2 = '#e6f0f0'; // approved $badgeStatus3 = '#bca52b'; -$badgeStatus4 = '#25a580'; +$badgeStatus4 = '#25a580'; // Color ok +$badgeStatus4b = '#25a580'; // Color ok $badgeStatus5 = '#cad2d2'; $badgeStatus6 = '#cad2d2'; $badgeStatus7 = '#277d1e'; From 071042b449b93567adb885c8dffb3092fab9b229 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Nov 2021 22:28:35 +0100 Subject: [PATCH 177/195] Code comment --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 33db393bbc6..a8986475095 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -127,7 +127,7 @@ class CMailFile * @param array $filename_list List of files to attach (full path of filename on file system) * @param array $mimetype_list List of MIME type of attached files * @param array $mimefilename_list List of attached file name in message - * @param string $addr_cc Email cc + * @param string $addr_cc Email cc (Example: 'abc@def.com, ghk@lmn.com') * @param string $addr_bcc Email bcc (Note: This is autocompleted with MAIN_MAIL_AUTOCOPY_TO if defined) * @param int $deliveryreceipt Ask a delivery receipt * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown make autodetection (with fast mode, not reliable) From c79fa4d3d038090f57c8186afcbb8229cb82ee3c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Nov 2021 23:03:12 +0100 Subject: [PATCH 178/195] NEW Add workflow action close purchase order on reception validation NEW Add workflow action close purchase order on reception closing --- htdocs/admin/workflow.php | 22 +++++- htdocs/core/modules/modWorkflow.class.php | 6 +- ...e_20_modWorkflow_WorkflowManager.class.php | 72 ++++++++++++++++++- htdocs/langs/en_US/workflow.lang | 6 +- 4 files changed, 99 insertions(+), 7 deletions(-) diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index ada5a6e0b3b..a58c3378ecd 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -123,9 +123,25 @@ $workflowcodes = array( ), // Automatic classification supplier order + 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION'=>array( + 'family'=>'classify_supplier_order', + 'position'=>63, + 'enabled'=>(!empty($conf->global->MAIN_FEATURES_LEVEL) && (!empty($conf->reception->enabled)) && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || empty($conf->supplier_order->enabled))), + 'picto'=>'supplier_order', + 'warning'=>'' + ), + + 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED'=>array( + 'family'=>'classify_supplier_order', + 'position'=>64, + 'enabled'=>(!empty($conf->global->MAIN_FEATURES_LEVEL) && (!empty($conf->reception->enabled)) && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || empty($conf->supplier_order->enabled))), + 'picto'=>'supplier_order', + 'warning'=>'' + ), + 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER'=>array( 'family'=>'classify_supplier_order', - 'position'=>62, + 'position'=>65, 'enabled'=>((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)), 'picto'=>'supplier_order', 'warning'=>'' @@ -134,7 +150,7 @@ $workflowcodes = array( // Automatic classification reception 'WORKFLOW_BILL_ON_RECEPTION'=>array( 'family'=>'classify_reception', - 'position'=>64, + 'position'=>80, 'enabled'=>(!empty($conf->reception->enabled) && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled))), 'picto'=>'reception' ), @@ -142,7 +158,7 @@ $workflowcodes = array( // Automatic classification shipping 'WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE' => array( 'family' => 'classify_shipping', - 'position' => 66, + 'position' => 90, 'enabled' => ! empty($conf->expedition->enabled) && ! empty($conf->facture->enabled), 'picto' => 'shipment' ) diff --git a/htdocs/core/modules/modWorkflow.class.php b/htdocs/core/modules/modWorkflow.class.php index eaaf15d40a1..4122f347664 100644 --- a/htdocs/core/modules/modWorkflow.class.php +++ b/htdocs/core/modules/modWorkflow.class.php @@ -90,8 +90,10 @@ class modWorkflow extends DolibarrModules 3=>array('WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED', 0, 'current', 0), 4=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER', 0, 'current', 0), 5=>array('WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL', 0, 'current', 0), - 6=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 0, 'current', 0), - 7=>array('WORKFLOW_BILL_ON_RECEPTION', 'chaine', '1', 'WORKFLOW_BILL_ON_RECEPTION', 0, 'current', 0) + 6=>array('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION', 0, 'current', 0), + 7=>array('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED', 0, 'current', 0), + 8=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 0, 'current', 0), + 9=>array('WORKFLOW_BILL_ON_RECEPTION', 'chaine', '1', 'WORKFLOW_BILL_ON_RECEPTION', 0, 'current', 0) ); // Boxes diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index c45ce9d2406..048dc170c0a 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -188,7 +188,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers return $ret; } - // classify billed order & billed propososal + // classify billed order & billed proposal if ($action == 'BILL_SUPPLIER_VALIDATE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); @@ -286,6 +286,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } + // If we validate or close a shipment if (($action == 'SHIPPING_VALIDATE') || ($action == 'SHIPPING_CLOSED')) { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); @@ -354,6 +355,75 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } + // If we validate or close a shipment + if (($action == 'RECEPTION_VALIDATE') || ($action == 'RECEPTION_CLOSED')) { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + + if ((!empty($conf->fournisseur->enabled) || !empty($conf->supplier_order->enabled)) && !empty($conf->reception->enabled) && !empty($conf->workflow->enabled) && + ( + (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION) && ($action == 'RECEPTION_VALIDATE')) || + (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED) && ($action == 'RECEPTION_CLOSED')) + ) + ) { + $qtyshipped = array(); + $qtyordred = array(); + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; + + // Find all reception on purchase order origin + $order = new CommandeFournisseur($this->db); + $ret = $order->fetch($object->origin_id); + if ($ret < 0) { + $this->error = $order->error; + $this->errors = $order->errors; + return $ret; + } + $ret = $order->fetchObjectLinked($order->id, 'supplier_order', null, 'reception'); + if ($ret < 0) { + $this->error = $order->error; + $this->errors = $order->errors; + return $ret; + } + //Build array of quantity received by product for a purchase order + if (is_array($order->linkedObjects) && count($order->linkedObjects) > 0) { + foreach ($order->linkedObjects as $type => $shipping_array) { + if ($type == 'reception' && is_array($shipping_array) && count($shipping_array) > 0) { + foreach ($shipping_array as $shipping) { + if (is_array($shipping->lines) && count($shipping->lines) > 0) { + foreach ($shipping->lines as $shippingline) { + $qtyshipped[$shippingline->fk_product] += $shippingline->qty; + } + } + } + } + } + } + + //Build array of quantity ordered to be received + if (is_array($order->lines) && count($order->lines) > 0) { + foreach ($order->lines as $orderline) { + // Exclude lines not qualified for shipment, similar code is found into calcAndSetStatusDispatch() for vendors + if (empty($conf->global->STOCK_SUPPORTS_SERVICES) && $orderline->product_type > 0) { + continue; + } + $qtyordred[$orderline->fk_product] += $orderline->qty; + } + } + //dol_syslog(var_export($qtyordred,true),LOG_DEBUG); + //dol_syslog(var_export($qtyshipped,true),LOG_DEBUG); + //Compare array + $diff_array = array_diff_assoc($qtyordred, $qtyshipped); + if (count($diff_array) == 0) { + //No diff => mean everythings is received + $ret = $order->setStatut(CommandeFournisseur::STATUS_RECEIVED_COMPLETELY, $object->origin_id, $object->origin, 'SUPPLIER_ORDER_CLOSE'); + if ($ret < 0) { + $this->error = $order->error; + $this->errors = $order->errors; + return $ret; + } + } + } + } + return 0; } diff --git a/htdocs/langs/en_US/workflow.lang b/htdocs/langs/en_US/workflow.lang index fafbc6e8d8a..b65f8449fef 100644 --- a/htdocs/langs/en_US/workflow.lang +++ b/htdocs/langs/en_US/workflow.lang @@ -14,9 +14,13 @@ descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source sales o descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source sales order as billed when customer invoice is set to paid (and if the amount of the invoice is the same as the total amount of the linked order) descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source sales order as shipped when a shipment is validated (and if the quantity shipped by all shipments is the same as in the order to update) descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED=Classify linked source sales order as shipped when a shipment is closed (and if the quantity shipped by all shipments is the same as in the order to update) -# Autoclassify purchase order +# Autoclassify purchase proposal descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source vendor proposal as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked proposal) +# Autoclassify purchase order descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source purchase order as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order) +descWORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION=Classify linked source purchase order as received when a reception is validated (and if the quantity received by all receptions is the same as in the purchase order to update) +descWORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED=Classify linked source purchase order as received when a reception is closed (and if the quantity received by all rceptions is the same as in the purchase order to update) +# Autoclassify purchase invoice descWORKFLOW_BILL_ON_RECEPTION=Classify receptions to "billed" when a linked supplier order is validated # Autoclose intervention descWORKFLOW_TICKET_CLOSE_INTERVENTION=Close all interventions linked to the ticket when a ticket is closed From 749ea1a92289c0e7752febc5c3b0f51cbf92fd68 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Nov 2021 23:21:44 +0100 Subject: [PATCH 179/195] Trans --- htdocs/langs/en_US/receptions.lang | 9 +++++++-- htdocs/langs/en_US/stocks.lang | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/htdocs/langs/en_US/receptions.lang b/htdocs/langs/en_US/receptions.lang index 46b2d689609..d9e8bdeebb7 100644 --- a/htdocs/langs/en_US/receptions.lang +++ b/htdocs/langs/en_US/receptions.lang @@ -23,7 +23,9 @@ ReceptionsAndReceivingForSameOrder=Receptions and receipts for this order ReceptionsToValidate=Receptions to validate StatusReceptionCanceled=Canceled StatusReceptionDraft=Draft -StatusReceptionValidated=Validated (products to ship or already shipped) +StatusReceptionValidated=Validated (products to receive or already received) +StatusReceptionValidatedToReceive=Validated (products to receive) +StatusReceptionValidatedReceived=Validated (products received) StatusReceptionProcessed=Processed StatusReceptionDraftShort=Draft StatusReceptionValidatedShort=Validated @@ -36,7 +38,7 @@ StatsOnReceptionsOnlyValidated=Statistics conducted on receptions only validated SendReceptionByEMail=Send reception by email SendReceptionRef=Submission of reception %s ActionsOnReception=Events on reception -ReceptionCreationIsDoneFromOrder=For the moment, creation of a new reception is done from the Purchase Order record. +ReceptionCreationIsDoneFromOrder=For the moment, creation of a new reception is done from the Purchase Order. ReceptionLine=Reception line ProductQtyInReceptionAlreadySent=Product quantity from open sales order already sent ProductQtyInSuppliersReceptionAlreadyRecevied=Product quantity from open supplier order already received @@ -46,3 +48,6 @@ ReceptionsReceiptModel=Document templates for receptions NoMorePredefinedProductToDispatch=No more predefined products to dispatch ReceptionExist=A reception exists ByingPrice=Bying price +ReceptionBackToDraftInDolibarr=Reception %s back to draft +ReceptionClassifyClosedInDolibarr=Reception %s classified Closed +ReceptionUnClassifyCloseddInDolibarr=Reception %s re-open \ No newline at end of file diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 2fa24d467ca..0110943b000 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -178,6 +178,7 @@ ProductStockWarehouseDeleted=Stock limit for alert and desired optimal stock cor AddNewProductStockWarehouse=Set new limit for alert and desired optimal stock AddStockLocationLine=Decrease quantity then click to add another warehouse for this product InventoryDate=Inventory date +Inventories=Inventories NewInventory=New inventory inventorySetup = Inventory Setup inventoryCreatePermission=Create new inventory @@ -206,8 +207,8 @@ INVENTORY_USE_INVENTORY_DATE_FOR_DATE_OF_MVT=Stock movements will have the date inventoryChangePMPPermission=Allow to change PMP value for a product ColumnNewPMP=New unit PMP OnlyProdsInStock=Do not add product without stock -TheoricalQty=Theorique qty -TheoricalValue=Theorique qty +TheoricalQty=Theorical qty +TheoricalValue=Theorical qty LastPA=Last BP CurrentPA=Curent BP RecordedQty=Recorded Qty From 59de1403668fb6110d6b452d493ed5481515df57 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 19 Nov 2021 23:39:25 +0100 Subject: [PATCH 180/195] css --- htdocs/core/tpl/contacts.tpl.php | 12 ++++++------ htdocs/theme/eldy/global.inc.php | 2 ++ htdocs/theme/md/style.css.php | 6 +++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index 3def83f4e0d..2dd9751a4c6 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -111,17 +111,17 @@ if ($permission) {
    global->MAIN_INFO_SOCIETE_NOM; ?>
    -
    select_dolusers($user->id, 'userid', 0, (!empty($userAlreadySelected) ? $userAlreadySelected : null), 0, null, null, 0, 56, '', 0, '', 'minwidth200imp'); ?>
    +
    select_dolusers($user->id, 'userid', 0, (!empty($userAlreadySelected) ? $userAlreadySelected : null), 0, null, null, 0, 56, 0, '', 0, '', 'minwidth100imp widthcentpercentminusxx maxwidth400'); ?>
    element == 'shipping' || $object->element == 'reception') && is_object($objectsrc)) { $tmpobject = $objectsrc; } - $formcompany->selectTypeContact($tmpobject, '', 'type', 'internal'); + $formcompany->selectTypeContact($tmpobject, '', 'type', 'internal', 'position', 0, 'minwidth125imp widthcentpercentminusx maxwidth400'); ?>
     
    -
    ">
    +
    ">
    element == 'shipping' || $object->element == 'reception') && is_object($objectsrc)) { $tmpobject = $objectsrc; } - $formcompany->selectTypeContact($tmpobject, $preselectedtypeofcontact, 'typecontact', 'external', 'position', 0, 'minwidth100imp'); + $formcompany->selectTypeContact($tmpobject, $preselectedtypeofcontact, 'typecontact', 'external', 'position', 0, 'minwidth125imp widthcentpercentminusx maxwidth400'); ?>
     
    - "trans("Add"); ?>"> + } ?>>
    diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 348ba82d9d9..a4b2c8e7dcb 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1455,6 +1455,7 @@ table[summary="list_of_modules"] .fa-cog { .minwidth50imp { min-width: 50px !important; } .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } + .minwidth125imp { min-width: 125px !important; } .minwidth150imp { min-width: 150px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth250imp { min-width: 250px !important; } @@ -1474,6 +1475,7 @@ table[summary="list_of_modules"] .fa-cog { .minwidth50imp { min-width: 50px !important; } .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } + .minwidth125imp { min-width: 125px !important; } .minwidth150imp { min-width: 110px !important; } .minwidth200imp { min-width: 110px !important; } .minwidth250imp { min-width: 115px !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index a2d912d46e6..26fb295e751 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1455,6 +1455,7 @@ tr.nobottom td { .minwidth50imp { min-width: 50px !important; } .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } + .minwidth125imp { min-width: 125px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth250imp { min-width: 250px !important; } .minwidth300imp { min-width: 300px !important; } @@ -1514,6 +1515,7 @@ tr.nobottom td { .minwidth50imp { min-width: 50px !important; } .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } + .minwidth125imp { min-width: 125px !important; } .minwidth150imp { min-width: 150px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth250imp { min-width: 250px !important; } @@ -1533,6 +1535,7 @@ tr.nobottom td { .minwidth50imp { min-width: 50px !important; } .minwidth75imp { min-width: 70px !important; } .minwidth100imp { min-width: 100px !important; } + .minwidth125imp { min-width: 125px !important; } .minwidth150imp { min-width: 110px !important; } .minwidth200imp { min-width: 110px !important; } .minwidth250imp { min-width: 115px !important; } @@ -1679,6 +1682,7 @@ select.widthcentpercentminusxx, span.widthcentpercentminusxx:not(.select2-select .minwidth50imp { min-width: 50px !important; } .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } + .minwidth125imp { min-width: 125px !important; } .minwidth150imp { min-width: 110px !important; } .minwidth200imp { min-width: 110px !important; } .minwidth250imp { min-width: 115px !important; } @@ -3459,7 +3463,7 @@ div.colorback border-left: 1px solid #ccc; } table.liste, table.noborder, table.formdoc, div.noborder { - width: calc(100% - 1px); /* -1 to fix a bug. Without, a scroll appears due to overflow-x: auto; of div-table-responsive */ + width: calc(100% - 2px); /* -2 to fix a bug. Without, a scroll appears due to overflow-x: auto; of div-table-responsive */ border-collapse: separate !important; border-spacing: 0px; From 001507f54e425aa1896d27c6b7f4cfd21ab4e772 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 20 Nov 2021 14:24:51 +0100 Subject: [PATCH 181/195] Fix css on disabled menu --- htdocs/core/menus/standard/eldy.lib.php | 6 +++++- htdocs/theme/eldy/global.inc.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 32dc909f2e2..9dc1781f2d3 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -2104,7 +2104,11 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM print '
    '."\n"; $lastlevel0 = 'enabled'; } elseif ($showmenu) { // Not enabled but visible (so greyed) - print ''."\n"; + print ''."\n"; $lastlevel0 = 'greyed'; } else { $lastlevel0 = 'hidden'; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index a4b2c8e7dcb..bfe92bd5fe9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -2872,7 +2872,7 @@ input.vmenusearchselectcombo[type=text] { a.vmenu:link, a.vmenu:visited, a.vmenu:hover, a.vmenu:active, span.vmenu, span.vsmenu { white-space: nowrap; font-family: ; text-align: ; } a.vmenu:link, a.vmenu:visited, a.vmenu:hover, a.vmenu:active, span.vmenu, span.vmenu:link, span.vmenu:visited, span.vmenu:hover, span.vmenu:active { font-weight: bold; } /* bold = 600, 500 is ko with Edge on 1200x960 */ -font.vmenudisabled { font-family: ; text-align: ; font-weight: bold; color: #aaa; margin-left: 4px; white-space: nowrap; } /* bold = 600, 500 is ko with Edge on 1200x960 */ +span.vmenudisabled, font.vmenudisabled { font-family: ; text-align: ; font-weight: bold; color: #aaa; margin-left: 4px; white-space: nowrap; } /* bold = 600, 500 is ko with Edge on 1200x960 */ a.vmenu:link, a.vmenu:visited { color: var(--colortextbackvmenu); } a.vsmenu:link, a.vsmenu:visited, a.vsmenu:hover, a.vsmenu:active, span.vsmenu { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 26fb295e751..e499319a722 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2924,7 +2924,7 @@ div.vmenu, td.vmenu { .searchform .bordertransp { border: 0; } a.vmenu:link, a.vmenu:visited, a.vmenu:hover, a.vmenu:active, span.vmenu, span.vsmenu { white-space: nowrap; font-size:px; font-family: ; text-align: ; font-weight: bold; } -font.vmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: bold; color: #aaa; margin-left: 4px; white-space: nowrap; } +span.vmenudisabled, font.vmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: bold; color: #aaa; margin-left: 4px; white-space: nowrap; } a.vmenu:link, a.vmenu:visited { color: #; } a.vsmenu:link, a.vsmenu:visited, a.vsmenu:hover, a.vsmenu:active, span.vsmenu { font-size:px; font-family: ; text-align: ; font-weight: normal; color: #202020; margin: 1px 1px 1px 8px; } From 63cd06394f39d60784d6e6a0ccf4867a71a6568f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 20 Nov 2021 15:41:31 +0100 Subject: [PATCH 182/195] Debug permission on supplier order. Fix #huntr58ddbd8a-0faf-4b3f-aec9-5850bb19ab67 --- htdocs/core/menus/standard/eldy.lib.php | 3 +- .../class/fournisseur.commande.class.php | 9 ++- htdocs/fourn/commande/card.php | 9 ++- htdocs/fourn/commande/dispatch.php | 49 +++++++++++----- htdocs/reception/card.php | 57 +++++++++++-------- htdocs/theme/eldy/global.inc.php | 4 +- htdocs/theme/md/style.css.php | 4 +- htdocs/user/perms.php | 13 +++++ 8 files changed, 101 insertions(+), 47 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 9dc1781f2d3..07ecf19de63 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -2149,7 +2149,8 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM // Not enabled but visible (so greyed), except if parent was not enabled. print ''."\n"; + print ''.$menu_array[$i]['titre'].'
    '; + print '
    '."\n"; } } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 15d93bfae2c..9b68ef199db 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2295,7 +2295,14 @@ class CommandeFournisseur extends CommonOrder dol_syslog(get_class($this)."::Livraison"); - if ($user->rights->fournisseur->commande->receptionner) { + $usercanreceive = 0; + if (empty($conf->reception->enabled)) { + $usercanreceive = $user->rights->fournisseur->commande->receptionner; + } else { + $usercanreceive = $user->rights->reception->creer; + } + + if ($usercanreceive) { // Define the new status if ($type == 'par') { $statut = self::STATUS_RECEIVED_PARTIALLY; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 8f6ed82160e..92501d57d1d 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -90,7 +90,6 @@ $datelivraison = dol_mktime(GETPOST('liv_hour', 'int'), GETPOST('liv_min', 'int' if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('ordersuppliercard', 'globalcard')); @@ -124,6 +123,8 @@ if ($id > 0 || !empty($ref)) { } } +$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); + // Common permissions $usercanread = ($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->lire); $usercancreate = ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer); @@ -136,7 +137,11 @@ $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($us $usercanapprove = $user->rights->fournisseur->commande->approuver; $usercanapprovesecond = $user->rights->fournisseur->commande->approve2; $usercanorder = $user->rights->fournisseur->commande->commander; -$usercanreceived = $user->rights->fournisseur->commande->receptionner; +if (empty($conf->reception->enabled)) { + $usercanreceive = $user->rights->fournisseur->commande->receptionner; +} else { + $usercanreceive = $user->rights->reception->creer; +} // Permissions for includes $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 547abd33b4b..311cbd5f022 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -62,11 +62,6 @@ $confirm = GETPOST('confirm', 'alpha'); if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); - -if (empty($conf->stock->enabled)) { - accessforbidden(); -} $hookmanager->initHooks(array('ordersupplierdispatch')); @@ -89,6 +84,21 @@ if ($id > 0 || !empty($ref)) { } } +if (empty($conf->reception->enabled)) { + $permissiontoreceive = $user->rights->fournisseur->commande->receptionner; + $permissiontocontrol = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande_advance->check))); +} else { + $permissiontoreceive = $user->rights->reception->creer; + $permissiontocontrol = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->reception_advance->validate))); +} + +// $id is id of a purchase order. +$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); + +if (empty($conf->stock->enabled)) { + accessforbidden(); +} + /* * Actions @@ -100,7 +110,7 @@ if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } -if ($action == 'checkdispatchline' && !((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) { +if ($action == 'checkdispatchline' && $permissiontocontrol) { $error = 0; $supplierorderdispatch = new CommandeFournisseurDispatch($db); @@ -137,7 +147,7 @@ if ($action == 'checkdispatchline' && !((empty($conf->global->MAIN_USE_ADVANCED_ } } -if ($action == 'uncheckdispatchline' && !((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) { +if ($action == 'uncheckdispatchline' && $permissiontocontrol) { $error = 0; $supplierorderdispatch = new CommandeFournisseurDispatch($db); @@ -173,7 +183,7 @@ if ($action == 'uncheckdispatchline' && !((empty($conf->global->MAIN_USE_ADVANCE } } -if ($action == 'denydispatchline' && !((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) { +if ($action == 'denydispatchline' && $permissiontocontrol) { $error = 0; $supplierorderdispatch = new CommandeFournisseurDispatch($db); @@ -209,7 +219,7 @@ if ($action == 'denydispatchline' && !((empty($conf->global->MAIN_USE_ADVANCED_P } } -if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) { +if ($action == 'dispatch' && $permissiontoreceive) { $error = 0; $db->begin(); @@ -387,7 +397,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) } // Remove a dispatched line -if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->fournisseur->commande->receptionner) { +if ($action == 'confirm_deleteline' && $confirm == 'yes' && $permissiontoreceive) { $db->begin(); $supplierorderdispatch = new CommandeFournisseurDispatch($db); @@ -430,7 +440,7 @@ if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->fourn } // Update a dispatched line -if ($action == 'updateline' && $user->rights->fournisseur->commande->receptionner) { +if ($action == 'updateline' && $permissiontoreceive) { $db->begin(); $error = 0; @@ -751,9 +761,9 @@ if ($id > 0 || !empty($ref)) { // Select warehouse to force it everywhere if (count($listwarehouses) > 1) { - print '
    '.$langs->trans("ForceTo").' '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 1, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1); + print '
    '.$langs->trans("ForceTo").' '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 1, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1); } elseif (count($listwarehouses) == 1) { - print '
    '.$langs->trans("ForceTo").' '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1); + print '
    '.$langs->trans("ForceTo").' '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1); } print ''; @@ -1055,10 +1065,19 @@ if ($id > 0 || !empty($ref)) { $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive") : $langs->trans("CreateReception"); - print '
    '; + print ''; } print '
    '; @@ -1257,7 +1276,7 @@ if ($id > 0 || !empty($ref)) { // Add button to check/uncheck disaptching print ''; - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check))) { + if (!$permissiontocontrol) { if (empty($objp->status)) { print ''.$langs->trans("Approve").''; print ''.$langs->trans("Deny").''; diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 9f326e8d36b..f84b8bd4d6c 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -112,9 +112,6 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('receptioncard', 'globalcard')); -$permissiondellink = $user->rights->reception->creer; // Used by the include of actions_dellink.inc.php -//var_dump($object->lines[0]->detail_batch); - $date_delivery = dol_mktime(GETPOST('date_deliveryhour', 'int'), GETPOST('date_deliverymin', 'int'), 0, GETPOST('date_deliverymonth', 'int'), GETPOST('date_deliveryday', 'int'), GETPOST('date_deliveryyear', 'int')); if ($id > 0 || !empty($ref)) { @@ -142,9 +139,10 @@ if ($user->socid) { $socid = $user->socid; } -if ($origin == 'reception') { +if (!empty($conf->reception->enabled) || $origin == 'reception' || empty($origin)) { $result = restrictedArea($user, 'reception', $id); } else { + // We do not use the reception module, so we test permission on the supplier orders if ($origin == 'supplierorder' || $origin == 'order_supplier') { $result = restrictedArea($user, 'fournisseur', $origin_id, 'commande_fournisseur', 'commande'); } elseif (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) { @@ -152,6 +150,20 @@ if ($origin == 'reception') { } } +if (!empty($conf->reception->enabled)) { + $permissiontoread = $user->rights->reception->lire; + $permissiontoadd = $user->rights->reception->creer; + $permissiondellink = $user->rights->reception->creer; // Used by the include of actions_dellink.inc.php + $permissiontovalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->reception_advance->validate))); + $permissiontodelete = $user->rights->reception->supprimer; +} else { + $permissiontoread = $user->rights->fournisseur->commande->receptionner; + $permissiontoadd = $user->rights->fournisseur->commande->receptionner; + $permissiondellink = $user->rights->fournisseur->commande->receptionner; // Used by the include of actions_dellink.inc.php + $permissiontovalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande_advance->check))); + $permissiontodelete = $user->rights->fournisseur->commande->receptionner; +} + /* * Actions @@ -171,12 +183,12 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once // Reopen - if ($action == 'reopen' && $user->rights->reception->creer) { + if ($action == 'reopen' && $permissiontoadd) { $result = $object->reOpen(); } // Confirm back to draft status - if ($action == 'modif' && $user->rights->reception->creer) { + if ($action == 'modif' && $permissiontoadd) { $result = $object->setDraft($user); if ($result >= 0) { // Define output language @@ -201,11 +213,11 @@ if (empty($reshook)) { } // Set incoterm - if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) { + if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled) && $permissiontoadd) { $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); } - if ($action == 'setref_supplier') { + if ($action == 'setref_supplier' && $permissiontoadd) { if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } @@ -220,7 +232,7 @@ if (empty($reshook)) { } } - if ($action == 'update_extras') { + if ($action == 'update_extras' && $permissiontoadd) { $object->oldcopy = dol_clone($object); // Fill array 'array_options' with data from update form @@ -244,7 +256,7 @@ if (empty($reshook)) { } // Create reception - if ($action == 'add' && $user->rights->reception->creer) { + if ($action == 'add' && $permissiontoadd) { $error = 0; $predef = ''; @@ -405,10 +417,7 @@ if (empty($reshook)) { $_GET["commande_id"] = GETPOST('commande_id', 'int'); $action = 'create'; } - } elseif ($action == 'confirm_valid' && $confirm == 'yes' && - ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->creer)) - || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->reception_advance->validate))) - ) { + } elseif ($action == 'confirm_valid' && $confirm == 'yes' && $permissiontovalidate) { $object->fetch_thirdparty(); $result = $object->valid($user); @@ -440,7 +449,7 @@ if (empty($reshook)) { } } } - } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->reception->supprimer) { + } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) { $result = $object->delete($user); if ($result > 0) { header("Location: ".DOL_URL_ROOT.'/reception/index.php'); @@ -455,7 +464,7 @@ if (empty($reshook)) { if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); }*/ - } elseif ($action == 'setdate_livraison' && $user->rights->reception->creer) { + } elseif ($action == 'setdate_livraison' && $permissiontoadd) { //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; $datedelivery = dol_mktime(GETPOST('liv_hour', 'int'), GETPOST('liv_min', 'int'), 0, GETPOST('liv_month', 'int'), GETPOST('liv_day', 'int'), GETPOST('liv_year', 'int')); @@ -506,7 +515,7 @@ if (empty($reshook)) { } $action = ""; - } elseif ($action == 'builddoc') { + } elseif ($action == 'builddoc' && $permissiontoread) { // Build document // En get ou en post // Save last template used to generate document @@ -532,7 +541,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); $action = ''; } - } elseif ($action == 'remove_file') { + } elseif ($action == 'remove_file' && $permissiontoadd) { // Delete file in doc form require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -550,13 +559,13 @@ if (empty($reshook)) { header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); exit(); } - } elseif ($action == 'classifyclosed') { + } elseif ($action == 'classifyclosed' && $permissiontoread) { $result = $object->setClosed(); if ($result >= 0) { header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); exit(); } - } elseif ($action == 'deleteline' && !empty($line_id)) { + } elseif ($action == 'deleteline' && !empty($line_id) && $permissiontoread) { // delete a line $lines = $object->lines; $line = new CommandeFournisseurDispatch($db); @@ -579,7 +588,7 @@ if (empty($reshook)) { } else { setEventMessages($line->error, $line->errors, 'errors'); } - } elseif ($action == 'updateline' && $user->rights->reception->creer && GETPOST('save')) { + } elseif ($action == 'updateline' && GETPOST('save') && $permissiontoadd) { // Update a line // Clean parameters $qty = 0; @@ -666,11 +675,11 @@ if (empty($reshook)) { $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } } else { - header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // Pour reaffichage de la fiche en cours d'edition + header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit exit(); } - } elseif ($action == 'updateline' && $user->rights->reception->creer && GETPOST('cancel', 'alpha') == $langs->trans("Cancel")) { - header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // Pour reaffichage de la fiche en cours d'edition + } elseif ($action == 'updateline' && $permissiontoadd && GETPOST('cancel', 'alpha') == $langs->trans("Cancel")) { + header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit exit(); } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index bfe92bd5fe9..218d2a20be0 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -2881,12 +2881,12 @@ a.vsmenu:link, a.vsmenu:visited, a.vsmenu:hover, a.vsmenu:active, span.vsmenu { color: #202020; margin: 1px 1px 1px 6px; } -font.vsmenudisabled { font-family: ; text-align: ; color: #aaa; } +span.vsmenudisabled, font.vsmenudisabled { font-family: ; text-align: ; color: #aaa; } a.vsmenu:link, a.vsmenu:visited { color: var(--colortextbackvmenu); white-space: nowrap; } -font.vsmenudisabledmargin { margin: 1px 1px 1px 6px; } +span.vsmenudisabledmargin, font.vsmenudisabledmargin { margin: 1px 1px 1px 6px; } li a.vsmenudisabled, li.vsmenudisabled { color: #aaa !important; } a.help:link, a.help:visited, a.help:hover, a.help:active, span.help { text-align: ; color: #aaa; text-decoration: none; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index e499319a722..c39bf34d74a 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2928,9 +2928,9 @@ span.vmenudisabled, font.vmenudisabled { font-size:px; a.vmenu:link, a.vmenu:visited { color: #; } a.vsmenu:link, a.vsmenu:visited, a.vsmenu:hover, a.vsmenu:active, span.vsmenu { font-size:px; font-family: ; text-align: ; font-weight: normal; color: #202020; margin: 1px 1px 1px 8px; } -font.vsmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: normal; color: #aaa; } +span.vsmenudisabled, font.vsmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: normal; color: #aaa; } a.vsmenu:link, a.vsmenu:visited { color: #; white-space: nowrap; } -font.vsmenudisabledmargin { margin: 1px 1px 1px 8px; } +span.vsmenudisabledmargin, font.vsmenudisabledmargin { margin: 1px 1px 1px 8px; } a.help:link, a.help:visited, a.help:hover, a.help:active, span.help { text-align: ; font-weight: normal; color: #999; text-decoration: none; } diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php index d3ba33a5acf..4571ed48884 100644 --- a/htdocs/user/perms.php +++ b/htdocs/user/perms.php @@ -317,6 +317,19 @@ if ($result) { continue; } + // Special cases + if (!empty($conf->reception->enabled)) { + // The 2 permission in fournisseur modules has been replaced by permissions into reception module + if ($obj->module == 'fournisseur' && $obj->perms == 'commande' && $obj->subperms == 'receptionner') { + $i++; + continue; + } + if ($obj->module == 'fournisseur' && $obj->perms == 'commande_advance' && $obj->subperms == 'check') { + $i++; + continue; + } + } + $objMod = $modules[$obj->module]; // Save field module_position in database if value is wrong From fcf86d5a02ddf9eee967b387fcb530180cf99727 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 20 Nov 2021 16:02:57 +0100 Subject: [PATCH 183/195] Trans --- htdocs/langs/en_US/bills.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 3aaa5465ca0..930a6489b83 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -604,3 +604,4 @@ SituationTotalProgress=Total progress %d %% SearchUnpaidInvoicesWithDueDate=Search unpaid invoices with a due date = %s NoPaymentAvailable=No payment available for %s PaymentRegisteredAndInvoiceSetToPaid=Payment registered and invoice %s set to paid +SendEmailsRemindersOnInvoiceDueDate=Send reminder by email for unpaid invoices From c2175bc215e4260e9ab33484146fb0fbe5605006 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 20 Nov 2021 16:10:55 +0100 Subject: [PATCH 184/195] Fix trans --- htdocs/cron/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index 270fe3f57c4..2a808b9a692 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -34,7 +34,7 @@ require_once DOL_DOCUMENT_ROOT."/core/class/html.formcron.class.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/cron.lib.php'; // Load translation files required by the page -$langs->loadLangs(array('admin', 'cron', 'members')); +$langs->loadLangs(array('admin', 'cron', 'members', 'bills')); $id = GETPOST('id', 'int'); $action = GETPOST('action', 'aZ09'); From 441af6b6fbeb0e937c1d40585b0f7d653f2b5ced Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Nov 2021 02:35:55 +0100 Subject: [PATCH 185/195] Fix add rel="noopener noreferrer" --- htdocs/accountancy/admin/accountmodel.php | 2 +- htdocs/accountancy/admin/categories_list.php | 2 +- htdocs/accountancy/admin/journals_list.php | 2 +- htdocs/adherents/admin/website.php | 2 +- htdocs/admin/agenda_xcal.php | 6 ++-- htdocs/admin/dav.php | 8 ++--- .../admin/dolistore/class/dolistore.class.php | 8 ++--- htdocs/admin/geoipmaxmind.php | 4 +-- htdocs/admin/mails_templates.php | 2 +- htdocs/admin/modulehelp.php | 2 +- htdocs/admin/modules.php | 10 +++--- htdocs/admin/multicurrency.php | 2 +- htdocs/admin/system/about.php | 34 +++++++++---------- htdocs/admin/system/dolibarr.php | 4 +-- htdocs/admin/ticket_public.php | 2 +- htdocs/admin/tools/update.php | 4 +-- htdocs/admin/translation.php | 2 +- htdocs/admin/website.php | 2 +- htdocs/api/admin/index.php | 4 +-- htdocs/bookmarks/bookmarks.lib.php | 4 +-- htdocs/bookmarks/card.php | 2 +- htdocs/categories/photos.php | 6 ++-- htdocs/comm/action/rapport/index.php | 5 +-- htdocs/comm/mailing/card.php | 4 +-- htdocs/compta/accounting-files.php | 2 +- .../compta/cashcontrol/cashcontrol_card.php | 8 ++--- htdocs/compta/facture/card.php | 2 +- htdocs/core/bookmarks_page.php | 2 +- htdocs/core/class/commonobject.class.php | 2 +- htdocs/core/class/html.formfile.class.php | 10 +++--- htdocs/core/get_info.php | 4 +-- htdocs/core/lib/cron.lib.php | 4 +-- htdocs/core/lib/doleditor.lib.php | 4 --- htdocs/core/lib/functions.lib.php | 8 ++--- htdocs/core/lib/payments.lib.php | 4 +-- htdocs/core/lib/signature.lib.php | 2 +- htdocs/core/lib/ticket.lib.php | 4 +-- htdocs/core/lib/usergroups.lib.php | 2 +- htdocs/core/lib/website.lib.php | 2 +- htdocs/core/lib/website2.lib.php | 2 +- htdocs/core/tpl/login.tpl.php | 4 +-- htdocs/core/tpl/passwordforgotten.tpl.php | 2 +- .../class/actions_datapolicy.class.php | 6 ++-- htdocs/datapolicy/class/datapolicy.class.php | 12 +++---- htdocs/datapolicy/langs/en_US/datapolicy.lang | 2 +- htdocs/datapolicy/langs/fr_FR/datapolicy.lang | 2 +- htdocs/datapolicy/langs/it_IT/datapolicy.lang | 2 +- .../conferenceorbooth_card.php | 2 +- .../conferenceorbooth_list.php | 6 ++-- .../conferenceorboothattendee_card.php | 6 ++-- .../conferenceorboothattendee_list.php | 8 ++--- htdocs/expedition/class/expedition.class.php | 2 +- htdocs/expensereport/card.php | 2 +- .../tpl/expensereport_linktofile.tpl.php | 4 +-- htdocs/imports/import.php | 12 +++---- htdocs/install/check.php | 2 +- htdocs/langs/en_US/admin.lang | 4 +-- htdocs/langs/en_US/companies.lang | 2 +- htdocs/langs/en_US/help.lang | 2 +- htdocs/langs/en_US/main.lang | 2 +- htdocs/langs/en_US/modulebuilder.lang | 2 +- htdocs/langs/en_US/oauth.lang | 4 +-- htdocs/langs/en_US/paybox.lang | 2 +- htdocs/langs/en_US/paypal.lang | 2 +- htdocs/langs/en_US/stripe.lang | 2 +- htdocs/langs/en_US/website.lang | 4 +-- htdocs/main.inc.php | 8 ++--- htdocs/modulebuilder/index.php | 10 +++--- htdocs/partnership/admin/website.php | 2 +- htdocs/paypal/admin/paypal.php | 2 +- htdocs/projet/admin/website.php | 2 +- htdocs/public/payment/newpayment.php | 4 +-- htdocs/public/test/test_csrf.php | 2 +- htdocs/reception/class/reception.class.php | 2 +- htdocs/recruitment/admin/public_interface.php | 2 +- .../recruitmentjobposition_card.php | 2 +- htdocs/societe/card.php | 6 ++-- htdocs/societe/class/societe.class.php | 2 +- htdocs/takepos/admin/bar.php | 8 ++--- htdocs/takepos/admin/other.php | 8 ++--- htdocs/takepos/admin/receipt.php | 2 +- htdocs/webservices/admin/index.php | 4 +-- 82 files changed, 171 insertions(+), 180 deletions(-) diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php index 97a460beaac..29c2b7d5510 100644 --- a/htdocs/accountancy/admin/accountmodel.php +++ b/htdocs/accountancy/admin/accountmodel.php @@ -495,7 +495,7 @@ if ($id) { if ($valuetoshow != '') { print ''; if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { - print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; + print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; } elseif (!empty($tabhelp[$id][$value])) { print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); } else { diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index d914b825b7f..bb629577ab6 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -520,7 +520,7 @@ if ($tabname[$id]) { if ($valuetoshow != '') { print ''; if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { - print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; + print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; } elseif (!empty($tabhelp[$id][$value])) { print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); } else { diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php index e60deef59a3..8af707c4626 100644 --- a/htdocs/accountancy/admin/journals_list.php +++ b/htdocs/accountancy/admin/journals_list.php @@ -453,7 +453,7 @@ if ($id) { if ($valuetoshow != '') { print ''; if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { - print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; + print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; } elseif (!empty($tabhelp[$id][$value])) { print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); } else { diff --git a/htdocs/adherents/admin/website.php b/htdocs/adherents/admin/website.php index f00fbb6b0de..cef6edec36e 100644 --- a/htdocs/adherents/admin/website.php +++ b/htdocs/adherents/admin/website.php @@ -265,7 +265,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) { print ''; print ajax_autoselect('publicurlmember'); } diff --git a/htdocs/admin/agenda_xcal.php b/htdocs/admin/agenda_xcal.php index f854649962c..0166769660a 100644 --- a/htdocs/admin/agenda_xcal.php +++ b/htdocs/admin/agenda_xcal.php @@ -159,7 +159,7 @@ $getentity = ($conf->entity > 1 ? "&entity=".$conf->entity : ""); // Show message $message = ''; -$urlvcal = ''; +$urlvcal = ''; $urlvcal .= $urlwithroot.'/public/agenda/agendaexport.php?format=vcal'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : 'KEYNOTDEFINED').''; $message .= img_picto('', 'globe').' '.str_replace('{url}', $urlvcal, ''.$langs->trans("WebCalUrlForVCalExport", 'vcal', '').''); $message .= ''; $message .= ajax_autoselect('onlinepaymenturl1'); $message .= '
    '; -$urlical = ''; +$urlical = ''; $urlical .= $urlwithroot.'/public/agenda/agendaexport.php?format=ical&type=event'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : 'KEYNOTDEFINED').''; $message .= img_picto('', 'globe').' '.str_replace('{url}', $urlical, ''.$langs->trans("WebCalUrlForVCalExport", 'ical/ics', '').''); $message .= ''; $message .= ajax_autoselect('onlinepaymenturl2'); $message .= '
    '; -$urlrss = ''; +$urlrss = ''; $urlrss .= $urlwithroot.'/public/agenda/agendaexport.php?format=rss'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : 'KEYNOTDEFINED').''; $message .= img_picto('', 'globe').' '.str_replace('{url}', $urlrss, ''.$langs->trans("WebCalUrlForVCalExport", 'rss', '').''); $message .= '