From 88a1eadfc7893084232dce9277e065fdcad5492e Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Wed, 20 Nov 2024 19:50:07 +0100 Subject: [PATCH 01/31] fix: php warning (#32020) * fix: php warning * fix php warning * fix php warning --- htdocs/admin/mails.php | 2 +- htdocs/comm/action/card.php | 4 ++-- htdocs/comm/action/peruser.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index ab8695e871bad..7808ff615d38f 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -511,7 +511,7 @@ function change_smtp_auth_method() { // SuperAdministrator access only if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) { - print $form->selectarray('MAIN_MAIL_SMTPS_OAUTH_SERVICE', $oauthservices, $conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE); + print $form->selectarray('MAIN_MAIL_SMTPS_OAUTH_SERVICE', $oauthservices, getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE')); } else { $text = $oauthservices[getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE')]; if (empty($text)) { diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index d37b799493c1c..30c71c6e01a8b 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1963,8 +1963,8 @@ function setdatefields() 'type' => 'user', //'transparency'=>$object->userassigned[$user->id]['transparency'], 'transparency' => $object->transparency, // Force transparency on ownerfrom event - 'answer_status' => $object->userassigned[$object->userownerid]['answer_status'], - 'mandatory' => $object->userassigned[$object->userownerid]['mandatory'] + 'answer_status' => (isset($object->userassigned[$object->userownerid]['answer_status']) ? $object->userassigned[$object->userownerid]['answer_status']: null), + 'mandatory' => (isset($object->userassigned[$object->userownerid]['mandatory']) ? $object->userassigned[$object->userownerid]['mandatory']:null) ); } if (!empty($object->userassigned)) { // Now concat assigned users diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 6abe480da9caa..56b758f64a606 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -1426,7 +1426,7 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & $tmpcontact->fetch($event->contact_id); $cachecontacts[$event->contact_id] = $tmpcontact; } - $cases2[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs); + $cases3[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs); } } if ($event->date_start_in_calendar < $c && $dateendtouse > $b2) { From 9f56bfe5b76171ba4f8452740fd0b9be76a6dc00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Cendrier?= <81741011+altairis-noe@users.noreply.github.com> Date: Wed, 20 Nov 2024 20:06:43 +0100 Subject: [PATCH 02/31] FIX: shipping date was not editable in view mode (#32022) --- htdocs/expedition/card.php | 14 +++++++--- htdocs/expedition/class/expedition.class.php | 28 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 532b7ae411ebb..38e18e2302c97 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -560,6 +560,14 @@ if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } + } elseif ($action == 'setdate_shipping' && $user->hasRight('expedition', 'creer')) { + $dateshipping = dol_mktime(GETPOSTINT('ship_hour'), GETPOSTINT('ship_min'), 0, GETPOSTINT('ship_month'), GETPOSTINT('ship_day'), GETPOSTINT('ship_year')); + + $object->fetch($id); + $result = $object->setShippingDate($user, $dateshipping); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } } elseif (in_array($action, array('settracking_number', 'settracking_url', 'settrueWeight', 'settrueWidth', 'settrueHeight', 'settrueDepth', 'setshipping_method_id')) && $user->hasRight('expedition', 'creer')) { // Action update $error = 0; @@ -2061,10 +2069,10 @@ print ''; print ''; if ($action == 'editdate_shipping') { - print '
'; + print ''; print ''; - print ''; - print $form->selectDate($object->date_shipping ? $object->date_shipping : -1, 'liv_', 1, 1, 0, "setdate_shipping", 1, 0); + print ''; + print $form->selectDate($object->date_shipping ? $object->date_shipping : -1, 'ship_', 1, 1, 0, "setdate_shipping", 1, 0); print ''; print '
'; } else { diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 8a49d6139a6b8..5193c3cde90d7 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2223,6 +2223,34 @@ public function setDeliveryDate($user, $delivery_date) } } + /** + * Set the shipping date + * + * @param User $user Object user that modify + * @param integer $shipping_date Date of shipping + * @return int Return integer <0 if KO, >0 if OK + */ + public function setShippingDate($user, $shipping_date) + { + if ($user->hasRight('expedition', 'creer')) { + $sql = "UPDATE ".MAIN_DB_PREFIX."expedition"; + $sql .= " SET date_expedition = ".($shipping_date ? "'".$this->db->idate($shipping_date)."'" : 'null'); + $sql .= " WHERE rowid = ".((int) $this->id); + + dol_syslog(get_class($this)."::setShippingDate", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + $this->date_shipping = $shipping_date; + return 1; + } else { + $this->error = $this->db->error(); + return -1; + } + } else { + return -2; + } + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Fetch deliveries method and return an array. Load array this->meths(rowid=>label). From a9b2e7bde133f0e29049e807e62608a3db18bfa4 Mon Sep 17 00:00:00 2001 From: Quentin-Seekness <72733832+Quentin-Seekness@users.noreply.github.com> Date: Wed, 20 Nov 2024 20:50:49 +0100 Subject: [PATCH 03/31] Update facture.class.php (#32013) Incoterms and location are missing when invoice is auto gen from an order (when WORKFLOW_ORDER_AUTOCREATE_INVOICE is active for instance) --- htdocs/compta/facture/class/facture.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index dacff6569d8e4..06eb0d45c293b 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1472,6 +1472,8 @@ public function createFromOrder($object, User $user) $this->fk_account = $object->fk_account; $this->cond_reglement_id = $object->cond_reglement_id; $this->mode_reglement_id = $object->mode_reglement_id; + $this->fk_incoterms = $object->fk_incoterms; + $this->location_incoterms = $object->location_incoterms; $this->availability_id = $object->availability_id; $this->demand_reason_id = $object->demand_reason_id; $this->delivery_date = $object->delivery_date; From b7816bf6480f77b10a8517210cad0a465e82c04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 20 Nov 2024 20:56:16 +0100 Subject: [PATCH 04/31] fix phpstan (#32010) * fix phpstan * Update extrafields_view.tpl.php * Update extrafields.class.php --- htdocs/core/class/extrafields.class.php | 2 +- htdocs/core/tpl/extrafields_view.tpl.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 221925075e18d..0aef926b6931a 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -51,7 +51,7 @@ class ExtraFields public $attributes = array(); /** - * @var array> Array with boolean of status of groups + * @var array>|null Array with boolean of status of groups */ public $expand_display; diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index e0dccc9b8ab7b..700824e7ae3f4 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -29,6 +29,7 @@ * @var CommonObject $object * @var Conf $conf * @var DoliDB $db + * @var ExtraFields $extrafields * @var Form $form * @var Translate $langs * @var User $user @@ -81,7 +82,7 @@ $enabled = 1; if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$tmpkeyextra])) { - $enabled = (int) dol_eval($extrafields->attributes[$object->table_element]['enabled'][$tmpkeyextra], 1, 1, '2'); + $enabled = (int) dol_eval((string) $extrafields->attributes[$object->table_element]['enabled'][$tmpkeyextra], 1, 1, '2'); } if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$tmpkeyextra])) { $enabled = (int) dol_eval($extrafields->attributes[$object->table_element]['list'][$tmpkeyextra], 1, 1, '2'); From 98b884e8ba26a466cd2806cefe31e52a0d624748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 20 Nov 2024 20:57:47 +0100 Subject: [PATCH 05/31] Fix typo in SECURITY.md (#32011) --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 50a74ea0716a9..062578e03b9fb 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,7 +12,7 @@ Security report are valid only on current stable version (see https://dolibarr.o To report a vulnerability, for a private report, you can: -- Send your report on Vulnerability Disclosure Program (VDP): Link will be upadeted soon (recommended for everybody) +- Send your report on Vulnerability Disclosure Program (VDP): Link will be updated soon (recommended for everybody) '; - $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element); + $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this, $this->table_element); break; case "edit": $listoftypestoshowpicto = explode(',', getDolGlobalString('MAIN_TYPES_TO_SHOW_PICTO', 'email,phone,ip,password')); if (in_array($extrafields->attributes[$this->table_element]['type'][$key], $listoftypestoshowpicto)) { $out .= getPictoForType($extrafields->attributes[$this->table_element]['type'][$key], ($extrafields->attributes[$this->table_element]['type'][$key] == 'text' ? 'tdtop' : '')); } - $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', '', $this->id, $this->table_element); + $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', '', $this, $this->table_element); break; } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 6138ad7c16927..4a1ed96b23818 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1076,18 +1076,18 @@ public function fetch_name_optionals_label($elementtype, $forceload = false, $at * Return HTML string to put an input field into a page * Code very similar with showInputField of common object * - * @param string $key Key of attribute + * @param string $key Key of attribute * @param string|array{start:int,end:int} $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value); for dates in filter mode, a range array('start'=>, 'end'=>) should be provided - * @param string $moreparam To add more parameters on html input tag - * @param string $keysuffix Suffix string to add after name and id of field (can be used to avoid duplicate names) - * @param string $keyprefix Prefix string to add before name and id of field (can be used to avoid duplicate names) - * @param string $morecss More css (to defined size of field. Old behaviour: may also be a numeric) - * @param int $objectid Current object id - * @param string $extrafieldsobjectkey The key to use to store retrieved data (commonly $object->table_element) - * @param int $mode 1=Used for search filters + * @param string $moreparam To add more parameters on html input tag + * @param string $keysuffix Suffix string to add after name and id of field (can be used to avoid duplicate names) + * @param string $keyprefix Prefix string to add before name and id of field (can be used to avoid duplicate names) + * @param string $morecss More css (to defined size of field. Old behaviour: may also be a numeric) + * @param int|CommonObject $object Current object or object ID. Preferably, pass the object itself. + * @param string $extrafieldsobjectkey The key to use to store retrieved data (commonly $object->table_element) + * @param int $mode 1=Used for search filters * @return string */ - public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '', $objectid = 0, $extrafieldsobjectkey = '', $mode = 0) + public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '', $object = 0, $extrafieldsobjectkey = '', $mode = 0) { global $conf, $langs, $form; @@ -1096,6 +1096,8 @@ public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $ $form = new Form($this->db); } + $objectid = (is_numeric($object) ? $object : $object->id); + $out = ''; if (!preg_match('/options_$/', $keyprefix)) { // Because we work on extrafields, we add 'options_' to prefix if not already added @@ -1120,6 +1122,7 @@ public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $ $list = (string) dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '2'); $totalizable = $this->attributes[$extrafieldsobjectkey]['totalizable'][$key]; $help = $this->attributes[$extrafieldsobjectkey]['help'][$key]; + $alwayseditable = $this->attributes[$extrafieldsobjectkey]['alwayseditable'][$key]; $hidden = (empty($list) ? 1 : 0); // If empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller) //var_dump('key='.$key.' '.$value.' '.$moreparam.' '.$keysuffix.' '.$keyprefix.' '.$objectid.' '.$extrafieldsobjectkey.' '.$mode); @@ -1935,6 +1938,12 @@ public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $ if (!empty($hidden)) { $out = ''; } + + // If alwayseditable is false, and object is not in draft, then showOutputField + // @phan-suppress-next-line PhanUndeclaredConstantOfClass + if ($alwayseditable == 0 && !is_numeric($object) && isset($object->status) && $object->status != $object::STATUS_DRAFT) { + $out = $this->showOutputField($key, $value, $moreparam, $extrafieldsobjectkey, null, $object); + } /* Add comments if ($type == 'date') $out.=' (YYYY-MM-DD)'; elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; From 914ed1b18cc1c388b1b9bd45982d43ec7c3dc432 Mon Sep 17 00:00:00 2001 From: Mohamed DAOUD Date: Wed, 20 Nov 2024 21:33:32 +0100 Subject: [PATCH 12/31] Fix #30766 Extra field Can Always Be Edited (#31876) * fix alwayseditable * Update extrafields.class.php * Update extrafields.class.php * Update extrafields.class.php * enhance fix alwayseditable * fix phan --- htdocs/core/class/commonobject.class.php | 4 ++-- htdocs/core/class/extrafields.class.php | 28 ++++++++++++++++-------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d6a0ef32ba4ab..37a0c324dfba2 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -9393,14 +9393,14 @@ public function showOptionals($extrafields, $mode = 'view', $params = null, $key $out .= getPictoForType($extrafields->attributes[$this->table_element]['type'][$key], ($extrafields->attributes[$this->table_element]['type'][$key] == 'text' ? 'tdtop' : '')); } //$out .= ''; - $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element); + $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this, $this->table_element); break; case "edit": $listoftypestoshowpicto = explode(',', getDolGlobalString('MAIN_TYPES_TO_SHOW_PICTO', 'email,phone,ip,password')); if (in_array($extrafields->attributes[$this->table_element]['type'][$key], $listoftypestoshowpicto)) { $out .= getPictoForType($extrafields->attributes[$this->table_element]['type'][$key], ($extrafields->attributes[$this->table_element]['type'][$key] == 'text' ? 'tdtop' : '')); } - $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', '', $this->id, $this->table_element); + $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', '', $this, $this->table_element); break; } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 6138ad7c16927..6aca908bffda1 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1076,18 +1076,18 @@ public function fetch_name_optionals_label($elementtype, $forceload = false, $at * Return HTML string to put an input field into a page * Code very similar with showInputField of common object * - * @param string $key Key of attribute + * @param string $key Key of attribute * @param string|array{start:int,end:int} $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value); for dates in filter mode, a range array('start'=>, 'end'=>) should be provided - * @param string $moreparam To add more parameters on html input tag - * @param string $keysuffix Suffix string to add after name and id of field (can be used to avoid duplicate names) - * @param string $keyprefix Prefix string to add before name and id of field (can be used to avoid duplicate names) - * @param string $morecss More css (to defined size of field. Old behaviour: may also be a numeric) - * @param int $objectid Current object id - * @param string $extrafieldsobjectkey The key to use to store retrieved data (commonly $object->table_element) - * @param int $mode 1=Used for search filters + * @param string $moreparam To add more parameters on html input tag + * @param string $keysuffix Suffix string to add after name and id of field (can be used to avoid duplicate names) + * @param string $keyprefix Prefix string to add before name and id of field (can be used to avoid duplicate names) + * @param string $morecss More css (to defined size of field. Old behaviour: may also be a numeric) + * @param int|CommonObject $object Current object or object ID. Preferably, pass the object itself. + * @param string $extrafieldsobjectkey The key to use to store retrieved data (commonly $object->table_element) + * @param int $mode 1=Used for search filters * @return string */ - public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '', $objectid = 0, $extrafieldsobjectkey = '', $mode = 0) + public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '', $object = 0, $extrafieldsobjectkey = '', $mode = 0) { global $conf, $langs, $form; @@ -1096,6 +1096,8 @@ public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $ $form = new Form($this->db); } + $objectid = (is_numeric($object) ? $object : $object->id); + $out = ''; if (!preg_match('/options_$/', $keyprefix)) { // Because we work on extrafields, we add 'options_' to prefix if not already added @@ -1120,6 +1122,7 @@ public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $ $list = (string) dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '2'); $totalizable = $this->attributes[$extrafieldsobjectkey]['totalizable'][$key]; $help = $this->attributes[$extrafieldsobjectkey]['help'][$key]; + $alwayseditable = $this->attributes[$extrafieldsobjectkey]['alwayseditable'][$key]; $hidden = (empty($list) ? 1 : 0); // If empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller) //var_dump('key='.$key.' '.$value.' '.$moreparam.' '.$keysuffix.' '.$keyprefix.' '.$objectid.' '.$extrafieldsobjectkey.' '.$mode); @@ -1935,6 +1938,12 @@ public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $ if (!empty($hidden)) { $out = ''; } + + // If alwayseditable is false, and object is not in draft, then showOutputField + // @phan-suppress-next-line PhanUndeclaredConstantOfClass + if ($alwayseditable == 0 && is_object($object) && isset($object->status) && defined(get_class($object)."::STATUS_DRAFT") && $object->status != $object::STATUS_DRAFT) { + $out = $this->showOutputField($key, $value, $moreparam, $extrafieldsobjectkey, null, $object); + } /* Add comments if ($type == 'date') $out.=' (YYYY-MM-DD)'; elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; @@ -1987,6 +1996,7 @@ public function showOutputField($key, $value, $moreparam = '', $extrafieldsobjec // If alwayseditable is false, and object is not in draft, then we show value instead of input field $showValueInsteadOfInputField = 0; // Variable used to disable update of fields via ajax + // @phan-suppress-next-line PhanUndeclaredConstantOfClass if ($alwayseditable == 0 && is_object($object) && isset($object->status) && defined(get_class($object)."::STATUS_DRAFT") && $object->status != $object::STATUS_DRAFT) { $showValueInsteadOfInputField = 1; } From d22c3dbded6282f7a834981cbeb43da56cdac678 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2024 21:47:02 +0100 Subject: [PATCH 13/31] Trans --- htdocs/product/stock/replenish.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 150984d40641c..1f0a72aeb43bb 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -745,7 +745,7 @@ $stocklabel = $langs->trans('PhysicalStock'); } if (getDolGlobalString('STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) { - $stocklabelbis = $stocklabel.' (Selected warehouse)'; + $stocklabelbis = $stocklabel.' ('.$langs->trans('SelectedWarehouse').')'; $stocklabel .= ' ('.$langs->trans("AllWarehouses").')'; } $texte = $langs->trans('Replenishment'); From ec1ea71175025787170d4ce0b4dbb99a91b4609d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2024 22:49:59 +0100 Subject: [PATCH 14/31] Fix to make protection ok when no stock and STOCK_ALLOW_NEGATIVE_TRANSFER on --- htdocs/product/stock/class/mouvementstock.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 6f4232b1ca759..45668188f936b 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -478,7 +478,7 @@ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = return -8; } } else { - if (isset($product->stock_warehouse[$entrepot_id]) && (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty))) { + if (empty($product->stock_warehouse[$entrepot_id]) || empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty)) { $langs->load("stocks"); $this->error = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; $this->errors[] = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; From 9191c216f3c95a8349f2878507f5fe131228b4e2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2024 22:49:59 +0100 Subject: [PATCH 15/31] Fix to make protection ok when no stock and STOCK_ALLOW_NEGATIVE_TRANSFER on --- htdocs/product/stock/class/mouvementstock.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index fd7ea010270e5..60cd678ba363d 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -446,7 +446,7 @@ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = return -8; } } else { - if (isset($product->stock_warehouse[$entrepot_id]) && (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty))) { + if (empty($product->stock_warehouse[$entrepot_id]) || empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty)) { $langs->load("stocks"); $this->error = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; $this->errors[] = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; From 0d07520e02c8156834093e2a9fdce45198b2f7ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2024 22:49:59 +0100 Subject: [PATCH 16/31] Fix to make protection ok when no stock and STOCK_ALLOW_NEGATIVE_TRANSFER on --- htdocs/comm/action/class/actioncomm.class.php | 131 +++++++++--------- .../stock/class/mouvementstock.class.php | 2 +- 2 files changed, 68 insertions(+), 65 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index fb94299c405c7..249e342d5fcda 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -2715,82 +2715,85 @@ public function sendEmailsReminder() // Load event $res = $this->fetch($actionCommReminder->fk_actioncomm); if ($res > 0) { - $res = $this->fetch_thirdparty(); - } - if ($res > 0) { - // PREPARE EMAIL - $errormesg = ''; - - // Make substitution in email content - $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $this); - - complete_substitutions_array($substitutionarray, $langs, $this); - - // Content - $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray); - - //Topic - $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder')); - - // Recipient - $recipient = new User($this->db); - $res = $recipient->fetch($actionCommReminder->fk_user); - if ($res > 0) { - if (!empty($recipient->email)) { - $to = $recipient->email; + $res2 = $this->fetch_thirdparty(); + if ($res2 >= 0) { + // PREPARE EMAIL + $errormesg = ''; + + // Make substitution in email content + $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $this); + + complete_substitutions_array($substitutionarray, $langs, $this); + + // Content + $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray); + + //Topic + $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder')); + + // Recipient + $recipient = new User($this->db); + $res = $recipient->fetch($actionCommReminder->fk_user); + if ($res > 0) { + if (!empty($recipient->email)) { + $to = $recipient->email; + } else { + $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user."; + $error++; + } } else { - $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user."; + $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user; $error++; } - } else { - $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user; - $error++; - } - - // Sender - $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); - if (empty($from)) { - $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM"; - $error++; - } - - if (!$error) { - // Errors Recipient - $errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO'); - - // Mail Creation - $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', ''); - // Sending Mail - if ($cMailFile->sendfile()) { - $nbMailSend++; - } else { - $errormesg = 'Failed to send email to: '.$to.' '.$cMailFile->error.implode(',', $cMailFile->errors); + // Sender + $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); + if (empty($from)) { + $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM"; $error++; } - } - if (!$error) { - $actionCommReminder->status = $actionCommReminder::STATUS_DONE; + if (!$error) { + // Errors Recipient + $errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO'); - $res = $actionCommReminder->update($user); - if ($res < 0) { - $errorsMsg[] = "Failed to update status to done of ActionComm Reminder"; - $error++; - break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first. + // Mail Creation + $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', ''); + + // Sending Mail + if ($cMailFile->sendfile()) { + $nbMailSend++; + } else { + $errormesg = 'Failed to send email to: '.$to.' '.$cMailFile->error.implode(',', $cMailFile->errors); + $error++; + } } - } else { - $actionCommReminder->status = $actionCommReminder::STATUS_ERROR; - $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1); - $res = $actionCommReminder->update($user); - if ($res < 0) { - $errorsMsg[] = "Failed to update status to error of ActionComm Reminder"; - $error++; - break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first. + if (!$error) { + $actionCommReminder->status = $actionCommReminder::STATUS_DONE; + + $res = $actionCommReminder->update($user); + if ($res < 0) { + $errorsMsg[] = "Failed to update status to done of ActionComm Reminder"; + $error++; + break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first. + } } else { - $errorsMsg[] = $errormesg; + $actionCommReminder->status = $actionCommReminder::STATUS_ERROR; + $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1); + + $res = $actionCommReminder->update($user); + if ($res < 0) { + $errorsMsg[] = "Failed to update status to error of ActionComm Reminder"; + $error++; + break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first. + } else { + $errorsMsg[] = $errormesg; + } } + } else { + $errorsMsg[] = 'Failed to fetch record thirdparty on actioncomm with ID = '.$actionCommReminder->fk_actioncomm; + $error++; } } else { $errorsMsg[] = 'Failed to fetch record actioncomm with ID = '.$actionCommReminder->fk_actioncomm; diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 6f4232b1ca759..45668188f936b 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -478,7 +478,7 @@ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = return -8; } } else { - if (isset($product->stock_warehouse[$entrepot_id]) && (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty))) { + if (empty($product->stock_warehouse[$entrepot_id]) || empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty)) { $langs->load("stocks"); $this->error = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; $this->errors[] = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; From 4a3edf9294aec3daca8301169291b24049357346 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2024 22:49:59 +0100 Subject: [PATCH 17/31] Fix to make protection ok when no stock and STOCK_ALLOW_NEGATIVE_TRANSFER on --- htdocs/comm/action/class/actioncomm.class.php | 129 +++++++++--------- 1 file changed, 67 insertions(+), 62 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 3ca29e1af4e57..0b0e6d73db98a 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -2702,81 +2702,86 @@ public function sendEmailsReminder() // Load event $res = $this->fetch($actionCommReminder->fk_actioncomm); - if ($res > 0) $res = $this->fetch_thirdparty(); if ($res > 0) { - // PREPARE EMAIL - $errormesg = ''; - - // Make substitution in email content - $substitutionarray = getCommonSubstitutionArray($langs, 0, '', $this); - - complete_substitutions_array($substitutionarray, $langs, $this); - - // Content - $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray); - - //Topic - $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder')); - - // Recipient - $recipient = new User($this->db); - $res = $recipient->fetch($actionCommReminder->fk_user); - if ($res > 0) { - if (!empty($recipient->email)) { - $to = $recipient->email; + $res2 = $this->fetch_thirdparty(); + if ($res2 >= 0) { + // PREPARE EMAIL + $errormesg = ''; + + // Make substitution in email content + $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $this); + + complete_substitutions_array($substitutionarray, $langs, $this); + + // Content + $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray); + + //Topic + $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder')); + + // Recipient + $recipient = new User($this->db); + $res = $recipient->fetch($actionCommReminder->fk_user); + if ($res > 0) { + if (!empty($recipient->email)) { + $to = $recipient->email; + } else { + $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user."; + $error++; + } } else { - $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user."; + $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user; $error++; } - } else { - $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user; - $error++; - } - - // Sender - $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); - if (empty($from)) { - $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM"; - $error++; - } - if (!$error) { - // Errors Recipient - $errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO'); - - // Mail Creation - $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', ''); - - // Sending Mail - if ($cMailFile->sendfile()) { - $nbMailSend++; - } else { - $errormesg = 'Failed to send email to: '.$to.' '.$cMailFile->error.implode(',', $cMailFile->errors); + // Sender + $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); + if (empty($from)) { + $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM"; $error++; } - } - if (!$error) { - $actionCommReminder->status = $actionCommReminder::STATUS_DONE; + if (!$error) { + // Errors Recipient + $errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO'); - $res = $actionCommReminder->update($user); - if ($res < 0) { - $errorsMsg[] = "Failed to update status to done of ActionComm Reminder"; - $error++; - break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first. + // Mail Creation + $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', ''); + + // Sending Mail + if ($cMailFile->sendfile()) { + $nbMailSend++; + } else { + $errormesg = 'Failed to send email to: '.$to.' '.$cMailFile->error.implode(',', $cMailFile->errors); + $error++; + } } - } else { - $actionCommReminder->status = $actionCommReminder::STATUS_ERROR; - $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1); - $res = $actionCommReminder->update($user); - if ($res < 0) { - $errorsMsg[] = "Failed to update status to error of ActionComm Reminder"; - $error++; - break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first. + if (!$error) { + $actionCommReminder->status = $actionCommReminder::STATUS_DONE; + + $res = $actionCommReminder->update($user); + if ($res < 0) { + $errorsMsg[] = "Failed to update status to done of ActionComm Reminder"; + $error++; + break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first. + } } else { - $errorsMsg[] = $errormesg; + $actionCommReminder->status = $actionCommReminder::STATUS_ERROR; + $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1); + + $res = $actionCommReminder->update($user); + if ($res < 0) { + $errorsMsg[] = "Failed to update status to error of ActionComm Reminder"; + $error++; + break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first. + } else { + $errorsMsg[] = $errormesg; + } } + } else { + $errorsMsg[] = 'Failed to fetch record thirdparty on actioncomm with ID = '.$actionCommReminder->fk_actioncomm; + $error++; } } else { $errorsMsg[] = 'Failed to fetch record actioncomm with ID = '.$actionCommReminder->fk_actioncomm; From e9c1274356162469298f6367182ebeee59ad4c31 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2024 23:47:39 +0100 Subject: [PATCH 18/31] Debug v21 --- htdocs/product/price.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index e10fe4caabd13..2ca40d0bad00f 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -2539,6 +2539,7 @@ function on_change() { $total_ttc = $resultarray[2]; if (!getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { + print ''."\n"; print ''; print '' . $langs->trans('Default') . ''; @@ -2580,7 +2581,10 @@ function on_change() { print ''; if (!empty($extralabels)) { foreach ($extralabels as $key) { - print ''; + // Show field if not hidden + if (!empty($extrafields->attributes["product_customer_price"]['list'][$key]) && $extrafields->attributes["product_customer_price"]['list'][$key] != 3) { + print ''; + } } } if ($user->hasRight('produit', 'supprimer') || $user->hasRight('service', 'supprimer')) { From e87c66ba4edecf46854b3021439e62229ddfc80b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 20 Nov 2024 23:59:50 +0100 Subject: [PATCH 19/31] Debug v21 --- htdocs/theme/eldy/info-box.inc.php | 3 +++ htdocs/theme/md/info-box.inc.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index c0ae0fa7a93e8..1f5608090d75c 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -447,6 +447,9 @@ .infobox-order_supplier:not(.error) { color: #599caf; } +.infobox-order_supplier::before { + margin-left: 5px; +} .infobox-contrat, .infobox-ticket{ color: #3bbfa8; } diff --git a/htdocs/theme/md/info-box.inc.php b/htdocs/theme/md/info-box.inc.php index 2107fc5bec3f1..71ac51a3d7fea 100644 --- a/htdocs/theme/md/info-box.inc.php +++ b/htdocs/theme/md/info-box.inc.php @@ -136,6 +136,9 @@ .infobox-order_supplier:not(.pictotitle):not(.error) { color: #599caf; } +.infobox-order_supplier::before { + margin-left: 3px; +} .infobox-contrat, .infobox-ticket{ color: #46a676; From 275627bd141a5396db846f5ff79ba7568db95ba6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2024 00:57:16 +0100 Subject: [PATCH 20/31] Clean code --- htdocs/public/ticket/ajax/ajax.php | 2 +- htdocs/ticket/class/ticket.class.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/public/ticket/ajax/ajax.php b/htdocs/public/ticket/ajax/ajax.php index e28b849eb2d62..a2f57cade82ec 100644 --- a/htdocs/public/ticket/ajax/ajax.php +++ b/htdocs/public/ticket/ajax/ajax.php @@ -57,7 +57,7 @@ * @var DoliDB $db */ - $action = GETPOST('action', 'aZ09'); +$action = GETPOST('action', 'aZ09'); $id = GETPOSTINT('id'); $email = GETPOST('email', 'custom', 0, FILTER_VALIDATE_EMAIL); diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index aafe16ca86894..691385ef87879 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2186,7 +2186,7 @@ public function setCustomer($id) { if ($this->id) { $sql = "UPDATE ".MAIN_DB_PREFIX."ticket"; - $sql .= " SET fk_soc = ".($id > 0 ? $id : "null"); + $sql .= " SET fk_soc = ".($id > 0 ? (int) $id : "null"); $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this).'::setCustomer sql='.$sql); $resql = $this->db->query($sql); @@ -2210,7 +2210,7 @@ public function setProgression($percent) { if ($this->id) { $sql = "UPDATE ".MAIN_DB_PREFIX."ticket"; - $sql .= " SET progress = ".($percent > 0 ? $percent : "null"); + $sql .= " SET progress = ".($percent > 0 ? (float) $percent : "null"); $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this).'::set_progression sql='.$sql); $resql = $this->db->query($sql); @@ -2234,7 +2234,7 @@ public function setContract($contractid) { if ($this->id) { $sql = "UPDATE ".MAIN_DB_PREFIX."ticket"; - $sql .= " SET fk_contract = ".($contractid > 0 ? $contractid : "null"); + $sql .= " SET fk_contract = ".($contractid > 0 ? (int) $contractid : "null"); $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this).'::setContract sql='.$sql); $resql = $this->db->query($sql); From 2d135b4c222238d85a99d76784d5f65d7a5acb95 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2024 02:27:41 +0100 Subject: [PATCH 21/31] Add step to read DCO --- .github/CONTRIBUTING.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 1eae1b063b040..d898628013e48 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -36,12 +36,13 @@ Definition: As the Developer: -1. [Fork](https://help.github.com/articles/fork-a-repo) the [GitHub repository](https://github.com/Dolibarr/dolibarr). -2. Clone your fork. -3. Choose a branch(See the [Branches](#branches) section below). -4. Read our developer documentation on the [Dolibarr Wiki](https://wiki.dolibarr.org/index.php?title=Developer_documentation). -5. Commit and push your changes. -6. [Make a pull request](https://help.github.com/articles/creating-a-pull-request). +1. Check you agree with the terms of the [DCO - Developer's Certificate of Origin](https://github.com/Dolibarr/dolibarr/DCO) +2. [Fork](https://help.github.com/articles/fork-a-repo) the [GitHub repository](https://github.com/Dolibarr/dolibarr). +3. Clone your fork. +4. Choose a branch(See the [Branches](#branches) section below). +5. Read our developer documentation on the [Dolibarr Wiki](https://wiki.dolibarr.org/index.php?title=Developer_documentation). +6. Commit and push your changes. +7. [Make a pull request](https://help.github.com/articles/creating-a-pull-request). As the PR Maintainer: From d04e0a7ac2dfe0c7818ec5d267cb7b14a587e825 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2024 04:45:11 +0100 Subject: [PATCH 22/31] Debug v21 --- htdocs/compta/bank/bankentries_list.php | 13 +++-- htdocs/compta/bank/releve.php | 3 +- htdocs/core/lib/bank.lib.php | 71 +++++++++++++++++++------ htdocs/langs/en_US/banks.lang | 2 +- htdocs/langs/en_US/stocks.lang | 1 + 5 files changed, 67 insertions(+), 23 deletions(-) diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 6f4e4a946f3aa..3dd37bf0d1be4 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -554,7 +554,11 @@ // Bank card $head = bank_prepare_head($object); - print dol_get_fiche_head($head, 'journal', $langs->trans("FinancialAccount"), 0, 'account'); + $activetab = 'journal'; + if ($action == 'reconcile') { + $activetab = 'reconcile'; + } + print dol_get_fiche_head($head, $activetab, $langs->trans("FinancialAccount"), 0, 'account'); $linkback = ''.$langs->trans("BackToList").''; @@ -566,7 +570,7 @@ /* * Buttons actions */ - + /* Moved into tab if ($action != 'reconcile') { if ($object->canBeConciliated() > 0) { $allowautomaticconciliation = false; // TODO @@ -598,6 +602,7 @@ } } } + */ } $sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro as conciliated, b.num_releve, b.num_chq,"; @@ -1032,8 +1037,8 @@ print ''; print ' '.$langs->trans("otherwise").' '; print ''; - print ' '.$langs->trans("or").' '; - print ''; + //print ' '.$langs->trans("or").' '; + //print ''; print ''; print '
'; diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index f1d3523c3368e..1ebf78604fdcd 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -310,7 +310,7 @@ print dol_get_fiche_end(); - + /* Moved as a tab if ($object->canBeConciliated() > 0) { $allowautomaticconciliation = false; // TODO $titletoconciliatemanual = $langs->trans("Conciliate"); @@ -339,6 +339,7 @@ } } } + */ // List of mass actions available $arrayofmassactions = array( diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php index 787ae74594958..7091f6aa0e5e4 100644 --- a/htdocs/core/lib/bank.lib.php +++ b/htdocs/core/lib/bank.lib.php @@ -38,7 +38,8 @@ */ function bank_prepare_head(Account $object) { - global $db, $langs, $conf; + global $db, $langs, $conf, $user; + $h = 0; $head = array(); @@ -52,23 +53,44 @@ function bank_prepare_head(Account $object) $head[$h][2] = 'journal'; $h++; - // if ($conf->global->MAIN_FEATURES_LEVEL >= 1) - // { - $head[$h][0] = DOL_URL_ROOT."/compta/bank/treso.php?account=".$object->id; - $head[$h][1] = $langs->trans("PlannedTransactions"); - $head[$h][2] = 'cash'; - $h++; - // } - - $head[$h][0] = DOL_URL_ROOT."/compta/bank/annuel.php?account=".$object->id; - $head[$h][1] = $langs->trans("IOMonthlyReporting"); - $head[$h][2] = 'annual'; - $h++; + if ($object->canBeConciliated() > 0) { + $allowautomaticconciliation = false; // TODO + $titletoconciliatemanual = $langs->trans("Conciliate"); + $titletoconciliateauto = $langs->trans("Conciliate"); + if ($allowautomaticconciliation) { + $titletoconciliatemanual .= ' ('.$langs->trans("Manual").')'; + $titletoconciliateauto .= ' ('.$langs->trans("Auto").')'; + } - $head[$h][0] = DOL_URL_ROOT."/compta/bank/graph.php?account=".$object->id; - $head[$h][1] = $langs->trans("Graph"); - $head[$h][2] = 'graph'; - $h++; + $param = ''; + + // If not cash account and can be reconciliate + if ($user->hasRight('banque', 'consolidate')) { + $head[$h][0] = DOL_URL_ROOT."/compta/bank/bankentries_list.php?id=".$object->id.'&action=reconcile&sortfield=b.datev,b.dateo,b.rowid&sortorder=asc,asc,asc&search_conciliated=0&search_account='.$object->id.$param; + $head[$h][1] = $titletoconciliatemanual; + $head[$h][2] = 'reconcile'; + $h++; + }/* else { + $buttonreconcile = ''.$titletoconciliatemanual.''; + }*/ + + if ($allowautomaticconciliation) { + // If not cash account and can be reconciliate + if ($user->hasRight('banque', 'consolidate')) { + $newparam = $param; + $newparam = preg_replace('/search_conciliated=\d+/i', '', $newparam); + + $head[$h][0] = DOL_URL_ROOT."/compta/bank/bankentries_list.php?id=".$object->id.'&action=reconcile&sortfield=b.datev,b.dateo,b.rowid&sortorder=asc,asc,asc&search_conciliated=0&search_account='.$object->id.$newparam; + $head[$h][1] = $titletoconciliateauto; + $head[$h][2] = 'reconcileauto'; + $h++; + + //$buttonreconcile .= ' '.$titletoconciliateauto.''; + }/* else { + $buttonreconcile .= ' '.$titletoconciliateauto.''; + }*/ + } + } if ($object->type != Account::TYPE_CASH || getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) { $nbReceipts = 0; @@ -110,6 +132,21 @@ function bank_prepare_head(Account $object) $head[$h][2] = 'document'; $h++; + $head[$h][0] = DOL_URL_ROOT."/compta/bank/annuel.php?account=".$object->id; + $head[$h][1] = $langs->trans("IOMonthlyReporting"); + $head[$h][2] = 'annual'; + $h++; + + $head[$h][0] = DOL_URL_ROOT."/compta/bank/graph.php?account=".$object->id; + $head[$h][1] = $langs->trans("Graph"); + $head[$h][2] = 'graph'; + $h++; + + $head[$h][0] = DOL_URL_ROOT."/compta/bank/treso.php?account=".$object->id; + $head[$h][1] = $langs->trans("PlannedTransactions"); + $head[$h][2] = 'cash'; + $h++; + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/langs/en_US/banks.lang b/htdocs/langs/en_US/banks.lang index 7084a3332d782..fc5a428396503 100644 --- a/htdocs/langs/en_US/banks.lang +++ b/htdocs/langs/en_US/banks.lang @@ -133,7 +133,7 @@ DeleteTransaction=Delete entry ConfirmDeleteTransaction=Are you sure you want to delete this entry? ThisWillAlsoDeleteBankRecord=This will also delete generated bank entry BankMovements=Movements -PlannedTransactions=Planned entries +PlannedTransactions=Upcoming entries Graph=Graphs ExportDataset_banque_1=Bank entries and account statement ExportDataset_banque_2=Deposit slip diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 400a39ec95175..0648dde54b4f4 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -348,3 +348,4 @@ QtyViewed=Quantity viewed QtyStock=Quantity on stock QtyRegulated=Quantity on stock correction InventoryEntrepot=Warehouse identity +SelectedWarehouse=Select a warehouse From ac91727bb6bedc93784c6ea26b3ece1b8d86bb00 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2024 04:49:57 +0100 Subject: [PATCH 23/31] Debug v21 --- htdocs/compta/bank/treso.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index 69c859037b29f..243ab3af6c1df 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -216,7 +216,7 @@ $morehtml = ''; $limit = 0; - print_barre_liste($langs->trans("RemainderToPay"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $picto, 0, $morehtml, '', $limit, 0, 0, 1); + print_barre_liste($langs->trans("PlannedTransactions"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $picto, 0, $morehtml, '', $limit, 0, 0, 1); $solde = $object->solde(0); From cc0db78984843173339cd6cab4b338bea6e722d4 Mon Sep 17 00:00:00 2001 From: Nicolas Domenech <52404047+nicolas-eoxia@users.noreply.github.com> Date: Thu, 21 Nov 2024 08:48:55 +0100 Subject: [PATCH 24/31] FIX #32007 missing parameter on function multiSelectArrayWithCheckbox (#32008) --- 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 d770f23f4f5ff..6f4a3aa4832bd 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -857,7 +857,7 @@ print ''; } elseif ($id > 0 || !empty($ref)) { - $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields /* * Projet card in view mode From c907327e3c0e6bea8d1b81e389e0b0979404cba7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2024 09:08:54 +0100 Subject: [PATCH 25/31] Fix removed foreign key not on a unique key --- htdocs/install/mysql/migration/19.0.0-20.0.0.sql | 3 ++- htdocs/install/mysql/tables/llx_societe_commerciaux.key.sql | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/install/mysql/migration/19.0.0-20.0.0.sql b/htdocs/install/mysql/migration/19.0.0-20.0.0.sql index b2397e2069cf0..ec3053a6a400c 100644 --- a/htdocs/install/mysql/migration/19.0.0-20.0.0.sql +++ b/htdocs/install/mysql/migration/19.0.0-20.0.0.sql @@ -349,7 +349,8 @@ ALTER TABLE llx_societe_commerciaux ADD COLUMN fk_c_type_contact_code varchar(32 -- VPGSQL8.2 DROP INDEX uk_societe_commerciaux; ALTER TABLE llx_societe_commerciaux ADD UNIQUE INDEX uk_societe_commerciaux_c_type_contact (fk_soc, fk_user, fk_c_type_contact_code); ALTER TABLE llx_c_type_contact ADD INDEX idx_c_type_contact_code (code); -ALTER TABLE llx_societe_commerciaux ADD CONSTRAINT fk_societe_commerciaux_fk_c_type_contact_code FOREIGN KEY (fk_c_type_contact_code) REFERENCES llx_c_type_contact(code); +--Removed, not unique. ALTER TABLE llx_societe_commerciaux ADD CONSTRAINT fk_societe_commerciaux_fk_c_type_contact_code FOREIGN KEY (fk_c_type_contact_code) REFERENCES llx_c_type_contact(code); +ALTER TABLE llx_societe_commerciaux DROP FOREIGN KEY fk_societe_commerciaux_fk_c_type_contact_code; ALTER TABLE llx_societe_commerciaux ADD CONSTRAINT fk_societe_commerciaux_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe(rowid); ALTER TABLE llx_societe_commerciaux ADD CONSTRAINT fk_societe_commerciaux_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user(rowid); diff --git a/htdocs/install/mysql/tables/llx_societe_commerciaux.key.sql b/htdocs/install/mysql/tables/llx_societe_commerciaux.key.sql index 1672ff659c1f4..f4bc719c4ba32 100644 --- a/htdocs/install/mysql/tables/llx_societe_commerciaux.key.sql +++ b/htdocs/install/mysql/tables/llx_societe_commerciaux.key.sql @@ -17,6 +17,6 @@ -- =================================================================== ALTER TABLE llx_societe_commerciaux ADD UNIQUE INDEX uk_societe_commerciaux_c_type_contact (fk_soc, fk_user, fk_c_type_contact_code); -ALTER TABLE llx_societe_commerciaux ADD CONSTRAINT fk_societe_commerciaux_fk_c_type_contact_code FOREIGN KEY (fk_c_type_contact_code) REFERENCES llx_c_type_contact(code); +--Removed, not unique. ALTER TABLE llx_societe_commerciaux ADD CONSTRAINT fk_societe_commerciaux_fk_c_type_contact_code FOREIGN KEY (fk_c_type_contact_code) REFERENCES llx_c_type_contact(code); ALTER TABLE llx_societe_commerciaux ADD CONSTRAINT fk_societe_commerciaux_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe(rowid); ALTER TABLE llx_societe_commerciaux ADD CONSTRAINT fk_societe_commerciaux_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user(rowid); From bf3a08ffa51771a197248911e1ee406833c01a59 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2024 09:41:59 +0100 Subject: [PATCH 26/31] Tooltip --- htdocs/langs/en_US/ticket.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index bb0cd645857cc..f0f7a31831d36 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -75,7 +75,7 @@ TicketParamMail=Email setup TicketEmailNotificationFrom=Sender e-mail for notification on answers TicketEmailNotificationFromHelp=Sender e-mail to use to send the notification email when an answer is provided inside the back office. For example noreply@example.com TicketEmailNotificationTo=Notify ticket creation to this e-mail address -TicketEmailNotificationToHelp=If present, this e-mail address will be notified of a ticket creation +TicketEmailNotificationToHelp=If present, this e-mail address will be notified of a ticket creation (in addition to already assigned contacts) TicketNewEmailBodyLabel=Text message sent after creating a ticket TicketNewEmailBodyHelp=The text specified here will be inserted into the email confirming the creation of a new ticket from the public interface. Information on the consultation of the ticket are automatically added. TicketParamPublicInterface=Public interface setup From 4c95fa2ac6b8a96baa6091a955aa128db30aa788 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2024 10:10:32 +0100 Subject: [PATCH 27/31] Fix clean a bugged option duplicated at wrong place in setup --- htdocs/admin/ticket.php | 40 +++------------------------- htdocs/ticket/class/ticket.class.php | 8 +++--- 2 files changed, 7 insertions(+), 41 deletions(-) diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index 76fd7f98064ab..b05d7e71f2345 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -89,17 +89,9 @@ } elseif (preg_match('/set_(.*)/', $action, $reg)) { $code = $reg[1]; $value = GETPOSTISSET($code) ? GETPOSTINT($code) : 1; - if ($code == 'TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS' && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { - $param_notification_also_main_addressemail = GETPOST('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', $param_notification_also_main_addressemail, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - } else { - $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } + $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; } } elseif (preg_match('/del_(.*)/', $action, $reg)) { $code = $reg[1]; @@ -211,15 +203,6 @@ if (!($res > 0)) { $error++; } - - // For compatibility when javascript is not enabled - if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2 && empty($conf->use_javascript_ajax)) { - $param_notification_also_main_addressemail = GETPOST('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', $param_notification_also_main_addressemail, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - } } @@ -659,23 +642,6 @@ print ''; print ''; -// Also send to TICKET_NOTIFICATION_EMAIL_TO for responses (not only creation) -if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { - print ''.$langs->trans("TicketsEmailAlsoSendToMainAddress").''; - print ''; - if ($conf->use_javascript_ajax) { - print ajax_constantonoff('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS'); - } else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $formcategory->selectarray("TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS", $arrval, $conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS); - } - print ''; - print ''; - print $formcategory->textwithpicto('', $langs->trans("TicketsEmailAlsoSendToMainAddressHelp"), 1, 'help'); - print ''; - print ''; -} - // Message header $mail_intro = getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO', ''); print ''.$langs->trans("TicketMessageMailIntro"); diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 219feb82a0f76..77671f6161438 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2779,10 +2779,10 @@ public function newMessage($user, &$action, $private = 1, $public_area = 0) } // Add global email address recipient - if (getDolGlobalString('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS') && - getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') && !array_key_exists(getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO'), $sendto) - ) { - $sendto[getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO')] = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO'); + if (getDolGlobalString('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS') && !array_key_exists(getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO'), $sendto)) { + if (getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO')) { + $sendto[getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO')] = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO'); + } } if (!empty($sendto)) { From 9a5aea09da2732df10a241260d4b44c280c39bfd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 21 Nov 2024 12:33:23 +0100 Subject: [PATCH 28/31] FIX Debug option not working replaced by the one that works. --- htdocs/admin/ticket.php | 31 +++++++++- htdocs/admin/ticket_public.php | 56 ++++++------------- ...terface_50_modTicket_TicketEmail.class.php | 18 ++++-- htdocs/langs/en_US/ticket.lang | 12 ++-- htdocs/ticket/class/ticket.class.php | 2 +- 5 files changed, 64 insertions(+), 55 deletions(-) diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index b05d7e71f2345..192a8ad9c9892 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -59,6 +59,15 @@ include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +if (GETPOSTISSET('TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION')) { // only for no js case + $param_disable_email = GETPOST('TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION', $param_disable_email, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + setEventMessages($db->lasterror(), null, 'errors'); + } +} + if ($action == 'updateMask') { $maskconstticket = GETPOST('maskconstticket', 'aZ09'); $maskticket = GETPOST('maskticket', 'alpha'); @@ -595,13 +604,14 @@ print ''; +print '
'; /* - * Notification + * Emails */ // Admin var of module -print load_fiche_titre($langs->trans("Notification"), '', ''); +print load_fiche_titre($langs->trans("Emails"), '', ''); print ''; @@ -636,12 +646,27 @@ // Email for notification of TICKET_CREATE print ''; print ''; +print ''; print ''; print ''; +// Disable email to customers +print ''; +print ''; +print ''; +print ''; + // Message header $mail_intro = getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO', ''); print ''; print ''; - // Also send to main email address - if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { - print ''; - print ''; - print ''; - print ''; - } - if (empty($conf->use_javascript_ajax)) { print ''; print ''; @@ -493,20 +467,6 @@ print '
'; print '
'.$langs->trans("TicketEmailNotificationTo").''; -print ''; print $formcategory->textwithpicto('', $langs->trans("TicketEmailNotificationToHelp"), 1, 'help'); print '
'; +print $form->textwithpicto($langs->trans("TicketsNotifyThirdPartyFromBackOfficeByDefault"), $langs->trans("TicketsNotifyThirdPartyFromBackOfficeByDefaultHelp"), 1, 'help'); +print ''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION", $arrval, getDolGlobalInt('TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION')); +} +print '
'.$langs->trans("TicketMessageMailIntro"); diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php index abda918f20200..91ae4bf549184 100644 --- a/htdocs/admin/ticket_public.php +++ b/htdocs/admin/ticket_public.php @@ -72,15 +72,6 @@ } } - if (GETPOSTISSET('TICKET_DISABLE_CUSTOMER_MAILS')) { // only for no js case - $param_disable_email = GETPOST('TICKET_DISABLE_CUSTOMER_MAILS', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_DISABLE_CUSTOMER_MAILS', $param_disable_email, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - $errors[] = $db->lasterror(); - } - } - if (GETPOSTISSET('TICKET_SHOW_COMPANY_LOGO')) { // only for no js case $param_show_module_logo = GETPOST('TICKET_SHOW_COMPANY_LOGO', 'alpha'); $res = dolibarr_set_const($db, 'TICKET_SHOW_COMPANY_LOGO', $param_show_module_logo, 'chaine', 0, '', $conf->entity); @@ -412,23 +403,6 @@ print '
'.$langs->trans("TicketsEmailAlsoSendToMainAddress").''; - if (!empty($conf->use_javascript_ajax)) { - print ajax_constantonoff('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS'); - } else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS", $arrval, getDolGlobalInt('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS')); - } - print ''; - print $form->textwithpicto('', $langs->trans("TicketsEmailAlsoSendToMainAddressHelp", $langs->transnoentitiesnoconv("TicketEmailNotificationTo").' ('.$langs->transnoentitiesnoconv("Creation").')', $langs->trans("Settings")), 1, 'help'); - print '
'; - // Activate email creation to user - print ''; - print ''; - print ''; - // Text of email after creatio of a ticket $mail_mesg_new = getDolGlobalString("TICKET_MESSAGE_MAIL_NEW", $langs->trans('TicketNewEmailBody')); print ''; print ''; + // Also send to main email address + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + print ''; + print ''; + print ''; + } + print '
'; - print $form->textwithpicto($langs->trans("TicketsDisableCustomerEmail"), $langs->trans("TicketsDisableEmailHelp"), 1, 'help'); - print ''; - if ($conf->use_javascript_ajax) { - print ajax_constantonoff('TICKET_DISABLE_CUSTOMER_MAILS'); - } else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_DISABLE_CUSTOMER_MAILS", $arrval, getDolGlobalInt('TICKET_DISABLE_CUSTOMER_MAILS')); - } - print '
'; @@ -541,6 +501,22 @@ print '
'.$langs->trans("TicketsEmailAlsoSendToMainAddress"); + print $form->textwithpicto('', $langs->trans("TicketsEmailAlsoSendToMainAddressHelp", $langs->transnoentitiesnoconv("TicketEmailNotificationTo").' ('.$langs->transnoentitiesnoconv("Creation").')', $langs->trans("Settings")), 1, 'help'); + print ''; + if (!empty($conf->use_javascript_ajax)) { + print ajax_constantonoff('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS", $arrval, getDolGlobalInt('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS')); + } + print '
'; print ''; diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index faa556da23576..ed97f3b7b408e 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -183,15 +183,19 @@ public function runTrigger($action, $object, User $user, Translate $langs, Conf $see_ticket_customer = 'TicketNewEmailBodyInfosTrackUrlCustomer'; // Send email to notification email + // Note: $object->context['disableticketemail'] is set to 1 by public interface at creation because email sending is already managed by page + // $object->context['createdfrompublicinterface'] may also be defined when creation done from public interface if (getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') && empty($object->context['disableticketemail'])) { - $sendto = !getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + $sendto = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO'); if ($sendto) { $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); } } // Send email to customer - if (!getDolGlobalInt('TICKET_DISABLE_CUSTOMER_MAILS') && empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) { + // Note: $object->context['disableticketemail'] is set to 1 by public interface at creation because email sending is already managed by page + // $object->context['createdfrompublicinterface'] may also be defined when creation done from public interface + if (empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) { $sendto = ''; // if contact selected send to email's contact else send to email's thirdparty @@ -238,15 +242,17 @@ public function runTrigger($action, $object, User $user, Translate $langs, Conf $see_ticket_customer = 'TicketCloseEmailBodyInfosTrackUrlCustomer'; // Send email to notification email + // Note: $object->context['disableticketemail'] is set to 1 by public interface at creation but not at closing if (getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') && empty($object->context['disableticketemail'])) { - $sendto = !getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + $sendto = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO'); if ($sendto) { $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); } } // Send email to customer. - if (!getDolGlobalString('TICKET_DISABLE_CUSTOMER_MAILS') && empty($object->context['disableticketemail'])) { + // Note: $object->context['disableticketemail'] is set to 1 by public interface at creation but not at closing + if (empty($object->context['disableticketemail'])) { $linked_contacts = $object->listeContact(-1, 'thirdparty'); $linked_contacts = array_merge($linked_contacts, $object->listeContact(-1, 'internal')); if (empty($linked_contacts) && getDolGlobalString('TICKET_NOTIFY_AT_CLOSING') && !empty($object->fk_soc)) { @@ -346,7 +352,7 @@ private function composeAndSendAdminMessage($sendto, $base_subject, $body, Ticke $message_admin .= '

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

'.$message.'


'; $message_admin .= '

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

'; - $from = getDolGlobalString('MAIN_INFO_SOCIETE_NOM') . '<' . getDolGlobalString('TICKET_NOTIFICATION_EMAIL_FROM').'>'; + $from = (getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? getDolGlobalString('MAIN_INFO_SOCIETE_NOM') . ' ' : '') . '<' . getDolGlobalString('TICKET_NOTIFICATION_EMAIL_FROM').'>'; $trackid = 'tic'.$object->id; @@ -434,7 +440,7 @@ private function composeAndSendCustomerMessage($sendto, $base_subject, $body, $s $message_customer .= '

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

'; $message_customer .= '

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

'; - $from = (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? '' : getDolGlobalString('MAIN_INFO_SOCIETE_NOM') . ' ').'<' . getDolGlobalString('TICKET_NOTIFICATION_EMAIL_FROM').'>'; + $from = (getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? getDolGlobalString('MAIN_INFO_SOCIETE_NOM') . ' ' : '').'<' . getDolGlobalString('TICKET_NOTIFICATION_EMAIL_FROM').'>'; $trackid = 'tic'.$object->id; diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index f0f7a31831d36..4e3788f05120f 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -72,10 +72,10 @@ TicketPublicAccess=A public interface requiring no identification is available a TicketSetupDictionaries=The type of ticket, severity and analytic codes are configurable from dictionaries TicketParamModule=Module variable setup TicketParamMail=Email setup -TicketEmailNotificationFrom=Sender e-mail for notification on answers -TicketEmailNotificationFromHelp=Sender e-mail to use to send the notification email when an answer is provided inside the back office. For example noreply@example.com +TicketEmailNotificationFrom=Sender e-mail for notification on tickets +TicketEmailNotificationFromHelp=Sender e-mail to use to send the notification emails for tickets creation or messages. For example noreply@example.com TicketEmailNotificationTo=Notify ticket creation to this e-mail address -TicketEmailNotificationToHelp=If present, this e-mail address will be notified of a ticket creation (in addition to already assigned contacts) +TicketEmailNotificationToHelp=If present, this e-mail address will be notified of a ticket creation (in addition to any other default recipients) TicketNewEmailBodyLabel=Text message sent after creating a ticket TicketNewEmailBodyHelp=The text specified here will be inserted into the email confirming the creation of a new ticket from the public interface. Information on the consultation of the ticket are automatically added. TicketParamPublicInterface=Public interface setup @@ -96,7 +96,9 @@ TicketPublicInterfaceTextHelpMessageHelpAdmin=This text will appear above the me ExtraFieldsTicket=Extra attributes TicketCkEditorEmailNotActivated=HTML editor is not activated. Please put FCKEDITOR_ENABLE_MAIL content to 1 to get it. TicketsDisableEmail=Do not send emails for ticket creation or message recording -TicketsDisableEmailHelp=By default, emails are sent when new tickets or messages created. Enable this option to disable *all* email notifications +TicketsDisableEmailHelp=By default, notification emails to third parties are sent when new tickets or messages are created for both backoffice and public interface. Enable this option to disable email notifications to thirdparties when creation is done from backoffice. +TicketsNotifyThirdPartyFromBackOfficeByDefault=Notify third party by default on ticket creation from backoffice +TicketsNotifyThirdPartyFromBackOfficeByDefaultHelp=When creating a ticket from the backoffice, the option "Notify third party" will be checked by default TicketsLogEnableEmail=Enable log by email TicketsLogEnableEmailHelp=At each change, an email will be sent **to each contact** associated with the ticket. TicketParams=Params @@ -117,7 +119,7 @@ TicketsAutoAssignTicketHelp=When creating a ticket, the user can be automaticall TicketNumberingModules=Tickets numbering module TicketsModelModule=Document templates for tickets TicketNotifyTiersAtCreation=Notify third party at creation -TicketsDisableCustomerEmail=Always disable emails when a ticket is created from public interface +TicketsDisableCustomerEmail=Always disable emails to third parties when a ticket is created from the backoffice TicketsPublicNotificationNewMessage=Send email(s) when a new message/comment is added to a ticket TicketsPublicNotificationNewMessageHelp=Send email(s) when a new message is added from public interface (to assigned user or the notifications email to (update) and/or the notifications email to) TicketPublicNotificationNewMessageDefaultEmail=Notifications email to (update) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 77671f6161438..24629554b3227 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -223,7 +223,7 @@ class Ticket extends CommonObject public $cache_msgs_ticket; /** - * @var int Notify thirdparty at create + * @var int Save if a thirdparty was notified at creation at ticket or not */ public $notify_tiers_at_create; From 283265448a1692a548ccba666e9516c3a8fb2b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 21 Nov 2024 17:12:16 +0100 Subject: [PATCH 29/31] fix CI phpstan (#32032) * fix CI phpstan * Update interface_50_modTicket_TicketEmail.class.php * Update interface_50_modTicket_TicketEmail.class.php --- htdocs/core/lib/bank.lib.php | 2 +- .../interface_50_modTicket_TicketEmail.class.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php index 7091f6aa0e5e4..5815d177767be 100644 --- a/htdocs/core/lib/bank.lib.php +++ b/htdocs/core/lib/bank.lib.php @@ -54,7 +54,7 @@ function bank_prepare_head(Account $object) $h++; if ($object->canBeConciliated() > 0) { - $allowautomaticconciliation = false; // TODO + $allowautomaticconciliation = getDolGlobalBool('MAIN_ALLOW_AUTOMATIC_CONCILIATION'); // TODO $titletoconciliatemanual = $langs->trans("Conciliate"); $titletoconciliateauto = $langs->trans("Conciliate"); if ($allowautomaticconciliation) { diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index 27b544205b1ac..9661cdb6416a8 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -164,9 +164,9 @@ public function runTrigger($action, $object, User $user, Translate $langs, Conf // $object->context['createdfrompublicinterface'] may also be defined when creation done from public interface if (getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') && empty($object->context['disableticketemail'])) { $sendto = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO'); - if ($sendto) { - $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); - } + // if ($sendto) { // already test, can't be empty + $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); + // } } // Send email to assignee if an assignee was set at creation @@ -251,9 +251,9 @@ public function runTrigger($action, $object, User $user, Translate $langs, Conf // Note: $object->context['disableticketemail'] is set to 1 by public interface at creation but not at closing if (getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') && empty($object->context['disableticketemail'])) { $sendto = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO'); - if ($sendto) { - $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); - } + // if ($sendto) { // already test, can't be empty + $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); + // } } // Send email to customer. From 6c2effa2247e5ef25ef6794d7f82574523ac4ceb Mon Sep 17 00:00:00 2001 From: Eric - CAP-REL <1468823+rycks@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:31:40 +0100 Subject: [PATCH 30/31] dol_add_file_process : return nb of success in case of multiple added files (#32027) --- htdocs/core/lib/files.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 2a77d59434944..737f8ac24fc0a 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1898,7 +1898,7 @@ function dol_init_file_process($pathtoscan = '', $trackid = '') * @param int<0,1> $generatethumbs 1=Generate also thumbs for uploaded image files * @param ?Object $object Object used to set 'src_object_*' fields * @param string $forceFullTestIndexation '1'=Force full text storage in database even if global option not set (consume a high level of data) - * @return int Return integer <=0 if KO, >0 if OK + * @return int Return integer <=0 if KO, nb of success if OK (>0) * @see dol_remove_file_process() */ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $updatesessionordb = 0, $varfiles = 'addedfile', $savingdocmask = '', $link = null, $trackid = '', $generatethumbs = 1, $object = null, $forceFullTestIndexation = '') @@ -2041,7 +2041,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $updatesessionor } } if ($nbok > 0) { - $res = 1; + $res = $nbok; setEventMessages($langs->trans("FileTransferComplete"), null, 'mesgs'); } } else { From d1ded1caa11391f5879072cd319ddb83079b358f Mon Sep 17 00:00:00 2001 From: Mathieu Moulin Date: Thu, 21 Nov 2024 18:05:35 +0100 Subject: [PATCH 31/31] Add option to hide only Volume (and keep weight) in shipping PDF - Issue #32030 (#32031) * Add option to hide only Volume (and keep weight) in shipping PDF * Fix use of option SHIPPING_PDF_HIDE_VOLUME in shipping lines --------- Co-authored-by: Laurent Destailleur --- htdocs/core/modules/expedition/doc/pdf_espadon.modules.php | 6 +++--- htdocs/core/modules/expedition/doc/pdf_rouget.modules.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index 190a50e6ae118..f5873eaeeb304 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -689,7 +689,7 @@ public function write_file($object, $outputlangs, $srctemplatepath = '', $hidede $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, getDolGlobalInt('SHIPMENT_ROUND_WEIGHT_ON_PDF', 5)).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1); } $voltxt = ''; - if (empty($object->lines[$i]->fk_product_type) && $object->lines[$i]->volume) { + if (empty($object->lines[$i]->fk_product_type) && $object->lines[$i]->volume && !getDolGlobalString('SHIPPING_PDF_HIDE_VOLUME')) { $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, getDolGlobalInt('SHIPMENT_ROUND_VOLUME_ON_PDF', 5)).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1); } @@ -883,13 +883,13 @@ protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs if (!empty($totalWeight)) { $totalWeighttoshow = showDimensionInBestUnit($totalWeight, 0, "weight", $outputlangs, -1, 'no', 1); } - if (!empty($totalVolume)) { + if (!empty($totalVolume) && !getDolGlobalString('SHIPPING_PDF_HIDE_VOLUME')) { $totalVolumetoshow = showDimensionInBestUnit($totalVolume, 0, "volume", $outputlangs, -1, 'no', 1); } if (!empty($object->trueWeight)) { $totalWeighttoshow = showDimensionInBestUnit($object->trueWeight, (int) $object->weight_units, "weight", $outputlangs); } - if (!empty($object->trueVolume)) { + if (!empty($object->trueVolume) && !getDolGlobalString('SHIPPING_PDF_HIDE_VOLUME')) { if ($object->volume_units < 50) { $totalVolumetoshow = showDimensionInBestUnit($object->trueVolume, $object->volume_units, "volume", $outputlangs); } else { diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index dfaa64aafea81..9d54b5b4e880b 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -583,7 +583,7 @@ public function write_file($object, $outputlangs, $srctemplatepath = '', $hidede $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, getDolGlobalInt('SHIPMENT_ROUND_WEIGHT_ON_PDF', 5)).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1); } $voltxt = ''; - if (empty($object->lines[$i]->fk_product_type) && $object->lines[$i]->volume) { + if (empty($object->lines[$i]->fk_product_type) && $object->lines[$i]->volume && !getDolGlobalString('SHIPPING_PDF_HIDE_VOLUME')) { $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, getDolGlobalInt('SHIPMENT_ROUND_VOLUME_ON_PDF', 5)).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1); } @@ -769,13 +769,13 @@ protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs if (!empty($totalWeight)) { $totalWeighttoshow = showDimensionInBestUnit($totalWeight, 0, "weight", $outputlangs, -1, 'no', 1); } - if (!empty($totalVolume)) { + if (!empty($totalVolume) && !getDolGlobalString('SHIPPING_PDF_HIDE_VOLUME')) { $totalVolumetoshow = showDimensionInBestUnit($totalVolume, 0, "volume", $outputlangs, -1, 'no', 1); } if (!empty($object->trueWeight)) { $totalWeighttoshow = showDimensionInBestUnit($object->trueWeight, (int) $object->weight_units, "weight", $outputlangs); } - if (!empty($object->trueVolume)) { + if (!empty($object->trueVolume) && !getDolGlobalString('SHIPPING_PDF_HIDE_VOLUME')) { $totalVolumetoshow = showDimensionInBestUnit($object->trueVolume, $object->volume_units, "volume", $outputlangs); }