From 3697d7f2aa1f25a06a4758dc8e7cd2927d0edf8f Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Mon, 7 Oct 2024 15:55:13 +0200 Subject: [PATCH 001/602] Fix: Grand total correction --- htdocs/core/tpl/list_print_total.tpl.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/tpl/list_print_total.tpl.php b/htdocs/core/tpl/list_print_total.tpl.php index 8900665eaeb..8990ce12984 100644 --- a/htdocs/core/tpl/list_print_total.tpl.php +++ b/htdocs/core/tpl/list_print_total.tpl.php @@ -64,7 +64,8 @@ if (isset($totalarray['pos'])) { while ($i < $totalarray['nbfield']) { $i++; if (!empty($totalarray['pos'][$i])) { - printTotalValCell($totalarray['type'][$i], $sumsarray[$totalarray['pos'][$i]]); + $fieldname = preg_replace('/[^a-z0-9]/', '', $totalarray['pos'][$i]); + printTotalValCell($totalarray['type'][$i], $sumsarray[$fieldname]); } else { if ($i == 1) { print ''; From 786905a6c8b341e9d52ec356fce9aab0bec35b63 Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Thu, 10 Oct 2024 09:16:32 +0200 Subject: [PATCH 002/602] Fix: Does not filter correctly by project contacts --- htdocs/core/lib/company.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 411fe6d0663..9a1ea12d88f 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -10,7 +10,7 @@ * Copyright (C) 2015-2024 Frédéric France * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2017 Rui Strecht - * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2018-2024 Ferran Marcet * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -1026,7 +1026,7 @@ function show_projects($conf, $langs, $db, $object, $backtopage = '', $nocreatel $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_contact as tc on ec.fk_c_type_contact = tc.rowid"; $sql .= " WHERE sc.fk_soc = ".((int) $object->id); $sql .= " AND p.entity IN (".getEntity('project').")"; - $sql .= " AND tc.element = 'project'"; + $sql .= " AND tc.element = 'project' AND tc.source = 'external'"; $sql .= " ORDER BY p.dateo DESC"; $result = $db->query($sql); From 4354165955958eb031f06bf5ba19bd70f704d941 Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Wed, 13 Nov 2024 10:31:47 +0100 Subject: [PATCH 003/602] Fix: Closed invoices are not considered as issued --- .../interface_20_modWorkflow_WorkflowManager.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index a816a83a428..5f291b9e5bd 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -2,7 +2,7 @@ /* Copyright (C) 2010 Regis Houssin * Copyright (C) 2011-2017 Laurent Destailleur * Copyright (C) 2014 Marcos García - * Copyright (C) 2022 Ferran Marcet + * Copyright (C) 2022-2024 Ferran Marcet * Copyright (C) 2023 Alexandre Janniaux * Copyright (C) 2024 MDW * @@ -248,7 +248,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers $totalHTInvoices = 0; $areAllInvoicesValidated = true; foreach ($orderLinked->linkedObjects['facture'] as $key => $invoice) { - if ($invoice->statut == Facture::STATUS_VALIDATED || $object->id == $invoice->id) { + if ($invoice->statut == Facture::STATUS_VALIDATED || $invoice->statut == Facture::STATUS_CLOSED || $object->id == $invoice->id) { $totalHTInvoices += (float) $invoice->total_ht; } else { $areAllInvoicesValidated = false; From 007860ae81859a755fdcb95fc4b3b1c68b3e9a8c Mon Sep 17 00:00:00 2001 From: Nicolas Date: Sat, 16 Nov 2024 17:53:53 +0100 Subject: [PATCH 004/602] NEW Closing task --- htdocs/core/lib/project.lib.php | 8 +++++ htdocs/projet/class/task.class.php | 53 ++++++++++++++++++++++++++++++ htdocs/projet/tasks.php | 15 +++++++++ htdocs/projet/tasks/task.php | 29 +++++++++++++++- 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 95566b86a53..f3921b19502 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -701,6 +701,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t $taskstatic->duration_effective = $lines[$i]->duration_effective; $taskstatic->budget_amount = $lines[$i]->budget_amount; $taskstatic->billable = $lines[$i]->billable; + $taskstatic->fk_statut = $lines[$i]->fk_statut; // Action column if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { @@ -953,6 +954,13 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t print ''; } + // Status + if (count($arrayfields) > 0 && !empty($arrayfields['t.fk_statut']['checked'])) { + print ''; + print $taskstatic->getLibStatut(5); + print ''; + } + // Extra fields $extrafieldsobjectkey = $taskstatic->table_element; $extrafieldsobjectprefix = 'efpt.'; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index f7688bec283..1f18dae8220 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -765,6 +765,59 @@ class Task extends CommonObjectLine } + /** + * Close task from database + * @param User $user User that close + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int Return integer <0 if KO, >0 if OK + */ + public function close($user,$notrigger = 0) { + + global $conf; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + $this->db->begin(); + + dol_syslog(get_class($this)."::close record task", LOG_DEBUG); + + $sql = " UPDATE ".MAIN_DB_PREFIX."projet_task "; + $sql.= "SET fk_statut=".$this::STATUS_CLOSED." WHERE rowid=".(int) $this->id; + + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = "Error ".$this->db->lasterror(); + } + + if (!$error) { + if (!$notrigger) { + // Call trigger + $result = $this->call_trigger('TASK_CLOSE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + } + + // Commit or rollback + if ($error) { + foreach ($this->errors as $errmsg) { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error .= ($this->error ? ', '.$errmsg : $errmsg); + } + $this->db->rollback(); + return -1 * $error; + } else { + $this->db->commit(); + return 1; + } + + } + + /** * Delete task from database * diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 632aa18b6a4..760cebdf120 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -98,6 +98,7 @@ $search_progresscalc = GETPOST('search_progresscalc'); $search_progressdeclare = GETPOST('search_progressdeclare'); $search_task_budget_amount = GETPOST('search_task_budget_amount'); $search_task_billable = GETPOST('search_task_billable'); +$search_fk_statut = GETPOSTINT('search_fk_statut'); $search_date_start_startmonth = GETPOSTINT('search_date_start_startmonth'); $search_date_start_startyear = GETPOSTINT('search_date_start_startyear'); @@ -183,6 +184,8 @@ $arrayfields = array( 't.progress_summary' => array('label' => "TaskProgressSummary", 'checked' => 1, 'position' => 10), 't.budget_amount' => array('label' => "Budget", 'checked' => 0, 'position' => 11), 'c.assigned' => array('label' => "TaskRessourceLinks", 'checked' => 1, 'position' => 12), + 't.fk_statut' => array('label' => "Status", 'checked' => 1, 'position' => 12), + ); if ($object->usage_bill_time) { $arrayfields['t.tobill'] = array('label' => $langs->trans("TimeToBill"), 'checked' => 0, 'position' => 11); @@ -248,6 +251,7 @@ if (empty($reshook)) { $search_progressdeclare = ''; $search_task_budget_amount = ''; $search_task_billable = ''; + $search_fk_statut = ''; $toselect = array(); $search_array_options = array(); $search_date_start_startmonth = ""; @@ -332,6 +336,9 @@ if ($search_task_budget_amount) { if ($search_task_billable) { $morewherefilterarray[] = " t.billable = ".($search_task_billable == "yes" ? 1 : 0); } +if ($search_fk_statut) { + $morewherefilterarray[] = " t.fk_statut = ".$search_fk_statut; +} //var_dump($morewherefilterarray); $morewherefilter = ''; @@ -1082,6 +1089,10 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- print $form->selectyesno('search_task_billable', $search_task_billable, 0, false, 1); print ''; } + if (!empty($arrayfields['t.fk_statut']['checked'])) { + print ''; + print ''; + } include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -1160,6 +1171,10 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- if (!empty($arrayfields['t.billable']['checked'])) { print_liste_field_titre($arrayfields['t.billable']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', ''); } + + if (!empty($arrayfields['t.fk_statut']['checked'])) { + print_liste_field_titre($arrayfields['t.fk_statut']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', ''); + } // Extra fields $disablesortlink = 1; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 68ff3707182..b75d3e2f0f9 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -208,6 +208,19 @@ if ($action == 'confirm_delete' && $confirm == "yes" && $user->hasRight('projet' } } +if ($action == 'confirm_close' && $confirm == "yes" && $user->hasRight('projet', 'creer')) { + $result = $projectstatic->fetch($object->fk_project); + $projectstatic->fetch_thirdparty(); + + if ($object->close($user) > 0) { + header('Location: '.DOL_URL_ROOT.'/projet/tasks.php?restore_lastsearch_values=1&id='.$projectstatic->id.($withproject ? '&withproject=1' : '')); + exit; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $action = ''; + } +} + // Retrieve First Task ID of Project if withprojet is on to allow project prev next to work if (!empty($project_ref) && !empty($withproject)) { if ($projectstatic->fetch(0, $project_ref) > 0) { @@ -579,6 +592,14 @@ if ($id > 0 || !empty($ref)) { print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ToClone"), $langs->trans("ConfirmCloneTask"), "confirm_clone", $formquestion, '', 1, 300, 590); } + if ($action == 'close') { + $formquestion = array( + 'text' => $langs->trans("ConfirmClose"), + ); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ToClose"), $langs->trans("ConfirmCloseTask"), "confirm_close", $formquestion, '', 1, 300, 590); + } + + if ($action == 'merge') { $formquestion = array( array( @@ -701,6 +722,7 @@ if ($id > 0 || !empty($ref)) { print ''.($object->billable ? $langs->trans('Yes') : $langs->trans('No')).''; print ''; + // Other attributes $cols = 3; $parameters = array('socid' => $socid); @@ -730,11 +752,16 @@ if ($id > 0 || !empty($ref)) { if (empty($reshook)) { // Modify if ($user->hasRight('projet', 'creer')) { - print ''.$langs->trans('Modify').''; + if ($object->fk_statut != $object::STATUS_CLOSED) + print ''.$langs->trans('Modify').''; print ''.$langs->trans('Clone').''; print ''.$langs->trans('Merge').''; + + if ($object->fk_statut != $object::STATUS_CLOSED) + print ''.$langs->trans('Close').''; } else { print ''.$langs->trans('Modify').''; + } // Delete From ee1b3df3f11f0a9df571a80c1c21d30f6362b512 Mon Sep 17 00:00:00 2001 From: William Mead Date: Sat, 16 Nov 2024 18:42:01 +0100 Subject: [PATCH 005/602] Fixed task closed confirm localisation --- htdocs/langs/en_US/projects.lang | 2 ++ htdocs/projet/tasks/task.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index a6f6175ce50..22f6e3f3559 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -312,3 +312,5 @@ TaskMergeSuccess=Tasks have been merged ErrorTaskIdIsMandatory=Error: Task id is mandatory ErrorsTaskMerge=An error occurred while merging tasks Billable = Billable +ConfirmCloseTask=Are you sure you want to close this task ? +ConfirmClosed=Confirm task closed diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index b75d3e2f0f9..0af8a5c26ce 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -594,7 +594,7 @@ if ($id > 0 || !empty($ref)) { if ($action == 'close') { $formquestion = array( - 'text' => $langs->trans("ConfirmClose"), + 'text' => $langs->trans("ConfirmClosed"), ); print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ToClose"), $langs->trans("ConfirmCloseTask"), "confirm_close", $formquestion, '', 1, 300, 590); } From 4cab9e8a6232f0313ea314053d361fc9dd24a05d Mon Sep 17 00:00:00 2001 From: William Mead Date: Sat, 16 Nov 2024 23:34:10 +0100 Subject: [PATCH 006/602] Fixed & refactored status label --- htdocs/core/lib/project.lib.php | 3 ++- htdocs/projet/class/task.class.php | 16 ++++++++-------- htdocs/projet/tasks.php | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index f3921b19502..89a70dc2329 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -701,6 +701,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t $taskstatic->duration_effective = $lines[$i]->duration_effective; $taskstatic->budget_amount = $lines[$i]->budget_amount; $taskstatic->billable = $lines[$i]->billable; + $taskstatic->status = $lines[$i]->status; $taskstatic->fk_statut = $lines[$i]->fk_statut; // Action column @@ -957,7 +958,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t // Status if (count($arrayfields) > 0 && !empty($arrayfields['t.fk_statut']['checked'])) { print ''; - print $taskstatic->getLibStatut(5); + print $taskstatic->getLibStatut(4); print ''; } diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 1f18dae8220..77203f5cfbc 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -2498,12 +2498,12 @@ class Task extends CommonObjectLine $this->labelStatus[0] = 'Draft'; $this->labelStatus[1] = 'ToDo'; $this->labelStatus[2] = 'Running'; - $this->labelStatus[3] = 'Finish'; + $this->labelStatus[3] = 'Closed'; $this->labelStatus[4] = 'Transfered'; $this->labelStatusShort[0] = 'Draft'; $this->labelStatusShort[1] = 'ToDo'; $this->labelStatusShort[2] = 'Running'; - $this->labelStatusShort[3] = 'Completed'; + $this->labelStatusShort[3] = 'Closed'; $this->labelStatusShort[4] = 'Transfered'; if ($mode == 0) { @@ -2540,17 +2540,17 @@ class Task extends CommonObjectLine } } elseif ($mode == 4) { if ($status == 0) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut0').' '.$langs->trans($this->labelStatus[$status]); + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status0', $mode); } elseif ($status == 1) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut1').' '.$langs->trans($this->labelStatus[$status]); + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status1', $mode); } elseif ($status == 2) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut3').' '.$langs->trans($this->labelStatus[$status]); + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status2', $mode); } elseif ($status == 3) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6').' '.$langs->trans($this->labelStatus[$status]); + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status3', $mode); } elseif ($status == 4) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6').' '.$langs->trans($this->labelStatus[$status]); + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status4', $mode); } elseif ($status == 5) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut5').' '.$langs->trans($this->labelStatus[$status]); + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status5', $mode); } } elseif ($mode == 5) { /*if ($status==0) return $langs->trans($this->labelStatusShort[$status]).' '.img_picto($langs->trans($this->labelStatusShort[$status]),'statut0'); diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 760cebdf120..e28d70853ad 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -1091,6 +1091,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- } if (!empty($arrayfields['t.fk_statut']['checked'])) { print ''; + //TODO: add status filter print ''; } From 0cb35d5b03ec8664cff82327c71fa65fbaaaef84 Mon Sep 17 00:00:00 2001 From: John BOTELLA <68917336+thersane-john@users.noreply.github.com> Date: Sat, 23 Nov 2024 09:15:34 +0100 Subject: [PATCH 007/602] New doc for icon list --- .../tools/ui/class/documentation.class.php | 6 + .../tools/ui/components/event-message.php | 2 +- htdocs/admin/tools/ui/components/icons.php | 131 ++++++++++++++++++ htdocs/admin/tools/ui/css/documentation.css | 6 +- htdocs/langs/en_US/uxdocumentation.lang | 5 + 5 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 htdocs/admin/tools/ui/components/icons.php diff --git a/htdocs/admin/tools/ui/class/documentation.class.php b/htdocs/admin/tools/ui/class/documentation.class.php index 584f6c36a7f..8d498125adb 100644 --- a/htdocs/admin/tools/ui/class/documentation.class.php +++ b/htdocs/admin/tools/ui/class/documentation.class.php @@ -126,6 +126,12 @@ class Documentation 'DocButtonSubmenu' => '#buttonsection-submenu', ), ), + 'Icons' => array( + 'url' => dol_buildpath($baseUrl.'/components/icons.php', 1), + 'icon' => 'far fa-flag pictofixedwidth', + 'submenu' => array(), + 'summary' => array(), + ), 'Progress' => array( 'url' => dol_buildpath($baseUrl.'/components/progress-bars.php', 1), 'icon' => 'fas fa-battery-half pictofixedwidth', diff --git a/htdocs/admin/tools/ui/components/event-message.php b/htdocs/admin/tools/ui/components/event-message.php index 98e3080c7d3..2e60227fcc3 100644 --- a/htdocs/admin/tools/ui/components/event-message.php +++ b/htdocs/admin/tools/ui/components/event-message.php @@ -104,7 +104,7 @@ $documentation->showSidebar(); ?> $lines = array( ' + * + * This program and files/directory inner it is free software: you can + * redistribute it and/or modify it under the terms of the + * GNU Affero General Public License (AGPL) 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 AGPL for more details. + * + * You should have received a copy of the GNU AGPL + * along with this program. If not, see . + */ + +$res=0; +if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; +endif; +if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; +endif; +if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; +endif; + +// Protection if external user +if ($user->socid > 0) : accessforbidden(); +endif; + +// Includes +dol_include_once('admin/tools/ui/class/documentation.class.php'); + +// Load documentation translations +$langs->load('uxdocumentation'); + +// +$documentation = new Documentation($db); + +// Output html head + body - Param is Title +$documentation->docHeader('Icons'); + +// Set view for menu and breadcrumb +// Menu must be set in constructor of documentation class +$documentation->view = array('Components','Icons'); + +// Output sidebar +$documentation->showSidebar(); ?> + +
+ + showBreadCrumb(); ?> + +
+ +

trans('DocIconsTitle'); ?>

+

trans('DocIconsMainDescription'); ?>

+ + + showSummary(); ?> + + +
+ + + +

trans('DocIconsList'); ?>

+ trans('DocDocIconsListDescription'); ?>

*/ ?> + + +
+ +
+ + '; + + + print '
+ + '.$iconCode.' + +
+
'. ($iconData[2]??($iconData[0]??'')) .'
+
+
+
+
'.dol_htmlentities($iconCode).'
+
+
+
+
+
'; + } + } + ?> +
+
+
+ +
+
+ +docFooter(); +?> diff --git a/htdocs/admin/tools/ui/css/documentation.css b/htdocs/admin/tools/ui/css/documentation.css index 0bee0aae2bf..3dbd1abdfb2 100644 --- a/htdocs/admin/tools/ui/css/documentation.css +++ b/htdocs/admin/tools/ui/css/documentation.css @@ -78,8 +78,12 @@ body.dolibarr-doc { .doc-wrapper .doc-content-wrapper .documentation-section h2.documentation-title {margin: 0;margin-bottom:16px;padding: 0;color: rgb(38,60,92);} .doc-wrapper .doc-content-wrapper .documentation-section .documentation-example {border:1px dashed #ccc;box-sizing: border-box;padding: 16px;margin-bottom: 16px;} .doc-wrapper .doc-content-wrapper .documentation-section .documentation-code {background: var(--colorbacklinepairchecked);border:1px dashed #ccc;box-sizing: border-box;padding: 16px;margin-bottom: 16px;overflow: auto;} +.doc-wrapper .doc-content-wrapper .documentation-section .info-box .documentation-code {padding: 3px 16px; margin-bottom: 5px;} .doc-wrapper .doc-content-wrapper .documentation-section .documentation-code pre {margin: 0;padding: 0;tab-size: 24px;} /* Documentation scroll indicator */ #documentation-scrollwrapper {height: 5px;position: fixed;bottom: 0;left: 260px;right:0;z-index: 99;} -#documentation-scroll {background: rgb(0, 123, 140);height: 5px;position: absolute;top: 0;left:0} \ No newline at end of file +#documentation-scroll {background: rgb(0, 123, 140);height: 5px;position: absolute;top: 0;left:0} + +/* component icons */ +.documentation-fontawesome-icon-list span{ color: #333; } diff --git a/htdocs/langs/en_US/uxdocumentation.lang b/htdocs/langs/en_US/uxdocumentation.lang index 56d3c587185..d8df8d0de27 100644 --- a/htdocs/langs/en_US/uxdocumentation.lang +++ b/htdocs/langs/en_US/uxdocumentation.lang @@ -79,3 +79,8 @@ DocSetEventMessage = Message #%s DocButtonIconsLowEmphasis = Low emphasis icon buttons DocButtonIconsDescriptionLowEmphasis = An icon button with low emphasis is typically a button that includes only an icon (no accompanying text) and has minimal styling to make it unobtrusive. Icon buttons with low emphasis are ideal for secondary or tertiary actions, like clear field, fill field, bookmarking, or sharing, especially in interfaces that have more prominent primary actions (like "Submit" or "Continue"). DocButtonIconsForTitle = Buttons for list title + +# Fontawesome icons +DocIconsTitle = Icons used by Dolibarr +DocIconsMainDescription = Dolibarr use a part of fontawesome 5 icons +DocIconsList = List of usable font icons From 469baa0b5bac7d6b4778216d08c8cf579894f77f Mon Sep 17 00:00:00 2001 From: John BOTELLA <68917336+thersane-john@users.noreply.github.com> Date: Sat, 23 Nov 2024 17:53:12 +0100 Subject: [PATCH 008/602] remove double --- htdocs/admin/tools/ui/components/icons.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/admin/tools/ui/components/icons.php b/htdocs/admin/tools/ui/components/icons.php index d0261f884aa..0b47d4d10d5 100644 --- a/htdocs/admin/tools/ui/components/icons.php +++ b/htdocs/admin/tools/ui/components/icons.php @@ -88,6 +88,7 @@ $documentation->showSidebar(); ?>
showSidebar(); ?> $class.= ' fa-'.$iconData[0]??''; } + if (in_array($class, $alreadyDisplay)) { + continue; + } + + $alreadyDisplay[] = $class; $iconCode = ''; From 0df412b6be718c2389a7ed87ff062b4aba86c030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 18:24:15 +0100 Subject: [PATCH 009/602] refactor loan schedule --- htdocs/core/lib/loan.lib.php | 16 ++++++---- htdocs/loan/schedule.php | 57 +++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/htdocs/core/lib/loan.lib.php b/htdocs/core/lib/loan.lib.php index 3de9f42290b..88b5146eff9 100644 --- a/htdocs/core/lib/loan.lib.php +++ b/htdocs/core/lib/loan.lib.php @@ -1,8 +1,8 @@ - * Copyright (C) 2015-2020 Frederic France + * Copyright (C) 2015-2024 Frédéric France * Copyright (C) 2020 Maxime DEMAREST - * Copyright (C) 2024 MDW + * Copyright (C) 2024 MDW * * 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 @@ -98,7 +98,7 @@ function loan_prepare_head($object) * @param float $rate Loan rate * @param int $numactualloadterm Actual loan term * @param int $nbterm Total number of term for this loan - * @return array Array with remaining capital, interest, and mensuality for each remaining terms + * @return array Array with remaining capital, interest, and mensuality for each remaining terms */ function loanCalcMonthlyPayment($mens, $capital, $rate, $numactualloadterm, $nbterm) { @@ -123,7 +123,13 @@ function loanCalcMonthlyPayment($mens, $capital, $rate, $numactualloadterm, $nbt $int = round($int, 2, PHP_ROUND_HALF_UP); $cap_rest = round((float) $capital - ((float) $mens - $int), 2, PHP_ROUND_HALF_UP); } - $output[$numactualloadterm] = array('cap_rest' => $cap_rest, 'cap_rest_str' => price($cap_rest, 0, '', 1, -1, -1, $conf->currency), 'interet' => $int, 'interet_str' => price($int, 0, '', 1, -1, -1, $conf->currency), 'mens' => $mens); + $output[$numactualloadterm] = array( + 'cap_rest' => $cap_rest, + 'cap_rest_str' => price($cap_rest, 0, '', 1, -1, -1, $conf->currency), + 'interet' => $int, + 'interet_str' => price($int, 0, '', 1, -1, -1, $conf->currency), + 'mens' => price($mens), + ); $numactualloadterm++; $capital = $cap_rest; @@ -139,7 +145,7 @@ function loanCalcMonthlyPayment($mens, $capital, $rate, $numactualloadterm, $nbt 'cap_rest_str' => price($cap_rest, 0, '', 1, -1, -1, $conf->currency), 'interet' => $int, 'interet_str' => price($int, 0, '', 1, -1, -1, $conf->currency), - 'mens' => $mens, + 'mens' => price($mens), ); $capital = $cap_rest; $numactualloadterm++; diff --git a/htdocs/loan/schedule.php b/htdocs/loan/schedule.php index e48ff1fe773..23e6c561dfd 100644 --- a/htdocs/loan/schedule.php +++ b/htdocs/loan/schedule.php @@ -214,34 +214,45 @@ dol_banner_tab($object, 'loanid', $linkback, 1, 'rowid', 'ref', $morehtmlref, '' ?> nbterm > 0 && count($echeances->lines) == 0) { print ''.dol_print_date(dol_time_plus_duree($object->datestart, $i - 1, 'm'), 'day').''; print ''.price($insu, 0, '', 1, -1, -1, $conf->currency).''; print ''.price($int, 0, '', 1, -1, -1, $conf->currency).''; - print ''; + print ''; print ''.price($cap_rest).''; print ''."\n"; $i++; @@ -327,7 +338,7 @@ if ($object->nbterm > 0 && count($echeances->lines) == 0) { print ''.price($insu, 0, '', 1, -1, -1, $conf->currency).''; print ''.price($int, 0, '', 1, -1, -1, $conf->currency).''; if (empty($line->fk_bank)) { - print ''; + print ''; } else { print ''.price($mens, 0, '', 1, -1, -1, $conf->currency).''; } From c642396dcaaca6cc1e26fe120306ab7f9016cce8 Mon Sep 17 00:00:00 2001 From: John BOTELLA <68917336+thersane-john@users.noreply.github.com> Date: Sat, 23 Nov 2024 18:26:40 +0100 Subject: [PATCH 010/602] Add List of usable icons with img_picto function --- .../tools/ui/class/documentation.class.php | 5 +- htdocs/admin/tools/ui/components/icons.php | 55 +++++++++++- htdocs/core/lib/functions.lib.php | 85 +++++++++++-------- htdocs/langs/en_US/uxdocumentation.lang | 3 +- 4 files changed, 106 insertions(+), 42 deletions(-) diff --git a/htdocs/admin/tools/ui/class/documentation.class.php b/htdocs/admin/tools/ui/class/documentation.class.php index 8d498125adb..183d89b547f 100644 --- a/htdocs/admin/tools/ui/class/documentation.class.php +++ b/htdocs/admin/tools/ui/class/documentation.class.php @@ -130,7 +130,10 @@ class Documentation 'url' => dol_buildpath($baseUrl.'/components/icons.php', 1), 'icon' => 'far fa-flag pictofixedwidth', 'submenu' => array(), - 'summary' => array(), + 'summary' => array( + 'DocIconsList' => '#img-picto-section-list', + 'DocIconsFontAwesomeList' => '#icon-section-list', + ), ), 'Progress' => array( 'url' => dol_buildpath($baseUrl.'/components/progress-bars.php', 1), diff --git a/htdocs/admin/tools/ui/components/icons.php b/htdocs/admin/tools/ui/components/icons.php index 0b47d4d10d5..e8f8b365f97 100644 --- a/htdocs/admin/tools/ui/components/icons.php +++ b/htdocs/admin/tools/ui/components/icons.php @@ -60,7 +60,58 @@ $documentation->showSidebar(); ?> showSummary(); ?> - + + +
+ + + +

trans('DocIconsList'); ?>

+ trans('DocDocIconsListDescription'); ?>

*/ ?> +
+
+ + + '.$iconCode.' + +
+
'. $iconName .'
+
+
+
+
'.dol_htmlentities('img_picto(\''.$labelAlt.'\', '.$iconName.')').'
+
+
+
+
+
'; + } + ?> +
+
+
+ + + +
showSidebar(); ?>

trans('DocIconsList'); ?>

trans('DocDocIconsListDescription'); ?>

*/ ?> - -
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index d2609495d49..3e103e06931 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5065,43 +5065,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0, $srco return $enabledisablehtml; } - if (empty($srconly) && in_array($pictowithouttext, array( - '1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected', - 'accountancy', 'accounting_account', 'account', 'accountline', 'action', 'add', 'address', 'ai', 'angle-double-down', 'angle-double-up', 'asset', - 'back', 'bank_account', 'barcode', 'bank', 'bell', 'bill', 'billa', 'billr', 'billd', 'birthday-cake', 'bom', 'bookcal', 'bookmark', 'briefcase-medical', 'bug', 'building', - 'card', 'calendarlist', 'calendar', 'calendarmonth', 'calendarweek', 'calendarday', 'calendarperuser', 'calendarpertype', 'hourglass', - 'cash-register', 'category', 'chart', 'check', 'clock', 'clone', 'close_title', 'code', 'cog', 'collab', 'company', 'contact', 'country', 'contract', 'conversation', 'cron', 'cross', 'cubes', - 'check-circle', 'check-square', 'circle', 'stop-circle', 'currency', 'multicurrency', - 'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', - 'chevron-double-left', 'chevron-double-right', 'chevron-double-down', 'chevron-double-top', - 'commercial', 'companies', - 'delete', 'dolly', 'dollyrevert', 'donation', 'download', 'dynamicprice', - 'edit', 'ellipsis-h', 'email', 'entity', 'envelope', 'eraser', 'establishment', 'expensereport', 'external-link-alt', 'external-link-square-alt', 'eye', - 'filter', 'file', 'file-o', 'file-code', 'file-export', 'file-import', 'file-upload', 'autofill', 'folder', 'folder-open', 'folder-plus', 'font', - 'gears', 'generate', 'generic', 'globe', 'globe-americas', 'graph', 'grip', 'grip_title', 'group', - 'hands-helping', 'help', 'holiday', - 'id-card', 'images', 'incoterm', 'info', 'intervention', 'inventory', 'intracommreport', 'jobprofile', - 'key', 'knowledgemanagement', - 'label', 'language', 'layout', 'line', 'link', 'list', 'list-alt', 'listlight', 'loan', 'lock', 'lot', 'long-arrow-alt-right', - 'margin', 'map-marker-alt', 'member', 'meeting', 'minus', 'money-bill-alt', 'movement', 'mrp', 'note', 'next', - 'off', 'on', 'order', - 'paiment', 'paragraph', 'play', 'pdf', 'phone', 'phoning', 'phoning_mobile', 'phoning_fax', 'playdisabled', 'previous', 'poll', 'pos', 'printer', 'product', 'propal', 'proposal', 'puce', - 'stock', 'resize', 'service', 'stats', - 'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'switch_on_grey', 'switch_on_warning', 'switch_on_red', 'tools', 'unlink', 'uparrow', 'user', 'user-tie', 'vcard', 'wrench', - 'github', 'google', 'jabber', 'microsoft', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp', - 'generic', 'home', 'hrm', 'members', 'products', 'invoicing', - 'partnership', 'payment', 'payment_vat', 'pencil-ruler', 'pictoconfirm', 'preview', 'project', 'projectpub', 'projecttask', 'question', 'refresh', 'region', - 'salary', 'shipment', 'state', 'supplier_invoice', 'supplier_invoicea', 'supplier_invoicer', 'supplier_invoiced', - 'technic', 'ticket', - 'error', 'warning', - 'recent', 'reception', 'recruitmentcandidature', 'recruitmentjobposition', 'replacement', 'resource', 'recurring','rss', - 'shapes', 'skill', 'square', 'sort-numeric-down', 'status', 'stop-circle', 'supplier', 'supplier_proposal', 'supplier_order', 'supplier_invoice', - 'terminal', 'tick', 'timespent', 'title_setup', 'title_accountancy', 'title_bank', 'title_hrm', 'title_agenda', 'trip', - 'uncheck', 'undo', 'url', 'user-cog', 'user-injured', 'user-md', 'vat', 'website', 'workstation', 'webhook', 'world', 'private', - 'conferenceorbooth', 'eventorganization', - 'stamp', 'signature', - 'webportal' - ))) { + if (empty($srconly) && in_array($pictowithouttext, getImgPictoNameList())) { $fakey = $pictowithouttext; $facolor = ''; $fasize = ''; @@ -5337,6 +5301,53 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0, $srco return ''.dol_escape_htmltag($alt).''; // Alt is used for accessibility, title for popup } +/** + * Get all usage icon name for img_picto + * @return string[] + */ +function getImgPictoNameList() +{ + + return array( + '1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected', + 'accountancy', 'accounting_account', 'account', 'accountline', 'action', 'add', 'address', 'ai', 'angle-double-down', 'angle-double-up', 'asset', + 'back', 'bank_account', 'barcode', 'bank', 'bell', 'bill', 'billa', 'billr', 'billd', 'birthday-cake', 'bom', 'bookcal', 'bookmark', 'briefcase-medical', 'bug', 'building', + 'card', 'calendarlist', 'calendar', 'calendarmonth', 'calendarweek', 'calendarday', 'calendarperuser', 'calendarpertype', 'hourglass', + 'cash-register', 'category', 'chart', 'check', 'clock', 'clone', 'close_title', 'code', 'cog', 'collab', 'company', 'contact', 'country', 'contract', 'conversation', 'cron', 'cross', 'cubes', + 'check-circle', 'check-square', 'circle', 'stop-circle', 'currency', 'multicurrency', + 'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', + 'chevron-double-left', 'chevron-double-right', 'chevron-double-down', 'chevron-double-top', + 'commercial', 'companies', + 'delete', 'dolly', 'dollyrevert', 'donation', 'download', 'dynamicprice', + 'edit', 'ellipsis-h', 'email', 'entity', 'envelope', 'eraser', 'establishment', 'expensereport', 'external-link-alt', 'external-link-square-alt', 'eye', + 'filter', 'file', 'file-o', 'file-code', 'file-export', 'file-import', 'file-upload', 'autofill', 'folder', 'folder-open', 'folder-plus', 'font', + 'gears', 'generate', 'generic', 'globe', 'globe-americas', 'graph', 'grip', 'grip_title', 'group', + 'hands-helping', 'help', 'holiday', + 'id-card', 'images', 'incoterm', 'info', 'intervention', 'inventory', 'intracommreport', 'jobprofile', + 'key', 'knowledgemanagement', + 'label', 'language', 'layout', 'line', 'link', 'list', 'list-alt', 'listlight', 'loan', 'lock', 'lot', 'long-arrow-alt-right', + 'margin', 'map-marker-alt', 'member', 'meeting', 'minus', 'money-bill-alt', 'movement', 'mrp', 'note', 'next', + 'off', 'on', 'order', + 'paiment', 'paragraph', 'play', 'pdf', 'phone', 'phoning', 'phoning_mobile', 'phoning_fax', 'playdisabled', 'previous', 'poll', 'pos', 'printer', 'product', 'propal', 'proposal', 'puce', + 'stock', 'resize', 'service', 'stats', + 'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'switch_on_grey', 'switch_on_warning', 'switch_on_red', 'tools', 'unlink', 'uparrow', 'user', 'user-tie', 'vcard', 'wrench', + 'github', 'google', 'jabber', 'microsoft', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp', + 'generic', 'home', 'hrm', 'members', 'products', 'invoicing', + 'partnership', 'payment', 'payment_vat', 'pencil-ruler', 'pictoconfirm', 'preview', 'project', 'projectpub', 'projecttask', 'question', 'refresh', 'region', + 'salary', 'shipment', 'state', 'supplier_invoice', 'supplier_invoicea', 'supplier_invoicer', 'supplier_invoiced', + 'technic', 'ticket', + 'error', 'warning', + 'recent', 'reception', 'recruitmentcandidature', 'recruitmentjobposition', 'replacement', 'resource', 'recurring', 'rss', + 'shapes', 'skill', 'square', 'sort-numeric-down', 'status', 'stop-circle', 'supplier', 'supplier_proposal', 'supplier_order', 'supplier_invoice', + 'terminal', 'tick', 'timespent', 'title_setup', 'title_accountancy', 'title_bank', 'title_hrm', 'title_agenda', 'trip', + 'uncheck', 'undo', 'url', 'user-cog', 'user-injured', 'user-md', 'vat', 'website', 'workstation', 'webhook', 'world', 'private', + 'conferenceorbooth', 'eventorganization', + 'stamp', 'signature', + 'webportal' + ); +} + + /** * Show a picto called object_picto (generic function) * diff --git a/htdocs/langs/en_US/uxdocumentation.lang b/htdocs/langs/en_US/uxdocumentation.lang index d8df8d0de27..590a150fccf 100644 --- a/htdocs/langs/en_US/uxdocumentation.lang +++ b/htdocs/langs/en_US/uxdocumentation.lang @@ -82,5 +82,6 @@ DocButtonIconsForTitle = Buttons for list title # Fontawesome icons DocIconsTitle = Icons used by Dolibarr +DocIconsList = List of usable icons with img_picto function DocIconsMainDescription = Dolibarr use a part of fontawesome 5 icons -DocIconsList = List of usable font icons +DocIconsFontAwesomeList = List of usable fontawesome icons From eb7faffec27b8294c76907a60b27e8fcfa786f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 18:49:12 +0100 Subject: [PATCH 011/602] refactor loan schedule --- htdocs/loan/payment/payment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php index 435e95efa60..0e1023315fa 100644 --- a/htdocs/loan/payment/payment.php +++ b/htdocs/loan/payment/payment.php @@ -198,7 +198,7 @@ if ($action == 'add_payment' && $permissiontoadd) { $ls->lines[$k - 1]->fk_bank = $payment->fk_bank; $ls->lines[$k - 1]->fk_payment_loan = $payment->id; } - $ls->lines[$k - 1]->amount_capital = $v['mens'] - $v['interet']; + $ls->lines[$k - 1]->amount_capital = ((float) price2num($v['mens'])) - $v['interet']; $ls->lines[$k - 1]->amount_interest = $v['interet']; $ls->lines[$k - 1]->tms = dol_now(); $ls->lines[$k - 1]->fk_user_modif = $user->id; From 343873c82f1aa8936a31e677209f48f777bb3d26 Mon Sep 17 00:00:00 2001 From: David Beniamine Date: Thu, 7 Nov 2024 23:42:03 +0100 Subject: [PATCH 012/602] Once payment is complet, a click on a product should start a new sale --- htdocs/takepos/index.php | 5 +++++ htdocs/takepos/pay.php | 1 + 2 files changed, 6 insertions(+) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index a92bc4cac53..c9fb88f2ed0 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -527,6 +527,10 @@ function MoreProducts(moreorless) { function ClickProduct(position, qty = 1) { console.log("ClickProduct at position"+position); + if ($('#invoiceid').val() == "") { + invoiceid = $('#invoiceid').val(); + Refresh(); + } $('#proimg'+position).animate({opacity: '0.5'}, 1); $('#proimg'+position).animate({opacity: '1'}, 100); if ($('#prodiv'+position).data('iscat')==1){ @@ -1015,6 +1019,7 @@ function ModalBox(ModalID) function DirectPayment(){ console.log("DirectPayment"); $("#poslines").load("invoice.php?place="+place+"&action=valid&token=&pay=LIQ", function() { + $('#invoiceid').val(""); }); } diff --git a/htdocs/takepos/pay.php b/htdocs/takepos/pay.php index d2ee2999100..492419e264d 100644 --- a/htdocs/takepos/pay.php +++ b/htdocs/takepos/pay.php @@ -352,6 +352,7 @@ if (!getDolGlobalInt("TAKEPOS_NUMPAD")) { parent.$("#poslines").load("invoice.php?place=&action=valid&token=&pay="+payment+"&amount="+amountpayed+"&excess="+excess+"&invoiceid="+invoiceid+"&accountid="+accountid, function() { if (amountpayed > || amountpayed == || amountpayed==0 ) { console.log("Close popup"); + parent.$('#invoiceid').val(""); parent.$.colorbox.close(); } else { From 9ae5c03f28ce1f715a66bb9f0452f7932c199efa Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 2 Dec 2024 09:47:43 +0100 Subject: [PATCH 013/602] FIX #32186 --- htdocs/fourn/facture/list.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index e6597b29ce3..086995608dd 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -307,7 +307,6 @@ if (empty($reshook)) { $search_categ_sup = 0; $filter = ''; $option = ''; - $socid = ""; } // Mass actions From d4236332661beb85ae94f8647ebfe2e55f6f5c83 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 2 Dec 2024 10:36:54 +0100 Subject: [PATCH 014/602] FIX phan errors --- htdocs/fourn/commande/list.php | 1 + htdocs/fourn/facture/card.php | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 5a80dc98f81..d806ef812d3 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -511,6 +511,7 @@ if (empty($reshook)) { } $tva_tx = $lines[$i]->tva_tx; + // @phan-suppress-next-line PhanTypeMismatchArgumentInternal if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) { $tva_tx .= ' ('.$lines[$i]->vat_src_code.')'; } diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 609270a284a..fe3507a8344 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1339,6 +1339,7 @@ if (empty($reshook)) { } $tva_tx = $lines[$i]->tva_tx; + // @phan-suppress-next-line PhanTypeMismatchArgumentInternal if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) { $tva_tx .= ' ('.$lines[$i]->vat_src_code.')'; } From 6aa70da43f232f50170074ba4cf2bce6d0ecd680 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 2 Dec 2024 11:24:03 +0100 Subject: [PATCH 015/602] FIX wrong "fournisseur" var value checking --- htdocs/societe/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 53842b8b2d8..28b3b7250a5 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1388,7 +1388,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio if (getDolGlobalString('THIRDPARTY_SUPPLIER_BY_DEFAULT')) { $default = 1; } - print $form->selectyesno("fournisseur", (GETPOSTINT('fournisseur') != '' ? GETPOSTINT('fournisseur') : (GETPOST("type") == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type") == '' ? 1 : 0), 1); + print $form->selectyesno("fournisseur", (GETPOSTINT('fournisseur') > 0 ? GETPOSTINT('fournisseur') : (GETPOST("type") == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type") == '' ? 1 : 0), 1); print ''; From 2beb6e1e3495fd43d4c26037cb8a38936cfaed70 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 2 Dec 2024 11:38:17 +0100 Subject: [PATCH 016/602] FIX uniformize code --- htdocs/supplier_proposal/list.php | 40 ++++++++++++++++++------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index 6622a28fec3..d8bc7165389 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -65,8 +65,8 @@ $mode = GETPOST('mode', 'alpha'); $search_user = GETPOST('search_user', 'intcomma'); $search_sale = GETPOST('search_sale', 'intcomma'); $search_ref = GETPOST('sf_ref') ? GETPOST('sf_ref', 'alpha') : GETPOST('search_ref', 'alpha'); -$search_societe = GETPOST('search_societe', 'alpha'); -$search_societe_alias = GETPOST('search_societe_alias', 'alpha'); +$search_company = GETPOST('search_company', 'alpha'); +$search_company_alias = GETPOST('search_company_alias', 'alpha'); $search_login = GETPOST('search_login', 'alpha'); $search_town = GETPOST('search_town', 'alpha'); $search_zip = GETPOST('search_zip', 'alpha'); @@ -236,8 +236,8 @@ if (empty($reshook)) { $search_user = ''; $search_sale = ''; $search_ref = ''; - $search_societe = ''; - $search_societe_alias = ''; + $search_company = ''; + $search_company_alias = ''; $search_montant_ht = ''; $search_montant_vat = ''; $search_montant_ttc = ''; @@ -294,6 +294,14 @@ $formcompany = new FormCompany($db); $now = dol_now(); +if ($socid > 0) { + $soc = new Societe($db); + $soc->fetch($socid); + if (empty($search_company)) { + $search_company = $soc->name; + } +} + $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields @@ -362,14 +370,14 @@ if ($search_type_thirdparty != '' && $search_type_thirdparty > 0) { if ($search_ref) { $sql .= natural_search('sp.ref', $search_ref); } -if (empty($arrayfields['s.name_alias']['checked']) && $search_societe) { - $sql .= natural_search(array("s.nom", "s.name_alias"), $search_societe); +if (empty($arrayfields['s.name_alias']['checked']) && $search_company) { + $sql .= natural_search(array("s.nom", "s.name_alias"), $search_company); } else { - if ($search_societe) { - $sql .= natural_search('s.nom', $search_societe); + if ($search_company) { + $sql .= natural_search('s.nom', $search_company); } - if ($search_societe_alias) { - $sql .= natural_search('s.name_alias', $search_societe_alias); + if ($search_company_alias) { + $sql .= natural_search('s.name_alias', $search_company_alias); } } if ($search_login) { @@ -571,11 +579,11 @@ if ($resql) { if ($search_ref) { $param .= '&search_ref='.urlencode($search_ref); } - if ($search_societe) { - $param .= '&search_societe='.urlencode($search_societe); + if ($search_company) { + $param .= '&search_company='.urlencode($search_company); } - if ($search_societe_alias) { - $param .= '&search_societe_alias='.urlencode($search_societe_alias); + if ($search_company_alias) { + $param .= '&search_company_alias='.urlencode($search_company_alias); } if ($search_user > 0) { $param .= '&search_user='.urlencode((string) ($search_user)); @@ -742,12 +750,12 @@ if ($resql) { } if (!empty($arrayfields['s.nom']['checked'])) { print ''; - print ''; + print ''; print ''; } if (!empty($arrayfields['s.name_alias']['checked'])) { print ''; - print ''; + print ''; print ''; } if (!empty($arrayfields['s.town']['checked'])) { From 3e3f9c755db2f8207f8f3da20424e120a5289267 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 2 Dec 2024 12:10:39 +0100 Subject: [PATCH 017/602] FIX Check "$search_sale" only if it's an internal user --- htdocs/comm/propal/list.php | 3 ++- htdocs/compta/facture/list.php | 3 ++- htdocs/fourn/commande/list.php | 3 ++- htdocs/fourn/facture/list.php | 3 ++- htdocs/supplier_proposal/list.php | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 9ad46ac19d6..9977b93927c 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -286,7 +286,8 @@ foreach ($object->fields as $key => $val) { } }*/ -if (!$user->hasRight('societe', 'client', 'voir')) { +// Check only if it's an internal user +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 29225c9e178..c48e14971de 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -304,7 +304,8 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); '@phan-var-force array,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan -if (!$user->hasRight('societe', 'client', 'voir')) { +// Check only if it's an internal user +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index d806ef812d3..c47a099ae47 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -217,7 +217,8 @@ $arrayfields = dol_sort_array($arrayfields, 'position'); $error = 0; -if (!$user->hasRight('societe', 'client', 'voir')) { +// Check only if it's an internal user +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 086995608dd..c7e10e2317c 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -226,7 +226,8 @@ if ((!$user->hasRight("fournisseur", "facture", "lire") && !getDolGlobalString(' accessforbidden(); } -if (!$user->hasRight('societe', 'client', 'voir')) { +// Check only if it' an internal user +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index d8bc7165389..3e8b03d3d22 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -198,7 +198,8 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); '@phan-var-force array,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan -if (!$user->hasRight('societe', 'client', 'voir')) { +// Check only if it's an internal user +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } From c86b50e3fc0ff807e78dbe68e51313d8350d60d4 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Sat, 30 Nov 2024 14:24:13 +0100 Subject: [PATCH 018/602] The $empty param must follow same rules than other select component. --- htdocs/core/class/html.formticket.class.php | 42 +++++++++++---------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 8920b259489..0cbd3e55876 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -332,7 +332,7 @@ class FormTicket // Type of Ticket print ''; - $this->selectTypesTickets((GETPOST('type_code', 'alpha') ? GETPOST('type_code', 'alpha') : $this->type_code), 'type_code', '', 2, 1, 0, 0, 'minwidth200'); + $this->selectTypesTickets((GETPOST('type_code', 'alpha') ? GETPOST('type_code', 'alpha') : $this->type_code), 'type_code', '', 2, 'ifone', 0, 0, 'minwidth200'); print ''; // Group => Category @@ -342,12 +342,12 @@ class FormTicket $filter = 'public=1'; } $selected = (GETPOST('category_code') ? GETPOST('category_code') : $this->category_code); - $this->selectGroupTickets($selected, 'category_code', $filter, 2, 1, 0, 0, 'minwidth200'); + $this->selectGroupTickets($selected, 'category_code', $filter, 2, 'ifone', 0, 0, 'minwidth200'); print ''; // Severity => Priority print ''; - $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 1); + $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 'ifone'); print ''; if (!empty($conf->knowledgemanagement->enabled)) { @@ -690,8 +690,8 @@ class FormTicket * @param string|array $selected Id of preselected field or array of Ids * @param string $htmlname Nom de la zone select * @param string $filtertype To filter on field type in llx_c_ticket_type (array('code'=>xx,'label'=>zz)) - * @param int $format 0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code - * @param int $empty 1=peut etre vide, 0 sinon + * @param int $format 0=id+label, 1=code+code, 2=code+label, 3=id+code + * @param int|string $empty 1 = can be empty or 'string' to show the string as the empty value, 0 = can't be empty, 'ifone' = can be empty but autoselected if there is one only * @param int $noadmininfo 0=Add admin info, 1=Disable admin info * @param int $maxlength Max length of label * @param string $morecss More CSS @@ -715,9 +715,9 @@ class FormTicket $ticketstat->loadCacheTypesTickets(); - print ''; + if ($empty) { + print ''; } if (is_array($ticketstat->cache_types_tickets) && count($ticketstat->cache_types_tickets)) { @@ -755,6 +755,8 @@ class FormTicket print ' selected="selected"'; } elseif ($arraytypes['use_default'] == "1" && empty($selected) && !$multiselect) { print ' selected="selected"'; + } elseif (count($ticketstat->cache_types_tickets) == 1 && (!$empty || $empty == 'ifone')) { // If only 1 choice, we autoselect it + print ' selected="selected"'; } print '>'; @@ -813,10 +815,10 @@ class FormTicket $ticketstat = new Ticket($this->db); $ticketstat->loadCacheCategoriesTickets($publicgroups ? 1 : -1); // get list of active ticket groups - if ($use_multilevel <= 0) { + if ($use_multilevel <= 0) { // Only one combo list to select the group of ticket (default) print ''; if ($empty) { - print ''; + print ''; } if (is_array($ticketstat->cache_severity_tickets) && count($ticketstat->cache_severity_tickets)) { @@ -1201,6 +1203,8 @@ class FormTicket print ' selected="selected"'; } elseif ($arrayseverities['use_default'] == "1" && empty($selected)) { print ' selected="selected"'; + } elseif (count($conf->cache['severity_tickets']) == 1 && (!$empty || $empty == 'ifone')) { // If only 1 choice, we autoselect it + print ' selected="selected"'; } print '>'; From e48e1e27d542787ca0d42f7fdc814214348f8edc Mon Sep 17 00:00:00 2001 From: tnegre Date: Fri, 6 Dec 2024 12:07:37 +0100 Subject: [PATCH 019/602] replace code from develop to match DLB18 variable name --- htdocs/core/class/html.formticket.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 0cbd3e55876..9c3a3847a24 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -1203,7 +1203,7 @@ class FormTicket print ' selected="selected"'; } elseif ($arrayseverities['use_default'] == "1" && empty($selected)) { print ' selected="selected"'; - } elseif (count($conf->cache['severity_tickets']) == 1 && (!$empty || $empty == 'ifone')) { // If only 1 choice, we autoselect it + } elseif (count($ticketstat->cache_severity_tickets) == 1 && (!$empty || $empty == 'ifone')) { // If only 1 choice, we autoselect it print ' selected="selected"'; } From e8aaa51edcf65d9feacb7000ee6e657419670275 Mon Sep 17 00:00:00 2001 From: tnegre Date: Fri, 6 Dec 2024 14:06:54 +0100 Subject: [PATCH 020/602] set empty value for choice --- htdocs/ticket/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 9e69271f09c..9f1f30a3e7f 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -856,11 +856,11 @@ foreach ($object->fields as $key => $val) { print ''; } elseif ($key == 'category_code') { print ''; - $formTicket->selectGroupTickets(dol_escape_htmltag(empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, '', 2, 1, 1, 0, (!empty($val['css']) ? $val['css'] : 'maxwidth150')); + $formTicket->selectGroupTickets(dol_escape_htmltag(empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, '', 2, ' ', 1, 0, (!empty($val['css']) ? $val['css'] : 'maxwidth150')); print ''; } elseif ($key == 'severity_code') { print ''; - $formTicket->selectSeveritiesTickets(dol_escape_htmltag(empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, '', 2, 1, 1, 0, (!empty($val['css']) ? $val['css'] : 'maxwidth150')); + $formTicket->selectSeveritiesTickets(dol_escape_htmltag(empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, '', 2, ' ', 1, 0, (!empty($val['css']) ? $val['css'] : 'maxwidth150')); print ''; } elseif ($key == 'fk_user_assign' || $key == 'fk_user_create') { print ''; From 05faaab489e7616c93a42c24c52ab43f9d37d316 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sat, 14 Dec 2024 08:36:41 +0100 Subject: [PATCH 021/602] Balance - Add backtopage on create --- htdocs/accountancy/bookkeeping/balance.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 1cfdcfe73ae..cd2641ff6be 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -136,6 +136,8 @@ if (!$user->hasRight('accounting', 'mouvements', 'lire')) { accessforbidden(); } +$permissiontoadd = $user->hasRight('accounting', 'mouvements', 'creer'); + /* * Action @@ -327,13 +329,13 @@ if ($action != 'export_csv') { if ($type == 'sub') { $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly')); - $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); + $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?type=sub' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); } else { $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); - $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly')); + $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?type=sub' . $url_param, '', 1, array('morecss' => 'marginleftonly')); } $newcardbutton .= dolGetButtonTitleSeparator(); - $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); + $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'.(!empty($type)?'&type=sub':'').'&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); } if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); From eb7c02b33aff60da3d247063aefe1822bd147cae Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 15 Dec 2024 22:57:02 +0100 Subject: [PATCH 022/602] Journal - Add backtopage on create --- htdocs/accountancy/bookkeeping/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 60409e47f0f..2573a737ebc 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -843,7 +843,7 @@ if (empty($reshook)) { $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?type=sub'.$param, '', 1, array('morecss' => 'marginleftonly')); - $url = './card.php?action=create'; + $url = './card.php?action=create'.(!empty($type)?'&type=sub':'').'&backtopage='.urlencode($_SERVER['PHP_SELF']); if (!empty($socid)) { $url .= '&socid='.$socid; } From 790396a48881d89e1f5fe5b0fb772e61113c4527 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 15 Dec 2024 22:57:27 +0100 Subject: [PATCH 023/602] Ledger - Add backtopage on create --- htdocs/accountancy/bookkeeping/listbyaccount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 7834b2a6d0f..2992bbf9c47 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -744,7 +744,7 @@ if (empty($reshook)) { $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly')); } $newcardbutton .= dolGetButtonTitleSeparator(); - $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); + $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'.(!empty($type)?'&type=sub':'').'&backtopage='.urlencode($_SERVER['PHP_SELF'])); } if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { From a90fd44e3eaeb6917811a1ad388b8fdd0b8b588a Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 15 Dec 2024 22:57:53 +0100 Subject: [PATCH 024/602] Accountancy - Add backtopage & type --- htdocs/accountancy/bookkeeping/card.php | 28 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 0da31291160..1ccc651b4f1 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -52,6 +52,12 @@ $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); +$type = GETPOST('type', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); +if (empty($backtopage)) { + $backtopage = '/accountancy/bookkeeping/list.php'; +} + $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $id = GETPOSTINT('id'); // id of record @@ -121,7 +127,7 @@ if (empty($reshook)) { $error = 0; if ($cancel) { - header("Location: ".DOL_URL_ROOT.'/accountancy/bookkeeping/list.php'); + header("Location: ".DOL_URL_ROOT. $backtopage . (!empty($type)?'?type=sub':'')); exit; } @@ -355,7 +361,7 @@ if (empty($reshook)) { if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } else { - header("Location: list.php?sortfield=t.piece_num&sortorder=asc"); + header("Location: " . DOL_URL_ROOT. $backtopage . "?sortfield=t.piece_num&sortorder=asc" . ($type ? '&type='.$type : '')); exit; } } @@ -458,6 +464,8 @@ if ($action == 'create') { print ''; print ''."\n"; print ''."\n"; + print ''; + print ''; print ''."\n"; print dol_get_fiche_head(); @@ -520,7 +528,7 @@ if ($action == 'create') { $head = array(); $h = 0; - $head[$h][0] = $_SERVER['PHP_SELF'].'?piece_num='.((int) $object->piece_num).($mode ? '&mode='.$mode : ''); + $head[$h][0] = DOL_URL_ROOT."/accountancy/bookkeeping/card.php".'?piece_num='.((int) $object->piece_num).($mode ? '&mode='.$mode : '').($type ? '&type='.$type : '').($backtopage ? '&backtopage='.urlencode($backtopage) : ''); $head[$h][1] = $langs->trans("Transaction"); $head[$h][2] = 'transaction'; $h++; @@ -572,6 +580,8 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -603,6 +613,8 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; + print ''; print $form->selectDate($object->doc_date ? $object->doc_date : -1, 'doc_date', 0, 0, 0, "setdate"); print ''; print ''; @@ -614,7 +626,7 @@ if ($action == 'create') { // Journal print ''; - print ''; print ''; print ''; @@ -1604,8 +1612,11 @@ if ($action == 'create') { if (GETPOSTISSET($inputName)) { $deliverableQty = GETPOSTINT($inputName); } - - print ''; + $qtylValue = $deliverableQty; + if (getDolGlobalBool('SHIPMENT_DONT_PREFILL_QTY', false)) { + $qtylValue = ''; + } + print ''; print ''; } else { if (getDolGlobalString('SHIPMENT_GETS_ALL_ORDER_PRODUCTS')) { @@ -1729,7 +1740,11 @@ if ($action == 'create') { $alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)] = $deliverableQty + $alreadyQtyBatchSetted[$line->fk_product][$dbatch->batch][intval($warehouse_id)]; print ''; print ''; } // Alias diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 375a9eb087a..76ca915f9a8 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4753,7 +4753,7 @@ class Facture extends CommonInvoice } // If the internal user must only see his customers, force searching by him $search_sale = 0; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } // Search on sale representative @@ -4946,7 +4946,7 @@ class Facture extends CommonInvoice $sql = "SELECT f.rowid, f.date_lim_reglement as datefin, f.fk_statut as status, f.total_ht"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = " AND"; @@ -5194,7 +5194,7 @@ class Facture extends CommonInvoice $sql = "SELECT count(f.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/compta/facture/class/facturestats.class.php b/htdocs/compta/facture/class/facturestats.class.php index 6476235c9b2..0a02a2294c6 100644 --- a/htdocs/compta/facture/class/facturestats.class.php +++ b/htdocs/compta/facture/class/facturestats.class.php @@ -136,7 +136,7 @@ class FactureStats extends Stats $sql = "SELECT date_format(f.datef,'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -162,7 +162,7 @@ class FactureStats extends Stats $sql = "SELECT date_format(f.datef,'%Y') as dm, COUNT(*), SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -187,7 +187,7 @@ class FactureStats extends Stats $sql = "SELECT date_format(datef,'%m') as dm, SUM(f.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -213,7 +213,7 @@ class FactureStats extends Stats $sql = "SELECT date_format(datef,'%m') as dm, AVG(f.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -236,7 +236,7 @@ class FactureStats extends Stats $sql = "SELECT date_format(datef,'%Y') as year, COUNT(*) as nb, SUM(f.".$this->field.") as total, AVG(f.".$this->field.") as avg"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -260,7 +260,7 @@ class FactureStats extends Stats $sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg"; $sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -288,7 +288,7 @@ class FactureStats extends Stats $startYear = $endYear - $numberYears; $sql = "SELECT date_format(datef,'%Y') as dm, SUM(f.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 29225c9e178..fde549cc967 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -304,15 +304,15 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); '@phan-var-force array,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan -if (!$user->hasRight('societe', 'client', 'voir')) { - $search_sale = $user->id; -} - // Security check $fieldid = (!empty($ref) ? 'ref' : 'rowid'); if (!empty($user->socid)) { $socid = $user->socid; } +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { + $search_sale = $user->id; +} + $result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid); diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index 9968411c62e..a238b4f6a2b 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -153,7 +153,7 @@ if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) { $sql .= " AND f.fk_soc = ".((int) $socid); } // Filter on sale representative - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = f.fk_soc AND sc.fk_user = ".((int) $user->id).")"; } // Add where from hooks @@ -304,7 +304,7 @@ if ((isModEnabled('fournisseur') && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMO $sql .= " AND ff.fk_soc = ".((int) $socid); } // Filter on sale representative - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = ff.fk_soc AND sc.fk_user = ".((int) $user->id).")"; } // Add where from hooks @@ -624,7 +624,7 @@ if (isModEnabled('invoice') && isModEnabled('order') && $user->hasRight("command $sql .= " AND c.fk_statut = ".((int) Commande::STATUS_CLOSED); $sql .= " AND c.facture = 0"; // Filter on sale representative - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = c.fk_soc AND sc.fk_user = ".((int) $user->id).")"; } diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 633034c27f4..8bf66f9fe2e 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2279,7 +2279,7 @@ class Contrat extends CommonObject $this->from = " FROM ".MAIN_DB_PREFIX."contrat as c"; $this->from .= ", ".MAIN_DB_PREFIX."contratdet as cd"; $this->from .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $this->from .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } @@ -2310,7 +2310,7 @@ class Contrat extends CommonObject if ($user->socid) { $sql .= " AND c.fk_soc = ".((int) $user->socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -2376,7 +2376,7 @@ class Contrat extends CommonObject $sql = "SELECT count(c.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."contrat as c"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON c.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index bc5af219667..09d8e040b26 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -200,7 +200,7 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); '@phan-var-force array,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan -if (!$user->hasRight('societe', 'client', 'voir')) { +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } @@ -875,7 +875,7 @@ if (!empty($arrayfields['c.ref_supplier']['checked'])) { } if (!empty($arrayfields['s.nom']['checked'])) { print ''; } if (!empty($arrayfields['s.email']['checked'])) { diff --git a/htdocs/core/boxes/box_actions.php b/htdocs/core/boxes/box_actions.php index 633914ce74b..1cd2a57f3dc 100644 --- a/htdocs/core/boxes/box_actions.php +++ b/htdocs/core/boxes/box_actions.php @@ -83,14 +83,14 @@ class box_actions extends ModeleBoxes $sql .= ", s.code_client, s.code_compta, s.client"; $sql .= ", s.logo, s.email, s.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm AS ta, ".MAIN_DB_PREFIX."actioncomm AS a"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; $sql .= " WHERE a.fk_action = ta.id"; $sql .= " AND a.entity IN (".getEntity('actioncomm').")"; $sql .= " AND a.percent >= 0 AND a.percent < 100"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")"; } if ($user->socid) { diff --git a/htdocs/core/boxes/box_actions_future.php b/htdocs/core/boxes/box_actions_future.php index 6a202bd9f2b..e9d8841fcc9 100644 --- a/htdocs/core/boxes/box_actions_future.php +++ b/htdocs/core/boxes/box_actions_future.php @@ -85,14 +85,14 @@ class box_actions_future extends ModeleBoxes $sql .= ", s.code_client, s.code_compta, s.client"; $sql .= ", s.logo, s.email, s.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm AS ta, ".MAIN_DB_PREFIX."actioncomm AS a"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; $sql .= " WHERE a.fk_action = ta.id"; $sql .= " AND a.entity IN (".getEntity('actioncomm').")"; //$sql .= " AND a.percent >= 0 AND a.percent < 100"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")"; } if ($user->socid) { diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 88571ed872b..3c8d2ce6a83 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -104,13 +104,13 @@ class box_activity extends ModeleBoxes $sql = "SELECT p.fk_statut, SUM(p.total_ttc) as Mnttot, COUNT(*) as nb"; $sql .= " FROM (".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= ")"; $sql .= " WHERE p.entity IN (".getEntity('propal').")"; $sql .= " AND p.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { @@ -193,13 +193,13 @@ class box_activity extends ModeleBoxes $sql = "SELECT c.fk_statut, sum(c.total_ttc) as Mnttot, count(*) as nb"; $sql .= " FROM (".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as c"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= ")"; $sql .= " WHERE c.entity IN (".getEntity('commande').")"; $sql .= " AND c.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { @@ -278,12 +278,12 @@ class box_activity extends ModeleBoxes $data = array(); $sql = "SELECT f.fk_statut, SUM(f.total_ttc) as Mnttot, COUNT(*) as nb"; $sql .= " FROM (".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= ")"; $sql .= " WHERE f.entity IN (".getEntity('invoice').')'; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_clients.php b/htdocs/core/boxes/box_clients.php index 7201ec1da11..a8d706fdb63 100644 --- a/htdocs/core/boxes/box_clients.php +++ b/htdocs/core/boxes/box_clients.php @@ -85,12 +85,12 @@ class box_clients extends ModeleBoxes $sql .= ", s.logo, s.email, s.entity"; $sql .= ", s.datec, s.tms, s.status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.client IN (1, 3)"; $sql .= " AND s.entity IN (".getEntity('societe').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } // Add where from hooks diff --git a/htdocs/core/boxes/box_commandes.php b/htdocs/core/boxes/box_commandes.php index d7a87dacbfa..bbb226fcf03 100644 --- a/htdocs/core/boxes/box_commandes.php +++ b/htdocs/core/boxes/box_commandes.php @@ -92,7 +92,7 @@ class box_commandes extends ModeleBoxes $sql .= ", c.total_tva"; $sql .= ", c.total_ttc"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c, ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -100,7 +100,7 @@ class box_commandes extends ModeleBoxes if (getDolGlobalString('ORDER_BOX_LAST_ORDERS_VALIDATED_ONLY')) { $sql .= " AND c.fk_statut = 1"; } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index b9be887b2ed..0d5f91eb35f 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -98,11 +98,11 @@ class box_contacts extends ModeleBoxes if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) { $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " AND ((sp.fk_user_creat = ".((int) $user->id)." AND sp.priv = 1) OR sp.priv = 0)"; // check if this is a private contact diff --git a/htdocs/core/boxes/box_contracts.php b/htdocs/core/boxes/box_contracts.php index 2f32b170066..2653acb63a1 100644 --- a/htdocs/core/boxes/box_contracts.php +++ b/htdocs/core/boxes/box_contracts.php @@ -77,12 +77,12 @@ class box_contracts extends ModeleBoxes $sql .= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat, c.datec, c.tms as date_modification, c.fin_validite, c.date_cloture,"; $sql .= " c.ref_customer, c.ref_supplier"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as c"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; $sql .= " AND c.entity = ".$conf->entity; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_customers_outstanding_bill_reached.php b/htdocs/core/boxes/box_customers_outstanding_bill_reached.php index 3aaf3082ae3..57237f6a318 100644 --- a/htdocs/core/boxes/box_customers_outstanding_bill_reached.php +++ b/htdocs/core/boxes/box_customers_outstanding_bill_reached.php @@ -84,12 +84,12 @@ class box_customers_outstanding_bill_reached extends ModeleBoxes $sql .= ", s.outstanding_limit"; $sql .= ", s.datec, s.tms, s.status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.client IN (1, 3)"; $sql .= " AND s.entity IN (".getEntity('societe').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_factures.php b/htdocs/core/boxes/box_factures.php index 3e8de6c90e8..8a4f99ffb1c 100644 --- a/htdocs/core/boxes/box_factures.php +++ b/htdocs/core/boxes/box_factures.php @@ -93,12 +93,12 @@ class box_factures extends ModeleBoxes $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; $sql .= " AND f.entity IN (".getEntity('invoice').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_factures_fourn.php b/htdocs/core/boxes/box_factures_fourn.php index cfaeddc5b0f..4e874faa4eb 100644 --- a/htdocs/core/boxes/box_factures_fourn.php +++ b/htdocs/core/boxes/box_factures_fourn.php @@ -91,12 +91,12 @@ class box_factures_fourn extends ModeleBoxes $sql .= ', f.date_lim_reglement as datelimite, f.tms, f.type'; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."facture_fourn as f"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; $sql .= " AND f.entity = ".$conf->entity; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_factures_fourn_imp.php b/htdocs/core/boxes/box_factures_fourn_imp.php index c75418ae958..24cecd0024a 100644 --- a/htdocs/core/boxes/box_factures_fourn_imp.php +++ b/htdocs/core/boxes/box_factures_fourn_imp.php @@ -93,14 +93,14 @@ class box_factures_fourn_imp extends ModeleBoxes $sql2 = " FROM ".MAIN_DB_PREFIX."societe as s"; $sql2 .= ",".MAIN_DB_PREFIX."facture_fourn as f"; $sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON f.rowid = pf.fk_facturefourn"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql2 .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql2 .= " WHERE f.fk_soc = s.rowid"; $sql2 .= " AND f.entity IN (".getEntity('supplier_invoice').")"; $sql2 .= " AND f.paye = 0"; $sql2 .= " AND fk_statut = 1"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql2 .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_factures_imp.php b/htdocs/core/boxes/box_factures_imp.php index 6cfb7650547..8f52032b742 100644 --- a/htdocs/core/boxes/box_factures_imp.php +++ b/htdocs/core/boxes/box_factures_imp.php @@ -102,7 +102,7 @@ class box_factures_imp extends ModeleBoxes if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) { $sql2 .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql2 .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql2 .= ", ".MAIN_DB_PREFIX."facture as f"; @@ -111,7 +111,7 @@ class box_factures_imp extends ModeleBoxes $sql2 .= " AND f.entity IN (".getEntity('invoice').")"; $sql2 .= " AND f.paye = 0"; $sql2 .= " AND fk_statut = 1"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql2 .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_ficheinter.php b/htdocs/core/boxes/box_ficheinter.php index 636c2b6eb2a..7da9d06d350 100644 --- a/htdocs/core/boxes/box_ficheinter.php +++ b/htdocs/core/boxes/box_ficheinter.php @@ -80,13 +80,13 @@ class box_ficheinter extends ModeleBoxes $sql .= ", s.code_client, s.code_compta, s.client"; $sql .= ", s.logo, s.email, s.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= ", ".MAIN_DB_PREFIX."fichinter as f"; $sql .= " WHERE f.fk_soc = s.rowid "; $sql .= " AND f.entity = ".$conf->entity; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php index ee5ae31472f..b54c5d7074a 100644 --- a/htdocs/core/boxes/box_fournisseurs.php +++ b/htdocs/core/boxes/box_fournisseurs.php @@ -78,12 +78,12 @@ class box_fournisseurs extends ModeleBoxes $sql .= ", s.logo, s.email, s.entity"; $sql .= ", s.datec, s.tms, s.status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.fournisseur = 1"; $sql .= " AND s.entity IN (".getEntity('societe').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } // Add where from hooks diff --git a/htdocs/core/boxes/box_graph_propales_permonth.php b/htdocs/core/boxes/box_graph_propales_permonth.php index e153e4bbe92..0597d7ec8de 100644 --- a/htdocs/core/boxes/box_graph_propales_permonth.php +++ b/htdocs/core/boxes/box_graph_propales_permonth.php @@ -93,7 +93,7 @@ class box_graph_propales_permonth extends ModeleBoxes if ($user->socid) { $socid = $user->socid; } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $prefix .= 'private-'.$user->id.'-'; // If user has no permission to see all, output dir is specific to user } diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index 9922fc1e881..3b2b4370237 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -81,12 +81,12 @@ class box_propales extends ModeleBoxes $sql .= ", s.logo, s.email, s.entity"; $sql .= ", p.rowid, p.ref, p.fk_statut as status, p.datep as dp, p.datec, p.fin_validite, p.date_cloture, p.total_ht, p.total_tva, p.total_ttc, p.tms"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p, ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.fk_soc = s.rowid"; $sql .= " AND p.entity IN (".getEntity('propal').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_prospect.php b/htdocs/core/boxes/box_prospect.php index aa4725935ab..159c9bca946 100644 --- a/htdocs/core/boxes/box_prospect.php +++ b/htdocs/core/boxes/box_prospect.php @@ -86,12 +86,12 @@ class box_prospect extends ModeleBoxes $sql .= ", s.fk_stcomm"; $sql .= ", s.datec, s.tms, s.status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.client IN (2, 3)"; $sql .= " AND s.entity IN (".getEntity('societe').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } // Add where from hooks diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index 6a9dd91c55a..21259696bfb 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -86,7 +86,7 @@ class box_services_contracts extends ModeleBoxes $sql .= " INNER JOIN ".MAIN_DB_PREFIX."contrat as c ON s.rowid = c.fk_soc"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."contratdet as cd ON c.rowid = cd.fk_contrat"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= ")"; diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php index e2dea31cd4a..0e6b66add1b 100644 --- a/htdocs/core/boxes/box_services_expired.php +++ b/htdocs/core/boxes/box_services_expired.php @@ -74,7 +74,7 @@ class box_services_expired extends ModeleBoxes $sql .= " s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,"; $sql .= " MIN(cd.date_fin_validite) as date_line, COUNT(cd.rowid) as nb_services"; $sql .= " FROM ".MAIN_DB_PREFIX."contrat as c, ".MAIN_DB_PREFIX."societe s, ".MAIN_DB_PREFIX."contratdet as cd"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE cd.statut = 4 AND cd.date_fin_validite <= '".$this->db->idate($now)."'"; @@ -83,7 +83,7 @@ class box_services_expired extends ModeleBoxes if ($user->socid) { $sql .= ' AND c.fk_soc = '.((int) $user->socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY c.rowid, c.ref, c.statut, c.date_contrat, c.ref_customer, c.ref_supplier, s.nom, s.rowid"; diff --git a/htdocs/core/boxes/box_shipments.php b/htdocs/core/boxes/box_shipments.php index 512dbc6a944..42fa9b4821c 100644 --- a/htdocs/core/boxes/box_shipments.php +++ b/htdocs/core/boxes/box_shipments.php @@ -92,7 +92,7 @@ class box_shipments extends ModeleBoxes $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON e.rowid = el.fk_target AND el.targettype = 'shipping' AND el.sourcetype IN ('commande')"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON el.fk_source = c.rowid AND el.sourcetype IN ('commande') AND el.targettype = 'shipping'"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = e.fk_soc"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON e.fk_soc = sc.fk_soc"; } $sql .= " WHERE e.entity IN (".getEntity('expedition').")"; @@ -102,7 +102,7 @@ class box_shipments extends ModeleBoxes if ($user->socid > 0) { $sql.= " AND s.rowid = ".((int) $user->socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND sc.fk_user = ".((int) $user->id); } else { $sql .= " ORDER BY e.tms DESC, e.date_delivery DESC, e.ref DESC"; diff --git a/htdocs/core/boxes/box_supplier_orders.php b/htdocs/core/boxes/box_supplier_orders.php index 88e87cff07b..3287e20c852 100644 --- a/htdocs/core/boxes/box_supplier_orders.php +++ b/htdocs/core/boxes/box_supplier_orders.php @@ -84,12 +84,12 @@ class box_supplier_orders extends ModeleBoxes $sql .= ", c.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande_fournisseur as c"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; $sql .= " AND c.entity IN (".getEntity('supplier_order').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php index acddab7dc23..86f30d122e1 100644 --- a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php +++ b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php @@ -81,14 +81,14 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes $sql .= ", c.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande_fournisseur as c"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; $sql .= " AND c.entity IN (".getEntity('supplier_order').")"; $sql .= " AND c.date_livraison IS NOT NULL"; $sql .= " AND c.fk_statut IN (".CommandeFournisseur::STATUS_ORDERSENT.", ".CommandeFournisseur::STATUS_RECEIVED_PARTIALLY.")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($user->socid) { diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index b1af5dbd95e..dee5549fee8 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -492,6 +492,7 @@ function getCustomerInvoiceDraftTable($maxCount = 500, $socid = 0) $result = ''; if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) { + if ($user->socid > 0) $socid = $user->socid; $maxofloop = (!getDolGlobalString('MAIN_MAXLIST_OVERLOAD') ? 500 : $conf->global->MAIN_MAXLIST_OVERLOAD); $tmpinvoice = new Facture($db); @@ -502,16 +503,16 @@ function getCustomerInvoiceDraftTable($maxCount = 500, $socid = 0) $sql .= ", s.rowid as socid, s.email"; $sql .= ", s.code_client, s.code_compta, s.code_fournisseur, s.code_compta_fournisseur"; $sql .= ", cc.rowid as country_id, cc.code as country_code"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", sc.fk_soc, sc.fk_user "; } $sql .= " FROM ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."societe as s LEFT JOIN ".MAIN_DB_PREFIX."c_country as cc ON cc.rowid = s.fk_pays"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.rowid = f.fk_soc AND f.fk_statut = ".Facture::STATUS_DRAFT; $sql .= " AND f.entity IN (".getEntity('invoice').")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -526,7 +527,7 @@ function getCustomerInvoiceDraftTable($maxCount = 500, $socid = 0) $sql .= " GROUP BY f.rowid, f.ref, f.datef, f.total_ht, f.total_tva, f.total_ttc, f.ref_client, f.type, f.fk_statut, f.paye,"; $sql .= " s.nom, s.rowid, s.email, s.code_client, s.code_compta, s.code_fournisseur, s.code_compta_fournisseur,"; $sql .= " cc.rowid, cc.code"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", sc.fk_soc, sc.fk_user"; } @@ -642,6 +643,7 @@ function getDraftSupplierTable($maxCount = 500, $socid = 0) $result = ''; if ((isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) && $user->hasRight('facture', 'lire')) { + if ($user->socid > 0) $socid = $user->socid; $maxofloop = (!getDolGlobalString('MAIN_MAXLIST_OVERLOAD') ? 500 : $conf->global->MAIN_MAXLIST_OVERLOAD); $facturesupplierstatic = new FactureFournisseur($db); @@ -653,12 +655,12 @@ function getDraftSupplierTable($maxCount = 500, $socid = 0) $sql .= ", s.code_fournisseur, s.code_compta_fournisseur"; $sql .= ", cc.rowid as country_id, cc.code as country_code"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f, ".MAIN_DB_PREFIX."societe as s LEFT JOIN ".MAIN_DB_PREFIX."c_country as cc ON cc.rowid = s.fk_pays"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.rowid = f.fk_soc AND f.fk_statut = ".FactureFournisseur::STATUS_DRAFT; $sql .= " AND f.entity IN (".getEntity('invoice').')'; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -773,12 +775,12 @@ function getDraftSupplierTable($maxCount = 500, $socid = 0) function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0) { global $conf, $db, $langs, $user; - + if ($user->socid > 0) $socid = $user->socid; $sql = "SELECT f.rowid, f.entity, f.ref, f.fk_statut as status, f.paye, f.type, f.total_ht, f.total_tva, f.total_ttc, f.datec,"; $sql .= " s.nom as socname, s.rowid as socid, s.canvas, s.client"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; @@ -786,7 +788,7 @@ function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0) if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY f.tms DESC"; @@ -881,12 +883,12 @@ function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0) function getPurchaseInvoiceLatestEditTable($maxCount = 5, $socid = 0) { global $conf, $db, $langs, $user; - + if ($user->socid > 0) $socid = $user->socid; $sql = "SELECT f.rowid, f.entity, f.ref, f.fk_statut as status, f.paye, f.total_ht, f.total_tva, f.total_ttc, f.type, f.ref_supplier, f.datec,"; $sql .= " s.nom as socname, s.rowid as socid, s.canvas, s.client"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; @@ -894,7 +896,7 @@ function getPurchaseInvoiceLatestEditTable($maxCount = 5, $socid = 0) if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY f.tms DESC"; @@ -999,6 +1001,7 @@ function getCustomerInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $result = ''; if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) { + if ($user->socid > 0) $socid = $user->socid; $tmpinvoice = new Facture($db); $sql = "SELECT f.rowid, f.ref, f.fk_statut as status, f.datef, f.type, f.total_ht, f.total_tva, f.total_ttc, f.paye, f.tms"; @@ -1011,12 +1014,12 @@ function getCustomerInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $sql .= ", sum(pf.amount) as am"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s LEFT JOIN ".MAIN_DB_PREFIX."c_country as cc ON cc.rowid = s.fk_pays,".MAIN_DB_PREFIX."facture as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf on f.rowid=pf.fk_facture"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.rowid = f.fk_soc AND f.paye = 0 AND f.fk_statut = ".Facture::STATUS_VALIDATED; $sql .= " AND f.entity IN (".getEntity('invoice').')'; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -1187,6 +1190,7 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $result = ''; if (isModEnabled("supplier_invoice") && ($user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'read'))) { + if ($user->socid > 0) $socid = $user->socid; $facstatic = new FactureFournisseur($db); $sql = "SELECT ff.rowid, ff.ref, ff.fk_statut as status, ff.type, ff.libelle as label, ff.total_ht, ff.total_tva, ff.total_ttc, ff.paye"; @@ -1198,14 +1202,14 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $sql .= ", sum(pf.amount) as am"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as ff"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf on ff.rowid=pf.fk_facturefourn"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.rowid = ff.fk_soc"; $sql .= " AND ff.entity = ".$conf->entity; $sql .= " AND ff.paye = 0"; $sql .= " AND ff.fk_statut = ".FactureFournisseur::STATUS_VALIDATED; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { diff --git a/htdocs/core/lib/order.lib.php b/htdocs/core/lib/order.lib.php index 2f2d71a978b..72bf04842b8 100644 --- a/htdocs/core/lib/order.lib.php +++ b/htdocs/core/lib/order.lib.php @@ -239,11 +239,11 @@ function getCustomerOrderPieChart($socid = 0) /* * Statistics */ - + if ($user->socid > 0) $socid = $user->socid; $sql = "SELECT count(c.rowid) as nb, c.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande as c"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -251,7 +251,7 @@ function getCustomerOrderPieChart($socid = 0) if ($user->socid) { $sql .= ' AND c.fk_soc = '.((int) $user->socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY c.fk_statut"; diff --git a/htdocs/core/lib/propal.lib.php b/htdocs/core/lib/propal.lib.php index 46cf91ce684..f9247d84d1f 100644 --- a/htdocs/core/lib/propal.lib.php +++ b/htdocs/core/lib/propal.lib.php @@ -217,15 +217,15 @@ function getCustomerProposalPieChart($socid = 0) if (!isModEnabled('propal') || !$user->hasRight('propal', 'lire')) { return ''; } - + $listofstatus = array(Propal::STATUS_DRAFT, Propal::STATUS_VALIDATED, Propal::STATUS_SIGNED, Propal::STATUS_NOTSIGNED, Propal::STATUS_BILLED); $propalstatic = new Propal($db); - + if ($user->socid > 0) $socid = $user->socid; $sql = "SELECT count(p.rowid) as nb, p.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."propal as p"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if ($user->socid == 0 && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($propalstatic->element).")"; @@ -233,7 +233,7 @@ function getCustomerProposalPieChart($socid = 0) if ($user->socid) { $sql .= ' AND p.fk_soc = '.((int) $user->socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if ($user->socid == 0 && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " AND p.fk_statut IN (".$db->sanitize(implode(" ,", $listofstatus)).")"; diff --git a/htdocs/fichinter/class/fichinterstats.class.php b/htdocs/fichinter/class/fichinterstats.class.php index 15d19eaba73..fea03d405fa 100644 --- a/htdocs/fichinter/class/fichinterstats.class.php +++ b/htdocs/fichinter/class/fichinterstats.class.php @@ -98,7 +98,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -122,7 +122,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%Y') as dm, COUNT(*) as nb, 0"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE ".$this->where; @@ -145,7 +145,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%m') as dm, 0"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -169,7 +169,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%m') as dm, 0"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -191,7 +191,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%Y') as year, COUNT(*) as nb, 0 as total, 0 as avg"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE ".$this->where; diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 08b4b55373a..450396fbe2b 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -296,7 +296,7 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -if (!$user->hasRight('societe', 'client', 'voir')) { +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= ", ".MAIN_DB_PREFIX."societe as s"; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 5eea5501d69..cb94ccd7366 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3207,7 +3207,7 @@ class CommandeFournisseur extends CommonOrder $sql = "SELECT count(co.rowid) as nb"; $sql .= " FROM ".$this->db->prefix()."commande_fournisseur as co"; $sql .= " LEFT JOIN ".$this->db->prefix()."societe as s ON co.fk_soc = s.rowid"; - if (!$user->hasRight("societe", "client", "voir") && !$user->socid) { + if (empty($user->socid) && !$user->hasRight("societe", "client", "voir") && !$user->socid) { $sql .= " LEFT JOIN ".$this->db->prefix()."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; @@ -3243,7 +3243,7 @@ class CommandeFournisseur extends CommonOrder $sql = "SELECT c.rowid, c.date_creation as datec, c.date_commande, c.fk_statut, c.date_livraison as delivery_date, c.total_ht"; $sql .= " FROM ".$this->db->prefix()."commande_fournisseur as c"; - if (!$user->hasRight("societe", "client", "voir") && !$user->socid) { + if (empty($user->socid) && !$user->hasRight("societe", "client", "voir") && !$user->socid) { $sql .= " JOIN ".$this->db->prefix()."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " WHERE c.entity = ".$conf->entity; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 79b345dab2c..0ca5cf7f339 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2703,7 +2703,7 @@ class FactureFournisseur extends CommonInvoice $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut as status, ff.total_ht, ff.total_ttc'; $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as ff'; - if (!$user->hasRight("societe", "client", "voir") && !$user->socid) { + if (empty($user->socid) && !$user->hasRight("societe", "client", "voir")) { $sql .= " JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ff.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= ' WHERE ff.paye = 0'; @@ -3123,7 +3123,7 @@ class FactureFournisseur extends CommonInvoice $sql = "SELECT count(f.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; - if (!$user->hasRight("societe", "client", "voir") && !$user->socid) { + if (empty($user->socid) && !$user->hasRight("societe", "client", "voir")) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 959533d131d..6437570bf0f 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -1943,7 +1943,7 @@ class SupplierProposal extends CommonObject $ga = array(); $search_sale = 0; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } @@ -2212,7 +2212,7 @@ class SupplierProposal extends CommonObject public function load_board($user, $mode) { // phpcs:enable - global $conf, $user, $langs; + global $conf, $langs; $now = dol_now(); @@ -2220,7 +2220,7 @@ class SupplierProposal extends CommonObject $sql = "SELECT p.rowid, p.ref, p.datec as datec, p.date_cloture as datefin"; $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = " AND"; @@ -2377,7 +2377,7 @@ class SupplierProposal extends CommonObject $sql = "SELECT count(p.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 4791136e400..839b4e89efa 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -891,7 +891,7 @@ class Ticket extends CommonObject $socid = $user->socid ? $user->socid : 0; // If the internal user must only see his customers, force searching by him $search_sale = 0; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } // Search on sale representative @@ -3156,7 +3156,7 @@ class Ticket extends CommonObject $sql = "SELECT p.rowid, p.ref, p.datec as datec"; $sql .= " FROM ".MAIN_DB_PREFIX."ticket as p"; - if (isModEnabled('societe') && !$user->hasRight('societe', 'client', 'voir') && !$user->socid) { + if (empty($user->socid) && isModEnabled('societe') && !$user->hasRight('societe', 'client', 'voir') && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = " AND"; @@ -3220,7 +3220,7 @@ class Ticket extends CommonObject $sql = "SELECT count(p.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."ticket as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; From df88c74d119c0da18880b7f73c6e411f4c630927 Mon Sep 17 00:00:00 2001 From: vmaury Date: Mon, 13 Jan 2025 12:04:16 +0100 Subject: [PATCH 041/602] Fix 31370 Pb with external account --- htdocs/core/lib/invoice.lib.php | 2 +- htdocs/core/lib/propal.lib.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index dee5549fee8..7eecd6b0131 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -1190,7 +1190,7 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $result = ''; if (isModEnabled("supplier_invoice") && ($user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'read'))) { - if ($user->socid > 0) $socid = $user->socid; + if ($user->socid > 0) $socid = $user->socid; $facstatic = new FactureFournisseur($db); $sql = "SELECT ff.rowid, ff.ref, ff.fk_statut as status, ff.type, ff.libelle as label, ff.total_ht, ff.total_tva, ff.total_ttc, ff.paye"; diff --git a/htdocs/core/lib/propal.lib.php b/htdocs/core/lib/propal.lib.php index f9247d84d1f..6ec7c824cee 100644 --- a/htdocs/core/lib/propal.lib.php +++ b/htdocs/core/lib/propal.lib.php @@ -217,7 +217,7 @@ function getCustomerProposalPieChart($socid = 0) if (!isModEnabled('propal') || !$user->hasRight('propal', 'lire')) { return ''; } - + $listofstatus = array(Propal::STATUS_DRAFT, Propal::STATUS_VALIDATED, Propal::STATUS_SIGNED, Propal::STATUS_NOTSIGNED, Propal::STATUS_BILLED); $propalstatic = new Propal($db); From db47ce3bb129a1dde64bf3348b46a4e2073acb09 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 20 Jan 2025 11:33:24 +0100 Subject: [PATCH 042/602] FIX delete supplier order line when linked to customer order line --- 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 020b551f99a..156ec3971ef 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3894,7 +3894,7 @@ class CommandeFournisseurLigne extends CommonOrderLine return -1; } - $sql1 = 'UPDATE '.MAIN_DB_PREFIX."commandedet SET fk_commandefourndet = NULL WHERE rowid=".((int) $this->id); + $sql1 = 'UPDATE '.MAIN_DB_PREFIX."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet=".((int) $this->id); $resql = $this->db->query($sql1); if (!$resql) { $this->db->rollback(); From 426f4305b05c6696994a8ebce17b4c4b7d6b6ac2 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 20 Jan 2025 11:48:37 +0100 Subject: [PATCH 043/602] FIX delete supplier order when at least one line linked to customer order line --- htdocs/fourn/class/fournisseur.commande.class.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index b98f14aa074..60b6f98f0cf 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2312,6 +2312,16 @@ class CommandeFournisseur extends CommonOrder $error++; } + if (!$error) { + $sql1 = 'UPDATE '.$this->db->prefix()."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet IN (SELECT rowid FROM ".$main." WHERE fk_commande = ".((int) $this->id).")"; + dol_syslog(__METHOD__." linked order lines", LOG_DEBUG); + if (!$this->db->query($sql1)) { + $error++; + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + } + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet WHERE fk_commande =".((int) $this->id); dol_syslog(get_class($this)."::delete", LOG_DEBUG); if (!$this->db->query($sql)) { From 08a976fd8545ec7edfa17543fb099f74d6a84a9d Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 20 Jan 2025 11:56:54 +0100 Subject: [PATCH 044/602] FIX delete supplier order when at least one line linked to customer order line --- htdocs/fourn/class/fournisseur.commande.class.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 156ec3971ef..8bd670525a1 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2133,6 +2133,16 @@ class CommandeFournisseur extends CommonOrder $error++; } + if (!$error) { + $sql1 = "UPDATE ".MAIN_DB_PREFIX."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet IN (SELECT rowid FROM ".$main." WHERE fk_commande = ".((int) $this->id).")"; + dol_syslog(__METHOD__." linked order lines", LOG_DEBUG); + if (!$this->db->query($sql1)) { + $error++; + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + } + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet WHERE fk_commande =".((int) $this->id); dol_syslog(get_class($this)."::delete", LOG_DEBUG); if (!$this->db->query($sql)) { From ad60a50d4de17dedcbf6244ff9082343148785d1 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 20 Jan 2025 11:58:58 +0100 Subject: [PATCH 045/602] Uniformize SQL concat char --- 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 8bd670525a1..0e16160189e 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3904,7 +3904,7 @@ class CommandeFournisseurLigne extends CommonOrderLine return -1; } - $sql1 = 'UPDATE '.MAIN_DB_PREFIX."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet=".((int) $this->id); + $sql1 = "UPDATE ".MAIN_DB_PREFIX."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet=".((int) $this->id); $resql = $this->db->query($sql1); if (!$resql) { $this->db->rollback(); From 7f2a253625148d02dc94a2513e2a8251020e8c3f Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 20 Jan 2025 12:17:12 +0100 Subject: [PATCH 046/602] Uniformize SQL concat char --- 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 60b6f98f0cf..6ad989bceb5 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2313,7 +2313,7 @@ class CommandeFournisseur extends CommonOrder } if (!$error) { - $sql1 = 'UPDATE '.$this->db->prefix()."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet IN (SELECT rowid FROM ".$main." WHERE fk_commande = ".((int) $this->id).")"; + $sql1 = "UPDATE ".$this->db->prefix()."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet IN (SELECT rowid FROM ".$main." WHERE fk_commande = ".((int) $this->id).")"; dol_syslog(__METHOD__." linked order lines", LOG_DEBUG); if (!$this->db->query($sql1)) { $error++; @@ -4147,7 +4147,7 @@ class CommandeFournisseurLigne extends CommonOrderLine return -1; } - $sql1 = 'UPDATE '.MAIN_DB_PREFIX."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet=".((int) $this->id); + $sql1 = "UPDATE ".MAIN_DB_PREFIX."commandedet SET fk_commandefourndet = NULL WHERE fk_commandefourndet=".((int) $this->id); $resql = $this->db->query($sql1); if (!$resql) { $this->db->rollback(); From 1ca277faeff8819d40c0df8153c5ec7ec292226a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Mon, 20 Jan 2025 12:36:10 +0100 Subject: [PATCH 047/602] NEW: Use the packaging feature to round the quantities to some given multiples for the sale --- htdocs/product/admin/product.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index d38409f9eaa..92f698ed976 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -169,6 +169,11 @@ if ($action == 'other') { $value = GETPOST('PRODUCT_USE_SUPPLIER_PACKAGING', 'alpha'); $res = dolibarr_set_const($db, "PRODUCT_USE_SUPPLIER_PACKAGING", $value, 'chaine', 0, '', $conf->entity); } + + if (GETPOSTISSET('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $value = GETPOST('PRODUCT_USE_CUSTOMER_PACKAGING', 'alpha'); + $res = dolibarr_set_const($db, "PRODUCT_USE_CUSTOMER_PACKAGING", $value, 'chaine', 0, '', $conf->entity); + } } @@ -642,6 +647,17 @@ if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { print ''; } +// Use packaging during your sales +if (isModEnabled("order") || isModEnabled("invoice")) { + print ''; + print ''; + print ''; + print ''; +} + print '
'; + print ''; if ($action != 'editjournal') { @@ -634,6 +646,8 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; + print ''; print $formaccounting->select_journal($object->code_journal, 'code_journal', 0, 0, 0, 1, 1); print ''; print ''; @@ -809,6 +823,8 @@ if ($action == 'create') { print ''."\n"; print ''."\n"; print ''."\n"; + print ''; + print ''; if (count($object->linesmvt) > 0) { print '
'; @@ -965,13 +981,13 @@ if ($action == 'create') { if (empty($total_debit) && empty($total_credit)) { print ''; } elseif ($total_debit == $total_credit) { - print ''.$langs->trans("ValidTransaction").''; + print ''.$langs->trans("ValidTransaction").''; } else { print ''; } print '   '; - print ''.$langs->trans("Cancel").''; + print ''.$langs->trans("Cancel").''; print "
"; } From ceff811dafeb269456e742091a7a41aedc57a537 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 16 Dec 2024 08:09:32 +0100 Subject: [PATCH 025/602] CI --- htdocs/accountancy/bookkeeping/card.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 1ccc651b4f1..690c0999fa8 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -55,7 +55,7 @@ $confirm = GETPOST('confirm', 'alpha'); $type = GETPOST('type', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); if (empty($backtopage)) { - $backtopage = '/accountancy/bookkeeping/list.php'; + $backtopage = '/accountancy/bookkeeping/list.php'; } $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') @@ -464,8 +464,8 @@ if ($action == 'create') { print ''; print ''."\n"; print ''."\n"; - print ''; - print ''; + print ''; + print ''; print ''."\n"; print dol_get_fiche_head(); @@ -580,8 +580,8 @@ if ($action == 'create') { print ''; print ''; print ''; - print ''; - print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -613,8 +613,8 @@ if ($action == 'create') { print ''; print ''; print ''; - print ''; - print ''; + print ''; + print ''; print $form->selectDate($object->doc_date ? $object->doc_date : -1, 'doc_date', 0, 0, 0, "setdate"); print ''; print ''; @@ -646,8 +646,8 @@ if ($action == 'create') { print ''; print ''; print ''; - print ''; - print ''; + print ''; + print ''; print $formaccounting->select_journal($object->code_journal, 'code_journal', 0, 0, 0, 1, 1); print ''; print ''; @@ -823,8 +823,8 @@ if ($action == 'create') { print ''."\n"; print ''."\n"; print ''."\n"; - print ''; - print ''; + print ''; + print ''; if (count($object->linesmvt) > 0) { print '
'; From 077a8e2653b8aac0b35ea11a67b35d5c7d9ee1e0 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 16 Dec 2024 08:19:52 +0100 Subject: [PATCH 026/602] Right on create link --- htdocs/accountancy/bookkeeping/list.php | 2 +- htdocs/accountancy/bookkeeping/listbyaccount.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 2573a737ebc..4b4f57cc3b1 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -848,7 +848,7 @@ if (empty($reshook)) { $url .= '&socid='.$socid; } $newcardbutton .= dolGetButtonTitleSeparator(); - $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', $url, '', $user->hasRight('accounting', 'mouvements', 'creer')); + $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', $url, '', $permissiontoadd); } print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 2992bbf9c47..32525479a01 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -744,7 +744,7 @@ if (empty($reshook)) { $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly')); } $newcardbutton .= dolGetButtonTitleSeparator(); - $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'.(!empty($type)?'&type=sub':'').'&backtopage='.urlencode($_SERVER['PHP_SELF'])); + $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'.(!empty($type)?'&type=sub':'').'&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); } if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { From e577232359fdf0e94149da0965f109f4e408a9ee Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 16 Dec 2024 08:27:31 +0100 Subject: [PATCH 027/602] CI --- htdocs/accountancy/bookkeeping/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 690c0999fa8..fab3dec1c6a 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -528,7 +528,7 @@ if ($action == 'create') { $head = array(); $h = 0; - $head[$h][0] = DOL_URL_ROOT."/accountancy/bookkeeping/card.php".'?piece_num='.((int) $object->piece_num).($mode ? '&mode='.$mode : '').($type ? '&type='.$type : '').($backtopage ? '&backtopage='.urlencode($backtopage) : ''); + $head[$h][0] = DOL_URL_ROOT."/accountancy/bookkeeping/card.php".'?piece_num='.((int) $object->piece_num).($mode ? '&mode='.$mode : '').($type ? '&type='.$type : '').'&backtopage='.urlencode($backtopage); $head[$h][1] = $langs->trans("Transaction"); $head[$h][2] = 'transaction'; $h++; From 86833633efb1098e2363e41e2047b4813b20405a Mon Sep 17 00:00:00 2001 From: tnegre Date: Wed, 18 Dec 2024 10:26:26 +0100 Subject: [PATCH 028/602] fix --- htdocs/core/class/html.formticket.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 9c3a3847a24..4a140185432 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -863,9 +863,9 @@ class FormTicket print ' selected="selected"'; } elseif (isset($selected) && $selected == $id) { print ' selected="selected"'; - } elseif ($arraycategories['use_default'] == "1" && !$selected && !$empty) { + } elseif ($arraycategories['use_default'] == "1" && !$selected && (!$empty || $empty == 'ifone')) { print ' selected="selected"'; - } elseif (count($ticketstat->cache_category_tickets) == 1) { + } elseif (count($ticketstat->cache_category_tickets) == 1 && (!$empty || $empty == 'ifone')) { print ' selected="selected"'; } @@ -1201,7 +1201,7 @@ class FormTicket print ' selected="selected"'; } elseif (isset($selected) && $selected == $id) { print ' selected="selected"'; - } elseif ($arrayseverities['use_default'] == "1" && empty($selected)) { + } elseif ($arrayseverities['use_default'] == "1" && empty($selected) && (!$empty || $empty == 'ifone')) { print ' selected="selected"'; } elseif (count($ticketstat->cache_severity_tickets) == 1 && (!$empty || $empty == 'ifone')) { // If only 1 choice, we autoselect it print ' selected="selected"'; From 9bb3345c7b360924daa924be946d88e64f9ee7a8 Mon Sep 17 00:00:00 2001 From: William Mead Date: Wed, 18 Dec 2024 15:45:57 +0100 Subject: [PATCH 029/602] Added status change on progress update. Updated task status & labels. Added status to update method. --- htdocs/projet/class/task.class.php | 17 +++++++++++++---- htdocs/projet/tasks/task.php | 5 +++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 89c99873c09..ca5ae3d3dd2 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -357,6 +357,11 @@ class Task extends CommonObjectLine */ const STATUS_VALIDATED = 1; + /** + * Ongoing status (In progress). Note: We also have the field progress to know the progression from 0 to 100%. + */ + const STATUS_ONGOING = 2; + /** * Finished status */ @@ -565,7 +570,6 @@ class Task extends CommonObjectLine $this->date_end = $this->db->jdate($obj->date_end); $this->fk_user_creat = $obj->fk_user_creat; $this->fk_user_valid = $obj->fk_user_valid; - $this->fk_statut = $obj->status; $this->status = $obj->status; $this->progress = $obj->progress; $this->budget_amount = $obj->budget_amount; @@ -647,6 +651,10 @@ class Task extends CommonObjectLine return -1; } + if (isset($this->status)) { + $this->status = (int) $this->status; + } + // Check parameters // Put here code to add control on parameters values @@ -667,7 +675,8 @@ class Task extends CommonObjectLine $sql .= " budget_amount=".(($this->budget_amount != '' && $this->budget_amount >= 0) ? $this->budget_amount : 'null').","; $sql .= " rang=".((!empty($this->rang)) ? ((int) $this->rang) : "0").","; $sql .= " priority=".((!empty($this->priority)) ? ((int) $this->priority) : "0").","; - $sql .= " billable=".((int) $this->billable); + $sql .= " billable=".((int) $this->billable).","; + $sql .= " fk_statut=".((int) $this->status); $sql .= " WHERE rowid=".((int) $this->id); $this->db->begin(); @@ -2497,12 +2506,12 @@ class Task extends CommonObjectLine // list of Statut of the task $this->labelStatus[0] = 'Draft'; $this->labelStatus[1] = 'ToDo'; - $this->labelStatus[2] = 'Running'; + $this->labelStatus[2] = 'In progress'; $this->labelStatus[3] = 'Closed'; $this->labelStatus[4] = 'Transfered'; $this->labelStatusShort[0] = 'Draft'; $this->labelStatusShort[1] = 'ToDo'; - $this->labelStatusShort[2] = 'Running'; + $this->labelStatusShort[2] = 'In progress'; $this->labelStatusShort[3] = 'Closed'; $this->labelStatusShort[4] = 'Transfered'; diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 8a219264f96..99d01b26eb3 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -128,6 +128,11 @@ if ($action == 'update' && !GETPOST("cancel") && $user->hasRight('projet', 'cree $object->progress = price2num(GETPOST('progress', 'alphanohtml')); $object->budget_amount = GETPOSTFLOAT('budget_amount'); $object->billable = (GETPOST('billable', 'aZ') == 'yes' ? 1 : 0); + if (GETPOST('progress') == '100') { + $object->status = $object::STATUS_CLOSED; + } elseif (GETPOST('progress') != '0') { + $object->status = $object::STATUS_VALIDATED; + } // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET'); From fed049e93e2bccf66bed6416e04bf0fa46e49768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20PASCAL?= Date: Tue, 24 Dec 2024 10:36:53 +0100 Subject: [PATCH 030/602] feat: add function to get public holidays list within period --- htdocs/core/lib/date.lib.php | 268 +++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 1005cc70941..77fbf7944e2 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -1013,6 +1013,274 @@ function num_public_holiday($timestampStart, $timestampEnd, $country_code = '', return $nbFerie; } +/** + * Return the list of public holidays including Friday, Saturday and Sunday (or not) between 2 dates in timestamp. + * Dates must be UTC with hour, min, sec to 0. + * Called by function num_open_day() + * + * @param int $timestampStart Timestamp start (UTC with hour, min, sec = 0) + * @param int $timestampEnd Timestamp end (UTC with hour, min, sec = 0) + * @param string $country_code Country code + * @param int $lastday Last day is included, 0: no, 1:yes + * @param int $excludesaturday Exclude saturday as non working day (-1=use setup, 0=no, 1=yes) + * @param int $excludesunday Exclude sunday as non working day (-1=use setup, 0=no, 1=yes) + * @param int $excludefriday Exclude friday as non working day (-1=use setup, 0=no, 1=yes) + * @param int $excludemonday Exclude monday as non working day (-1=use setup, 0=no, 1=yes) + * @return int|array List of public holidays or error message string if error + * @see num_between_day(), num_open_day() + */ +function list_public_holiday($timestampStart, $timestampEnd, $country_code = '', $lastday = 0, $excludesaturday = -1, $excludesunday = -1, $excludefriday = -1, $excludemonday = -1) +{ + global $conf, $db, $mysoc; + + // Check to ensure we use correct parameters + if (($timestampEnd - $timestampStart) % 86400 != 0) { + return 'Error Dates must use same hours and must be GMT dates'; + } + + if (empty($country_code)) { + $country_code = $mysoc->country_code; + } + if ($excludemonday < 0) { + $excludemonday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY', 0); + } + if ($excludefriday < 0) { + $excludefriday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY', 0); + } + if ($excludesaturday < 0) { + $excludesaturday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY', 1); + } + if ($excludesunday < 0) { + $excludesunday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY', 1); + } + + $country_id = dol_getIdFromCode($db, $country_code, 'c_country', 'code', 'rowid'); + + if (empty($conf->cache['arrayOfActivePublicHolidays_' . $country_id])) { + // Loop on public holiday defined into hrm_public_holiday for the day, month and year analyzed + $tmpArrayOfPublicHolidays = array(); + $sql = "SELECT id, code, entity, fk_country, dayrule, year, month, day, active"; + $sql .= " FROM " . MAIN_DB_PREFIX . "c_hrm_public_holiday"; + $sql .= " WHERE active = 1 and fk_country IN (0" . ($country_id > 0 ? ", " . $country_id : 0) . ")"; + $sql .= " AND entity IN (0," . getEntity('holiday') . ")"; + + $resql = $db->query($sql); + if ($resql) { + $num_rows = $db->num_rows($resql); + $i = 0; + while ($i < $num_rows) { + $obj = $db->fetch_object($resql); + $tmpArrayOfPublicHolidays[$obj->id] = array('dayrule' => $obj->dayrule, 'year' => $obj->year, 'month' => $obj->month, 'day' => $obj->day); + $i++; + } + } else { + dol_syslog($db->lasterror(), LOG_ERR); + return 'Error sql ' . $db->lasterror(); + } + + //var_dump($tmpArrayOfPublicHolidays); + $conf->cache['arrayOfActivePublicHolidays_' . $country_id] = $tmpArrayOfPublicHolidays; + } + + $arrayOfPublicHolidays = $conf->cache['arrayOfActivePublicHolidays_' . $country_id]; + $listFeries = []; + $i = 0; + while ((($lastday == 0 && $timestampStart < $timestampEnd) || ($lastday && $timestampStart <= $timestampEnd)) + && ($i < 50000)) { // Loop end when equals (Test on i is a security loop to avoid infinite loop) + $nonWorkingDay = false; + $ferie = false; + $specialdayrule = array(); + + $jour = (int) gmdate("d", $timestampStart); + $mois = (int) gmdate("m", $timestampStart); + $annee = (int) gmdate("Y", $timestampStart); + + // If we have to exclude Friday, Saturday and Sunday + if ($excludefriday || $excludesaturday || $excludesunday) { + $jour_julien = unixtojd($timestampStart); + $jour_semaine = jddayofweek($jour_julien, 0); + if ($excludefriday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 5) { + $nonWorkingDay = true; + } + } + if ($excludesaturday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 6) { + $nonWorkingDay = true; + } + } + if ($excludesunday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 0) { + $nonWorkingDay = true; + } + } + } + //print "ferie=".$nonWorkingDay."\n"; + + if (!$nonWorkingDay) { + //print "jour=".$jour." month=".$mois." year=".$annee." includesaturday=".$excludesaturday." includesunday=".$excludesunday."\n"; + foreach ($arrayOfPublicHolidays as $entrypublicholiday) { + if (!empty($entrypublicholiday['dayrule']) && $entrypublicholiday['dayrule'] != 'date') { // For example 'easter', '...' + $specialdayrule[$entrypublicholiday['dayrule']] = $entrypublicholiday['dayrule']; + } else { + $match = 1; + if (!empty($entrypublicholiday['year']) && $entrypublicholiday['year'] != $annee) { + $match = 0; + } + if ($entrypublicholiday['month'] != $mois) { + $match = 0; + } + if ($entrypublicholiday['day'] != $jour) { + $match = 0; + } + + if ($match) { + $ferie = true; + $listFeries[] = $timestampStart; + } + } + + $i++; + } + //var_dump($specialdayrule)."\n"; + //print "ferie=".$nonWorkingDay."\n"; + } + + if (!$nonWorkingDay && !$ferie) { + // Special dayrules + if (in_array('easter', $specialdayrule)) { + // Calculation for easter date + $date_paques = getGMTEasterDatetime($annee); + $jour_paques = gmdate("d", $date_paques); + $mois_paques = gmdate("m", $date_paques); + if ($jour_paques == $jour && $mois_paques == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Easter (sunday) + } + + if (in_array('eastermonday', $specialdayrule)) { + // Calculation for the monday of easter date + $date_paques = getGMTEasterDatetime($annee); + //print 'PPP'.$date_paques.' '.dol_print_date($date_paques, 'dayhour', 'gmt')." "; + $date_lundi_paques = $date_paques + (3600 * 24); + $jour_lundi_paques = gmdate("d", $date_lundi_paques); + $mois_lundi_paques = gmdate("m", $date_lundi_paques); + if ($jour_lundi_paques == $jour && $mois_lundi_paques == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Easter (monday) + //print 'annee='.$annee.' $jour='.$jour.' $mois='.$mois.' $jour_lundi_paques='.$jour_lundi_paques.' $mois_lundi_paques='.$mois_lundi_paques."\n"; + } + + //Good Friday + if (in_array('goodfriday', $specialdayrule)) { + // Pulls the date of Easter + $easter = getGMTEasterDatetime($annee); + + // Calculates the date of Good Friday based on Easter + $date_good_friday = $easter - (2 * 3600 * 24); + $dom_good_friday = gmdate("d", $date_good_friday); + $month_good_friday = gmdate("m", $date_good_friday); + + if ($dom_good_friday == $jour && $month_good_friday == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + } + + if (in_array('ascension', $specialdayrule)) { + // Calcul du jour de l'ascension (39 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_ascension = $date_paques + (3600 * 24 * 39); + $jour_ascension = gmdate("d", $date_ascension); + $mois_ascension = gmdate("m", $date_ascension); + if ($jour_ascension == $jour && $mois_ascension == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Ascension (thursday) + } + + if (in_array('pentecost', $specialdayrule)) { + // Calculation of "Pentecote" (49 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_pentecote = $date_paques + (3600 * 24 * 49); + $jour_pentecote = gmdate("d", $date_pentecote); + $mois_pentecote = gmdate("m", $date_pentecote); + if ($jour_pentecote == $jour && $mois_pentecote == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // "Pentecote" (sunday) + } + + if (in_array('pentecotemonday', $specialdayrule)) { + // Calculation of "Pentecote" (49 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_pentecote = $date_paques + (3600 * 24 * 50); + $jour_pentecote = gmdate("d", $date_pentecote); + $mois_pentecote = gmdate("m", $date_pentecote); + if ($jour_pentecote == $jour && $mois_pentecote == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // "Pentecote" (monday) + } + + if (in_array('viernessanto', $specialdayrule)) { + // Viernes Santo + $date_paques = getGMTEasterDatetime($annee); + $date_viernes = $date_paques - (3600 * 24 * 2); + $jour_viernes = gmdate("d", $date_viernes); + $mois_viernes = gmdate("m", $date_viernes); + if ($jour_viernes == $jour && $mois_viernes == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + //Viernes Santo + } + + if (in_array('fronleichnam', $specialdayrule)) { + // Fronleichnam (60 days after easter sunday) + $date_paques = getGMTEasterDatetime($annee); + $date_fronleichnam = $date_paques + (3600 * 24 * 60); + $jour_fronleichnam = gmdate("d", $date_fronleichnam); + $mois_fronleichnam = gmdate("m", $date_fronleichnam); + if ($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Fronleichnam + } + + if (in_array('genevafast', $specialdayrule)) { + // Geneva fast in Switzerland (Thursday after the first sunday in September) + $date_1sunsept = strtotime('next thursday', strtotime('next sunday', mktime(0, 0, 0, 9, 1, $annee))); + $jour_1sunsept = date("d", $date_1sunsept); + $mois_1sunsept = date("m", $date_1sunsept); + if ($jour_1sunsept == $jour && $mois_1sunsept == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Geneva fast in Switzerland + } + } + //print "ferie=".$nonWorkingDay."\n"; + + // Increase number of days (on go up into loop) + $timestampStart = dol_time_plus_duree($timestampStart, 1, 'd'); + //var_dump($jour.' '.$mois.' '.$annee.' '.$timestampStart); + + $i++; + } + + //print "nbFerie=".$nbFerie."\n"; + return $listFeries; +} + /** * Function to return number of days between two dates (date must be UTC date !) * Example: 2012-01-01 2012-01-02 => 1 if lastday=0, 2 if lastday=1 From 39e509f3809ee47d40cefe2c7977b7b34bff53b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9?= Date: Tue, 24 Dec 2024 10:50:29 +0100 Subject: [PATCH 031/602] fix: list_public_holiday function return type --- htdocs/core/lib/date.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 77fbf7944e2..87ad6a3a213 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -1026,7 +1026,7 @@ function num_public_holiday($timestampStart, $timestampEnd, $country_code = '', * @param int $excludesunday Exclude sunday as non working day (-1=use setup, 0=no, 1=yes) * @param int $excludefriday Exclude friday as non working day (-1=use setup, 0=no, 1=yes) * @param int $excludemonday Exclude monday as non working day (-1=use setup, 0=no, 1=yes) - * @return int|array List of public holidays or error message string if error + * @return string|array List of public holidays or error message string if error * @see num_between_day(), num_open_day() */ function list_public_holiday($timestampStart, $timestampEnd, $country_code = '', $lastday = 0, $excludesaturday = -1, $excludesunday = -1, $excludefriday = -1, $excludemonday = -1) From 303b7423f350590e7046b5ef11de4c19964b2144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9?= Date: Tue, 24 Dec 2024 11:01:15 +0100 Subject: [PATCH 032/602] fix: update list_public_holiday return type --- htdocs/core/lib/date.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 87ad6a3a213..956a3f2d2a5 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -1026,7 +1026,7 @@ function num_public_holiday($timestampStart, $timestampEnd, $country_code = '', * @param int $excludesunday Exclude sunday as non working day (-1=use setup, 0=no, 1=yes) * @param int $excludefriday Exclude friday as non working day (-1=use setup, 0=no, 1=yes) * @param int $excludemonday Exclude monday as non working day (-1=use setup, 0=no, 1=yes) - * @return string|array List of public holidays or error message string if error + * @return string|int[] List of public holidays timestamps or error message string if error * @see num_between_day(), num_open_day() */ function list_public_holiday($timestampStart, $timestampEnd, $country_code = '', $lastday = 0, $excludesaturday = -1, $excludesunday = -1, $excludefriday = -1, $excludemonday = -1) From a3193a08bce1df62f5f4af092ff001eb3a089ea1 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 6 Jan 2025 13:56:32 +0100 Subject: [PATCH 033/602] FIX merge problem --- htdocs/fourn/commande/list.php | 4 ---- htdocs/fourn/facture/card.php | 4 ---- 2 files changed, 8 deletions(-) diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index e399ce50745..7616d21227f 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -512,12 +512,8 @@ if (empty($reshook)) { } $tva_tx = $lines[$i]->tva_tx; -<<<<<<< HEAD // @phan-suppress-next-line PhanTypeMismatchArgumentInternal - if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) { -======= if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', (string) $tva_tx)) { ->>>>>>> branch '20.0' of git@github.com:Dolibarr/dolibarr.git $tva_tx .= ' ('.$lines[$i]->vat_src_code.')'; } diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index b2de69e162e..a7d7df70c25 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1339,12 +1339,8 @@ if (empty($reshook)) { } $tva_tx = $lines[$i]->tva_tx; -<<<<<<< HEAD // @phan-suppress-next-line PhanTypeMismatchArgumentInternal - if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) { -======= if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', (string) $tva_tx)) { ->>>>>>> branch '20.0' of git@github.com:Dolibarr/dolibarr.git $tva_tx .= ' ('.$lines[$i]->vat_src_code.')'; } From 510d622f155f7be46b90401f86d5c95284d75130 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 6 Jan 2025 14:16:36 +0100 Subject: [PATCH 034/602] Remove DOL_URL_ROOT already present in backtopage --- htdocs/accountancy/bookkeeping/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index fab3dec1c6a..2b4cd2506d8 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -127,7 +127,7 @@ if (empty($reshook)) { $error = 0; if ($cancel) { - header("Location: ".DOL_URL_ROOT. $backtopage . (!empty($type)?'?type=sub':'')); + header("Location: ". $backtopage . (!empty($type)?'?type=sub':'')); exit; } @@ -361,7 +361,7 @@ if (empty($reshook)) { if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } else { - header("Location: " . DOL_URL_ROOT. $backtopage . "?sortfield=t.piece_num&sortorder=asc" . ($type ? '&type='.$type : '')); + header("Location: " . $backtopage . "?sortfield=t.piece_num&sortorder=asc" . ($type ? '&type='.$type : '')); exit; } } @@ -987,7 +987,7 @@ if ($action == 'create') { } print '   '; - print ''.$langs->trans("Cancel").''; + print ''.$langs->trans("Cancel").''; print "
"; } From 3daf44bf68d7172cf729ab0ca4ad05d546dc62dd Mon Sep 17 00:00:00 2001 From: William Mead Date: Wed, 8 Jan 2025 15:21:40 +0100 Subject: [PATCH 035/602] Fixed status --- htdocs/projet/class/task.class.php | 6 ++++-- htdocs/projet/tasks.php | 1 + htdocs/projet/tasks/task.php | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index ca5ae3d3dd2..19ff42e4957 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -435,6 +435,7 @@ class Task extends CommonObjectLine $sql .= ", budget_amount"; $sql .= ", priority"; $sql .= ", billable"; + $sql .= ", fk_statut"; $sql .= ") VALUES ("; $sql .= (!empty($this->entity) ? (int) $this->entity : (int) $conf->entity); $sql .= ", ".((int) $this->fk_project); @@ -453,6 +454,7 @@ class Task extends CommonObjectLine $sql .= ", ".(($this->budget_amount != '' && $this->budget_amount >= 0) ? ((int) $this->budget_amount) : 'null'); $sql .= ", ".(($this->priority != '' && $this->priority >= 0) ? (int) $this->priority : 'null'); $sql .= ", ".((int) $this->billable); + $sql .= ", ".((int) $this->status); $sql .= ")"; $this->db->begin(); @@ -2505,12 +2507,12 @@ class Task extends CommonObjectLine // list of Statut of the task $this->labelStatus[0] = 'Draft'; - $this->labelStatus[1] = 'ToDo'; + $this->labelStatus[1] = 'Validated'; $this->labelStatus[2] = 'In progress'; $this->labelStatus[3] = 'Closed'; $this->labelStatus[4] = 'Transfered'; $this->labelStatusShort[0] = 'Draft'; - $this->labelStatusShort[1] = 'ToDo'; + $this->labelStatusShort[1] = 'Validated'; $this->labelStatusShort[2] = 'In progress'; $this->labelStatusShort[3] = 'Closed'; $this->labelStatusShort[4] = 'Transfered'; diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index a0dab9b2d30..281d7189419 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -387,6 +387,7 @@ if ($action == 'createtask' && $user->hasRight('projet', 'creer')) { $task->progress = $progress; $task->budget_amount = $budget_amount; $task->billable = $billable; + $task->status = Task::STATUS_VALIDATED; // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost(null, $task); diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 99d01b26eb3..4d09cbcb1ef 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -131,7 +131,7 @@ if ($action == 'update' && !GETPOST("cancel") && $user->hasRight('projet', 'cree if (GETPOST('progress') == '100') { $object->status = $object::STATUS_CLOSED; } elseif (GETPOST('progress') != '0') { - $object->status = $object::STATUS_VALIDATED; + $object->status = $object::STATUS_ONGOING; } // Fill array 'array_options' with data from add form From 3415fffaac7050a28e1f7afdc9a24be0cdb79b85 Mon Sep 17 00:00:00 2001 From: William Mead Date: Wed, 8 Jan 2025 17:14:05 +0100 Subject: [PATCH 036/602] Added status update on addTimeSpent --- htdocs/projet/class/task.class.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 19ff42e4957..69a2f523d2e 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1726,6 +1726,17 @@ class Task extends CommonObjectLine $sql .= " SET duration_effective = (SELECT SUM(element_duration) FROM ".MAIN_DB_PREFIX."element_time as ptt where ptt.elementtype = 'task' AND ptt.fk_element = ".((int) $this->id).")"; if (isset($this->progress)) { $sql .= ", progress = ".((float) $this->progress); // Do not overwrite value if not provided + if ($this->progress == 100) { + $this->status = Task::STATUS_CLOSED; + } elseif ($this->progress != 0) { + $this->status = Task::STATUS_ONGOING; + } else { + $this->status = Task::STATUS_VALIDATED; + } + $sql .= ", fk_statut = ".$this->status; + } else { + $this->status = Task::STATUS_ONGOING; + $sql .= ", fk_statut = ".$this->status; } $sql .= " WHERE rowid = ".((int) $this->id); From 34409e8a4dd465556208488dec2be2b8ca8ebe15 Mon Sep 17 00:00:00 2001 From: vmaury Date: Sat, 11 Jan 2025 07:33:08 +0100 Subject: [PATCH 037/602] Fix 31370 Pb with external account --- htdocs/comm/propal/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 59bea619be2..4a5a5e69795 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -286,7 +286,7 @@ foreach ($object->fields as $key => $val) { } }*/ -if (!$user->hasRight('societe', 'client', 'voir')) { +if ($socid == 0 && !$user->hasRight('societe', 'client', 'voir')) { // add VMA $search_sale = $user->id; } From 40e22cc40eeb811fad95c1949e8eb85b5e505e92 Mon Sep 17 00:00:00 2001 From: vmaury Date: Sat, 11 Jan 2025 12:31:35 +0100 Subject: [PATCH 038/602] Fix 31370 Pb with external account --- htdocs/comm/propal/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 4a5a5e69795..96f5da1ce5f 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -286,7 +286,7 @@ foreach ($object->fields as $key => $val) { } }*/ -if ($socid == 0 && !$user->hasRight('societe', 'client', 'voir')) { // add VMA +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } From 09185331720be2a4f381cb99e4762170355a5626 Mon Sep 17 00:00:00 2001 From: uvaldenaire-opendsi Date: Mon, 13 Jan 2025 11:54:58 +0100 Subject: [PATCH 039/602] NEW add option to not prefill qty line at shipment creation --- htdocs/admin/expedition.php | 8 ++++++++ htdocs/expedition/card.php | 25 ++++++++++++++++++++----- htdocs/langs/en_US/admin.lang | 1 + htdocs/langs/fr_FR/admin.lang | 1 + 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 3fcfa7c7b36..5ad30fc921f 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -490,6 +490,14 @@ print '
'; +// Pre fill shipment qty option +print ''; +print ''; +print ''; + print '
'; print $langs->trans('Codejournal'); print ''; print ajax_constantonoff('EXPEDITION_ALLOW_ONLINESIGN', array(), null, 0, 0, 0, 2, 0, 1, '', '', 'inline-block', 0, $langs->trans("WarningOnlineSignature")); print '
'.$langs->trans("DontPrefillShipmentQty"); +print ''; +print ajax_constantonoff('SHIPMENT_DONT_PREFILL_QTY', array(), null, 0, 0, 0, 2, 0, 1, '', '', 'inline-block', 0, ''); +print '
'; print $form->buttonsSaveCancel("Modify", ''); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 8c365e7bee5..1b74583596c 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1360,7 +1360,11 @@ if ($action == 'create') { $deliverableQty = GETPOSTINT('qtyl'.$indiceAsked); } print ''; - print ''; + $qtylValue = $deliverableQty; + if (getDolGlobalBool('SHIPMENT_DONT_PREFILL_QTY', false)) { + $qtylValue = ''; + } + print ''; } else { if (getDolGlobalString('SHIPMENT_GETS_ALL_ORDER_PRODUCTS')) { print ''; @@ -1491,7 +1495,11 @@ if ($action == 'create') { print '
'; - print ''; + $qtylValue = $deliverableQty; + if (getDolGlobalBool('SHIPMENT_DONT_PREFILL_QTY', false)) { + $qtylValue = ''; + } + print ''; print '
'; - print ''; + $qtylValue = $deliverableQty; + if (getDolGlobalBool('SHIPMENT_DONT_PREFILL_QTY', false)) { + $qtylValue = ''; + } + print ''; print ''; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 436c7d2ddd2..bca02410227 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1805,6 +1805,7 @@ SendingsNumberingModules=Sendings numbering modules SendingsAbility=Support shipping sheets for customer deliveries NoNeedForDeliveryReceipts=In most cases, shipping sheets are used both as sheets for customer deliveries (list of products to send) and sheets that are received and signed by customer. Hence the product deliveries receipt is a duplicated feature and is rarely activated. FreeLegalTextOnShippings=Free text on shipments +DontPrefillShipmentQty = Don't prefill lines quantities at shipment creation ##### Deliveries ##### DeliveryOrderNumberingModules=Products deliveries receipt numbering module DeliveryOrderModel=Products deliveries receipt model diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index b5d380188cb..6cfe8774cc5 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1800,6 +1800,7 @@ SendingsNumberingModules=Modèles de numérotation des expéditions SendingsAbility=Prise en charge des bons d'expédition pour les livraisons clients NoNeedForDeliveryReceipts=Dans le plupart des cas, la fiche expédition est utilisée en tant que bon d'expédition (liste des produits expédiés) et bon de livraison (signée par le client). Le bon de réception est un doublon de fonctionnalité et est rarement utilisé. FreeLegalTextOnShippings=Mention complémentaire sur les expéditions +DontPrefillShipmentQty = Ne pas pré-remplir les quantités des lignes à la création d'une expédition ##### Deliveries ##### DeliveryOrderNumberingModules=Modèle de numérotation des bons de réception client DeliveryOrderModel=Modèle de bon de réception client From cf0c04c6ee870b36ff82f3e2ed4f00d225286a92 Mon Sep 17 00:00:00 2001 From: vmaury Date: Mon, 13 Jan 2025 11:58:16 +0100 Subject: [PATCH 040/602] Fix 31370 Pb with external account --- htdocs/comm/index.php | 46 +++++++++---------- htdocs/comm/propal/class/propal.class.php | 6 +-- .../comm/propal/class/propalestats.class.php | 12 ++--- htdocs/commande/class/commande.class.php | 10 ++-- htdocs/commande/class/commandestats.class.php | 12 ++--- htdocs/commande/index.php | 16 +++---- htdocs/commande/list.php | 5 +- htdocs/compta/facture/class/facture.class.php | 6 +-- .../facture/class/facturestats.class.php | 14 +++--- htdocs/compta/facture/list.php | 8 ++-- htdocs/compta/index.php | 6 +-- htdocs/contrat/class/contrat.class.php | 6 +-- htdocs/contrat/list.php | 4 +- htdocs/core/boxes/box_actions.php | 4 +- htdocs/core/boxes/box_actions_future.php | 4 +- htdocs/core/boxes/box_activity.php | 12 ++--- htdocs/core/boxes/box_clients.php | 4 +- htdocs/core/boxes/box_commandes.php | 4 +- htdocs/core/boxes/box_contacts.php | 4 +- htdocs/core/boxes/box_contracts.php | 4 +- ...box_customers_outstanding_bill_reached.php | 4 +- htdocs/core/boxes/box_factures.php | 4 +- htdocs/core/boxes/box_factures_fourn.php | 4 +- htdocs/core/boxes/box_factures_fourn_imp.php | 4 +- htdocs/core/boxes/box_factures_imp.php | 4 +- htdocs/core/boxes/box_ficheinter.php | 4 +- htdocs/core/boxes/box_fournisseurs.php | 4 +- .../boxes/box_graph_propales_permonth.php | 2 +- htdocs/core/boxes/box_propales.php | 4 +- htdocs/core/boxes/box_prospect.php | 4 +- htdocs/core/boxes/box_services_contracts.php | 2 +- htdocs/core/boxes/box_services_expired.php | 4 +- htdocs/core/boxes/box_shipments.php | 4 +- htdocs/core/boxes/box_supplier_orders.php | 4 +- ...box_supplier_orders_awaiting_reception.php | 4 +- htdocs/core/lib/invoice.lib.php | 36 ++++++++------- htdocs/core/lib/order.lib.php | 6 +-- htdocs/core/lib/propal.lib.php | 8 ++-- .../fichinter/class/fichinterstats.class.php | 10 ++-- htdocs/fichinter/list.php | 2 +- .../class/fournisseur.commande.class.php | 4 +- .../fourn/class/fournisseur.facture.class.php | 4 +- .../class/supplier_proposal.class.php | 8 ++-- htdocs/ticket/class/ticket.class.php | 6 +-- 44 files changed, 165 insertions(+), 162 deletions(-) diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 01c96b952f2..c45c7cb0fe6 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -140,13 +140,13 @@ if (isModEnabled("propal") && $user->hasRight("propal", "lire")) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($propalstatic->element).")"; $sql .= " AND p.fk_soc = s.rowid"; $sql .= " AND p.fk_statut = ".Propal::STATUS_DRAFT; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -239,13 +239,13 @@ if (isModEnabled('supplier_proposal') && $user->hasRight("supplier_proposal", "l $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($supplierproposalstatic->element).")"; $sql .= " AND p.fk_statut = ".SupplierProposal::STATUS_DRAFT; $sql .= " AND p.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -336,13 +336,13 @@ if (isModEnabled('order') && $user->hasRight('commande', 'lire')) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity($orderstatic->element).")"; $sql .= " AND c.fk_statut = ".Commande::STATUS_DRAFT; $sql .= " AND c.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -436,13 +436,13 @@ if ((isModEnabled("fournisseur") && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMO $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as cf,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE cf.entity IN (".getEntity($supplierorderstatic->element).")"; $sql .= " AND cf.fk_statut = ".CommandeFournisseur::STATUS_DRAFT; $sql .= " AND cf.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -534,7 +534,7 @@ if (isModEnabled('intervention')) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.entity IN (".getEntity('intervention').")"; @@ -543,7 +543,7 @@ if (isModEnabled('intervention')) { if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -617,12 +617,12 @@ if (isModEnabled("societe") && $user->hasRight('societe', 'lire')) { $sql .= ", s.canvas"; $sql .= ", s.datec, s.tms"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.entity IN (".getEntity($companystatic->element).")"; $sql .= " AND s.client IN (".Societe::CUSTOMER.", ".Societe::PROSPECT.", ".Societe::CUSTOMER_AND_PROSPECT.")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } // Add where from hooks @@ -725,7 +725,7 @@ if (isModEnabled('propal')) { $sql .= " AND c.fk_soc = s.rowid"; // If the internal user must only see his customers, force searching by him $search_sale = 0; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } // Search on sale representative @@ -820,7 +820,7 @@ if (isModEnabled('order')) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -829,7 +829,7 @@ if (isModEnabled('order')) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.tms DESC"; @@ -908,12 +908,12 @@ if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && $use $sql .= ", s.canvas"; $sql .= ", s.datec as dc, s.tms as dm"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.entity IN (".getEntity($companystatic->element).")"; $sql .= " AND s.fournisseur = ".Societe::SUPPLIER; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } // Add where from hooks @@ -1023,13 +1023,13 @@ if (isModEnabled('contract') && $user->hasRight("contrat", "lire") && 0) { // TO $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."contrat as c"; $sql .= ", ".MAIN_DB_PREFIX."product as p"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity($staticcontrat->element).")"; $sql .= " AND c.fk_soc = s.rowid"; $sql .= " AND c.fk_product = p.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -1098,13 +1098,13 @@ if (isModEnabled("propal") && $user->hasRight("propal", "lire")) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($propalstatic->element).")"; $sql .= " AND p.fk_soc = s.rowid"; $sql .= " AND p.fk_statut = ".Propal::STATUS_VALIDATED; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -1217,13 +1217,13 @@ if (isModEnabled('order') && $user->hasRight('commande', 'lire')) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity($orderstatic->element).")"; $sql .= " AND c.fk_soc = s.rowid"; $sql .= " AND c.fk_statut IN (".Commande::STATUS_VALIDATED.", ".Commande::STATUS_SHIPMENTONPROCESS.")"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index a27eca21f18..44fd80ca8b7 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2861,7 +2861,7 @@ class Propal extends CommonObject // If the internal user must only see his customers, force searching by him $search_sale = 0; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } // Search on sale representative @@ -3384,7 +3384,7 @@ class Propal extends CommonObject } // If the internal user must only see his customers, force searching by him $search_sale = 0; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } // Search on sale representative @@ -3561,7 +3561,7 @@ class Propal extends CommonObject // If the internal user must only see his customers, force searching by him $search_sale = 0; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } // Search on sale representative diff --git a/htdocs/comm/propal/class/propalestats.class.php b/htdocs/comm/propal/class/propalestats.class.php index 5321886f0fb..ace66cd25bd 100644 --- a/htdocs/comm/propal/class/propalestats.class.php +++ b/htdocs/comm/propal/class/propalestats.class.php @@ -122,7 +122,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -147,7 +147,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -171,7 +171,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, SUM(p.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -196,7 +196,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, AVG(p.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -219,7 +219,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%Y') as year, COUNT(*) as nb, SUM(".$this->field.") as total, AVG(".$this->field.") as avg"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -247,7 +247,7 @@ class PropaleStats extends Stats $sql .= " FROM ".$this->from; $sql .= " INNER JOIN ".$this->from_line." ON p.rowid = tl.fk_propal"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."product as product ON tl.fk_product = product.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 2ac0d52671a..70a7656fa0b 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -2715,16 +2715,16 @@ class Commande extends CommonOrder $sql = "SELECT s.rowid, s.nom as name, s.client,"; $sql .= " c.rowid as cid, c.ref"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", sc.fk_soc, sc.fk_user"; } $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as c"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity('commande').")"; $sql .= " AND c.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -3551,7 +3551,7 @@ class Commande extends CommonOrder $sql = "SELECT c.rowid, c.date_creation as datec, c.date_commande, c.date_livraison as delivery_date, c.fk_statut, c.total_ht"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = " AND"; @@ -4059,7 +4059,7 @@ class Commande extends CommonOrder $sql = "SELECT count(co.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as co"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON co.fk_soc = s.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/commande/class/commandestats.class.php b/htdocs/commande/class/commandestats.class.php index f9f49ef7ada..332bddd1698 100644 --- a/htdocs/commande/class/commandestats.class.php +++ b/htdocs/commande/class/commandestats.class.php @@ -123,7 +123,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -148,7 +148,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -172,7 +172,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -197,7 +197,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, AVG(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -220,7 +220,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%Y') as year, COUNT(*) as nb, SUM(c.".$this->field.") as total, AVG(".$this->field.") as avg"; $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; @@ -246,7 +246,7 @@ class CommandeStats extends Stats $sql .= " FROM ".$this->from; $sql .= " INNER JOIN ".$this->from_line." ON c.rowid = tl.fk_commande"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."product as product ON tl.fk_product = product.rowid"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; diff --git a/htdocs/commande/index.php b/htdocs/commande/index.php index 61be815d34d..ff9d1a3a6e2 100644 --- a/htdocs/commande/index.php +++ b/htdocs/commande/index.php @@ -98,7 +98,7 @@ if (isModEnabled('order')) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -107,7 +107,7 @@ if (isModEnabled('order')) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -164,7 +164,7 @@ $sql .= ", s.code_client"; $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; -if (!$user->hasRight('societe', 'client', 'voir')) { +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -173,7 +173,7 @@ $sql .= " AND c.entity IN (".getEntity('commande').")"; if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } -if (!$user->hasRight('societe', 'client', 'voir')) { +if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.tms DESC"; @@ -250,7 +250,7 @@ if (isModEnabled('order')) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -259,7 +259,7 @@ if (isModEnabled('order')) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.rowid DESC"; @@ -339,7 +339,7 @@ if (isModEnabled('order')) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -348,7 +348,7 @@ if (isModEnabled('order')) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } - if (!$user->hasRight('societe', 'client', 'voir')) { + if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.rowid DESC"; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 3db787bbcc2..b60cb2e58fe 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -906,9 +906,8 @@ $sql .= ' AND c.entity IN ('.getEntity('commande').')'; if ($socid > 0) { $sql .= ' AND s.rowid = '.((int) $socid); } - // Restriction on sale representative -if (!$permissiontoreadallthirdparty) { +if (empty($user->socid) && !$permissiontoreadallthirdparty) { $sql .= " AND (EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = c.fk_soc AND sc.fk_user = ".((int) $user->id).")"; if (getDolGlobalInt('MAIN_SEE_SUBORDINATES') && $userschilds) { $sql .= " OR EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = c.fk_soc AND sc.fk_user IN (".$db->sanitize(implode(',', $userschilds))."))"; @@ -1619,7 +1618,7 @@ if (!empty($arrayfields['p.title']['checked'])) { // Thirpdarty if (!empty($arrayfields['s.nom']['checked'])) { print ''; - print ''; + print 'socid) ? " disabled" : "").'>'; print ''; - print ''; + print 'socid > 0 ? " disabled" : "").'>'; print '
'.$form->textwithpicto($langs->trans("UseProductCustomerPackaging"), $langs->trans("PackagingForThisProductSellDesc")).''; + print ajax_constantonoff("PRODUCT_USE_CUSTOMER_PACKAGING", array(), $conf->entity, 0, 0, 0, 0); + //print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_CUSTOMER_PACKAGING) ? $conf->global->PRODUCT_USE_CUSTOMER_PACKAGING : 0), 1); + print '
'; print '
'; From a14a474a708c117906bd91f96f35dd7820ed7350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Mon, 20 Jan 2025 12:43:30 +0100 Subject: [PATCH 048/602] ADD: packaging to round the quantities to some given multiples for the sale prices --- htdocs/product/class/product.class.php | 13 ++++++++++++ htdocs/product/price.php | 28 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index fa3cc2b2d4e..d0b9dfd9738 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1438,6 +1438,9 @@ class Product extends CommonObject $this->accountancy_code_sell_intra = trim($this->accountancy_code_sell_intra); $this->accountancy_code_sell_export = trim($this->accountancy_code_sell_export); + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING') && !empty($this->packaging)) { + $this->packaging = $this->packaging; + } $this->db->begin(); @@ -1588,6 +1591,9 @@ class Product extends CommonObject $sql .= ", fk_price_expression = ".($this->fk_price_expression != 0 ? (int) $this->fk_price_expression : 'NULL'); $sql .= ", fk_user_modif = ".($user->id > 0 ? $user->id : 'NULL'); $sql .= ", mandatory_period = ".($this->mandatory_period); + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING') && !empty($this->packaging)) { + $sql .= ", packaging = ".($this->packaging); + } // stock field is not here because it is a denormalized value from product_stock. $sql .= " WHERE rowid = ".((int) $id); @@ -2888,6 +2894,9 @@ class Product extends CommonObject } else { $sql .= " ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export, ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export,"; } + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $sql .= " p.packaging,"; + } // For MultiCompany // PMP per entity & Stocks Sharings stock_reel includes only stocks shared with this entity @@ -3067,6 +3076,10 @@ class Product extends CommonObject $this->mandatory_period = $obj->mandatory_period; + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $this->packaging = $obj->packaging; + } + $this->db->free($resql); // fetch optionals attributes and labels diff --git a/htdocs/product/price.php b/htdocs/product/price.php index c0d130de0db..aba3ab981c7 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -283,6 +283,11 @@ if (empty($reshook)) { $psq = empty($newpsq) ? 0 : $newpsq; $maxpricesupplier = $object->min_recommended_price(); + // Packaging / Conditionnement + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $packaging = GETPOST('packaging'); + } + if (isModEnabled('dynamicprices')) { $object->fk_price_expression = empty($eid) ? 0 : $eid; //0 discards expression @@ -481,6 +486,11 @@ if (empty($reshook)) { if (!$error) { $db->begin(); + // Packaging / Conditionnement + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $object->packaging = $packaging; + } + foreach ($pricestoupdate as $key => $val) { $newprice = $val['price']; @@ -1421,6 +1431,13 @@ if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUS } print ''; + // Packaging / Conditionnement + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + print ''.$form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductSellDesc")).''; + print $object->packaging; + print ''; + } + // Price Label print ''.$langs->trans("PriceLabel").''; print $object->price_label; @@ -1743,6 +1760,17 @@ if (($action == 'edit_price' || $action == 'edit_level_price') && $object->getRi print ''; print ''; + // Packaging / Conditionnement + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + print ''; + print $form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductSellDesc")); + print ''; + $packaging = $object->packaging; + print ''; + print ''; + print ''; + } + // Price Label print ''; print $langs->trans('PriceLabel'); From b7b0a29e42b7f502d94ffcabae8a7d2f6598b99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Mon, 20 Jan 2025 12:50:09 +0100 Subject: [PATCH 049/602] ADD: packaging to round the quantities to some given multiples for the sales orders --- htdocs/commande/class/commande.class.php | 30 +++++++++++++++++++++++ htdocs/commande/class/orderline.class.php | 11 +++++++++ 2 files changed, 41 insertions(+) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 474c50a7ff7..55bc6ff71a1 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1634,6 +1634,20 @@ class Commande extends CommonOrder $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $product = new Product($this->db); + $result = $product->fetch($fk_product); + if ($qty < $product->packaging) { + $qty = $product->packaging; + } else { + if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + $coeff = intval((float) $qty / $product->packaging) + 1; + $qty = (float) $product->packaging * $coeff; + setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); + } + } + } + // Clean vat code $reg = array(); $vat_src_code = ''; @@ -2192,6 +2206,10 @@ class Commande extends CommonOrder $line->volume = $objp->volume; $line->volume_units = $objp->volume_units; + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $line->packaging = $objp->packaging; + } + $line->date_start = $this->db->jdate($objp->date_start); $line->date_end = $this->db->jdate($objp->date_end); @@ -3163,6 +3181,18 @@ class Commande extends CommonOrder $this->line->rang = $rangmax + 1; } + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + if ($qty < $this->line->packaging) { + $qty = $this->line->packaging; + } else { + if (!empty($this->line->packaging) && ($qty % $this->line->packaging) > 0) { + $coeff = intval($qty / $this->line->packaging) + 1; + $qty = $this->line->packaging * $coeff; + setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs'); + } + } + } + $this->line->id = $rowid; $this->line->label = $label; $this->line->desc = $desc; diff --git a/htdocs/commande/class/orderline.class.php b/htdocs/commande/class/orderline.class.php index e16bde3054e..9db924777f5 100644 --- a/htdocs/commande/class/orderline.class.php +++ b/htdocs/commande/class/orderline.class.php @@ -145,6 +145,10 @@ class OrderLine extends CommonOrderLine */ public $skip_update_total; + /** + * @var float + */ + public $packaging; /** * Constructor @@ -171,6 +175,9 @@ class OrderLine extends CommonOrderLine $sql .= ' cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc, p.tobatch as product_tobatch,'; $sql .= ' cd.date_start, cd.date_end, cd.vat_src_code'; + if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $sql .= ', p.packaging'; + } $sql .= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; $sql .= ' WHERE cd.rowid = '.((int) $rowid); @@ -225,6 +232,10 @@ class OrderLine extends CommonOrderLine $this->product_tobatch = $objp->product_tobatch; $this->fk_unit = $objp->fk_unit; + if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $this->packaging = $objp->packaging; + } + $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); From 979a10fcb183d37005e67deafa2d87174c578552 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 20 Jan 2025 15:26:06 +0100 Subject: [PATCH 050/602] Update list.php --- htdocs/compta/facture/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 7b7b2565569..aecb059d464 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -304,7 +304,7 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); '@phan-var-force array,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan -// Check only if it's an internal user, external users are already filterd by $socid +// Check only if it's an internal user, external users are already filtered by $socid if (empty($user->socid) && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } From 02dea8d103a8edd96746b0cfb3a307e9ed2f61ba Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 20 Jan 2025 17:11:06 +0100 Subject: [PATCH 051/602] fix: allow list mass action update price when price mode is multiprice price --- htdocs/core/actions_massactions.inc.php | 42 ++++++++++++++++++------- htdocs/product/list.php | 5 ++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 6e26ef0eca7..3f06f4f3e8c 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1281,18 +1281,38 @@ if (!$error && ($action == 'updateprice' && $confirm == 'yes') && $permissiontoa $result = $object->fetch($toselectid); //var_dump($contcats);exit; if ($result > 0) { - if ($obj->price_base_type == 'TTC') { - $newprice = $object->price_ttc * (100 + $pricepercentage) / 100; - $minprice = $object->price_min_ttc; + if (getDolGlobalString('PRODUIT_MULTIPRICES')) { + for ($level = 1; $level <= getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); $level++) { + // Force the update of the price of the product using the new VAT + if ($object->price_base_type == 'TTC') { + $newprice = $object->multiprices_ttc[$level] * (100 + $pricepercentage) / 100; + $minprice = $object->multiprices_min_ttc[$level]; + } else { + $newprice = $object->multiprices[$level] * (100 + $pricepercentage) / 100; + $minprice = $object->multiprices_min[$level]; + } + $ret = $object->updatePrice($newprice, $object->price_base_type, $user, $object->tva_tx, $minprice, $level, $object->tva_npr, 0, 0, array(), $object->default_vat_code); + + if ($res > 0) { + $nbok++; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } } else { - $newprice = $object->price * (100 + $pricepercentage) / 100; - $minprice = $object->price_min; - } - $res = $object->updatePrice($newprice, $obj->price_base_type, $user, $object->tva_tx, $minprice, 0, $object->tva_npr, 0, 0, array(), $object->default_vat_code); - if ($res > 0) { - $nbok++; - } else { - setEventMessages($object->error, $object->errors, 'errors'); + if ($object->price_base_type == 'TTC') { + $newprice = $object->price_ttc * (100 + $pricepercentage) / 100; + $minprice = $object->price_min_ttc; + } else { + $newprice = $object->price * (100 + $pricepercentage) / 100; + $minprice = $object->price_min; + } + $res = $object->updatePrice($newprice, $object->price_base_type, $user, $object->tva_tx, $minprice, 0, $object->tva_npr, 0, 0, array(), $object->default_vat_code); + if ($res > 0) { + $nbok++; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } } } else { setEventMessages($object->error, $object->errors, 'errors'); diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 4d817250cbe..cecce963be1 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -829,9 +829,8 @@ $arrayofmassactions = array( //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), ); if ($user->hasRight($rightskey, 'creer')) { - if (getDolGlobalString('PRODUCT_PRICE_UNIQ') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) { - $arrayofmassactions['preupdateprice'] = img_picto('', 'edit', 'class="pictofixedwidth"').$langs->trans("UpdatePrice"); - } + $arrayofmassactions['preupdateprice'] = img_picto('', 'edit', 'class="pictofixedwidth"').$langs->trans("UpdatePrice"); + $arrayofmassactions['switchonsalestatus'] = img_picto('', 'stop-circle', 'class="pictofixedwidth"').$langs->trans("SwitchOnSaleStatus"); $arrayofmassactions['switchonpurchasestatus'] = img_picto('', 'stop-circle', 'class="pictofixedwidth"').$langs->trans("SwitchOnPurchaseStatus"); From e4078477c6c05d51caabeacfd8b5004bed0dffcb Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 20 Jan 2025 17:32:08 +0100 Subject: [PATCH 052/602] fix: allow list mass action update price when price mode is multiprice price --- htdocs/core/actions_massactions.inc.php | 3 +-- htdocs/core/tpl/massactions_pre.tpl.php | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 3f06f4f3e8c..e84c02a8c93 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1291,8 +1291,7 @@ if (!$error && ($action == 'updateprice' && $confirm == 'yes') && $permissiontoa $newprice = $object->multiprices[$level] * (100 + $pricepercentage) / 100; $minprice = $object->multiprices_min[$level]; } - $ret = $object->updatePrice($newprice, $object->price_base_type, $user, $object->tva_tx, $minprice, $level, $object->tva_npr, 0, 0, array(), $object->default_vat_code); - + $res = $object->updatePrice($newprice, $object->price_base_type, $user, $object->tva_tx, $minprice, $level, $object->tva_npr, 0, 0, array(), $object->default_vat_code); if ($res > 0) { $nbok++; } else { diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index 3c321f10123..bdbcee257f5 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -112,7 +112,12 @@ if ($massaction == 'preupdateprice') { 'value' => $valuefield ); - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmUpdatePrice"), $langs->trans("ConfirmUpdatePriceQuestion", count($toselect)), "updateprice", $formquestion, 1, 0, 200, 500, 1); + $descConfirmPreUpdatePrice=$langs->trans("ConfirmUpdatePriceQuestion", count($toselect)); + if (getDolGlobalString('PRODUIT_MULTIPRICES')) { + $descConfirmPreUpdatePrice=$langs->trans("ConfirmUpdatePriceQuestion", count($toselect)*getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT') .' ('.$langs->transnoentities('PricingRule').', '.$langs->transnoentities('MultiPricesNumPrices').')'); + } + + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmUpdatePrice"), $descConfirmPreUpdatePrice, "updateprice", $formquestion, 1, 0, 200, 500, 1); } if ($massaction == 'presetsupervisor') { From be06fc32affc41b37a2b580ccdabf3fdda282586 Mon Sep 17 00:00:00 2001 From: MDW Date: Mon, 20 Jan 2025 15:55:19 +0100 Subject: [PATCH 053/602] Qual: Fix ci for new api_memberstypes.class # Qual: Fix ci for new api_memberstypes.class This fixes the notifications for the new api_memberstypes.class --- htdocs/adherents/class/api_members.class.php | 16 +++++++------ .../class/api_memberstypes.class.php | 23 +++++++++++++------ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index 19882d2fc11..55f5b61af8c 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -1,9 +1,9 @@ - * Copyright (C) 2017 Regis Houssin - * Copyright (C) 2020 Thibault FOUCART - * Copyright (C) 2020 Frédéric France - * Copyright (C) 2024 MDW +/* Copyright (C) 2016 Xebax Christy + * Copyright (C) 2017 Regis Houssin + * Copyright (C) 2020 Thibault FOUCART + * Copyright (C) 2020-2024 Frédéric France + * Copyright (C) 2024-2025 MDW * * 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 @@ -37,7 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; class Members extends DolibarrApi { /** - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var string[] Mandatory fields, checked when create and update object */ public static $FIELDS = array( 'morphy', @@ -283,7 +283,9 @@ class Members extends DolibarrApi /** * Create member object * - * @param array $request_data Request data + * @param array $request_data Request data + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return int ID of member * * @throws RestException 403 Access denied diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index 32e9e105fa2..c96967f79ff 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2025 MDW * * 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 @@ -28,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; class MembersTypes extends DolibarrApi { /** - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var string[] Mandatory fields, checked when create and update object */ public static $FIELDS = array( 'label', @@ -84,6 +85,8 @@ class MembersTypes extends DolibarrApi * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.libelle:like:'SO-%') and (t.subscription:=:'1')" * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names * @return array Array of member type objects + * @phan-return AdherentType[] + * @phpstan-return AdherentType[] * * @throws RestException */ @@ -143,7 +146,9 @@ class MembersTypes extends DolibarrApi /** * Create member type object * - * @param array $request_data Request data + * @param array $request_data Request data + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return int ID of member type */ public function post($request_data = null) @@ -175,7 +180,9 @@ class MembersTypes extends DolibarrApi * * @param int $id ID of member type to update * @param array $request_data Datas - * @return int + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data + * @return Object */ public function put($id, $request_data = null) { @@ -227,6 +234,8 @@ class MembersTypes extends DolibarrApi * * @param int $id member type ID * @return array + * @phan-return array + * @phpstan-return array */ public function delete($id) { @@ -261,8 +270,8 @@ class MembersTypes extends DolibarrApi /** * Validate fields before creating an object * - * @param array|null $data Data to validate - * @return array + * @param ?array $data Data to validate + * @return array * * @throws RestException */ @@ -282,8 +291,8 @@ class MembersTypes extends DolibarrApi /** * Clean sensible object datas * - * @param Object $object Object to clean - * @return Object Object with cleaned properties + * @param Object $object Object to clean + * @return Object Object with cleaned properties */ protected function _cleanObjectDatas($object) { From 576e70c3ce95da7511ce3c13f6b501c7a56d3d4c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 20 Jan 2025 22:32:30 +0100 Subject: [PATCH 054/602] FIX wrong update function parameter --- htdocs/fourn/class/api_supplier_invoices.class.php | 2 +- htdocs/ticket/class/api_tickets.class.php | 2 +- htdocs/zapier/class/api_zapier.class.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 13dc0e8b094..1614552ee5c 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -272,7 +272,7 @@ class SupplierInvoices extends DolibarrApi $this->invoice->$field = $value; } - if ($this->invoice->update($id, DolibarrApiAccess::$user)) { + if ($this->invoice->update(DolibarrApiAccess::$user)) { return $this->get($id); } diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php index 62f94b2491b..a40e54934a1 100644 --- a/htdocs/ticket/class/api_tickets.class.php +++ b/htdocs/ticket/class/api_tickets.class.php @@ -389,7 +389,7 @@ class Tickets extends DolibarrApi $this->ticket->$field = $value; } - if ($this->ticket->update($id, DolibarrApiAccess::$user)) { + if ($this->ticket->update(DolibarrApiAccess::$user)) { return $this->get($id); } diff --git a/htdocs/zapier/class/api_zapier.class.php b/htdocs/zapier/class/api_zapier.class.php index 5ff155aebf0..2ed4e984126 100644 --- a/htdocs/zapier/class/api_zapier.class.php +++ b/htdocs/zapier/class/api_zapier.class.php @@ -300,7 +300,7 @@ class Zapier extends DolibarrApi $this->hook->$field = $value; } - if ($this->hook->update($id, DolibarrApiAccess::$user) > 0) { + if ($this->hook->update(DolibarrApiAccess::$user) > 0) { return $this->get($id); } else { throw new RestException(500, $this->hook->error); From dc976ce2ec02e172c8074a666f1bc08850d4b478 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 20 Jan 2025 22:54:37 +0100 Subject: [PATCH 055/602] FIX remove socid when cloning a project without third parties --- htdocs/projet/class/project.class.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index d4ecaff58a0..cf7cc5558a4 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1729,9 +1729,7 @@ class Project extends CommonObject // Load source object $clone_project->fetch($fromid); $clone_project->fetch_optionals(); - if ($newthirdpartyid > 0) { - $clone_project->socid = $newthirdpartyid; - } + $clone_project->socid = ($newthirdpartyid > 0 ? $newthirdpartyid : 0); $clone_project->fetch_thirdparty(); $orign_dt_start = $clone_project->date_start; From 3c2e6140a1fc3cd2a2fb6a9e9d31e2af2cb14682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Tue, 21 Jan 2025 09:43:00 +0100 Subject: [PATCH 056/602] ADD: packaging to round the quantities to some given multiples for the commercials proposals --- htdocs/comm/propal/class/propal.class.php | 26 +++++++++++++++++++ .../comm/propal/class/propaleligne.class.php | 11 ++++++++ 2 files changed, 37 insertions(+) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index a78da69017f..cb3cd883abe 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -709,6 +709,20 @@ class Propal extends CommonObject $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $product = new Product($this->db); + $result = $product->fetch($fk_product); + if ($qty < $product->packaging) { + $qty = $product->packaging; + } else { + if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + $coeff = intval((float) $qty / $product->packaging) + 1; + $qty = (float) $product->packaging * $coeff; + setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); + } + } + } + // Clean vat code $reg = array(); $vat_src_code = ''; @@ -974,6 +988,18 @@ class Propal extends CommonObject $this->line->rang = $rangmax + 1; } + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + if ($qty < $this->line->packaging) { + $qty = $this->line->packaging; + } else { + if (!empty($this->line->packaging) && ($qty % $this->line->packaging) > 0) { + $coeff = intval($qty / $this->line->packaging) + 1; + $qty = $this->line->packaging * $coeff; + setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs'); + } + } + } + $this->line->id = $rowid; $this->line->label = $label; $this->line->desc = $desc; diff --git a/htdocs/comm/propal/class/propaleligne.class.php b/htdocs/comm/propal/class/propaleligne.class.php index ea403b5b363..817b6866f64 100644 --- a/htdocs/comm/propal/class/propaleligne.class.php +++ b/htdocs/comm/propal/class/propaleligne.class.php @@ -343,6 +343,10 @@ class PropaleLigne extends CommonObjectLine */ public $multicurrency_total_ttc; + /** + * @var float + */ + public $packaging; /** * Class line Constructor @@ -370,6 +374,9 @@ class PropaleLigne extends CommonObjectLine $sql .= ' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; $sql .= ' pd.date_start, pd.date_end, pd.product_type'; + if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $sql .= ', p.packaging'; + } $sql .= ' FROM '.MAIN_DB_PREFIX.'propaldet as pd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pd.fk_product = p.rowid'; $sql .= ' WHERE pd.rowid = '.((int) $rowid); @@ -418,6 +425,10 @@ class PropaleLigne extends CommonObjectLine $this->product_desc = $objp->product_desc; $this->fk_unit = $objp->fk_unit; + if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $this->packaging = $objp->packaging; + } + $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); From 33d2969ab843fdb4330ff2f8d9e5c6816ee62409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Tue, 21 Jan 2025 09:56:43 +0100 Subject: [PATCH 057/602] ADD: packaging to round the quantities to some given multiples for the invoices --- htdocs/compta/facture/class/facture.class.php | 26 +++++++++++++++++++ .../facture/class/factureligne.class.php | 12 +++++++++ 2 files changed, 38 insertions(+) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 179385b1aba..4964b9d9929 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3994,6 +3994,20 @@ class Facture extends CommonInvoice $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $product = new Product($this->db); + $result = $product->fetch($fk_product); + if ($qty < $product->packaging) { + $qty = $product->packaging; + } else { + if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + $coeff = intval((float) $qty / $product->packaging) + 1; + $qty = (float) $product->packaging * $coeff; + setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); + } + } + } + // Clean vat code $reg = array(); $vat_src_code = ''; @@ -4298,6 +4312,18 @@ class Facture extends CommonInvoice $this->line->rang = $rangmax + 1; } + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + if ($qty < $this->line->packaging) { + $qty = $this->line->packaging; + } else { + if (!empty($this->line->packaging) && ($qty % $this->line->packaging) > 0) { + $coeff = intval($qty / $this->line->packaging) + 1; + $qty = $this->line->packaging * $coeff; + setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs'); + } + } + } + $this->line->id = $rowid; $this->line->rowid = $rowid; $this->line->label = $label; diff --git a/htdocs/compta/facture/class/factureligne.class.php b/htdocs/compta/facture/class/factureligne.class.php index e4e2b1a3ae2..c96f07c056b 100644 --- a/htdocs/compta/facture/class/factureligne.class.php +++ b/htdocs/compta/facture/class/factureligne.class.php @@ -180,6 +180,11 @@ class FactureLigne extends CommonInvoiceLine */ public $fk_prev_id; + /** + * @var float + */ + public $packaging; + /** * Constructor @@ -211,6 +216,9 @@ class FactureLigne extends CommonInvoiceLine $sql .= ' fd.multicurrency_total_tva,'; $sql .= ' fd.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc'; + if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $sql .= ', p.packaging'; + } $sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid'; $sql .= ' WHERE fd.rowid = '.((int) $rowid); @@ -277,6 +285,10 @@ class FactureLigne extends CommonInvoiceLine $this->multicurrency_total_tva = $objp->multicurrency_total_tva; $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; + if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $this->packaging = $objp->packaging; + } + $this->fetch_optionals(); $this->db->free($result); From cf1ae3a5da2fee841482fb3efaccbbad7957ad5a Mon Sep 17 00:00:00 2001 From: William Mead Date: Tue, 21 Jan 2025 10:15:41 +0100 Subject: [PATCH 058/602] Fixed task status badge. Refactored LibStatut. --- htdocs/core/lib/functions.lib.php | 14 +----- htdocs/projet/class/task.class.php | 77 ++++++++++++++++-------------- 2 files changed, 42 insertions(+), 49 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8b79a7f4a63..12ba56bbe58 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3207,18 +3207,8 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi $morehtmlstatus .= $object->getLibStatut(5); } } elseif ($object->element == 'project_task') { - $object->fk_statut = 1; - $object->status = 1; - if ($object->progress > 0) { - $object->fk_statut = 2; - $object->status = 2; - } - if ($object->progress >= 100) { - $object->fk_statut = 3; - $object->status = 3; - } - $tmptxt = $object->getLibStatut(5); - $morehtmlstatus .= $tmptxt; // No status on task + $tmptxt = $object->getLibStatut(4); + $morehtmlstatus .= $tmptxt; } elseif (method_exists($object, 'getLibStatut')) { // Generic case for status $tmptxt = $object->getLibStatut(6); if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3)) { diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index c038185554a..f2bd2c74fdb 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -2516,7 +2516,7 @@ class Task extends CommonObjectLine // phpcs:enable global $langs; - // list of Statut of the task + // list of status of the task $this->labelStatus[0] = 'Draft'; $this->labelStatus[1] = 'Validated'; $this->labelStatus[2] = 'In progress'; @@ -2533,46 +2533,49 @@ class Task extends CommonObjectLine } elseif ($mode == 1) { return $langs->trans($this->labelStatusShort[$status]); } elseif ($mode == 2) { - if ($status == 0) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut0').' '.$langs->trans($this->labelStatusShort[$status]); - } elseif ($status == 1) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut1').' '.$langs->trans($this->labelStatusShort[$status]); - } elseif ($status == 2) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut3').' '.$langs->trans($this->labelStatusShort[$status]); - } elseif ($status == 3) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6').' '.$langs->trans($this->labelStatusShort[$status]); - } elseif ($status == 4) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6').' '.$langs->trans($this->labelStatusShort[$status]); - } elseif ($status == 5) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut5').' '.$langs->trans($this->labelStatusShort[$status]); + switch ($status) { + case 0: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut0').' '.$langs->trans($this->labelStatusShort[$status]); + case 1: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut1').' '.$langs->trans($this->labelStatusShort[$status]); + case 2: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut3').' '.$langs->trans($this->labelStatusShort[$status]); + case 3: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6').' '.$langs->trans($this->labelStatusShort[$status]); + case 4: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6').' '.$langs->trans($this->labelStatusShort[$status]); + case 5: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut5').' '.$langs->trans($this->labelStatusShort[$status]); } } elseif ($mode == 3) { - if ($status == 0) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut0'); - } elseif ($status == 1) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut1'); - } elseif ($status == 2) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut3'); - } elseif ($status == 3) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6'); - } elseif ($status == 4) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6'); - } elseif ($status == 5) { - return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut5'); + switch ($status) { + case 0: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut0'); + case 1: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut1'); + case 2: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut3'); + case 3: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6'); + case 4: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut6'); + case 5: + return img_picto($langs->trans($this->labelStatusShort[$status]), 'statut5'); } } elseif ($mode == 4) { - if ($status == 0) { - return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status0', $mode); - } elseif ($status == 1) { - return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status1', $mode); - } elseif ($status == 2) { - return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status2', $mode); - } elseif ($status == 3) { - return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status3', $mode); - } elseif ($status == 4) { - return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status4', $mode); - } elseif ($status == 5) { - return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status5', $mode); + switch ($status) { + case 0: + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status0', $mode); + case 1: + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status1', $mode); + case 2: + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status2', $mode); + case 3: + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status3', $mode); + case 4: + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status4', $mode); + case 5: + return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]), '', 'status5', $mode); } } elseif ($mode == 5) { /*if ($status==0) return $langs->trans($this->labelStatusShort[$status]).' '.img_picto($langs->trans($this->labelStatusShort[$status]),'statut0'); From 58676e4287872529a0b62cd9f93c12f668a3d2d3 Mon Sep 17 00:00:00 2001 From: William Mead Date: Tue, 21 Jan 2025 12:03:17 +0100 Subject: [PATCH 059/602] Added task list status filter. Cleaned code. --- htdocs/core/lib/project.lib.php | 14 +++++------ htdocs/langs/en_US/main.lang | 1 + htdocs/langs/en_US/projects.lang | 1 + htdocs/projet/class/task.class.php | 27 +++++++++++--------- htdocs/projet/tasks.php | 40 ++++++++++++++++++------------ htdocs/projet/tasks/list.php | 31 +++++++++++++++++++++++ 6 files changed, 79 insertions(+), 35 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index ffd3420fb38..9ec5e33b555 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -870,6 +870,13 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t print ''; } + // Status + if (count($arrayfields) > 0 && !empty($arrayfields['t.fk_statut']['checked'])) { + print ''; + print $taskstatic->getLibStatut(4); + print ''; + } + if ($showbilltime) { // Time not billed if (count($arrayfields) > 0 && !empty($arrayfields['t.tobill']['checked'])) { @@ -955,13 +962,6 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t print ''; } - // Status - if (count($arrayfields) > 0 && !empty($arrayfields['t.fk_statut']['checked'])) { - print ''; - print $taskstatic->getLibStatut(4); - print ''; - } - // Extra fields $extrafieldsobjectkey = $taskstatic->table_element; $extrafieldsobjectprefix = 'efpt.'; diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index a76687104cb..0542f2ac060 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -1347,3 +1347,4 @@ SpecialLine=Special Line EcoTax=Eco-Tax GroupingLine=Grouping line AllTime=From start +Transferred=Transferred diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 22f6e3f3559..9e2bf735982 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -314,3 +314,4 @@ ErrorsTaskMerge=An error occurred while merging tasks Billable = Billable ConfirmCloseTask=Are you sure you want to close this task ? ConfirmClosed=Confirm task closed +TaskStatus=Task status diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index f2bd2c74fdb..4696ce2baf1 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -386,6 +386,21 @@ class Task extends CommonObjectLine public function __construct($db) { $this->db = $db; + // list of status of the task + $this->labelStatus = array( + 0 => 'Draft', + 1 => 'Validated', + 2 => 'In progress', + 3 => 'Closed', + 4 => 'Transferred', + ); + $this->labelStatusShort = array( + 0 => 'Draft', + 1 => 'Validated', + 2 => 'In progress', + 3 => 'Closed', + 4 => 'Transferred', + ); } @@ -2516,18 +2531,6 @@ class Task extends CommonObjectLine // phpcs:enable global $langs; - // list of status of the task - $this->labelStatus[0] = 'Draft'; - $this->labelStatus[1] = 'Validated'; - $this->labelStatus[2] = 'In progress'; - $this->labelStatus[3] = 'Closed'; - $this->labelStatus[4] = 'Transfered'; - $this->labelStatusShort[0] = 'Draft'; - $this->labelStatusShort[1] = 'Validated'; - $this->labelStatusShort[2] = 'In progress'; - $this->labelStatusShort[3] = 'Closed'; - $this->labelStatusShort[4] = 'Transfered'; - if ($mode == 0) { return $langs->trans($this->labelStatus[$status]); } elseif ($mode == 1) { diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 281d7189419..1128ffa0b0e 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -98,7 +98,7 @@ $search_progresscalc = GETPOST('search_progresscalc'); $search_progressdeclare = GETPOST('search_progressdeclare'); $search_task_budget_amount = GETPOST('search_task_budget_amount'); $search_task_billable = GETPOST('search_task_billable'); -$search_fk_statut = GETPOSTINT('search_fk_statut'); +$search_status = GETPOSTINT('search_status'); $search_date_start_startmonth = GETPOSTINT('search_date_start_startmonth'); $search_date_start_startyear = GETPOSTINT('search_date_start_startyear'); @@ -182,9 +182,9 @@ $arrayfields = array( 't.progress_calculated' => array('label' => "ProgressCalculated", 'checked' => 1, 'position' => 8), 't.progress' => array('label' => "ProgressDeclared", 'checked' => 1, 'position' => 9), 't.progress_summary' => array('label' => "TaskProgressSummary", 'checked' => 1, 'position' => 10), - 't.budget_amount' => array('label' => "Budget", 'checked' => 0, 'position' => 11), - 'c.assigned' => array('label' => "TaskRessourceLinks", 'checked' => 1, 'position' => 12), - 't.fk_statut' => array('label' => "Status", 'checked' => 1, 'position' => 12), + 't.fk_statut' => array('label' => "Status", 'checked' => 1, 'position' => 11), + 't.budget_amount' => array('label' => "Budget", 'checked' => 0, 'position' => 12), + 'c.assigned' => array('label' => "TaskRessourceLinks", 'checked' => 1, 'position' => 13), ); if ($object->usage_bill_time) { @@ -251,7 +251,7 @@ if (empty($reshook)) { $search_progressdeclare = ''; $search_task_budget_amount = ''; $search_task_billable = ''; - $search_fk_statut = ''; + $search_status = -1; $toselect = array(); $search_array_options = array(); $search_date_start_startmonth = ""; @@ -330,15 +330,15 @@ if (!empty($search_progresscalc)) { $morewherefilterarray[] = '(planned_workload IS NULL OR planned_workload = 0 OR '.natural_search('ROUND(100 * duration_effective / planned_workload, 2)', $search_progresscalc, 1, 1).')'; //natural_search('round(100 * $line->duration_effective / $line->planned_workload,2)', $filterprogresscalc, 1, 1).' {return 1;} else {return 0;}'; } +if ($search_status > -1) { + $morewherefilterarray[] = " t.fk_statut = ".$search_status; +} if ($search_task_budget_amount) { $morewherefilterarray[] = natural_search('t.budget_amount', $search_task_budget_amount, 1, 1); } if ($search_task_billable) { $morewherefilterarray[] = " t.billable = ".($search_task_billable == "yes" ? 1 : 0); } -if ($search_fk_statut) { - $morewherefilterarray[] = " t.fk_statut = ".$search_fk_statut; -} //var_dump($morewherefilterarray); $morewherefilter = ''; @@ -579,6 +579,9 @@ if ($id > 0 || !empty($ref)) { if ($search_progressdeclare) { $param .= '&search_progressdeclare='.urlencode($search_progressdeclare); } + if ($search_status) { + $param .= '&search_status='.urlencode($search_status); + } if ($search_task_budget_amount) { $param .= '&search_task_budget_amount='.urlencode($search_task_budget_amount); } @@ -1057,6 +1060,16 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- print ''; } + if (!empty($arrayfields['t.fk_statut']['checked'])) { + print ''; + $arrayofstatus = array(); + foreach ($taskstatic->labelStatusShort as $key => $val) { + $arrayofstatus[$key] = $langs->trans($val); + } + print $form->selectarray('search_status', $arrayofstatus, $search_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); + print ''; + } + if ($object->usage_bill_time) { if (!empty($arrayfields['t.tobill']['checked'])) { print ''; @@ -1085,11 +1098,6 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- print $form->selectyesno('search_task_billable', $search_task_billable, 0, false, 1); print ''; } - if (!empty($arrayfields['t.fk_statut']['checked'])) { - print ''; - //TODO: add status filter - print ''; - } include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -1147,6 +1155,9 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- if (!empty($arrayfields['t.progress_summary']['checked'])) { print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '', 1); } + if (!empty($arrayfields['t.fk_statut']['checked'])) { + print_liste_field_titre($arrayfields['t.fk_statut']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', ''); + } if ($object->usage_bill_time) { if (!empty($arrayfields['t.tobill']['checked'])) { print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "t.tobill", '', $param, '', $sortfield, $sortorder, 'right '); @@ -1168,9 +1179,6 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- print_liste_field_titre($arrayfields['t.billable']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', ''); } - if (!empty($arrayfields['t.fk_statut']['checked'])) { - print_liste_field_titre($arrayfields['t.fk_statut']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', ''); - } // Extra fields $disablesortlink = 1; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 056860cd47e..37c156c2b28 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -70,6 +70,7 @@ $search_project_user = GETPOST('search_project_user', 'intcomma'); $search_task_user = GETPOST('search_task_user', 'intcomma'); $search_task_progress = GETPOST('search_task_progress'); $search_task_budget_amount = GETPOST('search_task_budget_amount'); +$search_task_status = GETPOSTINT('search_task_status'); $search_societe = GETPOST('search_societe'); $search_societe_alias = GETPOST('search_societe_alias'); $search_opp_status = GETPOST("search_opp_status", 'alpha'); @@ -181,6 +182,7 @@ $arrayfields = array( 't.progress' => array('label' => "ProgressDeclared", 'checked' => 1, 'position' => 305), 't.progress_summary' => array('label' => "TaskProgressSummary", 'checked' => 1, 'position' => 306), 't.budget_amount' => array('label' => "Budget", 'checked' => 0, 'position' => 307), + 't.fk_statut' => array('label' => "TaskStatus", 'checked' => 0, 'position' => 308), 't.tobill' => array('label' => "TimeToBill", 'checked' => 0, 'position' => 310), 't.billed' => array('label' => "TimeBilled", 'checked' => 0, 'position' => 311), 't.datec' => array('label' => "DateCreation", 'checked' => 0, 'position' => 500), @@ -241,6 +243,7 @@ if (empty($reshook)) { $search_task_progress = ""; $search_task_budget_amount = ""; $search_task_user = -1; + $search_task_status = -1; $search_project_user = -1; $search_date_startday = ''; $search_date_startmonth = ''; @@ -464,6 +467,9 @@ if ($search_project_user > 0) { if ($search_task_user > 0) { $sql .= " AND ect.fk_c_type_contact IN (".$db->sanitize(implode(',', array_keys($listoftaskcontacttype))).") AND ect.element_id = t.rowid AND ect.fk_socpeople = ".((int) $search_task_user); } +if ($search_task_status > -1) { + $sql .= " AND t.fk_statut = ".((int) $search_task_status); +} // Search for tag/category ($searchCategoryProjectList is an array of ID) $searchCategoryProjectList = array($search_categ); $searchCategoryProjectOperator = 0; @@ -685,6 +691,9 @@ if ($search_task_ref_parent != '') { if ($search_task_progress != '') { $param .= '&search_task_progress='.urlencode($search_task_progress); } +if ($search_task_status != '') { + $param .= '&search_task_status='.urlencode($search_task_status); +} if ($search_societe != '') { $param .= '&search_societe='.urlencode($search_societe); } @@ -954,6 +963,15 @@ if (!empty($arrayfields['t.progress']['checked'])) { if (!empty($arrayfields['t.progress_summary']['checked'])) { print ''; } +if (!empty($arrayfields['t.fk_statut']['checked'])) { + print ''; + $arrayofstatus = array(); + foreach ($object->labelStatusShort as $key => $val) { + $arrayofstatus[$key] = $langs->trans($val); + } + print $form->selectarray('search_task_status', $arrayofstatus, $search_task_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); + print ''; +} if (!empty($arrayfields['t.budget_amount']['checked'])) { print ''; @@ -1086,6 +1104,10 @@ if (!empty($arrayfields['t.progress_summary']['checked'])) { print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "t.progress", "", $param, '', $sortfield, $sortorder, 'center '); $totalarray['nbfield']++; } +if (!empty($arrayfields['t.fk_statut']['checked'])) { + print_liste_field_titre($arrayfields['t.fk_statut']['label'], $_SERVER["PHP_SELF"], "t.fk_statut", "", $param, '', $sortfield, $sortorder, 'center '); + $totalarray['nbfield']++; +} if (!empty($arrayfields['t.budget_amount']['checked'])) { print_liste_field_titre($arrayfields['t.budget_amount']['label'], $_SERVER["PHP_SELF"], "t.budget_amount", "", $param, '', $sortfield, $sortorder, 'center '); $totalarray['nbfield']++; @@ -1479,6 +1501,15 @@ while ($i < $imaxinloop) { $totalarray['totalprogress_summary'] = $totalarray['nbfield']; } } + // Project status + if (!empty($arrayfields['t.fk_statut']['checked'])) { + print ''; + print $object->getLibStatut(4); + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } // Budget for task if (!empty($arrayfields['t.budget_amount']['checked'])) { print ''; From 932df6a5ed2dc4d0fa5d4750471c5b19847faab2 Mon Sep 17 00:00:00 2001 From: William Mead Date: Tue, 21 Jan 2025 12:18:16 +0100 Subject: [PATCH 060/602] Cleaned code --- htdocs/projet/class/task.class.php | 4 ---- htdocs/projet/tasks.php | 2 +- htdocs/projet/tasks/list.php | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 4696ce2baf1..848310af2e6 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -668,10 +668,6 @@ class Task extends CommonObjectLine return -1; } - if (isset($this->status)) { - $this->status = (int) $this->status; - } - // Check parameters // Put here code to add control on parameters values diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 1128ffa0b0e..fcd8aa3d572 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -580,7 +580,7 @@ if ($id > 0 || !empty($ref)) { $param .= '&search_progressdeclare='.urlencode($search_progressdeclare); } if ($search_status) { - $param .= '&search_status='.urlencode($search_status); + $param .= '&search_status='.urlencode((string)$search_status); } if ($search_task_budget_amount) { $param .= '&search_task_budget_amount='.urlencode($search_task_budget_amount); diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 37c156c2b28..a751dd53677 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -692,7 +692,7 @@ if ($search_task_progress != '') { $param .= '&search_task_progress='.urlencode($search_task_progress); } if ($search_task_status != '') { - $param .= '&search_task_status='.urlencode($search_task_status); + $param .= '&search_task_status='.urlencode((string)$search_task_status); } if ($search_societe != '') { $param .= '&search_societe='.urlencode($search_societe); From d03810a0d011e4b6374103a977519d14d10a8c18 Mon Sep 17 00:00:00 2001 From: William Mead Date: Tue, 21 Jan 2025 14:19:26 +0100 Subject: [PATCH 061/602] Fixed filter --- htdocs/projet/tasks.php | 3 +-- htdocs/projet/tasks/list.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index fcd8aa3d572..8563d7f1857 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -98,7 +98,7 @@ $search_progresscalc = GETPOST('search_progresscalc'); $search_progressdeclare = GETPOST('search_progressdeclare'); $search_task_budget_amount = GETPOST('search_task_budget_amount'); $search_task_billable = GETPOST('search_task_billable'); -$search_status = GETPOSTINT('search_status'); +$search_status = GETPOST('search_status'); $search_date_start_startmonth = GETPOSTINT('search_date_start_startmonth'); $search_date_start_startyear = GETPOSTINT('search_date_start_startyear'); @@ -431,7 +431,6 @@ if ($action == 'createtask' && $user->hasRight('projet', 'creer')) { } } - /* * View */ diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index a751dd53677..5dfdd4d7132 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -70,7 +70,7 @@ $search_project_user = GETPOST('search_project_user', 'intcomma'); $search_task_user = GETPOST('search_task_user', 'intcomma'); $search_task_progress = GETPOST('search_task_progress'); $search_task_budget_amount = GETPOST('search_task_budget_amount'); -$search_task_status = GETPOSTINT('search_task_status'); +$search_task_status = GETPOST('search_task_status'); $search_societe = GETPOST('search_societe'); $search_societe_alias = GETPOST('search_societe_alias'); $search_opp_status = GETPOST("search_opp_status", 'alpha'); From 1569366feb7903dad163663b34f756d3a8ced09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Tue, 21 Jan 2025 14:45:33 +0100 Subject: [PATCH 062/602] ADD: translations for option Use the packaging feature to round the quantities to some given multiples for the sale --- htdocs/langs/en_US/products.lang | 3 +++ htdocs/langs/fr_FR/products.lang | 3 +++ 2 files changed, 6 insertions(+) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index ededc52cbfc..40769a0af05 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -345,6 +345,9 @@ ProductSupplierDescription=Vendor description for the product UseProductSupplierPackaging=Use the "packaging" feature to round the quantities to some given multiples (when adding/updating line in a vendor documents, recalculate quantities and purchase prices according to the higher multiple set on the purchase prices of a product) PackagingForThisProduct=Packaging of quantities PackagingForThisProductDesc=You will automatically purchase a multiple of this quantity. +UseProductCustomerPackaging=Use the "packaging" feature to round the quantities to some given multiples (when adding/updating line in a customer documents, recalculate quantities and sale prices according to the higher multiple set on the sale prices of a product) +PackagingForThisProductSell=Packaging of quantities (sale) +PackagingForThisProductSellDesc=You will automatically sell a multiple of this quantity. QtyRecalculatedWithPackaging=The quantity of the line were recalculated according to supplier packaging #Attributes diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 2dd144775d4..73eb7584c2a 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -345,6 +345,9 @@ ProductSupplierDescription=Description du fournisseur du produit UseProductSupplierPackaging=Utilisez la fonction "conditionnement" pour arrondir les quantités à certains multiples donnés (lors de l'ajout/de la mise à jour d'une ligne, dans les documents d'un fournisseur, recalculez les quantités et les prix d'achat en fonction du multiple supérieur défini sur les prix d'achat d'un produit) PackagingForThisProduct=Conditionnement des quantités PackagingForThisProductDesc=Vous achèterez automatiquement un multiple de cette quantité. +UseProductCustomerPackaging=Utilisez la fonction "conditionnement" pour arrondir les quantités à certains multiples donnés (lors de l'ajout/de la mise à jour d'une ligne, dans les documents d'un client, recalculez les quantités et les prix de vente en fonction du multiple supérieur défini sur les prix de vente d'un produit) +PackagingForThisProductSell=Conditionnement des quantités (vente) +PackagingForThisProductSellDesc=Vous vendrez automatiquement un multiple de cette quantité. QtyRecalculatedWithPackaging=La quantité de la ligne a été recalculée en fonction de l'emballage du fournisseur #Attributes From 3230e83f2b5c5e34b157424f0c12e3321555f275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Tue, 21 Jan 2025 15:59:13 +0100 Subject: [PATCH 063/602] ADD: the packaging field to product import --- htdocs/core/modules/modProduct.class.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 7b87d30b1f4..01b77908a23 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -638,6 +638,12 @@ class modProduct extends DolibarrModules )); } + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $this->import_fields_array[$r] = array_merge($this->import_fields_array[$r], array( + 'p.packaging' => 'PackagingForThisProductSell', + )); + } + if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice") || isModEnabled('margin')) { $this->import_fields_array[$r] = array_merge($this->import_fields_array[$r], array('p.cost_price' => 'CostPrice')); } @@ -755,6 +761,13 @@ class modProduct extends DolibarrModules ) )); } + + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $import_sample = array_merge($import_sample, array( + 'p.packaging' => "2", + )); + } + $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample); $this->import_updatekeys_array[$r] = array('p.ref' => 'Ref'); if (isModEnabled('barcode')) { From 7a8e0d9b5ccd24e1571559a0e19dd9457f4147d3 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 21 Jan 2025 18:51:18 +0100 Subject: [PATCH 064/602] FIX #32736 + avoid php warning --- htdocs/compta/sociales/card.php | 1 + htdocs/compta/sociales/list.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index 67ede36a989..e6027db3b1c 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -207,6 +207,7 @@ if (empty($reshook)) { $object->mode_reglement_id = GETPOSTINT('mode_reglement_id'); $object->fk_account = GETPOSTINT('fk_account'); $object->fk_project = GETPOSTINT('fk_project'); + $object->paye = ChargeSociales::STATUS_UNPAID; $id = $object->create($user); if ($id <= 0) { diff --git a/htdocs/compta/sociales/list.php b/htdocs/compta/sociales/list.php index 550c532ddb5..92f4772fcab 100644 --- a/htdocs/compta/sociales/list.php +++ b/htdocs/compta/sociales/list.php @@ -72,7 +72,7 @@ $search_date_limit_endyear = GETPOSTINT('search_date_limit_endyear'); $search_date_limit_start = dol_mktime(0, 0, 0, $search_date_limit_startmonth, $search_date_limit_startday, $search_date_limit_startyear); $search_date_limit_end = dol_mktime(23, 59, 59, $search_date_limit_endmonth, $search_date_limit_endday, $search_date_limit_endyear); $search_project_ref = GETPOST('search_project_ref', 'alpha'); -$search_users = GETPOST('search_users', 'intcomma'); +$search_users = GETPOST('search_users', 'array:int'); $search_type = GETPOST('search_type', 'alpha'); $search_account = GETPOST('search_account', 'alpha'); From f709a073fc17765a0f0618065cb2e1747d715c9d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Jan 2025 22:42:50 +0100 Subject: [PATCH 065/602] Fix price format with multicurrency --- htdocs/core/class/html.form.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index a3787797c25..05d6f60ba06 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3978,16 +3978,16 @@ class Form $optstart .= ' data-product-id="' . dol_escape_htmltag($objp->rowid) . '"'; $optstart .= ' data-price-id="' . dol_escape_htmltag($objp->idprodfournprice) . '"'; $optstart .= ' data-qty="' . dol_escape_htmltag($objp->quantity) . '"'; - $optstart .= ' data-up="' . dol_escape_htmltag(price2num($objp->unitprice)) . '"'; - $optstart .= ' data-up-locale="' . dol_escape_htmltag(price($objp->unitprice)) . '"'; + $optstart .= ' data-up="' . dol_escape_htmltag(price2num($objp->unitprice)) . '"'; // the price with numeric international format + $optstart .= ' data-up-locale="' . dol_escape_htmltag(price($objp->unitprice)) . '"'; // the price formated in user languge $optstart .= ' data-discount="' . dol_escape_htmltag($outdiscount) . '"'; - $optstart .= ' data-tvatx="' . dol_escape_htmltag(price2num($objp->tva_tx)) . '"'; - $optstart .= ' data-tvatx-formated="' . dol_escape_htmltag(price($objp->tva_tx, 0, $langs, 1, -1, 2)) . '"'; + $optstart .= ' data-tvatx="' . dol_escape_htmltag(price2num($objp->tva_tx)) . '"'; // the rate with numeric international format + $optstart .= ' data-tvatx-formated="' . dol_escape_htmltag(price($objp->tva_tx, 0, $langs, 1, -1, 2)) . '"'; // the rate formated in user language $optstart .= ' data-default-vat-code="' . dol_escape_htmltag($objp->default_vat_code) . '"'; $optstart .= ' data-supplier-ref="' . dol_escape_htmltag($objp->ref_fourn) . '"'; if (isModEnabled('multicurrency')) { $optstart .= ' data-multicurrency-code="' . dol_escape_htmltag($objp->multicurrency_code) . '"'; - $optstart .= ' data-multicurrency-up="' . dol_escape_htmltag($objp->multicurrency_unitprice) . '"'; + $optstart .= ' data-multicurrency-up="' . dol_escape_htmltag(price2num($objp->multicurrency_unitprice)) . '"'; // the price with numeric international format } } $optstart .= ' data-description="' . dol_escape_htmltag($objp->description, 0, 1) . '"'; From da3d1f32f13352ae8f87a9229aa2101c9b35abc8 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 21 Jan 2025 22:55:43 +0100 Subject: [PATCH 066/602] FIX #32656 Loan - Note - Missing formclass project --- htdocs/loan/note.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php index 44f18d6821b..9bc1da5c0a9 100644 --- a/htdocs/loan/note.php +++ b/htdocs/loan/note.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2015-2024 Frédéric France - * Copyright (C) 2016-2024 Alexandre Spangaro + * Copyright (C) 2016-2025 Alexandre Spangaro * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2024 MDW * @@ -33,6 +33,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; if (isModEnabled('project')) { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; } /** @@ -83,7 +84,9 @@ if (empty($reshook)) { $morehtmlright = ''; $form = new Form($db); -$formproject = new FormProjets($db); +if (isModEnabled('project')) { + $formproject = new FormProjets($db); +} $title = $langs->trans("Loan").' - '.$langs->trans("Notes"); $help_url = 'EN:Module_Loan|FR:Module_Emprunt'; From 68e8452bd3d62557672d6855f7eda0f3a403865c Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 21 Jan 2025 23:08:39 +0100 Subject: [PATCH 067/602] Fix language --- htdocs/compta/accounting-files.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 2005e7d0fb2..5ccd1ffa2d8 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -1,12 +1,12 @@ - * Copyright (C) 2004-2019 Laurent Destailleur - * Copyright (C) 2017 Pierre-Henry Favre - * Copyright (C) 2020 Maxime DEMAREST - * Copyright (C) 2021 Gauthier VERDOL - * Copyright (C) 2022-2024 Alexandre Spangaro +/* Copyright (C) 2001-2006 Rodolphe Quiedeville + * Copyright (C) 2004-2019 Laurent Destailleur + * Copyright (C) 2017 Pierre-Henry Favre + * Copyright (C) 2020 Maxime DEMAREST + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2022-2025 Alexandre Spangaro * Copyright (C) 2024 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 Frédéric France * * 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 @@ -622,7 +622,7 @@ $charge_sociales = new ChargeSociales($db); $various_payment = new PaymentVarious($db); $payment_loan = new PaymentLoan($db); -$title = $langs->trans("ComptaFiles").' - '.$langs->trans("List"); +$title = $langs->trans("AccountantFiles").' - '.$langs->trans("List"); $help_url = ''; llxHeader('', $title, $help_url); From 391aca510c48fd59f790b0caa7f2022663950d83 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Jan 2025 23:18:04 +0100 Subject: [PATCH 068/602] FIX autofill price with multicurrency on supplier doc --- 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 a550f366b93..8c465f0e050 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3996,7 +3996,7 @@ class Form $optstart .= ' data-supplier-ref="' . dol_escape_htmltag($objp->ref_fourn) . '"'; if (isModEnabled('multicurrency')) { $optstart .= ' data-multicurrency-code="' . dol_escape_htmltag($objp->multicurrency_code) . '"'; - $optstart .= ' data-multicurrency-up="' . dol_escape_htmltag(price2num($objp->multicurrency_unitprice)) . '"'; // the price with numeric international format + $optstart .= ' data-multicurrency-unitprice="' . dol_escape_htmltag(price2num($objp->multicurrency_unitprice)) . '"'; // the price with numeric international format } } $optstart .= ' data-description="' . dol_escape_htmltag($objp->description, 0, 1) . '"'; From 87dbb1f445b57ff04fab99c9ec4df555f54fa4de Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 22 Jan 2025 02:38:41 +0100 Subject: [PATCH 069/602] Translate "Emailing" line 2345 --- htdocs/core/lib/company.lib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 6f6d25eecb8..ba8b55c69d7 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -2342,6 +2342,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = null, $nopr if (!empty($arraylist[$labelOfTypeToShow])) { $labelOfTypeToShow = $arraylist[$labelOfTypeToShow]; } elseif ($actionstatic->type_code == 'AC_EMAILING') { + $langs->load("mails"); $labelOfTypeToShow = $langs->trans("Emailing"); } if ($actionstatic->type_code == 'AC_OTH_AUTO' && ($actionstatic->type_code != $actionstatic->code) && $labelOfTypeToShow && !empty($arraylist[$actionstatic->code])) { From a8fe17688f41200f24d2bed1d8a9d561386b6e07 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 22 Jan 2025 02:46:47 +0100 Subject: [PATCH 070/602] Fix pre-commit --- htdocs/core/lib/company.lib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index ba8b55c69d7..09ff9d4edd1 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1756,6 +1756,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = null, $nopr global $user, $conf, $hookmanager; global $form; global $param, $massactionbutton; + global $langs; $start_year = GETPOSTINT('dateevent_startyear'); $start_month = GETPOSTINT('dateevent_startmonth'); From 7378dc0f7a7a268beb2e37a404a846456af563dc Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 22 Jan 2025 02:50:58 +0100 Subject: [PATCH 071/602] Fix pre-commit --- dev/translation/ignore_translation_keys.lst | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/translation/ignore_translation_keys.lst b/dev/translation/ignore_translation_keys.lst index 9a34c97bc3f..5679343b154 100644 --- a/dev/translation/ignore_translation_keys.lst +++ b/dev/translation/ignore_translation_keys.lst @@ -53,6 +53,7 @@ MoveField MyContacts NbOfActiveNotifications NbOfTargetedContacts +Payed PreviewMailing Processing PropalStatusClosedShort From 0ed1317607fbdf661551bc3fca130c4de5922ea7 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 22 Jan 2025 05:40:50 +0100 Subject: [PATCH 072/602] FIX avoid warning with the new Dolistore website --- htdocs/admin/modules.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 6f96506cc31..b4bc00f68ca 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -1185,7 +1185,9 @@ if ($mode == 'marketplace') { print '
'; - if (!getDolGlobalString('MAIN_DISABLE_DOLISTORE_SEARCH') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 1) { + $conf->global->MAIN_DISABLE_DOLISTORE_SEARCH = 1; // avoid warning with the new Dolistore website + + if (!getDolGlobalString('MAIN_DISABLE_DOLISTORE_SEARCH') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // $options is array with filter criteria //var_dump($options); $dolistore->getRemoteCategories(); From 99caa9aa37b67098be5be7d262240006942ddf0b Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 22 Jan 2025 05:48:25 +0100 Subject: [PATCH 073/602] FIX Brian is in the kitchen --- 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 8c465f0e050..29824c01b50 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3988,7 +3988,7 @@ class Form $optstart .= ' data-price-id="' . dol_escape_htmltag($objp->idprodfournprice) . '"'; $optstart .= ' data-qty="' . dol_escape_htmltag($objp->quantity) . '"'; $optstart .= ' data-up="' . dol_escape_htmltag(price2num($objp->unitprice)) . '"'; // the price with numeric international format - $optstart .= ' data-up-locale="' . dol_escape_htmltag(price($objp->unitprice)) . '"'; // the price formated in user languge + $optstart .= ' data-up-locale="' . dol_escape_htmltag(price($objp->unitprice)) . '"'; // the price formatted in user language $optstart .= ' data-discount="' . dol_escape_htmltag($outdiscount) . '"'; $optstart .= ' data-tvatx="' . dol_escape_htmltag(price2num($objp->tva_tx)) . '"'; // the rate with numeric international format $optstart .= ' data-tvatx-formated="' . dol_escape_htmltag(price($objp->tva_tx, 0, $langs, 1, -1, 2)) . '"'; // the rate formated in user language From 8c5dce626733611ee954812cbb08a0f15a13eaaf Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 22 Jan 2025 05:57:05 +0100 Subject: [PATCH 074/602] FIX Where is Brian ? --- htdocs/core/class/html.form.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 29824c01b50..0140a6589cc 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3991,7 +3991,7 @@ class Form $optstart .= ' data-up-locale="' . dol_escape_htmltag(price($objp->unitprice)) . '"'; // the price formatted in user language $optstart .= ' data-discount="' . dol_escape_htmltag($outdiscount) . '"'; $optstart .= ' data-tvatx="' . dol_escape_htmltag(price2num($objp->tva_tx)) . '"'; // the rate with numeric international format - $optstart .= ' data-tvatx-formated="' . dol_escape_htmltag(price($objp->tva_tx, 0, $langs, 1, -1, 2)) . '"'; // the rate formated in user language + $optstart .= ' data-tvatx-formated="' . dol_escape_htmltag(price($objp->tva_tx, 0, $langs, 1, -1, 2)) . '"'; // the rate formatted in user language $optstart .= ' data-default-vat-code="' . dol_escape_htmltag($objp->default_vat_code) . '"'; $optstart .= ' data-supplier-ref="' . dol_escape_htmltag($objp->ref_fourn) . '"'; if (isModEnabled('multicurrency')) { @@ -7082,17 +7082,17 @@ class Form if ($d) { // Show date with popup if ($usecalendar != 'combo') { - $formated_date = ''; + $formatted_date = ''; //print "e".$set_time." t ".$conf->format_date_short; if (strval($set_time) != '' && $set_time != -1) { - //$formated_date=dol_print_date($set_time,$conf->format_date_short); - $formated_date = dol_print_date($set_time, $langs->trans("FormatDateShortInput"), $gm); // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript + //$formatted_date=dol_print_date($set_time,$conf->format_date_short); + $formatted_date = dol_print_date($set_time, $langs->trans("FormatDateShortInput"), $gm); // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript } // Calendrier popup version eldy if ($usecalendar == "eldy") { // Input area to enter date manually - $retstring .= 'trans("FormatDateShortJavaInput") . '\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript $retstring .= ' autocomplete="off">'; @@ -7148,7 +7148,7 @@ class Form // Input area to enter date manually $retstring .= '
'; - $retstring .= 'trans("FormatDateShortJavaInput")) . '\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript From 5c6ddba47ae500afec95d9ebabd3fe788ae7eb6c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 22 Jan 2025 06:22:14 +0100 Subject: [PATCH 075/602] FIX #32743 --- htdocs/product/stock/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 346d0f89595..97a42add100 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -199,6 +199,7 @@ $form = new Form($db); $warehouse = new Entrepot($db); $now = dol_now(); +$totalarray = array(); $title = $langs->trans("Warehouses"); $help_url = 'EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; @@ -615,7 +616,6 @@ if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { } print ''."\n"; -$totalarray = array(); $totalarray['nbfield'] = 0; // Fields title label From 2c4bfe38604af5d47dc0f699f2dbb75d658af469 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 22 Jan 2025 05:57:05 +0100 Subject: [PATCH 076/602] FIX Where is Brian ? --- htdocs/core/class/html.form.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 8c465f0e050..e7a9fda4156 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3991,7 +3991,7 @@ class Form $optstart .= ' data-up-locale="' . dol_escape_htmltag(price($objp->unitprice)) . '"'; // the price formated in user languge $optstart .= ' data-discount="' . dol_escape_htmltag($outdiscount) . '"'; $optstart .= ' data-tvatx="' . dol_escape_htmltag(price2num($objp->tva_tx)) . '"'; // the rate with numeric international format - $optstart .= ' data-tvatx-formated="' . dol_escape_htmltag(price($objp->tva_tx, 0, $langs, 1, -1, 2)) . '"'; // the rate formated in user language + $optstart .= ' data-tvatx-formated="' . dol_escape_htmltag(price($objp->tva_tx, 0, $langs, 1, -1, 2)) . '"'; // the rate formatted in user language $optstart .= ' data-default-vat-code="' . dol_escape_htmltag($objp->default_vat_code) . '"'; $optstart .= ' data-supplier-ref="' . dol_escape_htmltag($objp->ref_fourn) . '"'; if (isModEnabled('multicurrency')) { @@ -7082,17 +7082,17 @@ class Form if ($d) { // Show date with popup if ($usecalendar != 'combo') { - $formated_date = ''; + $formatted_date = ''; //print "e".$set_time." t ".$conf->format_date_short; if (strval($set_time) != '' && $set_time != -1) { - //$formated_date=dol_print_date($set_time,$conf->format_date_short); - $formated_date = dol_print_date($set_time, $langs->trans("FormatDateShortInput"), $gm); // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript + //$formatted_date=dol_print_date($set_time,$conf->format_date_short); + $formatted_date = dol_print_date($set_time, $langs->trans("FormatDateShortInput"), $gm); // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript } // Calendrier popup version eldy if ($usecalendar == "eldy") { // Input area to enter date manually - $retstring .= 'trans("FormatDateShortJavaInput") . '\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript $retstring .= ' autocomplete="off">'; @@ -7148,7 +7148,7 @@ class Form // Input area to enter date manually $retstring .= '
'; - $retstring .= 'trans("FormatDateShortJavaInput")) . '\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript From 8ae1208ff659256d59d8d42b9e8ee63172be2513 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 22 Jan 2025 05:48:25 +0100 Subject: [PATCH 077/602] FIX Brian is in the kitchen --- 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 e7a9fda4156..0140a6589cc 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3988,7 +3988,7 @@ class Form $optstart .= ' data-price-id="' . dol_escape_htmltag($objp->idprodfournprice) . '"'; $optstart .= ' data-qty="' . dol_escape_htmltag($objp->quantity) . '"'; $optstart .= ' data-up="' . dol_escape_htmltag(price2num($objp->unitprice)) . '"'; // the price with numeric international format - $optstart .= ' data-up-locale="' . dol_escape_htmltag(price($objp->unitprice)) . '"'; // the price formated in user languge + $optstart .= ' data-up-locale="' . dol_escape_htmltag(price($objp->unitprice)) . '"'; // the price formatted in user language $optstart .= ' data-discount="' . dol_escape_htmltag($outdiscount) . '"'; $optstart .= ' data-tvatx="' . dol_escape_htmltag(price2num($objp->tva_tx)) . '"'; // the rate with numeric international format $optstart .= ' data-tvatx-formated="' . dol_escape_htmltag(price($objp->tva_tx, 0, $langs, 1, -1, 2)) . '"'; // the rate formatted in user language From d7bdb0941744ebce5763271c311014af8e685e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Wed, 22 Jan 2025 11:28:44 +0100 Subject: [PATCH 078/602] FIX: If the constant PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES is active, allow you to choose the price level --- htdocs/product/admin/product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index d38409f9eaa..b31fae0df5f 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -608,7 +608,7 @@ print ''; // multiprix nombre de prix a proposer -if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) { +if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { print ''; print ''.$langs->trans("MultiPricesNumPrices").''; print ''; From 0fd7d517bee448c899036fe3b77f054e3e980693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Wed, 22 Jan 2025 11:40:59 +0100 Subject: [PATCH 079/602] FIX: Allow import and export with the PRODUCT_CUSTOMER_PRICES_AND_MULTIPRICES option --- htdocs/core/modules/modProduct.class.php | 4 ++-- htdocs/core/modules/modService.class.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 7b87d30b1f4..7b5ae32f69a 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -335,7 +335,7 @@ class modProduct extends DolibarrModules $this->export_sql_order[$r] = ' GROUP BY p.rowid'; // FIXME The group by used a generic value to say "all fields in select except function fields" } - if (getDolGlobalString('PRODUIT_MULTIPRICES')) { + if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { // Exports product multiprice $r++; $this->export_code[$r] = $this->rights_class.'_'.$r; @@ -905,7 +905,7 @@ class modProduct extends DolibarrModules $this->import_updatekeys_array[$r] = array('sp.fk_product' => 'ProductOrService', 'sp.ref_fourn' => 'SupplierRef', 'sp.fk_soc' => 'Supplier', 'sp.quantity' => "QtyMin"); } - if (getDolGlobalString('PRODUIT_MULTIPRICES')) { + if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { // Import products multiprices $r++; $this->import_code[$r] = $this->rights_class.'_multiprice'; diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 7501cebf241..ea16a72ff63 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -285,7 +285,7 @@ class modService extends DolibarrModules } if (!isModEnabled("product")) { // We enable next import templates only if module product not already enabled (to avoid duplicate entries) - if (getDolGlobalString('PRODUIT_MULTIPRICES')) { + if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { // Exports product multiprice $r++; $this->export_code[$r] = $this->rights_class.'_'.$r; @@ -801,7 +801,7 @@ class modService extends DolibarrModules $this->import_updatekeys_array[$r] = array('sp.fk_product' => 'ProductOrService', 'sp.ref_fourn' => 'SupplierRef', 'sp.fk_soc' => 'Supplier'); } - if (getDolGlobalString('PRODUIT_MULTIPRICES')) { + if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { // Import products multiprices $r++; $this->import_code[$r] = $this->rights_class.'_multiprice'; From 8069cd304d508a388adf853045f1e231efaa4394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20NASSIET?= <109105553+comaiteseb@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:31:05 +0100 Subject: [PATCH 080/602] Update facture.class.php ajout de class_element_line --- htdocs/compta/facture/class/facture.class.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 0723255b101..3bad1dfee22 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -75,6 +75,11 @@ class Facture extends CommonInvoice */ public $table_element_line = 'facturedet'; + /** + * @var string Name of class line + */ + public $class_element_line = 'FactureLigne'; + /** * @var string Fieldname with ID of parent key if this field has a parent */ From 4f80adc2bf6e8fe5fc79ec493c8b880300a7283b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20NASSIET?= <109105553+comaiteseb@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:56:53 +0100 Subject: [PATCH 081/602] Update facture.class.php --- htdocs/compta/facture/class/facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 3bad1dfee22..0da59edf3d9 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -79,7 +79,7 @@ class Facture extends CommonInvoice * @var string Name of class line */ public $class_element_line = 'FactureLigne'; - + /** * @var string Fieldname with ID of parent key if this field has a parent */ From 0f0ea09f72e95842637cc3300709eac0be7a76d3 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 22 Jan 2025 16:28:05 +0100 Subject: [PATCH 082/602] Debug v21 - fix canonical url management --- htdocs/core/lib/website2.lib.php | 121 ++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 42 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index c2260b72b9e..fa39397bfcd 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -174,6 +174,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $tplcontent = ''; if (!isset($originalcontentonly)) { + // If we want to generate a page with some code to manage PHP content $tplcontent .= "'."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; // Add favicon if (in_array($objectpage->type_container, array('page', 'blogpost'))) { $tplcontent .= ''."\n"; } - // Add canonical reference + // Add the link of the canonical reference + // Note: $object is website, $objectpage is website page if ($object->virtualhost) { - $tplcontent .= ''."\n"; - } - // Add translation reference (main language) - if ($object->isMultiLang()) { - // Add page "translation of" - $translationof = $objectpage->fk_page; - if ($translationof) { - $tmppage = new WebsitePage($db); - $tmppage->fetch($translationof); - if ($tmppage->id > 0) { - $tmpshortlangcode = ''; - if ($tmppage->lang) { - $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en - } - if (empty($tmpshortlangcode)) { - $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en - } - if ($tmpshortlangcode != $shortlangcode) { - $tplcontent .= ''."\n"; - } + $canonicalurladdid = ''; + if ($objectpage->lang) { // A language is forced on the page, it means we may have other langueg files with hard links + $canonicalurl = (($objectpage->id == $object->fk_default_home) ? '/' : (($shortlangcode != substr($object->lang, 0, 2) ? '/'.$shortlangcode : '').'/'.$objectpage->pageurl.'.php')); + } else { // No language forced, it means the canonical is the one with + $canonicalurl = '/'.$objectpage->pageurl.'.php'; + + if ($object->lang && $object->isMultiLang()) { + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en + $canonicalurl .= '?l=shortlang ? $weblangs->shortlang : "'.$tmpshortlangcode.'"; ?>'; + // Add parameter ID required to be unique/canonical + $canonicalurladdid = ''; + } else { + // Add parameter ID required to be unique/canonical + $canonicalurladdid = ''; } } - // Add "has translation pages" - $sql = "SELECT rowid as id, lang, pageurl from ".MAIN_DB_PREFIX.'website_page where fk_page IN ('.$db->sanitize($objectpage->id.($translationof ? ", ".$translationof : '')).")"; - $resql = $db->query($sql); - if ($resql) { - $num_rows = $db->num_rows($resql); - if ($num_rows > 0) { - while ($obj = $db->fetch_object($resql)) { + $tplcontent .= ''."\n"; + } + + // Add the link of alternate translation reference + if ($object->isMultiLang()) { // If website has other languages to support + if ($objectpage->lang) { // If the page has been set to a given language + // Add page "translation of" + $translationof = $objectpage->fk_page; + if ($translationof) { + $tmppage = new WebsitePage($db); + $tmppage->fetch($translationof); + if ($tmppage->id > 0) { $tmpshortlangcode = ''; - if ($obj->lang) { - $tmpshortlangcode = preg_replace('/[_-].*$/', '', $obj->lang); // en_US or en-US -> en + if ($tmppage->lang) { + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en + } + if (empty($tmpshortlangcode)) { + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en } if ($tmpshortlangcode != $shortlangcode) { - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; } } } + + // Add "has translation pages" + $sql = "SELECT rowid as id, lang, pageurl from ".MAIN_DB_PREFIX.'website_page where fk_page IN ('.$db->sanitize($objectpage->id.($translationof ? ", ".$translationof : '')).")"; + $resql = $db->query($sql); + if ($resql) { + $num_rows = $db->num_rows($resql); + if ($num_rows > 0) { + while ($obj = $db->fetch_object($resql)) { + $tmpshortlangcode = ''; + if ($obj->lang) { + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $obj->lang); // en_US or en-US -> en + } + if ($tmpshortlangcode != $shortlangcode) { + $tplcontent .= ''."\n"; + } + } + } + } else { + dol_print_error($db); + } + + // Add myself + $tplcontent .= 'fk_default_home == $objectpage->id) ? '/' : (($shortlangcode != substr($object->lang, 0, 2)) ? '/'.$shortlangcode : '')).'/'.$objectpage->pageurl.'.php") { ?>'."\n"; + $tplcontent .= ''."\n"; + + $tplcontent .= ''."\n"; } else { - dol_print_error($db); } - - // Add myself - $tplcontent .= 'fk_default_home == $objectpage->id) ? '/' : (($shortlangcode != substr($object->lang, 0, 2)) ? '/'.$shortlangcode : '')).'/'.$objectpage->pageurl.'.php") { ?>'."\n"; - $tplcontent .= ''."\n"; - - $tplcontent .= ''."\n"; } // Add manifest.json. Do we have to add it only on home page ? $tplcontent .= 'use_manifest) { print \'\'."\n"; } ?>'."\n"; @@ -278,7 +301,9 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $tplcontent .= ''."\n"; $tplcontent .= 'content, '$__PAGE__TITLE__') !== false) { $tplcontent .= '$tmp = preg_replace("/.*?<\/title>/s", "<title>" . dol_escape_htmltag($__PAGE__TITLE__) . "", $tmp);'."\n"; $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; @@ -289,7 +314,19 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, if (strpos($objectpage->content, '$__PAGE__DESC__') !== false) { $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; } - $tplcontent .= 'dolWebsiteOutput($tmp, "html", '.$objectpage->id.'); dolWebsiteIncrementCounter('.$object->id.', "'.$objectpage->type_container.'", '.$objectpage->id.');'."\n"; + // New method for custom SEO + if (strpos($objectpage->content, 'define("__SEO_PAGE_TITLE__")') !== false) { + $tplcontent .= '$tmp = preg_replace("/.*?<\/title>/s", "<title>" . dol_escape_htmltag(constant("__SEO_PAGE_TITLE__")) . "", $tmp);'."\n"; + $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; + } + if (strpos($objectpage->content, 'define("__SEO_PAGE_KEYWORDS__")') !== false) { + $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; + } + if (strpos($objectpage->content, 'define("__SEO_PAGE_DESC__")') !== false) { + $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; + } + + $tplcontent .= 'dolWebsiteOutput($tmp, "html", '.((int) $objectpage->id).'); dolWebsiteIncrementCounter('.((int) $object->id).', "'.$objectpage->type_container.'", '.((int) $objectpage->id).');'."\n"; $tplcontent .= "// END PHP ?>\n"; } else { $tplcontent .= " Date: Wed, 22 Jan 2025 16:31:41 +0100 Subject: [PATCH 083/602] Clean meta tags --- htdocs/core/lib/website2.lib.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index fa39397bfcd..f539d9f68c4 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -191,14 +191,14 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, // If a language was forced on page, we use it, else we use the lang of visitor else the lang of web site $tplcontent .= 'lang ? ' lang="'.substr($objectpage->lang, 0, 2).'"' : 'shortlang ? \' lang="\'.$weblangs->shortlang.\'"\' : \'\' ?>').'>'."\n"; $tplcontent .= ''."\n"; - $tplcontent .= ''.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').''."\n"; + $tplcontent .= ''.dol_string_nohtmltag($objectpage->title, 1, 'UTF-8').''."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; - $tplcontent .= ''."\n"; - $tplcontent .= ''."\n"; - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; From f381a7322cd593a448971ac4c9cebc3e44405356 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 22 Jan 2025 18:48:03 +0100 Subject: [PATCH 084/602] Fix use of constants --- htdocs/core/lib/website2.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index f539d9f68c4..8aab8ba4962 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -315,14 +315,14 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; } // New method for custom SEO - if (strpos($objectpage->content, 'define("__SEO_PAGE_TITLE__")') !== false) { + if (strpos($objectpage->content, 'define("__SEO_PAGE_TITLE__"') !== false) { $tplcontent .= '$tmp = preg_replace("/.*?<\/title>/s", "<title>" . dol_escape_htmltag(constant("__SEO_PAGE_TITLE__")) . "", $tmp);'."\n"; $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; } - if (strpos($objectpage->content, 'define("__SEO_PAGE_KEYWORDS__")') !== false) { + if (strpos($objectpage->content, 'define("__SEO_PAGE_KEYWORDS__"') !== false) { $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; } - if (strpos($objectpage->content, 'define("__SEO_PAGE_DESC__")') !== false) { + if (strpos($objectpage->content, 'define("__SEO_PAGE_DESC__"') !== false) { $tplcontent .= '$tmp = preg_replace("//s", "", $tmp);'; } From 8d0a4ac6d91b0f719135d86c46311094b4987ba9 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 22 Jan 2025 20:18:53 +0100 Subject: [PATCH 085/602] fix: allow list mass action update price when price mode is multiprice price --- htdocs/core/actions_massactions.inc.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index e84c02a8c93..fb45b57ac7a 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1283,7 +1283,6 @@ if (!$error && ($action == 'updateprice' && $confirm == 'yes') && $permissiontoa if ($result > 0) { if (getDolGlobalString('PRODUIT_MULTIPRICES')) { for ($level = 1; $level <= getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); $level++) { - // Force the update of the price of the product using the new VAT if ($object->price_base_type == 'TTC') { $newprice = $object->multiprices_ttc[$level] * (100 + $pricepercentage) / 100; $minprice = $object->multiprices_min_ttc[$level]; From 4673f319621bb8693a0896b736a3a4486c768817 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 22 Jan 2025 21:13:26 +0100 Subject: [PATCH 086/602] Debug v21 - fix alternate lang --- htdocs/core/lib/website2.lib.php | 107 +++++++++++++++++-------------- 1 file changed, 59 insertions(+), 48 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 8aab8ba4962..6e156b5070a 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -207,79 +207,90 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $tplcontent .= ''."\n"; } + $listofaltlang = $object->otherlang; + // Add the link of the canonical reference // Note: $object is website, $objectpage is website page if ($object->virtualhost) { - $canonicalurladdid = ''; - if ($objectpage->lang) { // A language is forced on the page, it means we may have other langueg files with hard links + $canonicalurladdidlang = ''; + if ($objectpage->lang) { // A language is forced on the page, it means we may have other language files with hard links into properties of page $canonicalurl = (($objectpage->id == $object->fk_default_home) ? '/' : (($shortlangcode != substr($object->lang, 0, 2) ? '/'.$shortlangcode : '').'/'.$objectpage->pageurl.'.php')); } else { // No language forced, it means the canonical is the one with $canonicalurl = '/'.$objectpage->pageurl.'.php'; - if ($object->lang && $object->isMultiLang()) { + if ($object->lang && $listofaltlang) { $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en - $canonicalurl .= '?l=shortlang ? $weblangs->shortlang : "'.$tmpshortlangcode.'"; ?>'; // Add parameter ID required to be unique/canonical - $canonicalurladdid = ''; + $canonicalurladdidlang = ''; + $canonicalurladdidlang .= 'l=shortlang ? $weblangs->shortlang : "'.$tmpshortlangcode.'"; ?>'; } else { // Add parameter ID required to be unique/canonical - $canonicalurladdid = ''; + $canonicalurladdidlang = ''; } } - $tplcontent .= ''."\n"; - } + $tplcontent .= ''."\n"; - // Add the link of alternate translation reference - if ($object->isMultiLang()) { // If website has other languages to support - if ($objectpage->lang) { // If the page has been set to a given language - // Add page "translation of" - $translationof = $objectpage->fk_page; - if ($translationof) { - $tmppage = new WebsitePage($db); - $tmppage->fetch($translationof); - if ($tmppage->id > 0) { - $tmpshortlangcode = ''; - if ($tmppage->lang) { - $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en - } - if (empty($tmpshortlangcode)) { - $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en - } - if ($tmpshortlangcode != $shortlangcode) { - $tplcontent .= ''."\n"; - } - } - } - - // Add "has translation pages" - $sql = "SELECT rowid as id, lang, pageurl from ".MAIN_DB_PREFIX.'website_page where fk_page IN ('.$db->sanitize($objectpage->id.($translationof ? ", ".$translationof : '')).")"; - $resql = $db->query($sql); - if ($resql) { - $num_rows = $db->num_rows($resql); - if ($num_rows > 0) { - while ($obj = $db->fetch_object($resql)) { + // Add the link of alternate translation reference + if ($listofaltlang) { // If website has other languages to support + if ($objectpage->lang) { // A language is forced on the page, it means we may have other language files with hard links into properties of page + // Add page "translation of" + $translationof = $objectpage->fk_page; + if ($translationof) { + $tmppage = new WebsitePage($db); + $tmppage->fetch($translationof); + if ($tmppage->id > 0) { $tmpshortlangcode = ''; - if ($obj->lang) { - $tmpshortlangcode = preg_replace('/[_-].*$/', '', $obj->lang); // en_US or en-US -> en + if ($tmppage->lang) { + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en + } + if (empty($tmpshortlangcode)) { + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en } if ($tmpshortlangcode != $shortlangcode) { - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; } } } + + // Add "has translation pages" + $sql = "SELECT rowid as id, lang, pageurl from ".MAIN_DB_PREFIX.'website_page where fk_page IN ('.$db->sanitize($objectpage->id.($translationof ? ", ".$translationof : '')).")"; + $resql = $db->query($sql); + if ($resql) { + $num_rows = $db->num_rows($resql); + if ($num_rows > 0) { + while ($obj = $db->fetch_object($resql)) { + $tmpshortlangcode = ''; + if ($obj->lang) { + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $obj->lang); // en_US or en-US -> en + } + if ($tmpshortlangcode != $shortlangcode) { + $tplcontent .= ''."\n"; + } + } + } + } else { + dol_print_error($db); + } + + // Add myself + $tplcontent .= 'fk_default_home == $objectpage->id) ? '/' : (($shortlangcode != substr($object->lang, 0, 2)) ? '/'.$shortlangcode : '')).'/'.$objectpage->pageurl.'.php") { ?>'."\n"; + $tplcontent .= ''."\n"; + + $tplcontent .= ''."\n"; } else { - dol_print_error($db); + $canonicalurl = '/'.$objectpage->pageurl.'.php'; + $arrayofaltlang = explode(',', $listofaltlang); + foreach ($arrayofaltlang as $altlang) { + // Add parameter ID required to be unique/canonical + $canonicalurladdidlang = ''; + $canonicalurladdidlang .= 'l='.$altlang; + $tplcontent .= ''."\n"; + } } - - // Add myself - $tplcontent .= 'fk_default_home == $objectpage->id) ? '/' : (($shortlangcode != substr($object->lang, 0, 2)) ? '/'.$shortlangcode : '')).'/'.$objectpage->pageurl.'.php") { ?>'."\n"; - $tplcontent .= ''."\n"; - - $tplcontent .= ''."\n"; - } else { } } + // Add manifest.json. Do we have to add it only on home page ? $tplcontent .= 'use_manifest) { print \'\'."\n"; } ?>'."\n"; $tplcontent .= ''."\n"; From 6dc14c6560d0124e3dbc641cacf938f55ed0bb62 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 22 Jan 2025 21:21:29 +0100 Subject: [PATCH 087/602] Debug v21 - fix alternate lang --- htdocs/core/lib/website2.lib.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 6e156b5070a..07caa48f9a0 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -281,11 +281,16 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, } else { $canonicalurl = '/'.$objectpage->pageurl.'.php'; $arrayofaltlang = explode(',', $listofaltlang); + + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en + foreach ($arrayofaltlang as $altlang) { - // Add parameter ID required to be unique/canonical - $canonicalurladdidlang = ''; - $canonicalurladdidlang .= 'l='.$altlang; - $tplcontent .= ''."\n"; + if ($altlang != $tmpshortlangcode) { + // Add parameter ID required to be unique/canonical + $canonicalurladdidlang = ''; + $canonicalurladdidlang .= 'l='.$altlang; + $tplcontent .= ''."\n"; + } } } } From bae28f5b7e10ba07a186cddc509418ceae62288a Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 22 Jan 2025 21:21:29 +0100 Subject: [PATCH 088/602] Debug v21 - fix alternate lang --- htdocs/core/lib/website2.lib.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 6e156b5070a..31d90141eaa 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -281,12 +281,16 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, } else { $canonicalurl = '/'.$objectpage->pageurl.'.php'; $arrayofaltlang = explode(',', $listofaltlang); + foreach ($arrayofaltlang as $altlang) { // Add parameter ID required to be unique/canonical $canonicalurladdidlang = ''; $canonicalurladdidlang .= 'l='.$altlang; $tplcontent .= ''."\n"; } + + $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en + $tplcontent .= ''."\n"; } } } From e874b980d8a08231564cee8809706b6c6de38b38 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 22 Jan 2025 21:31:06 +0100 Subject: [PATCH 089/602] Debug v21 - Fix canonical --- htdocs/core/lib/website2.lib.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 31d90141eaa..d675473a98a 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -290,6 +290,8 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, } $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en + $canonicalurladdidlang = ''; + $canonicalurladdidlang .= 'l='.$tmpshortlangcode; $tplcontent .= ''."\n"; } } From 46ec36846202a8a0ee09973a53b03defc5cc674a Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 22 Jan 2025 21:50:38 +0100 Subject: [PATCH 090/602] Fix canonical name --- htdocs/core/lib/website2.lib.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index d675473a98a..fb161162679 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -221,11 +221,11 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, if ($object->lang && $listofaltlang) { $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en // Add parameter ID required to be unique/canonical - $canonicalurladdidlang = ''; + $canonicalurladdidlang = ''; $canonicalurladdidlang .= 'l=shortlang ? $weblangs->shortlang : "'.$tmpshortlangcode.'"; ?>'; } else { // Add parameter ID required to be unique/canonical - $canonicalurladdidlang = ''; + $canonicalurladdidlang = ''; } } @@ -284,13 +284,13 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, foreach ($arrayofaltlang as $altlang) { // Add parameter ID required to be unique/canonical - $canonicalurladdidlang = ''; + $canonicalurladdidlang = ''; $canonicalurladdidlang .= 'l='.$altlang; $tplcontent .= ''."\n"; } $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en - $canonicalurladdidlang = ''; + $canonicalurladdidlang = ''; $canonicalurladdidlang .= 'l='.$tmpshortlangcode; $tplcontent .= ''."\n"; } From cbe15c7c71059ad25315533d60d52dc973e93bba Mon Sep 17 00:00:00 2001 From: Eric Seigne Date: Wed, 22 Jan 2025 23:53:16 +0100 Subject: [PATCH 091/602] missing hookmanager like others doc_generic*odt modules --- .../project/task/doc/doc_generic_task_odt.modules.php | 8 ++++++++ .../core/modules/societe/doc/doc_generic_odt.modules.php | 1 + .../mymodule/doc/doc_generic_myobject_odt.modules.php | 5 +++++ .../doc_generic_recruitmentjobposition_odt.modules.php | 5 +++++ 4 files changed, 19 insertions(+) diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index 51e53e21d3f..f2cb1eddb78 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -469,6 +469,14 @@ class doc_generic_task_odt extends ModelePDFTask return -1; } + // Add odtgeneration hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + if (!is_object($outputlangs)) { $outputlangs = $langs; } diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index 374c44c7a25..49ce657fce7 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -216,6 +216,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc $hookmanager = new HookManager($this->db); } $hookmanager->initHooks(array('odtgeneration')); + global $action; if (!is_object($outputlangs)) { $outputlangs = $langs; diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php index e35fb604cec..680cf49de6b 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php @@ -233,7 +233,12 @@ class doc_generic_myobject_odt extends ModelePDFMyObject } // Add odtgeneration hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } $hookmanager->initHooks(array('odtgeneration')); + global $action; if (!is_object($outputlangs)) { $outputlangs = $langs; diff --git a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php index da7640d708a..128293c9d85 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php @@ -221,7 +221,12 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi } // Add odtgeneration hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } $hookmanager->initHooks(array('odtgeneration')); + global $action; if (!is_object($outputlangs)) { $outputlangs = $langs; From 821565e03142744fe1f9978c21bf1801c16d4c38 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Jan 2025 01:29:29 +0100 Subject: [PATCH 092/602] Debug v21 --- htdocs/comm/mailing/card.php | 31 +++++++++++++---------- htdocs/core/ajax/mailtemplate.php | 11 ++++---- htdocs/core/class/html.formmail.class.php | 6 ++--- htdocs/core/lib/functions.lib.php | 17 ------------- 4 files changed, 26 insertions(+), 39 deletions(-) diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index b36538b2a68..0920ddae516 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -799,7 +799,7 @@ if ($action == 'create') { // aaa // Print mail form print load_fiche_titre($langs->trans("NewMailing"), $availablelink, 'object_email'); - print dol_get_fiche_head(array(), '', '', -4, '', 0, '', ''); + print dol_get_fiche_head(array(), '', '', 0, '', 0, '', ''); print ''; @@ -831,17 +831,21 @@ if ($action == 'create') { // aaa } print '
'; - print '

'; + print '
'; print ''; - print ''; + print ''; + print ''; - print ''; + print ''; + print ''; - print ''; + print ''; + print ''; - print ''; + print ''; + print ''; // Other attributes $parameters = array(); @@ -852,7 +856,8 @@ if ($action == 'create') { // aaa } print '
'.$langs->trans("MailFrom").'
'.$langs->trans("MailFrom").''.img_picto('', 'email', 'class="pictofixedwidth"').'
'.$langs->trans("MailErrorsTo").'
'.$langs->trans("MailErrorsTo").''.img_picto('', 'email', 'class="pictofixedwidth"').'
'.$langs->trans("MailReply").'
'.$langs->trans("MailReply").''.img_picto('', 'email', 'class="pictofixedwidth"').'
'; - print '

'; + + print '
'; print ''; print ''; @@ -889,7 +894,7 @@ if ($action == 'create') { // aaa print '
'; // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtmlallowunvalid'), '', 600, 'dolibarr_mailings', '', true, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%'); + $doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtmlallowunvalid'), '', 600, 'dolibarr_mailings', '', true, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '100%'); $doleditor->Create(); print '
'; @@ -1129,7 +1134,7 @@ if ($action == 'create') { // aaa } print $text; if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') { - if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'mail') { + if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') && getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'mail') { print ' ('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER_EMAILING', getDolGlobalString('MAIN_MAIL_SMTP_SERVER')).')'; } } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE') != 'mail' && getDolGlobalString('MAIN_MAIL_SMTP_SERVER')) { @@ -1329,7 +1334,7 @@ if ($action == 'create') { // aaa $readonly = 1; // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', false, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%', $readonly); + $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', false, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '100%', $readonly); $doleditor->Create(); } else { print dol_htmlentitiesbr($object->body); @@ -1548,19 +1553,19 @@ if ($action == 'create') { // aaa if ($action == 'edit') { // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%'); + $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '100%'); $doleditor->Create(); } if ($action == 'edittxt') { // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, 0, 20, '90%'); + $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, 0, 20, '100%'); $doleditor->Create(); } if ($action == 'edithtml') { // HTML source editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, 'ace', 20, '90%'); + $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, 'ace', 20, '100%'); $doleditor->Create(0, '', false, 'HTML Source', 'php'); } diff --git a/htdocs/core/ajax/mailtemplate.php b/htdocs/core/ajax/mailtemplate.php index 41054250305..fd6981b8c7f 100644 --- a/htdocs/core/ajax/mailtemplate.php +++ b/htdocs/core/ajax/mailtemplate.php @@ -73,16 +73,17 @@ if (GETPOSTISSET('content')) { foreach ($selectedPosts as $postId) { $post = getNewsDetailsById($postId); + $newsList .= '
-

' . htmlentities($post['title']) . '

-

' . htmlentities($post['description']) . '

- Created By: ' . htmlentities($post['user_fullname']) . ' +

' . htmlentities(empty($post['title']) ? '' : $post['title']) . '

+

' . htmlentities(empty($post['description']) ? '' : $post['description']) . '

+ Created By: ' . htmlentities(empty($post['user_fullname']) ? '' : $post['user_fullname']) . '
- ' . dol_print_date($post['date_creation'], 'daytext', 'tzserver', $langs) . ' + ' . dol_print_date((empty($post['date_creation']) ? dol_now() : $post['date_creation']), 'daytext', 'tzserver', $langs) . '
- ' . ($post['image'] ? 'Image' : 'Gray rectangle') . ' + ' . (!empty($post['image']) ? 'Image' : 'Gray rectangle') . '
'; } diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 3f09d2816f7..21f064ba8ca 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -1693,7 +1693,7 @@ class FormMail extends Form // Use the multiselect array function to create the dropdown $out .= ''; $out .= '"; } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index aa46e7ccf0b..1c0d5a61aea 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -169,6 +169,7 @@ $ErrorCode = $ErrorShortMsg = $ErrorLongMsg = $ErrorSeverityCode = ''; $object = new stdClass(); // For triggers +/** @var CommonObject $object */ $error = 0; From d81a25ea11db395e4e95fbc9aa9386897cd14d18 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 19:39:19 +0100 Subject: [PATCH 119/602] Fix url payment ko --- htdocs/public/payment/paymentko.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index 17e42d8f16b..9a23d6201dd 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -343,7 +343,7 @@ if (!empty($doactionsthenredirect)) { // Redirect to an error page // Paymentko page must be created for the specific website if (!defined('USEDOLIBARRSERVER') && !empty($ws_virtuelhost)) { - $ext_urlok = $ws_virtuelhost . '/paymentok.php?fulltag='.$FULLTAG; + $ext_urlok = $ws_virtuelhost . '/paymentko.php?fulltag='.$FULLTAG; } else { $ext_urlko = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG; } From 6198d185442165ce26015b783b45839ae6582f89 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 19:42:50 +0100 Subject: [PATCH 120/602] Fix url payment ko --- htdocs/public/payment/paymentko.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index 9a23d6201dd..5f833ed119d 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -343,7 +343,7 @@ if (!empty($doactionsthenredirect)) { // Redirect to an error page // Paymentko page must be created for the specific website if (!defined('USEDOLIBARRSERVER') && !empty($ws_virtuelhost)) { - $ext_urlok = $ws_virtuelhost . '/paymentko.php?fulltag='.$FULLTAG; + $ext_urlko = $ws_virtuelhost . '/paymentko.php?fulltag='.$FULLTAG; } else { $ext_urlko = DOL_URL_ROOT.'/public/website/index.php?website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG; } From 132b4f95fe405b6e03a5ae205e766952fc0ab8dc Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 20:21:23 +0100 Subject: [PATCH 121/602] Fix move of files after a merge of products --- htdocs/product/card.php | 23 ++++++++++++++++++++--- htdocs/societe/class/societe.class.php | 20 ++++++++++---------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index c84c0dc6d63..4ce8eb72df0 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -361,7 +361,7 @@ if (empty($reshook)) { 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', ); - //First, all core objects must update their tables + // First, all core objects must update their tables foreach ($objects as $object_name => $object_file) { require_once DOL_DOCUMENT_ROOT.$object_file; @@ -406,13 +406,30 @@ if (empty($reshook)) { } if (!$error) { - // We finally remove the old product - // TODO merge attached files from old product into new one before delete + // Delete the product if ($productOrigin->delete($user) < 1) { $error++; } } + if ($error) { + // Move files from the dir of the third party to delete into the dir of the third party to keep + if (!empty($conf->product->multidir_output[$productOrigin->entity])) { + $srcdir = $conf->product->multidir_output[$productOrigin->entity]."/".$productOrigin->ref; + $destdir = $conf->product->multidir_output[$object->entity]."/".$object->ref; + + if (dol_is_dir($srcdir)) { + $dirlist = dol_dir_list($srcdir, 'files', 1); + foreach ($dirlist as $filetomove) { + $destfile = $destdir.'/'.$filetomove['relativename']; + //var_dump('Move file '.$filetomove['relativename'].' into '.$destfile); + dol_move($filetomove['fullname'], $destfile, '0', 0, 0, 1); + } + //exit; + } + } + } + if (!$error) { setEventMessages($langs->trans('ProductsMergeSuccess'), null, 'mesgs'); $db->commit(); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 13dd05eff14..8d664fda47f 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -5711,6 +5711,16 @@ class Societe extends CommonObject // End call triggers } + if (!$error) { + // We finally remove the old thirdparty + if ($soc_origin->delete($soc_origin->id, $user) < 1) { + $this->error = $soc_origin->error; + $this->errors = $soc_origin->errors; + $error++; + } + } + + if (!$error) { // Move files from the dir of the third party to delete into the dir of the third party to keep if (!empty($conf->societe->multidir_output[$this->entity])) { @@ -5729,16 +5739,6 @@ class Societe extends CommonObject } } - - if (!$error) { - // We finally remove the old thirdparty - if ($soc_origin->delete($soc_origin->id, $user) < 1) { - $this->error = $soc_origin->error; - $this->errors = $soc_origin->errors; - $error++; - } - } - if (!$error) { $this->db->commit(); return 0; From 9c7686e5718c855ed82a87fed68a74998b981b0f Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 21:02:49 +0100 Subject: [PATCH 122/602] Fix clean unvalid entries into ecm file table --- htdocs/install/repair.php | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index d3d8364b810..06d14be0720 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -111,6 +111,7 @@ print 'Option clean_menus is '.(GETPOST('clean_menus', 'alpha') ? GETPOST('clean print 'Option clean_orphelin_dir is '.(GETPOST('clean_orphelin_dir', 'alpha') ? GETPOST('clean_orphelin_dir', 'alpha') : 'undefined').'
'."\n"; print 'Option clean_product_stock_batch is '.(GETPOST('clean_product_stock_batch', 'alpha') ? GETPOST('clean_product_stock_batch', 'alpha') : 'undefined').'
'."\n"; print 'Option clean_perm_table is '.(GETPOST('clean_perm_table', 'alpha') ? GETPOST('clean_perm_table', 'alpha') : 'undefined').'
'."\n"; +print 'Option clean_ecm_files_table is '.(GETPOST('clean_ecm_files_table', 'alpha') ? GETPOST('clean_ecm_files_table', 'alpha') : 'undefined').'
'."\n"; print 'Option repair_link_dispatch_lines_supplier_order_lines, is '.(GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha') ? GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha') : 'undefined').'
'."\n"; // Init data print 'Option set_empty_time_spent_amount is '.(GETPOST('set_empty_time_spent_amount', 'alpha') ? GETPOST('set_empty_time_spent_amount', 'alpha') : 'undefined').'
'."\n"; @@ -205,7 +206,7 @@ $conf->global->MAIN_ENABLE_LOG_TO_HTML = 1; $oneoptionset = 0; $oneoptionset = (GETPOST('standard', 'alpha') || GETPOST('restore_thirdparties_logos', 'alpha') || GETPOST('clean_linked_elements', 'alpha') || GETPOST('clean_menus', 'alpha') || GETPOST('clean_orphelin_dir', 'alpha') || GETPOST('clean_product_stock_batch', 'alpha') || GETPOST('set_empty_time_spent_amount', 'alpha') || GETPOST('rebuild_product_thumbs', 'alpha') - || GETPOST('clean_perm_table', 'alpha') + || GETPOST('clean_perm_table', 'alpha') || GETPOST('clean_ecm_files_table', 'alpha') || GETPOST('force_disable_of_modules_not_found', 'alpha') || GETPOST('force_utf8_on_tables', 'alpha') || GETPOST('force_utf8mb4_on_tables', 'alpha') || GETPOST('force_collation_from_conf_on_tables', 'alpha') || GETPOST('rebuild_sequences', 'alpha') || GETPOST('recalculateinvoicetotal', 'alpha')); @@ -1294,6 +1295,55 @@ if ($ok && GETPOST('clean_perm_table', 'alpha')) { } +// clean_old_module_entries: Clean data into const when files of module were removed without being +if ($ok && GETPOST('clean_ecm_files_table', 'alpha')) { + print '
'; + + $MAXTODELETE = 100; + + $sql = "SELECT rowid, filename, filepath, entity from ".MAIN_DB_PREFIX."ecm_files"; + $sql .= " WHERE entity = 1"; + $sql .= " ORDER BY rowid ASC"; + + $nbfile = 0; + $nbfiletodelete = 0; + + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + if ($num) { + $i = 0; + while ($i < $num && $nbfiletodelete < $MAXTODELETE) { + $obj = $db->fetch_object($resql); + if ($obj->rowid > 0) { + $filetocheck = DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename; + $nbfile++; + if (!dol_is_file($filetocheck)) { + $nbfiletodelete++; + print ''; + } + } + $i++; + } + } + if ($nbfiletodelete > $MAXTODELETE) { + print ''; + } else { + print ''; + } + } else { + dol_print_error($db); + } +} // force utf8 on tables if ($ok && GETPOST('force_utf8_on_tables', 'alpha')) { From 78e0eeb557673e503f05b91a11269344c4e8134d Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 21:06:21 +0100 Subject: [PATCH 123/602] Fix repair script --- htdocs/install/repair.php | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 06d14be0720..4a0a1b8501b 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -1313,23 +1313,27 @@ if ($ok && GETPOST('clean_ecm_files_table', 'alpha')) { $num = $db->num_rows($resql); if ($num) { $i = 0; - while ($i < $num && $nbfiletodelete < $MAXTODELETE) { + while ($i < $num) { $obj = $db->fetch_object($resql); if ($obj->rowid > 0) { $filetocheck = DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename; $nbfile++; if (!dol_is_file($filetocheck)) { $nbfiletodelete++; - print ''; + } else { + break; } - print ''; } } $i++; From 8967d995a864a2a6f912fbd0173d1daa5f2ac5c0 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 21:08:45 +0100 Subject: [PATCH 124/602] Fix repair script --- htdocs/install/repair.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 4a0a1b8501b..20498bc6c9e 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -1318,7 +1318,7 @@ if ($ok && GETPOST('clean_ecm_files_table', 'alpha')) { if ($obj->rowid > 0) { $filetocheck = DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename; $nbfile++; - if (!dol_is_file($filetocheck)) { + if (!dol_is_file($filetocheck) && !dol_is_file($filetocheck.'.noexe')) { $nbfiletodelete++; if ($nbfiletodelete <= $MAXTODELETE) { print '"; //echo $conf->global->MAIN_START_WEEK.' '.$firstdate["wday"].' '.$startday; $cols = 0; @@ -291,7 +292,7 @@ function displayBox($selectedDate, $month, $year) $stoploop = 1; } else { $mydate = dol_getdate($thedate); - if ($firstdate["month"] != $mydate["month"]) { + if ($firstdate["mon"] != $mydate["mon"]) { $stoploop = 1; } } From ba32606084b605ea93c3c119694a3bb60b746337 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 16:19:57 +0100 Subject: [PATCH 141/602] Fix return value for getListOfCollation() --- htdocs/core/db/sqlite3.class.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index 3e5fe6cb908..23fa3483e76 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2015 Raphaël Doursenaud - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -1278,7 +1278,7 @@ class DoliDBSqlite3 extends DoliDB } /** - * Return list of available collation that can be used for database + * Return list of available collations that can be used for database * * @return ?array List of Collation */ @@ -1286,8 +1286,7 @@ class DoliDBSqlite3 extends DoliDB { $liste = array(); $i = 0; - $liste[$i]['charset'] = 'UTF-8'; - $liste[$i]['description'] = 'UTF-8'; + $liste[$i]['collation'] = 'UTF-8'; return $liste; } From f322aad97b227f2c12f84037527ba6c41a89383b Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 16:27:32 +0100 Subject: [PATCH 142/602] Qual: Ensure type is string. --- htdocs/core/extrafieldsinimport.inc.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/extrafieldsinimport.inc.php b/htdocs/core/extrafieldsinimport.inc.php index 570df5f8e0f..740043d47c0 100644 --- a/htdocs/core/extrafieldsinimport.inc.php +++ b/htdocs/core/extrafieldsinimport.inc.php @@ -1,4 +1,6 @@ + */ '@phan-var-force DolibarrModules $this'; // $keyforselect = name of main table @@ -51,7 +53,7 @@ if ($resql) { // This can fail when class is used on old database (during mig $tmpparam = jsonOrUnserialize($obj->param); // $tmp may be array 'options' => array 'c_currencies:code_iso:code_iso' => null if (is_array($tmpparam) && array_key_exists('options', $tmpparam) && $tmpparam['options'] && is_array($tmpparam['options'])) { $tmpkeys = array_keys($tmpparam['options']); - $tmp = array_shift($tmpkeys); + $tmp = (string) array_shift($tmpkeys); } if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) { $typeFilter = "List:".$tmp; From a35d502409948665edf98bd8c8a0da688a60a367 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 16:35:34 +0100 Subject: [PATCH 143/602] Fix: Correct key for position of extrafield --- htdocs/core/lib/company.lib.php | 4 ++-- htdocs/core/lib/customreports.lib.php | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index fc8177a2993..4be8ad3bf8d 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -11,7 +11,7 @@ * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2017 Rui Strecht * Copyright (C) 2018-2024 Ferran Marcet - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -1909,7 +1909,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = null, $nopr } elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') { $sql .= ", ".MAIN_DB_PREFIX."contrat as o"; } elseif (is_object($filterobj) && is_array($filterobj->fields) && is_array($filterobj->fields['rowid']) - && ((!empty($filterobj->fields['ref']) && is_array($filterobj->fields['ref'])) || (!empty($filterobj->fields['label']) && is_array($filterobj->fields['label'])) || (!empty($filterobj->fields['titre']) && is_array($filterobj->fields['titre']))) // @phan-suppress-curren-line PhanTypeInvalidDimOffset + && ((!empty($filterobj->fields['ref']) && is_array($filterobj->fields['ref'])) || (!empty($filterobj->fields['label']) && is_array($filterobj->fields['label'])) || (!empty($filterobj->fields['titre']) && is_array($filterobj->fields['titre']))) // @phan-suppress-current-line PhanTypeInvalidDimOffset && $filterobj->table_element && $filterobj->element) { $sql .= ", ".MAIN_DB_PREFIX.$filterobj->table_element." as o"; } diff --git a/htdocs/core/lib/customreports.lib.php b/htdocs/core/lib/customreports.lib.php index 574faafeabb..621b0dfd093 100644 --- a/htdocs/core/lib/customreports.lib.php +++ b/htdocs/core/lib/customreports.lib.php @@ -1,8 +1,8 @@ * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW -* + * Copyright (C) 2024-2025 MDW + * * 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 @@ -110,8 +110,11 @@ function fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesu if (!empty($object->isextrafieldmanaged) && isset($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || (int) dol_eval((string) $extrafields->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'))) { - // @phan-suppress-next-line PhanTypeMismatchDimAssignment - $position = (!empty($val['position']) ? $val['position'] : 0); + if (isset($extrafields->attributes[$object->table_element]['pos'][$key])) { + $position = $extrafields->attributes[$object->table_element]['pos'][$key]; + } else { + $position = 0; + } $arrayofmesures[preg_replace('/^t/', 'te', $tablealias).'.'.$key.'-sum'] = array( 'label' => img_picto('', (empty($object->picto) ? 'generic' : $object->picto), 'class="pictofixedwidth"').$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Sum").')', 'labelnohtml' => $labelofobject.': '.$langs->trans($val), From f64c0818f9cce3084820dd32fe013d345d92eb0e Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 16:53:07 +0100 Subject: [PATCH 144/602] Qual: Fix nullable and typing (phan notices) --- htdocs/core/lib/images.lib.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index 0f0ff2cf7be..bb874b7b6ec 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -1,7 +1,7 @@ * Copyright (C) 2005-2007 Regis Houssin - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -315,6 +315,10 @@ function dol_imageResizeOrCrop($file, $mode, $newWidth, $newHeight, $src_x = 0, break; } + if ($img === null) { + return "Error: Could not create Image from '$filetoread'"; + } + // Create empty image for target if ($newExt == 'gif') { // Compatibility image GIF @@ -615,6 +619,7 @@ function vignette($file, $maxWidth = 160, $maxHeight = 120, $extName = '_small', // Variable initialization according to image extension $img = null; + $extImg = null; switch ($infoImg[2]) { case IMAGETYPE_GIF: // 1 $img = imagecreatefromgif($filetoread); @@ -805,7 +810,7 @@ function vignette($file, $maxWidth = 160, $maxHeight = 120, $extName = '_small', imagejpeg($imgThumb, $imgThumbName, $newquality); // @phan-suppress-current-line PhanTypeMismatchArgumentNullableInternal,PhanPossiblyUndeclaredVariable break; case IMAGETYPE_PNG: // 3 - imagepng($imgThumb, $imgThumbName, $newquality); // @phan-suppress-current-line PhanPossiblyUndeclaredVariable + imagepng($imgThumb, $imgThumbName, !is_numeric($newquality) ? -1 : (int) $newquality); // @phan-suppress-current-line PhanPossiblyUndeclaredVariable break; case IMAGETYPE_BMP: // 6 // Not supported by PHP GD From 7847da3c1162a9e7d296f743d19035e8c273a177 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 16:55:45 +0100 Subject: [PATCH 145/602] Qual: Fix phan notices --- .../core/modules/asset/doc/pdf_standard_asset.modules.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php b/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php index 21868e83967..4854eb516c4 100644 --- a/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php +++ b/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php @@ -9,7 +9,7 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * * This program is free software; you can redistribute it and/or modify @@ -772,7 +772,7 @@ class pdf_standard_asset extends ModelePDFAsset //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } @@ -1001,6 +1001,8 @@ class pdf_standard_asset extends ModelePDFAsset if (is_object($thirdparty)) { $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + } else { + $carac_client_name = ''; } $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), ($usecontact ? 1 : 0), 'target', $object); From ac9301dc8f6b352a8ae4ad0effcefc3a74cbc674 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 16:58:53 +0100 Subject: [PATCH 146/602] Qual: Handle case where code to convert is --- htdocs/core/modules/barcode/doc/phpbarcode.modules.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/barcode/doc/phpbarcode.modules.php b/htdocs/core/modules/barcode/doc/phpbarcode.modules.php index b066f2a460c..56e846a0516 100644 --- a/htdocs/core/modules/barcode/doc/phpbarcode.modules.php +++ b/htdocs/core/modules/barcode/doc/phpbarcode.modules.php @@ -1,7 +1,7 @@ * Copyright (C) 2005 Regis Houssin - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -159,6 +159,7 @@ class modPhpbarcode extends ModeleBarCode $filebarcode = ''; } + $result = "No barcode ($code) to print"; dol_syslog(get_class($this)."::buildBarCode $code,$encoding,$scale,$mode,$filebarcode"); if ($code) { $result = barcode_print($code, $encoding, $scale, $mode, $filebarcode); From 56c060e14a175b5975a40f29c5da8a8365548a38 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 17:04:18 +0100 Subject: [PATCH 147/602] Qual: Define types for properties --- .../modules/barcode/mod_barcode_product_standard.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/barcode/mod_barcode_product_standard.php b/htdocs/core/modules/barcode/mod_barcode_product_standard.php index ca5c3b7a3e0..0188ad64d64 100644 --- a/htdocs/core/modules/barcode/mod_barcode_product_standard.php +++ b/htdocs/core/modules/barcode/mod_barcode_product_standard.php @@ -4,7 +4,7 @@ * Copyright (C) 2007-2012 Regis Houssin * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -43,9 +43,15 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode */ public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + /** + * @var ?string + */ public $searchcode; // Search string - public $numbitcounter; // Number of digits the counter + /** + * @var ?int + */ + public $numbitcounter; // Number of digits in the counter /** * Constructor From ccc0528dd48e85e530fbe3e62833b970508aa960 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 17:11:11 +0100 Subject: [PATCH 148/602] Qual: Fix argument types --- .../modules/commande/doc/pdf_einstein.modules.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php index 4b42d6c93da..b678fc7e9b4 100644 --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php @@ -7,8 +7,8 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2015 Marcos García * Copyright (C) 2017-2018 Ferran Marcet - * Copyright (C) 2018-2025 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * Copyright (C) 2024 Alexandre Spangaro * @@ -650,7 +650,7 @@ class pdf_einstein extends ModelePDFCommandes $pagecount = $pdf->setSourceFile($termsofsale); for ($i = 1; $i <= $pagecount; $i++) { $tplIdx = $pdf->importPage($i); - if ($tplIdx!==false) { + if ($tplIdx !== false) { $s = $pdf->getTemplatesize($tplIdx); $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L'); $pdf->useTemplate($tplIdx); @@ -967,11 +967,11 @@ class pdf_einstein extends ModelePDFCommandes // Total HT $pdf->SetFillColor(255, 255, 255); - $pdf->SetXY($col1x, $tab2_top+ $tab2_hl * $index); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1); $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht); - $pdf->SetXY($col2x, $tab2_top+ $tab2_hl * $index); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1); // Show VAT by rates and total @@ -1261,7 +1261,7 @@ class pdf_einstein extends ModelePDFCommandes //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } @@ -1614,7 +1614,7 @@ class pdf_einstein extends ModelePDFCommandes // Show shipping frame $pdf->SetXY($posx + 2, $posy - 5); $pdf->SetFont('', '', $default_font_size - 2); - $pdf->MultiCell($widthrecbox, '', $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); + $pdf->MultiCell($widthrecbox, 0, $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D'); // Show shipping name From c0ad3f22b9328271c600f3a21339853f04dbbacf Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 17:21:18 +0100 Subject: [PATCH 149/602] Qual: fix phan notices --- .../commande/doc/pdf_eratosthene.modules.php | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index e72b7d39491..5f1a384d7a0 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -9,7 +9,7 @@ * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2021-2024 Anthony Berton * Copyright (C) 2018-2025 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * Copyright (C) 2024 Joachim Kueter * Copyright (C) 2024 Alexandre Spangaro @@ -226,6 +226,7 @@ class pdf_eratosthene extends ModelePDFCommandes } $arephoto = false; + $realpath = null; foreach ($pdir as $midir) { if (!$arephoto) { if ($conf->entity != $objphoto->entity) { @@ -275,6 +276,12 @@ class pdf_eratosthene extends ModelePDFCommandes $file = $dir."/".$objectref.".pdf"; } + if ($dir === null) { + dol_syslog(get_class($this).'::'.__METHOD__."Target directory should not be null.". getCallerInfoString(), LOG_ERR); + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + if (!file_exists($dir)) { if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); @@ -365,7 +372,7 @@ class pdf_eratosthene extends ModelePDFCommandes $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10); if (!$hidetop && getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { // TODO : make this hidden conf the default behavior for each PDF when each PDF managed this new Display - $tab_top_newpage+= $this->tabTitleHeight; + $tab_top_newpage += $this->tabTitleHeight; } $tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext; @@ -603,6 +610,7 @@ class pdf_eratosthene extends ModelePDFCommandes // I remove the line commented below because it probably uselesss (or bug source) no need to change bottom margin because we have checked image fit //$pdf->setPageOrientation('', 0, $heightforfooter + $heightforfreetext); // The only function to edit the bottom margin of current page to set it. + // @phan-suppress-next-line PhanTypeMismatchProperty if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + $imageTopMargin, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually @@ -778,7 +786,7 @@ class pdf_eratosthene extends ModelePDFCommandes // Add last page for document footer if there are not enough size left $afterPosData = $this->getMaxAfterColsLinePositionsData(); - if ($afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot) ) { + if ($afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)) { $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); @@ -789,7 +797,7 @@ class pdf_eratosthene extends ModelePDFCommandes // Draw table frames and columns borders $drawTabNumbPage = $pdf->getNumPages(); - for ($i=$pageposbeforeprintlines; $i<=$drawTabNumbPage; $i++) { + for ($i = $pageposbeforeprintlines; $i <= $drawTabNumbPage; $i++) { $pdf->setPage($i); // reset page orientation each loop to override it if it was changed $pdf->setPageOrientation('', 0, 0); // The only function to edit the bottom margin of current page to set it. @@ -804,7 +812,7 @@ class pdf_eratosthene extends ModelePDFCommandes $drawTabTop = $tab_top; } elseif (!$drawTabHideTop) { if (getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { - $drawTabTop-= $this->tabTitleHeight; + $drawTabTop -= $this->tabTitleHeight; } else { $drawTabHideTop = 1; } @@ -813,7 +821,7 @@ class pdf_eratosthene extends ModelePDFCommandes // last page need to include document footer if ($i == $pdf->getNumPages()) { // remove document footer height to tab bottom position - $drawTabBottom-= $heightforfreetext + $heightforinfotot; + $drawTabBottom -= $heightforfreetext + $heightforinfotot; } $drawTabHeight = $drawTabBottom - $drawTabTop; @@ -865,7 +873,7 @@ class pdf_eratosthene extends ModelePDFCommandes $pagecount = $pdf->setSourceFile($termsofsale); for ($i = 1; $i <= $pagecount; $i++) { $tplIdx = $pdf->importPage($i); - if ($tplIdx!==false) { + if ($tplIdx !== false) { $s = $pdf->getTemplatesize($tplIdx); $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L'); $pdf->useTemplate($tplIdx); @@ -1471,7 +1479,7 @@ class pdf_eratosthene extends ModelePDFCommandes //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } @@ -1738,6 +1746,8 @@ class pdf_eratosthene extends ModelePDFCommandes if (is_object($thirdparty)) { $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + } else { + $carac_client_name = ''; } $mode = 'target'; @@ -1800,7 +1810,7 @@ class pdf_eratosthene extends ModelePDFCommandes // Show shipping frame $pdf->SetXY($posx + 2, $posy - 5); $pdf->SetFont('', '', $default_font_size - 2); - $pdf->MultiCell($widthrecbox, '', $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); + $pdf->MultiCell($widthrecbox, 0, $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D'); // Show shipping name From 1ae4f984ed9714242d214d0611b8d7e755c77c5a Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 17:23:07 +0100 Subject: [PATCH 150/602] Qual: fix phan notices --- htdocs/core/modules/contract/doc/pdf_strato.modules.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/contract/doc/pdf_strato.modules.php b/htdocs/core/modules/contract/doc/pdf_strato.modules.php index a5fb5ace0f3..e58fb460ea1 100644 --- a/htdocs/core/modules/contract/doc/pdf_strato.modules.php +++ b/htdocs/core/modules/contract/doc/pdf_strato.modules.php @@ -7,7 +7,7 @@ * Copyright (C) 2013-2024 Philippe Grand * Copyright (C) 2015 Marcos García * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024 Éric Seigne @@ -191,6 +191,12 @@ class pdf_strato extends ModelePDFContract $file = $dir."/".$objectref.".pdf"; } + if ($dir === null) { + dol_syslog(get_class($this).'::'.__METHOD__."Target directory should not be null.". getCallerInfoString(), LOG_ERR); + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", "Null dir"); + return 0; + } + if (!file_exists($dir)) { if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentitiesnoconv("ErrorCanNotCreateDir", $dir); From 44944ac15ac648a1feda8558b2a5d8607b996321 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 17:24:40 +0100 Subject: [PATCH 151/602] Qual: fix phan notices --- htdocs/core/modules/delivery/doc/pdf_storm.modules.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/delivery/doc/pdf_storm.modules.php b/htdocs/core/modules/delivery/doc/pdf_storm.modules.php index d75dade66fa..74e9375dcac 100644 --- a/htdocs/core/modules/delivery/doc/pdf_storm.modules.php +++ b/htdocs/core/modules/delivery/doc/pdf_storm.modules.php @@ -6,7 +6,7 @@ * Copyright (C) 2011-2021 Philippe Grand * Copyright (C) 2015 Marcos García * Copyright (C) 2020 John BOTELLA - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Nick Fragoulis * @@ -203,6 +203,7 @@ class pdf_storm extends ModelePDFDeliveryOrder } $arephoto = false; + $realpath = false; foreach ($pdir as $midir) { if (!$arephoto) { $dir = $conf->product->dir_output.'/'.$midir; @@ -663,7 +664,7 @@ class pdf_storm extends ModelePDFDeliveryOrder if (empty($hidetop)) { //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } From 7aa845efd0558de3e8eac962dee7f2730c434abe Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 18:12:36 +0100 Subject: [PATCH 152/602] Qual: Fix phan notices --- htdocs/core/customreports.php | 48 ++++++--- .../commande/doc/pdf_eratosthene.modules.php | 2 +- .../modules/commande/modules_commande.php | 4 +- .../delivery/doc/pdf_typhon.modules.php | 11 ++- .../expedition/doc/pdf_merou.modules.php | 13 ++- .../pdf_standard_expensereport.modules.php | 29 +++++- .../modules/facture/doc/pdf_crabe.modules.php | 18 ++-- .../facture/doc/pdf_octopus.modules.php | 12 ++- .../facture/doc/pdf_sponge.modules.php | 18 ++-- .../core/modules/facture/modules_facture.php | 50 +++++++++- htdocs/core/modules/fichinter/mod_pacific.php | 5 +- .../doc/pdf_standard_evaluation.modules.php | 2 +- .../modules/mailings/contacts1.modules.php | 4 +- .../modules/mailings/thirdparties.modules.php | 4 +- .../pdf_standard_movementstock.modules.php | 98 +++++++++++++------ .../modules/mrp/doc/pdf_vinci.modules.php | 6 +- .../modules/printing/printgcp.modules.php | 18 +++- .../product/doc/pdf_standard.modules.php | 61 ++++++------ .../task/doc/doc_generic_task_odt.modules.php | 4 +- .../modules/propale/doc/pdf_azur.modules.php | 21 ++-- .../modules/propale/doc/pdf_cyan.modules.php | 44 +++++---- .../core/modules/propale/modules_propale.php | 49 +++++++++- .../reception/doc/pdf_squille.modules.php | 4 +- 23 files changed, 372 insertions(+), 153 deletions(-) diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index 5535546dece..e15031940c7 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -1,4 +1,5 @@ * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France @@ -41,9 +42,9 @@ */ // Initialise values -$search_xaxis = array(); $search_groupby = array(); $tabfamily = null; +$objecttype = null; if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) { require '../main.inc.php'; @@ -70,7 +71,7 @@ if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) { '@phan-var-force string[] $search_groupby'; $search_yaxis = GETPOST('search_yaxis', 'array'); - $search_graph = GETPOST('search_graph', 'restricthtml'); + $search_graph = (string) GETPOST('search_graph', 'restricthtml'); // Load variable for pagination $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; @@ -113,12 +114,21 @@ if (empty($mode)) { if (!isset($search_measures)) { $search_measures = array(0 => 't.count'); } +if (!isset($search_xaxis)) { + // Ensure value is set and not null. + $search_xaxis = array(); +} +if (!isset($search_graph)) { + // Ensure value is set and not null + $search_graph = ''; +} if (!empty($object)) { $objecttype = $object->element.($object->module ? '@'.$object->module : ''); } -if (empty($objecttype)) { +if (!is_string($objecttype) || empty($objecttype)) { $objecttype = 'thirdparty'; } +'@phan-var-force string $objecttype'; // Help phan that suggests $objecttype can be null require_once DOL_DOCUMENT_ROOT."/core/class/extrafields.class.php"; require_once DOL_DOCUMENT_ROOT."/core/class/html.form.class.php"; @@ -163,6 +173,7 @@ $arrayoftype = array( // Complete $arrayoftype by external modules $parameters = array('objecttype' => $objecttype, 'tabfamily' => $tabfamily); +// @phan-suppress-next-line PhanTypeMismatchArgumentNullable $reshook = $hookmanager->executeHooks('loadDataForCustomReports', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); @@ -191,9 +202,12 @@ if ($objecttype) { } else { $fileforclass = "/".$objecttype."/class/".$objecttype.".class.php"; } - dol_include_once($fileforclass); + $ObjectClassName = null; - $ObjectClassName = $arrayoftype[$objecttype]['ObjectClassName']; + if ($fileforclass !== null) { + dol_include_once($fileforclass); + $ObjectClassName = $arrayoftype[$objecttype]['ObjectClassName']; + } if (!empty($ObjectClassName)) { if (class_exists($ObjectClassName)) { $object = new $ObjectClassName($db); @@ -369,7 +383,7 @@ if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) { $newarrayoftype = array(); foreach ($arrayoftype as $key => $val) { - if (dol_eval($val['enabled'], 1, 1, '1')) { + if (dol_eval((string) $val['enabled'], 1, 1, '1')) { $newarrayoftype[$key] = $arrayoftype[$key]; } if (!empty($val['langs'])) { @@ -378,11 +392,15 @@ foreach ($arrayoftype as $key => $val) { } $count = 0; -$arrayoffilterfields = fillArrayOfFilterFields($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayoffilterfields, 0, $count); +$label = ''; +if (array_key_exists($objecttype, $newarrayoftype)) { + $label = $langs->trans($newarrayoftype[$objecttype]['label']); +} +$arrayoffilterfields = fillArrayOfFilterFields($object, 't', $label, $arrayoffilterfields, 0, $count); $arrayoffilterfields = dol_sort_array($arrayoffilterfields, 'position', 'asc', 0, 0, 1); $count = 0; -$arrayofmesures = fillArrayOfMeasures($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofmesures, 0, $count); +$arrayofmesures = fillArrayOfMeasures($object, 't', $label, $arrayofmesures, 0, $count); $arrayofmesures = dol_sort_array($arrayofmesures, 'position', 'asc', 0, 0, 1); $count = 0; @@ -396,17 +414,17 @@ $arrayofgroupby = dol_sort_array($arrayofgroupby, 'position', 'asc', 0, 0, 1); // Check parameters if ($action == 'viewgraph') { - if (is_array($search_measures) && !count($search_measures)) { + if (!count($search_measures)) { setEventMessages($langs->trans("AtLeastOneMeasureIsRequired"), null, 'warnings'); } elseif ($mode == 'graph' && is_array($search_xaxis) && count($search_xaxis) > 1) { setEventMessages($langs->trans("OnlyOneFieldForXAxisIsPossible"), null, 'warnings'); $search_xaxis = array(0 => $search_xaxis[0]); } - if (is_array($search_groupby) && count($search_groupby) >= 2) { + if (count($search_groupby) >= 2) { setEventMessages($langs->trans("ErrorOnlyOneFieldForGroupByIsPossible"), null, 'warnings'); $search_groupby = array(0 => $search_groupby[0]); } - if (is_array($search_xaxis) && !count($search_xaxis)) { + if (!count($search_xaxis)) { setEventMessages($langs->trans("AtLeastOneXAxisIsRequired"), null, 'warnings'); } elseif ($mode == 'graph' && $search_graph == 'bars' && count($search_measures) > $MAXMEASURESINBARGRAPH) { $langs->load("errors"); @@ -417,7 +435,7 @@ if ($action == 'viewgraph') { // Get all possible values of fields when a 'group by' is set, and save this into $arrayofvaluesforgroupby // $arrayofvaluesforgroupby will be used to forge lael of each grouped series -if (is_array($search_groupby) && count($search_groupby)) { +if (count($search_groupby)) { $fieldtocount = ''; foreach ($search_groupby as $gkey => $gval) { $gvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $gval); @@ -563,7 +581,7 @@ if (is_array($search_groupby) && count($search_groupby)) { } } //var_dump($labeloffield); - setEventMessages($langs->transnoentitiesnoconv("ErrorTooManyDifferentValueForSelectedGroupBy", $MAXUNIQUEVALFORGROUP, $labeloffield), null, 'warnings'); + setEventMessages($langs->transnoentitiesnoconv("ErrorTooManyDifferentValueForSelectedGroupBy", (string) $MAXUNIQUEVALFORGROUP, (string) $labeloffield), null, 'warnings'); $search_groupby = array(); } @@ -1064,7 +1082,7 @@ foreach ($search_measures as $key => $val) { $legend[] = $langs->trans($arrayofmesures[$val]['label']); } -$useagroupby = (is_array($search_groupby) && count($search_groupby)); +$useagroupby = count($search_groupby); //var_dump($useagroupby); //var_dump($arrayofvaluesforgroupby); @@ -1221,7 +1239,7 @@ if ($mode == 'graph') { $px1->SetLegend($legend); $px1->setShowLegend($SHOWLEGEND); - $px1->SetMinValue($px1->GetFloorMinValue()); + $px1->SetMinValue((int) $px1->GetFloorMinValue()); $px1->SetMaxValue($px1->GetCeilMaxValue()); $px1->SetWidth($WIDTH); $px1->SetHeight($HEIGHT); diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index 5f1a384d7a0..1362556387d 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -278,7 +278,7 @@ class pdf_eratosthene extends ModelePDFCommandes if ($dir === null) { dol_syslog(get_class($this).'::'.__METHOD__."Target directory should not be null.". getCallerInfoString(), LOG_ERR); - $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", "Null dir"); return 0; } diff --git a/htdocs/core/modules/commande/modules_commande.php b/htdocs/core/modules/commande/modules_commande.php index db65437e38e..fdac0976b70 100644 --- a/htdocs/core/modules/commande/modules_commande.php +++ b/htdocs/core/modules/commande/modules_commande.php @@ -85,14 +85,14 @@ abstract class ModelePDFCommandes extends CommonDocGenerator /** * Local tax rates Array[tax_type][tax_rate] * - * @var array> + * @var array> */ public $localtax1; /** * Local tax rates Array[tax_type][tax_rate] * - * @var array> + * @var array> */ public $localtax2; diff --git a/htdocs/core/modules/delivery/doc/pdf_typhon.modules.php b/htdocs/core/modules/delivery/doc/pdf_typhon.modules.php index 9371f68b116..5841616cda7 100644 --- a/htdocs/core/modules/delivery/doc/pdf_typhon.modules.php +++ b/htdocs/core/modules/delivery/doc/pdf_typhon.modules.php @@ -5,7 +5,7 @@ * Copyright (C) 2008 Chiptronik * Copyright (C) 2011-2021 Philippe Grand * Copyright (C) 2015 Marcos García - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Nick Fragoulis * @@ -72,8 +72,17 @@ class pdf_typhon extends ModelePDFDeliveryOrder */ public $version = 'dolibarr'; + /** + * @var float + */ public $posxcomm; // For customer comment column + /** + * @var float + */ public $posxweightvol; // For weight or volume + /** + * @var float + */ public $posxremainingqty; diff --git a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php index d4aca633a6e..d54d831adb1 100644 --- a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Marcos García - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Nick Fragoulis * @@ -65,8 +65,17 @@ class pdf_merou extends ModelePdfExpedition */ public $type; + /** + * @var Contact + */ public $destinataire; + /** + * @var ?Societe + */ public $expediteur; + /** + * @var User + */ public $livreur; /** @@ -624,7 +633,7 @@ class pdf_merou extends ModelePdfExpedition $label .= $object->tracking_url; } $pdf->SetFont('', 'B', $default_font_size - 3); - $pdf->writeHTMLCell(50, 8, '', '', $label, '', 'L'); + $pdf->writeHTMLCell(50, 8, '', '', $label, 0, 1, false, true, 'L'); } } } else { diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php index 44d26eb9f0b..925ff9efce6 100644 --- a/htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php @@ -7,7 +7,7 @@ * Copyright (C) 2019 Markus Welters * Copyright (C) 2019 Rafael Ingenleuf * Copyright (C) 2020 Marc Guenneugues - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * * This program is free software; you can redistribute it and/or modify @@ -77,19 +77,46 @@ class pdf_standard_expensereport extends ModeleExpenseReport */ public $version = 'dolibarr'; + /** + * @var float + */ public $posxpiece; + /** + * @var float + */ public $posxcomment; + /** + * @var float + */ public $posxtva; + /** + * @var float + */ public $posxup; + /** + * @var float + */ public $posxqty; + /** + * @var float + */ public $posxtype; /** * @var int posx date */ public $posxdate; + /** + * @var float + */ public $posxprojet; + /** + * @var float + */ public $postotalht; + /** + * @var float + */ public $postotalttc; diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 9b540229124..b751a886983 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -11,7 +11,7 @@ * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2022-2024 Anthony Berton * Copyright (C) 2022 Charlene Benke - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * Copyright (C) 2024 Alexandre Spangaro * @@ -800,7 +800,7 @@ class pdf_crabe extends ModelePDFFactures if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'])) { $this->tva_array[$vatrate . ($vatcode ? ' (' . $vatcode . ')' : '')]['tot_ht'] = 0; } - $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne, 'tot_ht'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'] + $object->lines[$i]->total_ht); + $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne, 'tot_ht' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'] + $object->lines[$i]->total_ht); } else { if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) { $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0; @@ -901,7 +901,7 @@ class pdf_crabe extends ModelePDFFactures $pagecount = $pdf->setSourceFile($termsofsale); for ($i = 1; $i <= $pagecount; $i++) { $tplIdx = $pdf->importPage($i); - if ($tplIdx!==false) { + if ($tplIdx !== false) { $s = $pdf->getTemplatesize($tplIdx); $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L'); $pdf->useTemplate($tplIdx); @@ -1884,7 +1884,7 @@ class pdf_crabe extends ModelePDFFactures $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } @@ -1903,10 +1903,10 @@ class pdf_crabe extends ModelePDFFactures if (getDolGlobalString('MAIN_GENERATE_INVOICES_WITH_PICTURE')) { $pdf->line($this->posxpicture - 1, $tab_top, $this->posxpicture - 1, $tab_top + $tab_height); - if (empty($hidetop)) { - //$pdf->SetXY($this->posxpicture-1, $tab_top+1); - //$pdf->MultiCell($this->posxtva-$this->posxpicture-1,2, $outputlangs->transnoentities("Photo"),'','C'); - } + //if (empty($hidetop)) { + //$pdf->SetXY($this->posxpicture-1, $tab_top+1); + //$pdf->MultiCell($this->posxtva-$this->posxpicture-1,2, $outputlangs->transnoentities("Photo"),'','C'); + //} } if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) { @@ -2338,7 +2338,7 @@ class pdf_crabe extends ModelePDFFactures // Show shipping frame $pdf->SetXY($posx + 2, $posy - 5); $pdf->SetFont('', '', $default_font_size - 2); - $pdf->MultiCell($widthrecbox, '', $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); + $pdf->MultiCell($widthrecbox, 0, $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D'); // Show shipping name diff --git a/htdocs/core/modules/facture/doc/pdf_octopus.modules.php b/htdocs/core/modules/facture/doc/pdf_octopus.modules.php index b3fa9ee860f..ae9408a933d 100644 --- a/htdocs/core/modules/facture/doc/pdf_octopus.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_octopus.modules.php @@ -12,7 +12,7 @@ * Copyright (C) 2022 Anthony Berton * Copyright (C) 2022-2024 Alexandre Spangaro * Copyright (C) 2022-2024 Eric Seigne - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * * This program is free software; you can redistribute it and/or modify @@ -336,6 +336,7 @@ class pdf_octopus extends ModelePDFFactures } $arephoto = false; + $realpath = false; foreach ($pdir as $midir) { if (!$arephoto) { if ($conf->entity != $objphoto->entity) { @@ -811,6 +812,7 @@ class pdf_octopus extends ModelePDFFactures } } + /** @phan-suppress-next-line PhanTypeMismatchProperty */ if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $posy + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually @@ -1046,7 +1048,7 @@ class pdf_octopus extends ModelePDFFactures if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'])) { $this->tva_array[$vatrate . ($vatcode ? ' (' . $vatcode . ')' : '')]['tot_ht'] = 0; } - $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne, 'tot_ht'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'] + $object->lines[$i]->total_ht); + $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne, 'tot_ht' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'] + $object->lines[$i]->total_ht); } else { if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) { $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0; @@ -2077,7 +2079,7 @@ class pdf_octopus extends ModelePDFFactures // MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } $tab_top += 4; } @@ -2503,7 +2505,7 @@ class pdf_octopus extends ModelePDFFactures // Show shipping frame $pdf->SetXY($posx + 2, $posy - 5); $pdf->SetFont('', '', $default_font_size - 2); - $pdf->MultiCell($widthrecbox, '', $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); + $pdf->MultiCell($widthrecbox, 0, $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D'); // Show shipping name @@ -2883,7 +2885,7 @@ class pdf_octopus extends ModelePDFFactures //$pdf->Rect($this->posx_cumul_anterieur - 1, $tab_top, $width, 5, 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); $pdf->RoundedRect($this->posx_cumul_anterieur - 1, $tab_top, $width, 5, $this->corner_radius, '1001', 'F', explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); //$pdf->Rect($this->marge_gauche, $tab_top + 92.5, $this->page_largeur - $this->marge_gauche - $this->marge_droite, 5, 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); - $pdf->RoundedRect($this->marge_gauche, $tab_top + 92.5, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top + 92.5, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 10bd4544923..0474bd6bf61 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -11,7 +11,7 @@ * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2018-2024 Anthony Berton * Copyright (C) 2022-2024 Alexandre Spangaro - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * Copyright (C) 2024 Franck Moreau * @@ -262,6 +262,7 @@ class pdf_sponge extends ModelePDFFactures } $arephoto = false; + $realpath = false; foreach ($pdir as $midir) { if (!$arephoto) { if ($conf->entity != $objphoto->entity) { @@ -751,6 +752,7 @@ class pdf_sponge extends ModelePDFFactures } $pdf->setPageOrientation('', 0, $this->heightforfooter + $this->heightforfreetext); // The only function to edit the bottom margin of current page to set it. + // @phan-suppress-next-line PhanTypeMismatchProperty if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + $imageTopMargin, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually @@ -941,7 +943,7 @@ class pdf_sponge extends ModelePDFFactures if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'])) { $this->tva_array[$vatrate . ($vatcode ? ' (' . $vatcode . ')' : '')]['tot_ht'] = 0; } - $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne, 'tot_ht'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'] + $object->lines[$i]->total_ht); + $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne, 'tot_ht' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'] + $object->lines[$i]->total_ht); } else { if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) { $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0; @@ -979,7 +981,7 @@ class pdf_sponge extends ModelePDFFactures // Draw table frames and columns borders $drawTabNumbPage = $pdf->getNumPages(); - for ($i=$pageposbeforeprintlines; $i<=$drawTabNumbPage; $i++) { + for ($i = $pageposbeforeprintlines; $i <= $drawTabNumbPage; $i++) { $pdf->setPage($i); // reset page orientation each loop to override it if it was changed $pdf->setPageOrientation('', 0, 0); // The only function to edit the bottom margin of current page to set it. @@ -994,7 +996,7 @@ class pdf_sponge extends ModelePDFFactures $drawTabTop = $this->tab_top; } elseif (!$drawTabHideTop) { if (getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { - $drawTabTop-= $this->tabTitleHeight; + $drawTabTop -= $this->tabTitleHeight; } else { $drawTabHideTop = 1; } @@ -1003,7 +1005,7 @@ class pdf_sponge extends ModelePDFFactures // last page need to include document footer if ($i == $pdf->getNumPages()) { // remove document footer height to tab bottom position - $drawTabBottom-= $this->heightforfreetext + $this->heightforinfotot + $this->getHeightForQRInvoice($pdf->getPage(), $object, $outputlangs); + $drawTabBottom -= $this->heightforfreetext + $this->heightforinfotot + $this->getHeightForQRInvoice($pdf->getPage(), $object, $outputlangs); } $drawTabHeight = $drawTabBottom - $drawTabTop; @@ -1061,7 +1063,7 @@ class pdf_sponge extends ModelePDFFactures $pagecount = $pdf->setSourceFile($termsofsale); for ($i = 1; $i <= $pagecount; $i++) { $tplIdx = $pdf->importPage($i); - if ($tplIdx!==false) { + if ($tplIdx !== false) { $s = $pdf->getTemplatesize($tplIdx); $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L'); $pdf->useTemplate($tplIdx); @@ -2190,7 +2192,7 @@ class pdf_sponge extends ModelePDFFactures //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } @@ -2586,7 +2588,7 @@ class pdf_sponge extends ModelePDFFactures // Show shipping frame $pdf->SetXY($posx + 2, $posy - 5); $pdf->SetFont('', '', $default_font_size - 2); - $pdf->MultiCell($widthrecbox, '', $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); + $pdf->MultiCell($widthrecbox, 0, $outputlangs->transnoentities('ShippingTo'), 0, 'L', 0); $pdf->RoundedRect($posx, $posy, $widthrecbox, $hautcadre, $this->corner_radius, '1234', 'D'); // Show shipping name diff --git a/htdocs/core/modules/facture/modules_facture.php b/htdocs/core/modules/facture/modules_facture.php index b81a17895d4..0f6ace0c642 100644 --- a/htdocs/core/modules/facture/modules_facture.php +++ b/htdocs/core/modules/facture/modules_facture.php @@ -4,7 +4,7 @@ * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2014 Marcos García - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -42,21 +42,69 @@ use Sprain\SwissQrBill; */ abstract class ModelePDFFactures extends CommonDocGenerator { + /** + * @var float + */ public $posxpicture; + /** + * @var float + */ public $posxtva; + /** + * @var float + */ public $posxup; + /** + * @var float + */ public $posxqty; + /** + * @var float + */ public $posxunit; + /** + * @var float + */ public $posxdesc; + /** + * @var float + */ public $posxdiscount; + /** + * @var float + */ public $postotalht; + + /** + * @var array + */ public $tva; + /** + * @var array + */ public $tva_array; + /** + * Local tax rates Array[tax_type][tax_rate] + * + * @var array> + */ public $localtax1; + + /** + * Local tax rates Array[tax_type][tax_rate] + * + * @var array> + */ public $localtax2; + /** + * @var int<0,1> + */ public $atleastonediscount = 0; + /** + * @var int<0,1> + */ public $atleastoneratenotnull = 0; diff --git a/htdocs/core/modules/fichinter/mod_pacific.php b/htdocs/core/modules/fichinter/mod_pacific.php index f6eaa326c75..fe69438341b 100644 --- a/htdocs/core/modules/fichinter/mod_pacific.php +++ b/htdocs/core/modules/fichinter/mod_pacific.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2024-2025 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -140,13 +140,12 @@ class mod_pacific extends ModeleNumRefFicheinter $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; $sql .= " AND entity = ".$conf->entity; + $max = 0; $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); if ($obj) { $max = intval($obj->max); - } else { - $max = 0; } } diff --git a/htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php b/htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php index e0d8afd8668..8b2b2fb5c0b 100644 --- a/htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php +++ b/htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php @@ -7,7 +7,7 @@ * Copyright (C) 2019 Markus Welters * Copyright (C) 2019 Rafael Ingenleuf * Copyright (C) 2020 Marc Guenneugues - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index e8eca88cf4f..6a47290e352 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -2,7 +2,7 @@ /* Copyright (C) 2005 Rodolphe Quiedeville * Copyright (C) 2005-2009 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -314,7 +314,7 @@ class mailing_contacts1 extends MailingTargets require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $formadmin = new FormAdmin($this->db); $s .= img_picto($langs->trans("DefaultLang"), 'language', 'class="pictofixedwidth"'); - $s .= $formadmin->select_language(GETPOST('filter_lang', 'aZ09'), 'filter_lang', 0, null, $langs->trans("DefaultLang"), 0, 0, '', 0, 0, 0, null, 1); + $s .= $formadmin->select_language(GETPOST('filter_lang', 'aZ09'), 'filter_lang', 0, array(), $langs->trans("DefaultLang"), 0, 0, '', 0, 0, 0, array(), 1); } return $s; diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php index 583d0aec206..4385c039596 100644 --- a/htdocs/core/modules/mailings/thirdparties.modules.php +++ b/htdocs/core/modules/mailings/thirdparties.modules.php @@ -2,7 +2,7 @@ /* Copyright (C) 2018-2018 Andre Schild * Copyright (C) 2005-2010 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This file is an example to follow to add your own email selector inside @@ -385,7 +385,7 @@ class mailing_thirdparties extends MailingTargets $formadmin = new FormAdmin($this->db); $s .= img_picto($langs->trans("DefaultLang"), 'language', 'class="pictofixedwidth"'); //$s .= ''.$langs->trans("DefaultLang").': '; - $s .= $formadmin->select_language(GETPOST('filter_lang_thirdparties', 'aZ09'), 'filter_lang_thirdparties', 0, null, $langs->trans("DefaultLang"), 0, 0, '', 0, 0, 0, null, 1); + $s .= $formadmin->select_language(GETPOST('filter_lang_thirdparties', 'aZ09'), 'filter_lang_thirdparties', 0, array(), $langs->trans("DefaultLang"), 0, 0, '', 0, 0, 0, array(), 1); } return $s; diff --git a/htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php b/htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php index 7a0624cb99b..9f461561c32 100644 --- a/htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php +++ b/htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Nick Fragoulis * @@ -45,16 +45,49 @@ class pdf_standard_movementstock extends ModelePDFMovement */ public $update_main_doc_field; + /** + * @var int + */ public $wref; + /** + * @var float + */ public $posxidref; + /** + * @var float + */ public $posxdatemouv; + /** + * @var float + */ public $posxdesc; + /** + * @var float + */ public $posxlabel; + /** + * @var float + */ public $posxtva; + /** + * @var float + */ public $posxqty; + /** + * @var float + */ public $posxup; + /** + * @var float + */ public $posxunit; + /** + * @var float + */ public $posxdiscount; + /** + * @var float + */ public $postotalht; @@ -320,7 +353,7 @@ class pdf_standard_movementstock extends ModelePDFMovement $resql = $this->db->query($sql); - $nbtotalofrecords = $this->db->num_rows($result); + $nbtotalofrecords = $this->db->num_rows($resql); /* * END TODO @@ -840,7 +873,7 @@ class pdf_standard_movementstock extends ModelePDFMovement if (empty($hidetop)) { //$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line takes a position y in 2nd parameter and 4th parameter $pdf->SetXY($this->posxidref, $tab_top + 1); - $pdf->MultiCell($this->posxdatemouv - $this->posxdatemouv - 0.8, 3, $outputlangs->transnoentities("Ref"), '', 'L'); + $pdf->MultiCell($this->posxdesc - $this->posxdatemouv - 0.8, 3, $outputlangs->transnoentities("Ref"), '', 'L'); } //Date mouv @@ -1036,6 +1069,7 @@ class pdf_standard_movementstock extends ModelePDFMovement $obj = $this->db->fetch_object($resqlbis); $lastmovementdate = $this->db->jdate($obj->datem); } else { + $lastmovementdate = 0; dol_print_error($this->db); } @@ -1088,39 +1122,39 @@ class pdf_standard_movementstock extends ModelePDFMovement // $top_shift = $pdf->getY() - $current_y; //} - if ($showaddress) { - /* - // Sender properties - $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); + //if ($showaddress) { + /* + // Sender properties + $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); - // Show sender - $posy=42; - $posx=$this->marge_gauche; - if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) $posx=$this->page_largeur-$this->marge_droite-80; - $hautcadre=40; + // Show sender + $posy=42; + $posx=$this->marge_gauche; + if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) $posx=$this->page_largeur-$this->marge_droite-80; + $hautcadre=40; - // Show sender frame - $pdf->SetTextColor(0,0,0); - $pdf->SetFont('','', $default_font_size - 2); - $pdf->SetXY($posx,$posy-5); - $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, 'L'); - $pdf->SetXY($posx,$posy); - $pdf->SetFillColor(230,230,230); - $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); - $pdf->SetTextColor(0,0,60); + // Show sender frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, 'L'); + $pdf->SetXY($posx,$posy); + $pdf->SetFillColor(230,230,230); + $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0,0,60); - // Show sender name - $pdf->SetXY($posx+2,$posy+3); - $pdf->SetFont('','B', $default_font_size); - $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); - $posy=$pdf->getY(); + // Show sender name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + $posy=$pdf->getY(); - // Show sender information - $pdf->SetXY($posx+2,$posy); - $pdf->SetFont('','', $default_font_size - 1); - $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); - */ - } + // Show sender information + $pdf->SetXY($posx+2,$posy); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); + */ + //} $pdf->SetTextColor(0, 0, 0); diff --git a/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php b/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php index 1625bbffca0..9fde1bfb432 100644 --- a/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php +++ b/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php @@ -5,8 +5,8 @@ * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet - * Copyright (C) 2018-2025 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2018-2025 Frédéric France + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Josep Lluís Amador * Copyright (C) 2024 Nick Fragoulis * @@ -944,7 +944,7 @@ class pdf_vinci extends ModelePDFMo //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index 060168279ab..af35adb57d0 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -1,7 +1,7 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -216,7 +216,7 @@ class printing_printgcp extends PrintingDriver $html .= ''; $html .= ''; $html .= ''."\n"; - $list = $this->getlistAvailablePrinters(); + $list = $this->getlistAvailableGcpPrinters(); //$html.= ''; foreach ($list['available'] as $printer_det) { $html .= ''; @@ -245,9 +245,21 @@ class printing_printgcp extends PrintingDriver /** * Return list of available printers * - * @return array{available:array{name:string,displayname:string,id:string,ownerName:string,status:string,connectionStatus:string,type:string}} list of printers + * @return array list of printers */ public function getlistAvailablePrinters() + { + /* Compatible with paretn class signature */ + return $this->getlistAvailableGcpPrinters()['available']; + } + + + /** + * Return list of available printers (internal format) + * + * @return array{available:array} list of printers + */ + public function getlistAvailableGcpPrinters() { global $conf; $ret = array(); diff --git a/htdocs/core/modules/product/doc/pdf_standard.modules.php b/htdocs/core/modules/product/doc/pdf_standard.modules.php index 68f6a5a7e81..adba3813d90 100644 --- a/htdocs/core/modules/product/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/product/doc/pdf_standard.modules.php @@ -1,7 +1,7 @@ * Copyright (C) 2023 Anthony Berton - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Nick Fragoulis * @@ -278,6 +278,7 @@ class pdf_standard extends ModelePDFProduct } // Define size of image if we need it $imglinesize = array(); + $nexyafterphoto = null; if (!empty($realpath) && $arephoto) { $imgsize = pdf_getSizeForImage($realpath); $imgsizewidth = $imgsize['width'] + 20; @@ -832,39 +833,39 @@ class pdf_standard extends ModelePDFProduct // Show list of linked objects $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); - if ($showaddress) { - /* - // Sender properties - $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); + //if ($showaddress) { + /* + // Sender properties + $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); - // Show sender - $posy=42; - $posx=$this->marge_gauche; - if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) $posx=$this->page_largeur-$this->marge_droite-80; - $hautcadre=40; + // Show sender + $posy=42; + $posx=$this->marge_gauche; + if (getDolGlobalString('MAIN_INVERT_SENDER_RECIPIENT')) $posx=$this->page_largeur-$this->marge_droite-80; + $hautcadre=40; - // Show sender frame - $pdf->SetTextColor(0,0,0); - $pdf->SetFont('','', $default_font_size - 2); - $pdf->SetXY($posx,$posy-5); - $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, 'L'); - $pdf->SetXY($posx,$posy); - $pdf->SetFillColor(230,230,230); - $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); - $pdf->SetTextColor(0,0,60); + // Show sender frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(80, 5, $outputlangs->transnoentities("BillFrom"), 0, 'L'); + $pdf->SetXY($posx,$posy); + $pdf->SetFillColor(230,230,230); + $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0,0,60); - // Show sender name - $pdf->SetXY($posx+2,$posy+3); - $pdf->SetFont('','B', $default_font_size); - $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); - $posy=$pdf->getY(); + // Show sender name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + $posy=$pdf->getY(); - // Show sender information - $pdf->SetXY($posx+2,$posy); - $pdf->SetFont('','', $default_font_size - 1); - $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); - */ - } + // Show sender information + $pdf->SetXY($posx+2,$posy); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); + */ + //} $pdf->SetTextColor(0, 0, 0); diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index a20c933500a..705f32894e5 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -5,7 +5,7 @@ * Copyright (C) 2016 Charlie Benke * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2023 Gauthier VERDOL - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -647,7 +647,7 @@ class doc_generic_task_odt extends ModelePDFTask $soc->fetch($contact['socid']); $contact['socname'] = $soc->name; } - $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1); + $contact['fullname'] = is_object($objectdetail) ? $objectdetail->getFullName($outputlangs, 1) : null; $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs); diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 0397dd86f0f..03d5134db0e 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -10,7 +10,7 @@ * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2019 Pierre Ardoin * Copyright (C) 2021-2024 Anthony Berton - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * Copyright (C) 2024 Alexandre Spangaro * @@ -775,7 +775,7 @@ class pdf_azur extends ModelePDFPropales $pagecount = $pdf->setSourceFile($termsofsale); for ($i = 1; $i <= $pagecount; $i++) { $tplIdx = $pdf->importPage($i); - if ($tplIdx!==false) { + if ($tplIdx !== false) { $s = $pdf->getTemplatesize($tplIdx); $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L'); $pdf->useTemplate($tplIdx); @@ -816,6 +816,7 @@ class pdf_azur extends ModelePDFPropales // If PDF is selected and file is not empty if (count($filetomerge->lines) > 0) { foreach ($filetomerge->lines as $linefile) { + $filetomerge_dir = null; if (!empty($linefile->id) && !empty($linefile->file_name)) { if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) { if (isModEnabled("product")) { @@ -831,7 +832,11 @@ class pdf_azur extends ModelePDFPropales } } - dol_syslog(get_class($this).':: upload_dir='.$filetomerge_dir, LOG_DEBUG); + dol_syslog(get_class($this).':: upload_dir='.$filetomerge_dir, $filetomerge_dir === null ? LOG_ERR : LOG_DEBUG); + if ($filetomerge_dir === null) { + // Skip loop + continue; + } $infile = $filetomerge_dir.'/'.$linefile->file_name; if (file_exists($infile) && is_readable($infile)) { @@ -1447,7 +1452,7 @@ class pdf_azur extends ModelePDFPropales //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, 5, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } @@ -1466,10 +1471,10 @@ class pdf_azur extends ModelePDFPropales if (getDolGlobalString('MAIN_GENERATE_PROPOSALS_WITH_PICTURE')) { $pdf->line($this->posxpicture - 1, $tab_top, $this->posxpicture - 1, $tab_top + $tab_height); - if (empty($hidetop)) { - //$pdf->SetXY($this->posxpicture-1, $tab_top+1); - //$pdf->MultiCell($this->posxtva-$this->posxpicture-1,2, $outputlangs->transnoentities("Photo"),'','C'); - } + //if (empty($hidetop)) { + //$pdf->SetXY($this->posxpicture-1, $tab_top+1); + //$pdf->MultiCell($this->posxtva-$this->posxpicture-1,2, $outputlangs->transnoentities("Photo"),'','C'); + //} } if (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) { diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index 6121fc0bff5..4170db78e4b 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -9,7 +9,7 @@ * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2021-2024 Anthony Berton * Copyright (C) 2018-2025 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * Copyright (C) 2024 Alexandre Spangaro * @@ -359,7 +359,7 @@ class pdf_cyan extends ModelePDFPropales $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10); if (!$hidetop && getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { // TODO : make this hidden conf the default behavior for each PDF when each PDF managed this new Display - $tab_top_newpage+= $this->tabTitleHeight; + $tab_top_newpage += $this->tabTitleHeight; } $nexY = $tab_top; @@ -611,6 +611,7 @@ class pdf_cyan extends ModelePDFPropales } $pdf->setPageOrientation('', 0, $heightforfooter + $heightforfreetext); // The only function to edit the bottom margin of current page to set it. + // @phan-suppress-next-line PhanTypeMismatchProperty if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + $imageTopMargin, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually @@ -804,7 +805,7 @@ class pdf_cyan extends ModelePDFPropales // Add last page for document footer if there are not enough size left $afterPosData = $this->getMaxAfterColsLinePositionsData(); - if ($afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot) ) { + if ($afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot)) { $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); @@ -815,7 +816,7 @@ class pdf_cyan extends ModelePDFPropales // Draw table frames and columns borders $drawTabNumbPage = $pdf->getNumPages(); - for ($i=$pageposbeforeprintlines; $i<=$drawTabNumbPage; $i++) { + for ($i = $pageposbeforeprintlines; $i <= $drawTabNumbPage; $i++) { $pdf->setPage($i); // reset page orientation each loop to override it if it was changed $pdf->setPageOrientation('', 0, 0); // The only function to edit the bottom margin of current page to set it. @@ -830,7 +831,7 @@ class pdf_cyan extends ModelePDFPropales $drawTabTop = $tab_top; } elseif (!$drawTabHideTop) { if (getDolGlobalInt('MAIN_PDF_ENABLE_COL_HEAD_TITLE_REPEAT')) { - $drawTabTop-= $this->tabTitleHeight; + $drawTabTop -= $this->tabTitleHeight; } else { $drawTabHideTop = 1; } @@ -839,7 +840,7 @@ class pdf_cyan extends ModelePDFPropales // last page need to include document footer if ($i == $pdf->getNumPages()) { // remove document footer height to tab bottom position - $drawTabBottom-= $heightforsignature + $heightforfreetext + $heightforinfotot; + $drawTabBottom -= $heightforsignature + $heightforfreetext + $heightforinfotot; } $drawTabHeight = $drawTabBottom - $drawTabTop; @@ -895,7 +896,7 @@ class pdf_cyan extends ModelePDFPropales $pagecount = $pdf->setSourceFile($termsofsale); for ($i = 1; $i <= $pagecount; $i++) { $tplIdx = $pdf->importPage($i); - if ($tplIdx!==false) { + if ($tplIdx !== false) { $s = $pdf->getTemplatesize($tplIdx); $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L'); $pdf->useTemplate($tplIdx); @@ -937,6 +938,7 @@ class pdf_cyan extends ModelePDFPropales if (count($filetomerge->lines) > 0) { foreach ($filetomerge->lines as $linefile) { if (!empty($linefile->id) && !empty($linefile->file_name)) { + $filetomerge_dir = null; if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) { if (isModEnabled("product")) { $filetomerge_dir = $conf->product->multidir_output[$entity_product_file].'/'.get_exdir($product->id, 2, 0, 0, $product, 'product').$product->id."/photos"; @@ -951,7 +953,11 @@ class pdf_cyan extends ModelePDFPropales } } - dol_syslog(get_class($this).':: upload_dir='.$filetomerge_dir, LOG_DEBUG); + dol_syslog(get_class($this).':: upload_dir='.$filetomerge_dir, $filetomerge_dir === null ? LOG_ERR : LOG_DEBUG); + if ($filetomerge_dir === null) { + // Skip loop + continue; + } $infile = $filetomerge_dir.'/'.$linefile->file_name; if (file_exists($infile) && is_readable($infile)) { @@ -1259,11 +1265,11 @@ class pdf_cyan extends ModelePDFPropales // Total HT $pdf->SetFillColor(255, 255, 255); - $pdf->SetXY($col1x, $tab2_top+ $tab2_hl * $index); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1); $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht); - $pdf->SetXY($col2x, $tab2_top+ $tab2_hl * $index); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1); // Show VAT by rates and total @@ -1377,12 +1383,12 @@ class pdf_cyan extends ModelePDFPropales foreach ($localtax_rate as $tvakey => $tvaval) { if ($tvakey != 0) { // On affiche pas taux 0 - //$this->atleastoneratenotnull++; + //$this->atleastoneratenotnull++; - $index++; - $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $tvacompl = ''; + $tvacompl = ''; if (preg_match('/\*/', $tvakey)) { $tvakey = str_replace('*', '', $tvakey); $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; @@ -1412,12 +1418,12 @@ class pdf_cyan extends ModelePDFPropales foreach ($localtax_rate as $tvakey => $tvaval) { // retrieve global local tax if ($tvakey != 0) { // On affiche pas taux 0 - //$this->atleastoneratenotnull++; + //$this->atleastoneratenotnull++; - $index++; - $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $tvacompl = ''; + $tvacompl = ''; if (preg_match('/\*/', $tvakey)) { $tvakey = str_replace('*', '', $tvakey); $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; @@ -1555,7 +1561,7 @@ class pdf_cyan extends ModelePDFPropales //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; if (getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR')) { - $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', null, explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); + $pdf->RoundedRect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, $this->corner_radius, '1001', 'F', array(), explode(',', getDolGlobalString('MAIN_PDF_TITLE_BACKGROUND_COLOR'))); } } diff --git a/htdocs/core/modules/propale/modules_propale.php b/htdocs/core/modules/propale/modules_propale.php index f21eb694c9e..b4643a0ab69 100644 --- a/htdocs/core/modules/propale/modules_propale.php +++ b/htdocs/core/modules/propale/modules_propale.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2014 Marcos García - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -38,21 +38,68 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Requis */ abstract class ModelePDFPropales extends CommonDocGenerator { + /** + * @var float + */ public $posxpicture; + /** + * @var float + */ public $posxtva; + /** + * @var float + */ public $posxup; + /** + * @var float + */ public $posxqty; + /** + * @var float + */ public $posxunit; + /** + * @var float + */ public $posxdesc; + /** + * @var float + */ public $posxdiscount; + /** + * @var float + */ public $postotalht; + /** + * @var array + */ public $tva; + /** + * @var array + */ public $tva_array; + /** + * Local tax rates Array[tax_type][tax_rate] + * + * @var array> + */ public $localtax1; + + /** + * Local tax rates Array[tax_type][tax_rate] + * + * @var array> + */ public $localtax2; + /** + * @var int<0,1> + */ public $atleastonediscount = 0; + /** + * @var int<0,1> + */ public $atleastoneratenotnull = 0; diff --git a/htdocs/core/modules/reception/doc/pdf_squille.modules.php b/htdocs/core/modules/reception/doc/pdf_squille.modules.php index 3062ff64178..35d4e0fe107 100644 --- a/htdocs/core/modules/reception/doc/pdf_squille.modules.php +++ b/htdocs/core/modules/reception/doc/pdf_squille.modules.php @@ -1,7 +1,7 @@ * Copyright (C) 2023-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Nick Fragoulis * * This program is free software; you can redistribute it and/or modify @@ -1029,7 +1029,7 @@ class pdf_squille extends ModelePdfReception if (empty($arrayidcontact)) { $arrayidcontact = $object->origin_object->getIdContact('internal', 'SHIPPING'); } - if (count($arrayidcontact) > 0) { + if (is_array($arrayidcontact) && count($arrayidcontact) > 0) { $object->fetch_user(reset($arrayidcontact)); $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name")); $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname.": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs)); From f17ad3933bb6430b6f41ad96b42f453585016867 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 19:55:12 +0100 Subject: [PATCH 153/602] Update baseline --- dev/tools/phan/baseline.txt | 80 +++++++++++++------------------------ 1 file changed, 27 insertions(+), 53 deletions(-) diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 598f3de73fe..5da7be21753 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -12,41 +12,40 @@ return [ // PhanUndeclaredProperty : 560+ occurrences // PhanPossiblyUndeclaredGlobalVariable : 310+ occurrences // PhanUndeclaredGlobalVariable : 280+ occurrences - // PhanTypeMismatchArgumentProbablyReal : 230+ occurrences + // PhanTypeMismatchArgumentProbablyReal : 200+ occurrences // PhanPluginUnknownArrayMethodReturnType : 180+ occurrences // PhanTypeMismatchProperty : 130+ occurrences // PhanPluginUnknownArrayMethodParamType : 120+ occurrences - // PhanPluginUnknownPropertyType : 110+ occurrences - // PhanPossiblyUndeclaredVariable : 65+ occurrences + // PhanPluginUnknownPropertyType : 45+ occurrences + // PhanPossiblyUndeclaredVariable : 45+ occurrences // PhanRedefineFunction : 45+ occurrences // PhanTypeExpectedObjectPropAccess : 45+ occurrences - // PhanTypeMismatchArgumentNullableInternal : 40+ occurrences - // PhanTypeInvalidDimOffset : 30+ occurrences - // PhanTypeMismatchDimFetch : 30+ occurrences - // PhanPluginEmptyStatementIf : 15+ occurrences + // PhanTypeMismatchArgumentNullableInternal : 30+ occurrences + // PhanTypeInvalidDimOffset : 25+ occurrences + // PhanTypeMismatchDimFetch : 20+ occurrences + // PhanUndeclaredConstant : 15+ occurrences + // PhanPluginEmptyStatementIf : 10+ occurrences // PhanTypeComparisonFromArray : 10+ occurrences - // PhanTypeMismatchDimFetchNullable : 10+ occurrences // PhanUndeclaredMethod : 10+ occurrences // PhanEmptyForeach : 8 occurrences // PhanPluginUnknownObjectMethodCall : 8 occurrences // PhanPluginBothLiteralsBinaryOp : 7 occurrences - // PhanPluginDuplicateExpressionBinaryOp : 7 occurrences // PhanPluginSuspiciousParamPosition : 7 occurrences + // PhanPluginDuplicateExpressionBinaryOp : 6 occurrences // PhanTypeArraySuspiciousNull : 6 occurrences // PhanParamTooMany : 5 occurrences - // PhanPossiblyNullTypeMismatchProperty : 4 occurrences + // PhanPluginDuplicateArrayKey : 4 occurrences // PhanEmptyFQSENInClasslike : 3 occurrences // PhanInvalidFQSENInClasslike : 3 occurrences - // PhanTypeMismatchReturn : 3 occurrences + // PhanPossiblyNullTypeMismatchProperty : 3 occurrences // PhanTypeMismatchDimAssignment : 2 occurrences + // PhanTypeMismatchDimFetchNullable : 2 occurrences + // PhanTypeMismatchReturn : 2 occurrences // PhanTypeSuspiciousStringExpression : 2 occurrences - // PhanUndeclaredTypeParameter : 2 occurrences // PhanAccessMethodProtected : 1 occurrence // PhanPluginDuplicateExpressionAssignmentOperation : 1 occurrence // PhanPluginUnknownArrayPropertyType : 1 occurrence - // PhanTypeConversionFromArray : 1 occurrence // PhanTypeExpectedObjectPropAccessButGotNull : 1 occurrence - // PhanTypeMismatchArgumentInternalProbablyReal : 1 occurrence // Currently, file_suppressions and directory_suppressions are the only supported suppressions 'file_suppressions' => [ @@ -122,7 +121,7 @@ return [ 'htdocs/compta/paiement/card.php' => ['PhanUndeclaredProperty'], 'htdocs/compta/paiement/cheque/list.php' => ['PhanTypeMismatchProperty', 'PhanUndeclaredGlobalVariable'], 'htdocs/compta/paiement/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredGlobalVariable'], - 'htdocs/compta/sociales/card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredProperty'], + 'htdocs/compta/sociales/card.php' => ['PhanUndeclaredProperty'], 'htdocs/compta/tva/class/paymentvat.class.php' => ['PhanUndeclaredProperty'], 'htdocs/compta/tva/clients.php' => ['PhanTypeArraySuspiciousNull', 'PhanTypeInvalidDimOffset', 'PhanTypeMismatchProperty'], 'htdocs/compta/tva/payments.php' => ['PhanTypeMismatchArgumentNullableInternal'], @@ -143,76 +142,51 @@ return [ 'htdocs/core/class/commonsocialnetworks.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/conf.class.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchProperty'], 'htdocs/core/class/ctyperesource.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/class/cunits.class.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/class/doleditor.class.php' => ['PhanPluginDuplicateExpressionAssignmentOperation'], 'htdocs/core/class/dolgraph.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/emailsenderprofile.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/hookmanager.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/class/html.form.class.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/class/html.formcompany.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/html.formfile.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/html.formmail.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/class/ldap.class.php' => ['PhanTypeMismatchArgumentInternalProbablyReal'], 'htdocs/core/class/notify.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/class/smtps.class.php' => ['PhanTypeConversionFromArray'], 'htdocs/core/class/timespent.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'], - 'htdocs/core/customreports.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchDimFetchNullable'], - 'htdocs/core/datepicker.php' => ['PhanTypeInvalidDimOffset'], - 'htdocs/core/db/sqlite3.class.php' => ['PhanTypeMismatchReturn'], - 'htdocs/core/extrafieldsinimport.inc.php' => ['PhanTypeMismatchArgumentNullableInternal'], 'htdocs/core/lib/admin.lib.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/lib/company.lib.php' => ['PhanTypeInvalidDimOffset'], - 'htdocs/core/lib/customreports.lib.php' => ['PhanTypeMismatchDimFetch', 'PhanUndeclaredProperty'], + 'htdocs/core/lib/customreports.lib.php' => ['PhanUndeclaredProperty'], 'htdocs/core/lib/files.lib.php' => ['PhanUndeclaredProperty'], 'htdocs/core/lib/functions2.lib.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/lib/images.lib.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal'], 'htdocs/core/lib/pdf.lib.php' => ['PhanUndeclaredProperty'], 'htdocs/core/lib/project.lib.php' => ['PhanUndeclaredProperty'], 'htdocs/core/lib/xcal.lib.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/modules/asset/mod_asset_advanced.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/modules/barcode/doc/phpbarcode.modules.php' => ['PhanPossiblyNullTypeMismatchProperty', 'PhanPossiblyUndeclaredVariable'], - 'htdocs/core/modules/barcode/mod_barcode_product_standard.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/bom/mod_bom_advanced.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/modules/commande/doc/pdf_einstein.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/commande/modules_commande.php' => ['PhanPluginUnknownPropertyType'], - 'htdocs/core/modules/contract/doc/pdf_strato.modules.php' => ['PhanTypeMismatchArgumentNullableInternal'], - 'htdocs/core/modules/delivery/doc/pdf_storm.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/core/modules/delivery/doc/pdf_typhon.modules.php' => ['PhanPluginUnknownPropertyType'], + 'htdocs/core/modules/commande/doc/pdf_einstein.modules.php' => ['PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php' => ['PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/delivery/mod_delivery_saphir.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/modules/expedition/doc/pdf_merou.modules.php' => ['PhanPluginUnknownPropertyType', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php' => ['PhanPluginUnknownPropertyType', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/facture/doc/pdf_crabe.modules.php' => ['PhanPluginEmptyStatementIf', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/facture/doc/pdf_octopus.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/facture/doc/pdf_sponge.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/facture/modules_facture.php' => ['PhanPluginUnknownPropertyType'], - 'htdocs/core/modules/fichinter/mod_pacific.php' => ['PhanPossiblyUndeclaredVariable'], + 'htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/facture/doc/pdf_crabe.modules.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/facture/doc/pdf_octopus.modules.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/facture/doc/pdf_sponge.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/hrm/mod_evaluation_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/import/import_csv.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchProperty'], 'htdocs/core/modules/import/import_xlsx.modules.php' => ['PhanTypeMismatchProperty'], - 'htdocs/core/modules/mailings/contacts1.modules.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/core/modules/mailings/thirdparties.modules.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php' => ['PhanPluginDuplicateExpressionBinaryOp', 'PhanPluginEmptyStatementIf', 'PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable'], - 'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/mrp/mod_mo_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/oauth/github_oauthcallback.php' => ['PhanUndeclaredGlobalVariable'], - 'htdocs/core/modules/printing/printgcp.modules.php' => ['PhanTypeMismatchDimFetch'], - 'htdocs/core/modules/product/doc/pdf_standard.modules.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/project/doc/pdf_timespent.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/propale/doc/pdf_azur.modules.php' => ['PhanPluginEmptyStatementIf', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/propale/doc/pdf_cyan.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/propale/modules_propale.php' => ['PhanPluginUnknownPropertyType'], - 'htdocs/core/modules/reception/doc/pdf_squille.modules.php' => ['PhanTypeMismatchArgumentNullableInternal', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/propale/doc/pdf_azur.modules.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/propale/doc/pdf_cyan.modules.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/reception/doc/pdf_squille.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/societe/mod_codecompta_aquarium.php' => ['PhanPluginUnknownPropertyType'], 'htdocs/core/modules/societe/mod_codecompta_digitaria.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullableInternal'], 'htdocs/core/modules/stock/doc/pdf_standard_stock.modules.php' => ['PhanPluginUnknownPropertyType', 'PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanUndeclaredProperty'], 'htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php' => ['PhanUndeclaredProperty'], + 'htdocs/core/modules/syslog/mod_syslog_file.php' => ['PhanPluginDuplicateArrayKey'], 'htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php' => ['PhanPossiblyUndeclaredVariable'], 'htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchProperty'], 'htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php' => ['PhanPossiblyUndeclaredVariable'], @@ -272,7 +246,6 @@ return [ 'htdocs/ecm/dir_card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/ecm/index.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/emailcollector/class/emailcollector.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/emailcollector/lib/emailcollector.lib.php' => ['PhanUndeclaredTypeParameter'], 'htdocs/eventorganization/class/conferenceorboothattendee.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'], 'htdocs/eventorganization/conferenceorbooth_card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/eventorganization/conferenceorbooth_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], @@ -580,6 +553,7 @@ return [ 'htdocs/workstation/workstation_list.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/zapier/class/api_zapier.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/zapier/class/hook.class.php' => ['PhanUndeclaredProperty'], + 'internal' => ['PhanUndeclaredConstant'], ], // 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed. // (directory_suppressions will currently be ignored by subsequent calls to --save-baseline, but may be preserved in future Phan releases) From b1c88fd248699ddea8a4b9515d968bf5a0897450 Mon Sep 17 00:00:00 2001 From: Jyhere Date: Fri, 24 Jan 2025 11:52:29 +0100 Subject: [PATCH 154/602] FIX: when vat setting in on payment date and FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is set, vat lines are incompletes --- htdocs/core/lib/tax.lib.php | 42 +++---------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/htdocs/core/lib/tax.lib.php b/htdocs/core/lib/tax.lib.php index ed5586ff29d..0050910fced 100644 --- a/htdocs/core/lib/tax.lib.php +++ b/htdocs/core/lib/tax.lib.php @@ -438,19 +438,7 @@ function tax_by_thirdparty($type, $db, $y, $date_start, $date_end, $modetax, $di $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid"; $sql .= " WHERE f.entity IN (".getEntity($invoicetable).")"; $sql .= " AND f.fk_statut in (1,2)"; // Paid (partially or completely) - if ($direction == 'buy') { - if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { - $sql .= " AND f.type IN (0,1,2,5)"; - } else { - $sql .= " AND f.type IN (0,1,2,3,5)"; - } - } else { - if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) { - $sql .= " AND f.type IN (0,1,2,5)"; - } else { - $sql .= " AND f.type IN (0,1,2,3,5)"; - } - } + $sql .= " AND f.type IN (0,1,2,3,5)"; $sql .= " AND f.rowid = d.".$fk_facture; $sql .= " AND s.rowid = f.fk_soc"; $sql .= " AND pf.".$fk_facture2." = f.rowid"; @@ -825,19 +813,7 @@ function tax_by_rate($type, $db, $y, $q, $date_start, $date_end, $modetax, $dire $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid"; $sql .= " WHERE f.entity IN (".getEntity($invoicetable).")"; $sql .= " AND f.fk_statut in (1,2)"; // Paid (partially or completely) - if ($direction == 'buy') { - if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { - $sql .= " AND f.type IN (0,1,2,5)"; - } else { - $sql .= " AND f.type IN (0,1,2,3,5)"; - } - } else { - if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) { - $sql .= " AND f.type IN (0,1,2,5)"; - } else { - $sql .= " AND f.type IN (0,1,2,3,5)"; - } - } + $sql .= " AND f.type IN (0,1,2,3,5)"; if ($y && $m) { $sql .= " AND pa.datep >= '".$db->idate(dol_get_first_day($y, $m, false))."'"; $sql .= " AND pa.datep <= '".$db->idate(dol_get_last_day($y, $m, false))."'"; @@ -1026,19 +1002,7 @@ function tax_by_rate($type, $db, $y, $q, $date_start, $date_end, $modetax, $dire $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid"; $sql .= " WHERE f.entity IN (".getEntity($invoicetable).")"; $sql .= " AND f.fk_statut in (1,2)"; // Paid (partially or completely) - if ($direction == 'buy') { - if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { - $sql .= " AND f.type IN (0,1,2,5)"; - } else { - $sql .= " AND f.type IN (0,1,2,3,5)"; - } - } else { - if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) { - $sql .= " AND f.type IN (0,1,2,5)"; - } else { - $sql .= " AND f.type IN (0,1,2,3,5)"; - } - } + $sql .= " AND f.type IN (0,1,2,3,5)"; if ($y && $m) { $sql .= " AND pa.datep >= '".$db->idate(dol_get_first_day($y, $m, false))."'"; $sql .= " AND pa.datep <= '".$db->idate(dol_get_last_day($y, $m, false))."'"; From 75db8061027376a07093d3dac991406d00a91d8d Mon Sep 17 00:00:00 2001 From: ATM-Lucas Date: Fri, 24 Jan 2025 12:23:08 +0100 Subject: [PATCH 155/602] Adding sending mails on product --- htdocs/core/tpl/card_presend.tpl.php | 5 +++++ htdocs/product/card.php | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index d29932c2c20..9a5a12be721 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -115,6 +115,11 @@ if ($action == 'presend') { } if ($forcebuilddoc) { // If there is no default value for supplier invoice, we do not generate file, even if modelpdf was set by a manual generation if ((!$file || !is_readable($file)) && method_exists($object, 'generateDocument')) { + + $hidedetails = $hidedetails?$hidedetails:''; + $hidedesc = $hidedetails?$hidedetails:''; + $hideref = $hidedetails?$hidedetails:''; + $result = $object->generateDocument(GETPOST('model') ? GETPOST('model') : $object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); if ($result < 0) { dol_print_error($db, $object->error, $object->errors); diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 5de9cda0342..bcbe53236c5 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1295,6 +1295,14 @@ if (empty($reshook)) { setEventMessages($langs->trans("WarningSelectOneDocument"), null, 'warnings'); } } + + // Actions to send emails + $triggersendname = 'PRODUCT_SENTBYMAIL'; + $paramname = 'id'; + $autocopy = 'MAIN_MAIL_AUTOCOPY_PRODUCT_TO'; + $trackid = 'prod'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + } @@ -3027,6 +3035,9 @@ if ($action != 'create' && $action != 'edit') { print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id, '', $usercancreate); } + //Send + print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init&token=' . newToken() . '#formmailbeforetitle'); + if (!isset($hookmanager->resArray['no_button_copy']) || $hookmanager->resArray['no_button_copy'] != 1) { if (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile)) { $cloneProductUrl = ''; @@ -3198,6 +3209,15 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete') { $somethingshown = $formactions->showactions($object, 'product', 0, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for product print ''; + + // Presend form + $modelmail = 'product_send'; // Modèle d'e-mail pour les produits + $defaulttopic = $object->label; // Sujet par défaut + $diroutput = $conf->product->multidir_output[$object->entity]; // Répertoire de sortie + $trackid = 'prod' . $object->id; // ID de suivi + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; + } // End of page From ba6f80c307be59843ee1354d16fe12ca4685e592 Mon Sep 17 00:00:00 2001 From: ATM-Lucas Date: Fri, 24 Jan 2025 12:24:43 +0100 Subject: [PATCH 156/602] comm --- htdocs/product/card.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index bcbe53236c5..1efadc81fbf 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -3211,10 +3211,10 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete') { print ''; // Presend form - $modelmail = 'product_send'; // Modèle d'e-mail pour les produits - $defaulttopic = $object->label; // Sujet par défaut - $diroutput = $conf->product->multidir_output[$object->entity]; // Répertoire de sortie - $trackid = 'prod' . $object->id; // ID de suivi + $modelmail = 'product_send'; + $defaulttopic = $object->label; + $diroutput = $conf->product->multidir_output[$object->entity]; + $trackid = 'prod' . $object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; From 81b0ff4ebf7c510fc9d81d24790c035da4a11a1f Mon Sep 17 00:00:00 2001 From: Dolibot Date: Fri, 24 Jan 2025 12:06:49 +0000 Subject: [PATCH 157/602] PHPStan > Update baseline --- dev/build/phpstan/phpstan-baseline.neon | 234 ------------------------ 1 file changed, 234 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index ff60a067420..51aaca26db7 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -10734,36 +10734,12 @@ parameters: count: 1 path: ../../../htdocs/core/customreports.php - - - message: '#^Variable \$gval might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/customreports.php - - message: '#^Variable \$page might not be defined\.$#' identifier: variable.undefined count: 1 path: ../../../htdocs/core/customreports.php - - - message: '#^Variable \$search_graph might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../../htdocs/core/customreports.php - - - - message: '#^Variable \$search_groupby might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/core/customreports.php - - - - message: '#^Variable \$search_xaxis might not be defined\.$#' - identifier: variable.undefined - count: 5 - path: ../../../htdocs/core/customreports.php - - message: '#^Variable \$search_yaxis might not be defined\.$#' identifier: variable.undefined @@ -10782,12 +10758,6 @@ parameters: count: 1 path: ../../../htdocs/core/customreports.php - - - message: '#^Variable \$tabfamily might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../../htdocs/core/customreports.php - - message: '#^Constructor of class DoliDBMysqli has an unused parameter \$type\.$#' identifier: constructor.unusedParameter @@ -10866,12 +10836,6 @@ parameters: count: 1 path: ../../../htdocs/core/db/sqlite3.class.php - - - message: '#^Method DoliDBSqlite3\:\:getListOfCollation\(\) should return array\\|null but returns array\{array\{charset\: ''UTF\-8'', description\: ''UTF\-8''\}\}\.$#' - identifier: return.type - count: 1 - path: ../../../htdocs/core/db/sqlite3.class.php - - message: '#^Cannot access property \$db on mixed\.$#' identifier: property.nonObject @@ -11424,12 +11388,6 @@ parameters: count: 3 path: ../../../htdocs/core/lib/images.lib.php - - - message: '#^Variable \$extImg might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/lib/images.lib.php - - message: '#^Loose comparison using \=\= between ''suppliers'' and ''fourn'' will always evaluate to false\.$#' identifier: equal.alwaysFalse @@ -12150,12 +12108,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php - - - message: '#^Variable \$carac_client_name might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php - - message: '#^Call to function is_object\(\) with object will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -12198,12 +12150,6 @@ parameters: count: 2 path: ../../../htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php - - - message: '#^Variable \$result might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/barcode/doc/phpbarcode.modules.php - - message: '#^Property modTcpdfbarcode\:\:\$is2d has no type specified\.$#' identifier: missingType.property @@ -12216,18 +12162,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/barcode/mod_barcode_product_standard.php - - - message: '#^Property mod_barcode_product_standard\:\:\$numbitcounter has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/barcode/mod_barcode_product_standard.php - - - - message: '#^Property mod_barcode_product_standard\:\:\$searchcode has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/barcode/mod_barcode_product_standard.php - - message: '#^Parameter \#2 \$type of method mod_barcode_thirdparty_standard\:\:literalBarcodeType\(\) expects int, string given\.$#' identifier: argument.type @@ -12336,12 +12270,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 1 - path: ../../../htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php - - message: '#^Property Commande\:\:\$availability \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -12450,18 +12378,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php - - - message: '#^Variable \$carac_client_name might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php - - - - message: '#^Variable \$realpath might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php - - message: '#^Parameter \#1 \$object of method CommonDocGenerator\:\:get_substitutionarray_each_var_object\(\) expects array\, Contrat given\.$#' identifier: argument.type @@ -12498,12 +12414,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/delivery/doc/pdf_storm.modules.php - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 1 - path: ../../../htdocs/core/modules/delivery/doc/pdf_storm.modules.php - - message: '#^Parameter \#3 \$posy of method pdf_storm\:\:_tableau_info\(\) expects int, float given\.$#' identifier: argument.type @@ -12558,12 +12468,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/delivery/doc/pdf_storm.modules.php - - - message: '#^Variable \$realpath might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/delivery/doc/pdf_storm.modules.php - - message: '#^Call to function is_object\(\) with object will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -12582,24 +12486,6 @@ parameters: count: 2 path: ../../../htdocs/core/modules/delivery/doc/pdf_typhon.modules.php - - - message: '#^Property pdf_typhon\:\:\$posxcomm has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/delivery/doc/pdf_typhon.modules.php - - - - message: '#^Property pdf_typhon\:\:\$posxremainingqty has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/delivery/doc/pdf_typhon.modules.php - - - - message: '#^Property pdf_typhon\:\:\$posxweightvol has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/delivery/doc/pdf_typhon.modules.php - - message: '#^Call to function is_object\(\) with object will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -12720,24 +12606,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/expedition/doc/pdf_merou.modules.php - - - message: '#^Property pdf_merou\:\:\$destinataire has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/expedition/doc/pdf_merou.modules.php - - - - message: '#^Property pdf_merou\:\:\$expediteur has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/expedition/doc/pdf_merou.modules.php - - - - message: '#^Property pdf_merou\:\:\$livreur has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/expedition/doc/pdf_merou.modules.php - - message: '#^Parameter \#4 \$posy of method pdf_rouget\:\:_tableau_tot\(\) expects int, float given\.$#' identifier: argument.type @@ -12768,36 +12636,6 @@ parameters: count: 6 path: ../../../htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php - - - message: '#^Property pdf_standard_expensereport\:\:\$postotalttc has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php - - - - message: '#^Property pdf_standard_expensereport\:\:\$posxcomment has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php - - - - message: '#^Property pdf_standard_expensereport\:\:\$posxpiece has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php - - - - message: '#^Property pdf_standard_expensereport\:\:\$posxprojet has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php - - - - message: '#^Property pdf_standard_expensereport\:\:\$posxtype has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php - - message: '#^Ternary operator condition is always false\.$#' identifier: ternary.alwaysFalse @@ -12900,12 +12738,6 @@ parameters: count: 13 path: ../../../htdocs/core/modules/facture/doc/pdf_octopus.modules.php - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 1 - path: ../../../htdocs/core/modules/facture/doc/pdf_octopus.modules.php - - message: '#^Parameter \#1 \$a of method pdf_octopus\:\:sumSituation\(\) expects array\\|float\|int\>, array\ given\.$#' identifier: argument.type @@ -13068,12 +12900,6 @@ parameters: count: 3 path: ../../../htdocs/core/modules/facture/doc/pdf_octopus.modules.php - - - message: '#^Variable \$realpath might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/facture/doc/pdf_octopus.modules.php - - message: '#^Call to function is_object\(\) with object will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -13086,12 +12912,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/facture/doc/pdf_sponge.modules.php - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 1 - path: ../../../htdocs/core/modules/facture/doc/pdf_sponge.modules.php - - message: '#^Property CommonInvoice\:\:\$type \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -13212,12 +13032,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/facture/doc/pdf_sponge.modules.php - - - message: '#^Variable \$realpath might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/facture/doc/pdf_sponge.modules.php - - message: '#^Property mod_facture_mars\:\:\$prefixcreditnote has no type specified\.$#' identifier: missingType.property @@ -13296,12 +13110,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php - - - message: '#^Variable \$max might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/fichinter/mod_pacific.php - - message: '#^Property CommonObject\:\:\$entity \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -14094,36 +13902,6 @@ parameters: count: 2 path: ../../../htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php - - - message: '#^Property pdf_standard_movementstock\:\:\$posxdatemouv has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php - - - - message: '#^Property pdf_standard_movementstock\:\:\$posxidref has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php - - - - message: '#^Property pdf_standard_movementstock\:\:\$wref has no type specified\.$#' - identifier: missingType.property - count: 1 - path: ../../../htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php - - - - message: '#^Variable \$lastmovementdate might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php - - - - message: '#^Variable \$result might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php - - message: '#^Parameter \#1 \$object of method CommonDocGenerator\:\:get_substitutionarray_each_var_object\(\) expects array\, Mo given\.$#' identifier: argument.type @@ -14526,12 +14304,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/propale/doc/pdf_azur.modules.php - - - message: '#^Variable \$filetomerge_dir might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/core/modules/propale/doc/pdf_azur.modules.php - - message: '#^Call to function is_object\(\) with object will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -14646,12 +14418,6 @@ parameters: count: 1 path: ../../../htdocs/core/modules/propale/doc/pdf_cyan.modules.php - - - message: '#^Variable \$filetomerge_dir might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/core/modules/propale/doc/pdf_cyan.modules.php - - message: '#^Call to function is_object\(\) with object will always evaluate to true\.$#' identifier: function.alreadyNarrowedType From 697a9fc59961107e509f0e3d21aed212f07cc06c Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 24 Jan 2025 13:12:48 +0100 Subject: [PATCH 158/602] Finish cleaning v21 of the setup pages --- htdocs/admin/accountant.php | 2 +- htdocs/admin/bank.php | 4 +-- htdocs/admin/barcode.php | 2 +- htdocs/admin/bom.php | 2 +- htdocs/admin/clicktodial.php | 4 +-- htdocs/admin/company.php | 2 +- htdocs/admin/contract.php | 2 +- htdocs/admin/dav.php | 4 +-- htdocs/admin/debugbar.php | 2 +- htdocs/admin/delais.php | 8 +++--- htdocs/admin/delivery.php | 2 +- htdocs/admin/ecm.php | 2 +- htdocs/admin/eventorganization.php | 4 +-- htdocs/admin/fichinter.php | 2 +- htdocs/admin/geoipmaxmind.php | 2 +- htdocs/admin/holiday.php | 20 +-------------- htdocs/admin/hrm.php | 4 +-- htdocs/admin/invoice.php | 4 +-- htdocs/admin/knowledgemanagement.php | 4 +-- htdocs/admin/ldap.php | 2 +- htdocs/admin/limits.php | 4 +-- htdocs/admin/mailing.php | 2 +- htdocs/admin/mails_ingoing.php | 2 +- htdocs/admin/mrp.php | 2 +- htdocs/admin/notification.php | 2 +- htdocs/admin/openinghours.php | 14 +++++------ htdocs/admin/order.php | 2 +- htdocs/admin/payment.php | 2 +- htdocs/admin/paymentbybanktransfer.php | 4 +-- htdocs/admin/pdf.php | 4 +-- htdocs/admin/pdf_other.php | 34 +++++++++----------------- htdocs/admin/prelevement.php | 4 +-- htdocs/admin/resource.php | 2 +- htdocs/admin/sms.php | 4 +-- htdocs/admin/stock.php | 2 +- htdocs/admin/stocktransfer.php | 4 +-- htdocs/admin/supplier_invoice.php | 2 +- htdocs/admin/supplier_order.php | 2 +- htdocs/admin/supplier_payment.php | 2 +- htdocs/admin/syslog.php | 4 +-- htdocs/admin/taxes.php | 2 +- htdocs/admin/webhook.php | 4 +-- htdocs/admin/website_options.php | 2 +- htdocs/admin/workstation.php | 4 +-- htdocs/core/class/conf.class.php | 9 ++++++- 45 files changed, 88 insertions(+), 109 deletions(-) diff --git a/htdocs/admin/accountant.php b/htdocs/admin/accountant.php index 0dbe9d5dc4c..174e71a7516 100644 --- a/htdocs/admin/accountant.php +++ b/htdocs/admin/accountant.php @@ -127,7 +127,7 @@ print ''; print ''; print '
'.$langs->trans("MailTopic").'

*** Clean table ecm_files from lines of entries whose physical files does not exists anymore (emplemented for entity 1 only)
Found line with id '.$obj->rowid.', entity '.$obj->entity.', file "'.$filetocheck.'" to delete'; + if (GETPOST('clean_ecm_files_table', 'alpha') == 'confirmed') { + $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."ecm_files WHERE rowid = ".((int) $obj->rowid); + $resqldelete = $db->query($sqldelete); + if (!$resqldelete) { + dol_print_error($db); + } + print ' - deleted'; + } + print '
There is more than '.$MAXTODELETE.' invalid entries into ecm_files index table (among '.$nbfile.' analyzed) with no valid physical files. Run the page several time to process all of them.
Nb of entries processed into ecm_files index table: '.$nbfile.', number of invalid record: '.$nbfiletodelete.'
Found line with id '.$obj->rowid.', entity '.$obj->entity.', file "'.$filetocheck.'" to delete'; - if (GETPOST('clean_ecm_files_table', 'alpha') == 'confirmed') { - $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."ecm_files WHERE rowid = ".((int) $obj->rowid); - $resqldelete = $db->query($sqldelete); - if (!$resqldelete) { - dol_print_error($db); + if ($nbfiletodelete <= $MAXTODELETE) { + print '
Found line with id '.$obj->rowid.', entity '.$obj->entity.', file "'.$filetocheck.'" to delete'; + if (GETPOST('clean_ecm_files_table', 'alpha') == 'confirmed') { + $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."ecm_files WHERE rowid = ".((int) $obj->rowid); + $resqldelete = $db->query($sqldelete); + if (!$resqldelete) { + dol_print_error($db); + } + print ' - deleted'; } - print ' - deleted'; + print '
Found line with id '.$obj->rowid.', entity '.$obj->entity.', file "'.$filetocheck.'" to delete'; From 1ef30c3006081ab67f6ebc63df38a49f795d188f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 23 Jan 2025 21:59:04 +0100 Subject: [PATCH 125/602] fix --- htdocs/adherents/class/api_memberstypes.class.php | 3 ++- htdocs/loan/note.php | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index 32e9e105fa2..ce8f2457f66 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2025 Frédéric France * * 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 @@ -28,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; class MembersTypes extends DolibarrApi { /** - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var string[] $FIELDS Mandatory fields, checked when create and update object */ public static $FIELDS = array( 'label', diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php index 9bc1da5c0a9..3fa7c606d83 100644 --- a/htdocs/loan/note.php +++ b/htdocs/loan/note.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2007 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry - * Copyright (C) 2015-2024 Frédéric France + * Copyright (C) 2015-2025 Frédéric France * Copyright (C) 2016-2025 Alexandre Spangaro * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2024 MDW @@ -84,9 +84,6 @@ if (empty($reshook)) { $morehtmlright = ''; $form = new Form($db); -if (isModEnabled('project')) { - $formproject = new FormProjets($db); -} $title = $langs->trans("Loan").' - '.$langs->trans("Notes"); $help_url = 'EN:Module_Loan|FR:Module_Emprunt'; @@ -109,6 +106,7 @@ if ($id > 0) { $morehtmlref .= $form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1); // Project if (isModEnabled('project')) { + $formproject = new FormProjets($db); $langs->loadLangs(array("projects")); $morehtmlref .= '
'.$langs->trans('Project').' : '; if ($user->hasRight('loan', 'write')) { From 5c616a2812b551845a5731b0fdbd84f7bcc6e9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 23 Jan 2025 22:01:57 +0100 Subject: [PATCH 126/602] fix --- htdocs/adherents/class/api_memberstypes.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index ce8f2457f66..fc230bbaf41 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -29,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; class MembersTypes extends DolibarrApi { /** - * @var string[] $FIELDS Mandatory fields, checked when create and update object + * @var string[] Mandatory fields, checked when create and update object */ public static $FIELDS = array( 'label', From db128814b566feddaeea7ed6f104d52745bfc3e4 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 22:13:19 +0100 Subject: [PATCH 127/602] Debug v21 --- htdocs/theme/eldy/info-box.inc.php | 8 ++++---- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/info-box.inc.php | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index 44f1ff7ddd8..24f981291a5 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -329,10 +329,10 @@ if (getDolGlobalString('THEME_INFOBOX_COLOR_ON_BACKGROUND')) { } if (!isset($conf->global->THEME_SATURATE_RATIO)) { - $conf->global->THEME_SATURATE_RATIO = 0.7; + $conf->global->THEME_SATURATE_RATIO = 0.8; } if (GETPOSTISSET('THEME_SATURATE_RATIO')) { - $conf->global->THEME_SATURATE_RATIO = GETPOSTINT('THEME_SATURATE_RATIO'); + $conf->global->THEME_SATURATE_RATIO = GETPOSTFLOAT('THEME_SATURATE_RATIO'); } ?> @@ -341,8 +341,8 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) { color: #fff !important; opacity: 0.95; - global->THEME_SATURATE_RATIO)) { ?> - filter: saturate(global->THEME_SATURATE_RATIO; ?>); + + filter: saturate(); } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 9ce2b990fcd..4fad79772c3 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -411,7 +411,7 @@ print 'fontsizesmaller='.$fontsizesmaller."\n"; print 'topMenuFontSize='.$topMenuFontSize."\n"; print 'toolTipBgColor='.$toolTipBgColor."\n"; print 'toolTipFontColor='.$toolTipFontColor."\n"; -print 'conf->global->THEME_SATURATE_RATIO='.getDolGlobalString('THEME_SATURATE_RATIO')." (must be between 0 and 1)\n"; +print 'getDolGlobalString("THEME_SATURATE_RATIO")='.getDolGlobalString('THEME_SATURATE_RATIO')." (must be between 0 and 1)\n"; print '*/'."\n"; diff --git a/htdocs/theme/md/info-box.inc.php b/htdocs/theme/md/info-box.inc.php index f2afc753cf4..a0588f5656b 100644 --- a/htdocs/theme/md/info-box.inc.php +++ b/htdocs/theme/md/info-box.inc.php @@ -34,10 +34,10 @@ if (getDolGlobalString('THEME_INFOBOX_COLOR_ON_BACKGROUND')) { } if (!isset($conf->global->THEME_SATURATE_RATIO)) { - $conf->global->THEME_SATURATE_RATIO = 0.7; + $conf->global->THEME_SATURATE_RATIO = 0.8; } if (GETPOSTISSET('THEME_SATURATE_RATIO')) { - $conf->global->THEME_SATURATE_RATIO = GETPOSTINT('THEME_SATURATE_RATIO'); + $conf->global->THEME_SATURATE_RATIO = GETPOSTFLOAT('THEME_SATURATE_RATIO'); } ?> @@ -241,8 +241,8 @@ a.info-box-text-a i.fa.fa-exclamation-triangle { height: 94px; /* must be same height as min-height of .info-box */ width: 86px; background: var(--colorbacktitle1) !important; - global->THEME_SATURATE_RATIO)) { ?> - filter: saturate(global->THEME_SATURATE_RATIO; ?>); + + filter: saturate(); } @@ -459,10 +459,10 @@ if (getDolGlobalString('THEME_INFOBOX_COLOR_ON_BACKGROUND')) { } if (!isset($conf->global->THEME_SATURATE_RATIO)) { - $conf->global->THEME_SATURATE_RATIO = 0.7; + $conf->global->THEME_SATURATE_RATIO = 0.8; } if (GETPOSTISSET('THEME_SATURATE_RATIO')) { - $conf->global->THEME_SATURATE_RATIO = GETPOSTINT('THEME_SATURATE_RATIO'); + $conf->global->THEME_SATURATE_RATIO = GETPOSTFLOAT('THEME_SATURATE_RATIO'); } ?> .bg-infobox-project i.fa{ From 622a655a3c65b4ede7fd30875e5b0cd1ad526ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 23 Jan 2025 22:15:11 +0100 Subject: [PATCH 128/602] fix --- .../adherents/class/api_memberstypes.class.php | 16 ++++++++++++---- htdocs/core/class/conf.class.php | 6 +++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index fc230bbaf41..9d0c1ebfd7e 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -85,6 +85,8 @@ class MembersTypes extends DolibarrApi * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.libelle:like:'SO-%') and (t.subscription:=:'1')" * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names * @return array Array of member type objects + * @phan-return AdherentType[] + * @phpstan-return AdherentType[] * * @throws RestException */ @@ -144,7 +146,9 @@ class MembersTypes extends DolibarrApi /** * Create member type object * - * @param array $request_data Request data + * @param array $request_data Request data + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return int ID of member type */ public function post($request_data = null) @@ -176,7 +180,9 @@ class MembersTypes extends DolibarrApi * * @param int $id ID of member type to update * @param array $request_data Datas - * @return int + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data + * @return Object */ public function put($id, $request_data = null) { @@ -228,6 +234,8 @@ class MembersTypes extends DolibarrApi * * @param int $id member type ID * @return array + * @phan-return array + * @phpstan-return array */ public function delete($id) { @@ -262,8 +270,8 @@ class MembersTypes extends DolibarrApi /** * Validate fields before creating an object * - * @param array|null $data Data to validate - * @return array + * @param ?array $data Data to validate + * @return array * * @throws RestException */ diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index f6f452062c1..fe27db7061e 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2004-2020 Laurent Destailleur * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2006 Jean Heimburger - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * * 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 @@ -1197,10 +1197,10 @@ class Conf extends stdClass // For modules that want to disable top or left menu if (!empty($this->global->MAIN_HIDE_TOP_MENU)) { - $this->dol_hide_topmenu = getDolGlobalString('MAIN_HIDE_TOP_MENU'); + $this->dol_hide_topmenu = getDolGlobalInt('MAIN_HIDE_TOP_MENU'); } if (!empty($this->global->MAIN_HIDE_LEFT_MENU)) { - $this->dol_hide_leftmenu = getDolGlobalString('MAIN_HIDE_LEFT_MENU'); + $this->dol_hide_leftmenu = getDolGlobalInt('MAIN_HIDE_LEFT_MENU'); } if (empty($this->global->MAIN_SIZE_SHORTLIST_LIMIT)) { From b6390f959cdaf47676fd7a806d7f9a718fd6ab7e Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 22:19:39 +0100 Subject: [PATCH 129/602] Add slugify function for security purpose --- htdocs/core/lib/functions.lib.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 459bc021b4d..e436c45cfb5 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1874,6 +1874,33 @@ function dol_string_nounprintableascii($str, $removetabcrlf = 1) } } +/** + * Returns text slugified (no special char, separator is "-". + * + * @param string $stringtoslugify String to slugify + * @return string Slugified string + */ +function dolSlugify($stringtoslugify) +{ + $slug = dol_string_unaccent($stringtoslugify); + + // Convert special characters to their ASCII equivalents + if (function_exists('iconv')) { + $slug = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $slug); + } + + // Convert to lowercase + $slug = strtolower($slug); + + // Replace non-alphanumeric characters with hyphens + $slug = preg_replace('/[^a-z0-9]+/', '-', $slug); + + // Remove leading and trailing hyphens + $slug = trim($slug, '-'); + + return $slug; +} + /** * Returns text escaped for inclusion into javascript code * From 9ea11cabf7ea7296a674c2ddcf54aee1b82ada13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 23 Jan 2025 22:26:02 +0100 Subject: [PATCH 130/602] fix --- .../triggers/interface_50_modTicket_TicketEmail.class.php | 5 +++-- htdocs/public/payment/paymentok.php | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index 40cd8f49827..d077ff607c1 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -4,6 +4,7 @@ * 2016 Christophe Battarel * Copyright (C) 2023 Benjamin Falière * Copyright (C) 2024 MDW + * Copyright (C) 2025 Frédéric France * * 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 @@ -178,6 +179,7 @@ class InterfaceTicketEmail extends DolibarrTriggers if (!getDolGlobalString('TICKET_DISABLE_ALL_MAILS')) { // Send email to assigned user $sendto = $userstat->email; + $old_MAIN_MAIL_AUTOCOPY_TO = ''; if (!getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; @@ -192,8 +194,7 @@ class InterfaceTicketEmail extends DolibarrTriggers } } } else { - $this->error = $userstat->error; - $this->errors = $userstat->errors; + $this->setErrorsFromObject($userstat); } } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 1c0d5a61aea..aa46e7ccf0b 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -169,7 +169,6 @@ $ErrorCode = $ErrorShortMsg = $ErrorLongMsg = $ErrorSeverityCode = ''; $object = new stdClass(); // For triggers -/** @var CommonObject $object */ $error = 0; From 6fdb20902df842f49a2b7c52c141f74406b06973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 23 Jan 2025 22:31:21 +0100 Subject: [PATCH 131/602] fix --- build/phpstan/phpstan-baseline.neon | 50 ++++------------------------- 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index c850e576f25..260f9b768c0 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -5457,7 +5457,7 @@ parameters: - message: '#^Variable \$i might not be defined\.$#' identifier: variable.undefined - count: 4 + count: 3 path: ../../htdocs/compta/facture/card.php - @@ -6582,12 +6582,6 @@ parameters: count: 1 path: ../../htdocs/compta/sociales/card.php - - - message: '#^Variable \$resteapayer might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../htdocs/compta/sociales/card.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue @@ -9096,12 +9090,6 @@ parameters: count: 1 path: ../../htdocs/core/class/commonobject.class.php - - - message: '#^Parameter \#17 \$pa_ht of method Commande\:\:updateline\(\) expects int, float given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/core/class/commonobject.class.php - - message: '#^Parameter \#2 \$line of method CommonObject\:\:printObjectLine\(\) expects CommonObjectLine, CommonObject\|stdClass given\.$#' identifier: argument.type @@ -20244,12 +20232,6 @@ parameters: count: 2 path: ../../htdocs/fourn/commande/dispatch.php - - - message: '#^Variable \$reception might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/fourn/commande/dispatch.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -22854,12 +22836,6 @@ parameters: count: 2 path: ../../htdocs/loan/class/loanschedule.class.php - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 1 - path: ../../htdocs/loan/class/paymentloan.class.php - - message: '#^Property PaymentLoan\:\:\$amount_capital \(float\|int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -28734,12 +28710,6 @@ parameters: count: 16 path: ../../htdocs/public/webportal/webportal.main.inc.php - - - message: '#^Variable \$logged_partnership might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/public/webportal/webportal.main.inc.php - - message: '#^Negated boolean expression is always false\.$#' identifier: booleanNot.alwaysFalse @@ -30315,7 +30285,7 @@ parameters: - message: '#^Ternary operator condition is always true\.$#' identifier: ternary.alwaysTrue - count: 4 + count: 3 path: ../../htdocs/societe/card.php - @@ -32581,14 +32551,14 @@ parameters: path: ../../htdocs/variants/class/ProductAttributeValue.class.php - - message: '#^Loose comparison using \!\= between ''ErrorProductAlready…'' and ''ErrorProductAlready…'' will always evaluate to false\.$#' - identifier: notEqual.alwaysFalse + message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' + identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/variants/class/ProductCombination.class.php - - message: '#^Negated boolean expression is always false\.$#' - identifier: booleanNot.alwaysFalse + message: '#^Loose comparison using \!\= between ''ErrorProductAlready…'' and ''ErrorProductAlready…'' will always evaluate to false\.$#' + identifier: notEqual.alwaysFalse count: 1 path: ../../htdocs/variants/class/ProductCombination.class.php @@ -33289,7 +33259,7 @@ parameters: path: ../../htdocs/website/index.php - - message: '#^Comparison operation "\>\=" between 1 and 0 is always true\.$#' + message: '#^Comparison operation "\>\=" between 0\|1 and 0 is always true\.$#' identifier: greaterOrEqual.alwaysTrue count: 1 path: ../../htdocs/website/samples/wrapper.php @@ -33297,12 +33267,6 @@ parameters: - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse - count: 3 - path: ../../htdocs/website/samples/wrapper.php - - - - message: '#^If condition is always true\.$#' - identifier: if.alwaysTrue count: 1 path: ../../htdocs/website/samples/wrapper.php From 48190b39de0a80f8a6335277de6ca1342568c695 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 23:26:59 +0100 Subject: [PATCH 132/602] Debug v21 --- htdocs/societe/class/societeaccount.class.php | 10 +++++++ htdocs/societe/website.php | 14 ++++----- htdocs/website/class/website.class.php | 30 +++++++++++-------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php index e97ec89d8fa..47207ec2fda 100644 --- a/htdocs/societe/class/societeaccount.class.php +++ b/htdocs/societe/class/societeaccount.class.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + /** * Class for SocieteAccount */ @@ -257,6 +258,15 @@ class SocieteAccount extends CommonObject */ public function create(User $user, $notrigger = 0) { + global $langs; + + if ($this->site == 'dolibarr_website') { + if ((int) $this->fk_website <= 0) { + $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Website")); + return -1; + } + } + return $this->createCommon($user, $notrigger); } diff --git a/htdocs/societe/website.php b/htdocs/societe/website.php index 4ed8e18f7d6..1fa3b0678f7 100644 --- a/htdocs/societe/website.php +++ b/htdocs/societe/website.php @@ -35,6 +35,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php'; +require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; @@ -684,15 +685,14 @@ while ($i < $imaxinloop) { print ' title="'.dol_escape_htmltag($object->$key).'"'; } print '>'; - /*if ($key == 'status') { - print $objectwebsiteaccount->getLibStatut(5); - } elseif ($key == 'rowid') { - print $objectwebsiteaccount->showOutputField($val, $key, $object->id, ''); - } else { - print $objectwebsiteaccount->showOutputField($val, $key, $object->$key, ''); - }*/ if ($key == 'login') { print $objectwebsiteaccount->getNomUrl(1, '', 0, '', 1); + } elseif ($key == 'fk_website') { + if ($obj->$key > 0) { + $tmpwebsite = new Website($db); + $tmpwebsite->fetch($obj->$key); + print $tmpwebsite->getNomUrl(1); + } } else { print $objectwebsiteaccount->showOutputField($val, $key, $obj->$key, ''); } diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 98fe79aa763..a95a2d84463 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -901,25 +901,31 @@ class Website extends CommonObject $result = ''; - $label = ''.$langs->trans("WebSite").''; + $label = ''.img_picto('', 'website', 'class="pictofixedwidth"').$langs->trans("WebSite").''; $label .= '
'; $label .= ''.$langs->trans('Ref').': '.$this->ref.'
'; $label .= ''.$langs->trans('MainLanguage').': '.$this->lang; - $linkstart = 'picto ? $this->picto : 'generic'), ($notooltip ? '' : 'class="classfortooltip"')).$linkend); - if ($withpicto != 2) { - $result .= ' '; - } + */ + if (!empty($this->virtualhost)) { + $linkstart = ''; + $linkend = ''; + } else { + $linkstart = $linkend = ''; } - $result .= $linkstart.$this->ref.$linkend; + + $result .= $linkstart; + if ($withpicto) { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), 'class="pictofixedwidth'.($notooltip ? '' : ' classfortooltip').'"'); + } + $result .= $this->ref; + $result .= $linkend; + return $result; } From 58b9fac4b51dac17907df3331225f36b7d65a148 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 23 Jan 2025 23:41:51 +0100 Subject: [PATCH 133/602] Fix sort on natural order --- htdocs/core/class/html.formfile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 00c1a3bf98e..c95f857a4a9 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1437,7 +1437,7 @@ class FormFile //var_dump($sortfield.' - '.$sortorder); if ($sortfield && $sortorder) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) - $filearray = dol_sort_array($filearray, $sortfield, $sortorder); + $filearray = dol_sort_array($filearray, $sortfield, $sortorder, 1); } } From f649f59cb9258bc7695938d761eeb60839499506 Mon Sep 17 00:00:00 2001 From: PsyCrow <93346975+PsyCrow-code@users.noreply.github.com> Date: Thu, 23 Jan 2025 18:17:38 -0600 Subject: [PATCH 134/602] FIX #32765 JS Error: Uncaught TypeError FIX #32765 JS Error: Uncaught TypeError --- htdocs/core/lib/functions.lib.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ed2f8085a32..3a6cff28efc 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -11036,7 +11036,7 @@ function printCommonFooter($zone = 'private') } // Management of focus and mandatory for fields - if ($action == 'create' || $action == 'edit' || (empty($action) && (preg_match('/new\.php/', $_SERVER["PHP_SELF"]))) || ((empty($action) || $action == 'addline') && (preg_match('/card\.php/', $_SERVER["PHP_SELF"])))) { + if ($action == 'create' || $action == 'add' || $action == 'edit' || (empty($action) && (preg_match('/new\.php/', $_SERVER["PHP_SELF"]))) || ((empty($action) || $action == 'addline') && (preg_match('/card\.php/', $_SERVER["PHP_SELF"])))) { print '/* JS CODE TO ENABLE to manage focus and mandatory form fields */'."\n"; $relativepathstring = $_SERVER["PHP_SELF"]; // Clean $relativepathstring @@ -11107,7 +11107,7 @@ function printCommonFooter($zone = 'private') // Solution 1: Add handler on submit to check if mandatory fields are empty print 'var form = $(\'#'.dol_escape_js($paramkey).'\').closest("form");'."\n"; print "form.on('submit', function(event) { - var submitter = event.originalEvent.submitter; + var submitter = $(this).find(':submit:focus').get(0); if (submitter) { var buttonName = $(submitter).attr('name'); if (buttonName == 'cancel') { @@ -11134,10 +11134,10 @@ function printCommonFooter($zone = 'private') if (tmpvalue === null || tmpvalue === undefined || tmpvalue === '') { tmpvalueisempty = true; } - if (tmpvalue === '0' && tmptypefield == 'select') { + if (tmpvalue === '0' && (tmptypefield == 'select' || tmptypefield == 'input')) { tmpvalueisempty = true; } - if (tmpvalueisempty) { + if (tmpvalueisempty && (buttonName == 'save')) { console.log('field has type '+tmptypefield+' and is empty, we cancel the submit'); event.preventDefault(); // Stop submission of form to allow custom code to decide. event.stopPropagation(); // Stop other handlers. From 53ec7e48d129383735f0d6bcf9e00b48a3135615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 24 Jan 2025 09:59:02 +0100 Subject: [PATCH 135/602] fix comments --- htdocs/install/mysql/migration/19.0.0-20.0.0.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 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 ec3053a6a40..cf2697e3567 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,7 @@ 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); ---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); +-- 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); @@ -363,7 +363,7 @@ ALTER TABLE llx_ecm_files DROP column keyword; ALTER TABLE llx_c_type_container ADD COLUMN typecontainer varchar(10) DEFAULT 'page'; UPDATE llx_c_type_container SET typecontainer = 'container' WHERE code IN ('banner', 'other', 'menu'); ---UPDATE llx_c_type_container SET typecontainer = 'page' WHERE code IN ('page', 'blogpost'); +-- UPDATE llx_c_type_container SET typecontainer = 'page' WHERE code IN ('page', 'blogpost'); UPDATE llx_c_type_container SET position = 10 WHERE code IN ('page'); UPDATE llx_c_type_container SET position = 20 WHERE code IN ('blogpost'); @@ -413,7 +413,7 @@ ALTER TABLE llx_hrm_evaluation ADD COLUMN entity INTEGER DEFAULT 1 NOT NULL; -- Error SQL DB_ERROR_1170 BLOB/TEXT column 'url' used in key specification without a key length, so we remove completely the unique key ALTER TABLE llx_menu DROP INDEX idx_menu_uk_menu; ALTER TABLE llx_menu MODIFY COLUMN url TEXT NOT NULL; ---ALTER TABLE llx_menu ADD UNIQUE INDEX idx_menu_uk_menu (menu_handler, fk_menu, position, entity, url); +-- ALTER TABLE llx_menu ADD UNIQUE INDEX idx_menu_uk_menu (menu_handler, fk_menu, position, entity, url); UPDATE llx_c_units SET short_label = 'mn' WHERE short_label = 'i' AND code = 'MI'; From c2be92dad5c10a38862ce65d7ad3df38c3d6c4dd Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 15:09:07 +0100 Subject: [PATCH 136/602] Fix: fetch_object takes resultset, not sql --- htdocs/core/class/cunits.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/cunits.class.php b/htdocs/core/class/cunits.class.php index 34f5eb68660..71dbae2b866 100644 --- a/htdocs/core/class/cunits.class.php +++ b/htdocs/core/class/cunits.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -488,7 +488,7 @@ class CUnits extends CommonDict $resql = $this->db->query($sql); if ($resql) { // TODO : add base col into unit dictionary table - $unit = $this->db->fetch_object($sql); + $unit = $this->db->fetch_object($resql); if ($unit) { // TODO : if base exists in unit dictionary table, remove this conversion exception and update conversion infos in database. // Example time hour currently scale 3600 will become scale 2 base 60 From b19122b046f7cffb3b5f4afe9a8fa39922ccc2c4 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 15:24:34 +0100 Subject: [PATCH 137/602] Qual: Fix argument type --- 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 9a1409b9b0d..a4ae40aa36a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2637,7 +2637,7 @@ class Form $events = array(); $out .= img_picto('', 'resource', 'class="pictofixedwidth"'); - $out .= $formresources->select_resource_list(0, $htmlname, [], 1, 1, 0, $events, array(), 2, 0); + $out .= $formresources->select_resource_list(0, $htmlname, '', 1, 1, 0, $events, '', 2, 0); //$out .= $this->select_dolusers('', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter); $out .= ' '; $out .= '
'; From 4246215730f027986bf5527be7891d97e86a54a2 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 15:31:49 +0100 Subject: [PATCH 138/602] Fix: Convert email references array to string --- htdocs/core/class/smtps.class.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index 7740ed0066f..c0d6e3357c8 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2015 Laurent Destailleur * Copyright (C) 2006-2011 Regis Houssin * Copyright (C) 2016 Jonathan TISSEAU - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -1574,8 +1574,11 @@ class SMTPs if ($this->getInReplyTo()) { $_header .= "In-Reply-To: ".$this->getInReplyTo()."\r\n"; } - if ($this->getReferences()) { - $_header .= "References: ".$this->getReferences()."\r\n"; + $references = $this->getReferences(); + if ($references) { + // List of message ids: + // Example "References: + $_header .= "References: ".implode(' ', $references)."\r\n"; } return $_header; From 694342484d8f7e29e2d705ebd0a3863bbc7ff358 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 15:50:20 +0100 Subject: [PATCH 139/602] Qual: Fix phan notices --- htdocs/core/customreports.php | 27 +++++----- .../modules/commande/modules_commande.php | 49 ++++++++++++++++++- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index f0f1cd22712..5535546dece 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -40,6 +40,11 @@ * @var User $user */ +// Initialise values +$search_xaxis = array(); +$search_groupby = array(); +$tabfamily = null; + if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) { require '../main.inc.php'; @@ -56,14 +61,10 @@ if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) { //$search_xaxis = GETPOST('search_xaxis', 'array'); if (GETPOST('search_xaxis', 'alpha') && GETPOST('search_xaxis', 'alpha') != '-1') { $search_xaxis = array(GETPOST('search_xaxis', 'alpha')); - } else { - $search_xaxis = array(); } //$search_groupby = GETPOST('search_groupby', 'array'); if (GETPOST('search_groupby', 'alpha') && GETPOST('search_groupby', 'alpha') != '-1') { $search_groupby = array(GETPOST('search_groupby', 'alpha')); - } else { - $search_groupby = array(); } '@phan-var-force string[] $search_groupby'; @@ -385,11 +386,11 @@ $arrayofmesures = fillArrayOfMeasures($object, 't', $langs->trans($newarrayoftyp $arrayofmesures = dol_sort_array($arrayofmesures, 'position', 'asc', 0, 0, 1); $count = 0; -$arrayofxaxis = fillArrayOfXAxis($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofxaxis, 0, $count); +$arrayofxaxis = fillArrayOfXAxis($object, 't', $label, $arrayofxaxis, 0, $count); $arrayofxaxis = dol_sort_array($arrayofxaxis, 'position', 'asc', 0, 0, 1); $count = 0; -$arrayofgroupby = fillArrayOfGroupBy($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofgroupby, 0, $count); +$arrayofgroupby = fillArrayOfGroupBy($object, 't', $label, $arrayofgroupby, 0, $count); $arrayofgroupby = dol_sort_array($arrayofgroupby, 'position', 'asc', 0, 0, 1); @@ -548,7 +549,7 @@ if (is_array($search_groupby) && count($search_groupby)) { */ $labeloffield = $arrayofgroupby[$fieldtocount]['labelnohtml']; } else { - $labeloffield = $langs->transnoentitiesnoconv($keyforlabeloffield); + $labeloffield = 'FK_ISSUE'; // $langs->transnoentitiesnoconv($keyforlabeloffield); } } else { // This is a common field $reg = array(); @@ -585,7 +586,7 @@ if (!defined('MAIN_CUSTOM_REPORT_KEEP_GRAPH_ONLY')) { print '
'; print ''; print ''; - print ''; + print ''; $viewmode = ''; @@ -725,9 +726,9 @@ if (!defined('MAIN_CUSTOM_REPORT_KEEP_GRAPH_ONLY')) { print ''; } - if ($mode == 'graph') { - // - } + //if ($mode == 'graph') { + // + //} print '
'; print ''; @@ -1114,7 +1115,7 @@ if ($sql) { */ foreach ($search_measures as $key => $val) { $gi = 0; - foreach ($search_groupby as $gkey) { + foreach ($search_groupby as $gkey => $gval) { //var_dump('*** Fetch #'.$ifetch.' for labeltouse='.$labeltouse.' measure number '.$key.' and group g_'.$gi); //var_dump($arrayofvaluesforgroupby); foreach ($arrayofvaluesforgroupby['g_'.$gi] as $gvaluepossiblekey => $gvaluepossiblelabel) { diff --git a/htdocs/core/modules/commande/modules_commande.php b/htdocs/core/modules/commande/modules_commande.php index a0d1f4eda9e..db65437e38e 100644 --- a/htdocs/core/modules/commande/modules_commande.php +++ b/htdocs/core/modules/commande/modules_commande.php @@ -6,7 +6,7 @@ * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2014 Marcos García - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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,21 +41,68 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; */ abstract class ModelePDFCommandes extends CommonDocGenerator { + /** + * @var float + */ public $posxpicture; + /** + * @var float + */ public $posxtva; + /** + * @var float + */ public $posxup; + /** + * @var float + */ public $posxqty; + /** + * @var float + */ public $posxunit; + /** + * @var float + */ public $posxdesc; + /** + * @var float + */ public $posxdiscount; + /** + * @var float + */ public $postotalht; + /** + * @var array + */ public $tva; + /** + * @var array + */ public $tva_array; + /** + * Local tax rates Array[tax_type][tax_rate] + * + * @var array> + */ public $localtax1; + + /** + * Local tax rates Array[tax_type][tax_rate] + * + * @var array> + */ public $localtax2; + /** + * @var int<0,1> + */ public $atleastoneratenotnull = 0; + /** + * @var int<0,1> + */ public $atleastonediscount = 0; From 3fb717bb68c14450f4fd63fc628d9ce76f4b4616 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 5 Jan 2025 16:18:22 +0100 Subject: [PATCH 140/602] Fix date types/arrays (phan notices) --- htdocs/core/datepicker.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/core/datepicker.php b/htdocs/core/datepicker.php index 0c2e3f12160..12bc0fc9d94 100644 --- a/htdocs/core/datepicker.php +++ b/htdocs/core/datepicker.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2010 Laurent Destailleur * Copyright (C) 2005-2007 Regis Houssin * Copyright (C) 2014 Juanjo Menent - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This file is a modified version of datepicker.php from phpBSM to fix some @@ -233,7 +233,8 @@ function displayBox($selectedDate, $month, $year) //print "x ".$thedate." y"; // $thedate = first day of month $firstdate = dol_getdate($thedate); //var_dump($firstdateofweek); - $mydate = dol_get_first_day_week(1, $month, $year, true); // mydate = cursor date + $mydate_tmp = dol_get_first_day_week(1, $month, $year, true); // mydate = cursor date + $mydate = dol_getdate(dol_mktime(12, 0, 0, $mydate_tmp['first_month'], $mydate_tmp['first_day'], $mydate_tmp['first_year'])); // Loop on each day of month $stoploop = 0; @@ -241,7 +242,7 @@ function displayBox($selectedDate, $month, $year) $cols = 0; while (!$stoploop) { //print_r($mydate); - if ($mydate < $firstdate) { // At first run + if ($mydate[0] < $firstdate[0]) { // At first run echo "
'.$langs->trans('GCP_Type').''.$langs->trans("Select").'
'.print_r($list,true).'
'; -print ''."\n"; +print ''."\n"; // Name of Accountant Company print ' diff --git a/htdocs/partnership/core/modules/partnership/mod_partnership_advanced.php b/htdocs/partnership/core/modules/partnership/mod_partnership_advanced.php index 1c677e2b282..c259be9cda6 100644 --- a/htdocs/partnership/core/modules/partnership/mod_partnership_advanced.php +++ b/htdocs/partnership/core/modules/partnership/mod_partnership_advanced.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2019-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -82,7 +82,7 @@ class mod_partnership_advanced extends ModeleNumRefPartnership // Parametrage du prefix $text .= ''; - $text .= ''; + $text .= ''; $text .= ''; diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 60757b73689..fcb51f0e773 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -9,7 +9,7 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2016 Charlie Benke * Copyright (C) 2016 Ferran Marcet - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -69,7 +69,7 @@ $select_pricing_rules = array( 'PRODUCT_PRICE_UNIQ' => $langs->trans('PriceCatalogue'), // Unique price 'PRODUIT_MULTIPRICES' => $langs->trans('MultiPricesAbility'), // Several prices according to a customer level 'PRODUIT_CUSTOMER_PRICES' => $langs->trans('PriceByCustomer'), // Different price for each customer - 'PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES'=>$langs->trans('PriceByCustomeAndMultiPricesAbility'), // Different price for each customer and several prices according to a customer level + 'PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES' => $langs->trans('PriceByCustomeAndMultiPricesAbility'), // Different price for each customer and several prices according to a customer level ); $keyforparam = 'PRODUIT_CUSTOMER_PRICES_BY_QTY'; if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 1 || getDolGlobalString($keyforparam)) { @@ -504,7 +504,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/product/admin/product_lot.php b/htdocs/product/admin/product_lot.php index 0b777f04943..77b16d06800 100644 --- a/htdocs/product/admin/product_lot.php +++ b/htdocs/product/admin/product_lot.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -280,7 +280,7 @@ if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { } print ''; print "\n"; @@ -382,7 +382,7 @@ if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { } print ''; print "\n"; @@ -511,7 +511,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 323a650bbbb..deff2ccba3b 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -20,7 +20,7 @@ * Copyright (C) 2019-2020 Thibault FOUCART * Copyright (C) 2020 Pierre Ardoin * Copyright (C) 2022 Vincent de Grandpré - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -1513,7 +1513,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio $inherited_mask_lot = getDolGlobalString('LOT_ADVANCED_MASK'); $inherited_mask_sn = getDolGlobalString('SN_ADVANCED_MASK'); print ''; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 7e0da30d5c8..f815cd849ed 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -17,7 +17,7 @@ * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2023 Lenin Rivas * Copyright (C) 2023 William Mead - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify @@ -2164,7 +2164,7 @@ if ($action == 'create') { $sday = date("d", $tmpdte); print $form->selectDate($syear."-".$smonth."-".$sday, 'date_livraison', 0, 0, 0, "addprop"); } else { - $tmp_date_delivery = GETPOST('date_delivery') ? : -1; + $tmp_date_delivery = GETPOST('date_delivery') ?: -1; print $form->selectDate($tmp_date_delivery, 'date_livraison', 0, 0, 0, "addprop", 1, 1); } print ''; @@ -2174,7 +2174,7 @@ if ($action == 'create') { $langs->load("projects"); print ''; print ''; print ''; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 5f3e292e106..7457acd4e36 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -19,7 +19,7 @@ * Copyright (C) 2022 OpenDSI * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2023 William Mead - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -3771,7 +3771,7 @@ class Propal extends CommonObject if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) { $res = $this->fetchProject(); if ($res > 0 && $this->project instanceof Project) { - $datas['project'] = '
'.$langs->trans('Project').': '.$this->project->getNomUrl(1, '', 0, 1); + $datas['project'] = '
'.$langs->trans('Project').': '.$this->project->getNomUrl(1, '', 0, '1'); } } } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index f448bf25154..5fb70cfcc54 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3728,7 +3728,7 @@ class Commande extends CommonOrder if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) { $res = $this->fetchProject(); if ($res > 0 && $this->project instanceof Project) { - $datas['project'] = '
'.$langs->trans('Project').': '.$this->project->getNomUrl(1, '', 0, 1); + $datas['project'] = '
'.$langs->trans('Project').': '.$this->project->getNomUrl(1, '', 0, '1'); } } } diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 5ccd1ffa2d8..94bd781bcdd 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -5,7 +5,7 @@ * Copyright (C) 2020 Maxime DEMAREST * Copyright (C) 2021 Gauthier VERDOL * Copyright (C) 2022-2025 Alexandre Spangaro - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -673,7 +673,7 @@ if (isModEnabled('project')) { $formproject = new FormProjets($db); $langs->load('projects'); print ''.$langs->trans('Project').":"; - print img_picto('', 'project').$formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, ''); + print img_picto('', 'project').$formproject->select_projects(($socid > 0 ? $socid : -1), (string) $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, ''); print ''; print '
'; } diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index fe6102bbf61..5d985f68ce0 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -514,7 +514,7 @@ if ($action == 'create') { print '
'; } @@ -626,7 +626,7 @@ if ($id) { $morehtmlref .= ''; $morehtmlref .= ''; $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects(-1, $object->fk_project, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); + $morehtmlref .= $formproject->select_projects(-1, (string) $object->fk_project, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); $morehtmlref .= ''; $morehtmlref .= ''; } else { diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 932f72d8864..e374e52450e 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -17,7 +17,7 @@ * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2023 Nick Fragoulis - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify @@ -892,27 +892,27 @@ if (empty($reshook)) { $keyforvatrate = $line->tva_tx.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''); if (!isset($amount_ht[$keyforvatrate])) { - $amount_ht[$keyforvatrate]=0; + $amount_ht[$keyforvatrate] = 0; } $amount_ht[$keyforvatrate] += $line->total_ht; if (!isset($amount_tva[$keyforvatrate])) { - $amount_tva[$keyforvatrate]=0; + $amount_tva[$keyforvatrate] = 0; } $amount_tva[$keyforvatrate] += $line->total_tva; if (!isset($amount_ttc[$keyforvatrate])) { - $amount_ttc[$keyforvatrate]=0; + $amount_ttc[$keyforvatrate] = 0; } $amount_ttc[$keyforvatrate] += $line->total_ttc; if (!isset($multicurrency_amount_ht[$keyforvatrate])) { - $multicurrency_amount_ht[$keyforvatrate]=0; + $multicurrency_amount_ht[$keyforvatrate] = 0; } $multicurrency_amount_ht[$keyforvatrate] += $line->multicurrency_total_ht; if (!isset($multicurrency_amount_tva[$keyforvatrate])) { - $multicurrency_amount_tva[$keyforvatrate]=0; + $multicurrency_amount_tva[$keyforvatrate] = 0; } $multicurrency_amount_tva[$keyforvatrate] += $line->multicurrency_total_tva; if (!isset($multicurrency_amount_ttc[$keyforvatrate])) { - $multicurrency_amount_ttc[$keyforvatrate]=0; + $multicurrency_amount_ttc[$keyforvatrate] = 0; } $multicurrency_amount_ttc[$keyforvatrate] += $line->multicurrency_total_ttc; $i++; @@ -4070,7 +4070,7 @@ if ($action == 'create') { $langs->load('projects'); print ''; } diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index 4bda1228b91..9c37b76e37b 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -4,7 +4,7 @@ * Copyright (C) 2016-2024 Frédéric France * Copyright (C) 2017-2024 Alexandre Spangaro * Copyright (C) 2021 Gauthier VERDOL - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -431,7 +431,7 @@ if ($action == 'create') { print ''; } diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index f1ea95f0024..e2e5496e0c8 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2068,7 +2068,7 @@ class Contrat extends CommonObject if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) { $res = $this->fetchProject(); if ($res > 0 && $this->project instanceof Project) { - $datas['project'] = '
'.$langs->trans('Project').': '.$this->project->getNomUrl(1, '', 0, 1); + $datas['project'] = '
'.$langs->trans('Project').': '.$this->project->getNomUrl(1, '', 0, '1'); } } } diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index f817c7b98bb..2534c04a58c 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -3,7 +3,7 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2018 Charlene Benke * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Benjamin Falière * * This program is free software; you can redistribute it and/or modify @@ -113,7 +113,7 @@ class FormProjets extends Form } $out .= ''; - $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array()); + $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/projet/ajax/projects.php', $urloption, getDolGlobalInt('PROJECT_USE_SEARCH_TO_SELECT'), 0, array()); } else { $out .= $this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, abs($discard_closed), $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss, $morefilter); } @@ -153,7 +153,6 @@ class FormProjets extends Form * @param string $morecss More CSS * @param string $morefilter More filters (Must be a sql sanitized string) * @return int|string|array HTML string or array of option or <0 if KO - */ public function select_projects_list($socid = -1, $selected = 0, $htmlname = 'projectid', $maxlength = 24, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $htmlid = '', $morecss = 'maxwidth500', $morefilter = '') { @@ -333,16 +332,16 @@ class FormProjets extends Form * @param int $selected Id task preselected * @param string $htmlname Name of HTML select * @param int $maxlength Maximum length of label - * @param int $option_only Return only html options lines without the select tag + * @param int<0,1> $option_only Return only html options lines without the select tag * @param string $show_empty Add an empty line ('1' or string to show for empty line) - * @param int $discard_closed Discard closed projects (0=Keep, 1=hide completely, 2=Disable) - * @param int $forcefocus Force focus on field (works with javascript only) - * @param int $disabled Disabled + * @param int<0,2> $discard_closed Discard closed projects (0=Keep, 1=hide completely, 2=Disable) + * @param int<0,1> $forcefocus Force focus on field (works with javascript only) + * @param int<0,1> $disabled Disabled * @param string $morecss More css added to the select component * @param string $projectsListId ''=Automatic filter on project allowed. List of id=Filter on project ids. - * @param string $showmore 'all' = Show project info, 'progress' = Show task progression, ''=Show nothing more - * @param User $usertofilter User object to use for filtering - * @param int $nooutput 1=Return string, do not send to output + * @param 'all'|'progress'|'' $showmore 'all' = Show project info, 'progress' = Show task progression, ''=Show nothing more + * @param ?User $usertofilter User object to use for filtering + * @param int<0,1> $nooutput 1=Return string, do not send to output * * @return int|string Nbr of tasks if OK, <0 if KO. If nooutput=1: Return a HTML select string. */ @@ -694,17 +693,17 @@ class FormProjets extends Form * Build a HTML select list of element of same thirdparty to suggest to link them to project * * @param string $htmlname HTML name - * @param string $preselected Preselected (int or 'all' or 'none') - * @param int $showempty Add an empty line - * @param int $useshortlabel Use short label - * @param int $showallnone Add choice "All" and "None" - * @param int $showpercent Show default probability for status - * @param string $morecss Add more css - * @param int $noadmininfo 0=Add admin info, 1=Disable admin info - * @param int $addcombojs 1=Add a js combo + * @param int|'all'|'none'|'notopenedopp' $preselected Preselected (int or 'all' or 'none') + * @param int<0,1> $showempty Add an empty line + * @param int<0,1> $useshortlabel Use short label + * @param int<0,1> $showallnone Add choice "All" and "None" + * @param int<0,1> $showpercent Show default probability for status + * @param string $morecss Add more css + * @param int<0,1> $noadmininfo 0=Add admin info, 1=Disable admin info + * @param int<0,1> $addcombojs 1=Add a js combo * @return int<-1,-1>|string The HTML select list of element or '' if nothing or -1 if KO */ - public function selectOpportunityStatus($htmlname, $preselected = '-1', $showempty = 1, $useshortlabel = 0, $showallnone = 0, $showpercent = 0, $morecss = '', $noadmininfo = 0, $addcombojs = 0) + public function selectOpportunityStatus($htmlname, $preselected = -1, $showempty = 1, $useshortlabel = 0, $showallnone = 0, $showpercent = 0, $morecss = '', $noadmininfo = 0, $addcombojs = 0) { global $conf, $langs, $user; @@ -780,12 +779,12 @@ class FormProjets extends Form /** * Return combo list of different statuses of orders * - * @param string $selected Preselected value - * @param int $short Use short labels - * @param string $hmlname Name of HTML select element + * @param string $selected Preselected value + * @param int<0,1> $short Use short labels + * @param string $htmlname Name of HTML select element * @return void */ - public function selectProjectsStatus($selected = '', $short = 0, $hmlname = 'order_status') + public function selectProjectsStatus($selected = '', $short = 0, $htmlname = 'order_status') { $options = array(); @@ -813,7 +812,7 @@ class FormProjets extends Form $selectedarray = explode(',', $selected); } - print Form::multiselectarray($hmlname, $options, $selectedarray, 0, 0, 'minwidth100'); + print Form::multiselectarray($htmlname, $options, $selectedarray, 0, 0, 'minwidth100'); } /** @@ -947,11 +946,11 @@ class FormProjets extends Form * * @param string $page Page * @param string $selected Id preselected - * @param int $percent_value percentage of the opportunity + * @param ''|int $percent_value percentage of the opportunity * @param string $htmlname_status name of HTML element for status select * @param string $htmlname_percent name of HTML element for percent input * @param string $filter optional filters criteras - * @param int $nooutput No print output. Return it only. + * @param int<0,1> $nooutput No print output. Return it only. * @return void|string */ public function formOpportunityStatus($page, $selected = '', $percent_value = 0, $htmlname_status = 'none', $htmlname_percent = 'none', $filter = '', $nooutput = 0) diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 6143ed6ac5b..6945ef93e8c 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2022-2025 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -138,7 +138,7 @@ function print_actions_filter( print '
'; print img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth inline-block"'); - print $formproject->select_projects($socid ? $socid : -1, $pid, 'search_projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, 'minwidth100 maxwidth250 widthcentpercentminusx'); + print $formproject->select_projects($socid ? $socid : -1, (string) $pid, 'search_projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, 'minwidth100 maxwidth250 widthcentpercentminusx'); print '
'; } diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 4c5e77fb0a3..f7b1f3e7203 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -5,7 +5,7 @@ * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2022 Charlene Benke * Copyright (C) 2023 Gauthier VERDOL - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Vincent de Grandpré * * This program is free software; you can redistribute it and/or modify @@ -587,7 +587,7 @@ function project_admin_prepare_head() * @param int $level Level (start to 0, then increased/decrease by recursive call), or -1 to show all level in order of $lines without the recursive groupment feature. * @param string $var Not used * @param int $showproject Show project columns - * @param int $taskrole Array of roles of user for each tasks + * @param array $taskrole Array of roles of user for each tasks * @param string $projectsListId List of id of projects allowed to user (string separated with comma) * @param int $addordertick Add a tick to move task * @param int $projectidfortotallink 0 or Id of project to use on total line (link to see all time consumed for project) @@ -1182,8 +1182,8 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t * @param ?User $fuser Restrict list to user if defined * @param Task[] $lines Array of lines * @param int $level Level (start to 0, then increased/decrease by recursive call) - * @param string $projectsrole Array of roles user has on project - * @param string $tasksrole Array of roles user has on task + * @param array $projectsrole Array of roles user has on project + * @param array $tasksrole Array of roles user has on task * @param string $mine Show only task lines I am assigned to * @param int<0,1> $restricteditformytask 0=No restriction, 1=Enable add time only if task is a task i am affected to * @param int $preselectedday Preselected day @@ -1412,8 +1412,8 @@ function projectLinesPerAction(&$inc, $parent, $fuser, $lines, &$level, &$projec * @param ?User $fuser Restrict list to user if defined * @param Task[] $lines Array of lines * @param int $level Level (start to 0, then increased/decrease by recursive call) - * @param string $projectsrole Array of roles user has on project - * @param string $tasksrole Array of roles user has on task + * @param array $projectsrole Array of roles user has on project + * @param array $tasksrole Array of roles user has on task * @param int<0,1> $mine Show only task lines I am assigned to * @param int<0,2> $restricteditformytask 0=No restriction, 1=Enable add time only if task is assigned to me, 2=Enable add time only if tasks is assigned to me and hide others * @param int $preselectedday Preselected day @@ -1816,8 +1816,8 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr * @param int $parent Id of parent task to show (0 to show all) * @param Task[] $lines Array of lines (list of tasks but we will show only if we have a specific role on task) * @param int $level Level (start to 0, then increased/decrease by recursive call) - * @param string $projectsrole Array of roles user has on project - * @param string $tasksrole Array of roles user has on task + * @param array $projectsrole Array of roles user has on project + * @param array $tasksrole Array of roles user has on task * @param int<0,1> $mine Show only task lines I am assigned to * @param int<0,2> $restricteditformytask 0=No restriction, 1=Enable add time only if task is assigned to me, 2=Enable add time only if tasks is assigned to me and hide others * @param array,afternoon:int<0,1>}> $isavailable Array with data that say if user is available for several days for morning and afternoon @@ -2222,13 +2222,13 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ * @param int $parent Id of parent task to show (0 to show all) * @param Task[] $lines Array of lines (list of tasks but we will show only if we have a specific role on task) * @param int $level Level (start to 0, then increased/decrease by recursive call) - * @param string $projectsrole Array of roles user has on project - * @param string $tasksrole Array of roles user has on task + * @param array $projectsrole Array of roles user has on project + * @param array $tasksrole Array of roles user has on task * @param int<0,1> $mine Show only task lines I am assigned to * @param int<0,1> $restricteditformytask 0=No restriction, 1=Enable add time only if task is a task i am affected to * @param array,afternoon:int<0,1>}> $isavailable Array with data that say if user is available for several days for morning and afternoon * @param int $oldprojectforbreak Old project id of last project break - * @param string[] $TWeek Array of week numbers ('02', ... + * @param string[] $TWeek Array of week numbers ('02', ... * @param array> $arrayfields Array of additional column * @param Extrafields $extrafields Object extrafields * @return array Array with time spent for $fuser for each day of week on tasks in $lines and subtasks (index is string, month is '01', ...) @@ -2525,7 +2525,7 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & * @param int $inc Counter that count number of lines legitimate to show (for return) * @param int $parent Id of parent task to start * @param Task[] $lines Array of all tasks - * @param string $taskrole Array of task filtered on a particular user + * @param array $taskrole Array of task filtered on a particular user * @return int 1 if there is */ function searchTaskInChild(&$inc, $parent, &$lines, &$taskrole) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 92afd4da700..b7a37c346d6 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -1113,10 +1113,10 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl } $checkonentitydone = 1; } - if (in_array($feature, $checktask) && $objectid > 0) { + if (in_array($feature, $checktask) && (int) $objectid > 0) { if (isModEnabled('project') && !$user->hasRight('projet', 'all', 'lire')) { $task = new Task($db); - $task->fetch($objectid); + $task->fetch((int) $objectid); $projectid = $task->fk_project; include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; diff --git a/htdocs/core/modules/mailings/eventorganization.modules.php b/htdocs/core/modules/mailings/eventorganization.modules.php index 528072d76e9..79ee29df177 100644 --- a/htdocs/core/modules/mailings/eventorganization.modules.php +++ b/htdocs/core/modules/mailings/eventorganization.modules.php @@ -2,7 +2,7 @@ /* Copyright (C) 2018-2018 Andre Schild * Copyright (C) 2005-2010 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This file is an example to follow to add your own email selector inside @@ -204,7 +204,7 @@ class mailing_eventorganization extends MailingTargets $formproject = new FormProjets($this->db); $s = img_picto($langs->trans("OrganizedEvent"), 'project', 'class="pictofixedwidth"'); - $s .= $formproject->select_projects(-1, 0, "filter_eventorganization", 0, 0, $langs->trans("OrganizedEvent"), 1, 0, 0, 0, '', 1, 0, '', '', 'usage_organize_event=1'); + $s .= $formproject->select_projects(-1, '0', "filter_eventorganization", 0, 0, $langs->trans("OrganizedEvent"), 1, 0, 0, 0, '', 1, 0, '', '', 'usage_organize_event=1'); return $s; } diff --git a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php index 63f17a6a644..94878e5d2ae 100644 --- a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php @@ -5,7 +5,7 @@ * Copyright (C) 2016-2023 Charlene Benke * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2023 Gauthier VERDOL - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -183,7 +183,6 @@ class doc_generic_project_odt extends ModelePDFProjects * @param Task $task Task Object * @param Translate $outputlangs Lang object to use for output * @return array{task_ref:string,task_fk_project:string,task_projectref:string,task_projectlabel:string,task_label:string,task_description:string,task_fk_parent:string,task_duration:string,task_duration_hour:string,task_planned_workload:string,task_planned_workload_hour:string,task_progress:string,task_public:string,task_date_start:string,task_date_end:string,task_note_private:string,task_note_public:string} Return a substitution array + extrafields - */ public function get_substitutionarray_tasks(Task $task, $outputlangs) { @@ -1053,7 +1052,7 @@ class doc_generic_project_odt extends ModelePDFProjects $ref_array['type'] = (string) $langs->trans($classname); $element = new $classname($this->db); - $element->fetch($elementarray[$i]); + $element->fetch((int) $elementarray[$i]); $element->fetch_thirdparty(); //Ref object diff --git a/htdocs/core/modules/project/doc/pdf_beluga.modules.php b/htdocs/core/modules/project/doc/pdf_beluga.modules.php index 3b5cf8daf32..0c0a6527da8 100644 --- a/htdocs/core/modules/project/doc/pdf_beluga.modules.php +++ b/htdocs/core/modules/project/doc/pdf_beluga.modules.php @@ -467,7 +467,7 @@ class pdf_beluga extends ModelePDFProjects //var_dump("$key, $tablename, $datefieldname, $dates, $datee"); $elementarray = $object->get_element_list($key, $tablename, $datefieldname, 0, 0, $projectField); - $num = count($elementarray); + $num = is_array($elementarray) ? count($elementarray) : $elementarray; if ($num >= 0) { $nexY = $pdf->GetY() + 5; diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 082111cd7f0..2ddcc41a1c0 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2016 Juanjo Menent * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -887,7 +887,7 @@ class Holiday extends CommonObject * * @param User $user User that approve * @param int<0,1> $notrigger 0=launch triggers after, 1=disable triggers - * @return int Return integer <0 if KO, >0 if OK + * @return int Return integer <0 if KO, >0 if OK */ public function approve($user = null, $notrigger = 0) { @@ -1151,9 +1151,9 @@ class Holiday extends CommonObject /** * Delete object in database * - * @param User $user User that delete - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int Return integer <0 if KO, >0 if OK + * @param User $user User that delete + * @param int<0,1> $notrigger 0=launch triggers after, 1=disable triggers + * @return int Return integer <0 if KO, >0 if OK */ public function delete($user, $notrigger = 0) { @@ -1202,12 +1202,12 @@ class Holiday extends CommonObject * This function can be used to avoid to have 2 leave requests on same period for example. * Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call. * - * @param int $fk_user Id user - * @param integer $dateStart Start date of period to check - * @param integer $dateEnd End date of period to check - * @param int $halfday Tag to define how start and end the period to check: + * @param int $fk_user Id user + * @param int $dateStart Start date of period to check + * @param int $dateEnd End date of period to check + * @param int<-1,2> $halfday Tag to define how start and end the period to check: * 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning - * @return boolean False = New range overlap an existing holiday, True = no overlapping (is never on holiday during checked period). + * @return bool False = New range overlap an existing holiday, True = no overlapping (is never on holiday during checked period). * @see verifDateHolidayForTimestamp() */ public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0) @@ -1287,9 +1287,9 @@ class Holiday extends CommonObject * Check that a user is not on holiday for a particular timestamp. Can check approved leave requests and not into public holidays of company. * * @param int $fk_user Id user - * @param integer $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00) + * @param int $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00) * @param string $status Filter on holiday status. '-1' = no filter. - * @return array{morning_reason?:string,afternoon_reason?:string} array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp. + * @return array{morning:int<0,1>,afternoon:int<0,1>,morning_reason?:string,afternoon_reason?:string} array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp. * @see verifDateHolidayCP() */ public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1') @@ -1349,7 +1349,7 @@ class Holiday extends CommonObject dol_print_error($this->db); } - $result = array('morning' => $isavailablemorning, 'afternoon' => $isavailableafternoon); + $result = array('morning' => (int) $isavailablemorning, 'afternoon' => (int) $isavailableafternoon); if (!$isavailablemorning) { $result['morning_reason'] = 'leave_request'; } diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 3a784e4db5e..e5958376156 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2010 François Legastelois * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -90,9 +90,9 @@ $search_declared_progress = GETPOST('search_declared_progress', 'alpha'); $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); -$monthofday = GETPOST('addtimemonth'); -$dayofday = GETPOST('addtimeday'); -$yearofday = GETPOST('addtimeyear'); +$monthofday = GETPOSTINT('addtimemonth'); +$dayofday = GETPOSTINT('addtimeday'); +$yearofday = GETPOSTINT('addtimeyear'); //var_dump(GETPOST('remonth')); //var_dump(GETPOST('button_search_x')); @@ -134,9 +134,9 @@ $extrafields->fetch_name_optionals_label($object->table_element); // Definition of fields for list $arrayfields = array(); -$arrayfields['t.planned_workload'] = array('label' => 'PlannedWorkload', 'checked' => 1, 'enabled' => 1, 'position' => 0); -$arrayfields['t.progress'] = array('label' => 'ProgressDeclared', 'checked' => 1, 'enabled' => 1, 'position' => 0); -$arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => 1, 'enabled' => 1, 'position' => 15); +$arrayfields['t.planned_workload'] = array('label' => 'PlannedWorkload', 'checked' => '1', 'enabled' => '1', 'position' => 0); +$arrayfields['t.progress'] = array('label' => 'ProgressDeclared', 'checked' => '1', 'enabled' => '1', 'position' => 0); +$arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => '1', 'enabled' => '1', 'position' => 15); /*$arrayfields=array( // Project 'p.opp_amount'=>array('label'=>$langs->trans("OpportunityAmountShort"), 'checked'=>0, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>103), @@ -150,7 +150,7 @@ $arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => 1, if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) { - $arrayfields["efpt.".$key] = array('label' => $extrafields->attributes[$object->table_element]['label'][$key], 'checked' => (($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), 'position' => $extrafields->attributes[$object->table_element]['pos'][$key], 'enabled' => (abs((int) $extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key])); + $arrayfields["efpt.".$key] = array('label' => $extrafields->attributes[$object->table_element]['label'][$key], 'checked' => (($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? '0' : '1'), 'position' => $extrafields->attributes[$object->table_element]['pos'][$key], 'enabled' => (string) (int) (abs((int) $extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key])); } } } @@ -407,14 +407,14 @@ $search_options_pattern = 'search_task_options_'; $extrafieldsobjectkey = 'projet_task'; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; -$tasksarray = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. +$tasksarray = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, (string) $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. $tasksarraywithoutfilter = array(); if ($morewherefilter) { // Get all task without any filter, so we can show total of time spent for not visible tasks - $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. + $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', (string) $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. } -$projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? $project->id : 0), 0, $onlyopenedproject); -$tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? $project->id : 0), 0, $onlyopenedproject); +$projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? (string) $project->id : '0'), 0, $onlyopenedproject); +$tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? (string) $project->id : '0'), 0, $onlyopenedproject); llxHeader('', $title, '', '', 0, 0, array('/core/js/timesheet.js'), '', '', 'mod-project project-activity page-activity_perday'); @@ -521,7 +521,7 @@ if (!$user->hasRight('user', 'user', 'lire')) { $includeonly = array($user->id); } $selecteduser = $search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id; -$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, '', '0', 0, 0, '', 0, '', 'maxwidth200'); if ($form->num > 1 || empty($conf->dol_optimize_smallscreen)) { $moreforfilter .= '
'; $moreforfilter .= '
'; @@ -656,7 +656,7 @@ if (getDolGlobalString('MAIN_DEFAULT_WORKING_DAYS')) { } $statusofholidaytocheck = Holiday::STATUS_APPROVED; -$isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $daytoparse, $statusofholidaytocheck); // $daytoparse is a date with hours = 0 +$isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $daytoparse, (string) $statusofholidaytocheck); // $daytoparse is a date with hours = 0 $isavailable[$daytoparse] = $isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day $test = num_public_holiday($daytoparsegmt, $daytoparsegmt + 86400, $mysoc->country_code); diff --git a/htdocs/projet/activity/permonth.php b/htdocs/projet/activity/permonth.php index 502e85e1cba..dbb30f61c91 100644 --- a/htdocs/projet/activity/permonth.php +++ b/htdocs/projet/activity/permonth.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2010 François Legastelois - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2025 Alexandre Spangaro * @@ -137,9 +137,9 @@ $arrayfields = array(); 'p.budget_amount'=>array('label'=>$langs->trans("Budget"), 'checked'=>0, 'position'=>110), 'p.usage_bill_time'=>array('label'=>$langs->trans("BillTimeShort"), 'checked'=>0, 'position'=>115), );*/ -$arrayfields['t.planned_workload'] = array('label' => 'PlannedWorkload', 'checked' => 1, 'enabled' => 1, 'position' => 5); -$arrayfields['t.progress'] = array('label' => 'ProgressDeclared', 'checked' => 1, 'enabled' => 1, 'position' => 10); -$arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => 1, 'enabled' => 1, 'position' => 15); +$arrayfields['t.planned_workload'] = array('label' => 'PlannedWorkload', 'checked' => '1', 'enabled' => '1', 'position' => 5); +$arrayfields['t.progress'] = array('label' => 'ProgressDeclared', 'checked' => '1', 'enabled' => '1', 'position' => 10); +$arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => '1', 'enabled' => '1', 'position' => 15); /*foreach($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field @@ -150,7 +150,7 @@ $arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => 1, if (!empty($extrafields->attributes['projet_task']['label']) && is_array($extrafields->attributes['projet_task']['label']) && count($extrafields->attributes['projet_task']['label']) > 0) { foreach ($extrafields->attributes['projet_task']['label'] as $key => $val) { if (!empty($extrafields->attributes['projet_task']['list'][$key])) { - $arrayfields["efpt.".$key] = array('label' => $extrafields->attributes['projet_task']['label'][$key], 'checked' => (($extrafields->attributes['projet_task']['list'][$key] < 0) ? 0 : 1), 'position' => $extrafields->attributes['projet_task']['pos'][$key], 'enabled' => (abs((int) $extrafields->attributes['projet_task']['list'][$key]) != 3 && $extrafields->attributes['projet_task']['perms'][$key])); + $arrayfields["efpt.".$key] = array('label' => $extrafields->attributes['projet_task']['label'][$key], 'checked' => (($extrafields->attributes['projet_task']['list'][$key] < 0) ? '0' : '1'), 'position' => $extrafields->attributes['projet_task']['pos'][$key], 'enabled' => (string) (int) (abs((int) $extrafields->attributes['projet_task']['list'][$key]) != 3 && $extrafields->attributes['projet_task']['perms'][$key])); } } } @@ -424,12 +424,12 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; $tasksarraywithoutfilter = array(); // Default -$tasksarray = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. +$tasksarray = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, (string) $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. if ($morewherefilter) { // Get all task without any filter, so we can show total of time spent for not visible tasks - $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. + $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', (string) $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. } -$projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? $project->id : 0), 0, $onlyopenedproject); -$tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? $project->id : 0), 0, $onlyopenedproject); +$projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? (string) $project->id : '0'), 0, $onlyopenedproject); +$tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? (string) $project->id : '0'), 0, $onlyopenedproject); //var_dump($tasksarray); //var_dump($projectsrole); //var_dump($taskrole); @@ -536,7 +536,7 @@ if (!$user->hasRight('user', 'user', 'lire')) { $includeonly = array($user->id); } $selecteduser = $search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id; -$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, array(), 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, array(), '0', 0, 0, '', 0, '', 'maxwidth200'); if ($form->num > 1 || empty($conf->dol_optimize_smallscreen)) { $moreforfilter .= '
'; $moreforfilter .= '
'; @@ -774,8 +774,8 @@ if (count($tasksarray) > 0) { if (!empty($THolidays[$weekNb]["ids"]) && in_array($h->rowid, $THolidays[$weekNb]["ids"])) { continue; } - $startweekholiday =(int) (($h["date_debut"] <= $weekstart) ? $weekstart : $h["date_debut"] ); - $endweekholiday =(int) (($h["date_fin"] >= $weekend) ? $weekend : $h["date_fin"]); + $startweekholiday = (int) (($h["date_debut"] <= $weekstart) ? $weekstart : $h["date_debut"]); + $endweekholiday = (int) (($h["date_fin"] >= $weekend) ? $weekend : $h["date_fin"]); $halfdays = (int) $h["halfday"]; $nbdays = num_open_day($startweekholiday, $endweekholiday, 0, 1, $halfdays); diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index a7f799d74aa..a2a96bb2b01 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2010 François Legastelois * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -139,9 +139,9 @@ $arrayfields = array(); 'p.budget_amount'=>array('label'=>$langs->trans("Budget"), 'checked'=>0, 'position'=>110), 'p.usage_bill_time'=>array('label'=>$langs->trans("BillTimeShort"), 'checked'=>0, 'position'=>115), );*/ -$arrayfields['t.planned_workload'] = array('label' => 'PlannedWorkload', 'checked' => 1, 'enabled' => 1, 'position' => 5); -$arrayfields['t.progress'] = array('label' => 'ProgressDeclared', 'checked' => 1, 'enabled' => 1, 'position' => 10); -$arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => 1, 'enabled' => 1, 'position' => 15); +$arrayfields['t.planned_workload'] = array('label' => 'PlannedWorkload', 'checked' => '1', 'enabled' => '1', 'position' => 5); +$arrayfields['t.progress'] = array('label' => 'ProgressDeclared', 'checked' => '1', 'enabled' => '1', 'position' => 10); +$arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => '1', 'enabled' => '1', 'position' => 15); /*foreach($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field @@ -152,7 +152,7 @@ $arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => 1, if (!empty($extrafields->attributes['projet_task']['label']) && is_array($extrafields->attributes['projet_task']['label']) && count($extrafields->attributes['projet_task']['label']) > 0) { foreach ($extrafields->attributes['projet_task']['label'] as $key => $val) { if (!empty($extrafields->attributes['projet_task']['list'][$key])) { - $arrayfields["efpt.".$key] = array('label' => $extrafields->attributes['projet_task']['label'][$key], 'checked' => (($extrafields->attributes['projet_task']['list'][$key] < 0) ? 0 : 1), 'position' => $extrafields->attributes['projet_task']['pos'][$key], 'enabled' => (abs((int) $extrafields->attributes['projet_task']['list'][$key]) != 3 && $extrafields->attributes['projet_task']['perms'][$key])); + $arrayfields["efpt.".$key] = array('label' => $extrafields->attributes['projet_task']['label'][$key], 'checked' => (($extrafields->attributes['projet_task']['list'][$key] < 0) ? '0' : '1'), 'position' => $extrafields->attributes['projet_task']['pos'][$key], 'enabled' => (string) (int) (abs((int) $extrafields->attributes['projet_task']['list'][$key]) != 3 && $extrafields->attributes['projet_task']['perms'][$key])); } } } @@ -422,13 +422,13 @@ $search_options_pattern = 'search_task_options_'; $extrafieldsobjectkey = 'projet_task'; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; -$tasksarray = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. +$tasksarray = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, (string) $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. $tasksarraywithoutfilter = array(); if ($morewherefilter) { // Get all task without any filter, so we can show total of time spent for not visible tasks - $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. + $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', (string) $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. } -$projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? $project->id : 0), 0, $onlyopenedproject); -$tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? $project->id : 0), 0, $onlyopenedproject); +$projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? (string) $project->id : '0'), 0, (int) $onlyopenedproject); +$tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? (string) $project->id : '0'), 0, (int) $onlyopenedproject); //var_dump($tasksarray); //var_dump($projectsrole); //var_dump($taskrole); @@ -542,7 +542,7 @@ for ($idw = 0; $idw < 7; $idw++) { $statusofholidaytocheck = Holiday::STATUS_APPROVED; - $isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $dayinloopfromfirstdaytoshow, $statusofholidaytocheck); + $isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $dayinloopfromfirstdaytoshow, (string) $statusofholidaytocheck); $isavailable[$dayinloopfromfirstdaytoshow] = $isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day $test = num_public_holiday($dayinloopfromfirstdaytoshowgmt, $dayinloopfromfirstdaytoshowgmt + 86400, $mysoc->country_code); @@ -571,7 +571,7 @@ if (!$user->hasRight('user', 'user', 'lire')) { $includeonly = array($user->id); } $selecteduser = $search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id; -$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, '', '0', 0, 0, '', 0, '', 'maxwidth200'); if ($form->num > 1 || empty($conf->dol_optimize_smallscreen)) { $moreforfilter .= '
'; $moreforfilter .= '
'; diff --git a/htdocs/projet/ajax/projects.php b/htdocs/projet/ajax/projects.php index 81ffe73f17d..8b2dc432e60 100644 --- a/htdocs/projet/ajax/projects.php +++ b/htdocs/projet/ajax/projects.php @@ -4,6 +4,7 @@ * Copyright (C) 2007-2020 Laurent Destailleur * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -78,7 +79,7 @@ if (empty($mode) || $mode != 'gettasks') { $searchkey = (GETPOSTISSET($htmlname) ? GETPOST($htmlname, 'aZ09') : ''); $formproject = new FormProjets($db); - $arrayresult = $formproject->select_projects_list($socid, '', '', 0, 0, 1, $discard_closed, 0, 0, 1, $searchkey); + $arrayresult = $formproject->select_projects_list($socid, 0, '', 0, 0, 1, $discard_closed, 0, 0, 1, $searchkey); $db->close(); @@ -93,7 +94,7 @@ if ($mode == 'gettasks') { top_httphead(); $formproject = new FormProjets($db); - $formproject->selectTasks((!empty($socid) ? $socid : -1), 0, 'taskid', 24, 1, '1', 1, 0, 0, 'maxwidth500', GETPOSTINT('projectid'), ''); + $formproject->selectTasks((!empty($socid) ? $socid : -1), 0, 'taskid', 24, 1, '1', 1, 0, 0, 'maxwidth500', (string) GETPOSTINT('projectid'), ''); $db->close(); diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index dba5f48db1c..08625a71259 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2023 Charlene Benke * Copyright (C) 2023 Christian Foellmann - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro * @@ -313,7 +313,7 @@ if (empty($reshook)) { } $db->begin(); - $old_start_date = null; + $old_start_date = 0; if (!$error) { $object->oldcopy = clone $object; @@ -1095,7 +1095,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) { print '
'; } @@ -1240,7 +1240,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ''; print ''; // Opportunity Amount @@ -1808,7 +1808,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { $genallowed = ($user->hasRight('projet', 'lire') && $userAccess > 0); $delallowed = ($user->hasRight('projet', 'creer') && $userWrite > 0); - print $formfile->showdocuments('project', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', '', '', $object); + print $formfile->showdocuments('project', $filename, $filedir, $urlsource, (int) $genallowed, (int) $delallowed, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', '', '', $object); print '
'; diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 979745c3805..842522ff561 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2016 Laurent Destailleur - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -31,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; class Projects extends DolibarrApi { /** - * @var string[] $FIELDS Mandatory fields, checked when create and update object + * @var string[] Mandatory fields, checked when create and update object */ public static $FIELDS = array( 'ref', @@ -39,12 +39,12 @@ class Projects extends DolibarrApi ); /** - * @var Project $project {@type Project} + * @var Project {@type Project} */ public $project; /** - * @var Task $task {@type Task} + * @var Task {@type Task} */ public $task; @@ -459,7 +459,7 @@ class Projects extends DolibarrApi $userp = new User($this->db); $userp->fetch($userid); } - $this->project->roles = $taskstatic->getUserRolesForProjectsOrTasks($userp, null, $id, 0); + $this->project->roles = $taskstatic->getUserRolesForProjectsOrTasks($userp, null, (string) $id, 0); $result = array(); foreach ($this->project->roles as $line) { array_push($result, $this->_cleanObjectDatas($line)); diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index fa22c00d98b..fa328d51da8 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -861,13 +861,13 @@ class Project extends CommonObject /** * Return list of elements for type, linked to a project * - * @param string $type 'propal','order','invoice','order_supplier','invoice_supplier',... - * @param string $tablename name of table associated of the type - * @param string $datefieldname name of date field for filter - * @param int $date_start Start date - * @param int $date_end End date - * @param string $projectkey Equivalent key to fk_projet for actual type - * @return mixed Array list of object ids linked to project, < 0 or string if error + * @param string $type 'propal','order','invoice','order_supplier','invoice_supplier',... + * @param string $tablename name of table associated of the type + * @param string $datefieldname name of date field for filter + * @param ?int $date_start Start date + * @param ?int $date_end End date + * @param string $projectkey Equivalent key to fk_projet for actual type + * @return array|int<-1,-1>|string Array list of object ids linked to project, < 0 or string if error */ public function get_element_list($type, $tablename, $datefieldname = '', $date_start = null, $date_end = null, $projectkey = 'fk_projet') { @@ -884,23 +884,23 @@ class Project extends CommonObject $ids = $this->id; if ($type == 'agenda') { - $sql = "SELECT id as rowid FROM ".MAIN_DB_PREFIX."actioncomm WHERE fk_project IN (".$this->db->sanitize($ids).") AND entity IN (".getEntity('agenda').")"; + $sql = "SELECT id as rowid FROM ".MAIN_DB_PREFIX."actioncomm WHERE fk_project IN (".$this->db->sanitize((string) $ids).") AND entity IN (".getEntity('agenda').")"; } elseif ($type == 'expensereport') { - $sql = "SELECT ed.rowid FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND e.entity IN (".getEntity('expensereport').") AND ed.fk_projet IN (".$this->db->sanitize($ids).")"; + $sql = "SELECT ed.rowid FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND e.entity IN (".getEntity('expensereport').") AND ed.fk_projet IN (".$this->db->sanitize((string) $ids).")"; } elseif ($type == 'project_task') { - $sql = "SELECT DISTINCT pt.rowid FROM ".MAIN_DB_PREFIX."projet_task as pt WHERE pt.fk_projet IN (".$this->db->sanitize($ids).")"; + $sql = "SELECT DISTINCT pt.rowid FROM ".MAIN_DB_PREFIX."projet_task as pt WHERE pt.fk_projet IN (".$this->db->sanitize((string) $ids).")"; } elseif ($type == 'element_time') { // Case we want to duplicate line foreach user - $sql = "SELECT DISTINCT pt.rowid, ptt.fk_user FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."element_time as ptt WHERE pt.rowid = ptt.fk_element AND ptt.elementtype = 'task' AND pt.fk_projet IN (".$this->db->sanitize($ids).")"; + $sql = "SELECT DISTINCT pt.rowid, ptt.fk_user FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."element_time as ptt WHERE pt.rowid = ptt.fk_element AND ptt.elementtype = 'task' AND pt.fk_projet IN (".$this->db->sanitize((string) $ids).")"; } elseif ($type == 'stocktransfer_stocktransfer') { - $sql = "SELECT ms.rowid, ms.fk_user_author as fk_user FROM ".MAIN_DB_PREFIX."stocktransfer_stocktransfer as ms, ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = ms.fk_entrepot AND e.entity IN (".getEntity('stock').") AND ms.origintype = 'project' AND ms.fk_origin IN (".$this->db->sanitize($ids).") AND ms.type_mouvement = 1"; + $sql = "SELECT ms.rowid, ms.fk_user_author as fk_user FROM ".MAIN_DB_PREFIX."stocktransfer_stocktransfer as ms, ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = ms.fk_entrepot AND e.entity IN (".getEntity('stock').") AND ms.origintype = 'project' AND ms.fk_origin IN (".$this->db->sanitize((string) $ids).") AND ms.type_mouvement = 1"; } elseif ($type == 'loan') { - $sql = "SELECT l.rowid, l.fk_user_author as fk_user FROM ".MAIN_DB_PREFIX."loan as l WHERE l.entity IN (".getEntity('loan').") AND l.fk_projet IN (".$this->db->sanitize($ids).")"; + $sql = "SELECT l.rowid, l.fk_user_author as fk_user FROM ".MAIN_DB_PREFIX."loan as l WHERE l.entity IN (".getEntity('loan').") AND l.fk_projet IN (".$this->db->sanitize((string) $ids).")"; } else { - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$tablename." WHERE ".$projectkey." IN (".$this->db->sanitize($ids).") AND entity IN (".getEntity($type).")"; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$tablename." WHERE ".$projectkey." IN (".$this->db->sanitize((string) $ids).") AND entity IN (".getEntity($type).")"; } if (isDolTms($date_start) && $type == 'loan') { - $sql .= " AND (dateend > '".$this->db->idate($date_start)."' OR dateend IS NULL)"; + $sql .= " AND (dateend > '".$this->db->idate((int) $date_start)."' OR dateend IS NULL)"; } elseif (isDolTms($date_start) && ($type != 'project_task')) { // For table project_taks, we want the filter on date apply on project_time_spent table if (empty($datefieldname) && !empty($this->table_element_date)) { $datefieldname = $this->table_element_date; @@ -908,11 +908,11 @@ class Project extends CommonObject if (empty($datefieldname)) { return 'Error this object has no date field defined'; } - $sql .= " AND (".$datefieldname." >= '".$this->db->idate($date_start)."' OR ".$datefieldname." IS NULL)"; + $sql .= " AND (".$datefieldname." >= '".$this->db->idate((int) $date_start)."' OR ".$datefieldname." IS NULL)"; } if (isDolTms($date_end) && $type == 'loan') { - $sql .= " AND (datestart < '".$this->db->idate($date_end)."' OR datestart IS NULL)"; + $sql .= " AND (datestart < '".$this->db->idate((int) $date_end)."' OR datestart IS NULL)"; } elseif (isDolTms($date_end) && ($type != 'project_task')) { // For table project_taks, we want the filter on date apply on project_time_spent table if (empty($datefieldname) && !empty($this->table_element_date)) { $datefieldname = $this->table_element_date; @@ -920,7 +920,7 @@ class Project extends CommonObject if (empty($datefieldname)) { return 'Error this object has no date field defined'; } - $sql .= " AND (".$datefieldname." <= '".$this->db->idate($date_end)."' OR ".$datefieldname." IS NULL)"; + $sql .= " AND (".$datefieldname." <= '".$this->db->idate((int) $date_end)."' OR ".$datefieldname." IS NULL)"; } $parameters = array( @@ -1411,18 +1411,18 @@ class Project extends CommonObject } /** - * Return clickable name (with picto eventually) + * Return clickable name (with optional picto) * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param string $option Variant where the link point to ('', 'nolink') - * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string - * @param string $moreinpopup Text to add into popup - * @param string $sep Separator between ref and label if option addlabel is set - * @param int $notooltip 1=Disable tooltip - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @param string $morecss More css on a link - * @param string $save_pageforbacktolist Back to this page 'context:url' - * @return string String with URL + * @param int<0,2> $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @param string $option Variant where the link point to ('', 'nolink') + * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string + * @param string $moreinpopup Text to add into popup + * @param string $sep Separator between ref and label if option addlabel is set + * @param int<0,1> $notooltip 1=Disable tooltip + * @param int<-1,1> $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @param string $morecss More css on a link + * @param string $save_pageforbacktolist Back to this page 'context:url' + * @return string String with URL */ public function getNomUrl($withpicto = 0, $option = '', $addlabel = 0, $moreinpopup = '', $sep = ' - ', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '', $save_pageforbacktolist = '') { @@ -1740,17 +1740,17 @@ class Project extends CommonObject /** * Load an object from its id and create a new one in database * - * @param User $user User making the clone - * @param int $fromid Id of object to clone - * @param bool $clone_contact Clone contact of project - * @param bool $clone_task Clone task of project - * @param bool $clone_project_file Clone file of project - * @param bool $clone_task_file Clone file of task (if task are copied) - * @param bool $clone_note Clone note of project - * @param bool $move_date Move task date on clone - * @param int $notrigger No trigger flag - * @param int $newthirdpartyid New thirdparty id - * @return int New id of clone + * @param User $user User making the clone + * @param int $fromid Id of object to clone + * @param bool|int<0,1> $clone_contact Clone contact of project + * @param bool|int<0,1> $clone_task Clone task of project + * @param bool|int<0,1> $clone_project_file Clone file of project + * @param bool|int<0,1> $clone_task_file Clone file of task (if task are copied) + * @param bool|int<0,1> $clone_note Clone note of project + * @param bool|int<0,1> $move_date Move task date on clone + * @param int<0,1> $notrigger No trigger flag + * @param int $newthirdpartyid New thirdparty id + * @return int New id of clone */ public function createFromClone(User $user, $fromid, $clone_contact = false, $clone_task = true, $clone_project_file = false, $clone_task_file = false, $clone_note = true, $move_date = true, $notrigger = 0, $newthirdpartyid = 0) { diff --git a/htdocs/projet/class/projectstats.class.php b/htdocs/projet/class/projectstats.class.php index 90eb6b41040..892171de15e 100644 --- a/htdocs/projet/class/projectstats.class.php +++ b/htdocs/projet/class/projectstats.class.php @@ -1,7 +1,7 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -224,7 +224,7 @@ class ProjectStats extends Stats } if (!empty($this->status)) { - $sqlwhere[] = " t.fk_statut IN (".$this->db->sanitize($this->status).")"; + $sqlwhere[] = " t.fk_statut IN (".$this->db->sanitize((string) $this->status).")"; } if (!empty($this->opp_status)) { diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index d76e3a605f4..da26f12997b 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -674,7 +674,7 @@ class Task extends CommonObjectLine // Update request $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task SET"; $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; - $sql .= " ref=".(isset($this->ref) ? "'".$this->db->escape($this->ref)."'" : "'".$this->db->escape($this->id)."'").","; + $sql .= " ref=".(isset($this->ref) ? "'".$this->db->escape($this->ref)."'" : "'".$this->db->escape((string) $this->id)."'").","; $sql .= " fk_task_parent=".(isset($this->fk_task_parent) ? $this->fk_task_parent : "null").","; $sql .= " label=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; $sql .= " description=".(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").","; @@ -1121,24 +1121,24 @@ class Task extends CommonObjectLine * Return list of tasks for all projects or for one particular project * Sort order is on project, then on position of task, and last on start date of first level task * - * @param ?User $usert Object user to limit tasks affected to a particular user - * @param ?User $userp Object user to limit projects of a particular user and public projects - * @param int $projectid Project id - * @param int $socid Third party id - * @param int $mode 0=Return list of tasks and their projects, 1=Return projects and tasks if exists - * @param string $filteronproj Filter on project ref or label - * @param string $filteronprojstatus Filter on project status ('-1'=no filter, '0,1'=Draft+Validated only) - * @param string $morewherefilter Add more filter into where SQL request (must start with ' AND ...') - * @param int $filteronprojuser Filter on user that is a contact of project - * @param int $filterontaskuser Filter on user assigned to task - * @param ?Extrafields $extrafields Show additional column from project or task - * @param int $includebilltime Calculate also the time to bill and billed + * @param ?User $usert Object user to limit tasks affected to a particular user + * @param ?User $userp Object user to limit projects of a particular user and public projects + * @param int $projectid Project id + * @param int $socid Third party id + * @param int<0,1> $mode 0=Return list of tasks and their projects, 1=Return projects and tasks if exists + * @param string $filteronproj Filter on project ref or label + * @param string $filteronprojstatus Filter on project status ('-1'=no filter, '0,1'=Draft+Validated only) + * @param string $morewherefilter Add more filter into where SQL request (must start with ' AND ...') + * @param int<0,1> $filteronprojuser Filter on user that is a contact of project + * @param int<0,1> $filterontaskuser Filter on user assigned to task + * @param ?Extrafields $extrafields Show additional column from project or task + * @param int<0,1> $includebilltime Calculate also the time to bill and billed * @param array $search_array_options Array of search filters. Not Used yet. - * @param int $loadextras Fetch all Extrafields on each project and task - * @param int $loadRoleMode 1= will test Roles on task; 0 used in delete project action - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @return Task[]|string Array of tasks + * @param int<0,1> $loadextras Fetch all Extrafields on each project and task + * @param int<0,1> $loadRoleMode 1= will test Roles on task; 0 used in delete project action + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @return Task[]|string Array of tasks */ public function getTasksArray($usert = null, $userp = null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj = '', $filteronprojstatus = '-1', $morewherefilter = '', $filteronprojuser = 0, $filterontaskuser = 0, $extrafields = null, $includebilltime = 0, $search_array_options = array(), $loadextras = 0, $loadRoleMode = 1, $sortfield = '', $sortorder = '') { @@ -1244,7 +1244,7 @@ class Task extends CommonObjectLine $sql .= " AND p.fk_soc = ".((int) $socid); } if ($projectid) { - $sql .= " AND p.rowid IN (".$this->db->sanitize($projectid).")"; + $sql .= " AND p.rowid IN (".$this->db->sanitize((string) $projectid).")"; } if ($filteronproj) { $sql .= natural_search(array("p.ref", "p.title"), $filteronproj); @@ -1907,11 +1907,11 @@ class Task extends CommonObjectLine } if ($dates > 0) { $datefieldname = "element_datehour"; - $sql .= " AND (".$datefieldname." >= '".$this->db->idate($dates)."' OR ".$datefieldname." IS NULL)"; + $sql .= " AND (".$datefieldname." >= '".$this->db->idate((int) $dates)."' OR ".$datefieldname." IS NULL)"; } if ($datee > 0) { $datefieldname = "element_datehour"; - $sql .= " AND (".$datefieldname." <= '".$this->db->idate($datee)."' OR ".$datefieldname." IS NULL)"; + $sql .= " AND (".$datefieldname." <= '".$this->db->idate((int) $datee)."' OR ".$datefieldname." IS NULL)"; } //print $sql; @@ -2220,7 +2220,7 @@ class Task extends CommonObjectLine if (!$error) { $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; - $sql .= " SET duration_effective = duration_effective - ".$this->db->escape($this->timespent_duration ? $this->timespent_duration : 0); + $sql .= " SET duration_effective = duration_effective - ".$this->db->escape($this->timespent_duration ? (string) $this->timespent_duration : '0'); $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG); @@ -2291,7 +2291,7 @@ class Task extends CommonObjectLine require_once DOL_DOCUMENT_ROOT."/core/modules/project/task/" . getDolGlobalString('PROJECT_TASK_ADDON').'.php'; $modTask = new $obj(); '@phan-var-force ModeleNumRefTask $modTask'; - $defaultref = $modTask->getNextValue(0, $clone_task); + $defaultref = $modTask->getNextValue(null, $clone_task); } $ori_project_id = $clone_task->fk_project; diff --git a/htdocs/projet/class/taskstats.class.php b/htdocs/projet/class/taskstats.class.php index 3db3f872217..99a176c9470 100644 --- a/htdocs/projet/class/taskstats.class.php +++ b/htdocs/projet/class/taskstats.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -162,7 +162,7 @@ class TaskStats extends Stats $sqlwhere[] = " t.datec BETWEEN '".$this->db->idate(dol_get_first_day($this->year, $this->month))."' AND '".$this->db->idate(dol_get_last_day($this->year, $this->month))."'"; } if (!empty($this->priority)) { - $sqlwhere[] = " t.priority IN (".$this->db->sanitize($this->priority, 1).")"; + $sqlwhere[] = " t.priority IN (".$this->db->sanitize((string) $this->priority, 1).")"; } if (count($sqlwhere) > 0) { diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php index f04c1df9ae6..22f4d4a33a9 100644 --- a/htdocs/projet/contact.php +++ b/htdocs/projet/contact.php @@ -1,7 +1,7 @@ * Copyright (C) 2012-2015 Laurent Destailleur - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -88,16 +88,16 @@ if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } +$formconfirmtoaddtasks = ''; if (empty($reshook)) { // Test if we can add contact to the tasks at the same times, if not or not required, make a redirect - $formconfirmtoaddtasks = ''; if ($action == 'addcontact' && $permissiontoadd) { $form = new Form($db); $source = GETPOST("source", 'aZ09'); $taskstatic = new Task($db); - $task_array = $taskstatic->getTasksArray(0, 0, $object->id, 0, 0); + $task_array = $taskstatic->getTasksArray(null, null, $object->id, 0, 0); $nbTasks = count($task_array); //If no task available, redirec to to add confirm @@ -191,7 +191,7 @@ if (empty($reshook)) { if ($result > 0) { $excludefilter = 'statut = 1'; $tmpcontactarray = $usergroup->listUsersForGroup($excludefilter, 0); - if ($contactarray <= 0) { + if (!is_array($tmpcontactarray)) { $error++; } else { foreach ($tmpcontactarray as $tmpuser) { @@ -245,7 +245,7 @@ if (empty($reshook)) { foreach ($task_to_affect as $task_id) { if (GETPOSTISSET('person_'.$task_id) && GETPOST('person_'.$task_id, 'san_alpha')) { $tasksToAffect = new Task($db); - $result = $tasksToAffect->fetch($task_id); + $result = $tasksToAffect->fetch((int) $task_id); if ($result < 0) { setEventMessages($tasksToAffect->error, null, 'errors'); } else { diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 21fea1424d9..7d03c54a5b6 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -737,7 +737,7 @@ if (!empty($hookmanager->resArray)) { if ($action == "addelement") { $tablename = GETPOST("tablename"); - $elementselectid = GETPOST("elementselect"); + $elementselectid = GETPOSTINT("elementselect"); $result = $object->update_element($tablename, $elementselectid); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -766,10 +766,10 @@ if (!$showdatefilter) { print ''; print ''; print '
'; - print $form->selectDate($dates, 'dates', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print $form->selectDate((int) $dates, 'dates', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); print '
'; print '
'; - print $form->selectDate($datee, 'datee', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print $form->selectDate((int) $datee, 'datee', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); print '
'; print '
'; print ''; @@ -866,8 +866,8 @@ foreach ($listofreferent as $key => $value) { $num = count($elementarray); for ($i = 0; $i < $num; $i++) { $tmp = explode('_', $elementarray[$i]); - $idofelement = $tmp[0]; - $idofelementuser = !empty($tmp[1]) ? $tmp[1] : ""; + $idofelement = (int) $tmp[0]; + $idofelementuser = !empty($tmp[1]) ? (int) $tmp[1] : 0; $element->fetch($idofelement); if ($idofelementuser) { @@ -896,15 +896,20 @@ foreach ($listofreferent as $key => $value) { // Define $total_ht_by_line if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') { + '@phan-var-force ChargeSociales|PaymentVarious|Salary $element'; $total_ht_by_line = $element->amount; } elseif ($tablename == 'fichinter') { + '@phan-var-force Fichinter $element'; $total_ht_by_line = $element->getAmount(); } elseif ($tablename == 'stock_mouvement') { + '@phan-var-force MouvementStock $element'; $total_ht_by_line = $element->price * abs($element->qty); } elseif ($tablename == 'projet_task') { - $tmp = $element->getSumOfAmount($idofelementuser ? $elementuser : '', $dates, $datee); + '@phan-var-force Task $element'; + $tmp = $element->getSumOfAmount($idofelementuser ? $elementuser : '', (string) $dates, (string) $datee); $total_ht_by_line = price2num($tmp['amount'], 'MT'); } elseif ($key == 'loan') { + '@phan-var-force Loan $element'; if ((empty($dates) && empty($datee)) || (intval($dates) <= $element->datestart && intval($datee) >= $element->dateend)) { // Get total loan $total_ht_by_line = -$element->capital; @@ -933,12 +938,16 @@ foreach ($listofreferent as $key => $value) { // Define $total_ttc_by_line if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') { + '@phan-var-force ChargeSociales|PaymentVarious|Salary $element'; $total_ttc_by_line = $element->amount; } elseif ($tablename == 'fichinter') { + '@phan-var-force Fichinter $element'; $total_ttc_by_line = $element->getAmount(); } elseif ($tablename == 'stock_mouvement') { + '@phan-var-force MouvementStock $element'; $total_ttc_by_line = $element->price * abs($element->qty); } elseif ($tablename == 'projet_task') { + '@phan-var-force Task $element'; $defaultvat = get_default_tva($mysoc, $mysoc); $reg = array(); if (preg_replace('/^(\d+\.)\s\(.*\)/', $defaultvat, $reg)) { @@ -1101,7 +1110,7 @@ foreach ($listofreferent as $key => $value) { $exclude_select_element[] = $value['exclude_select_element']; } - if ($qualified) { + if ($qualified && $tablename !== null) { // If we want the project task array to have details of users //if ($key == 'project_task') $key = 'project_task_time'; @@ -1268,8 +1277,8 @@ foreach ($listofreferent as $key => $value) { $total_time = 0; for ($i = 0; $i < $num; $i++) { $tmp = explode('_', $elementarray[$i]); - $idofelement = $tmp[0]; - $idofelementuser = isset($tmp[1]) ? $tmp[1] : ""; + $idofelement = (int) $tmp[0]; + $idofelementuser = isset($tmp[1]) ? (int) $tmp[1] : 0; $element->fetch($idofelement); if ($idofelementuser) { @@ -1390,6 +1399,7 @@ foreach ($listofreferent as $key => $value) { print "\n"; // Product and qty on stock movement if ('MouvementStock' == $classname) { + '@phan-var-force MouvementStock $element'; $mvsProd = new Product($element->db); $mvsProd->fetch($element->product_id); print '
'; @@ -1397,28 +1407,38 @@ foreach ($listofreferent as $key => $value) { } // Date or TimeSpent $date = ''; - $total_time_by_line = null; + $total_time_by_line = 0; if ($tablename == 'expensereport_det') { + '@phan-var-force ExpenseReportLine $element'; $date = $element->date; // No draft status on lines } elseif ($tablename == 'stock_mouvement') { + '@phan-var-force MouvementStock $element'; $date = $element->datem; } elseif ($tablename == 'salary') { + '@phan-var-force Salary $element'; $date = $element->datesp; } elseif ($tablename == 'payment_various') { + '@phan-var-force PaymentVarious $element'; $date = $element->datev; } elseif ($tablename == 'chargesociales') { + '@phan-var-force ChargeSociales $element'; $date = $element->date_ech; } elseif (!empty($element->status) || !empty($element->statut) || !empty($element->fk_status)) { if ($tablename == 'don') { - $date = $element->datedon; + '@phan-var-force Don $element'; + $date = $element->date; } if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') { + '@phan-var-force CommandeFournisseur $element'; $date = ($element->date_commande ? $element->date_commande : $element->date_valid); } elseif ($tablename == 'supplier_proposal') { + '@phan-var-force SupplierProposal $element'; $date = $element->date_validation; // There is no other date for this } elseif ($tablename == 'fichinter') { + '@phan-var-force Fichinter $element'; $date = $element->datev; // There is no other date for this } elseif ($tablename == 'projet_task') { + '@phan-var-force Task $element'; $date = ''; // We show no date. Showing date of beginning of task make user think it is date of time consumed } else { $date = $element->date; // invoice, ... @@ -1429,21 +1449,25 @@ foreach ($listofreferent as $key => $value) { $date = $element->datev; } if (empty($date) && !empty($datefieldname)) { + // @phan-suppress-next-line PhanUndeclaredProperty $date = $element->$datefieldname; } } } elseif ($key == 'loan') { + '@phan-var-force Loan $element'; $date = $element->datestart; } print ''; // Add duration and store it in counter for fichinter if ($tablename == 'fichinter') { + '@phan-var-force FichInter $element'; print ''; if (in_array($tablename, array('projet_task'))) { print ''; print ''; @@ -1746,8 +1782,8 @@ function canApplySubtotalOn($tablename) /** * sortElementsByClientName * - * @param int[] $elementarray Element array - * @return int[] Element array sorted + * @param array $elementarray Element array + * @return array Element array sorted */ function sortElementsByClientName($elementarray) { diff --git a/htdocs/projet/ganttchart.inc.php b/htdocs/projet/ganttchart.inc.php index a887f6d24b5..c2a68c65d7c 100644 --- a/htdocs/projet/ganttchart.inc.php +++ b/htdocs/projet/ganttchart.inc.php @@ -1,7 +1,7 @@ * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -26,6 +26,13 @@ * @var DoliDB $db * @var Translate $langs */ +' +@phan-var-force string $dateformatinput +@phan-var-force string $dateformat +@phan-var-force string $datehourformat +@phan-var-force array,task_css:string,task_position:int,task_planned_workload:int,task_milestone:int,task_percent_complete:float,task_name:string,task_start_date:int,task_end_date:int,task_color:string,task_resources:string,note:string,task_parent_alternate_id:int}> $tasks +@phan-var-force array{} $task_dependencies +'; ?>
@@ -129,14 +136,14 @@ if (g.getDivId() != null) $projecttmp = new Project($db); $projecttmp->fetch($t['task_project_id']); $tmpt = array( - 'task_id' => '-'.$t['task_project_id'], - 'task_alternate_id' => '-'.$t['task_project_id'], + 'task_id' => (int) -$t['task_project_id'], + 'task_alternate_id' => (int) -$t['task_project_id'], 'task_name' => $projecttmp->ref.' '.$projecttmp->title, 'task_resources' => '', - 'task_start_date' => '', - 'task_end_date' => '', + 'task_start_date' => 0, + 'task_end_date' => 0, 'task_is_group' => 1, 'task_position' => 0, 'task_css' => 'ggroupblack', 'task_milestone' => 0, 'task_parent' => 0, 'task_parent_alternate_id' => 0, - 'task_notes' => '', + 'note' => '', 'task_planned_workload' => 0 ); constructGanttLine($tasks, $tmpt, array(), 0, $t['task_project_id']); @@ -166,10 +173,10 @@ else ,task_position:int,task_css:string,task_milestone:int,task_parent:int,task_parent_alternate_id:int}> $tarr Array of all tasks - * @param array{task_id:string,task_alternate_id:string,task_name:string,task_resources:string,task_start_date:string,task_end_date:string,task_is_group:int<0,1>,task_position:int,task_css:string,task_milestone:int,task_parent:int,task_parent_alternate_id:int} $task Array with properties of one task + * @param array,task_position:int,task_css:string,task_milestone:int,task_parent:int,task_parent_alternate_id:int}> $tarr Array of all tasks + * @param array{task_id:int,task_alternate_id:int,task_name:string,task_resources:string,task_start_date:int,task_end_date:int,task_is_group:int<0,1>,task_position:int,task_css:string,task_milestone:int,task_parent:int,task_parent_alternate_id:int} $task Array with properties of one task * @param array $task_dependencies Task dependencies (array(array(0=>idtask,1=>idtasktofinishfisrt)) * @param int $level Level * @param int $project_id Id of project @@ -280,8 +287,8 @@ function constructGanttLine($tarr, $task, $task_dependencies, $level = 0, $proje /** * Find child Gantt line * - * @param array,task_position:int,task_css:string,task_milestone:int,task_parent:int,task_parent_alternate_id:int}> $tarr tarr - * @param string $parent Parent + * @param array,task_position:int,task_css:string,task_milestone:int,task_parent:int,task_parent_alternate_id:int}> $tarr tarr + * @param int $parent Parent * @param array $task_dependencies Task dependencies * @param int $level Level * @return void @@ -298,12 +305,12 @@ function findChildGanttLine($tarr, $parent, $task_dependencies, $level) { $tmpt = array( 'task_id'=> -98, 'task_name'=>'Level '.$level, 'task_resources'=>'', 'task_start_date'=>'', 'task_end_date'=>'', - 'task_is_group'=>1, 'task_css'=>'ggroupblack', 'task_milestone'=> 0, 'task_parent'=>$tarr[$x]["task_parent"], 'task_notes'=>''); + 'task_is_group'=>1, 'task_css'=>'ggroupblack', 'task_milestone'=> 0, 'task_parent'=>$tarr[$x]["task_parent"], 'note'=>''); constructGanttLine($tasks, $tmpt, array(), 0, $tarr[$x]['task_project_id']); $old_parent_id = $tarr[$x]['task_project_id']; }*/ - constructGanttLine($tarr, $tarr[$x], $task_dependencies, $level, null); + constructGanttLine($tarr, $tarr[$x], $task_dependencies, $level, 0); findChildGanttLine($tarr, $tarr[$x]["task_id"], $task_dependencies, $level + 1); } } diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 33f7122723b..97ea895d75f 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -2,7 +2,7 @@ /* Copyright (C) 2005 Rodolphe Quiedeville * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -101,6 +101,8 @@ $help_url = "EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; llxHeader("", $title, $help_url, '', 0, 0, $arrayofjs, $arrayofcss, '', 'mod-project page-card_ganttview'); +$userWrite = 0; + if (($id > 0 && is_numeric($id)) || !empty($ref)) { // To verify role of users //$userAccess = $object->restrictedProjectArea($user,'read'); @@ -272,7 +274,7 @@ print load_fiche_titre($title, $linktotasks.'   '.$linktocreatetask, 'proje // Get list of tasks in tasksarray and taskarrayfiltered // We need all tasks (even not limited to a user because a task to user // can have a parent that is not affected to him). -$tasksarray = $task->getTasksArray(0, 0, ($object->id ? $object->id : $id), $socid, 0); +$tasksarray = $task->getTasksArray(null, null, ($object->id ? $object->id : $id), $socid, 0); // We load also tasks limited to a particular user //$tasksrole=($_REQUEST["mode"]=='mine' ? $task->getUserRolesForProjectsOrTasks(null, $user, $object->id, 0) : ''); //var_dump($tasksarray); @@ -313,7 +315,7 @@ if (count($tasksarray) > 0) { $tasks[$taskcursor]['task_css'] = 'ggroupblack'; //$tasks[$taskcursor]['task_css'] = 'gtaskblue'; } - $tasks[$taskcursor]['task_milestone'] = '0'; + $tasks[$taskcursor]['task_milestone'] = 0; $tasks[$taskcursor]['task_percent_complete'] = $val->progress; //$tasks[$taskcursor]['task_name']=$task->getNomUrl(1); //print dol_print_date($val->date_start).dol_print_date($val->date_end).'
'."\n"; diff --git a/htdocs/projet/graph_opportunities.inc.php b/htdocs/projet/graph_opportunities.inc.php index 78d3ead854d..9ddb37a5d26 100644 --- a/htdocs/projet/graph_opportunities.inc.php +++ b/htdocs/projet/graph_opportunities.inc.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024-2025 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -29,6 +29,13 @@ * @var int $socid * @var string[] $listofoppstatus */ +' +@phan-var-force string $projectsListId +@phan-var-force int $socid +@phan-var-force string[] $listofoppstatus +@phan-var-force ?array $listofopplabel +@phan-var-force array $colorseries +'; if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) { $sql = "SELECT p.fk_opp_status as opp_status, cls.code, COUNT(p.rowid) as nb, SUM(p.opp_amount) as opp_amount, SUM(p.opp_amount * p.opp_percent) as ponderated_opp_amount"; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index c606b0d14f1..71c71590c54 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -8,7 +8,7 @@ * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2019 Juanjo Menent * Copyright (C) 2020 Tobias Sean - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Benjamin Falière * Copyright (C) 2024 William Mead @@ -246,8 +246,8 @@ foreach ($object->fields as $key => $val) { $visible = (int) dol_eval((string) $val['visible'], 1, 1, '1'); $arrayfields['p.'.$key] = array( 'label' => $val['label'], - 'checked' => (($visible < 0) ? 0 : 1), - 'enabled' => (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)), + 'checked' => (($visible < 0) ? '0' : '1'), + 'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)), 'position' => $val['position'], 'help' => isset($val['help']) ? $val['help'] : '' ); @@ -257,38 +257,48 @@ foreach ($object->fields as $key => $val) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; // Add non object fields to fields for list -$arrayfields['s.nom'] = array('label' => "ThirdParty", 'checked' => 1, 'position' => 21, 'enabled' => (!isModEnabled('societe') ? 0 : 1)); -$arrayfields['s.name_alias'] = array('label' => "AliasNameShort", 'checked' => 0, 'position' => 22); -$arrayfields['co.country_code'] = array('label' => "Country", 'checked' => -1, 'position' => 23); -$arrayfields['commercial'] = array('label' => "SaleRepresentativesOfThirdParty", 'checked' => 0, 'position' => 25); -$arrayfields['c.assigned'] = array('label' => "AssignedTo", 'checked' => 1, 'position' => 120); -$arrayfields['opp_weighted_amount'] = array('label' => 'OpportunityWeightedAmountShort', 'checked' => 0, 'enabled' => (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES') ? 0 : 1), 'position' => 106); -$arrayfields['u.login'] = array('label' => "Author", 'checked' => -1, 'position' => 165); +$arrayfields['s.nom'] = array('label' => "ThirdParty", 'checked' => '1', 'position' => 21, 'enabled' => (!isModEnabled('societe') ? '0' : '1')); +$arrayfields['s.name_alias'] = array('label' => "AliasNameShort", 'checked' => '0', 'position' => 22); +$arrayfields['co.country_code'] = array('label' => "Country", 'checked' => '-1', 'position' => 23); +$arrayfields['commercial'] = array('label' => "SaleRepresentativesOfThirdParty", 'checked' => '0', 'position' => 25); +$arrayfields['c.assigned'] = array('label' => "AssignedTo", 'checked' => '1', 'position' => 120); +$arrayfields['opp_weighted_amount'] = array('label' => 'OpportunityWeightedAmountShort', 'checked' => '0', 'enabled' => (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES') ? '0' : '1'), 'position' => 106); +$arrayfields['u.login'] = array('label' => "Author", 'checked' => '-1', 'position' => 165); // Force some fields according to search_usage filter... //if (GETPOST('search_usage_opportunity')) { //$arrayfields['p.usage_opportunity']['visible'] = 1; // Not required, filter on search_opp_status is enough //$arrayfields['p.usage_opportunity']['checked'] = 1; // Not required, filter on search_opp_status is enough //} if (GETPOST('search_usage_event_organization')) { - $arrayfields['p.fk_opp_status']['enabled'] = 0; - $arrayfields['p.opp_amount']['enabled'] = 0; - $arrayfields['p.opp_percent']['enabled'] = 0; - $arrayfields['opp_weighted_amount']['enabled'] = 0; - $arrayfields['p.usage_organize_event']['visible'] = 1; - $arrayfields['p.usage_organize_event']['checked'] = 1; + if (array_key_exists('p.fk_opp_status', $arrayfields)) { + $arrayfields['p.fk_opp_status']['enabled'] = '0'; + } + if (array_key_exists('p.fk_opp_amount', $arrayfields)) { + $arrayfields['p.opp_amount']['enabled'] = '0'; + } + if (array_key_exists('p.fk_opp_percent', $arrayfields)) { + $arrayfields['p.opp_percent']['enabled'] = '0'; + } + $arrayfields['opp_weighted_amount']['enabled'] = '0'; + if (array_key_exists('p.usage_organize_event', $arrayfields)) { + $arrayfields['p.usage_organize_event']['visible'] = '1'; + $arrayfields['p.usage_organize_event']['checked'] = '1'; + } } -$arrayfields['p.fk_project']['enabled'] = 0; +$arrayfields['p.fk_project']['enabled'] = '0'; // Force this field to be visible if ($contextpage == 'lead') { - $arrayfields['p.fk_opp_status']['enabled'] = 1; - $arrayfields['p.fk_opp_status']['visible'] = 1; + if (array_key_exists('p.fk_opp_status', $arrayfields)) { + $arrayfields['p.fk_opp_status']['enabled'] = '1'; + $arrayfields['p.fk_opp_status']['visible'] = '1'; + } } $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); -'@phan-var-force array,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan +// '@phan-var-force array $arrayfields'; // dol_sort_array looses type for Phan // Add a groupby field. Set $groupby and $groupbyvalues. // TODO Move this into a inc file @@ -1203,7 +1213,7 @@ $includeonly = ''; if (!$user->hasRight('user', 'user', 'lire')) { $includeonly = array($user->id); } -$moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_project_user ? $search_project_user : '', 'search_project_user', $tmptitle, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx'); +$moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_project_user ? $search_project_user : '', 'search_project_user', $tmptitle, null, 0, $includeonly, '', '0', 0, 0, '', 0, '', 'maxwidth300 widthcentpercentminusx'); $moreforfilter .= '
'; $moreforfilter .= '
'; @@ -1291,7 +1301,7 @@ if (!empty($arrayfields['s.nom']['checked'])) { $tmpthirdparty->fetch($socid); $search_societe = $tmpthirdparty->name; } - print ''; + print ''; print ''; } @@ -1527,14 +1537,17 @@ if (!empty($arrayfields['c.assigned']['checked'])) { $totalarray['nbfield']++; } if (!empty($arrayfields['p.fk_opp_status']['checked'])) { + // @phan-suppress-next-line PhanTypeInvalidDimOffset print_liste_field_titre($arrayfields['p.fk_opp_status']['label'], $_SERVER["PHP_SELF"], 'p.fk_opp_status', "", $param, '', $sortfield, $sortorder, 'center '); $totalarray['nbfield']++; } if (!empty($arrayfields['p.opp_amount']['checked'])) { + // @phan-suppress-next-line PhanTypeInvalidDimOffset print_liste_field_titre($arrayfields['p.opp_amount']['label'], $_SERVER["PHP_SELF"], 'p.opp_amount', "", $param, '', $sortfield, $sortorder, 'right '); $totalarray['nbfield']++; } if (!empty($arrayfields['p.opp_percent']['checked'])) { + // @phan-suppress-next-line PhanTypeInvalidDimOffset print_liste_field_titre($arrayfields['p.opp_percent']['label'], $_SERVER['PHP_SELF'], 'p.opp_percent', "", $param, '', $sortfield, $sortorder, 'right '); $totalarray['nbfield']++; } @@ -1559,6 +1572,7 @@ if (!empty($arrayfields['p.usage_bill_time']['checked'])) { $totalarray['nbfield']++; } if (!empty($arrayfields['p.usage_organize_event']['checked'])) { + // @phan-suppress-next-line PhanTypeInvalidDimOffset print_liste_field_titre($arrayfields['p.usage_organize_event']['label'], $_SERVER["PHP_SELF"], 'p.usage_organize_event', "", $param, '', $sortfield, $sortorder, ''); $totalarray['nbfield']++; } diff --git a/htdocs/webservices/server_project.php b/htdocs/webservices/server_project.php index 4f9091a3df4..87921d46d99 100644 --- a/htdocs/webservices/server_project.php +++ b/htdocs/webservices/server_project.php @@ -420,7 +420,7 @@ function getProject($authentication, $id = '', $ref = '') foreach ($listofreferent as $key => $tablename) { $elements[$key] = array(); $element_array = $project->get_element_list($key, $tablename); - if (count($element_array) > 0 && is_array($element_array)) { + if (is_array($element_array) && count($element_array) > 0) { foreach ($element_array as $element) { $tmp = explode('_', $element); $idofelement = count($tmp) > 0 ? $tmp[0] : ""; From b4f06c8f1c49209072860e249aec4ccbc931ba63 Mon Sep 17 00:00:00 2001 From: NefiteTifall | Nicolas Date: Tue, 11 Feb 2025 10:20:23 +0100 Subject: [PATCH 600/602] =?UTF-8?q?=F0=9F=94=A7=20Remove=20escape?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminated unnecessary escaping of help text in button titles, simplifying the code and ensuring that the title attribute directly uses the provided help text without modification. --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b21a6f45fe9..0c3ce6892f0 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -13024,7 +13024,7 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u ); if (!empty($helpText)) { - $attr['title'] = dol_escape_php($helpText); + $attr['title'] = $helpText; } elseif ($label) { // empty($attr['title']) && $attr['title'] = $label; $useclassfortooltip = 0; From 9055ab3b4c908447ad84b2c9b4cfc98119e148b9 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 11 Feb 2025 10:55:34 +0100 Subject: [PATCH 601/602] css --- htdocs/theme/eldy/global.inc.php | 4 ++-- htdocs/theme/md/style.css.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 082c4bc1ff5..2b42d7f9937 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5509,8 +5509,8 @@ div.boximport { .fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor) !important; } -td.widthpictotitle, .table-fiche-title img.widthpictotitle { width: 38px; text-align: ; } -span.widthpictotitle { font-size: 1.7em; } +td.widthpictotitle, .table-fiche-title img.widthpictotitle { width: 34px; text-align: ; } +span.widthpictotitle { font-size: 1.5em; } table.titlemodulehelp tr td img.widthpictotitle { width: 80px; } .dolgraphtitle { margin-top: 6px; margin-bottom: 4px; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index afa4c41ddf7..185e9916abb 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2835,7 +2835,7 @@ td.nobordernopadding.widthpictotitle.col-picto { width: 14px; } span.widthpictotitle { - font-size: 1.3em; + font-size: 1em; } .table-list-of-attached-files .col-picto, .table-list-of-links .col-picto { opacity: 0.7 !important; From a4e39ba1be5e2fb50dc4702686d619489c61f1d2 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 11 Feb 2025 11:01:24 +0100 Subject: [PATCH 602/602] Debug v21 --- htdocs/core/lib/functions.lib.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0c3ce6892f0..87edd5fc92e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -13001,7 +13001,7 @@ function getFieldErrorIcon($fieldValidationErrorMsg) */ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $url = '', $id = '', $status = 1, $params = array()) { - global $langs, $conf, $user; + global $langs, $user; // Actually this conf is used in css too for external module compatibility and smooth transition to this function if (getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED') && (!$user->admin) && $status <= 0) { @@ -13038,9 +13038,9 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u $attr['href'] = ''; if ($status == -1) { // disable - $attr['title'] = dol_escape_htmltag($langs->transnoentitiesnoconv("FeatureDisabled")); + $attr['title'] = $langs->transnoentitiesnoconv("FeatureDisabled"); } elseif ($status == 0) { // Not enough permissions - $attr['title'] = dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")); + $attr['title'] = $langs->transnoentitiesnoconv("NotEnoughPermissions"); } } @@ -13071,6 +13071,7 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u // TODO : add a hook + // Generate attributes with escapement $TCompiledAttr = array(); foreach ($attr as $key => $value) { $TCompiledAttr[] = $key.'="'.dol_escape_htmltag($value).'"'; // Do not use dolPrintHTMLForAttribute() here, we must accept "javascript:string"
'.$langs->trans("CompanyInfo").''.$langs->trans("Value").'
'.$langs->trans("CompanyInfo").'
'; diff --git a/htdocs/admin/bank.php b/htdocs/admin/bank.php index 18b5dff4645..2e1afa189cc 100644 --- a/htdocs/admin/bank.php +++ b/htdocs/admin/bank.php @@ -444,8 +444,8 @@ print load_fiche_titre($langs->trans("BankColorizeMovement"), '', ''); print '
'; print ''."\n"; print ''."\n"; -print ''; -print ''."\n"; +print ''; +print ''."\n"; print "\n"; print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Other attributes $cols = 2; $objectconf = $object; @@ -447,11 +447,6 @@ if ($projectid > 0) { print '
'.$langs->trans("Name").''.$langs->trans("Value").''.$langs->trans("Parameter").'
'; diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php index a2d261159e0..f425524f3cc 100644 --- a/htdocs/admin/barcode.php +++ b/htdocs/admin/barcode.php @@ -450,7 +450,7 @@ print '
'; print ''; print ''; print ''; -print ''; +print ''; print ''; print ''; diff --git a/htdocs/admin/bom.php b/htdocs/admin/bom.php index 1c28ed4c482..1c4f0b4377a 100644 --- a/htdocs/admin/bom.php +++ b/htdocs/admin/bom.php @@ -456,7 +456,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; print ''; -print ''; +print ''; print "\n"; print "\n"; diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php index 49cb87e885c..ba4836f815c 100644 --- a/htdocs/admin/clicktodial.php +++ b/htdocs/admin/clicktodial.php @@ -92,8 +92,8 @@ print ''; print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; -print ''; -print ''; +print ''; +print ''; print "\n"; diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index e3d08bb29cb..68856768f08 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -899,7 +899,7 @@ if ($mysoc->country_code == 'GR') { print '
'.$langs->trans("Name").''.$langs->trans("Value").''.$langs->trans("Parameter").'
'; print ''; print ''; - print ''; + print ''; print ''; print "\n"; diff --git a/htdocs/admin/contract.php b/htdocs/admin/contract.php index cf91b5fb5cb..ae676a142fd 100644 --- a/htdocs/admin/contract.php +++ b/htdocs/admin/contract.php @@ -497,7 +497,7 @@ print '
'; print '
'.$langs->trans("AccountParameter").''.$langs->trans("Value").'
'; print ''; print ''; -print ''; +print ''; print "\n"; $substitutionarray = pdf_getSubstitutionArray($langs, array('objectamount'), null, 2); diff --git a/htdocs/admin/dav.php b/htdocs/admin/dav.php index 76bfbd63b8f..6099d183348 100644 --- a/htdocs/admin/dav.php +++ b/htdocs/admin/dav.php @@ -102,7 +102,7 @@ if ($action == 'edit') { print ''; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print ''; + print ''; foreach ($arrayofparameters as $key => $val) { if (isset($val['enabled']) && empty($val['enabled'])) { @@ -138,7 +138,7 @@ if ($action == 'edit') { print '
'; } else { print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; - print ''; + print ''; foreach ($arrayofparameters as $key => $val) { if (isset($val['enabled']) && empty($val['enabled'])) { diff --git a/htdocs/admin/debugbar.php b/htdocs/admin/debugbar.php index 9d1356362ba..6f77e1ef4e9 100644 --- a/htdocs/admin/debugbar.php +++ b/htdocs/admin/debugbar.php @@ -97,7 +97,7 @@ print ''; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/delais.php b/htdocs/admin/delais.php index fe17368d821..092ec5bc5fc 100644 --- a/htdocs/admin/delais.php +++ b/htdocs/admin/delais.php @@ -249,11 +249,11 @@ if ($action == 'edit') { // Show if meteo is enabled print '
'.$langs->trans("Parameter").''.$langs->trans("Value").''.$langs->trans("Parameter").'
'; - print ''; + print ''; print ''; print ''; print '
'.$langs->trans("Option").''.$langs->trans("Value").'
'.$langs->trans("Option").'
'.$langs->trans("MAIN_DISABLE_METEO").''; - print $form->selectarray('MAIN_DISABLE_METEO', $labelmeteo, (!getDolGlobalString('MAIN_DISABLE_METEO') ? 0 : $conf->global->MAIN_DISABLE_METEO)); + print $form->selectarray('MAIN_DISABLE_METEO', $labelmeteo, getDolGlobalInt('MAIN_DISABLE_METEO')); print '
'; @@ -263,7 +263,7 @@ if ($action == 'edit') { */ print ''; - print ''; + print ''; foreach ($modules as $module => $delays) { if (isModEnabled($module)) { @@ -283,7 +283,7 @@ if ($action == 'edit') { // Show if meteo is enabled print '
'.$langs->trans("DelaysOfToleranceBeforeWarning").''.$langs->trans("Value").'
'.$langs->trans("DelaysOfToleranceBeforeWarning").'
'; - print ''; + print ''; print ''; print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Other attributes $cols = 2; $savobject = $object; @@ -1047,11 +1047,6 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print '
'.$langs->trans("Option").''.$langs->trans("Value").'
'.$langs->trans("Option").'
'.$langs->trans("MAIN_DISABLE_METEO").''; diff --git a/htdocs/admin/delivery.php b/htdocs/admin/delivery.php index f8d6c1730ad..fa05a39c472 100644 --- a/htdocs/admin/delivery.php +++ b/htdocs/admin/delivery.php @@ -490,7 +490,7 @@ if (getDolGlobalString('MAIN_SUBMODULE_DELIVERY')) { print ''; print ''; print ''; - print ''; + print ''; print ''; print "\n"; diff --git a/htdocs/admin/ecm.php b/htdocs/admin/ecm.php index b881d6d6a1a..cfc02d93efa 100644 --- a/htdocs/admin/ecm.php +++ b/htdocs/admin/ecm.php @@ -96,7 +96,7 @@ print dol_get_fiche_head($head, 'ecm', '', -1, ''); print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; print ''; -print ''."\n"; +print ''."\n"; print ''; // Mail required for members diff --git a/htdocs/admin/eventorganization.php b/htdocs/admin/eventorganization.php index a92affd82cd..51eaededfb0 100644 --- a/htdocs/admin/eventorganization.php +++ b/htdocs/admin/eventorganization.php @@ -186,7 +186,7 @@ if ($action == 'edit') { print ''; print '
'.$langs->trans("Description").''.$langs->trans("Value").'
'; - print ''; + print ''; foreach ($arrayofparameters as $constname => $val) { if ($val['enabled'] == 1) { @@ -269,7 +269,7 @@ if ($action == 'edit') { } else { if (!empty($arrayofparameters)) { print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; - print ''; + print ''; foreach ($arrayofparameters as $constname => $val) { if ($val['enabled'] == 1) { diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index 9e04a9894da..edcd0469c1a 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -538,7 +538,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print ''; print ''; -print ''; +print ''; print "\n"; print "\n"; diff --git a/htdocs/admin/geoipmaxmind.php b/htdocs/admin/geoipmaxmind.php index 64bc975d3da..20716b351cf 100644 --- a/htdocs/admin/geoipmaxmind.php +++ b/htdocs/admin/geoipmaxmind.php @@ -110,7 +110,7 @@ print ''; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/holiday.php b/htdocs/admin/holiday.php index 18b7ac33f6d..b6fc587032d 100644 --- a/htdocs/admin/holiday.php +++ b/htdocs/admin/holiday.php @@ -461,27 +461,9 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").''.$langs->trans("Parameter").'
'; print ''; print ''; -print ''; +print ''; print "\n"; -//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY); -//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY); -//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY); -//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY); - -if (!isset($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY)) { - $conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY = 1; -} -if (!isset($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY)) { - $conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY = 1; -} - -//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY); -//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY); -//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY); -//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY); - - // Set working days print ''; print ""; diff --git a/htdocs/admin/hrm.php b/htdocs/admin/hrm.php index 6671a5b68ad..e80962f6d25 100644 --- a/htdocs/admin/hrm.php +++ b/htdocs/admin/hrm.php @@ -510,7 +510,7 @@ if ($action == 'edit') { print ''; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
".$langs->trans("XIsAUsualNonWorkingDay", $langs->transnoentitiesnoconv("Monday"))."
'; - print ''; + print ''; foreach ($arrayofparameters as $constname => $val) { if ($val['enabled'] == 1) { @@ -595,7 +595,7 @@ if ($action == 'edit') { } else { if (!empty($arrayofparameters)) { print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; - print ''; + print ''; foreach ($arrayofparameters as $constname => $val) { if ($val['enabled'] == 1) { diff --git a/htdocs/admin/invoice.php b/htdocs/admin/invoice.php index 736078cd4cf..e9dc88c9b96 100644 --- a/htdocs/admin/invoice.php +++ b/htdocs/admin/invoice.php @@ -792,7 +792,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; @@ -879,7 +879,7 @@ print '
'; print '
'.$langs->trans("Parameters").''.$langs->trans("Value").' 
'."\n"; print ''."\n"; print ''."\n"; -print ''."\n"; +print ''."\n"; print "\n"; print ''."\n"; print ''."\n"; diff --git a/htdocs/admin/knowledgemanagement.php b/htdocs/admin/knowledgemanagement.php index ffd63bb379c..7c7458a6901 100644 --- a/htdocs/admin/knowledgemanagement.php +++ b/htdocs/admin/knowledgemanagement.php @@ -217,7 +217,7 @@ if ($action == 'edit') { print ''; print '
'.$langs->trans("Name").''.$langs->trans("Value").'
'.$langs->trans("PathDirectory").'
'; - print ''; + print ''; // @phan-suppress-next-line PhanEmptyForeach foreach ($arrayofparameters as $constname => $val) { @@ -285,7 +285,7 @@ if ($action == 'edit') { } else { if (!empty($arrayofparameters)) { print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; - print ''; + print ''; // @phan-suppress-next-line PhanEmptyForeach foreach ($arrayofparameters as $constname => $val) { diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index c7c55268b4b..2fb95d6e572 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -198,7 +198,7 @@ print $hookmanager->resPrint; print ''; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/limits.php b/htdocs/admin/limits.php index a3e9b993621..164a0ce525c 100644 --- a/htdocs/admin/limits.php +++ b/htdocs/admin/limits.php @@ -173,7 +173,7 @@ if ($action == 'edit') { clearstatcache(); print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'.$langs->trans("Parameter").''.$langs->trans("Value").''.$langs->trans("Example").'
'; - print ''; + print ''; print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Other attributes $cols = 2; - //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + $savobject = $object; + $object = $projectstatic; + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + $object = $savobject; print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_UNIT"), $langs->trans("ParameterActiveForNextInputOnly")); @@ -204,7 +204,7 @@ if ($action == 'edit') { } else { print '
'; print ''; - print ''; + print ''; print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Other attributes $cols = 2; - //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + $savobject = $object; + $object = $projectstatic; + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + $object = $savobject; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_UNIT"), $langs->trans("ParameterActiveForNextInputOnly")); diff --git a/htdocs/admin/mailing.php b/htdocs/admin/mailing.php index 36b8553156e..73a0787486b 100644 --- a/htdocs/admin/mailing.php +++ b/htdocs/admin/mailing.php @@ -144,7 +144,7 @@ print ''; print ''; print ''; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/mails_ingoing.php b/htdocs/admin/mails_ingoing.php index 734d83f619c..a206f4bed29 100644 --- a/htdocs/admin/mails_ingoing.php +++ b/htdocs/admin/mails_ingoing.php @@ -118,7 +118,7 @@ print "

\n"; /* print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table print '
'.$langs->trans("Parameter").''.$langs->trans("Value").''.$langs->trans("Example").'
'; -print ''; +print ''; print '
'; diff --git a/htdocs/admin/mrp.php b/htdocs/admin/mrp.php index bf7c39d8b9a..0b343459e3d 100644 --- a/htdocs/admin/mrp.php +++ b/htdocs/admin/mrp.php @@ -450,7 +450,7 @@ print load_fiche_titre($langs->trans("OtherOptions"), '', ''); print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print ''; print ''; -print ''; +print ''; print "\n"; print "\n"; diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index d9a9ae5bbfc..7bf96c88081 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -202,7 +202,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; print ''; -print ''; +print ''; print "\n"; diff --git a/htdocs/admin/openinghours.php b/htdocs/admin/openinghours.php index 67289748f37..f79b92a7949 100644 --- a/htdocs/admin/openinghours.php +++ b/htdocs/admin/openinghours.php @@ -107,37 +107,37 @@ if (empty($action) || $action == 'edit' || $action == 'updateedit') { print ''."\n"; + print ''."\n"; print ''."\n"; + print ''."\n"; print ''."\n"; + print ''."\n"; print ''."\n"; + print ''."\n"; print ''."\n"; + print ''."\n"; print ''."\n"; + print ''."\n"; print ''."\n"; + print ''."\n"; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; print $form->textwithpicto($langs->trans("Monday"), $langs->trans("OpeningHoursFormatDesc")); print ''; - print '
'; print $form->textwithpicto($langs->trans("Tuesday"), $langs->trans("OpeningHoursFormatDesc")); print ''; - print '
'; print $form->textwithpicto($langs->trans("Wednesday"), $langs->trans("OpeningHoursFormatDesc")); print ''; - print '
'; print $form->textwithpicto($langs->trans("Thursday"), $langs->trans("OpeningHoursFormatDesc")); print ''; - print '
'; print $form->textwithpicto($langs->trans("Friday"), $langs->trans("OpeningHoursFormatDesc")); print ''; - print '
'; print $form->textwithpicto($langs->trans("Saturday"), $langs->trans("OpeningHoursFormatDesc")); print ''; - print '
'; print $form->textwithpicto($langs->trans("Sunday"), $langs->trans("OpeningHoursFormatDesc")); print ''; - print '
'; diff --git a/htdocs/admin/order.php b/htdocs/admin/order.php index d915eda1693..38b4dd721cf 100644 --- a/htdocs/admin/order.php +++ b/htdocs/admin/order.php @@ -649,7 +649,7 @@ print '
'; print ''; print ''; print ''; -print ''; +print ''; print "\n"; print "\n"; diff --git a/htdocs/admin/payment.php b/htdocs/admin/payment.php index c37c008ad9c..f60bed8f0c9 100644 --- a/htdocs/admin/payment.php +++ b/htdocs/admin/payment.php @@ -265,7 +265,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/paymentbybanktransfer.php b/htdocs/admin/paymentbybanktransfer.php index a4771a9013b..3d5fb00b6ac 100644 --- a/htdocs/admin/paymentbybanktransfer.php +++ b/htdocs/admin/paymentbybanktransfer.php @@ -162,7 +162,7 @@ print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; print ''; -print ''; +print ''; print ""; // Bank account (from Banks module) @@ -445,7 +445,7 @@ if (isModEnabled('notification')) print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; print ''; print ''; - print ''; + print ''; print ''; print "\n"; diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index 6101cdcc7bf..02521e57b9e 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -306,7 +306,7 @@ print load_fiche_titre($langs->trans("DictionaryPaperFormat"), '', ''); print '
'; print '
'.$langs->trans("User").''.$langs->trans("Value").''.$langs->trans("Action").'
'; -print ''; +print ''; $selected = getDolGlobalString('MAIN_PDF_FORMAT'); if (empty($selected)) { @@ -515,7 +515,7 @@ print load_fiche_titre($langs->trans("Other"), '', ''); print '
'; print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; -print ''; +print ''; // Use 2 languages into PDF diff --git a/htdocs/admin/pdf_other.php b/htdocs/admin/pdf_other.php index 39e97b2ee70..c325cec6aed 100644 --- a/htdocs/admin/pdf_other.php +++ b/htdocs/admin/pdf_other.php @@ -211,7 +211,7 @@ if (isModEnabled('propal')) { print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; - print ''; + print ''; /* This feature seems not yet used into Dolibarr. So option is kept hidden and enabled by default print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Other attributes $cols = 2; - //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + $savobject = $object; + $object = $projectstatic; + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + $object = $savobject; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; @@ -253,11 +253,12 @@ if (isModEnabled('propal')) { } if (isModEnabled('order')) { - print load_fiche_titre($langs->trans("Orders"), '', 'bill'); + $langs->load("orders"); + print load_fiche_titre($langs->trans('CustomersOrders'), '', 'order'); print '
'; print ''; - print ''; + print ''; print ''; - print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; print $form->textwithpicto($langs->trans("MAIN_PDF_ADD_TERMSOFSALE_ORDER"), $langs->trans("PdfAddTermOfSaleHelp")); print ''; @@ -268,19 +269,8 @@ if (isModEnabled('order')) { print $form->selectarray("MAIN_PDF_ADD_TERMSOFSALE_ORDER", $arrval, $conf->global->MAIN_PDF_ADD_TERMSOFSALE_ORDER); } print '
'; - print '
'; -} -if (isModEnabled('order')) { - $langs->load("orders"); - print load_fiche_titre($langs->trans('CustomersOrders'), '', 'order'); - - print '
'; - print ''; - print ''; - - print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Other attributes $cols = 2; - //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + $savobject = $object; + $object = $projectstatic; + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + $object = $savobject; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print '
'; print $form->textwithpicto($langs->trans("SALES_ORDER_SHOW_SHIPPING_ADDRESS"), $langs->trans("SALES_ORDER_SHOW_SHIPPING_ADDRESSMore")); print ''; if ($conf->use_javascript_ajax) { @@ -302,7 +292,7 @@ if (isModEnabled('supplier_proposal')) { print '
'; print ''; - print ''; + print ''; print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; @@ -702,11 +702,6 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print $form->textwithpicto($langs->trans("MAIN_GENERATE_DOCUMENTS_SUPPLIER_PROPOSAL_WITHOUT_UNIT_PRICE"), ''); @@ -337,7 +327,7 @@ if (isModEnabled('supplier_order')) { print '
'; print ''; - print ''; + print ''; print ''; } -// Visibility -print ''; - if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) { // Opportunity status print ''; +// Visibility +print ''; + // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; @@ -380,11 +380,6 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print $form->textwithpicto($langs->trans("MAIN_GENERATE_DOCUMENTS_PURCHASE_ORDER_WITHOUT_UNIT_PRICE"), ''); @@ -370,7 +360,7 @@ if (isModEnabled('invoice')) { print '
'; print ''; - print ''; + print ''; print ''; } - // Visibility - print ''; - if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && !empty($object->usage_opportunity)) { // Opportunity status print ''; + // Visibility + print ''; + // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; @@ -492,11 +492,6 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; print $form->textwithpicto($langs->trans("MAIN_PDF_ADD_TERMSOFSALE_INVOICE"), $langs->trans("PdfAddTermOfSaleHelp")); @@ -476,7 +466,7 @@ if (isModEnabled('shipping')) { print '
'; print ''; - print ''; + print ''; print '\n"; print ''; - $toBeShipped = array(); - $toBeShippedTotal = 0; while ($i < $num) { $objp = $db->fetch_object($resql); @@ -733,7 +734,7 @@ if ($id > 0 || !empty($ref)) { $text .= ' - '.$label; $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($objp->description)).'
'; $description .= $product_static->show_photos('product', $conf->product->multidir_output[$product_static->entity], 1, 1, 0, 0, 0, 80); - print $form->textwithtooltip($text, $description, 3, '', '', $i); + print $form->textwithtooltip($text, $description, 3, '', 0, (string) $i); // Show range print_date_range($db->jdate($objp->date_start), $db->jdate($objp->date_end)); @@ -754,7 +755,7 @@ if ($id > 0 || !empty($ref)) { if (!empty($objp->label)) { $text .= ' '.$objp->label.''; - print $form->textwithtooltip($text, $objp->description, 3, '', '', $i); + print $form->textwithtooltip($text, $objp->description, 3, 0, '', (string) $i); } else { print $text.' '.nl2br($objp->description); } diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index e0cd273c028..d931c854afb 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -5,7 +5,7 @@ * Copyright (C) 2015-2023 Alexandre Spangaro * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -234,6 +234,7 @@ if (empty($reshook)) { // Action clone object if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) { + // @phan-suppress-next-line PhanPluginBothLiteralsBinaryOp if (1 == 0 && !GETPOST('clone_content', 'alpha') && !GETPOST('clone_receivers', 'alpha')) { setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors'); } else { @@ -1358,7 +1359,7 @@ if (empty($reshook)) { if (!$error) { // TODO Use update method of ExpenseReportLine - $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id, $fk_c_exp_tax_cat, $fk_ecm_files); + $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, (float) $qty, (float) $value_unit, $date, $id, $fk_c_exp_tax_cat, $fk_ecm_files); if ($result >= 0) { if ($result > 0) { // Define output language @@ -1431,6 +1432,7 @@ $paymentexpensereportstatic = new PaymentExpenseReport($db); $bankaccountstatic = new Account($db); $ecmfilesstatic = new EcmFiles($db); $formexpensereport = new FormExpenseReport($db); +$remaintopay = 0; // Create if ($action == 'create') { @@ -1474,7 +1476,7 @@ if ($action == 'create') { if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('expensereport', 'writeall_advance')) { $include_users = array(); } - $s = $form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users, '', '0,'.$conf->entity); + $s = $form->select_dolusers($defaultselectuser, "fk_user_author", 0, null, 0, $include_users, '', '0,'.$conf->entity); print $s; print ''; print ''; @@ -1495,7 +1497,7 @@ if ($action == 'create') { if (GETPOSTINT('fk_user_validator') > 0) { $defaultselectuser = GETPOSTINT('fk_user_validator'); } - $s = $form->select_dolusers($defaultselectuser, "fk_user_validator", 1, "", ((empty($defaultselectuser) || !getDolGlobalString('EXPENSEREPORT_DEFAULT_VALIDATOR_UNCHANGEABLE')) ? 0 : 1), $include_users); + $s = $form->select_dolusers($defaultselectuser, "fk_user_validator", 1, null, ((empty($defaultselectuser) || !getDolGlobalString('EXPENSEREPORT_DEFAULT_VALIDATOR_UNCHANGEABLE')) ? 0 : 1), $include_users); print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate")); } print ''; @@ -1552,6 +1554,7 @@ if ($action == 'create') { print ''; } elseif ($id > 0 || $ref) { + $userauthor = null; $result = $object->fetch($id, $ref); if ($result > 0) { @@ -1624,7 +1627,7 @@ if ($action == 'create') { print ''; print ''; print ''; print ''; } @@ -1634,7 +1637,7 @@ if ($action == 'create') { print ''; // Approbator print ''; print ''; @@ -2225,7 +2228,7 @@ if ($action == 'create') { print ''; - print ''; + print ''; if ($action != 'editline') { print ''; @@ -2400,7 +2403,7 @@ if ($action == 'create') { // Select project if (isModEnabled('project')) { print ''; } @@ -2412,7 +2415,7 @@ if ($action == 'create') { if (getDolGlobalString('MAIN_USE_EXPENSE_IK')) { print ''; } @@ -2424,7 +2427,7 @@ if ($action == 'create') { // VAT $selectedvat = price2num($line->vatrate).(!empty($line->vat_src_code) ? ' ('.$line->vat_src_code.')' : ''); print ''; // Unit price @@ -2439,7 +2442,7 @@ if ($action == 'create') { // Quantity print ''; //print ''; @@ -2455,7 +2458,7 @@ if ($action == 'create') { print ''; print ''; @@ -2582,7 +2585,7 @@ if ($action == 'create') { // Select project if (isModEnabled('project')) { print ''; } @@ -2610,7 +2613,7 @@ if ($action == 'create') { // If option to have no default VAT on expense report is on, we force MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none'; } - print $form->load_tva('vatrate', (!empty($vatrate) ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1); + print $form->load_tva('vatrate', (!empty($vatrate) ? $vatrate : $defaultvat), $mysoc, null, 0, 0, '', false, 1); print ''; // Unit price net @@ -2638,7 +2641,7 @@ if ($action == 'create') { } print ''; print ''; @@ -2938,7 +2941,7 @@ if ($action != 'presend') { // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'expensereport', null); + $somethingshown = $formactions->showactions($object, 'expensereport', 0); print ''; } From 0438db7747cbcfd8fca449e3908ba5316b32a4a5 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 29 Jan 2025 07:10:41 +0100 Subject: [PATCH 320/602] FIX wrong table name --- htdocs/accountancy/class/accountancycategory.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php index 379e2b802e1..fbbdb35e7a8 100644 --- a/htdocs/accountancy/class/accountancycategory.class.php +++ b/htdocs/accountancy/class/accountancycategory.class.php @@ -439,7 +439,7 @@ class AccountancyCategory // extends CommonObject { global $conf; $sql = "SELECT t.rowid, t.account_number, t.label"; - $sql .= " FROM ".$this->db->prefix().$this->table_element." as t"; + $sql .= " FROM ".$this->db->prefix()."accounting_account as t"; $sql .= " WHERE t.fk_accounting_category = ".((int) $id); $sql .= " AND t.entity = ".$conf->entity; From c43f74687a6aa19318d09435db5c673d2300e9dc Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 29 Jan 2025 07:32:22 +0100 Subject: [PATCH 321/602] FIX #32843 --- htdocs/bom/bom_card.php | 2 +- htdocs/mrp/mo_card.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index c5456de0a21..0656d9d1e31 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -800,7 +800,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed = $user->hasRight('bom', 'read'); // If you can read, you can build the PDF to read content $delallowed = $user->hasRight('bom', 'write'); // If you can create/edit, you can remove a file on card - print $formfile->showdocuments('bom', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); + print $formfile->showdocuments('bom', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang, '', $object); // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('bom')); diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index 17f5aefcb62..7f1ccf1729e 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -853,7 +853,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed = $user->hasRight('mrp', 'read'); // If you can read, you can build the PDF to read content $delallowed = $user->hasRight("mrp", "creer"); // If you can create/edit, you can remove a file on card - print $formfile->showdocuments('mrp:mo', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $mysoc->default_lang); + print $formfile->showdocuments('mrp:mo', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $mysoc->default_lang, '', $object); // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('mo')); From 510da33c338f3f6be53cb9ec90626bcb404aeab7 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 29 Jan 2025 08:35:55 +0100 Subject: [PATCH 322/602] FIX #32840 --- htdocs/categories/class/categorie.class.php | 35 ++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 330baf65469..b3721d1bee7 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -285,6 +285,38 @@ class Categorie extends CommonObject */ public $imgHeight; + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed (Example: 1 or 'getDolGlobalString("MY_SETUP_PARAM")' + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + /** + * @var array|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string}> Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields = array( + 'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'visible' => 1, 'showoncombobox' => 1), + ); + /** * Constructor * @@ -1751,7 +1783,8 @@ class Categorie extends CommonObject } // Check contrast with background and correct text color - $forced_color = 'categtextwhite'; + //$forced_color = 'categtextwhite'; // TODO This css class hide the link + $forced_color = 'categtextblack'; if ($this->color) { if (colorIsLight($this->color)) { $forced_color = 'categtextblack'; From 3f1efcfb53a5d9bb58800aed0f3f27574d0fb3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 09:01:32 +0100 Subject: [PATCH 323/602] dict type contact --- htdocs/admin/dict.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index c201ca97b73..d96d7ce0e4f 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -11,7 +11,7 @@ * Copyright (C) 2011-2024 Alexandre Spangaro * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud - * Copyright (C) 2019-2024 Frédéric France + * Copyright (C) 2019-2025 Frédéric France * Copyright (C) 2020-2022 Open-Dsi * Copyright (C) 2024 Charlene Benke * Copyright (C) 2024 MDW @@ -716,6 +716,7 @@ if ($id == DICT_TYPE_CONTACT) { 'project_task' => img_picto('', 'projecttask', 'class="pictofixedwidth"').$langs->trans('Task'), 'propal' => img_picto('', 'propal', 'class="pictofixedwidth"').$langs->trans('Proposal'), 'commande' => img_picto('', 'order', 'class="pictofixedwidth"').$langs->trans('Order'), + 'shipping' => img_picto('', 'dolly', 'class="pictofixedwidth"') . $langs->trans('Shipment'), 'facture' => img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans('Bill'), 'fichinter' => img_picto('', 'intervention', 'class="pictofixedwidth"').$langs->trans('InterventionCard'), 'contrat' => img_picto('', 'contract', 'class="pictofixedwidth"').$langs->trans('Contract'), From 40d8bea77e2133335de16b8336e66b074a96e205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 09:14:13 +0100 Subject: [PATCH 324/602] dict type contact --- htdocs/commande/class/commande.class.php | 4 ++-- htdocs/install/mysql/migration/21.0.0-22.0.0.sql | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 71e03085f69..ccce40846ce 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1638,9 +1638,9 @@ class Commande extends CommonOrder $product = new Product($this->db); $result = $product->fetch($fk_product); if ($qty < $product->packaging) { - $qty = $product->packaging; + $qty = (float) $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); diff --git a/htdocs/install/mysql/migration/21.0.0-22.0.0.sql b/htdocs/install/mysql/migration/21.0.0-22.0.0.sql index 0837bdb61a8..0aef3f65cc8 100644 --- a/htdocs/install/mysql/migration/21.0.0-22.0.0.sql +++ b/htdocs/install/mysql/migration/21.0.0-22.0.0.sql @@ -42,6 +42,13 @@ ALTER TABLE llx_societe_account ADD UNIQUE INDEX uk_societe_account_login_websit -- V22 migration +-- fix element +UPDATE llx_c_type_contact set element='shipping' WHERE element='expedition'; +-- Shipment / Expedition +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'internal', 'SALESREPFOLL', 'Responsable suivi de l''expédition', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'CUSTOMER', 'Customer shipping contact', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'SHIPPING', 'Loading facility', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'DELIVERY', 'Delivery facility', 1); ALTER TABLE llx_holiday_config DROP INDEX idx_holiday_config; ALTER TABLE llx_holiday_config ADD COLUMN entity integer DEFAULT 1 NOT NULL AFTER rowid; @@ -49,4 +56,4 @@ ALTER TABLE llx_holiday_config ADD UNIQUE INDEX idx_holiday_config (entity, name ALTER TABLE llx_societe_account ADD COLUMN ip varchar(250); -ALTER TABLE llx_product ADD COLUMN packaging float(24,8) DEFAULT NULL; \ No newline at end of file +ALTER TABLE llx_product ADD COLUMN packaging float(24,8) DEFAULT NULL; From e7088d779415b158720aa3081ca01a44f30ec31c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 29 Jan 2025 09:14:37 +0100 Subject: [PATCH 325/602] FIX add other fields --- htdocs/categories/class/categorie.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index b3721d1bee7..305649da4e4 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -314,7 +314,9 @@ class Categorie extends CommonObject * @var array|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string}> Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. */ public $fields = array( - 'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'visible' => 1, 'showoncombobox' => 1), + 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'index' => 1, 'position' => 1, 'comment' => 'Id'), + 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'default' => '1', 'notnull' => 1, 'index' => 1, 'position' => 5), + 'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'visible' => 1, 'showoncombobox' => 1, 'position' => 15, 'csslist' => 'tdoverflowmax250'), ); /** From 262a07f5fa43a0a6418579d1eb42034583977471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 09:25:23 +0100 Subject: [PATCH 326/602] dict type contact --- htdocs/compta/facture/class/facture.class.php | 4 ++-- htdocs/install/mysql/migration/21.0.0-22.0.0.sql | 9 +++++---- htdocs/langs/en_US/propal.lang | 2 +- htdocs/langs/en_US/sendings.lang | 6 ++++++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 09dddafbbd5..68a019043d5 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4003,9 +4003,9 @@ class Facture extends CommonInvoice $product = new Product($this->db); $result = $product->fetch($fk_product); if ($qty < $product->packaging) { - $qty = $product->packaging; + $qty = (float) $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); diff --git a/htdocs/install/mysql/migration/21.0.0-22.0.0.sql b/htdocs/install/mysql/migration/21.0.0-22.0.0.sql index 0aef3f65cc8..4cf68ce85ad 100644 --- a/htdocs/install/mysql/migration/21.0.0-22.0.0.sql +++ b/htdocs/install/mysql/migration/21.0.0-22.0.0.sql @@ -45,10 +45,11 @@ ALTER TABLE llx_societe_account ADD UNIQUE INDEX uk_societe_account_login_websit -- fix element UPDATE llx_c_type_contact set element='shipping' WHERE element='expedition'; -- Shipment / Expedition -insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'internal', 'SALESREPFOLL', 'Responsable suivi de l''expédition', 1); -insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'CUSTOMER', 'Customer shipping contact', 1); -insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'SHIPPING', 'Loading facility', 1); -insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'DELIVERY', 'Delivery facility', 1); +INSERT INTO llx_c_type_contact (element, source, code, libelle, active ) VALUES ('shipping', 'internal', 'SALESREPFOLL', 'Representative following-up shipping', 1); +INSERT INTO llx_c_type_contact (element, source, code, libelle, active ) VALUES ('shipping', 'external', 'BILLING', 'Customer invoice contact', 1); +INSERT INTO llx_c_type_contact (element, source, code, libelle, active ) VALUES ('shipping', 'external', 'CUSTOMER', 'Customer shipping contact', 1); +INSERT INTO llx_c_type_contact (element, source, code, libelle, active ) VALUES ('shipping', 'external', 'SHIPPING', 'Loading facility', 1); +INSERT INTO llx_c_type_contact (element, source, code, libelle, active ) VALUES ('shipping', 'external', 'DELIVERY', 'Delivery facility', 1); ALTER TABLE llx_holiday_config DROP INDEX idx_holiday_config; ALTER TABLE llx_holiday_config ADD COLUMN entity integer DEFAULT 1 NOT NULL AFTER rowid; diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index 1b4f57d49c9..e08c7fbb26d 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -77,7 +77,7 @@ AvailabilityTypeAV_1W=1 week AvailabilityTypeAV_2W=2 weeks AvailabilityTypeAV_3W=3 weeks AvailabilityTypeAV_1M=1 month -##### Types ofe contacts ##### +##### Types of contacts ##### TypeContact_propal_internal_SALESREPFOLL=Representative following-up proposal TypeContact_propal_external_BILLING=Customer invoice contact TypeContact_propal_external_CUSTOMER=Customer contact following-up proposal diff --git a/htdocs/langs/en_US/sendings.lang b/htdocs/langs/en_US/sendings.lang index 95406dcc87e..fe9fdc20532 100644 --- a/htdocs/langs/en_US/sendings.lang +++ b/htdocs/langs/en_US/sendings.lang @@ -83,3 +83,9 @@ ShipmentDistribution=Shipment distribution ErrorTooManyCombinationBatchcode=No dispatch for line %s as too many combinations of warehouse, product, batch code was found (%s). ErrorNoCombinationBatchcode=Could not save the line %s as the combination of warehouse-product-lot/serial (%s, %s, %s) was not found in stock. ErrorTooMuchShipped=Quantity shipped should not be greater than quantity ordered for line %s +##### Types of contacts ##### +TypeContact_shipping_internal_SALESREPFOLL=Representative following-up shipping +TypeContact_shipping_external_BILLING=Customer invoice contact +TypeContact_shipping_external_CUSTOMER=Customer contact following-up shipping +TypeContact_shipping_external_SHIPPING=Customer contact for shipping +TypeContact_shipping_external_DELIVERY=Customer contact for delivery From 0eb75b7e4fc3004d3cccaf82953becfe10c124dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 09:28:36 +0100 Subject: [PATCH 327/602] dict type contact --- htdocs/comm/propal/class/propal.class.php | 4 ++-- htdocs/install/mysql/data/llx_c_type_contact.sql | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index eb81c4c084e..070f9914417 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -713,9 +713,9 @@ class Propal extends CommonObject $product = new Product($this->db); $result = $product->fetch($fk_product); if ($qty < $product->packaging) { - $qty = $product->packaging; + $qty = (float) $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); diff --git a/htdocs/install/mysql/data/llx_c_type_contact.sql b/htdocs/install/mysql/data/llx_c_type_contact.sql index d7bbbf77cf2..6611bd3b5aa 100644 --- a/htdocs/install/mysql/data/llx_c_type_contact.sql +++ b/htdocs/install/mysql/data/llx_c_type_contact.sql @@ -74,7 +74,8 @@ insert into llx_c_type_contact (element, source, code, libelle, active ) values insert into llx_c_type_contact (element, source, code, libelle, active ) values ('commande', 'external', 'SHIPPING', 'Contact client livraison commande', 1); -- Shipment / Expedition -insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'internal', 'SALESREPFOLL', 'Responsable suivi de l''expédition', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'internal', 'SALESREPFOLL', 'Representative following-up shipping', 1); +INSERT INTO llx_c_type_contact (element, source, code, libelle, active ) VALUES ('shipping', 'external', 'BILLING', 'Customer invoice contact', 1); insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'CUSTOMER', 'Customer shipping contact', 1); insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'SHIPPING', 'Loading facility', 1); insert into llx_c_type_contact (element, source, code, libelle, active ) values ('shipping', 'external', 'DELIVERY', 'Delivery facility', 1); From 7bd2bb6efc7071ee2f4f74d1663865df14c04b4d Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 29 Jan 2025 09:35:37 +0100 Subject: [PATCH 328/602] FIX DROP INDEX IF EXISTS is not possible ! --- htdocs/core/class/extrafields.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 4cfb2fed5db..9b1f5921740 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -749,7 +749,7 @@ class ExtraFields $sql = "ALTER TABLE ".$this->db->prefix().$table." ADD UNIQUE INDEX uk_".$table."_".$this->db->sanitize($attrname)." (".$this->db->sanitize($attrname).")"; } else { dol_syslog(get_class($this).'::update_common', LOG_DEBUG); - $sql = "ALTER TABLE ".$this->db->prefix().$table." DROP INDEX IF EXISTS uk_".$table."_".$this->db->sanitize($attrname); + $sql = "ALTER TABLE ".$this->db->prefix().$table." DROP INDEX uk_".$table."_".$this->db->sanitize($attrname); } dol_syslog(get_class($this).'::update', LOG_DEBUG); $resql = $this->db->query($sql, 1, 'dml'); From f3dc94d3345867b732fcb17a712b043f931a0c44 Mon Sep 17 00:00:00 2001 From: Irvine Fleith Date: Wed, 29 Jan 2025 10:14:46 +0100 Subject: [PATCH 329/602] fix(services-list): added missing hook printFieldListSearchParam --- htdocs/contrat/services_list.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 0b3666a295e..70dc312c2be 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -442,6 +442,10 @@ if ($optioncss != '') { } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( From 3c7327a457738acfe503bf4afad0675c8332ee68 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 29 Jan 2025 12:35:27 +0100 Subject: [PATCH 330/602] Missing notes --- htdocs/core/modules/modProjet.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index d58edcf7de2..bed2e414cc6 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -231,6 +231,7 @@ class modProjet extends DolibarrModules 'p.rowid'=>"Numeric", 'p.ref'=>"Text", 'p.title'=>"Text", 'p.usage_opportunity'=>'Boolean', 'p.usage_task'=>'Boolean', 'p.usage_bill_time'=>'Boolean', 'p.datec'=>"Date", 'p.dateo'=>"Date", 'p.datee'=>"Date", 'p.fk_statut'=>'Status', 'cls.code'=>"Text", 'p.opp_percent'=>'Numeric', 'p.opp_amount'=>'Numeric', 'p.description'=>"Text", 'p.entity'=>'Numeric', 'p.budget_amount'=>'Numeric', + 'p.note_public'=>'Text', 'p.note_private'=>'Text', 'pt.rowid'=>'Numeric', 'pt.ref'=>'Text', 'pt.label'=>'Text', 'pt.dateo'=>"Date", 'pt.datee'=>"Date", 'pt.duration_effective'=>"Duree", 'pt.planned_workload'=>"Numeric", 'pt.progress'=>"Numeric", 'pt.description'=>"Text", 'ptt.rowid'=>'Numeric', 'ptt.element_date'=>'Date', 'ptt.element_duration'=>"Duree", 'ptt.fk_user'=>"FormSelect:select_dolusers", 'ptt.note'=>"Text" ); @@ -243,7 +244,8 @@ class modProjet extends DolibarrModules 's.phone'=>'Phone', 's.email'=>'Email', 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 's.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode', 'p.rowid'=>"ProjectId", 'p.ref'=>"RefProject", 'p.title'=>'ProjectLabel', 'p.usage_opportunity'=>'ProjectFollowOpportunity', 'p.usage_task'=>'ProjectFollowTasks', 'p.usage_bill_time'=>'BillTime', - 'p.datec'=>"DateCreation", 'p.dateo'=>"DateStart", 'p.datee'=>"DateEnd", 'p.fk_statut'=>'ProjectStatus', 'cls.code'=>'OpportunityStatus', 'p.opp_percent'=>'OpportunityProbability', 'p.opp_amount'=>'OpportunityAmount', 'p.budget_amount'=>'Budget', 'p.description'=>"Description" + 'p.datec'=>"DateCreation", 'p.dateo'=>"DateStart", 'p.datee'=>"DateEnd", 'p.fk_statut'=>'ProjectStatus', 'cls.code'=>'OpportunityStatus', 'p.opp_percent'=>'OpportunityProbability', 'p.opp_amount'=>'OpportunityAmount', 'p.description'=>"Description", 'p.budget_amount'=>'Budget', + 'p.note_public'=>'NotePublic', 'p.note_private'=>'NotePrivate', ); // Add multicompany field if (getDolGlobalString('MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED')) { From f94cfd0d60a80a5f8a2eab641c80330ef8abd489 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 29 Jan 2025 13:29:44 +0100 Subject: [PATCH 331/602] Fix position --- htdocs/projet/card.php | 100 ++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 4fc99beac08..a62f4437fd6 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -812,31 +812,6 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ''; } - // Visibility - print ''; - if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) { // Opportunity status print ''; @@ -901,6 +876,31 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ""; } + // Visibility + print ''; + // Selection of Owner contact type print ''; print ''; } - // Visibility - print ''; - if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) { $classfortr = ($object->usage_opportunity ? '' : ' hideobject'); // Opportunity status @@ -1322,6 +1297,31 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ""; } + // Visibility + print ''; + // Other options $parameters = array(); $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook From a121e52d82f62fa4c323069eb362cda8181f6c1d Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 29 Jan 2025 13:29:44 +0100 Subject: [PATCH 332/602] Fix position --- htdocs/projet/card.php | 100 ++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 0eb947f56a6..6fdd27c568c 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -812,31 +812,6 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ''; } - // Visibility - print ''; - if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) { // Opportunity status print ''; @@ -901,6 +876,31 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ""; } + // Visibility + print ''; + // Selection of Owner contact type print ''; print ''; } - // Visibility - print ''; - if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) { $classfortr = ($object->usage_opportunity ? '' : ' hideobject'); // Opportunity status @@ -1322,6 +1297,31 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ""; } + // Visibility + print ''; + // Other options $parameters = array(); $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook From 9870069f44f25c6774134aa7dc4ba9099c368bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 13:56:46 +0100 Subject: [PATCH 333/602] more fields in liste_contacts --- htdocs/core/class/commonobject.class.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3aa18de36e9..02cee9b9716 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1500,14 +1500,14 @@ abstract class CommonObject $sql = "SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact"; // This field contains id of llx_socpeople or id of llx_user if ($source == 'internal') { - $sql .= ", '-1' as socid, t.statut as statuscontact, t.login, t.photo, t.gender"; + $sql .= ", '-1' as socid, t.statut as statuscontact, t.login, t.photo, t.gender, t.fk_country as country_id"; } if ($source == 'external' || $source == 'thirdparty') { - $sql .= ", t.fk_soc as socid, t.statut as statuscontact"; + $sql .= ", t.fk_soc as socid, t.statut as statuscontact, t.fk_pays as country_id"; } - $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email"; + $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email, t.address, t.zip, t.town"; if (empty($arrayoftcids)) { - $sql .= ", tc.source, tc.element, tc.code, tc.libelle as type_label"; + $sql .= ", tc.source, tc.element, tc.code, tc.libelle as type_label, co.label as country"; } $sql .= " FROM"; if (empty($arrayoftcids)) { @@ -1516,9 +1516,11 @@ abstract class CommonObject $sql .= " ".$this->db->prefix()."element_contact as ec"; if ($source == 'internal') { // internal contact (user) $sql .= " LEFT JOIN ".$this->db->prefix()."user as t on ec.fk_socpeople = t.rowid"; + $sql .= " LEFT JOIN ".$this->db->prefix()."c_country as co ON co.rowid = t.fk_country"; } if ($source == 'external' || $source == 'thirdparty') { // external contact (socpeople) $sql .= " LEFT JOIN ".$this->db->prefix()."socpeople as t on ec.fk_socpeople = t.rowid"; + $sql .= " LEFT JOIN ".$this->db->prefix()."c_country as co ON co.rowid = t.fk_pays"; } $sql .= " WHERE ec.element_id = ".((int) $this->id); if (empty($arrayoftcids)) { @@ -1566,6 +1568,11 @@ abstract class CommonObject 'lastname' => $obj->lastname, 'firstname' => $obj->firstname, 'email' => $obj->email, + 'address' => $obj->address, + 'zip' => $obj->zip, + 'town' => $obj->town, + 'country_id' => $obj->country_id, + 'country' => $obj->country, 'login' => (empty($obj->login) ? '' : $obj->login), 'photo' => (empty($obj->photo) ? '' : $obj->photo), 'gender' => (empty($obj->gender) ? '' : $obj->gender), From cad040a96d6953b80889d6336392f6cf5ef4f1fe Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 29 Jan 2025 14:08:48 +0100 Subject: [PATCH 334/602] Debug v21 - print of description --- htdocs/projet/card.php | 39 +++++++++++++++-------------- htdocs/projet/contact.php | 37 ++++++++++++++++------------ htdocs/projet/element.php | 37 ++++++++++++++++------------ htdocs/projet/tasks.php | 37 ++++++++++++++++------------ htdocs/projet/tasks/contact.php | 42 +++++++++++++++++++------------- htdocs/projet/tasks/document.php | 42 +++++++++++++++++++------------- htdocs/projet/tasks/note.php | 42 +++++++++++++++++++------------- htdocs/projet/tasks/task.php | 42 +++++++++++++++++++------------- htdocs/projet/tasks/time.php | 37 ++++++++++++++++------------ htdocs/theme/eldy/global.inc.php | 2 +- 10 files changed, 206 insertions(+), 151 deletions(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 6fdd27c568c..fea8f4ce90e 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -1409,17 +1409,6 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print ''; } - // Visibility - print ''; - if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && !empty($object->usage_opportunity)) { // Opportunity status print ''; + // Visibility + print ''; + // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; @@ -1475,13 +1475,6 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; print $langs->trans("BARCODE_ON_SHIPPING_PDF"); @@ -498,7 +488,7 @@ if (isModEnabled('reception')) { print '
'; print ''; - print ''; + print ''; print ''; print ''; @@ -453,9 +453,9 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; print $langs->trans("RECEPTION_PDF_HIDE_ORDERED"); @@ -541,7 +531,7 @@ if (isModEnabled('stocktransfer')) { print '
'; print ''; - print ''; + print ''; print ''; @@ -413,9 +413,9 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; print $langs->trans("BARCODE_ON_STOCKTRANSFER_PDF"); @@ -561,7 +551,7 @@ if (isModEnabled('stocktransfer')) { print load_fiche_titre($langs->trans("Files"), '', 'file'); print '
'; print ''; -print ''; +print ''; // Terms of sale $tooltiptermsofsale = $langs->trans('AvailableFormats').' : pdf'; diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index 90a150ba6bc..50a5430df3e 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -164,7 +164,7 @@ print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; print ''; print ''; -print ''; +print ''; print ""; @@ -460,7 +460,7 @@ if (isModEnabled('notification') ) print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; print ''; print ''; - print ''; + print ''; print ''; print "\n"; diff --git a/htdocs/admin/resource.php b/htdocs/admin/resource.php index aac4c03bfb4..7b16c42eb81 100644 --- a/htdocs/admin/resource.php +++ b/htdocs/admin/resource.php @@ -88,7 +88,7 @@ print '
'; print '
'.$langs->trans("User").''.$langs->trans("Value").''.$langs->trans("Action").'
'; print ''; print ''."\n"; -print ''."\n"; +print ''."\n"; print ''; diff --git a/htdocs/admin/sms.php b/htdocs/admin/sms.php index ad815dc5bc8..15bbe9a6691 100644 --- a/htdocs/admin/sms.php +++ b/htdocs/admin/sms.php @@ -181,7 +181,7 @@ if ($action == 'edit') { clearstatcache(); print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'; - print ''; + print ''; // Disable print '"; print '"; print '"; print ''; if (!$i) { diff --git a/htdocs/eventorganization/conferenceorboothattendee_card.php b/htdocs/eventorganization/conferenceorboothattendee_card.php index b7010dadaf5..041e671a8f0 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_card.php +++ b/htdocs/eventorganization/conferenceorboothattendee_card.php @@ -1,7 +1,7 @@ * Copyright (C) 2024 Alexandre Spangaro - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -75,6 +75,8 @@ $diroutputmassaction = $conf->eventorganization->dir_output.'/temp/massgeneratio $hookmanager->initHooks(array('conferenceorboothattendeecard', 'globalcard')); // Note that conf->hooks_modules contains array +$confOrBooth = null; + if ($conf_or_booth_id > 0) { $confOrBooth = new ConferenceOrBooth($db); $result = $confOrBooth->fetch($id > 0 ? $id : $conf_or_booth_id); @@ -221,7 +223,7 @@ $help_url = 'EN:Module_Event_Organization'; llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-eventorganization page-attendee-card'); -$result = $projectstatic->fetch(empty($confOrBooth->fk_project) ? $fk_project : $confOrBooth->fk_project); +$result = $projectstatic->fetch(($confOrBooth === null || empty($confOrBooth->fk_project)) ? $fk_project : $confOrBooth->fk_project); if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($projectstatic, 'fetchComments') && empty($projectstatic->comments)) { $projectstatic->fetchComments(); } @@ -357,7 +359,7 @@ if (!empty($withproject)) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '', $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print '"; print '"; print '"; print '"; print '"; print '"; print '"; print '"; - // Link to ICS for the event - print '"; + // Show message + $message = ''.$langs->trans('DownloadICSLink').img_picto('', 'download', 'class="paddingleft"').''; + print $message; + print ""; print ''; if (!$i) { diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 1b74583596c..a19523f9d7b 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -14,7 +14,7 @@ * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2020 Lenin Rivas * Copyright (C) 2022 Josep Lluís Amador - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -388,7 +388,7 @@ if (empty($reshook)) { } // Extrafields - $array_options[$i] = $extrafields->getOptionalsFromPost($object->table_element_line, $i); + $array_options[$i] = $extrafields->getOptionalsFromPost($object->table_element_line, (string) $i); // Unset extrafield if (isset($extrafields->attributes[$object->table_element_line]['label']) && is_array($extrafields->attributes[$object->table_element_line]['label'])) { // Get extra fields @@ -528,7 +528,7 @@ if (empty($reshook)) { } } elseif ($action == 'confirm_cancel' && $confirm == 'yes' && $user->hasRight('expedition', 'supprimer')) { $also_update_stock = (GETPOST('alsoUpdateStock', 'alpha') ? 1 : 0); - $result = $object->cancel(0, $also_update_stock); + $result = $object->cancel(0, (bool) $also_update_stock); if ($result > 0) { $result = $object->setStatut(-1); } else { @@ -536,7 +536,7 @@ if (empty($reshook)) { } } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $user->hasRight('expedition', 'supprimer')) { $also_update_stock = (GETPOST('alsoUpdateStock', 'alpha') ? 1 : 0); - $result = $object->delete($user, 0, $also_update_stock); + $result = $object->delete($user, 0, (bool) $also_update_stock); if ($result > 0) { header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); exit; @@ -1035,7 +1035,7 @@ if ($action == 'create') { print ''; print ''; print ''; @@ -1081,7 +1081,7 @@ if ($action == 'create') { print ''; @@ -1094,7 +1094,7 @@ if ($action == 'create') { print ' x '; print ' x '; print ' '; - $text = $formproduct->selectMeasuringUnits("size_units", "size", GETPOSTINT('size_units'), 0, 2); + $text = $formproduct->selectMeasuringUnits("size_units", "size", (string) GETPOSTINT('size_units'), 0, 2); $htmltext = $langs->trans("KeepEmptyForAutoCalculation"); print $form->textwithpicto($text, $htmltext); print ''; @@ -1277,7 +1277,7 @@ if ($action == 'create') { $text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label); $description = ($showdescinproductdesc ? '' : dol_htmlentitiesbr($line->desc)); - print $form->textwithtooltip($text, $description, 3, 0, '', $i); + print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i); // Show range print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end)); @@ -1298,7 +1298,7 @@ if ($action == 'create') { if (!empty($line->label)) { $text .= ' '.$line->label.''; - print $form->textwithtooltip($text, $line->desc, 3, 0, '', $i); + print $form->textwithtooltip($text, $line->desc, 3, 0, '', (string) $i); } else { print $text.' '.nl2br($line->desc); } @@ -1856,7 +1856,7 @@ if ($action == 'create') { $expLine->array_options = array_merge($expLine->array_options, $srcLine->array_options); - print $expLine->showOptionals($extrafields, 'edit', array('style' => 'class="drag drop oddeven"', 'colspan' => $colspan), $indiceAsked, '', 1); + print $expLine->showOptionals($extrafields, 'edit', array('style' => 'class="drag drop oddeven"', 'colspan' => $colspan), (string) $indiceAsked, '', '1'); } } @@ -2003,7 +2003,7 @@ if ($action == 'create') { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); @@ -2107,13 +2107,13 @@ if ($action == 'create') { print ''; print ''; print ''; - print $formproduct->selectMeasuringUnits("weight_units", "weight", $object->weight_units, 0, 2, 'maxwidth125 valignmiddle'); + print $formproduct->selectMeasuringUnits("weight_units", "weight", (string) $object->weight_units, 0, 2, 'maxwidth125 valignmiddle'); print ' '; print ' '; print ''; } else { print $object->trueWeight; - print ($object->trueWeight && $object->weight_units != '') ? ' '.measuringUnitString(0, "weight", $object->weight_units) : ''; + print ($object->trueWeight && $object->weight_units != '') ? ' '.measuringUnitString(0, "weight", (string) $object->weight_units) : ''; } // Calculated @@ -2228,7 +2228,7 @@ if ($action == 'create') { } else { if ($object->shipping_method_id > 0) { // Get code using getLabelFromKey - $code = $langs->getLabelFromKey($db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); + $code = $langs->getLabelFromKey($db, (string) $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); print $langs->trans("SendingMethod".strtoupper($code)); } } @@ -2462,7 +2462,7 @@ if ($action == 'create') { $text = $product_static->getNomUrl(1); $text .= ' - '.$label; $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($lines[$i]->description)); - print $form->textwithtooltip($text, $description, 3, 0, '', $i); + print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i); print_date_range(!empty($lines[$i]->date_start) ? $lines[$i]->date_start : '', !empty($lines[$i]->date_end) ? $lines[$i]->date_end : ''); if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) { print (!empty($lines[$i]->description) && $lines[$i]->description != $lines[$i]->product) ? '
'.dol_htmlentitiesbr($lines[$i]->description) : ''; @@ -2478,7 +2478,7 @@ if ($action == 'create') { if (!empty($lines[$i]->label)) { $text .= ' '.$lines[$i]->label.''; - print $form->textwithtooltip($text, $lines[$i]->description, 3, 0, '', $i); + print $form->textwithtooltip($text, $lines[$i]->description, 3, 0, '', (string) $i); } else { print $text.' '.nl2br($lines[$i]->description); } @@ -2489,7 +2489,7 @@ if ($action == 'create') { $unit_order = ''; if (getDolGlobalString('PRODUCT_USE_UNITS')) { - $unit_order = measuringUnitString($lines[$i]->fk_unit); + $unit_order = measuringUnitString((int) $lines[$i]->fk_unit); } // Qty ordered @@ -2529,7 +2529,7 @@ if ($action == 'create') { } } } - print $form->textwithpicto($qtyalreadysent, $htmltooltip, 1, 'info', '', 0, 3, 'tooltip'.$lines[$i]->id); + print $form->textwithpicto((string) $qtyalreadysent, $htmltooltip, 1, 'info', '', 0, 3, 'tooltip'.$lines[$i]->id); print ''; } @@ -2738,9 +2738,9 @@ if ($action == 'create') { // TODO Show all in same line by setting $display_type = 'line' if ($action == 'editline' && $line->id == $line_id) { - print $lines[$i]->showOptionals($extrafields, 'edit', array('colspan' => $colspan), !empty($indiceAsked) ? $indiceAsked : '', '', 0, 'card'); + print $lines[$i]->showOptionals($extrafields, 'edit', array('colspan' => $colspan), !empty($indiceAsked) ? $indiceAsked : '', '', '', 'card'); } else { - print $lines[$i]->showOptionals($extrafields, 'view', array('colspan' => $colspan), !empty($indiceAsked) ? $indiceAsked : '', '', 0, 'card'); + print $lines[$i]->showOptionals($extrafields, 'view', array('colspan' => $colspan), !empty($indiceAsked) ? $indiceAsked : '', '', '', 'card'); } } } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 61e50c14373..d3ecb5adad9 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -13,7 +13,7 @@ * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2020 Lenin Rivas - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 William Mead * * This program is free software; you can redistribute it and/or modify @@ -306,7 +306,6 @@ class Expedition extends CommonObject * Closed status * -> parcel was received by customer / end of process * prev status : validated or shipment_in_progress - * */ const STATUS_CLOSED = 2; @@ -1476,10 +1475,10 @@ class Expedition extends CommonObject * Delete shipment. * Warning, do not delete a shipment if a delivery is linked to (with table llx_element_element) * - * @param User $user User making the deletion - * @param int $notrigger Disable triggers - * @param bool $also_update_stock true if the stock should be increased back (false by default) - * @return int >0 if OK, 0 if deletion done but failed to delete files, <0 if KO + * @param ?User $user User making the deletion + * @param int<0,1> $notrigger Disable triggers + * @param bool $also_update_stock true if the stock should be increased back (false by default) + * @return int >0 if OK, 0 if deletion done but failed to delete files, <0 if KO */ public function delete($user = null, $notrigger = 0, $also_update_stock = false) { @@ -2437,7 +2436,6 @@ class Expedition extends CommonObject * @param string $labelmovement Label of movement * @return int Return integer <0 if KO, >0 if OK * @throws Exception - * */ private function manageStockMvtOnEvt($user, $labelmovement = 'ShipmentClassifyClosedInDolibarr') { diff --git a/htdocs/expedition/contact.php b/htdocs/expedition/contact.php index 3818847e84e..534515a84f6 100644 --- a/htdocs/expedition/contact.php +++ b/htdocs/expedition/contact.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2023 Christian Foellmann * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -52,6 +53,7 @@ $id = GETPOSTINT('id'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); +$typeobject = null; $object = new Expedition($db); if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); @@ -85,7 +87,7 @@ $result = restrictedArea($user, 'expedition', $object->id, ''); * Actions */ -$parameters = array('id'=>$id); +$parameters = array('id' => $id); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); @@ -172,7 +174,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); diff --git a/htdocs/expedition/dispatch.php b/htdocs/expedition/dispatch.php index e1340a8b0d7..67c30c5ff95 100644 --- a/htdocs/expedition/dispatch.php +++ b/htdocs/expedition/dispatch.php @@ -9,7 +9,7 @@ * Copyright (C) 2017-2022 Ferran Marcet * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2019-2020 Christophe Battarel - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -141,6 +141,7 @@ if ($action == 'updatelines' && $usercancreate) { $reg = array(); if (preg_match('/^product_.*([0-9]+)_([0-9]+)$/i', $key, $reg)) { $pos++; + $modebatch = null; if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) { $modebatch = "barcode"; } elseif (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) { // With batchmode enabled @@ -156,7 +157,7 @@ if ($action == 'updatelines' && $usercancreate) { $qty = "qty_".$reg[1].'_'.$reg[2]; $ent = "entrepot_".$reg[1].'_'.$reg[2]; $fk_commandedet = "fk_commandedet_".$reg[1].'_'.$reg[2]; - $idline = GETPOST("idline_".$reg[1].'_'.$reg[2]); + $idline = GETPOSTINT("idline_".$reg[1].'_'.$reg[2]); $warehouse_id = GETPOSTINT($ent); $prod_id = GETPOSTINT($prod); //$pu = "pu_".$reg[1].'_'.$reg[2]; // This is unit price including discount @@ -245,6 +246,7 @@ if ($action == 'updatelines' && $usercancreate) { $sqlsearchdet .= " AND batch = '".$db->escape($lot)."'"; $resqlsearchdet = $db->query($sqlsearchdet); + $objsearchdet = null; if ($resqlsearchdet) { $objsearchdet = $db->fetch_object($resqlsearchdet); } else { @@ -384,6 +386,7 @@ $warehouse_static = new Entrepot($db); $title = $object->ref." - ".$langs->trans('ShipmentDistribution'); $help_url = 'EN:Module_Shipments|FR:Module_Expéditions|ES:Módulo_Expediciones|DE:Modul_Lieferungen'; $morejs = array('/expedition/js/lib_dispatch.js.php'); +$typeobject = null; llxHeader('', $title, $help_url, '', 0, 0, $morejs, '', '', 'mod-expedition page-card_dispatch'); @@ -459,7 +462,7 @@ if ($object->id > 0 || !empty($object->ref)) { if ($action != 'classify' && $permissiontoadd) { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); @@ -546,6 +549,11 @@ if ($object->id > 0 || !empty($object->ref)) { $entrepot = new Entrepot($db); $listwarehouses = $entrepot->list_array(1); + $nbfreeproduct = 0; // Nb of lines of free products/services + $nbproduct = 0; // Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default) + // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on. + + print '
'; @@ -683,10 +691,6 @@ if ($object->id > 0 || !empty($object->ref)) { print "\n"; } - $nbfreeproduct = 0; // Nb of lines of free products/services - $nbproduct = 0; // Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default) - // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on. - $conf->cache['product'] = array(); // Loop on each line of origin order diff --git a/htdocs/expedition/document.php b/htdocs/expedition/document.php index f8b1cc3ad85..4dc74e52a72 100644 --- a/htdocs/expedition/document.php +++ b/htdocs/expedition/document.php @@ -6,6 +6,7 @@ * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -79,6 +80,7 @@ if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); $object->fetch_thirdparty(); + $typeobject = null; if (!empty($object->origin)) { $typeobject = $object->origin; $origin = $object->origin; @@ -159,7 +161,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc->fk_project)) { $proj = new Project($db); diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index b45450396bc..03a6a11db5d 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -6,7 +6,7 @@ * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2020 Thibault FOUCART * Copyright (C) 2023 Christophe Battarel - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Benjamin Falière * Copyright (C) 2024 Vincent Maury * Copyright (C) 2024 William Mead @@ -557,9 +557,6 @@ if (empty($reshook)) { if ($search_company) { $param .= "&search_company=".urlencode($search_company); } - if ($search_shipping_method_id) { - $param .= "&search_shipping_method_id=".urlencode($search_shipping_method_id); - } if ($search_tracking) { $param .= "&search_tracking=".urlencode($search_tracking); } @@ -1089,7 +1086,7 @@ if ($massaction == 'createbills') { print $langs->trans('DateInvoice'); print ''; print '
'; print ''; print ''; @@ -1106,7 +1103,7 @@ if ($massaction == 'createbills') { print ''; print ''; } // Town @@ -1353,7 +1350,7 @@ if (!empty($arrayfields['e.signed_status']['checked'])) { // Status billed if (!empty($arrayfields['e.billed']['checked'])) { print ''; } // Action column @@ -1649,7 +1646,7 @@ while ($i < $imaxinloop) { } if (!empty($arrayfields['e.fk_shipping_method']['checked'])) { // Get code using getLabelFromKey - $code = $langs->getLabelFromKey($db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); + $code = $langs->getLabelFromKey($db, (string) $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'.$langs->trans("MAIN_DISABLE_ALL_SMS").''; @@ -217,7 +217,7 @@ if ($action == 'edit') { print '
'; } else { print ''; - print ''; + print ''; // Disable print ''; diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 78590db9795..952bccf2074 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -697,7 +697,7 @@ print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'.$langs->trans("MAIN_DISABLE_ALL_SMS").''.yn(getDolGlobalString('MAIN_DISABLE_ALL_SMS')).'
'; print ''; print "\n"; -print ''."\n"; +print ''."\n"; print ''."\n"; print ''; diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index e1281c1bf58..6a14e25c466 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -192,7 +192,7 @@ print ''.$langs->trans("StockTransferSetupPage").''; print '
".$langs->trans("Parameter")."'.$langs->trans("Value").'
'; - print ''; + print ''; foreach ($arrayofparameters as $key => $val) { @@ -213,7 +213,7 @@ print ''.$langs->trans("StockTransferSetupPage").''; - print ''; + print ''; foreach ($arrayofparameters as $key => $val) { diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php index 325378332ce..8dab80b8157 100644 --- a/htdocs/admin/supplier_invoice.php +++ b/htdocs/admin/supplier_invoice.php @@ -472,7 +472,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index 17aa2f5f78f..ba4886573f3 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -477,7 +477,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/supplier_payment.php b/htdocs/admin/supplier_payment.php index b76fe11f1bd..3419f734977 100644 --- a/htdocs/admin/supplier_payment.php +++ b/htdocs/admin/supplier_payment.php @@ -454,7 +454,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php index fac147f09d4..2a922fbd752 100644 --- a/htdocs/admin/syslog.php +++ b/htdocs/admin/syslog.php @@ -217,7 +217,7 @@ print '
'; // You can use div-table-resp print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; @@ -309,7 +309,7 @@ print ''; print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table print '
'.$langs->trans("Type").''.$langs->trans("Value").'
'; print ''; -print ''; +print ''; print ''; print "\n"; diff --git a/htdocs/admin/taxes.php b/htdocs/admin/taxes.php index 77ff2b03096..d70217c985e 100644 --- a/htdocs/admin/taxes.php +++ b/htdocs/admin/taxes.php @@ -180,7 +180,7 @@ if (empty($mysoc->tva_assuj)) { print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table print '
'.$langs->trans("Parameter").''.$langs->trans("Value").''.$langs->trans("Parameter").'
'; - print ''; + print ''; print ''; From 4afb100767382bdaf926da456c0c9899ab978695 Mon Sep 17 00:00:00 2001 From: ATM-Lucas Date: Fri, 24 Jan 2025 16:52:50 +0100 Subject: [PATCH 163/602] Adding model Mail --- htdocs/admin/mails_templates.php | 3 +++ htdocs/core/class/html.formmail.class.php | 3 ++- htdocs/product/card.php | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 6f79d58551a..d710306172c 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -252,6 +252,9 @@ if (isModEnabled('eventorganization') && $user->hasRight('eventorganization', 'r if (isModEnabled('partnership') && $user->hasRight('partnership', 'read')) { $elementList['partnership_send'] = img_picto('', 'partnership', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToPartnership')); } +if (isModEnabled('product') && !empty($user->rights->produit->lire)) { + $elementList['product_send'] = img_picto('', 'product', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('Product')); +} $parameters = array('elementList' => $elementList); $reshook = $hookmanager->executeHooks('emailElementlist', $parameters); // Note that $action and $object may have been modified by some hooks diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 3f09d2816f7..8964679bc7e 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -534,6 +534,7 @@ class FormMail extends Form $listofmimes = array(); $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined + if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) { foreach ($this->param['fileinit'] as $path) { @@ -624,7 +625,7 @@ class FormMail extends Form } elseif (!empty($this->param['models']) && in_array($this->param['models'], array( 'propal_send', 'order_send', 'facture_send', 'shipping_send', 'fichinter_send', 'supplier_proposal_send', 'order_supplier_send', - 'invoice_supplier_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'all' + 'invoice_supplier_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'product_send', 'all' ))) { // If list of template is empty $out .= '
'."\n"; diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 2a0868bcaa3..7c3588d0e08 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -3176,6 +3176,10 @@ if (getDolGlobalString('PRODUCT_ADD_FORM_ADD_TO') && $object->id && ($action == * Generated documents */ +if (GETPOST('modelselected')) { + $action = 'presend'; +} + if ($action != 'create' && $action != 'edit' && $action != 'delete') { print '
'; print ''; // ancre From 9c10d36b1b6f96c6327009110a2b707d688c56d0 Mon Sep 17 00:00:00 2001 From: ATM-Lucas Date: Fri, 24 Jan 2025 16:55:13 +0100 Subject: [PATCH 164/602] fault --- htdocs/core/class/html.formmail.class.php | 1152 ++++++++++----------- 1 file changed, 576 insertions(+), 576 deletions(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 8964679bc7e..a5881534518 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -473,7 +473,7 @@ class FormMail extends Form global $conf, $langs, $user, $hookmanager, $form; // Required to show preview wof mail attachments - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; $formfile = new FormFile($this->db); if (!is_object($form)) { @@ -532,632 +532,632 @@ class FormMail extends Form $listofpaths = array(); $listofnames = array(); $listofmimes = array(); - $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined + $keytoavoidconflict = empty($this->trackid) ? '' : '-' . $this->trackid; // this->trackid must be defined if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { - if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { - if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) { - foreach ($this->param['fileinit'] as $path) { - if (!empty($path)) { - $this->add_attached_files($path); + if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { + if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) { + foreach ($this->param['fileinit'] as $path) { + if (!empty($path)) { + $this->add_attached_files($path); + } } } } - } - if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) { - $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]); - } - if (!empty($_SESSION["listofnames".$keytoavoidconflict])) { - $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]); - } - if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) { - $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]); - } - - - $out .= "\n".'
'."\n"; - if ($this->withform == 1) { - $out .= '
'."\n"; - - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - } - if (!empty($this->withfrom)) { - if (!empty($this->withfromreadonly)) { - $out .= ''; - $out .= ''; + if (!empty($_SESSION["listofpaths" . $keytoavoidconflict])) { + $listofpaths = explode(';', $_SESSION["listofpaths" . $keytoavoidconflict]); } - } - foreach ($this->param as $key => $value) { - if (is_array($value)) { - $out .= "\n"; - } else { - $out .= ''."\n"; + if (!empty($_SESSION["listofnames" . $keytoavoidconflict])) { + $listofnames = explode(';', $_SESSION["listofnames" . $keytoavoidconflict]); } - } - - $modelmail_array = array(); - if ($this->param['models'] != 'none') { - $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs); - if ($result < 0) { - setEventMessages($this->error, $this->errors, 'errors'); + if (!empty($_SESSION["listofmimes" . $keytoavoidconflict])) { + $listofmimes = explode(';', $_SESSION["listofmimes" . $keytoavoidconflict]); } - foreach ($this->lines_model as $line) { - $reg = array(); - if (preg_match('/\((.*)\)/', $line->label, $reg)) { - $labeltouse = $langs->trans($reg[1]); // langs->trans when label is __(xxx)__ + + $out .= "\n" . '
' . "\n"; + if ($this->withform == 1) { + $out .= '' . "\n"; + + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + } + if (!empty($this->withfrom)) { + if (!empty($this->withfromreadonly)) { + $out .= ''; + $out .= ''; + } + } + foreach ($this->param as $key => $value) { + if (is_array($value)) { + $out .= "\n"; } else { - $labeltouse = $line->label; - } - - // We escape the $labeltouse to store it into $modelmail_array. - $modelmail_array[$line->id] = dol_escape_htmltag($labeltouse); - if ($line->lang) { - $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang); - } - if ($line->private) { - $modelmail_array[$line->id] .= ' - '.dol_escape_htmltag($langs->trans("Private")).''; + $out .= '' . "\n"; } } - } - // Zone to select email template - if (count($modelmail_array) > 0) { - $model_mail_selected_id = GETPOSTISSET('modelmailselected') ? GETPOSTINT('modelmailselected') : ($arraydefaultmessage->id > 0 ? $arraydefaultmessage->id : 0); + $modelmail_array = array(); + if ($this->param['models'] != 'none') { + $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs); + if ($result < 0) { + setEventMessages($this->error, $this->errors, 'errors'); + } - // If list of template is filled - $out .= '
'."\n"; - - $out .= $this->selectarray('modelmailselected', $modelmail_array, $model_mail_selected_id, $langs->trans('SelectMailModel'), 0, 0, '', 0, 0, 0, '', 'minwidth100', 1, '', 0, 1); - if ($user->admin) { - $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1); - } - - $out .= '   '; - $out .= ''; - $out .= '   '; - $out .= '
'; - } elseif (!empty($this->param['models']) && in_array($this->param['models'], array( - 'propal_send', 'order_send', 'facture_send', - 'shipping_send', 'fichinter_send', 'supplier_proposal_send', 'order_supplier_send', - 'invoice_supplier_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'product_send', 'all' - ))) { - // If list of template is empty - $out .= '
'."\n"; - $out .= ''.$langs->trans('SelectMailModel').': '; - $out .= ''; // Do not put 'disabled' on 'option' tag, it is already on 'select' and it makes chrome crazy. - if ($user->admin) { - $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1); - } - $out .= '   '; - $out .= ''; - $out .= '   '; - $out .= '
'; - } else { - $out .= ''; - } - - - $out .= '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("Parameters").'
'; print ''; diff --git a/htdocs/admin/webhook.php b/htdocs/admin/webhook.php index 382971d9906..a4451fec911 100644 --- a/htdocs/admin/webhook.php +++ b/htdocs/admin/webhook.php @@ -182,7 +182,7 @@ if ($action == 'edit') { print ''; print ''; - print ''; + print ''; // @phan-suppress-next-line PhanEmptyForeach foreach ($arrayofparameters as $constname => $val) { @@ -273,7 +273,7 @@ if ($action == 'edit') { } else { if (!empty($arrayofparameters)) { print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; - print ''; + print ''; foreach ($arrayofparameters as $constname => $val) { if ($val['enabled'] == 1) { diff --git a/htdocs/admin/website_options.php b/htdocs/admin/website_options.php index e41ccdf90c7..4cb3f9c6120 100644 --- a/htdocs/admin/website_options.php +++ b/htdocs/admin/website_options.php @@ -128,7 +128,7 @@ print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; print ''; print ''; print ''; -print ''."\n"; +print ''."\n"; print ''; diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php index f05467d68da..eac57dbf797 100644 --- a/htdocs/admin/workstation.php +++ b/htdocs/admin/workstation.php @@ -195,7 +195,7 @@ if ($action == 'edit') { print ''; print '
'.$langs->trans("Parameter").' '.$langs->trans("Value").'
'; - print ''; + print ''; // @phan-suppress-next-line PhanEmptyForeach foreach ($arrayofparameters as $key => $val) { @@ -215,7 +215,7 @@ if ($action == 'edit') { } else { if (!empty($arrayofparameters)) { print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; - print ''; + print ''; foreach ($arrayofparameters as $key => $val) { $setupnotempty++; diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index f6f452062c1..d0471938c67 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -20,7 +20,6 @@ * along with this program. If not, see . */ - /** * \file htdocs/core/class/conf.class.php * \ingroup core @@ -1038,6 +1037,14 @@ class Conf extends stdClass $this->global->MAIN_MAX_DECIMALS_SHOWN = 8; } + // Non working days + if (!isset($this->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY)) { + $this->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY = 1; + } + if (!isset($this->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY)) { + $this->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY = 1; + } + // Default pdf option if (!isset($this->global->MAIN_PDF_DASH_BETWEEN_LINES)) { $this->global->MAIN_PDF_DASH_BETWEEN_LINES = 1; // use dash between lines From 34feedbb033f2eb348b065ae1f5b56bcd7fceb4d Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 24 Jan 2025 13:14:32 +0100 Subject: [PATCH 159/602] Clean dead code --- htdocs/admin/workstation.php | 51 ------------------------------------ 1 file changed, 51 deletions(-) diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php index eac57dbf797..dc6017c33ed 100644 --- a/htdocs/admin/workstation.php +++ b/htdocs/admin/workstation.php @@ -185,57 +185,6 @@ print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); $head = workstationAdminPrepareHead(); print dol_get_fiche_head($head, 'settings', $langs->trans($page_name), -1, "workstation"); -// Setup page goes here -//echo ''.$langs->trans("WorkstationSetupPage").'

'; - - -if ($action == 'edit') { - print ''; - print ''; - print ''; - - print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").'
'; - print ''; - - // @phan-suppress-next-line PhanEmptyForeach - foreach ($arrayofparameters as $key => $val) { - print ''; - } - print '
'.$langs->trans("Parameter").'
'; - $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); - print $form->textwithpicto($langs->trans($key), $tooltiphelp); - print '
'; - - print '
'; - print ''; - print '
'; - - print ''; - print '
'; -} else { - if (!empty($arrayofparameters)) { - print ''; - print ''; - - foreach ($arrayofparameters as $key => $val) { - $setupnotempty++; - - print ''; - } - - print '
'.$langs->trans("Parameter").'
'; - $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); - print $form->textwithpicto($langs->trans($key), $tooltiphelp); - print ''.getDolGlobalString($key).'
'; - - print '
'; - print ''.$langs->trans("Modify").''; - print '
'; - }/* else { - print '
'.$langs->trans("NothingToSetup"); - }*/ -} - foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { if ($myTmpObjectArray['includerefgeneration']) { From e3856d0de5a11c137681d493a7075393ed42eafb Mon Sep 17 00:00:00 2001 From: ATM-Lucas Date: Fri, 24 Jan 2025 14:04:30 +0100 Subject: [PATCH 160/602] pre-commit error --- htdocs/core/tpl/card_presend.tpl.php | 1 - htdocs/product/card.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index 9a5a12be721..e0654d487ca 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -115,7 +115,6 @@ if ($action == 'presend') { } if ($forcebuilddoc) { // If there is no default value for supplier invoice, we do not generate file, even if modelpdf was set by a manual generation if ((!$file || !is_readable($file)) && method_exists($object, 'generateDocument')) { - $hidedetails = $hidedetails?$hidedetails:''; $hidedesc = $hidedetails?$hidedetails:''; $hideref = $hidedetails?$hidedetails:''; diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 1efadc81fbf..2a0868bcaa3 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1302,7 +1302,6 @@ if (empty($reshook)) { $autocopy = 'MAIN_MAIL_AUTOCOPY_PRODUCT_TO'; $trackid = 'prod'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; - } @@ -3217,7 +3216,6 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete') { $trackid = 'prod' . $object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; - } // End of page From 4e9faa16be7b29708f5f0c282c3776637a9fccf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 24 Jan 2025 14:14:10 +0100 Subject: [PATCH 161/602] Update societeaccount.class.php --- htdocs/societe/class/societeaccount.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php index 47207ec2fda..80fb22b0838 100644 --- a/htdocs/societe/class/societeaccount.class.php +++ b/htdocs/societe/class/societeaccount.class.php @@ -162,6 +162,12 @@ class SocieteAccount extends CommonObject * @var string */ public $site; + + /** + * @var int + */ + public $fk_website; + /** * @var ?string */ From a6f978c67f9d19f66a7c8b4a4e015b57bd107c0a Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 24 Jan 2025 14:26:07 +0100 Subject: [PATCH 162/602] FIX broken feature, compatibility with "Default search filters" --- htdocs/ticket/list.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 8e800a841db..ea06f4fc308 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -387,13 +387,15 @@ foreach ($search as $key => $val) { $tmpkey = 't.' . $key; if ($key == 'fk_statut' && !empty($search['fk_statut'])) { $newarrayofstatus = array(); - foreach ($search['fk_statut'] as $key2 => $val2) { - if (in_array($val2, array('openall', 'closeall'))) { - continue; + if (is_array($search['fk_statut'])) { + foreach ($search['fk_statut'] as $key2 => $val2) { + if (in_array($val2, array('openall', 'closeall'))) { + continue; + } + $newarrayofstatus[] = $val2; } - $newarrayofstatus[] = $val2; } - if ($search['fk_statut'] == 'openall' || in_array('openall', $search['fk_statut'])) { + if ($search['fk_statut'] == 'openall' || (is_array($search['fk_statut']) && in_array('openall', $search['fk_statut']))) { $newarrayofstatus[] = Ticket::STATUS_NOT_READ; $newarrayofstatus[] = Ticket::STATUS_READ; $newarrayofstatus[] = Ticket::STATUS_ASSIGNED; @@ -401,7 +403,7 @@ foreach ($search as $key => $val) { $newarrayofstatus[] = Ticket::STATUS_NEED_MORE_INFO; $newarrayofstatus[] = Ticket::STATUS_WAITING; } - if ($search['fk_statut'] == 'closeall' || in_array('closeall', $search['fk_statut'])) { + if ($search['fk_statut'] == 'closeall' || (is_array($search['fk_statut']) && in_array('closeall', $search['fk_statut']))) { $newarrayofstatus[] = Ticket::STATUS_CLOSED; $newarrayofstatus[] = Ticket::STATUS_CANCELED; } @@ -901,7 +903,11 @@ foreach ($object->fields as $key => $val) { //var_dump(array_values($search[$key])); $selectedarray = null; if (!empty($search[$key])) { - $selectedarray = array_values($search[$key]); + if (is_array($search[$key])) { + $selectedarray = array_values($search[$key]); + } else { + $selectedarray = array($search[$key]); // Compatibility with "Default search filters" + } } print Form::multiselectarray('search_fk_statut', $arrayofstatus, $selectedarray, 0, 0, 'search_status width150 onrightofpage', 1, 0, '', '', ''); print '
'."\n"; - - // Substitution array/string - $helpforsubstitution = ''; - if (is_array($this->substit) && count($this->substit)) { - $helpforsubstitution .= $langs->trans('AvailableVariables').' :

'."\n"; - } - foreach ($this->substit as $key => $val) { - // Do not show deprecated variables into the tooltip help of substitution variables - if (in_array($key, array('__NEWREF__', '__REFCLIENT__', '__REFSUPPLIER__', '__SUPPLIER_ORDER_DATE_DELIVERY__', '__SUPPLIER_ORDER_DELAY_DELIVERY__'))) { - continue; - } - $helpforsubstitution .= $key.' -> '.$langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText($val))).'
'; - } - if (is_array($this->substit) && count($this->substit)) { - $helpforsubstitution .= '
'; - } - - /* - if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this. - $out .= '\n"; - }*/ - - // From - if (!empty($this->withfrom)) { - if (!empty($this->withfromreadonly)) { - $out .= '
'; - if (is_numeric($this->withsubstit)) { - $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage - } else { - $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage - } - $out .= "
'.$langs->trans("MailFrom").''; - - // $this->fromtype is the default value to use to select sender - if (!($this->fromtype === 'user' && $this->fromid > 0) - && !($this->fromtype === 'company') - && !($this->fromtype === 'robot') - && !preg_match('/user_aliases/', $this->fromtype) - && !preg_match('/global_aliases/', $this->fromtype) - && !preg_match('/senderprofile/', $this->fromtype) - ) { - // Use this->fromname and this->frommail or error if not defined - $out .= $this->fromname; - if ($this->frommail) { - $out .= ' <'.$this->frommail.'>'; + foreach ($this->lines_model as $line) { + $reg = array(); + if (preg_match('/\((.*)\)/', $line->label, $reg)) { + $labeltouse = $langs->trans($reg[1]); // langs->trans when label is __(xxx)__ } else { - if ($this->fromtype) { + $labeltouse = $line->label; + } + + // We escape the $labeltouse to store it into $modelmail_array. + $modelmail_array[$line->id] = dol_escape_htmltag($labeltouse); + if ($line->lang) { + $modelmail_array[$line->id] .= ' ' . picto_from_langcode($line->lang); + } + if ($line->private) { + $modelmail_array[$line->id] .= ' - ' . dol_escape_htmltag($langs->trans("Private")) . ''; + } + } + } + + // Zone to select email template + if (count($modelmail_array) > 0) { + $model_mail_selected_id = GETPOSTISSET('modelmailselected') ? GETPOSTINT('modelmailselected') : ($arraydefaultmessage->id > 0 ? $arraydefaultmessage->id : 0); + + // If list of template is filled + $out .= '
' . "\n"; + + $out .= $this->selectarray('modelmailselected', $modelmail_array, $model_mail_selected_id, $langs->trans('SelectMailModel'), 0, 0, '', 0, 0, 0, '', 'minwidth100', 1, '', 0, 1); + if ($user->admin) { + $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup') . ' - ' . $langs->transnoentitiesnoconv('EMails')), 1); + } + + $out .= '   '; + $out .= ''; + $out .= '   '; + $out .= '
'; + } elseif (!empty($this->param['models']) && in_array($this->param['models'], array( + 'propal_send', 'order_send', 'facture_send', + 'shipping_send', 'fichinter_send', 'supplier_proposal_send', 'order_supplier_send', + 'invoice_supplier_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'product_send', 'all' + ))) { + // If list of template is empty + $out .= '
' . "\n"; + $out .= '' . $langs->trans('SelectMailModel') . ': '; + $out .= ''; // Do not put 'disabled' on 'option' tag, it is already on 'select' and it makes chrome crazy. + if ($user->admin) { + $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup') . ' - ' . $langs->transnoentitiesnoconv('EMails')), 1); + } + $out .= '   '; + $out .= ''; + $out .= '   '; + $out .= '
'; + } else { + $out .= ''; + } + + + $out .= '' . "\n"; + + // Substitution array/string + $helpforsubstitution = ''; + if (is_array($this->substit) && count($this->substit)) { + $helpforsubstitution .= $langs->trans('AvailableVariables') . ' :

' . "\n"; + } + foreach ($this->substit as $key => $val) { + // Do not show deprecated variables into the tooltip help of substitution variables + if (in_array($key, array('__NEWREF__', '__REFCLIENT__', '__REFSUPPLIER__', '__SUPPLIER_ORDER_DATE_DELIVERY__', '__SUPPLIER_ORDER_DELAY_DELIVERY__'))) { + continue; + } + $helpforsubstitution .= $key . ' -> ' . $langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText($val))) . '
'; + } + if (is_array($this->substit) && count($this->substit)) { + $helpforsubstitution .= '
'; + } + + /* + if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this. + $out .= '\n"; + }*/ + + // From + if (!empty($this->withfrom)) { + if (!empty($this->withfromreadonly)) { + $out .= '\n"; - } else { - $out .= '\n"; - } - } - - // To - if (!empty($this->withto) || is_array($this->withto)) { - $out .= $this->getHtmlForTo(); - } - - // To User - if (!empty($this->withtouser) && is_array($this->withtouser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) { - $out .= '\n"; - } - - // With option for one email per recipient - if (!empty($this->withoptiononeemailperrecipient)) { - if (abs($this->withoptiononeemailperrecipient) == 1) { - $out .= ''; - } else { - $out .= ''; - } - } - - // CC - if (!empty($this->withtocc) || is_array($this->withtocc)) { - $out .= $this->getHtmlForCc(); - } - - // To User cc - if (!empty($this->withtoccuser) && is_array($this->withtoccuser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) { - $out .= '\n"; - } - - // CCC - if (!empty($this->withtoccc) || is_array($this->withtoccc)) { - $out .= $this->getHtmlForWithCcc(); - } - - // Replyto - if (!empty($this->withreplyto)) { - if ($this->withreplytoreadonly) { - $out .= ''; - $out .= ''; - $out .= "\n"; - } - } - - // Errorsto - if (!empty($this->witherrorsto)) { - $out .= $this->getHtmlForWithErrorsTo(); - } - - // Ask delivery receipt - if (!empty($this->withdeliveryreceipt) && getDolGlobalInt('MAIN_EMAIL_SUPPORT_ACK')) { - $out .= $this->getHtmlForDeliveryreceipt(); - } - - // Topic - if (!empty($this->withtopic)) { - $out .= $this->getHtmlForTopic($arraydefaultmessage, $helpforsubstitution); - } - - // Attached files - if (!empty($this->withfile)) { - $out .= ''; - $out .= ''; - - $out .= '\n"; } else { - $out .= '
'; + $out .= '\n"; } } - if (is_numeric($this->withfile)) { - // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript - $out .= ''."\n"; - $out .= ''."\n"; - if (count($listofpaths)) { - foreach ($listofpaths as $key => $val) { - $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val))); + // To + if (!empty($this->withto) || is_array($this->withto)) { + $out .= $this->getHtmlForTo(); + } - $entity = (isset($this->param['object_entity']) ? $this->param['object_entity'] : $conf->entity); - if ($entity > 1) { - $relativepathtofile = str_replace('/'.$entity.'/', '/', $relativepathtofile); + // To User + if (!empty($this->withtouser) && is_array($this->withtouser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) { + $out .= '\n"; + } + + // With option for one email per recipient + if (!empty($this->withoptiononeemailperrecipient)) { + if (abs($this->withoptiononeemailperrecipient) == 1) { + $out .= ''; + } else { + $out .= ''; + } + } + + // CC + if (!empty($this->withtocc) || is_array($this->withtocc)) { + $out .= $this->getHtmlForCc(); + } + + // To User cc + if (!empty($this->withtoccuser) && is_array($this->withtoccuser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) { + $out .= '\n"; + } + + // CCC + if (!empty($this->withtoccc) || is_array($this->withtoccc)) { + $out .= $this->getHtmlForWithCcc(); + } + + // Replyto + if (!empty($this->withreplyto)) { + if ($this->withreplytoreadonly) { + $out .= ''; + $out .= ''; + $out .= "\n"; + } + } + + // Errorsto + if (!empty($this->witherrorsto)) { + $out .= $this->getHtmlForWithErrorsTo(); + } + + // Ask delivery receipt + if (!empty($this->withdeliveryreceipt) && getDolGlobalInt('MAIN_EMAIL_SUPPORT_ACK')) { + $out .= $this->getHtmlForDeliveryreceipt(); + } + + // Topic + if (!empty($this->withtopic)) { + $out .= $this->getHtmlForTopic($arraydefaultmessage, $helpforsubstitution); + } + + // Attached files + if (!empty($this->withfile)) { + $out .= ''; + $out .= ''; + + $out .= '\n"; } - $out .= "\n"; - } - - // Message (+ Links to choose layout or ai prompt) - if (!empty($this->withbody)) { - $defaultmessage = GETPOST('message', 'restricthtml'); - if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') { - if ($arraydefaultmessage && $arraydefaultmessage->content) { - $defaultmessage = $arraydefaultmessage->content; - } elseif (!is_numeric($this->withbody)) { - $defaultmessage = $this->withbody; + // Message (+ Links to choose layout or ai prompt) + if (!empty($this->withbody)) { + $defaultmessage = GETPOST('message', 'restricthtml'); + if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') { + if ($arraydefaultmessage && $arraydefaultmessage->content) { + $defaultmessage = $arraydefaultmessage->content; + } elseif (!is_numeric($this->withbody)) { + $defaultmessage = $this->withbody; + } } - } - // Complete substitution array with the url to make online payment - $paymenturl = ''; - // Set the online payment url link into __ONLINE_PAYMENT_URL__ key - require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; - $validpaymentmethod = getValidOnlinePaymentMethods(''); - - if (empty($this->substit['__REF__'])) { // @phan-suppress-current-line PhanTypeMismatchProperty + // Complete substitution array with the url to make online payment $paymenturl = ''; - } else { - $langs->loadLangs(array('paypal', 'other')); - $typeforonlinepayment = 'free'; - if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') { - $typeforonlinepayment = 'order'; // TODO use detection on something else than template - } - if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') { - $typeforonlinepayment = 'invoice'; // TODO use detection on something else than template - } - if ($this->param["models"] == 'member') { - $typeforonlinepayment = 'member'; // TODO use detection on something else than template - } - $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']); - $paymenturl = $url; - } + // Set the online payment url link into __ONLINE_PAYMENT_URL__ key + require_once DOL_DOCUMENT_ROOT . '/core/lib/payments.lib.php'; + $validpaymentmethod = getValidOnlinePaymentMethods(''); - if (count($validpaymentmethod) > 0 && $paymenturl) { - $langs->load('other'); - $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl)); - $this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl; - } elseif (count($validpaymentmethod) > 0) { - $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__'; - $this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__'; - } else { - $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = ''; - $this->substit['__ONLINE_PAYMENT_URL__'] = ''; - } - - $this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = ''; - - // Generate the string with the template for lines repeated and filled for each line - $lines = ''; - $defaultlines = $arraydefaultmessage->content_lines; - if (isset($defaultlines)) { - foreach ($this->substit_lines as $lineid => $substit_line) { - $lines .= make_substitutions($defaultlines, $substit_line)."\n"; - } - } - $this->substit['__LINES__'] = $lines; - - $defaultmessage = str_replace('\n', "\n", $defaultmessage); - - // Deal with format differences between message and some substitution variables (text / HTML) - $atleastonecomponentishtml = 0; - if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) { - $atleastonecomponentishtml++; - } - if (strpos($defaultmessage, '__SENDEREMAIL_SIGNATURE__') !== false && dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) { - $atleastonecomponentishtml++; - } - if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) { - $atleastonecomponentishtml++; - } - if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) { - $atleastonecomponentishtml++; - } - if (dol_textishtml($defaultmessage)) { - $atleastonecomponentishtml++; - } - if ($atleastonecomponentishtml) { - if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) { - $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']); - } - if (!dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) { - $this->substit['__SENDEREMAIL_SIGNATURE__'] = dol_nl2br($this->substit['__SENDEREMAIL_SIGNATURE__']); - } - if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) { - $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']); - } - if (!dol_textishtml($defaultmessage)) { - $defaultmessage = dol_nl2br($defaultmessage); - } - } - - if (GETPOSTISSET("message") && !GETPOST('modelselected')) { - $defaultmessage = GETPOST("message", "restricthtml"); - } else { - $defaultmessage = make_substitutions($defaultmessage, $this->substit); - // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty) - $defaultmessage = preg_replace("/^(
)+/", "", $defaultmessage); - $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage); - } - - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - - $out .= ''; - $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + + $out .= ''; + $out .= '\n"; } - $out .= "\n"; - } - $out .= '
'; + if (is_numeric($this->withsubstit)) { + $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage + } else { + $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage + } + $out .= "
' . $langs->trans("MailFrom") . ''; + + // $this->fromtype is the default value to use to select sender + if (!($this->fromtype === 'user' && $this->fromid > 0) + && !($this->fromtype === 'company') + && !($this->fromtype === 'robot') + && !preg_match('/user_aliases/', $this->fromtype) + && !preg_match('/global_aliases/', $this->fromtype) + && !preg_match('/senderprofile/', $this->fromtype) + ) { + // Use this->fromname and this->frommail or error if not defined + $out .= $this->fromname; + if ($this->frommail) { + $out .= ' <' . $this->frommail . '>'; + } else { + if ($this->fromtype) { + $langs->load('errors'); + $out .= ' <' . $langs->trans('ErrorNoMailDefinedForThisUser') . '> '; + } + } + } else { + $liste = array(); + + // Add user email + if (empty($user->email)) { $langs->load('errors'); - $out .= ' <'.$langs->trans('ErrorNoMailDefinedForThisUser').'> '; + $s = $user->getFullName($langs) . ' <' . $langs->trans('ErrorNoMailDefinedForThisUser') . '>'; + } else { + $s = $user->getFullName($langs) . ' <' . $user->email . '>'; } - } - } else { - $liste = array(); + $liste['user'] = array('label' => $s, 'data-html' => $s); - // Add user email - if (empty($user->email)) { - $langs->load('errors'); - $s = $user->getFullName($langs).' <'.$langs->trans('ErrorNoMailDefinedForThisUser').'>'; - } else { - $s = $user->getFullName($langs).' <'.$user->email.'>'; - } - $liste['user'] = array('label' => $s, 'data-html' => $s); - - // Add also company main email - if (getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) { - $s = (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? $conf->global->MAIN_INFO_SOCIETE_EMAIL : $conf->global->MAIN_INFO_SOCIETE_NOM).' <' . getDolGlobalString('MAIN_INFO_SOCIETE_MAIL').'>'; - $liste['company'] = array('label' => $s, 'data-html' => $s); - } - - // Add also email aliases if there is some - $listaliases = array( - 'user_aliases' => (empty($user->email_aliases) ? '' : $user->email_aliases), - 'global_aliases' => getDolGlobalString('MAIN_INFO_SOCIETE_MAIL_ALIASES'), - ); - - if (!empty($arraydefaultmessage->email_from)) { - $templatemailfrom = ' <'.$arraydefaultmessage->email_from.'>'; - $liste['from_template_'.GETPOST('modelmailselected')] = array('label' => $templatemailfrom, 'data-html' => $templatemailfrom); - } - - // Also add robot email - if (!empty($this->fromalsorobot)) { - if (getDolGlobalString('MAIN_MAIL_EMAIL_FROM') && getDolGlobalString('MAIN_MAIL_EMAIL_FROM') != getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) { - $s = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); - if ($this->frommail) { - $s .= ' <' . getDolGlobalString('MAIN_MAIL_EMAIL_FROM').'>'; - } - $liste['main_from'] = array('label' => $s, 'data-html' => $s); + // Add also company main email + if (getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) { + $s = (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? $conf->global->MAIN_INFO_SOCIETE_EMAIL : $conf->global->MAIN_INFO_SOCIETE_NOM) . ' <' . getDolGlobalString('MAIN_INFO_SOCIETE_MAIL') . '>'; + $liste['company'] = array('label' => $s, 'data-html' => $s); } - } - // Add also email aliases from the c_email_senderprofile table - $sql = "SELECT rowid, label, email FROM ".$this->db->prefix()."c_email_senderprofile"; - $sql .= " WHERE active = 1 AND (private = 0 OR private = ".((int) $user->id).")"; - $sql .= " ORDER BY position"; - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < $num) { - $obj = $this->db->fetch_object($resql); - if ($obj) { - $listaliases['senderprofile_'.$obj->rowid] = $obj->label.' <'.$obj->email.'>'; - } - $i++; + // Add also email aliases if there is some + $listaliases = array( + 'user_aliases' => (empty($user->email_aliases) ? '' : $user->email_aliases), + 'global_aliases' => getDolGlobalString('MAIN_INFO_SOCIETE_MAIL_ALIASES'), + ); + + if (!empty($arraydefaultmessage->email_from)) { + $templatemailfrom = ' <' . $arraydefaultmessage->email_from . '>'; + $liste['from_template_' . GETPOST('modelmailselected')] = array('label' => $templatemailfrom, 'data-html' => $templatemailfrom); } - } else { - dol_print_error($this->db); - } - foreach ($listaliases as $typealias => $listalias) { - $posalias = 0; - $listaliasarray = explode(',', $listalias); - foreach ($listaliasarray as $listaliasval) { - $posalias++; - $listaliasval = trim($listaliasval); - if ($listaliasval) { - $listaliasval = preg_replace('//', '>', $listaliasval); - if (!preg_match('/</', $listaliasval)) { - $listaliasval = '<'.$listaliasval.'>'; + // Also add robot email + if (!empty($this->fromalsorobot)) { + if (getDolGlobalString('MAIN_MAIL_EMAIL_FROM') && getDolGlobalString('MAIN_MAIL_EMAIL_FROM') != getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) { + $s = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); + if ($this->frommail) { + $s .= ' <' . getDolGlobalString('MAIN_MAIL_EMAIL_FROM') . '>'; } - $liste[$typealias.'_'.$posalias] = array('label' => $listaliasval, 'data-html' => $listaliasval); + $liste['main_from'] = array('label' => $s, 'data-html' => $s); } } - } - // Using ajaxcombo here make the '' no more visible on list because is not a valid html tag, - // so we transform before each record into $liste to be printable with ajaxcombo by replacing <> into () - // $liste['senderprofile_0_0'] = array('label'=>'rrr', 'data-html'=>'rrr <aaaa>'); - foreach ($liste as $key => $val) { - if (!empty($liste[$key]['data-html'])) { - $liste[$key]['data-html'] = str_replace(array('<', '<', '>', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $liste[$key]['data-html']); - $liste[$key]['data-html'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('(', ')'), $liste[$key]['data-html']); + // Add also email aliases from the c_email_senderprofile table + $sql = "SELECT rowid, label, email FROM " . $this->db->prefix() . "c_email_senderprofile"; + $sql .= " WHERE active = 1 AND (private = 0 OR private = " . ((int)$user->id) . ")"; + $sql .= " ORDER BY position"; + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $this->db->fetch_object($resql); + if ($obj) { + $listaliases['senderprofile_' . $obj->rowid] = $obj->label . ' <' . $obj->email . '>'; + } + $i++; + } + } else { + dol_print_error($this->db); } + + foreach ($listaliases as $typealias => $listalias) { + $posalias = 0; + $listaliasarray = explode(',', $listalias); + foreach ($listaliasarray as $listaliasval) { + $posalias++; + $listaliasval = trim($listaliasval); + if ($listaliasval) { + $listaliasval = preg_replace('//', '>', $listaliasval); + if (!preg_match('/</', $listaliasval)) { + $listaliasval = '<' . $listaliasval . '>'; + } + $liste[$typealias . '_' . $posalias] = array('label' => $listaliasval, 'data-html' => $listaliasval); + } + } + } + + // Using ajaxcombo here make the '' no more visible on list because is not a valid html tag, + // so we transform before each record into $liste to be printable with ajaxcombo by replacing <> into () + // $liste['senderprofile_0_0'] = array('label'=>'rrr', 'data-html'=>'rrr <aaaa>'); + foreach ($liste as $key => $val) { + if (!empty($liste[$key]['data-html'])) { + $liste[$key]['data-html'] = str_replace(array('<', '<', '>', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $liste[$key]['data-html']); + $liste[$key]['data-html'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('(', ')'), $liste[$key]['data-html']); + } + } + $out .= ' ' . $form->selectarray('fromtype', $liste, empty($arraydefaultmessage->email_from) ? $this->fromtype : 'from_template_' . GETPOST('modelmailselected'), 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails); } - $out .= ' '.$form->selectarray('fromtype', $liste, empty($arraydefaultmessage->email_from) ? $this->fromtype : 'from_template_'.GETPOST('modelmailselected'), 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails); - } - $out .= "
'.$langs->trans("MailFrom").""; - $out .= $langs->trans("Name").':'; - $out .= '    '; - $out .= $langs->trans("EMail").':<>'; - $out .= "
'; - $out .= $langs->trans("MailToUsers"); - $out .= ''; - - // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time - $tmparray = $this->withtouser; - foreach ($tmparray as $key => $val) { - $tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true); - } - $withtoselected = GETPOST("receiveruser", 'array'); // Array of selected value - if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') { - $withtoselected = array_keys($tmparray); - } - $out .= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, ""); - $out .= "
'; - $out .= $langs->trans("GroupEmails"); - $out .= ''; - $out .= ' withoptiononeemailperrecipient > 0 ? ' checked="checked"' : '').'> '; - $out .= ''; - //$out .= ''; - //$out .= ' - '; - //$out .= $langs->trans("WarningIfYouCheckOneRecipientPerEmail"); - //$out .= ''; - if (getDolGlobalString('MASS_ACTION_EMAIL_ON_DIFFERENT_THIRPARTIES_ADD_CUSTOM_EMAIL')) { - if (!empty($this->withto) && !is_array($this->withto)) { - $out .= ' '.$langs->trans("or").' '; - } - } - $out .= '
'; - $out .= $langs->trans("MailToCCUsers"); - $out .= ''; - - // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time - $tmparray = $this->withtoccuser; - foreach ($tmparray as $key => $val) { - $tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true); - } - $withtoselected = GETPOST("receiverccuser", 'array'); // Array of selected value - if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') { - $withtoselected = array_keys($tmparray); - } - $out .= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, ""); - $out .= "
".$langs->trans("MailReply")."".$this->replytoname.($this->replytomail ? (" <".$this->replytomail.">") : ""); - $out .= "
'.$langs->trans("MailFile").''; - - if ($this->withmaindocfile) { - // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked) - if (GETPOSTISSET('sendmail')) { - $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1); - } elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { - // If a template was selected, we use setup of template to define if join file checkbox is selected or not. - $this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1); - } - } - - if (!empty($this->withmaindocfile)) { - if ($this->withmaindocfile == 1) { - $out .= ''; - } elseif ($this->withmaindocfile == -1) { - $out .= ''; - } - if (getDolGlobalString('MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND')) { - $out .= '
'; + $out .= "
' . $langs->trans("MailFrom") . ""; + $out .= $langs->trans("Name") . ':'; + $out .= '    '; + $out .= $langs->trans("EMail") . ':<>'; + $out .= "
'; + $out .= $langs->trans("MailToUsers"); + $out .= ''; + + // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time + $tmparray = $this->withtouser; + foreach ($tmparray as $key => $val) { + $tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true); + } + $withtoselected = GETPOST("receiveruser", 'array'); // Array of selected value + if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') { + $withtoselected = array_keys($tmparray); + } + $out .= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, ""); + $out .= "
'; + $out .= $langs->trans("GroupEmails"); + $out .= ''; + $out .= ' withoptiononeemailperrecipient > 0 ? ' checked="checked"' : '') . '> '; + $out .= ''; + //$out .= ''; + //$out .= ' - '; + //$out .= $langs->trans("WarningIfYouCheckOneRecipientPerEmail"); + //$out .= ''; + if (getDolGlobalString('MASS_ACTION_EMAIL_ON_DIFFERENT_THIRPARTIES_ADD_CUSTOM_EMAIL')) { + if (!empty($this->withto) && !is_array($this->withto)) { + $out .= ' ' . $langs->trans("or") . ' '; } - // Try to extract data from full path - $formfile_params = array(); - preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params); - - $out .= '
'; - // Preview of attachment - $out .= img_mime($listofnames[$key]).$listofnames[$key]; - - $out .= ' '.$formfile->showPreview(array(), $formfile_params[2], $formfile_params[4], 0, ($entity == 1 ? '' : 'entity='.((int) $entity))); - - if (!$this->withfilereadonly) { - $out .= ' '; - //$out.= ' '.img_delete($langs->trans("Remove"), 'id="removedfile_'.$key.'" name="removedfile_'.$key.'"', 'removedfile input-nobottom').''; - } - $out .= '
'; } - } /*elseif (empty($this->withmaindocfile)) { + $out .= '
'; + $out .= $langs->trans("MailToCCUsers"); + $out .= ''; + + // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time + $tmparray = $this->withtoccuser; + foreach ($tmparray as $key => $val) { + $tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true); + } + $withtoselected = GETPOST("receiverccuser", 'array'); // Array of selected value + if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') { + $withtoselected = array_keys($tmparray); + } + $out .= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, ""); + $out .= "
" . $langs->trans("MailReply") . "" . $this->replytoname . ($this->replytomail ? (" <" . $this->replytomail . ">") : ""); + $out .= "
' . $langs->trans("MailFile") . ''; + + if ($this->withmaindocfile) { + // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked) + if (GETPOSTISSET('sendmail')) { + $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1); + } elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { + // If a template was selected, we use setup of template to define if join file checkbox is selected or not. + $this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1); + } + } + + if (!empty($this->withmaindocfile)) { + if ($this->withmaindocfile == 1) { + $out .= ''; + } elseif ($this->withmaindocfile == -1) { + $out .= ''; + } + if (getDolGlobalString('MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND')) { + $out .= '
'; + } else { + $out .= '
'; + } + } + + if (is_numeric($this->withfile)) { + // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript + $out .= '' . "\n"; + $out .= '' . "\n"; + if (count($listofpaths)) { + foreach ($listofpaths as $key => $val) { + $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val))); + + $entity = (isset($this->param['object_entity']) ? $this->param['object_entity'] : $conf->entity); + if ($entity > 1) { + $relativepathtofile = str_replace('/' . $entity . '/', '/', $relativepathtofile); + } + // Try to extract data from full path + $formfile_params = array(); + preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params); + + $out .= '
'; + // Preview of attachment + $out .= img_mime($listofnames[$key]) . $listofnames[$key]; + + $out .= ' ' . $formfile->showPreview(array(), $formfile_params[2], $formfile_params[4], 0, ($entity == 1 ? '' : 'entity=' . ((int)$entity))); + + if (!$this->withfilereadonly) { + $out .= ' '; + //$out.= ' '.img_delete($langs->trans("Remove"), 'id="removedfile_'.$key.'" name="removedfile_'.$key.'"', 'removedfile input-nobottom').''; + } + $out .= '
'; + } + } /*elseif (empty($this->withmaindocfile)) { //$out .= ''.$langs->trans("NoAttachedFiles").'
'; }*/ - if ($this->withfile == 2) { - $maxfilesizearray = getMaxFileSizeArray(); - $maxmin = $maxfilesizearray['maxmin']; - if ($maxmin > 0) { - $out .= ''; // MAX_FILE_SIZE must precede the field type=file + if ($this->withfile == 2) { + $maxfilesizearray = getMaxFileSizeArray(); + $maxmin = $maxfilesizearray['maxmin']; + if ($maxmin > 0) { + $out .= ''; // MAX_FILE_SIZE must precede the field type=file + } + // Can add other files + if (!getDolGlobalString('FROM_MAIL_DONT_USE_INPUT_FILE_MULTIPLE')) { + $out .= ''; + } else { + $out .= ''; + } + $out .= ' '; + $out .= ''; } - // Can add other files - if (!getDolGlobalString('FROM_MAIL_DONT_USE_INPUT_FILE_MULTIPLE')) { - $out .= ''; - } else { - $out .= ''; - } - $out .= ' '; - $out .= ''; + } else { + $out .= $this->withfile; } - } else { - $out .= $this->withfile; + + $out .= "
'; - $out .= $form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody'); - $out .= ''; - - $formmail = $this; - $showlinktolayout = ($formmail->withfckeditor && getDolGlobalInt('MAIN_EMAIL_USE_LAYOUT')) ? $formmail->withlayout : ''; - $showlinktolayoutlabel = $langs->trans("FillMessageWithALayout"); - $showlinktoai = ($formmail->withaiprompt && isModEnabled('ai')) ? 'textgenerationemail' : ''; - $showlinktoailabel = $langs->trans("FillMessageWithAIContent"); - $formatforouput = ''; - $htmlname = 'message'; - - // Fill $out - include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php'; - - $out .= '
'; - if ($this->withbodyreadonly) { - $out .= nl2br($defaultmessage); - $out .= ''; - } else { - if (!isset($this->ckeditortoolbar)) { - $this->ckeditortoolbar = 'dolibarr_mailings'; + if (empty($this->substit['__REF__'])) { // @phan-suppress-current-line PhanTypeMismatchProperty + $paymenturl = ''; + } else { + $langs->loadLangs(array('paypal', 'other')); + $typeforonlinepayment = 'free'; + if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') { + $typeforonlinepayment = 'order'; // TODO use detection on something else than template + } + if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') { + $typeforonlinepayment = 'invoice'; // TODO use detection on something else than template + } + if ($this->param["models"] == 'member') { + $typeforonlinepayment = 'member'; // TODO use detection on something else than template + } + $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']); + $paymenturl = $url; } - // Editor wysiwyg - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - if ($this->withfckeditor == -1) { - if (getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) { - $this->withfckeditor = 1; - } else { - $this->withfckeditor = 0; + if (count($validpaymentmethod) > 0 && $paymenturl) { + $langs->load('other'); + $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl)); + $this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl; + } elseif (count($validpaymentmethod) > 0) { + $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__'; + $this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__'; + } else { + $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = ''; + $this->substit['__ONLINE_PAYMENT_URL__'] = ''; + } + + $this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = ''; + + // Generate the string with the template for lines repeated and filled for each line + $lines = ''; + $defaultlines = $arraydefaultmessage->content_lines; + if (isset($defaultlines)) { + foreach ($this->substit_lines as $lineid => $substit_line) { + $lines .= make_substitutions($defaultlines, $substit_line) . "\n"; + } + } + $this->substit['__LINES__'] = $lines; + + $defaultmessage = str_replace('\n', "\n", $defaultmessage); + + // Deal with format differences between message and some substitution variables (text / HTML) + $atleastonecomponentishtml = 0; + if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) { + $atleastonecomponentishtml++; + } + if (strpos($defaultmessage, '__SENDEREMAIL_SIGNATURE__') !== false && dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) { + $atleastonecomponentishtml++; + } + if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) { + $atleastonecomponentishtml++; + } + if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) { + $atleastonecomponentishtml++; + } + if (dol_textishtml($defaultmessage)) { + $atleastonecomponentishtml++; + } + if ($atleastonecomponentishtml) { + if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) { + $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']); + } + if (!dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) { + $this->substit['__SENDEREMAIL_SIGNATURE__'] = dol_nl2br($this->substit['__SENDEREMAIL_SIGNATURE__']); + } + if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) { + $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']); + } + if (!dol_textishtml($defaultmessage)) { + $defaultmessage = dol_nl2br($defaultmessage); } } - $doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%'); - $out .= $doleditor->Create(1); + if (GETPOSTISSET("message") && !GETPOST('modelselected')) { + $defaultmessage = GETPOST("message", "restricthtml"); + } else { + $defaultmessage = make_substitutions($defaultmessage, $this->substit); + // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty) + $defaultmessage = preg_replace("/^(
)+/", "", $defaultmessage); + $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage); + } + + $out .= '
'; + $out .= $form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody'); + $out .= ''; + + $formmail = $this; + $showlinktolayout = ($formmail->withfckeditor && getDolGlobalInt('MAIN_EMAIL_USE_LAYOUT')) ? $formmail->withlayout : ''; + $showlinktolayoutlabel = $langs->trans("FillMessageWithALayout"); + $showlinktoai = ($formmail->withaiprompt && isModEnabled('ai')) ? 'textgenerationemail' : ''; + $showlinktoailabel = $langs->trans("FillMessageWithAIContent"); + $formatforouput = ''; + $htmlname = 'message'; + + // Fill $out + include DOL_DOCUMENT_ROOT . '/core/tpl/formlayoutai.tpl.php'; + + $out .= '
'; + if ($this->withbodyreadonly) { + $out .= nl2br($defaultmessage); + $out .= ''; + } else { + if (!isset($this->ckeditortoolbar)) { + $this->ckeditortoolbar = 'dolibarr_mailings'; + } + + // Editor wysiwyg + require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; + if ($this->withfckeditor == -1) { + if (getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) { + $this->withfckeditor = 1; + } else { + $this->withfckeditor = 0; + } + } + + $doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%'); + $out .= $doleditor->Create(1); + } + $out .= "
'."\n"; + $out .= '
' . "\n"; - if ($this->withform == 1 || $this->withform == -1) { - $out .= '
'; - $out .= 'withfile == 2 && $conf->use_javascript_ajax) { - $out .= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"'; + if ($this->withform == 1 || $this->withform == -1) { + $out .= '
'; + $out .= 'withfile == 2 && $conf->use_javascript_ajax) { + $out .= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\'' . dol_escape_js($langs->trans("FileWasNotUploaded")) . '\'); return false; } else { return true; }"'; + } + $out .= ' />'; + if ($this->withcancel) { + $out .= ''; + } + $out .= '
' . "\n"; } - $out .= ' />'; - if ($this->withcancel) { - $out .= ''; + + if ($this->withform == 1) { + $out .= '' . "\n"; } - $out .= '
'."\n"; - } - if ($this->withform == 1) { - $out .= ''."\n"; - } - - // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set - if (getDolGlobalString('MAIN_MAILFORM_DISABLE_ENTERKEY')) { - $out .= ''; + $out .= ' })'; + $out .= ''; + } + + $out .= "\n"; + + return $out; } - - $out .= "\n"; - - return $out; } } - /** * get html For To * From 0932c2e492169019a1dd5cd1c6c5c30f1c7e1f3a Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 24 Jan 2025 17:28:10 +0100 Subject: [PATCH 165/602] Debug v21 --- htdocs/comm/action/class/actioncomm.class.php | 2 +- htdocs/comm/action/index.php | 259 ++--- htdocs/comm/action/peruser.php | 930 +++++++++++++++--- htdocs/contact/card.php | 5 +- htdocs/holiday/list.php | 5 +- htdocs/langs/fr_FR/holiday.lang | 2 +- 6 files changed, 939 insertions(+), 264 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 6eb05106686..d198de99b1a 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -1883,7 +1883,7 @@ class ActionComm extends CommonObject $color = 'style="color: #'.$this->type_color.' !important;"'; } if ($this->type_picto) { - $imgpicto = img_picto($titlealt.'rr', $this->type_picto, '', 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); + $imgpicto = img_picto($titlealt, $this->type_picto, '', 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); } else { if ($this->type_code == 'AC_RDV') { $imgpicto = img_picto($titlealt, 'meeting', $color, 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 93ae98884a3..02737de7db2 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -33,14 +33,13 @@ // Load Dolibarr environment require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; -require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; -if (isModEnabled('project')) { - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; -} +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; /** * @var Conf $conf @@ -50,14 +49,7 @@ if (isModEnabled('project')) { * @var User $user */ -if (!isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) { - $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW = 3; -} - -if (!getDolGlobalString('AGENDA_EXT_NB')) { - $conf->global->AGENDA_EXT_NB = 5; -} -$MAXAGENDA = getDolGlobalString('AGENDA_EXT_NB'); +$MAXAGENDA = getDolGlobalString('AGENDA_EXT_NB', 5); $DELAYFORCACHE = 300; // 300 seconds $disabledefaultvalues = GETPOSTINT('disabledefaultvalues'); @@ -122,10 +114,10 @@ $year = GETPOSTINT("year") ? GETPOSTINT("year") : date("Y"); $month = GETPOSTINT("month") ? GETPOSTINT("month") : date("m"); $week = GETPOSTINT("week") ? GETPOSTINT("week") : date("W"); $day = GETPOSTINT("day") ? GETPOSTINT("day") : date("d"); -$pid = GETPOSTINT("search_projectid", 3) ? GETPOSTINT("search_projectid", 3) : GETPOSTINT("projectid", 3); +$pid = GETPOSTISSET("search_projectid") ? GETPOSTINT("search_projectid", 3) : GETPOSTINT("projectid", 3); $status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 $type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); -$maxprint = GETPOSTISSET("maxprint") ? GETPOSTINT("maxprint") : getDolGlobalInt('AGENDA_MAX_EVENTS_DAY_VIEW'); +$maxprint = GETPOSTISSET("maxprint") ? GETPOSTINT("maxprint") : getDolGlobalInt('AGENDA_MAX_EVENTS_DAY_VIEW', 3); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $dateselect = dol_mktime(0, 0, 0, GETPOSTINT('dateselectmonth'), GETPOSTINT('dateselectday'), GETPOSTINT('dateselectyear')); @@ -149,7 +141,7 @@ if (is_scalar($actioncode) && $actioncode == '-1') { } if ($status == '' && !GETPOSTISSET('search_status')) { - $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); + $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS')); } $defaultview = getDolGlobalString('AGENDA_DEFAULT_VIEW', 'show_month'); // default for app @@ -253,14 +245,14 @@ if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } -$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda|DE:Modul_Terminplanung'; -llxHeader('', $langs->trans("Agenda"), $help_url); - $form = new Form($db); $companystatic = new Societe($db); $contactstatic = new Contact($db); $userstatic = new User($db); +$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda|DE:Modul_Terminplanung'; +llxHeader('', $langs->trans("Agenda"), $help_url); + $now = dol_now(); $nowarray = dol_getdate($now); $nowyear = $nowarray['year']; @@ -407,9 +399,13 @@ if ($mode == 'show_day') { //print dol_print_date($firstdaytoshow,'dayhour').' '.dol_print_date($lastdaytoshow,'dayhour'); /*$title = $langs->trans("DoneAndToDoActions"); - if ($status == 'done') $title = $langs->trans("DoneActions"); - if ($status == 'todo') $title = $langs->trans("ToDoActions"); - */ +if ($status == 'done') { + $title = $langs->trans("DoneActions"); +} +if ($status == 'todo') { + $title = $langs->trans("ToDoActions"); +} +*/ $param = ''; if ($actioncode || GETPOSTISSET('search_actioncode')) { @@ -428,10 +424,10 @@ if ($status || GETPOSTISSET('status') || GETPOSTISSET('search_status')) { $param .= "&search_status=".urlencode($status); } if ($filter) { - $param .= "&search_filter=".urlencode($filter); + $param .= "&search_filter=".urlencode((string) $filter); } if ($filtert) { - $param .= "&search_filtert=".urlencode($filtert); + $param .= "&search_filtert=".urlencode((string) $filtert); } if ($usergroup > 0) { $param .= "&search_usergroup=".urlencode((string) ($usergroup)); @@ -771,10 +767,14 @@ if ($resourceid > 0) { } // We must filter on assignment table if ($filtert > 0 || $usergroup > 0) { - $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar"; -} -if ($usergroup > 0) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as ar"; + $sql .= " ON ar.fk_actioncomm = a.id AND ar.element_type='user'"; + if ($filtert > 0) { + $sql .= " AND ar.fk_element = ".((int) $filtert); + } + if ($usergroup > 0) { + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element AND ugu.fk_usergroup = ".((int) $usergroup); + } } $sql .= ' WHERE a.fk_action = ca.id'; $sql .= ' AND a.entity IN ('.getEntity('agenda').')'; // bookcal is a "virtual view" of agenda @@ -830,10 +830,6 @@ if ($search_sale && $search_sale != '-1') { if ($socid) { $sql .= " AND a.fk_soc = ".((int) $socid); } -// We must filter on assignment table -if ($filtert > 0 || $usergroup > 0) { - $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'"; -} //var_dump($day.' '.$month.' '.$year); if ($mode == 'show_day') { $sql .= " AND ("; @@ -866,7 +862,7 @@ if ($status == '0') { // To do (not started) $sql .= " AND a.percent = 0"; } -if ($status == 'na') { +if ($status === 'na') { // Not applicable $sql .= " AND a.percent = -1"; } @@ -902,7 +898,7 @@ if ($search_categ_cus != -1) { } // Sort on date -$sql .= ' ORDER BY datep'; +$sql .= $db->order("datep"); //print $sql; dol_syslog("comm/action/index.php", LOG_DEBUG); @@ -1170,8 +1166,8 @@ if ($user->hasRight("holiday", "read")) { $event->type = 'holiday'; $event->type_picto = 'holiday'; - $event->datep = $db->jdate($obj->date_start) + (empty($halfday) || $halfday == 1 ? 0 : 12 * 60 * 60 - 1); - $event->datef = $db->jdate($obj->date_end) + (empty($halfday) || $halfday == -1 ? 24 : 12) * 60 * 60 - 1; + $event->datep = $db->jdate($obj->date_start) + (empty($obj->halfday) || $obj->halfday == 1 ? 0 : 12 * 60 * 60 - 1); + $event->datef = $db->jdate($obj->date_end) + (empty($obj->halfday) || $obj->halfday == -1 ? 24 : 12) * 60 * 60 - 1; $event->date_start_in_calendar = $event->datep; $event->date_end_in_calendar = $event->datef; @@ -1183,24 +1179,50 @@ if ($user->hasRight("holiday", "read")) { $event->percentage = 0; } - if ($obj->halfday == 1) { - $event->label = $obj->lastname.' ('.$langs->trans("Morning").')'; - } elseif ($obj->halfday == -1) { - $event->label = $obj->lastname.' ('.$langs->trans("Afternoon").')'; - } else { - $event->label = $obj->lastname; - } + $event->label = $langs->trans("Holiday"); $daycursor = $event->date_start_in_calendar; $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); + $daycursorend = $event->date_end_in_calendar; + $anneeend = (int) dol_print_date($daycursorend, '%Y', 'tzuserrel'); + $moisend = (int) dol_print_date($daycursorend, '%m', 'tzuserrel'); + $jourend = (int) dol_print_date($daycursorend, '%d', 'tzuserrel'); + + // daykey must be date that represent day box in calendar so must be a user time $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + $ifornbofdays = 0; do { - $eventarray[$daykey][] = $event; + $ifornbofdays++; + + $firstdayofholiday = ($ifornbofdays == 1); + $lastdayofholiday = ($daykeygmt == dol_get_first_hour($event->date_end_in_calendar, 'gmt')); + + /* + var_dump(dol_print_date($daykeygmt, 'dayhour', 'gmt')); + var_dump(dol_print_date(dol_get_first_hour($event->date_end_in_calendar, 'gmt'), 'dayhour', 'gmt')); + var_dump($lastdayofholiday); + var_dump($obj->halfday); + */ + + if ((in_array($obj->halfday, array(1, 2)) == 1 && $lastdayofholiday) || (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday)) { + // We create a copy of event because we want tochange the label + $newevent = dol_clone($event, 1); + if (in_array($obj->halfday, array(1, 2)) && $lastdayofholiday) { + $newevent->label .= ' ('.$langs->trans("Morning").')'; + } elseif (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday) { + $newevent->label .= ' ('.$langs->trans("Afternoon").')'; + } + $eventarray[$daykey][] = $newevent; // We need to use ->gtTypePicto, getXXXon object, so clone must be PHP clone. + } else { + $eventarray[$daykey][] = $event; // We can use the event unchanged + } $daykey += 60 * 60 * 24; + $daykeygmt += 60 * 60 * 24; } while ($daykey <= $event->date_end_in_calendar); $i++; @@ -1951,6 +1973,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if (!empty($cacheusers[$event->userownerid]->color)) { $color = $cacheusers[$event->userownerid]->color; } + + /* May be we need this: if (getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) { + $color = $event->type_color; + }*/ } elseif ($event->type_code == 'ICALEVENT') { // Event come from external ical file $numical++; if (!empty($event->icalname)) { @@ -2092,7 +2118,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa //var_dump($event->userassigned); //var_dump($event->transparency); print ''; + + // First the tr of the event (only one tr for event is used, but several td) print ''; print ''; + // Status - Percent $withstatus = 0; - if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') { + if ($event->type_code != 'HOLIDAY' && $event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') { $withstatus = 1; if ($event->percentage >= 0) { $withstatus = 2; diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index bab2ff5916c..915094db599 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -49,14 +49,12 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; * @var User $user */ -if (!isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) { - $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW = 3; -} - -$action = GETPOST('action', 'aZ09'); +$MAXAGENDA = getDolGlobalString('AGENDA_EXT_NB', 5); +$DELAYFORCACHE = 300; // 300 seconds $disabledefaultvalues = GETPOSTINT('disabledefaultvalues'); +$check_holiday = GETPOSTINT('check_holiday'); $filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); $filtert = GETPOSTINT("search_filtert", 3) ? GETPOSTINT("search_filtert", 3) : GETPOSTINT("filtert", 3); $usergroup = GETPOSTINT("search_usergroup", 3) ? GETPOSTINT("search_usergroup", 3) : GETPOSTINT("usergroup", 3); @@ -64,10 +62,9 @@ $usergroup = GETPOSTINT("search_usergroup", 3) ? GETPOSTINT("search_usergroup", //$showbirthday = empty($conf->use_javascript_ajax)?GETPOST("showbirthday","int"):1; $showbirthday = 0; -// If not choice done on calendar owner, we filter on user. -/*if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) -{ - $filtert = $user->id; +// If no choice done on calendar owner (like on left menu link "Agenda"), we filter on current user by default. +/*if (empty($filtert) && !getDolGlobalString('AGENDA_ALL_CALENDARS')) { + $filtert = (string) $user->id; }*/ $sortfield = GETPOST('sortfield', 'aZ09comma'); @@ -85,6 +82,7 @@ if (!$sortfield) { $sortfield = "a.datec"; } +// Security check $socid = GETPOSTINT("search_socid") ? GETPOSTINT("search_socid") : GETPOSTINT("socid"); if ($user->socid) { $socid = $user->socid; @@ -101,19 +99,21 @@ if (!$user->hasRight('agenda', 'allactions', 'read')) { $canedit = 0; } if (!$user->hasRight('agenda', 'allactions', 'read') || $filter == 'mine') { // If no permission to see all, we show only affected to me - $filtert = $user->id; + $filtert = (string) $user->id; } +$action = GETPOST('action', 'aZ09'); + $mode = 'show_peruser'; $resourceid = GETPOSTINT("search_resourceid") ? GETPOSTINT("search_resourceid") : GETPOSTINT("resourceid"); -$year = GETPOSTINT("year") ? GETPOSTINT("year") : idate("Y"); -$month = GETPOSTINT("month") ? GETPOSTINT("month") : idate("m"); -$week = GETPOSTINT("week") ? GETPOSTINT("week") : idate("W"); -$day = GETPOSTINT("day") ? GETPOSTINT("day") : idate("d"); +$year = GETPOSTINT("year") ? GETPOSTINT("year") : date("Y"); +$month = GETPOSTINT("month") ? GETPOSTINT("month") : date("m"); +$week = GETPOSTINT("week") ? GETPOSTINT("week") : date("W"); +$day = GETPOSTINT("day") ? GETPOSTINT("day") : date("d"); $pid = GETPOSTISSET("search_projectid") ? GETPOSTINT("search_projectid", 3) : GETPOSTINT("projectid", 3); $status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 -$type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); -$maxprint = ((GETPOSTINT("maxprint") != '') ? GETPOSTINT("maxprint") : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); +$maxprint = GETPOSTISSET("maxprint") ? GETPOSTINT("maxprint") : getDolGlobalInt('AGENDA_MAX_EVENTS_DAY_VIEW', 3); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $search_categ_cus = GETPOSTINT("search_categ_cus", 3) ? GETPOSTINT("search_categ_cus", 3) : 0; // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) @@ -133,7 +133,7 @@ if ($dateselect > 0) { $year = GETPOSTINT('dateselectyear'); } -$tmp = !getDolGlobalString('MAIN_DEFAULT_WORKING_HOURS') ? '9-18' : $conf->global->MAIN_DEFAULT_WORKING_HOURS; +$tmp = getDolGlobalString('MAIN_DEFAULT_WORKING_HOURS', '9-18'); $tmp = str_replace(' ', '', $tmp); // FIX 7533 $tmparray = explode('-', $tmp); $begin_h = GETPOSTISSET('begin_h') ? GETPOSTINT('begin_h') : ($tmparray[0] != '' ? $tmparray[0] : 9); @@ -148,7 +148,7 @@ if ($end_h <= $begin_h) { $end_h = $begin_h + 1; } -$tmp = !getDolGlobalString('MAIN_DEFAULT_WORKING_DAYS') ? '1-5' : $conf->global->MAIN_DEFAULT_WORKING_DAYS; +$tmp = getDolGlobalString('MAIN_DEFAULT_WORKING_DAYS', '1-5'); $tmp = str_replace(' ', '', $tmp); // FIX 7533 $tmparray = explode('-', $tmp); $begin_d = GETPOSTISSET('begin_d') ? GETPOSTINT('begin_d') : ($tmparray[0] != '' ? $tmparray[0] : 1); @@ -164,7 +164,7 @@ if ($end_d < $begin_d) { } if ($status == '' && !GETPOSTISSET('search_status')) { - $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); + $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS')); } if (empty($mode) && !GETPOSTISSET('mode')) { @@ -177,12 +177,12 @@ if (GETPOST('viewcal', 'alpha') && $mode != 'show_day' && $mode != 'show_week' & } // View by month if (GETPOST('viewweek', 'alpha') || $mode == 'show_week') { $mode = 'show_week'; - $week = ($week ? $week : idate("W")); - $day = ($day ? $day : idate("d")); + $week = ($week ? $week : date("W")); + $day = ($day ? $day : date("d")); } // View by week if (GETPOST('viewday', 'alpha') || $mode == 'show_day') { $mode = 'show_day'; - $day = ($day ? $day : idate("d")); + $day = ($day ? $day : date("d")); } // View by day $object = new ActionComm($db); @@ -193,7 +193,7 @@ $langs->loadLangs(array('users', 'agenda', 'other', 'commercial')); // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context $hookmanager->initHooks(array('agenda')); -$result = restrictedArea($user, 'agenda', 0, '', 'myactions'); +$result = restrictedArea($user, 'agenda', 0, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id'); if ($user->socid && $socid) { $result = restrictedArea($user, 'societe', $socid); } @@ -248,9 +248,65 @@ $nowmonth = $nowarray['mon']; $nowday = $nowarray['mday']; -// Define list of all external calendars (global setup) $listofextcals = array(); +// Define list of all external calendars (global setup) +if (!getDolGlobalString('AGENDA_DISABLE_EXT')) { + $i = 0; + while ($i < $MAXAGENDA) { + $i++; + $source = 'AGENDA_EXT_SRC'.$i; + $name = 'AGENDA_EXT_NAME'.$i; + $offsettz = 'AGENDA_EXT_OFFSETTZ'.$i; + $color = 'AGENDA_EXT_COLOR'.$i; + $default = 'AGENDA_EXT_ACTIVEBYDEFAULT'.$i; + $buggedfile = 'AGENDA_EXT_BUGGEDFILE'.$i; + if (getDolGlobalString($source) && getDolGlobalString($name)) { + // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' + $listofextcals[] = array( + 'type' => 'globalsetup', + 'src' => getDolGlobalString($source), + 'name' => dol_string_nohtmltag(getDolGlobalString($name)), + 'offsettz' => (int) getDolGlobalInt($offsettz, 0), + 'color' => dol_string_nohtmltag(getDolGlobalString($color)), + // @phan-suppress-next-line PhanPluginSuspiciousParamPosition + 'default' => dol_string_nohtmltag(getDolGlobalString($default)), + 'buggedfile' => dol_string_nohtmltag(getDolGlobalString('buggedfile', '')) + ); + } + } +} + +// Define list of external calendars (user setup) +if (!getDolUserString('AGENDA_DISABLE_EXT')) { + $i = 0; + while ($i < $MAXAGENDA) { + $i++; + $source = 'AGENDA_EXT_SRC_'.$user->id.'_'.$i; + $name = 'AGENDA_EXT_NAME_'.$user->id.'_'.$i; + $offsettz = 'AGENDA_EXT_OFFSETTZ_'.$user->id.'_'.$i; + $color = 'AGENDA_EXT_COLOR_'.$user->id.'_'.$i; + $enabled = 'AGENDA_EXT_ENABLED_'.$user->id.'_'.$i; + $default = 'AGENDA_EXT_ACTIVEBYDEFAULT_'.$user->id.'_'.$i; + $buggedfile = 'AGENDA_EXT_BUGGEDFILE_'.$user->id.'_'.$i; + + if (getDolUserString($source) && getDolUserString($name)) { + // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' + $listofextcals[] = array( + 'type' => 'usersetup', + 'src' => getDolUserString($source), + 'name' => dol_string_nohtmltag(getDolUserString($name)), + 'offsettz' => (int) (empty($user->conf->$offsettz) ? 0 : $user->conf->$offsettz), + 'color' => dol_string_nohtmltag(getDolUserString($color)), + // @phan-suppress-next-line PhanPluginSuspiciousParamPosition + 'default' => dol_string_nohtmltag(getDolUserString($default)), + 'buggedfile' => dol_string_nohtmltag(isset($user->conf->buggedfile) ? $user->conf->buggedfile : '') + ); + } + } +} + + $prev = dol_get_first_day_week($day, $month, $year); $first_day = $prev['first_day']; $first_month = $prev['first_month']; @@ -264,7 +320,7 @@ $next_year = $next['year']; $next_month = $next['month']; $next_day = $next['day']; -$max_day_in_month = idate("t", dol_mktime(0, 0, 0, $month, 1, $year)); +$max_day_in_month = date("t", dol_mktime(0, 0, 0, $month, 1, $year)); $tmpday = $first_day; //print 'xx'.$prev_year.'-'.$prev_month.'-'.$prev_day; @@ -296,7 +352,7 @@ if ($status || GETPOSTISSET('status') || GETPOSTISSET('search_status')) { $param .= "&search_status=".urlencode($status); } if ($filter) { - $param .= "&search_filter=".urlencode($filter); + $param .= "&search_filter=".urlencode((string) $filter); } if ($filtert) { $param .= "&search_filtert=".urlencode((string) $filtert); @@ -377,66 +433,31 @@ $nav .= " ".dol_print_date(dol_mktime(0, 0, 0, $first_mo $nav .= " \n"; $nav .= "   trans("Next"))."\">\n"; if (empty($conf->dol_optimize_smallscreen)) { - $nav .= "   '.$langs->trans("Today").' '; + $nav .= '   '.$langs->trans("Today").' '; } $nav .= ''; $nav .= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0); -$nav .= ' '; +//$nav .= ' '; +$nav .= ''; // Must be after the nav definition -$param .= '&year='.urlencode((string) ($year)).'&month='.urlencode((string) ($month)).($day ? '&day='.urlencode((string) ($day)) : ''); +$paramnodate = $param; +$param .= '&year='.$year.'&month='.$month.($day ? '&day='.$day : ''); //print 'x'.$param; -$paramnoaction = preg_replace('/action=[a-z_]+/', '', $param); +$paramnoaction = preg_replace('/mode=[a-z_]+/', '', preg_replace('/action=[a-z_]+/', '', $param)); +$paramnoactionodate = preg_replace('/mode=[a-z_]+/', '', preg_replace('/action=[a-z_]+/', '', $paramnodate)); $head = calendars_prepare_head($paramnoaction); print ''."\n"; - -$showextcals = $listofextcals; -// Legend -if ($conf->use_javascript_ajax) { - $s = ''; - $s .= ''."\n"; - if (!empty($conf->use_javascript_ajax)) { - $s .= '
'.$langs->trans("LocalAgenda").'  
'; - if (is_array($showextcals) && count($showextcals) > 0) { - foreach ($showextcals as $val) { - $htmlname = md5($val['name']); - $s .= ''."\n"; - $s .= '
'.$val ['name'].'  
'; - } - } - - //$s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; - - // Calendars from hooks - $parameters = array(); - $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); - if (empty($reshook)) { - $s .= $hookmanager->resPrint; - } elseif ($reshook > 1) { - $s = $hookmanager->resPrint; - } - } +if ($optioncss != '') { + print ''; } +print ''; +print ''; + $mode = 'show_peruser'; $massactionbutton = ''; @@ -515,43 +536,135 @@ if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda' $newcardbutton .= dolGetButtonTitle($langs->trans("AddAction"), '', 'fa fa-plus-circle', $urltocreateaction); } -$num = 0; - -print_barre_liste($langs->trans("Agenda"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, -1, 'object_action', 0, $nav.''.$newcardbutton, '', $limit, 1, 0, 1, $viewmode); +// Define the legend/list of calendard to show +$s = ''; $link = ''; -//print load_fiche_titre('', $link.'     '.$nav.' '.$newcardbutton, ''); -$s .= "\n".''."\n"; +$showextcals = $listofextcals; +$bookcalcalendars = array(); -// Local calendar -$newtitle = '
'; -$newtitle .= ' '.$langs->trans("LocalAgenda").'   '; -$newtitle .= '
'; -//$newtitle=$langs->trans($title); - -$s = $newtitle; - -// Calendars from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); -if (empty($reshook)) { - $s .= $hookmanager->resPrint; -} elseif ($reshook > 1) { - $s = $hookmanager->resPrint; +// Load Bookcal Calendars +if (isModEnabled("bookcal")) { + $sql = "SELECT ba.rowid, bc.label, bc.ref, bc.rowid as id_cal"; + $sql .= " FROM ".MAIN_DB_PREFIX."bookcal_availabilities as ba"; + $sql .= " JOIN ".MAIN_DB_PREFIX."bookcal_calendar as bc"; + $sql .= " ON bc.rowid = ba.fk_bookcal_calendar"; + $sql .= " WHERE bc.status = 1"; + $sql .= " AND ba.status = 1"; + $sql .= " AND bc.entity IN (".getEntity('agenda').")"; // bookcal is a "virtual view" of agenda + if (!empty($filtert) && $filtert != '-1') { + $sql .= " AND bc.visibility IN (".$db->sanitize($filtert, 0, 0, 0, 0).")"; + } + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) { + $objp = $db->fetch_object($resql); + $label = !empty($objp->label) ? $objp->label : $objp->ref; + $bookcalcalendars["calendars"][] = array("id" => $objp->id_cal, "label" => $label); + $bookcalcalendars["availabilitieslink"][$objp->rowid] = $objp->id_cal; + $i++; + } + } else { + dol_print_error($db); + } } -$s .= "\n".''."\n"; +if (!empty($conf->use_javascript_ajax)) { // If javascript on + $s .= "\n".''."\n"; -print $s; + $s .= ''."\n"; -print '
'; -print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, '', (string) $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid, $search_categ_cus); -print '
'; + // Local calendar + $s .= '
'; + + // Holiday calendar + if ($user->hasRight("holiday", "read")) { + $s .= ' +
+   +
'; + } + + // External calendars + if (is_array($showextcals) && count($showextcals) > 0) { + foreach ($showextcals as $val) { + $htmlname = md5($val['name']); // not used for security purpose, only to get a string with no special char + + $s .= ''."\n"; + $s .= '
'.$val ['name'].'  
'; + } + } + + // Birthdays + //$s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; + + // Bookcal Calendar + /* + if (isModEnabled("bookcal")) { + if (!empty($bookcalcalendars["calendars"])) { + foreach ($bookcalcalendars["calendars"] as $key => $value) { + $label = $value['label']; + $s .= '
'; + $s .= ''; + $s .= '  
'; + } + } + } + */ + + // Calendars from hooks + $parameters = array(); + $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); + if (empty($reshook)) { + $s .= $hookmanager->resPrint; + } elseif ($reshook > 1) { + $s = $hookmanager->resPrint; + } + + $s .= "\n".''."\n"; +} else { // If javascript off + $newparam = $param; // newparam is for birthday links + $newparam = preg_replace('/showbirthday=[0-1]/i', 'showbirthday='.(empty($showbirthday) ? 1 : 0), $newparam); + if (!preg_match('/showbirthday=/i', $newparam)) { + $newparam .= '&showbirthday=1'; + } + $link = ''; + if (empty($showbirthday)) { + $link .= $langs->trans("AgendaShowBirthdayEvents"); + } else { + $link .= $langs->trans("AgendaHideBirthdayEvents"); + } + $link .= ''; +} -// Get event in an array +// Load events from database into $eventarray $eventarray = array(); @@ -566,8 +679,14 @@ $sql .= " a.datep2,"; $sql .= " a.percent,"; $sql .= " a.fk_user_author,a.fk_user_action,"; $sql .= " a.transparency, a.priority, a.fulldayevent, a.location,"; -$sql .= " a.fk_soc, a.fk_contact, a.fk_element, a.elementtype, a.fk_project,"; -$sql .= " ca.code, ca.libelle as type_label, ca.color, ca.type as type_type, ca.picto as type_picto"; +$sql .= " a.fk_soc, a.fk_contact, a.fk_project, a.fk_bookcal_calendar,"; +$sql .= " a.fk_element, a.elementtype,"; +$sql .= " ca.code as type_code, ca.libelle as type_label, ca.color as type_color, ca.type as type_type, ca.picto as type_picto"; + +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; + $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm as ca, ".MAIN_DB_PREFIX."actioncomm as a"; // We must filter on resource table if ($resourceid > 0) { @@ -586,7 +705,7 @@ if ($filtert > 0 || $usergroup > 0) { } $sql .= " WHERE a.fk_action = ca.id"; -$sql .= " AND a.entity IN (".getEntity('agenda').")"; +$sql .= " AND a.entity IN (".getEntity('agenda').")"; // bookcal is a "virtual view" of agenda // Condition on actioncode if (!empty($actioncode)) { if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) { @@ -624,7 +743,7 @@ if ($pid) { } // If the internal user must only see his customers, force searching by him $search_sale = 0; -if (!$user->hasRight('societe', 'client', 'voir')) { +if (isModEnabled("societe") && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } // Search on sale representative @@ -668,6 +787,7 @@ if ($type) { $sql .= " AND ca.id = ".((int) $type); } if ($status == '0') { + // To do (not started) $sql .= " AND a.percent = 0"; } if ($status === 'na') { @@ -684,6 +804,18 @@ if ($status == 'done' || $status == '100') { if ($status == 'todo') { $sql .= " AND (a.percent >= 0 AND a.percent < 100)"; } +// We must filter on assignment table +if ($filtert > 0 || $usergroup > 0) { + $sql .= " AND ("; + if ($filtert > 0) { + $sql .= "ar.fk_element = ".((int) $filtert); + } + if ($usergroup > 0) { + $sql .= ($filtert > 0 ? " OR " : "")." ugu.fk_usergroup = ".((int) $usergroup); + } + $sql .= ")"; +} + // Search in categories, -1 is all and -2 is no categories if ($search_categ_cus != -1) { if ($search_categ_cus == -2) { @@ -701,13 +833,14 @@ $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); + $MAXONSAMEPAGE = 10000; // Useless to have more. Protection to avoid memory overload when high number of event (for example after a mass import) $i = 0; - while ($i < $num) { + while ($i < $num && $i < $MAXONSAMEPAGE) { $obj = $db->fetch_object($resql); //print $obj->fk_user_action.' '.$obj->id."
"; // Discard auto action if option is on - if (getDolGlobalString('AGENDA_ALWAYS_HIDE_AUTO') && $obj->code == 'AC_OTH_AUTO') { + if (getDolGlobalString('AGENDA_ALWAYS_HIDE_AUTO') && $obj->type_code == 'AC_OTH_AUTO') { $i++; continue; } @@ -718,49 +851,70 @@ if ($resql) { // Create a new object action $event = new ActionComm($db); + $event->id = $obj->id; - $event->datep = $datep; // datep and datef are GMT date - $event->datef = $datep2; - $event->type_code = $obj->code; - $event->type_color = $obj->color; + $event->ref = $event->id; + + $event->fulldayevent = $obj->fulldayevent; + + // event->datep and event->datef must be GMT date. + if ($event->fulldayevent) { + $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT'); + $event->datep = $db->jdate($obj->datep, $tzforfullday ? 'tzuser' : 'tzserver'); // If saved in $tzforfullday = gmt, we must invert date to be in user tz + $event->datef = $db->jdate($obj->datep2, $tzforfullday ? 'tzuser' : 'tzserver'); + } else { + // Example: $obj->datep = '1970-01-01 01:00:00', jdate will return 0 if TZ of PHP server is Europe/Berlin (+1) + $event->datep = $db->jdate($obj->datep, 'tzserver'); + $event->datef = $db->jdate($obj->datep2, 'tzserver'); + } + //$event->datep_formated_gmt = dol_print_date($event->datep, 'dayhour', 'gmt'); + //var_dump($obj->id.' '.$obj->datep.' '.dol_print_date($obj->datep, 'dayhour', 'gmt')); + //var_dump($obj->id.' '.$event->datep.' '.dol_print_date($event->datep, 'dayhour', 'gmt')); + + $event->type_code = $obj->type_code; + $event->type_label = $obj->type_label; + $event->type_color = $obj->type_color; + $event->type = $obj->type_type; + $event->type_picto = $obj->type_picto; + $event->label = $obj->label; $event->percentage = $obj->percent; $event->authorid = $obj->fk_user_author; // user id of creator $event->userownerid = $obj->fk_user_action; // user id of owner + $event->fetch_userassigned(); // This load $event->userassigned + $event->priority = $obj->priority; - $event->fulldayevent = $obj->fulldayevent; $event->location = $obj->location; $event->transparency = $obj->transparency; + $event->fk_element = $obj->fk_element; + $event->elementid = $obj->fk_element; + $event->elementtype = $obj->elementtype; $event->fk_project = $obj->fk_project; $event->socid = $obj->fk_soc; $event->contact_id = $obj->fk_contact; - - $event->fk_element = $obj->fk_element; - $event->elementid = $obj->fk_element; - $event->elementtype = $obj->elementtype; + $event->fk_bookcal_calendar = $obj->fk_bookcal_calendar; + if (!empty($event->fk_bookcal_calendar)) { + $event->type = "bookcal_calendar"; + } // Defined date_start_in_calendar and date_end_in_calendar property // They are date start and end of action but modified to not be outside calendar view. - $event->date_start_in_calendar = $datep; - if ($datep2 != '' && $datep2 >= $datep) { - $event->date_end_in_calendar = $datep2; + $event->date_start_in_calendar = $event->datep; + if ($event->datef != '' && $event->datef >= $event->datep) { + $event->date_end_in_calendar = $event->datef; } else { - $event->date_end_in_calendar = $datep; + $event->date_end_in_calendar = $event->datep; } //print '
'.$i.' - eventid='.$event->id.' '.dol_print_date($event->date_start_in_calendar, 'dayhour').' '.dol_print_date($firstdaytoshow, 'dayhour').' - '.dol_print_date($event->date_end_in_calendar, 'dayhour').' '.dol_print_date($lastdaytoshow, 'dayhour').'
'."\n"; // Check values - if ($event->date_end_in_calendar < $firstdaytoshow || - $event->date_start_in_calendar >= $lastdaytoshow) { + if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { // This record is out of visible range unset($event); } else { - //print $i.' - eventid='.$event->id.' '.dol_print_date($event->date_start_in_calendar, 'dayhour').' - '.dol_print_date($event->date_end_in_calendar, 'dayhour').'
'."\n"; - $event->fetch_userassigned(); // This load $event->userassigned - if ($event->date_start_in_calendar < $firstdaytoshow) { $event->date_start_in_calendar = $firstdaytoshow; } @@ -773,33 +927,527 @@ if ($resql) { $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); - //print $daycursor.' '.dol_print_date($daycursor, 'dayhour', 'gmt').' '.$event->id.' -> '.$annee.'-'.$mois.'-'.$jour.'
'; + + $daycursorend = $event->date_end_in_calendar; + $anneeend = (int) dol_print_date($daycursorend, '%Y', 'tzuserrel'); + $moisend = (int) dol_print_date($daycursorend, '%m', 'tzuserrel'); + $jourend = (int) dol_print_date($daycursorend, '%d', 'tzuserrel'); // Loop on each day covered by action to prepare an index to show on calendar $loop = true; $j = 0; - $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); // $mois, $jour, $annee has been set for user tz + $daykeyend = dol_mktime(0, 0, 0, $moisend, $jourend, $anneeend, 'gmt'); // $moisend, $jourend, $anneeend has been set for user tz + /* + print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'
'; + print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'
'; + print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'
'; + print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'
'; + print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'
'; + print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'
'; + */ do { - //print 'Add event into eventarray for daykey='.$daykey.'='.dol_print_date($daykey, 'dayhour', 'gmt').' '.$event->id.' '.$event->datep.' '.$event->datef.'
'; + //if ($event->id==408) + //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'gmt').' - '.dol_print_date($event->datep, 'dayhour', 'gmt').' '.dol_print_date($event->datef, 'dayhour', 'gmt').'
'; + //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'tzuserrel').' - '.dol_print_date($event->datep, 'dayhour', 'tzuserrel').' '.dol_print_date($event->datef, 'dayhour', 'tzuserrel').'
'; $eventarray[$daykey][] = $event; $j++; $daykey += 60 * 60 * 24; - if ($daykey > $event->date_end_in_calendar) { + //if ($daykey > $event->date_end_in_calendar) { + if ($daykey > $daykeyend) { $loop = false; } } while ($loop); - + //var_dump($eventarray); //print 'Event '.$i.' id='.$event->id.' (start='.dol_print_date($event->datep).'-end='.dol_print_date($event->datef); //print ' startincalendar='.dol_print_date($event->date_start_in_calendar).'-endincalendar='.dol_print_date($event->date_end_in_calendar).') was added in '.$j.' different index key of array
'; } + + $parameters['obj'] = $obj; + $reshook = $hookmanager->executeHooks('hookEventElements', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks + $event = $hookmanager->resPrint; + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + $i++; } $db->free($resql); } else { dol_print_error($db); } +//var_dump($eventarray); + + +// BIRTHDATES CALENDAR +// Complete $eventarray with birthdates +if ($showbirthday) { + // Add events in array + $sql = 'SELECT sp.rowid, sp.lastname, sp.firstname, sp.birthday'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'socpeople as sp'; + $sql .= ' WHERE (priv=0 OR (priv=1 AND fk_user_creat='.((int) $user->id).'))'; + $sql .= " AND sp.entity IN (".getEntity('contact').")"; + if ($mode == 'show_day') { + $sql .= ' AND MONTH(birthday) = '.((int) $month); + $sql .= ' AND DAY(birthday) = '.((int) $day); + } else { + $sql .= ' AND MONTH(birthday) = '.((int) $month); + } + $sql .= ' ORDER BY birthday'; + + dol_syslog("comm/action/index.php", LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $db->fetch_object($resql); + + $event = new ActionComm($db); + + $event->id = $obj->rowid; // We put contact id in action id for birthdays events + $event->ref = $event->id; + + $datebirth = dol_stringtotime($obj->birthday, 1); + //print 'ee'.$obj->birthday.'-'.$datebirth; + $datearray = dol_getdate($datebirth, true); + $event->datep = dol_mktime(0, 0, 0, $datearray['mon'], $datearray['mday'], $year, true); // For full day events, date are also GMT but they won't but converted during output + $event->datef = $event->datep; + + $event->type_code = 'BIRTHDAY'; + $event->type_label = ''; + $event->type_color = ''; + $event->type = 'birthdate'; + $event->type_picto = 'birthdate'; + + $event->label = $langs->trans("Birthday").' '.dolGetFirstLastname($obj->firstname, $obj->lastname); + $event->percentage = 100; + $event->fulldayevent = 1; + + $event->contact_id = $obj->rowid; + + $event->date_start_in_calendar = $db->jdate($event->datep); + $event->date_end_in_calendar = $db->jdate($event->datef); + + // Add an entry in eventarray for each day + $daycursor = $event->datep; + $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); + $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); + $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); + + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + + $eventarray[$daykey][] = $event; + + /*$loop = true; + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee); + do { + $eventarray[$daykey][] = $event; + $daykey += 60 * 60 * 24; + if ($daykey > $event->date_end_in_calendar) $loop = false; + } while ($loop); + */ + $i++; + } + } else { + dol_print_error($db); + } +} + +if ($user->hasRight("holiday", "read")) { + // LEAVE-HOLIDAY CALENDAR + $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.statut, x.rowid, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.statut as status"; + $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u"; + $sql .= " WHERE u.rowid = x.fk_user"; + $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user) + $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved) + + if ($mode == 'show_day') { + // Request only leaves for the current selected day + $sql .= " AND '".$db->escape($year)."-".$db->escape($month)."-".$db->escape($day)."' BETWEEN x.date_debut AND x.date_fin"; // date_debut and date_fin are date without time + } elseif ($mode == 'show_week') { + // Restrict on current month (we get more, but we will filter later) + $sql .= " AND date_debut < '".$db->idate(dol_get_last_day($year, $month))."'"; + $sql .= " AND date_fin >= '".$db->idate(dol_get_first_day($year, $month))."'"; + } elseif ($mode == 'show_month') { + // Restrict on current month + $sql .= " AND date_debut <= '".$db->idate(dol_get_last_day($year, $month))."'"; + $sql .= " AND date_fin >= '".$db->idate(dol_get_first_day($year, $month))."'"; + } + + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + + while ($i < $num) { + $obj = $db->fetch_object($resql); + + $event = new ActionComm($db); + + // Need the id of the leave object for link to it + $event->id = $obj->rowid; + $event->ref = $event->id; + + $event->type_code = 'HOLIDAY'; + $event->type_label = ''; + $event->type_color = ''; + $event->type = 'holiday'; + $event->type_picto = 'holiday'; + + $event->datep = $db->jdate($obj->date_start) + (empty($obj->halfday) || $obj->halfday == 1 ? 0 : 12 * 60 * 60 - 1); + $event->datef = $db->jdate($obj->date_end) + (empty($obj->halfday) || $obj->halfday == -1 ? 24 : 12) * 60 * 60 - 1; + $event->date_start_in_calendar = $event->datep; + $event->date_end_in_calendar = $event->datef; + + if ($obj->status == 3) { + // Show no symbol for leave with state "leave approved" + $event->percentage = -1; + } elseif ($obj->status == 2) { + // Show TO-DO symbol for leave with state "leave wait for approval" + $event->percentage = 0; + } + + if ($obj->halfday == 1) { + $event->label = $obj->lastname.' ('.$langs->trans("Morning").')'; + } elseif ($obj->halfday == -1) { + $event->label = $obj->lastname.' ('.$langs->trans("Afternoon").')'; + } else { + $event->label = $obj->lastname; + } + + $daycursor = $event->date_start_in_calendar; + $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); + $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); + $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); + + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + do { + $eventarray[$daykey][] = $event; + + $daykey += 60 * 60 * 24; + } while ($daykey <= $event->date_end_in_calendar); + + $i++; + } + } +} + +// EXTERNAL CALENDAR +// Complete $eventarray with external import Ical +if (count($listofextcals)) { + require_once DOL_DOCUMENT_ROOT.'/comm/action/class/ical.class.php'; + + foreach ($listofextcals as $key => $extcal) { + $url = $extcal['src']; // Example: https://www.google.com/calendar/ical/eldy10%40gmail.com/private-cde92aa7d7e0ef6110010a821a2aaeb/basic.ics + $namecal = $extcal['name']; + $offsettz = $extcal['offsettz']; + $colorcal = $extcal['color']; + $buggedfile = $extcal['buggedfile']; + + $pathforcachefile = dol_sanitizePathName($conf->user->dir_temp).'/'.dol_sanitizeFileName('extcal_'.$namecal.'_user'.$user->id).'.cache'; + //var_dump($pathforcachefile);exit; + + $ical = new ICal(); + $ical->parse($url, $pathforcachefile, $DELAYFORCACHE); + if ($ical->error) { + // Save error message for extcal + $listofextcals[$key]['error'] = $ical->error; + $s .= '
'.dol_escape_htmltag($listofextcals[$key]['name']).': '.$url.'
Error message: '.dol_escape_htmltag($ical->error).'
'; + } + + // After this $ical->cal['VEVENT'] contains array of events, $ical->cal['DAYLIGHT'] contains daylight info, $ical->cal['STANDARD'] contains non daylight info, ... + //var_dump($ical->cal); exit; + $icalevents = array(); + if (is_array($ical->get_event_list())) { + $icalevents = array_merge($icalevents, $ical->get_event_list()); // Add $ical->cal['VEVENT'] + } + if (is_array($ical->get_freebusy_list())) { + $icalevents = array_merge($icalevents, $ical->get_freebusy_list()); // Add $ical->cal['VFREEBUSY'] + } + + if (count($icalevents) > 0) { + // Duplicate all repeatable events into new entries + $moreicalevents = array(); + foreach ($icalevents as $icalevent) { + if (isset($icalevent['RRULE']) && is_array($icalevent['RRULE'])) { //repeatable event + //if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; + //if ($event->date_end_in_calendar > $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow-1); + if ($icalevent['DTSTART;VALUE=DATE']) { //fullday event + $datecurstart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1); + $datecurend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day + } elseif (is_array($icalevent['DTSTART']) && !empty($icalevent['DTSTART']['unixtime'])) { + $datecurstart = $icalevent['DTSTART']['unixtime']; + $datecurend = $icalevent['DTEND']['unixtime']; + if (!empty($ical->cal['DAYLIGHT']['DTSTART']) && $datecurstart) { + //var_dump($ical->cal); + $tmpcurstart = $datecurstart; + $tmpcurend = $datecurend; + $tmpdaylightstart = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['DAYLIGHT']['DTSTART']; + $tmpdaylightend = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['STANDARD']['DTSTART']; + //var_dump($tmpcurstart);var_dump($tmpcurend); var_dump($ical->cal['DAYLIGHT']['DTSTART']);var_dump($ical->cal['STANDARD']['DTSTART']); + // Edit datecurstart and datecurend + if ($tmpcurstart >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) { + $datecurstart -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36; + } else { + $datecurstart -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36; + } + if ($tmpcurend >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) { + $datecurend -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36; + } else { + $datecurend -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36; + } + } + // datecurstart and datecurend are now GMT date + //var_dump($datecurstart); var_dump($datecurend); exit; + } else { + // Not a recognized record + dol_syslog("Found a not recognized repeatable record with unknown date start", LOG_ERR); + continue; + } + //print 'xx'.$datecurstart;exit; + + $interval = (empty($icalevent['RRULE']['INTERVAL']) ? 1 : $icalevent['RRULE']['INTERVAL']); + $until = empty($icalevent['RRULE']['UNTIL']) ? 0 : dol_stringtotime($icalevent['RRULE']['UNTIL'], 1); + $maxrepeat = empty($icalevent['RRULE']['COUNT']) ? 0 : $icalevent['RRULE']['COUNT']; + if ($until && ($until + ($datecurend - $datecurstart)) < $firstdaytoshow) { + continue; // We discard repeatable event that end before start date to show + } + if ($datecurstart >= $lastdaytoshow) { + continue; // We discard repeatable event that start after end date to show + } + + $numofevent = 0; + while (($datecurstart < $lastdaytoshow) && (empty($maxrepeat) || ($numofevent < $maxrepeat))) { + if ($datecurend >= $firstdaytoshow) { // We add event + $newevent = $icalevent; + unset($newevent['RRULE']); + if ($icalevent['DTSTART;VALUE=DATE']) { + $newevent['DTSTART;VALUE=DATE'] = dol_print_date($datecurstart, '%Y%m%d'); + $newevent['DTEND;VALUE=DATE'] = dol_print_date($datecurend + 1, '%Y%m%d'); + } else { + $newevent['DTSTART'] = $datecurstart; + $newevent['DTEND'] = $datecurend; + } + $moreicalevents[] = $newevent; + } + // Jump on next occurrence + $numofevent++; + $savdatecurstart = $datecurstart; + if ($icalevent['RRULE']['FREQ'] == 'DAILY') { + $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'd'); + $datecurend = dol_time_plus_duree($datecurend, $interval, 'd'); + } + if ($icalevent['RRULE']['FREQ'] == 'WEEKLY') { + $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'w'); + $datecurend = dol_time_plus_duree($datecurend, $interval, 'w'); + } elseif ($icalevent['RRULE']['FREQ'] == 'MONTHLY') { + $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'm'); + $datecurend = dol_time_plus_duree($datecurend, $interval, 'm'); + } elseif ($icalevent['RRULE']['FREQ'] == 'YEARLY') { + $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'y'); + $datecurend = dol_time_plus_duree($datecurend, $interval, 'y'); + } + // Test to avoid infinite loop ($datecurstart must increase) + if ($savdatecurstart >= $datecurstart) { + dol_syslog("Found a rule freq ".$icalevent['RRULE']['FREQ']." not managed by dolibarr code. Assume 1 week frequency.", LOG_ERR); + $datecurstart += 3600 * 24 * 7; + $datecurend += 3600 * 24 * 7; + } + } + } + } + $icalevents = array_merge($icalevents, $moreicalevents); + + // Loop on each entry into cal file to know if entry is qualified and add an ActionComm into $eventarray + foreach ($icalevents as $icalevent) { + //var_dump($icalevent); + + //print $icalevent['SUMMARY'].'->'; + //var_dump($icalevent);exit; + if (!empty($icalevent['RRULE'])) { + continue; // We found a repeatable event. It was already split into unitary events, so we discard general rule. + } + + // Create a new object action + $event = new ActionComm($db); + $addevent = false; + if (isset($icalevent['DTSTART;VALUE=DATE'])) { // fullday event + // For full day events, date are also GMT but they won't but converted using tz during output + $datestart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1); + if (empty($icalevent['DTEND;VALUE=DATE'])) { + $dateend = $datestart + 86400 - 1; + } else { + $dateend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day + } + //print 'x'.$datestart.'-'.$dateend;exit; + //print dol_print_date($dateend,'dayhour','gmt'); + $event->fulldayevent = 1; + $addevent = true; + } elseif (!is_array($icalevent['DTSTART'])) { // not fullday event (DTSTART is not array. It is a value like '19700101T000000Z' for 00:00 in greenwitch) + $datestart = $icalevent['DTSTART']; + $dateend = empty($icalevent['DTEND']) ? $datestart : $icalevent['DTEND']; + + $datestart += +($offsettz * 3600); + $dateend += +($offsettz * 3600); + + $addevent = true; + //var_dump($offsettz); + //var_dump(dol_print_date($datestart, 'dayhour', 'gmt')); + } elseif (isset($icalevent['DTSTART']['unixtime'])) { // File contains a local timezone + a TZ (for example when using bluemind) + $datestart = $icalevent['DTSTART']['unixtime']; + $dateend = $icalevent['DTEND']['unixtime']; + + $datestart += +($offsettz * 3600); + $dateend += +($offsettz * 3600); + + // $buggedfile is set to uselocalandtznodaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtznodaylight' + if ($buggedfile === 'uselocalandtznodaylight') { // unixtime is a local date that does not take daylight into account, TZID is +1 for example for 'Europe/Paris' in summer instead of 2 + // TODO + } + // $buggedfile is set to uselocalandtzdaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtzdaylight' (for example with bluemind) + if ($buggedfile === 'uselocalandtzdaylight') { // unixtime is a local date that does take daylight into account, TZID is +2 for example for 'Europe/Paris' in summer + $localtzs = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTSTART']['TZID'])); + $localtze = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTEND']['TZID'])); + $localdts = new DateTime(dol_print_date($datestart, 'dayrfc', 'gmt'), $localtzs); + $localdte = new DateTime(dol_print_date($dateend, 'dayrfc', 'gmt'), $localtze); + $tmps = -1 * $localtzs->getOffset($localdts); + $tmpe = -1 * $localtze->getOffset($localdte); + $datestart += $tmps; + $dateend += $tmpe; + //var_dump($datestart); + } + $addevent = true; + } + + if ($addevent) { + $event->id = $icalevent['UID']; + $event->ref = $event->id; + $userId = $userstatic->findUserIdByEmail($namecal); + if (!empty($userId) && $userId > 0) { + $event->userassigned[$userId] = $userId; + $event->percentage = -1; + } + + $event->type_code = "ICALEVENT"; + $event->type_label = $namecal; + $event->type_color = $colorcal; + $event->type = 'icalevent'; + $event->type_picto = 'rss'; + + $event->icalname = $namecal; + $event->icalcolor = $colorcal; + $usertime = 0; // We don't modify date because we want to have date into memory datep and datef stored as GMT date. Compensation will be done during output. + $event->datep = $datestart + $usertime; + $event->datef = $dateend + $usertime; + + if (isset($icalevent['SUMMARY']) && $icalevent['SUMMARY']) { + $event->label = dol_string_nohtmltag($icalevent['SUMMARY']); + } elseif (isset($icalevent['DESCRIPTION']) && $icalevent['DESCRIPTION']) { + $event->label = dol_nl2br(dol_string_nohtmltag($icalevent['DESCRIPTION']), 1); + } else { + $event->label = $langs->trans("ExtSiteNoLabel"); + } + + // Priority (see https://www.kanzaki.com/docs/ical/priority.html) + // LOW = 0 to 4 + // MEDIUM = 5 + // HIGH = 6 to 9 + if (!empty($icalevent['PRIORITY'])) { + $event->priority = $icalevent['PRIORITY']; + } + + // Transparency (see https://www.kanzaki.com/docs/ical/transp.html) + if (!empty($icalevent['TRANSP'])) { + if ($icalevent['TRANSP'] == "TRANSPARENT") { + $event->transparency = 0; // 0 = available / free + } + if ($icalevent['TRANSP'] == "OPAQUE") { + $event->transparency = 1; // 1 = busy + } + + // TODO: MS outlook states + // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:TRANSPARENT => Available / Free + // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:OPAQUE => Work another place + // X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE + TRANSP:OPAQUE => With reservations + // X-MICROSOFT-CDO-BUSYSTATUS:BUSY + TRANSP:OPAQUE => Busy + // X-MICROSOFT-CDO-BUSYSTATUS:OOF + TRANSP:OPAQUE => Away from the office / off-site + } + + if (!empty($icalevent['LOCATION'])) { + $event->location = $icalevent['LOCATION']; + } + + $event->date_start_in_calendar = $event->datep; + + if ($event->datef != '' && $event->datef >= $event->datep) { + $event->date_end_in_calendar = $event->datef; + } else { + $event->date_end_in_calendar = $event->datep; + } + + // Add event into $eventarray if date range are ok. + if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { + //print 'x'.$datestart.'-'.$dateend;exit; + //print 'x'.$datestart.'-'.$dateend;exit; + //print 'x'.$datestart.'-'.$dateend;exit; + // This record is out of visible range + } else { + if ($event->date_start_in_calendar < $firstdaytoshow) { + $event->date_start_in_calendar = $firstdaytoshow; + } + if ($event->date_end_in_calendar >= $lastdaytoshow) { + $event->date_end_in_calendar = ($lastdaytoshow - 1); + } + + // Add an entry in actionarray for each day + $daycursor = $event->date_start_in_calendar; + $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); + $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); + $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); + + // Loop on each day covered by action to prepare an index to show on calendar + $loop = true; + $j = 0; + // daykey must be date that represent day box in calendar so must be a user time + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + do { + //if ($event->fulldayevent) print dol_print_date($daykeygmt,'dayhour','gmt').'-'.dol_print_date($daykey,'dayhour','gmt').'-'.dol_print_date($event->date_end_in_calendar,'dayhour','gmt').' '; + $eventarray[$daykey][] = $event; + $daykey += 60 * 60 * 24; + $daykeygmt += 60 * 60 * 24; // Add one day + if (($event->fulldayevent ? $daykeygmt : $daykey) > $event->date_end_in_calendar) { + $loop = false; + } + } while ($loop); + } + } + } + } + } +} + +// Complete $eventarray with events coming from external module +$parameters = array(); +$object = null; +$reshook = $hookmanager->executeHooks('getCalendarEvents', $parameters, $object, $action); +if (!empty($hookmanager->resArray['eventarray'])) { + foreach ($hookmanager->resArray['eventarray'] as $keyDate => $events) { + if (!isset($eventarray[$keyDate])) { + $eventarray[$keyDate] = array(); + } + $eventarray[$keyDate] = array_merge($eventarray[$keyDate], $events); + } +} + +// Sort events +foreach ($eventarray as $keyDate => &$dateeventarray) { + usort($dateeventarray, 'sort_events_by_date'); +} + $maxnbofchar = 18; $cachethirdparties = array(); @@ -812,9 +1460,24 @@ if (is_readable($color_file)) { include $color_file; } if (!is_array($theme_datacolor)) { - $theme_datacolor = array(array(120, 130, 150), array(200, 160, 180), array(190, 190, 220)); + $theme_datacolor = array(array(137, 86, 161), array(60, 147, 183), array(250, 190, 80), array(80, 166, 90), array(190, 190, 100), array(91, 115, 247), array(140, 140, 220), array(190, 120, 120), array(115, 125, 150), array(100, 170, 20), array(150, 135, 125), array(85, 135, 150), array(150, 135, 80), array(150, 80, 150)); } +$massactionbutton = ''; + +$num = 0; + +print_barre_liste($langs->trans("Agenda"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, -1, 'object_action', 0, $nav.''.$newcardbutton, '', $limit, 1, 0, 1, $viewmode); + +$link = ''; + +// Show div with list of calendars +print $s; + +print '
'; +print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, '', (string) $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid, $search_categ_cus); +print '
'; + $newparam = $param; // newparam is for birthday links $newparam = preg_replace('/showbirthday=/i', 'showbirthday_=', $newparam); // To avoid replacement when replace day= is done @@ -1091,6 +1754,7 @@ if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && getDolGlobalString('AGENDA_US } print "\n".''; + print "\n"; // Add js code to manage click on a box @@ -1187,13 +1851,13 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & // We are in a particular day for $username, now we scan all events foreach ($eventarray as $daykey => $notused) { - $annee = dol_print_date($daykey, '%Y', 'tzuserrel'); - $mois = dol_print_date($daykey, '%m', 'tzuserrel'); - $jour = dol_print_date($daykey, '%d', 'tzuserrel'); + $annee = (int) dol_print_date($daykey, '%Y', 'tzuserrel'); + $mois = (int) dol_print_date($daykey, '%m', 'tzuserrel'); + $jour = (int) dol_print_date($daykey, '%d', 'tzuserrel'); //var_dump("daykey=$daykey day=$day jour=$jour, month=$month mois=$mois, year=$year annee=$annee"); - if ($day == $jour && (int) $month == (int) $mois && $year == $annee) { // Is it the day we are looking for when calling function ? + if ($day == $jour && (int) $month == $mois && $year == $annee) { // Is it the day we are looking for when calling function ? //var_dump("day=$day jour=$jour month=$month mois=$mois year=$year annee=$annee"); // Scan all event for this date diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index a3db32f86cb..606ca72fecf 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -924,16 +924,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print '
'; print ''; $daterange = ''; - if ($event->type_code == 'BIRTHDAY') { - // It's birthday calendar - $picb = ''; - //$pice = ''; - //$typea = ($objp->typea == 'birth') ? $picb : $pice; - //var_dump($event); - print $picb.' '.$langs->trans("Birthday").'
'; - //print img_picto($langs->trans("Birthday"), 'birthday-cake').' '; - - $tmpid = $event->id; - - if (empty($cachecontacts[$tmpid])) { - $newcontact = new Contact($db); - $newcontact->fetch($tmpid); - $cachecontacts[$tmpid] = $newcontact; - } - print $cachecontacts[$tmpid]->getNomUrl(1, '', 0, '', -1, 0, 'valignmiddle inline-block'); - - //$event->picto = 'birthday-cake'; - //print $event->getNomUrl(1, $maxnbofchar, 'cal_event', 'birthday', 'contact'); - /*$listofcontacttoshow = ''; - $listofcontacttoshow .= '
'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valignmiddle'); - print $listofcontacttoshow; - */ - } elseif ($event->type_code == 'HOLIDAY') { - // It's holiday calendar - $tmpholiday->fetch($event->id); - - print $tmpholiday->getNomUrl(1, -1, 0, 'valignmiddle inline-block'); - - $tmpid = $tmpholiday->fk_user; - if (empty($cacheusers[$tmpid])) { - $newuser = new User($db); - $newuser->fetch($tmpid); - $cacheusers[$tmpid] = $newuser; - } - - $listofusertoshow = ''; - $listofusertoshow .= '
'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valignmiddle inline-block'); - print $listofusertoshow; - } - $parameters = array(); $reshook = $hookmanager->executeHooks('eventOptions', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { @@ -2174,41 +2160,49 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } */ - // Date - if (empty($event->fulldayevent)) { - // Show hours (start ... end) - $tmpyearstart = dol_print_date($event->date_start_in_calendar, '%Y', 'tzuserrel'); - $tmpmonthstart = dol_print_date($event->date_start_in_calendar, '%m', 'tzuserrel'); - $tmpdaystart = dol_print_date($event->date_start_in_calendar, '%d', 'tzuserrel'); - $tmpyearend = dol_print_date($event->date_end_in_calendar, '%Y', 'tzuserrel'); - $tmpmonthend = dol_print_date($event->date_end_in_calendar, '%m', 'tzuserrel'); - $tmpdayend = dol_print_date($event->date_end_in_calendar, '%d', 'tzuserrel'); + if ($event->type_code == 'BIRTHDAY') { + // It's birthday calendar + $picb = img_picto('', 'birthday-cake', 'class="pictofixedwidth"'); + print $picb.$langs->trans("Birthday").'
'; + } - // Hour start - if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) { - $daterange .= dol_print_date($event->date_start_in_calendar, 'hour', 'tzuserrel'); - if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { - if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) { - $daterange .= '-'; + // Date + if ($event->type_code != 'HOLIDAY' && $event->type_code != 'BIRTHDAY') { + if (empty($event->fulldayevent)) { + // Show hours (start ... end) + $tmpyearstart = dol_print_date($event->date_start_in_calendar, '%Y', 'tzuserrel'); + $tmpmonthstart = dol_print_date($event->date_start_in_calendar, '%m', 'tzuserrel'); + $tmpdaystart = dol_print_date($event->date_start_in_calendar, '%d', 'tzuserrel'); + $tmpyearend = dol_print_date($event->date_end_in_calendar, '%Y', 'tzuserrel'); + $tmpmonthend = dol_print_date($event->date_end_in_calendar, '%m', 'tzuserrel'); + $tmpdayend = dol_print_date($event->date_end_in_calendar, '%d', 'tzuserrel'); + + // Hour start + if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) { + $daterange .= dol_print_date($event->date_start_in_calendar, 'hour', 'tzuserrel'); + if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { + if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) { + $daterange .= '-'; + } + //else + //print '...'; } - //else - //print '...'; } - } - if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { - if ($tmpyearstart != $tmpyearend || $tmpmonthstart != $tmpmonthend || $tmpdaystart != $tmpdayend) { - $daterange .= '...'; + if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { + if ($tmpyearstart != $tmpyearend || $tmpmonthstart != $tmpmonthend || $tmpdaystart != $tmpdayend) { + $daterange .= '...'; + } } - } - // Hour end - if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { - if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) { - $daterange .= dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel'); + // Hour end + if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { + if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) { + $daterange .= dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel'); + } + } + } else { + if ($showinfo) { + print $langs->trans("EventOnFullDay")."
\n"; } - } - } else { - if ($showinfo) { - print $langs->trans("EventOnFullDay")."
\n"; } } @@ -2216,7 +2210,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $titletoshow = $daterange; $titletoshow .= ($titletoshow ? ' ' : '').dol_escape_htmltag($event->label); - if ($event->type_code != 'ICALEVENT') { + if ($event->type_code != 'ICALEVENT' && $event->type_code != 'BIRTHDAY') { $savlabel = $event->label; $event->label = $titletoshow; // Note: List of users are inside $event->userassigned. Link may be clickable depending on permissions of user. @@ -2242,8 +2236,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $listofusertoshow .= $cacheusers[$tmpid]->getNomUrl(-3, '', 0, 0, 0, 0, '', 'valignmiddle inline-block'); } - print $titletoshow; - print $listofusertoshow.'  '; + if ($event->type_code != 'BIRTHDAY') { + print $titletoshow; + print $listofusertoshow.'  '; + } if ($event->type_code == 'ICALEVENT') { print '
('.dol_trunc($event->icalname, $maxnbofchar).')'; @@ -2263,7 +2259,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $thirdparty = $cachethirdparties[$thirdparty_id]; } if (!empty($thirdparty->id)) { - $linerelatedto .= $thirdparty->getNomUrl(1, '', 0, 0, -1, 0, '', 'valignmiddle inline-block'); + $linerelatedto .= $thirdparty->getNomUrl(1, '', 0, 0, -1, 0, '', 'valignmiddle inline'); // using inline-block make the content completely replace with ... when too large } } if (!empty($contact_id) && $contact_id > 0) { @@ -2278,7 +2274,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $linerelatedto .= ' '; } if (!empty($contact->id)) { - $linerelatedto .= $contact->getNomUrl(1, '', 0, '', -1, 0, 'valignmiddle inline-block'); + $linerelatedto .= $contact->getNomUrl(1, '', 0, '', -1, 0, 'valignmiddle inline'); // using inline-block make the content completely replace with ... when too large } } if (!empty($event->fk_element) && $event->fk_element > 0 && !empty($event->elementtype) && getDolGlobalString('AGENDA_SHOW_LINKED_OBJECT')) { @@ -2296,6 +2292,24 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } } + if ($event->type_code == 'HOLIDAY') { + // It's holiday calendar + $tmpholiday->fetch($event->id); + + //print $tmpholiday->getNomUrl(1, -1, 0, 'valignmiddle inline-block'); + + $tmpid = $tmpholiday->fk_user; + if (empty($cacheusers[$tmpid])) { + $newuser = new User($db); + $newuser->fetch($tmpid); + $cacheusers[$tmpid] = $newuser; + } + + $listofusertoshow = ''; + $listofusertoshow .= "\n".'
'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valignmiddle inline-block')."\n"; + print $listofusertoshow; + } + // Show location if ($showinfo) { if ($event->location) { @@ -2305,9 +2319,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } print '
'; // Date To Birth - print ''; - print '\n"; + } else { + $out .= '\n"; + } + } - $entity = (isset($this->param['object_entity']) ? $this->param['object_entity'] : $conf->entity); - if ($entity > 1) { - $relativepathtofile = str_replace('/' . $entity . '/', '/', $relativepathtofile); - } - // Try to extract data from full path - $formfile_params = array(); - preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params); + // To + if (!empty($this->withto) || is_array($this->withto)) { + $out .= $this->getHtmlForTo(); + } - $out .= '
'; - // Preview of attachment - $out .= img_mime($listofnames[$key]) . $listofnames[$key]; + // To User + if (!empty($this->withtouser) && is_array($this->withtouser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) { + $out .= '
\n"; + } - if (!$this->withfilereadonly) { - $out .= ' '; - //$out.= ' '.img_delete($langs->trans("Remove"), 'id="removedfile_'.$key.'" name="removedfile_'.$key.'"', 'removedfile input-nobottom').''; - } - $out .= '
'; + // With option for one email per recipient + if (!empty($this->withoptiononeemailperrecipient)) { + if (abs($this->withoptiononeemailperrecipient) == 1) { + $out .= ''; + } else { + $out .= ''; + } + } + + // CC + if (!empty($this->withtocc) || is_array($this->withtocc)) { + $out .= $this->getHtmlForCc(); + } + + // To User cc + if (!empty($this->withtoccuser) && is_array($this->withtoccuser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) { + $out .= '\n"; + } + + // CCC + if (!empty($this->withtoccc) || is_array($this->withtoccc)) { + $out .= $this->getHtmlForWithCcc(); + } + + // Replyto + if (!empty($this->withreplyto)) { + if ($this->withreplytoreadonly) { + $out .= ''; + $out .= ''; + $out .= "\n"; + } + } + + // Errorsto + if (!empty($this->witherrorsto)) { + $out .= $this->getHtmlForWithErrorsTo(); + } + + // Ask delivery receipt + if (!empty($this->withdeliveryreceipt) && getDolGlobalInt('MAIN_EMAIL_SUPPORT_ACK')) { + $out .= $this->getHtmlForDeliveryreceipt(); + } + + // Topic + if (!empty($this->withtopic)) { + $out .= $this->getHtmlForTopic($arraydefaultmessage, $helpforsubstitution); + } + + // Attached files + if (!empty($this->withfile)) { + $out .= ''; + $out .= ''; + + $out .= '\n"; + } else { + $out .= $this->withfile; } - // Message (+ Links to choose layout or ai prompt) - if (!empty($this->withbody)) { - $defaultmessage = GETPOST('message', 'restricthtml'); - if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') { - if ($arraydefaultmessage && $arraydefaultmessage->content) { - $defaultmessage = $arraydefaultmessage->content; - } elseif (!is_numeric($this->withbody)) { - $defaultmessage = $this->withbody; - } - } + $out .= "\n"; + } - // Complete substitution array with the url to make online payment + // Message (+ Links to choose layout or ai prompt) + if (!empty($this->withbody)) { + $defaultmessage = GETPOST('message', 'restricthtml'); + if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') { + if ($arraydefaultmessage && $arraydefaultmessage->content) { + $defaultmessage = $arraydefaultmessage->content; + } elseif (!is_numeric($this->withbody)) { + $defaultmessage = $this->withbody; + } + } + + // Complete substitution array with the url to make online payment + $paymenturl = ''; + // Set the online payment url link into __ONLINE_PAYMENT_URL__ key + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + $validpaymentmethod = getValidOnlinePaymentMethods(''); + + if (empty($this->substit['__REF__'])) { // @phan-suppress-current-line PhanTypeMismatchProperty $paymenturl = ''; - // Set the online payment url link into __ONLINE_PAYMENT_URL__ key - require_once DOL_DOCUMENT_ROOT . '/core/lib/payments.lib.php'; - $validpaymentmethod = getValidOnlinePaymentMethods(''); - - if (empty($this->substit['__REF__'])) { // @phan-suppress-current-line PhanTypeMismatchProperty - $paymenturl = ''; - } else { - $langs->loadLangs(array('paypal', 'other')); - $typeforonlinepayment = 'free'; - if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') { - $typeforonlinepayment = 'order'; // TODO use detection on something else than template - } - if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') { - $typeforonlinepayment = 'invoice'; // TODO use detection on something else than template - } - if ($this->param["models"] == 'member') { - $typeforonlinepayment = 'member'; // TODO use detection on something else than template - } - $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']); - $paymenturl = $url; + } else { + $langs->loadLangs(array('paypal', 'other')); + $typeforonlinepayment = 'free'; + if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') { + $typeforonlinepayment = 'order'; // TODO use detection on something else than template } - - if (count($validpaymentmethod) > 0 && $paymenturl) { - $langs->load('other'); - $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl)); - $this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl; - } elseif (count($validpaymentmethod) > 0) { - $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__'; - $this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__'; - } else { - $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = ''; - $this->substit['__ONLINE_PAYMENT_URL__'] = ''; + if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') { + $typeforonlinepayment = 'invoice'; // TODO use detection on something else than template } - - $this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = ''; - - // Generate the string with the template for lines repeated and filled for each line - $lines = ''; - $defaultlines = $arraydefaultmessage->content_lines; - if (isset($defaultlines)) { - foreach ($this->substit_lines as $lineid => $substit_line) { - $lines .= make_substitutions($defaultlines, $substit_line) . "\n"; - } + if ($this->param["models"] == 'member') { + $typeforonlinepayment = 'member'; // TODO use detection on something else than template } - $this->substit['__LINES__'] = $lines; - - $defaultmessage = str_replace('\n', "\n", $defaultmessage); - - // Deal with format differences between message and some substitution variables (text / HTML) - $atleastonecomponentishtml = 0; - if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) { - $atleastonecomponentishtml++; - } - if (strpos($defaultmessage, '__SENDEREMAIL_SIGNATURE__') !== false && dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) { - $atleastonecomponentishtml++; - } - if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) { - $atleastonecomponentishtml++; - } - if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) { - $atleastonecomponentishtml++; - } - if (dol_textishtml($defaultmessage)) { - $atleastonecomponentishtml++; - } - if ($atleastonecomponentishtml) { - if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) { - $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']); - } - if (!dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) { - $this->substit['__SENDEREMAIL_SIGNATURE__'] = dol_nl2br($this->substit['__SENDEREMAIL_SIGNATURE__']); - } - if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) { - $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']); - } - if (!dol_textishtml($defaultmessage)) { - $defaultmessage = dol_nl2br($defaultmessage); - } - } - - if (GETPOSTISSET("message") && !GETPOST('modelselected')) { - $defaultmessage = GETPOST("message", "restricthtml"); - } else { - $defaultmessage = make_substitutions($defaultmessage, $this->substit); - // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty) - $defaultmessage = preg_replace("/^(
)+/", "", $defaultmessage); - $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage); - } - - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - - $out .= ''; - $out .= '\n"; + $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']); + $paymenturl = $url; } - $out .= '
'; + print '
'; $form = new Form($db); if ($object->birthday) { print $form->selectDate($object->birthday, 'birthday', 0, 0, 0, "perso", 1, 0); } else { print $form->selectDate('', 'birthday', 0, 0, 1, "perso", 1, 0); } - print ': '; + print '   '; if (!empty($object->birthday_alert)) { print ''; } else { diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index cfe0f519db9..de0d14ebd49 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -246,7 +246,7 @@ $holidaystatic = new Holiday($db); // Update sold $result = $object->updateBalance(); -$title = $langs->trans('CPTitreMenu'); +$title = $langs->trans('Holidays'); $help_url = 'EN:Module_Holiday'; llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-holiday page-list'); @@ -542,9 +542,6 @@ if ($id > 0) { // For user tab print ''; } else { - $title = $langs->trans("ListeCP"); - - $newcardbutton = ''; $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition')); $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition')); diff --git a/htdocs/langs/fr_FR/holiday.lang b/htdocs/langs/fr_FR/holiday.lang index 859f6d0d00a..7c9c40ea112 100644 --- a/htdocs/langs/fr_FR/holiday.lang +++ b/htdocs/langs/fr_FR/holiday.lang @@ -1,7 +1,7 @@ # Dolibarr language file - Source file is en_US - holiday HRM=GRH Holidays=Congés -Holiday=Demande de congés +Holiday=Congés CPTitreMenu=Demande de congés MenuReportMonth=État mensuel MenuAddCP=Créer demande de congés From e9e7b854104880c84207d13ca370a1d560a8d72d Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 24 Jan 2025 20:22:23 +0100 Subject: [PATCH 166/602] Debug v21 - pb holiday view into agenda --- htdocs/comm/action/index.php | 23 +-- htdocs/comm/action/pertype.php | 2 - htdocs/comm/action/peruser.php | 326 ++++++++++++++++++------------- htdocs/theme/eldy/global.inc.php | 7 +- htdocs/theme/md/style.css.php | 8 + htdocs/user/perms.php | 3 +- 6 files changed, 219 insertions(+), 150 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 02737de7db2..e13c531d640 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -620,8 +620,8 @@ if (!empty($conf->use_javascript_ajax)) { // If javascript on $s .= '' . "\n"; - if (count($listofpaths)) { - foreach ($listofpaths as $key => $val) { - $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val))); + $out .= "
'.$langs->trans("MailFrom").""; + $out .= $langs->trans("Name").':'; + $out .= '    '; + $out .= $langs->trans("EMail").':<>'; + $out .= "
'; + $out .= $langs->trans("MailToUsers"); + $out .= ''; - $out .= ' ' . $formfile->showPreview(array(), $formfile_params[2], $formfile_params[4], 0, ($entity == 1 ? '' : 'entity=' . ((int)$entity))); + // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time + $tmparray = $this->withtouser; + foreach ($tmparray as $key => $val) { + $tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true); + } + $withtoselected = GETPOST("receiveruser", 'array'); // Array of selected value + if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') { + $withtoselected = array_keys($tmparray); + } + $out .= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, ""); + $out .= "
'; + $out .= $langs->trans("GroupEmails"); + $out .= ''; + $out .= ' withoptiononeemailperrecipient > 0 ? ' checked="checked"' : '').'> '; + $out .= ''; + //$out .= ''; + //$out .= ' - '; + //$out .= $langs->trans("WarningIfYouCheckOneRecipientPerEmail"); + //$out .= ''; + if (getDolGlobalString('MASS_ACTION_EMAIL_ON_DIFFERENT_THIRPARTIES_ADD_CUSTOM_EMAIL')) { + if (!empty($this->withto) && !is_array($this->withto)) { + $out .= ' '.$langs->trans("or").' '; + } + } + $out .= '
'; + $out .= $langs->trans("MailToCCUsers"); + $out .= ''; + + // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time + $tmparray = $this->withtoccuser; + foreach ($tmparray as $key => $val) { + $tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true); + } + $withtoselected = GETPOST("receiverccuser", 'array'); // Array of selected value + if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') { + $withtoselected = array_keys($tmparray); + } + $out .= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, ""); + $out .= "
".$langs->trans("MailReply")."".$this->replytoname.($this->replytomail ? (" <".$this->replytomail.">") : ""); + $out .= "
'.$langs->trans("MailFile").''; + + if ($this->withmaindocfile) { + // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked) + if (GETPOSTISSET('sendmail')) { + $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1); + } elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { + // If a template was selected, we use setup of template to define if join file checkbox is selected or not. + $this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1); + } + } + + if (!empty($this->withmaindocfile)) { + if ($this->withmaindocfile == 1) { + $out .= ''; + } elseif ($this->withmaindocfile == -1) { + $out .= ''; + } + if (getDolGlobalString('MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND')) { + $out .= '
'; + } else { + $out .= '
'; + } + } + + if (is_numeric($this->withfile)) { + // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript + $out .= ''."\n"; + $out .= ''."\n"; + if (count($listofpaths)) { + foreach ($listofpaths as $key => $val) { + $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val))); + + $entity = (isset($this->param['object_entity']) ? $this->param['object_entity'] : $conf->entity); + if ($entity > 1) { + $relativepathtofile = str_replace('/'.$entity.'/', '/', $relativepathtofile); } - } /*elseif (empty($this->withmaindocfile)) { + // Try to extract data from full path + $formfile_params = array(); + preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params); + + $out .= '
'; + // Preview of attachment + $out .= img_mime($listofnames[$key]).$listofnames[$key]; + + $out .= ' '.$formfile->showPreview(array(), $formfile_params[2], $formfile_params[4], 0, ($entity == 1 ? '' : 'entity='.((int) $entity))); + + if (!$this->withfilereadonly) { + $out .= ' '; + //$out.= ' '.img_delete($langs->trans("Remove"), 'id="removedfile_'.$key.'" name="removedfile_'.$key.'"', 'removedfile input-nobottom').''; + } + $out .= '
'; + } + } /*elseif (empty($this->withmaindocfile)) { //$out .= ''.$langs->trans("NoAttachedFiles").'
'; }*/ - if ($this->withfile == 2) { - $maxfilesizearray = getMaxFileSizeArray(); - $maxmin = $maxfilesizearray['maxmin']; - if ($maxmin > 0) { - $out .= ''; // MAX_FILE_SIZE must precede the field type=file - } - // Can add other files - if (!getDolGlobalString('FROM_MAIL_DONT_USE_INPUT_FILE_MULTIPLE')) { - $out .= ''; - } else { - $out .= ''; - } - $out .= ' '; - $out .= ''; + if ($this->withfile == 2) { + $maxfilesizearray = getMaxFileSizeArray(); + $maxmin = $maxfilesizearray['maxmin']; + if ($maxmin > 0) { + $out .= ''; // MAX_FILE_SIZE must precede the field type=file } - } else { - $out .= $this->withfile; + // Can add other files + if (!getDolGlobalString('FROM_MAIL_DONT_USE_INPUT_FILE_MULTIPLE')) { + $out .= ''; + } else { + $out .= ''; + } + $out .= ' '; + $out .= ''; } - - $out .= "
'; - $out .= $form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody'); - $out .= ''; - - $formmail = $this; - $showlinktolayout = ($formmail->withfckeditor && getDolGlobalInt('MAIN_EMAIL_USE_LAYOUT')) ? $formmail->withlayout : ''; - $showlinktolayoutlabel = $langs->trans("FillMessageWithALayout"); - $showlinktoai = ($formmail->withaiprompt && isModEnabled('ai')) ? 'textgenerationemail' : ''; - $showlinktoailabel = $langs->trans("FillMessageWithAIContent"); - $formatforouput = ''; - $htmlname = 'message'; - - // Fill $out - include DOL_DOCUMENT_ROOT . '/core/tpl/formlayoutai.tpl.php'; - - $out .= '
'; - if ($this->withbodyreadonly) { - $out .= nl2br($defaultmessage); - $out .= ''; - } else { - if (!isset($this->ckeditortoolbar)) { - $this->ckeditortoolbar = 'dolibarr_mailings'; - } - - // Editor wysiwyg - require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; - if ($this->withfckeditor == -1) { - if (getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) { - $this->withfckeditor = 1; - } else { - $this->withfckeditor = 0; - } - } - - $doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%'); - $out .= $doleditor->Create(1); - } - $out .= "
' . "\n"; - - if ($this->withform == 1 || $this->withform == -1) { - $out .= '
'; - $out .= 'withfile == 2 && $conf->use_javascript_ajax) { - $out .= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\'' . dol_escape_js($langs->trans("FileWasNotUploaded")) . '\'); return false; } else { return true; }"'; - } - $out .= ' />'; - if ($this->withcancel) { - $out .= ''; - } - $out .= '
' . "\n"; + if (count($validpaymentmethod) > 0 && $paymenturl) { + $langs->load('other'); + $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl)); + $this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl; + } elseif (count($validpaymentmethod) > 0) { + $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__'; + $this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__'; + } else { + $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = ''; + $this->substit['__ONLINE_PAYMENT_URL__'] = ''; } - if ($this->withform == 1) { - $out .= '' . "\n"; + $this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = ''; + + // Generate the string with the template for lines repeated and filled for each line + $lines = ''; + $defaultlines = $arraydefaultmessage->content_lines; + if (isset($defaultlines)) { + foreach ($this->substit_lines as $lineid => $substit_line) { + $lines .= make_substitutions($defaultlines, $substit_line)."\n"; + } + } + $this->substit['__LINES__'] = $lines; + + $defaultmessage = str_replace('\n', "\n", $defaultmessage); + + // Deal with format differences between message and some substitution variables (text / HTML) + $atleastonecomponentishtml = 0; + if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) { + $atleastonecomponentishtml++; + } + if (strpos($defaultmessage, '__SENDEREMAIL_SIGNATURE__') !== false && dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) { + $atleastonecomponentishtml++; + } + if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) { + $atleastonecomponentishtml++; + } + if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) { + $atleastonecomponentishtml++; + } + if (dol_textishtml($defaultmessage)) { + $atleastonecomponentishtml++; + } + if ($atleastonecomponentishtml) { + if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) { + $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']); + } + if (!dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) { + $this->substit['__SENDEREMAIL_SIGNATURE__'] = dol_nl2br($this->substit['__SENDEREMAIL_SIGNATURE__']); + } + if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) { + $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']); + } + if (!dol_textishtml($defaultmessage)) { + $defaultmessage = dol_nl2br($defaultmessage); + } } - // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set - if (getDolGlobalString('MAIN_MAILFORM_DISABLE_ENTERKEY')) { - $out .= ''; - } - - $out .= "\n"; - - return $out; + $out .= ' })'; + $out .= ''; } + + $out .= "\n"; + + return $out; } } + /** * get html For To * @@ -1694,7 +1693,7 @@ class FormMail extends Form // Use the multiselect array function to create the dropdown $out .= ''; $out .= ''."\n"; - // Add headers + + // Add HTML headers (must be before the Add of the common CSS and js). The common js may content javascript using jquery or a framework loaded by the HTML header. $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= preg_replace('/<\/?html>/ims', '', $objectpage->htmlheader)."\n"; + + // Add css + $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; + + // Add js + $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; + // Page content $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= $objectpage->content."\n"; From 579b0918df72c33a1b01c757166ac8b03258e57b Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 28 Jan 2025 20:08:04 +0100 Subject: [PATCH 309/602] Doc --- htdocs/core/lib/website2.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 0a6885fba3d..0f11bd01a63 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -306,11 +306,11 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $tplcontent .= preg_replace('/<\/?html>/ims', '', $objectpage->htmlheader)."\n"; // Add css - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; // Add js - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; From 4a08b6cfcbdda5a31995ffc5f1a1d5b0a651c8a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 28 Jan 2025 20:32:57 +0100 Subject: [PATCH 310/602] fix phpstan --- 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 690866f52c3..3186e8d9e74 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2128,7 +2128,7 @@ class CommandeFournisseur extends CommonOrder $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', (empty($this->fk_soc) ? $this->socid : $this->fk_soc)); if ($qty < $prod->packaging) { - $qty = $prod->packaging; + $qty = (float) $prod->packaging; } else { if (!empty($prod->packaging) && (fmod((float) $qty, (float) $prod->packaging) > 0.000001)) { $coeff = intval((float) $qty / $prod->packaging) + 1; From 612c26c2e023a7c15d3a953677326a3d9e5e9ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 28 Jan 2025 20:35:25 +0100 Subject: [PATCH 311/602] fix phpstan --- htdocs/fourn/class/fournisseur.commande.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 3186e8d9e74..7b1500750d1 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2211,8 +2211,9 @@ class CommandeFournisseur extends CommonOrder $this->line->total_localtax2 = (float) $total_localtax2; $this->line->total_ttc = (float) $total_ttc; $this->line->product_type = $type; - $this->line->special_code = (!empty($special_code) ? $special_code : 0); + $this->line->special_code = (!empty($special_code) ? $special_code : 0); $this->line->origin = $origin; + $this->line->origin_type = $origin; $this->line->origin_id = $origin_id; $this->line->fk_unit = $fk_unit; From 00249c9a90b6206cf7359507fd4163e674ac9cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 28 Jan 2025 20:46:05 +0100 Subject: [PATCH 312/602] fix phpstan --- .../class/fournisseur.commande.class.php | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 7b1500750d1..700be6e45fc 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -553,16 +553,16 @@ class CommandeFournisseur extends CommonOrder $this->user_validation_id = $obj->user_validation_id; $this->user_approve_id = $obj->user_approve_id; $this->user_approve_id2 = $obj->user_approve_id2; - $this->total_ht = $obj->total_ht; - $this->total_tva = $obj->total_tva; - $this->total_localtax1 = $obj->localtax1; - $this->total_localtax2 = $obj->localtax2; - $this->total_ttc = $obj->total_ttc; + $this->total_ht = $obj->total_ht; + $this->total_tva = $obj->total_tva; + $this->total_localtax1 = $obj->localtax1; + $this->total_localtax2 = $obj->localtax2; + $this->total_ttc = $obj->total_ttc; $this->date_creation = $this->db->jdate($obj->date_creation); $this->date_valid = $this->db->jdate($obj->date_valid); - $this->date_approve = $this->db->jdate($obj->date_approve); - $this->date_approve2 = $this->db->jdate($obj->date_approve2); - $this->date_commande = $this->db->jdate($obj->date_commande); // date we make the order to supplier + $this->date_approve = $this->db->jdate($obj->date_approve); + $this->date_approve2 = $this->db->jdate($obj->date_approve2); + $this->date_commande = $this->db->jdate($obj->date_commande); // date we make the order to supplier if (isset($obj->date_commande)) { $this->date = $this->date_commande; } else { @@ -1372,9 +1372,11 @@ class CommandeFournisseur extends CommonOrder $this->ref = $this->newref; if ($movetoapprovestatus) { - $this->statut = self::STATUS_ACCEPTED; + $this->statut = self::STATUS_ACCEPTED; // deprecated + $this->status = self::STATUS_ACCEPTED; } else { - $this->statut = self::STATUS_VALIDATED; + $this->statut = self::STATUS_VALIDATED; // deprecated + $this->status = self::STATUS_VALIDATED; } if (empty($secondlevel)) { // standard or first level approval $this->date_approve = $now; @@ -1531,7 +1533,8 @@ class CommandeFournisseur extends CommonOrder dol_syslog(get_class($this)."::commande", LOG_DEBUG); if ($this->db->query($sql)) { - $this->statut = self::STATUS_ORDERSENT; + $this->statut = self::STATUS_ORDERSENT; // deprecated + $this->status = self::STATUS_ORDERSENT; $this->methode_commande_id = $methode; $this->date_commande = $date; $this->context = array('comments' => $comment); @@ -1827,7 +1830,7 @@ class CommandeFournisseur extends CommonOrder $sql .= " localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 : "null").","; $sql .= " total_ht=".(isset($this->total_ht) ? $this->total_ht : "null").","; $sql .= " total_ttc=".(isset($this->total_ttc) ? $this->total_ttc : "null").","; - $sql .= " fk_statut=".(isset($this->statut) ? $this->statut : "null").","; + $sql .= " fk_statut=".(isset($this->status) ? $this->status : "null").","; $sql .= " fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id : "null").","; $sql .= " fk_user_valid=".(isset($this->user_validation_id) && $this->user_validation_id > 0 ? $this->user_validation_id : "null").","; $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; @@ -1923,7 +1926,8 @@ class CommandeFournisseur extends CommonOrder } $this->id = 0; - $this->statut = self::STATUS_DRAFT; + $this->statut = self::STATUS_DRAFT; // deprecated + $this->status = self::STATUS_DRAFT; // Clear fields $this->user_author_id = $user->id; @@ -2259,8 +2263,7 @@ class CommandeFournisseur extends CommonOrder return -1; } } else { - $this->error = $this->line->error; - $this->errors = $this->line->errors; + $this->setErrorsFromObject($this->line); dol_syslog(get_class($this)."::addline error=".$this->error, LOG_ERR); $this->db->rollback(); return -1; @@ -2313,7 +2316,7 @@ class CommandeFournisseur extends CommonOrder $inventorycode = dol_print_date(dol_now(), 'dayhourlog'); - if (($this->statut == self::STATUS_ORDERSENT || $this->statut == self::STATUS_RECEIVED_PARTIALLY || $this->statut == self::STATUS_RECEIVED_COMPLETELY)) { + if (($this->status == self::STATUS_ORDERSENT || $this->status == self::STATUS_RECEIVED_PARTIALLY || $this->status == self::STATUS_RECEIVED_COMPLETELY)) { $this->db->begin(); $sql = "INSERT INTO ".$this->db->prefix()."receptiondet_batch"; @@ -2387,7 +2390,7 @@ class CommandeFournisseur extends CommonOrder { global $user; - if ($this->statut == 0) { + if ($this->status == 0) { $line = new CommandeFournisseurLigne($this->db); if ($line->fetch($idline) <= 0) { @@ -2680,8 +2683,8 @@ class CommandeFournisseur extends CommonOrder $resql = $this->db->query($sql); if ($resql) { $result = 1; - $old_statut = $this->statut; - $this->statut = $statut; + $old_statut = $this->status; + $this->status = $statut; $this->context['actionmsg2'] = $comment; // Call trigger @@ -2694,7 +2697,7 @@ class CommandeFournisseur extends CommonOrder if (empty($error)) { $this->db->commit(); } else { - $this->statut = $old_statut; + $this->status = $old_statut; $this->db->rollback(); $this->error = $this->db->lasterror(); $result = -1; @@ -2932,7 +2935,7 @@ class CommandeFournisseur extends CommonOrder } if (!$error) { - $this->statut = $status; + $this->status = $status; $this->db->commit(); return 1; } else { @@ -2972,7 +2975,7 @@ class CommandeFournisseur extends CommonOrder $error = 0; - if ($this->statut == self::STATUS_DRAFT) { + if ($this->status == self::STATUS_DRAFT) { // Clean parameters if (empty($qty)) { $qty = 0; @@ -3193,7 +3196,7 @@ class CommandeFournisseur extends CommonOrder $this->multicurrency_tx = 1; $this->multicurrency_code = $conf->currency; - $this->statut = 0; + $this->statut = 0; // deprecated $this->status = 0; // Lines @@ -3536,7 +3539,7 @@ class CommandeFournisseur extends CommonOrder { global $conf; - if ($this->statut == self::STATUS_ORDERSENT || $this->statut == self::STATUS_RECEIVED_PARTIALLY) { + if ($this->status == self::STATUS_ORDERSENT || $this->status == self::STATUS_RECEIVED_PARTIALLY) { $now = dol_now(); if (!empty($this->delivery_date)) { $date_to_test = $this->delivery_date; @@ -3550,7 +3553,7 @@ class CommandeFournisseur extends CommonOrder $now = dol_now(); $date_to_test = $this->date_commande; - return ($this->statut > 0 && $this->statut < 5) && $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay); + return ($this->status > 0 && $this->status < 5) && $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay); } } @@ -3569,7 +3572,7 @@ class CommandeFournisseur extends CommonOrder $text = ''; - if ($this->statut == self::STATUS_ORDERSENT || $this->statut == self::STATUS_RECEIVED_PARTIALLY) { + if ($this->status == self::STATUS_ORDERSENT || $this->status == self::STATUS_RECEIVED_PARTIALLY) { if (!empty($this->delivery_date)) { $text = $langs->trans("DeliveryDate").' '.dol_print_date($this->delivery_date, 'day'); } else { From bb261ce017b220eb3f30fa17872083dc8929f2a3 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 28 Jan 2025 21:12:55 +0100 Subject: [PATCH 313/602] Fix cache delay param --- htdocs/website/samples/wrapper.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/website/samples/wrapper.php b/htdocs/website/samples/wrapper.php index eadc7c68a53..51c6c2500bb 100644 --- a/htdocs/website/samples/wrapper.php +++ b/htdocs/website/samples/wrapper.php @@ -129,10 +129,11 @@ if (GETPOSTISSET('type')) { $original_file = str_replace("../", "/", $original_file); // Cache or not -if (GETPOST("cache", 'aZ09') || image_format_supported($original_file) >= 0) { +$cachestring = GETPOST("cache", 'aZ09'); // May be 1, or an int, or a hash +if ($cachestring || image_format_supported($original_file) >= 0) { // Important: Following code is to avoid page request by browser and PHP CPU at // each Dolibarr page access. - header('Cache-Control: max-age=3600, public, must-revalidate'); + header('Cache-Control: max-age='.((is_numeric($cachestring) && (int) $cachestring > 1 && (int) $cachestring < 999999) ? $cachestring : '3600').', public, must-revalidate'); header('Pragma: cache'); // This is to avoid having Pragma: no-cache } From 64f1d966f13f77c920619518cbba7b14897219b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 28 Jan 2025 21:33:32 +0100 Subject: [PATCH 314/602] fix phpstan --- htdocs/fourn/class/fournisseur.class.php | 9 +++++---- htdocs/fourn/class/fournisseur.commande.class.php | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.class.php b/htdocs/fourn/class/fournisseur.class.php index 2529bce86ec..20eb2ef661b 100644 --- a/htdocs/fourn/class/fournisseur.class.php +++ b/htdocs/fourn/class/fournisseur.class.php @@ -1,9 +1,10 @@ - * Copyright (C) 2006 Laurent Destailleur - * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2011 Juanjo Menent +/* Copyright (C) 2004-2007 Rodolphe Quiedeville + * Copyright (C) 2006 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2024 MDW + * Copyright (C) 2025 Frédéric France * * 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 diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 700be6e45fc..9ad00e00bc2 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -14,8 +14,8 @@ * Copyright (C) 2021 Josep Lluís Amador * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2024 Solution Libre SAS - * Copyright (C) 2024 MDW - * Copyright (C) 2024 William Mead + * Copyright (C) 2024 MDW + * Copyright (C) 2024 William Mead * * 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 @@ -3358,7 +3358,8 @@ class CommandeFournisseur extends CommonOrder while ($obj = $this->db->fetch_object($resql)) { $commandestatic->delivery_date = $this->db->jdate($obj->delivery_date); $commandestatic->date_commande = $this->db->jdate($obj->date_commande); - $commandestatic->statut = $obj->fk_statut; + $commandestatic->statut = $obj->fk_statut; // deprecated + $commandestatic->status = $obj->fk_statut; $response->nbtodo++; $response->total += $obj->total_ht; From 656a63acdc7d51673b5f9af52cf4d6e8688fb77f Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 28 Jan 2025 22:07:11 +0100 Subject: [PATCH 315/602] Debug v21 --- htdocs/core/class/html.form.class.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 71031684d57..34623d573df 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -933,9 +933,10 @@ class Form * @param int<0,1> $addspecialentries 1=Add dedicated entries for group of countries (like 'European Economic Community', ...) * @param string[] $exclude_country_code Array of country code (iso2) to exclude * @param int<0,1> $hideflags Hide flags + * @param int<0,1> $forcecombo Force to load all values and output a standard combobox (with no beautification) * @return string HTML string with select */ - public function select_country($selected = '', $htmlname = 'country_id', $htmloption = '', $maxlength = 0, $morecss = 'minwidth300', $usecodeaskey = '', $showempty = 1, $disablefavorites = 0, $addspecialentries = 0, $exclude_country_code = array(), $hideflags = 0) + public function select_country($selected = '', $htmlname = 'country_id', $htmloption = '', $maxlength = 0, $morecss = 'minwidth300', $usecodeaskey = '', $showempty = 1, $disablefavorites = 0, $addspecialentries = 0, $exclude_country_code = array(), $hideflags = 0, $forcecombo = 0) { // phpcs:enable global $conf, $langs, $mysoc; @@ -1047,8 +1048,10 @@ class Form } // Make select dynamic - include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $out .= ajax_combobox('select' . $htmlname, array(), 0, 0, 'resolve'); + if (empty($forcecombo)) { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $out .= ajax_combobox('select' . $htmlname, array(), 0, 0, 'resolve'); + } return $out; } @@ -1076,7 +1079,7 @@ class Form $langs->load("dict"); $out = ''; - $moreattrib = ''; + //$moreattrib = ''; $incotermArray = array(); $sql = "SELECT rowid, code"; @@ -1129,7 +1132,7 @@ class Form if ($conf->use_javascript_ajax && empty($disableautocomplete)) { $out .= ajax_multiautocompleter('location_incoterms', array(), DOL_URL_ROOT . '/core/ajax/locationincoterms.php') . "\n"; - $moreattrib .= ' autocomplete="off"'; + //$moreattrib .= ' autocomplete="off"'; } $out .= '' . "\n"; From 995e0792e5872d075059b2aa3f5979512878ba42 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jan 2025 00:44:39 +0100 Subject: [PATCH 316/602] Fix escaping var --- htdocs/product/class/product.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 0a9b0206f54..0f368838f0f 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1311,12 +1311,12 @@ class Product extends CommonObject $sql .= ", accountancy_code_sell_export= '" . $this->db->escape($this->accountancy_code_sell_export) . "'"; } $sql .= ", desiredstock = ".((isset($this->desiredstock) && is_numeric($this->desiredstock)) ? (float) $this->desiredstock : "null"); - $sql .= ", cost_price = ".($this->cost_price != '' ? $this->db->escape($this->cost_price) : 'null'); + $sql .= ", cost_price = ".($this->cost_price != '' ? ((float) $this->cost_price) : 'null'); $sql .= ", fk_unit= ".(!$this->fk_unit ? 'NULL' : (int) $this->fk_unit); $sql .= ", price_autogen = ".(!$this->price_autogen ? 0 : 1); $sql .= ", fk_price_expression = ".($this->fk_price_expression != 0 ? (int) $this->fk_price_expression : 'NULL'); - $sql .= ", fk_user_modif = ".($user->id > 0 ? $user->id : 'NULL'); - $sql .= ", mandatory_period = ".($this->mandatory_period); + $sql .= ", fk_user_modif = ".($user->id > 0 ? (int) $user->id : 'NULL'); + $sql .= ", mandatory_period = ".((int) $this->mandatory_period); // stock field is not here because it is a denormalized value from product_stock. $sql .= " WHERE rowid = ".((int) $id); From 1c7a3a0e73d0379a3d09f21c42beb57cc073b2ad Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jan 2025 01:38:11 +0100 Subject: [PATCH 317/602] More complete fix for #32839 --- htdocs/core/lib/functions.lib.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 27c1b697b5e..0a8cab279a9 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1,5 +1,4 @@ * Copyright (C) 2003 Jean-Louis Bergamo * Copyright (C) 2004-2024 Laurent Destailleur @@ -2172,7 +2171,7 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta $tmp = str_ireplace('__DONOTDECODEAPOS', '&apos', $tmp); $tmp = str_ireplace('__DONOTDECODE39', ''', $tmp); - $tmp = str_ireplace(''', '__SIMPLEQUOTE', $tmp); // HTML 4 + $tmp = str_ireplace(''', '__SIMPLEQUOTE__', $tmp); // HTML 4 } if (!$keepb) { $tmp = strtr($tmp, array("" => '', '' => '', '' => '', '' => '')); @@ -2213,7 +2212,7 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta if (preg_match('/<'.preg_quote($tagtoreplace, '/').'(\s+)([^>]+)>/', $tmp, $reg)) { // We want to protect the attribute part ... in '' to avoid transformation by htmlentities() later $tmpattributes = str_ireplace(array('[', ']'), '_', $reg[2]); // We must never have [ ] inside the attribute string - $tmpattributes = str_ireplace('"', '__DOUBLEQUOTE', $tmpattributes); + $tmpattributes = str_ireplace('"', '__DOUBLEQUOTE__', $tmpattributes); $tmpattributes = preg_replace('/[^a-z0-9_%,\/\?\;\s=&\.\-@:\.#\+]/i', '', $tmpattributes); //$tmpattributes = preg_replace("/float:\s*(left|right)/", "", $tmpattributes); // Disabled: we must not remove content $tmp = str_replace('<'.$tagtoreplace.$reg[1].$reg[2].'>', '__BEGINTAGTOREPLACE'.$tagtoreplace.'['.$tmpattributes.']__', $tmp); @@ -2223,9 +2222,9 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta } while ($diff); } - $tmp = str_ireplace('"', '__DOUBLEQUOTE', $tmp); - $tmp = str_ireplace('<', '__LESSTAN', $tmp); - $tmp = str_ireplace('>', '__GREATERTHAN', $tmp); + $tmp = str_ireplace('"', '__DOUBLEQUOTENOSEMICOLON__', $tmp); + $tmp = str_ireplace('<', '__LESSTHAN__', $tmp); + $tmp = str_ireplace('>', '__GREATERTHAN__', $tmp); } // Warning: htmlentities encode HTML tags like & into & and more (but not < > "es; ' ' & that remains untouched). @@ -2243,12 +2242,14 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta $result = preg_replace('/__BEGINENDTAGTOREPLACE'.$tagtoreplace.'\[([^\]]*)\]__/', '<'.$tagtoreplace.' \1 />', $result); } - $result = str_ireplace('__DOUBLEQUOTE', '"', $result); - $result = str_ireplace('__LESSTAN', '<', $result); - $result = str_ireplace('__GREATERTHAN', '>', $result); + $result = str_ireplace('__DOUBLEQUOTE__', '"', $result); + + $result = str_ireplace('__DOUBLEQUOTENOSEMICOLON__', '"', $result); + $result = str_ireplace('__LESSTHAN__', '<', $result); + $result = str_ireplace('__GREATERTHAN__', '>', $result); } - $result = str_ireplace('__SIMPLEQUOTE', ''', $result); + $result = str_ireplace('__SIMPLEQUOTE__', ''', $result); //$result="\n\n\n".var_export($tmp, true)."\n\n\n".var_export($result, true); From 09a282bc38bdd95282fe56871813153430234e6a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jan 2025 01:38:11 +0100 Subject: [PATCH 318/602] More complete fix for #32839 --- htdocs/core/lib/functions.lib.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 41387eacc26..7ad4d1888ce 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2169,7 +2169,7 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta $tmp = str_ireplace('__DONOTDECODEAPOS', '&apos', $tmp); $tmp = str_ireplace('__DONOTDECODE39', ''', $tmp); - $tmp = str_ireplace(''', '__SIMPLEQUOTE', $tmp); // HTML 4 + $tmp = str_ireplace(''', '__SIMPLEQUOTE__', $tmp); // HTML 4 } if (!$keepb) { $tmp = strtr($tmp, array("" => '', '' => '', '' => '', '' => '')); @@ -2210,7 +2210,7 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta if (preg_match('/<'.preg_quote($tagtoreplace, '/').'(\s+)([^>]+)>/', $tmp, $reg)) { // We want to protect the attribute part ... in '' to avoid transformation by htmlentities() later $tmpattributes = str_ireplace(array('[', ']'), '_', $reg[2]); // We must never have [ ] inside the attribute string - $tmpattributes = str_ireplace('"', '__DOUBLEQUOTE', $tmpattributes); + $tmpattributes = str_ireplace('"', '__DOUBLEQUOTE__', $tmpattributes); $tmpattributes = preg_replace('/[^a-z0-9_%,\/\?\;\s=&\.\-@:\.#\+]/i', '', $tmpattributes); //$tmpattributes = preg_replace("/float:\s*(left|right)/", "", $tmpattributes); // Disabled: we must not remove content $tmp = str_replace('<'.$tagtoreplace.$reg[1].$reg[2].'>', '__BEGINTAGTOREPLACE'.$tagtoreplace.'['.$tmpattributes.']__', $tmp); @@ -2220,9 +2220,9 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta } while ($diff); } - $tmp = str_ireplace('"', '__DOUBLEQUOTE', $tmp); - $tmp = str_ireplace('<', '__LESSTAN', $tmp); - $tmp = str_ireplace('>', '__GREATERTHAN', $tmp); + $tmp = str_ireplace('"', '__DOUBLEQUOTENOSEMICOLON__', $tmp); + $tmp = str_ireplace('<', '__LESSTHAN__', $tmp); + $tmp = str_ireplace('>', '__GREATERTHAN__', $tmp); } // Warning: htmlentities encode HTML tags like & into & and more (but not < > "es; ' ' & that remains untouched). @@ -2240,12 +2240,14 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta $result = preg_replace('/__BEGINENDTAGTOREPLACE'.$tagtoreplace.'\[([^\]]*)\]__/', '<'.$tagtoreplace.' \1 />', $result); } - $result = str_ireplace('__DOUBLEQUOTE', '"', $result); - $result = str_ireplace('__LESSTAN', '<', $result); - $result = str_ireplace('__GREATERTHAN', '>', $result); + $result = str_ireplace('__DOUBLEQUOTE__', '"', $result); + + $result = str_ireplace('__DOUBLEQUOTENOSEMICOLON__', '"', $result); + $result = str_ireplace('__LESSTHAN__', '<', $result); + $result = str_ireplace('__GREATERTHAN__', '>', $result); } - $result = str_ireplace('__SIMPLEQUOTE', ''', $result); + $result = str_ireplace('__SIMPLEQUOTE__', ''', $result); //$result="\n\n\n".var_export($tmp, true)."\n\n\n".var_export($result, true); From e5c385999d73490e1b0ab68477444178b2984f88 Mon Sep 17 00:00:00 2001 From: MDW Date: Sun, 19 Jan 2025 02:30:36 +0100 Subject: [PATCH 319/602] Qual: Fix multiple phan notices # Qual: Fix multiple phan notices Fix multiple phan notices --- htdocs/comm/propal/class/propal.class.php | 14 +++---- htdocs/commande/class/commande.class.php | 38 +++++++++--------- htdocs/compta/facture/class/facture.class.php | 7 ++-- htdocs/core/class/html.form.class.php | 38 +++++++++--------- htdocs/ecm/dir_card.php | 4 +- htdocs/ecm/index.php | 14 ++++--- .../conferenceorbooth_card.php | 10 ++--- .../conferenceorbooth_list.php | 7 ++-- .../conferenceorboothattendee_card.php | 18 +++++---- .../conferenceorboothattendee_list.php | 37 ++++++++--------- htdocs/expedition/card.php | 40 +++++++++---------- htdocs/expedition/class/expedition.class.php | 12 +++--- htdocs/expedition/contact.php | 6 ++- htdocs/expedition/dispatch.php | 18 +++++---- htdocs/expedition/document.php | 4 +- htdocs/expedition/list.php | 19 ++++----- htdocs/expedition/note.php | 4 +- htdocs/expedition/shipment.php | 33 +++++++-------- htdocs/expensereport/card.php | 35 ++++++++-------- 19 files changed, 187 insertions(+), 171 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index eb81c4c084e..ecd6898734c 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -19,7 +19,7 @@ * Copyright (C) 2022 OpenDSI * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2023 William Mead - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -146,23 +146,23 @@ class Propal extends CommonObject /** * @var int|'' - * @deprecated + * @deprecated Use $date_validation * @see $date_validation */ public $datev; /** - * @var integer|'' $date_validation; + * @var int|'' */ public $date_validation; /** - * @var integer|'' $date_signature; + * @var int|'' */ public $date_signature; /** - * @var User $user_signature + * @var User */ public $user_signature; @@ -715,7 +715,7 @@ class Propal extends CommonObject if ($qty < $product->packaging) { $qty = $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); @@ -772,7 +772,7 @@ class Propal extends CommonObject $this->line->fk_propal = $this->id; $this->line->label = $label; $this->line->desc = $desc; - $this->line->qty = $qty; + $this->line->qty = (float) $qty; $this->line->vat_src_code = $vat_src_code; $this->line->tva_tx = $txtva; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 71e03085f69..6c747d2602b 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -13,7 +13,7 @@ * Copyright (C) 2016-2022 Ferran Marcet * Copyright (C) 2021-2025 Frédéric France * Copyright (C) 2022 Gauthier VERDOL - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 William Mead * * This program is free software; you can redistribute it and/or modify @@ -1637,10 +1637,10 @@ class Commande extends CommonOrder if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { $product = new Product($this->db); $result = $product->fetch($fk_product); - if ($qty < $product->packaging) { + if ($qty < (float) $product->packaging) { $qty = $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); @@ -1703,7 +1703,7 @@ class Commande extends CommonOrder $this->line->fk_commande = $this->id; $this->line->label = $label; $this->line->desc = $desc; - $this->line->qty = $qty; + $this->line->qty = (float) $qty; $this->line->ref_ext = $ref_ext; $this->line->vat_src_code = $vat_src_code; @@ -1863,21 +1863,21 @@ class Commande extends CommonOrder $this->lines[] = $line; /** POUR AJOUTER AUTOMATIQUEMENT LES SOUSPRODUITS a LA COMMANDE - if (getDolGlobalString('PRODUIT_SOUSPRODUITS')) { - $prod = new Product($this->db); - $prod->fetch($idproduct); - $prod -> get_sousproduits_arbo(); - $prods_arbo = $prod->get_arbo_each_prod(); - if(count($prods_arbo) > 0) - { - foreach($prods_arbo as $key => $value) - { - // print "id : ".$value[1].' :qty: '.$value[0].'
'; - if not in lines { - $this->add_product($value[1], $value[0]); - } - } - } + * if (getDolGlobalString('PRODUIT_SOUSPRODUITS')) { + * $prod = new Product($this->db); + * $prod->fetch($idproduct); + * $prod -> get_sousproduits_arbo(); + * $prods_arbo = $prod->get_arbo_each_prod(); + * if(count($prods_arbo) > 0) + * { + * foreach($prods_arbo as $key => $value) + * { + * // print "id : ".$value[1].' :qty: '.$value[0].'
'; + * if not in lines { + * $this->add_product($value[1], $value[0]); + * } + * } + * } **/ } } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 09dddafbbd5..88430241586 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -20,7 +20,7 @@ * Copyright (C) 2022 Sylvain Legrand * Copyright (C) 2023 Gauthier VERDOL * Copyright (C) 2023 Nick Fragoulis - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024-2025 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -174,7 +174,6 @@ class Facture extends CommonInvoice public $resteapayer; /** - * * @var int<0,1> 1 if invoice paid COMPLETELY, 0 otherwise * @deprecated * Use statut and close_code) */ @@ -4002,10 +4001,10 @@ class Facture extends CommonInvoice if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { $product = new Product($this->db); $result = $product->fetch($fk_product); - if ($qty < $product->packaging) { + if ($qty < (float) $product->packaging) { $qty = $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index e374296cf13..143cc1a07d9 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -107,9 +107,9 @@ class Form * @param object $object Object (on the page we show) * @param int<0,1> $perm Permission to allow button to edit parameter. Set it to 0 to have a not edited field. * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datehourpicker' 'checkbox:ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...) - * @param string $moreparam More param to add on a href URL. - * @param int $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS. - * @param int<0,3> $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' + * @param string $moreparam More param to add on a href URL. + * @param int<0,1> $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS. + * @param int<0,3> $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' * @param string $paramid Key of parameter for id ('id', 'socid') * @param string $help Tooltip help * @return string HTML edit field @@ -624,19 +624,19 @@ class Form * Show a text and picto with tooltip on text or picto. * Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip * - * @param string $text Text to show - * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. - * @param int $tooltipon 1=tooltip on text, 2=tooltip on image, 3=tooltip on both - * @param int $direction -1=image is before, 0=no image, 1=image is after - * @param string $img Html code for image (use img_xxx() function to get it) - * @param string $extracss Add a CSS style to td tags - * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span - * @param string $incbefore Include code before the text - * @param int $noencodehtmltext Do not encode into html entity the htmltext - * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) - * @param int $forcenowrap Force no wrap between text and picto (works with notabs=2 only) - * @return string Code html du tooltip (texte+picto) - * @see textwithpicto() Use textwithpicto() instead of textwithtooltip if you can. + * @param string $text Text to show + * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. + * @param int<0,3> $tooltipon 1=tooltip on text, 2=tooltip on image, 3=tooltip on both + * @param int<-1,1> $direction -1=image is before, 0=no image, 1=image is after + * @param string $img Html code for image (use img_xxx() function to get it) + * @param string $extracss Add a CSS style to td tags + * @param int<0,3> $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span + * @param string $incbefore Include code before the text + * @param int<0,1> $noencodehtmltext Do not encode into html entity the htmltext + * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) + * @param int<0,1> $forcenowrap Force no wrap between text and picto (works with notabs=2 only) + * @return string Code html du tooltip (texte+picto) + * @see textwithpicto() Use textwithpicto() instead of textwithtooltip if you can. */ public function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 3, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger = '', $forcenowrap = 0) { @@ -5645,9 +5645,9 @@ class Form * @param string $title Title * @param string $question Question * @param string $action Action - * @param array}>|string|null $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) - * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'datetime', 'select', 'multiselect', 'morecss', - * 'other', 'onecolumn' or 'hidden'... + * @param array}>|string|null $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) + * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'datetime', 'select', 'multiselect', 'morecss', + * 'other', 'onecolumn' or 'hidden'... * @param int<0,1>|''|'no'|'yes'|'1'|'0' $selectedchoice '' or 'no', or 'yes' or '1', 1, '0' or 0 * @param int<0,2>|string $useajax 0=No, 1=Yes use Ajax to show the popup, 2=Yes and also submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx * @param int|string $height Force height of box (0 = auto) diff --git a/htdocs/ecm/dir_card.php b/htdocs/ecm/dir_card.php index fcfff57f74a..cf7d8c159c9 100644 --- a/htdocs/ecm/dir_card.php +++ b/htdocs/ecm/dir_card.php @@ -1,6 +1,7 @@ * Copyright (C) 2024-2025 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -85,7 +86,7 @@ $ecmdir = new EcmDirectory($db); if ($module == 'ecm') { // $section should be an int except if it is dir not yet created into EcmDirectory - $result = $ecmdir->fetch($section); + $result = preg_match('/^\d+$/', $section) ? $ecmdir->fetch((int) $section) : 0; if ($result > 0) { $relativepath = $ecmdir->getRelativePath(); $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; @@ -199,6 +200,7 @@ if ($action == 'confirm_deletedir' && $confirm == 'yes' && $permissiontoupload) // Update dirname or description if ($action == 'update' && !GETPOST('cancel', 'alpha') && $permissiontoadd) { $error = 0; + $oldlabel = ''; if ($module == 'ecm') { $oldlabel = $ecmdir->label; diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php index 0f3e5cd7c24..213d60c4a17 100644 --- a/htdocs/ecm/index.php +++ b/htdocs/ecm/index.php @@ -2,6 +2,7 @@ /* Copyright (C) 2008-2017 Laurent Destailleur * Copyright (C) 2008-2010 Regis Houssin * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -109,10 +110,11 @@ $permissiontodeletedir = $user->hasRight('ecm', 'setup'); //$backtopage = $_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid; // used after a confirm_deletefile into actions_linkedfiles.inc.php //include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; +$relativepath = ''; + // Upload file (code similar but different than actions_linkedfiles.inc.php) if (GETPOST("sendit", 'alphanohtml') && getDolGlobalString('MAIN_UPLOAD_DOC') && $permissiontocreate) { // Define relativepath and upload_dir - $relativepath = ''; if ($ecmdir->id) { $relativepath = $ecmdir->getRelativePath(); } else { @@ -277,11 +279,11 @@ if ($action == 'refreshmanual' && $permissiontoread) { //print $ecmdirtmp->cachenbofdoc."
\n";exit; $id = $ecmdirtmp->create($user); if ($id > 0) { - $newdirsql = array('id'=>$id, - 'id_mere'=>$ecmdirtmp->fk_parent, - 'label'=>$ecmdirtmp->label, - 'description'=>$ecmdirtmp->description, - 'fullrelativename'=>$relativepathmissing); + $newdirsql = array('id' => $id, + 'id_mere' => $ecmdirtmp->fk_parent, + 'label' => $ecmdirtmp->label, + 'description' => $ecmdirtmp->description, + 'fullrelativename' => $relativepathmissing); $sqltree[] = $newdirsql; // We complete fulltree for following loops //var_dump($sqltree); $adirwascreated = 1; diff --git a/htdocs/eventorganization/conferenceorbooth_card.php b/htdocs/eventorganization/conferenceorbooth_card.php index 69162c5fca8..ff6d66b04f3 100644 --- a/htdocs/eventorganization/conferenceorbooth_card.php +++ b/htdocs/eventorganization/conferenceorbooth_card.php @@ -3,7 +3,7 @@ * Copyright (C) 2021 Florian Henry * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -187,7 +187,7 @@ $help_url = 'EN:Module_Event_Organization'; llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-eventorganization page-card'); if ($action == 'create') { - $result = $projectstatic->fetch(GETPOST('fk_project')); + $result = $projectstatic->fetch(GETPOSTINT('fk_project')); } else { $result = $projectstatic->fetch($object->fk_project); } @@ -351,7 +351,7 @@ if (!empty($withproject)) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '', $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print '
'; - print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; @@ -359,7 +359,7 @@ if (!empty($withproject)) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestBoothHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '', $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; @@ -377,7 +377,7 @@ if (!empty($withproject)) { print '
'; print $form->editfieldkey($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', '', $projectstatic, $permissiontoadd, 'integer:3', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', $projectstatic->max_attendees, $projectstatic, $permissiontoadd, 'integer:3', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', $projectstatic->max_attendees, $projectstatic, $permissiontoadd, 'integer:3', '', null, null, '', 0, '', 'projectid'); print "
'.$langs->trans("EventOrganizationICSLink").''; diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index 46bb260a6be..dcaecaf7f4e 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -3,6 +3,7 @@ * Copyright (C) 2021 Florian Henry * Copyright (C) 2023-2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro + * Copyright (C) 2025 MDW * * 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 @@ -880,7 +881,7 @@ foreach ($object->fields as $key => $val) { } elseif ($key == 'lang') { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $formadmin = new FormAdmin($db); - print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth100imp maxwidth125', 2); + print $formadmin->select_language($search[$key], 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2); } else { print ''; } @@ -1032,7 +1033,7 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['t.'.$key]['checked'])) { print '$key)) { - print ' title="'.dol_escape_htmltag($object->$key).'"'; + print ' title="'.dol_escape_htmltag((string) $object->$key).'"'; } print '>'; if ($key == 'status') { @@ -1040,7 +1041,7 @@ while ($i < $imaxinloop) { } elseif ($key == 'ref') { print $object->getNomUrl(1, 0, '', (($projectid > 0) ? 'withproject' : '')); } else { - print $object->showOutputField($val, $key, $object->$key, ''); + print $object->showOutputField($val, $key, (string) $object->$key, ''); } print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; @@ -365,7 +367,7 @@ if (!empty($withproject)) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestBoothHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '', $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', '1', $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; @@ -377,7 +379,7 @@ if (!empty($withproject)) { print '
'; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print "
'.$langs->trans("EventOrganizationICSLink").''; @@ -439,7 +441,7 @@ if (!empty($withproject)) { } // Part to create -if ($action == 'create') { +if ($action == 'create' && $confOrBooth !== null) { print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("ConferenceOrBoothAttendee")), '', 'object_'.$object->picto); @@ -484,7 +486,7 @@ if ($action == 'create') { } // Part to edit record -if (($id || $ref) && $action == 'edit') { +if (($id || $ref) && $action == 'edit' && $confOrBooth !== null) { print load_fiche_titre($langs->trans("ConferenceOrBoothAttendee"), '', 'object_'.$object->picto); print '
'; @@ -527,7 +529,7 @@ if (($id || $ref) && $action == 'edit') { } // Part to show record -if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { +if ($confOrBooth !== null && $object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { $object->fetch_optionals(); $moreparam = ''; diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index c5934e13ecd..3cabcb13528 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -3,6 +3,7 @@ * Copyright (C) 2021 Florian Henry * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -564,7 +565,7 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', $projectstatic->accept_conference_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print '
'; - print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', $projectstatic->accept_conference_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestConf', 'accept_conference_suggestions', $projectstatic->accept_conference_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; @@ -572,39 +573,39 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { $htmltext = $langs->trans("AllowUnknownPeopleSuggestBoothHelp"); print $form->editfieldkey('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', $projectstatic->accept_booth_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', 0, 0, 'projectid', $htmltext); print ''; - print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', $projectstatic->accept_booth_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval('AllowUnknownPeopleSuggestBooth', 'accept_booth_suggestions', $projectstatic->accept_booth_suggestions ? 1 : 0, $projectstatic, 0, $typeofdata, '', null, null, '', 0, '', 'projectid'); print "
'; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', $projectstatic->price_booth, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfBooth'), $langs->trans("PriceOfBoothHelp")), 'price_booth', $projectstatic->price_booth, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print "
'; print $form->editfieldkey($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', '', $projectstatic, 0, 'amount', '', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, 0, '', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('PriceOfRegistration'), $langs->trans("PriceOfRegistrationHelp")), 'price_registration', $projectstatic->price_registration, $projectstatic, 0, 'amount', '', null, null, '', 0, '', 'projectid'); print "
'; print $form->editfieldkey($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', '', $projectstatic, $permissiontoadd, 'integer:3', '&withproject=1', 0, 0, 'projectid'); print ''; - print $form->editfieldval($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', $projectstatic->max_attendees, $projectstatic, $permissiontoadd, 'integer:3', '', null, 0, '&withproject=1', 0, '', 'projectid'); + print $form->editfieldval($form->textwithpicto($langs->trans('MaxNbOfAttendees'), ''), 'max_attendees', $projectstatic->max_attendees, $projectstatic, $permissiontoadd, 'integer:3', '', null, null, '&withproject=1', 0, '', 'projectid'); print "
'.$langs->trans("EventOrganizationICSLinkProject").''; + // Link to ICS for the event + print '
'.$langs->trans("EventOrganizationICSLinkProject").''; // Define $urlwithroot - $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); - $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; - // Show message - $message = ''.$langs->trans('DownloadICSLink').img_picto('', 'download', 'class="paddingleft"').''; - print $message; - print "
'.$langs->trans("EventOrganizationICSLink").''; // Define $urlwithroot @@ -870,7 +871,7 @@ foreach ($object->fields as $key => $val) { } elseif ($key == 'lang') { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $formadmin = new FormAdmin($db); - print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth100imp maxwidth125', 2); + print $formadmin->select_language($search[$key], 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2); } else { print ''; } @@ -1021,7 +1022,7 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['t.'.$key]['checked'])) { print '$key)) { - print ' title="'.dol_escape_htmltag($object->$key).'"'; + print ' title="'.dol_escape_htmltag((string) $object->$key).'"'; } print '>'; if ($key == 'status') { @@ -1033,7 +1034,7 @@ while ($i < $imaxinloop) { } print $object->getNomUrl(1, $optionLink); } else { - print $object->showOutputField($val, $key, $object->$key, ''); + print $object->showOutputField($val, $key, (string) $object->$key, ''); } print '
'.$langs->trans("Project").''; print img_picto('', 'project', 'class="pictofixedwidth"'); - $numprojet = $formproject->select_projects($soc->id, $projectid, 'projectid', 0); + $numprojet = $formproject->select_projects($soc->id, (string) $projectid, 'projectid', 0); print ' id).'">'; print '
'; print img_picto('', 'fa-balance-scale', 'class="pictofixedwidth"'); print ' '; - $text = $formproduct->selectMeasuringUnits("weight_units", "weight", GETPOSTINT('weight_units'), 0, 2); + $text = $formproduct->selectMeasuringUnits("weight_units", "weight", (string) GETPOSTINT('weight_units'), 0, 2); $htmltext = $langs->trans("KeepEmptyForAutoCalculation"); print $form->textwithpicto($text, $htmltext); print '
'; - print $form->selectDate('', '', '', '', '', '', 1, 1); + print $form->selectDate('', '', 0, 0, 0, '', 1, 1); print '
'; if (!empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) { - print $form->selectyesno('validate_invoices', 0, 1, 1); + print $form->selectyesno('validate_invoices', 0, 1, true); $langs->load("errors"); print ' ('.$langs->trans("WarningAutoValNotPossibleWhenStockIsDecreasedOnInvoiceVal").')'; } else { @@ -1152,7 +1149,7 @@ if ($user->hasRight('user', 'user', 'lire')) { $moreforfilter .= '
'; $tmptitle = $langs->trans('LinkedToSpecificUsers'); $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"'); - $moreforfilter .= $form->select_dolusers($search_user, 'search_user', $tmptitle, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200'); + $moreforfilter .= $form->select_dolusers($search_user, 'search_user', $tmptitle, null, 0, '', '', '0', 0, 0, '', 0, '', 'maxwidth200'); $moreforfilter .= '
'; } // If the user can view prospects other than his' @@ -1190,7 +1187,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // @phan-suppress-current-line PhanTypeMismatchArgument if ($massactionbutton) { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); // This also change content of $arrayfields } @@ -1223,7 +1220,7 @@ if (!empty($arrayfields['e.ref_customer']['checked'])) { // Thirdparty if (!empty($arrayfields['s.nom']['checked'])) { print '
'; - print ''; + print ''; print ''; - print $form->selectyesno('search_billed', $search_billed, 1, 0, 1); + print $form->selectyesno('search_billed', $search_billed, 1, false, 1); print ''; if ($object->shipping_method_id > 0) { print $langs->trans("SendingMethod".strtoupper($code)); diff --git a/htdocs/expedition/note.php b/htdocs/expedition/note.php index 862253ba2ce..f2186c1be04 100644 --- a/htdocs/expedition/note.php +++ b/htdocs/expedition/note.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -54,6 +55,7 @@ if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); $object->fetch_thirdparty(); + $typeobject = null; if (!empty($object->origin)) { $typeobject = $object->origin; $origin = $object->origin; @@ -128,7 +130,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index 89930ef944c..e7ecf387ec1 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -5,7 +5,7 @@ * Copyright (C) 2012-2015 Juanjo Menent * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2018-2022 Philippe Grand - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -146,7 +146,7 @@ if (empty($reshook)) { if ($action == 'setavailability' && $permissiontoadd) { $object->fetch($id); - $result = $object->availability(GETPOST('availability_id')); + $result = $object->availability(GETPOSTINT('availability_id')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } @@ -154,7 +154,7 @@ if (empty($reshook)) { if ($action == 'setdemandreason' && $permissiontoadd) { $object->fetch($id); - $result = $object->demand_reason(GETPOST('demand_reason_id')); + $result = $object->demand_reason(GETPOSTINT('demand_reason_id')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } @@ -301,7 +301,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { $proj = new Project($db); @@ -336,8 +336,8 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans('Discounts').''; - $absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount); - $absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote); + $absolute_discount = $soc->getAvailableDiscounts(null, $filterabsolutediscount); + $absolute_creditnote = $soc->getAvailableDiscounts(null, $filtercreditnote); $absolute_discount = price2num($absolute_discount, 'MT'); $absolute_creditnote = price2num($absolute_creditnote, 'MT'); @@ -396,9 +396,9 @@ if ($id > 0 || !empty($ref)) { print '
'; print '
'; if ($action == 'editavailability') { - $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'availability_id', 1); + $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->availability_id, 'availability_id', 1); } else { - $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'none', 1); + $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->availability_id, 'none', 1); } print '
'; print '
'; if ($action == 'editshippingmethod') { - $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1); + $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->shipping_method_id, 'shipping_method_id', 1); } else { - $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none'); + $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->shipping_method_id, 'none'); } print '
'; print '
'; if ($action == 'editdemandreason') { - $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'demand_reason_id', 1); + $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->demand_reason_id, 'demand_reason_id', 1); } else { - $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'none'); + $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->demand_reason_id, 'none'); } // Terms of payment @@ -620,6 +620,9 @@ if ($id > 0 || !empty($ref)) { $sql .= " WHERE cd.fk_commande = ".((int) $object->id); $sql .= " ORDER BY cd.rang, cd.rowid"; + $toBeShipped = array(); + $toBeShippedTotal = 0; + //print $sql; dol_syslog("shipment.php", LOG_DEBUG); $resql = $db->query($sql); @@ -643,8 +646,6 @@ if ($id > 0 || !empty($ref)) { print "
'.$langs->trans("ModePaiement").''; - $form->select_types_paiements($object->fk_c_paiement, 'fk_c_paiement'); + $form->select_types_paiements((string) $object->fk_c_paiement, 'fk_c_paiement'); print '
'.$langs->trans("VALIDATOR").''; $include_users = $object->fetch_users_approver_expensereport(); - $s = $form->select_dolusers($object->fk_user_validator, "fk_user_validator", 1, "", 0, $include_users); + $s = $form->select_dolusers($object->fk_user_validator, "fk_user_validator", 1, null, 0, $include_users); print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate")); print '
'.price($line->value_unit).''.dol_escape_htmltag($line->qty).''.dol_escape_htmltag((string) $line->qty).''.price($line->total_ht).''; - $formproject->select_projects(-1, $line->fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth300'); + $formproject->select_projects(-1, (string) $line->fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth300'); print ''; $params = array('fk_expense' => $object->id, 'fk_expense_det' => $line->id, 'date' => $line->date); - print $form->selectExpenseCategories($line->fk_c_exp_tax_cat, 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params); + print $form->selectExpenseCategories($line->fk_c_exp_tax_cat, 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', (string) $userauthor->default_c_exp_tax_cat, $params); print ''; - print $form->load_tva('vatrate', (GETPOSTISSET("vatrate") ? GETPOST("vatrate") : $selectedvat), $mysoc, '', 0, 0, '', false, 1, 2); + print $form->load_tva('vatrate', (GETPOSTISSET("vatrate") ? GETPOST("vatrate") : $selectedvat), $mysoc, null, 0, 0, '', false, 1, 2); print ''; - print ''; // We must be able to enter decimal qty + print ''; // We must be able to enter decimal qty print ''.$langs->trans('AmountHT').''; print ''; - print $form->buttonsSaveCancel('Save', 'Cancel', array(), 0, 'small'); + print $form->buttonsSaveCancel('Save', 'Cancel', array(), false, 'small'); print '
'; - $formproject->select_projects(-1, !empty($fk_project) ? $fk_project : 0, 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300'); + $formproject->select_projects(-1, !empty($fk_project) ? (string) $fk_project : '0', 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300'); print ''; - print $form->buttonsSaveCancel("Add", '', '', 1, 'reposition'); + print $form->buttonsSaveCancel("Add", '', array(), true, 'reposition'); print '
'.$langs->trans("Visibility").''; - $array = array(); - if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) { - $array[0] = $langs->trans("PrivateProject"); - } - if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) { - $array[1] = $langs->trans("SharedProject"); - } - - if (count($array) > 0) { - print $form->selectarray('public', $array, GETPOSTINT('public') ? 1 : 0, 0, 0, 0, '', 0, 0, 0, '', '', 1); - } else { - print ''; - - if (GETPOSTINT('public') == 0) { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans("PrivateProject"); - } else { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans("SharedProject"); - } - } - print '
'.$langs->trans("OpportunityStatus").'
'.$langs->trans("Visibility").''; + $array = array(); + if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) { + $array[0] = $langs->trans("PrivateProject"); + } + if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) { + $array[1] = $langs->trans("SharedProject"); + } + + if (count($array) > 0) { + print $form->selectarray('public', $array, GETPOSTINT('public') ? 1 : 0, 0, 0, 0, '', 0, 0, 0, '', '', 1); + } else { + print ''; + + if (GETPOSTINT('public') == 0) { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans("PrivateProject"); + } else { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans("SharedProject"); + } + } + print '
'.$langs->trans("ProjectContactTypeManager").''; @@ -1210,31 +1210,6 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print '
'.$langs->trans("Visibility").''; - $array = array(); - if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) { - $array[0] = $langs->trans("PrivateProject"); - } - if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) { - $array[1] = $langs->trans("SharedProject"); - } - - if (count($array) > 0) { - print $form->selectarray('public', $array, $object->public, 0, 0, 0, '', 0, 0, 0, '', '', 1); - } else { - print ''; - - if ($object->public == 0) { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans("PrivateProject"); - } else { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans("SharedProject"); - } - } - print '
'.$langs->trans("Visibility").''; + $array = array(); + if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) { + $array[0] = $langs->trans("PrivateProject"); + } + if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) { + $array[1] = $langs->trans("SharedProject"); + } + + if (count($array) > 0) { + print $form->selectarray('public', $array, $object->public, 0, 0, 0, '', 0, 0, 0, '', '', 1); + } else { + print ''; + + if ($object->public == 0) { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans("PrivateProject"); + } else { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans("SharedProject"); + } + } + print '
'.$langs->trans("Visibility").''; - $array = array(); - if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) { - $array[0] = $langs->trans("PrivateProject"); - } - if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) { - $array[1] = $langs->trans("SharedProject"); - } - - if (count($array) > 0) { - print $form->selectarray('public', $array, GETPOSTINT('public') ? 1 : 0, 0, 0, 0, '', 0, 0, 0, '', '', 1); - } else { - print ''; - - if (GETPOSTINT('public') == 0) { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans("PrivateProject"); - } else { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans("SharedProject"); - } - } - print '
'.$langs->trans("OpportunityStatus").'
'.$langs->trans("Visibility").''; + $array = array(); + if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) { + $array[0] = $langs->trans("PrivateProject"); + } + if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) { + $array[1] = $langs->trans("SharedProject"); + } + + if (count($array) > 0) { + print $form->selectarray('public', $array, GETPOSTINT('public') ? 1 : 0, 0, 0, 0, '', 0, 0, 0, '', '', 1); + } else { + print ''; + + if (GETPOSTINT('public') == 0) { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans("PrivateProject"); + } else { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans("SharedProject"); + } + } + print '
'.$langs->trans("ProjectContactTypeManager").''; @@ -1210,31 +1210,6 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print '
'.$langs->trans("Visibility").''; - $array = array(); - if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) { - $array[0] = $langs->trans("PrivateProject"); - } - if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) { - $array[1] = $langs->trans("SharedProject"); - } - - if (count($array) > 0) { - print $form->selectarray('public', $array, $object->public, 0, 0, 0, '', 0, 0, 0, '', '', 1); - } else { - print ''; - - if ($object->public == 0) { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans("PrivateProject"); - } else { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans("SharedProject"); - } - } - print '
'.$langs->trans("Visibility").''; + $array = array(); + if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) { + $array[0] = $langs->trans("PrivateProject"); + } + if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) { + $array[1] = $langs->trans("SharedProject"); + } + + if (count($array) > 0) { + print $form->selectarray('public', $array, $object->public, 0, 0, 0, '', 0, 0, 0, '', '', 1); + } else { + print ''; + + if ($object->public == 0) { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans("PrivateProject"); + } else { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans("SharedProject"); + } + } + print '
'.$langs->trans("Visibility").''; - if ($object->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); - } else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); - } - print '
'.$langs->trans("OpportunityStatus"); @@ -1463,6 +1452,17 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { } print '
'.$langs->trans("Visibility").''; + if ($object->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); + } else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); + } + print '
'; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($object->description) { + print ''; + } + print '
'.$langs->trans("Description").''; - print '
'; - print dolPrintHTML($object->description); - print '
'; - print '
'.$langs->trans("Categories").''; @@ -1489,6 +1482,16 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($object->description); + print '
'; + print '
'; print '
'; diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php index 4f2dde28a50..f04c1df9ae6 100644 --- a/htdocs/projet/contact.php +++ b/htdocs/projet/contact.php @@ -424,17 +424,6 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Visibility").''; - if ($object->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); - } else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); - } - print '
'.$langs->trans("OpportunityStatus").''; @@ -480,6 +469,17 @@ if ($id > 0 || !empty($ref)) { } print '
'.$langs->trans("Visibility").''; + if ($object->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); + } else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); + } + print '
'; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($object->description) { + print ''; + } + print '
'.$langs->trans("Description").''; - print dol_htmlentitiesbr($object->description); - print '
'.$langs->trans("Categories").''; @@ -504,6 +499,16 @@ if ($id > 0 || !empty($ref)) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($object->description); + print '
'; + print '
'; print '
'; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index f4ffea34d18..80af93b7cd0 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -311,17 +311,6 @@ if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJ print '
'.$langs->trans("Visibility").''; -if ($object->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); -} else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); -} -print '
'.$langs->trans("OpportunityStatus").''; @@ -368,6 +357,17 @@ if ($object->hasDelay()) { } print '
'.$langs->trans("Visibility").''; +if ($object->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); +} else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); +} +print '
'; -// Description -print ''; - // Categories if (isModEnabled('category')) { print '"; } +// Description +print ''; +if ($object->description) { + print ''; +} + print '
'.$langs->trans("Description").''; -print dol_htmlentitiesbr($object->description); -print '
'.$langs->trans("Categories").''; @@ -392,6 +387,16 @@ if (isModEnabled('category')) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($object->description); + print '
'; + print '
'; print '
'; diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 2dde9cf51ed..4cd188910ec 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -660,17 +660,6 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Visibility").''; - if ($object->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); - } else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); - } - print '
'.$langs->trans("Budget").''; if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) { @@ -690,6 +679,17 @@ if ($id > 0 || !empty($ref)) { } print '
'.$langs->trans("Visibility").''; + if ($object->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); + } else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); + } + print '
'; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($object->description) { + print ''; + } + print '
'.$langs->trans("Description").''; - print dol_htmlentitiesbr($object->description); - print '
'.$langs->trans("Categories").''; @@ -714,6 +709,16 @@ if ($id > 0 || !empty($ref)) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($object->description); + print '
'; + print '
'; print '
'; diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php index f829533062a..ef379748e77 100644 --- a/htdocs/projet/tasks/contact.php +++ b/htdocs/projet/tasks/contact.php @@ -255,17 +255,6 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Visibility").''; - if ($projectstatic->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); - } else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); - } - print '
'.$langs->trans("Budget").''; if (isset($projectstatic->budget_amount) && strcmp($projectstatic->budget_amount, '')) { @@ -285,9 +274,23 @@ if ($id > 0 || !empty($ref)) { } print '
'.$langs->trans("Visibility").''; + if ($projectstatic->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); + } else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); + } + print '
'; @@ -297,11 +300,6 @@ if ($id > 0 || !empty($ref)) { print ''; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($projectstatic->description) { + print ''; + } + print '
'.$langs->trans("Description").''; - print nl2br($projectstatic->description); - print '
'.$langs->trans("Categories").''; @@ -309,6 +307,16 @@ if ($id > 0 || !empty($ref)) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($projectstatic->description); + print '
'; + print '
'; print '
'; diff --git a/htdocs/projet/tasks/document.php b/htdocs/projet/tasks/document.php index 8f091a04a5e..a85d451efa8 100644 --- a/htdocs/projet/tasks/document.php +++ b/htdocs/projet/tasks/document.php @@ -212,17 +212,6 @@ if ($object->id > 0) { print '
'.$langs->trans("Visibility").''; - if ($projectstatic->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); - } else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); - } - print '
'.$langs->trans("Budget").''; if (isset($projectstatic->budget_amount) && strcmp($projectstatic->budget_amount, '')) { @@ -242,9 +231,23 @@ if ($object->id > 0) { } print '
'.$langs->trans("Visibility").''; + if ($projectstatic->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); + } else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); + } + print '
'; @@ -254,11 +257,6 @@ if ($object->id > 0) { print ''; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($projectstatic->description) { + print ''; + } + print '
'.$langs->trans("Description").''; - print nl2br($projectstatic->description); - print '
'.$langs->trans("Categories").''; @@ -266,6 +264,16 @@ if ($object->id > 0) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($projectstatic->description); + print '
'; + print '
'; print '
'; diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php index 673c820368b..c938650cef5 100644 --- a/htdocs/projet/tasks/note.php +++ b/htdocs/projet/tasks/note.php @@ -202,17 +202,6 @@ if ($object->id > 0) { print '
'.$langs->trans("Visibility").''; - if ($projectstatic->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); - } else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); - } - print '
'.$langs->trans("Budget").''; if (isset($projectstatic->budget_amount) && strcmp($projectstatic->budget_amount, '')) { @@ -232,9 +221,23 @@ if ($object->id > 0) { } print '
'.$langs->trans("Visibility").''; + if ($projectstatic->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); + } else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); + } + print '
'; @@ -244,11 +247,6 @@ if ($object->id > 0) { print ''; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($projectstatic->description) { + print ''; + } + print '
'.$langs->trans("Description").''; - print nl2br($projectstatic->description); - print '
'.$langs->trans("Categories").''; @@ -256,6 +254,16 @@ if ($object->id > 0) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($projectstatic->description); + print '
'; + print '
'; print '
'; diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 494e3f20774..8eaa2bb9062 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -361,17 +361,6 @@ if ($id > 0 || !empty($ref)) { print '
'.$langs->trans("Visibility").''; - if ($projectstatic->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); - } else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); - } - print '
'.$langs->trans("Budget").''; if (isset($projectstatic->budget_amount) && strcmp($projectstatic->budget_amount, '')) { @@ -391,9 +380,23 @@ if ($id > 0 || !empty($ref)) { } print '
'.$langs->trans("Visibility").''; + if ($projectstatic->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); + } else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); + } + print '
'; @@ -404,11 +407,6 @@ if ($id > 0 || !empty($ref)) { print ''; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($projectstatic->description) { + print ''; + } + print '
'.$langs->trans("Description").''; - print nl2br($projectstatic->description); - print '
'.$langs->trans("Categories").''; @@ -416,6 +414,16 @@ if ($id > 0 || !empty($ref)) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($projectstatic->description); + print '
'; + print '
'; print ''; diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index e72ccc48706..568cf922cd5 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1002,17 +1002,6 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print '
' . $langs->trans("Visibility") . ''; - if ($projectstatic->public) { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans('SharedProject'); - } else { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans('PrivateProject'); - } - print '
' . $langs->trans("Budget") . ''; if (!is_null($projectstatic->budget_amount) && strcmp($projectstatic->budget_amount, '')) { @@ -1032,6 +1021,17 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } print '
' . $langs->trans("Visibility") . ''; + if ($projectstatic->public) { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans('SharedProject'); + } else { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans('PrivateProject'); + } + print '
'; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($projectstatic->description) { + print ''; + } + print '
'.$langs->trans("Description").''; - print dol_htmlentitiesbr($projectstatic->description); - print '
' . $langs->trans("Categories") . ''; @@ -1059,6 +1054,16 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($projectstatic->description); + print '
'; + print '
'; print '
'; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index d94ade62111..46f5c1ddf45 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -2313,7 +2313,7 @@ datalist { .linkobject { cursor: pointer; } -table.tableforfield tr:not(.liste_titre)>td:first-of-type, tr.trforfield:not(.liste_titre)>td:first-of-type, div.tableforfield div.tagtr:not(.liste_titre)>div.tagtd:first-of-type { +table.tableforfield tr:not(.liste_titre)>td:first-of-type:not(.nottitleforfield), tr.trforfield:not(.liste_titre)>td:first-of-type, div.tableforfield div.tagtr:not(.liste_titre)>div.tagtd:first-of-type { color: var(--tableforfieldcolor); } From 710b5d3405c75ac6922821efc34d49380d7d2fa8 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 29 Jan 2025 14:15:08 +0100 Subject: [PATCH 335/602] Debug v21 --- .../conferenceorbooth_list.php | 37 +++++++++++-------- .../conferenceorboothattendee_list.php | 37 +++++++++++-------- htdocs/projet/element.php | 2 +- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index 46bb260a6be..020aecc753f 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -385,17 +385,6 @@ if ($projectid > 0) { print '
'.$langs->trans("Visibility").''; - if ($project->public == 0) { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans("PrivateProject"); - } else { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans("SharedProject"); - } - print '
'.$langs->trans("Budget").''; if (strcmp($project->budget_amount, '')) { @@ -432,6 +421,17 @@ if ($projectid > 0) { print $project->location; print '
'.$langs->trans("Visibility").''; + if ($project->public == 0) { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans("PrivateProject"); + } else { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans("SharedProject"); + } + print '
'; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($project->description) { + print ''; + } + print ''; } - // Visibility - print ''; - // Budget print ''; + // Visibility + print ''; + // Location event print ' diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 78e0e8a2da0..5ae58298924 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -2,6 +2,7 @@ /* Copyright (C) 2010-2012 Laurent Destailleur * Copyright (C) 2012 Regis Houssin * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -210,18 +211,18 @@ if (is_array($param)) { array('varchar', 'phone', 'mail', 'url', 'ip', 'select', 'password', 'text', 'html'), - 'double'=>array('double', 'price'), - 'price'=>array('double', 'price'), - 'text'=>array('text', 'html'), - 'html'=>array('text', 'html'), - 'password'=>array('password', 'varchar'), - 'mail'=>array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), - 'url'=>array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), - 'phone'=>array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), - 'ip'=>array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), - 'select'=>array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), - 'date'=>array('date', 'datetime') + 'varchar' => array('varchar', 'phone', 'mail', 'url', 'ip', 'select', 'password', 'text', 'html'), + 'double' => array('double', 'price'), + 'price' => array('double', 'price'), + 'text' => array('text', 'html'), + 'html' => array('text', 'html'), + 'password' => array('password', 'varchar'), + 'mail' => array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), + 'url' => array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), + 'phone' => array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), + 'ip' => array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), + 'select' => array('varchar', 'phone', 'mail', 'url', 'ip', 'select'), + 'date' => array('date', 'datetime') ); /* Disabled because text is text on several lines, when varchar is text on 1 line, we should not be able to convert if ($size <= 255 && in_array($type, array('text', 'html'))) { @@ -256,12 +257,12 @@ if (in_array($type, array_keys($typewecanchangeinto))) {
'.$langs->trans("Description").''; - print dol_htmlentitiesbr($project->description); - print '
'.$langs->trans("Categories").''; @@ -459,6 +454,16 @@ if ($projectid > 0) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($project->description); + print '
'; + print '
'; $typeofdata = 'checkbox:'.($project->accept_conference_suggestions ? ' checked="checked"' : ''); $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index c5934e13ecd..98ea7f6adf9 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -484,17 +484,6 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { print '
'.$langs->trans("Visibility").''; - if ($projectstatic->public == 0) { - print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); - print $langs->trans("PrivateProject"); - } else { - print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); - print $langs->trans("SharedProject"); - } - print '
'.$langs->trans("Budget").''; if (strcmp($projectstatic->budget_amount, '')) { @@ -526,6 +515,17 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { } print '
'.$langs->trans("Visibility").''; + if ($projectstatic->public == 0) { + print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"'); + print $langs->trans("PrivateProject"); + } else { + print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"'); + print $langs->trans("SharedProject"); + } + print '
'.$langs->trans("Location").''; print $projectstatic->location; @@ -547,11 +547,6 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { print ''; - // Description - print ''; - // Categories if (isModEnabled('category')) { print '"; } + // Description + print ''; + if ($projectstatic->description) { + print ''; + } + print ''; } -if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) { +if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && !empty($object->usage_opportunity)) { // Opportunity status print ''; if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch actioncolumn '); + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.rowid']['checked'])) { + print ''; + } + if (!empty($arrayfields['t.libelle']['checked'])) { + print ''; + } + if (!empty($arrayfields['t.morphy']['checked'])) { + print ''; } - print ''; - print ''; - print ''; print ''; print ''; print ''; @@ -353,7 +369,8 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print ''; print ''; if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch center '); + $totalarray['nbfield']++; } print "\n"; @@ -397,13 +414,15 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print ''; } } - - print ''; - - print ''; + if (!empty($arrayfields['t.rowid']['checked'])) { + print ''; + } + if (!empty($arrayfields['t.libelle']['checked'])) { + print ''; + } print ''; + $totalarray['nbfield']++; } if (!empty($arrayfields['t.libelle']['checked'])) { print ''; + $totalarray['nbfield']++; } if (!empty($arrayfields['t.morphy']['checked'])) { print ''; + $totalarray['nbfield']++; } print ''; print ''; @@ -423,16 +426,17 @@ if (!$rowid && $action != 'create' && $action != 'edit') { if (!empty($arrayfields['t.libelle']['checked'])) { print ''; } - - print ''; } - print ''; print ''; $totalarray['nbfield']++; } - print ''; + if (!empty($arrayfields['t.duration']['checked'])) { + print ''; + $totalarray['nbfield']++; + } print ''; print ''; print ''; @@ -437,19 +440,20 @@ if (!$rowid && $action != 'create' && $action != 'edit') { } print ''; } - - print ''; } - print ''; print ''; From 0cbedd4ff0a4e8c24b85c7a43eae70ebb37de050 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 29 Jan 2025 19:15:57 +0100 Subject: [PATCH 349/602] Fix warnings --- htdocs/comm/propal/class/propal.class.php | 18 ++++++++-------- .../comm/propal/class/propaleligne.class.php | 8 ++----- htdocs/commande/class/commande.class.php | 21 ++++++++----------- htdocs/commande/class/orderline.class.php | 9 ++------ htdocs/compta/facture/class/facture.class.php | 14 ++++++------- .../facture/class/factureligne.class.php | 10 +++------ htdocs/product/class/product.class.php | 15 ++++++------- htdocs/product/price.php | 6 +++--- 8 files changed, 41 insertions(+), 60 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index eb81c4c084e..2fb35bdcf2f 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -634,7 +634,7 @@ class Propal extends CommonObject */ public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $info_bits = 0, $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $date_start = '', $date_end = '', $array_options = array(), $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $fk_remise_except = 0, $noupdateafterinsertline = 0) { - global $mysoc, $conf, $langs; + global $mysoc, $langs; dol_syslog(get_class($this)."::addline propalid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_except=$remise_percent, price_base_type=$price_base_type, pu_ttc=$pu_ttc, info_bits=$info_bits, type=$type, fk_remise_except=".$fk_remise_except); @@ -659,7 +659,7 @@ class Propal extends CommonObject } $remise_percent = price2num($remise_percent); - $qty = (float) price2num($qty); + $qty = (float) price2num($qty, 'MS'); $pu_ht = price2num($pu_ht); $pu_ht_devise = price2num($pu_ht_devise); $pu_ttc = price2num($pu_ttc); @@ -710,14 +710,14 @@ class Propal extends CommonObject $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $product = new Product($this->db); - $result = $product->fetch($fk_product); - if ($qty < $product->packaging) { - $qty = $product->packaging; + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($fk_product); + if (abs($qty) < $tmpproduct->packaging) { + $qty = (float) $tmpproduct->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { - $coeff = intval((float) $qty / $product->packaging) + 1; - $qty = (float) $product->packaging * $coeff; + if (!empty($tmpproduct->packaging) && $qty > $tmpproduct->packaging) { + $coeff = intval(abs($qty) / $tmpproduct->packaging) + 1; + $qty = price2num((float) $tmpproduct->packaging * $coeff, 'MS'); setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); } } diff --git a/htdocs/comm/propal/class/propaleligne.class.php b/htdocs/comm/propal/class/propaleligne.class.php index 67c941e9851..b976193a0e1 100644 --- a/htdocs/comm/propal/class/propaleligne.class.php +++ b/htdocs/comm/propal/class/propaleligne.class.php @@ -373,10 +373,8 @@ class PropaleLigne extends CommonObjectLine $sql .= ' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,'; $sql .= ' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; + $sql .= ' p.packaging,'; $sql .= ' pd.date_start, pd.date_end, pd.product_type'; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $sql .= ', p.packaging'; - } $sql .= ' FROM '.MAIN_DB_PREFIX.'propaldet as pd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pd.fk_product = p.rowid'; $sql .= ' WHERE pd.rowid = '.((int) $rowid); @@ -425,9 +423,7 @@ class PropaleLigne extends CommonObjectLine $this->product_desc = $objp->product_desc; $this->fk_unit = $objp->fk_unit; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $this->packaging = $objp->packaging; - } + $this->packaging = $objp->packaging; $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 71e03085f69..b052263ee7e 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1635,14 +1635,14 @@ class Commande extends CommonOrder $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $product = new Product($this->db); - $result = $product->fetch($fk_product); - if ($qty < $product->packaging) { - $qty = $product->packaging; + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($fk_product); + if (abs($qty) < $tmpproduct->packaging) { + $qty = (float) $tmpproduct->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { - $coeff = intval((float) $qty / $product->packaging) + 1; - $qty = (float) $product->packaging * $coeff; + if (!empty($tmpproduct->packaging) && $qty > $tmpproduct->packaging) { + $coeff = intval(abs($qty) / $tmpproduct->packaging) + 1; + $qty = price2num((float) $tmpproduct->packaging * $coeff, 'MS'); setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); } } @@ -2130,7 +2130,7 @@ class Commande extends CommonOrder $sql .= ' l.fk_unit,'; $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tosell as product_tosell, p.tobuy as product_tobuy, p.tobatch as product_tobatch, p.barcode as product_barcode,'; - $sql .= ' p.weight, p.weight_units, p.volume, p.volume_units'; + $sql .= ' p.weight, p.weight_units, p.volume, p.volume_units, p.packaging'; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as l'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (p.rowid = l.fk_product)'; $sql .= ' WHERE l.fk_commande = '.((int) $this->id); @@ -2205,10 +2205,7 @@ class Commande extends CommonOrder $line->weight_units = $objp->weight_units; $line->volume = $objp->volume; $line->volume_units = $objp->volume_units; - - if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $line->packaging = $objp->packaging; - } + $line->packaging = $objp->packaging; $line->date_start = $this->db->jdate($objp->date_start); $line->date_end = $this->db->jdate($objp->date_end); diff --git a/htdocs/commande/class/orderline.class.php b/htdocs/commande/class/orderline.class.php index 10519dd0cf2..ec78db8e44d 100644 --- a/htdocs/commande/class/orderline.class.php +++ b/htdocs/commande/class/orderline.class.php @@ -174,10 +174,8 @@ class OrderLine extends CommonOrderLine $sql .= ' cd.fk_unit,'; $sql .= ' cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc,'; $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc, p.tobatch as product_tobatch,'; + $sql .= ' p.packaging,'; $sql .= ' cd.date_start, cd.date_end, cd.vat_src_code'; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $sql .= ', p.packaging'; - } $sql .= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; $sql .= ' WHERE cd.rowid = '.((int) $rowid); @@ -231,10 +229,7 @@ class OrderLine extends CommonOrderLine $this->product_desc = $objp->product_desc; $this->product_tobatch = $objp->product_tobatch; $this->fk_unit = $objp->fk_unit; - - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $this->packaging = $objp->packaging; - } + $this->packaging = $objp->packaging; $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 09dddafbbd5..8307f205204 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4000,14 +4000,14 @@ class Facture extends CommonInvoice $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $product = new Product($this->db); - $result = $product->fetch($fk_product); - if ($qty < $product->packaging) { - $qty = $product->packaging; + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($fk_product); + if (abs($qty) < $tmpproduct->packaging) { + $qty = (float) $tmpproduct->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { - $coeff = intval((float) $qty / $product->packaging) + 1; - $qty = (float) $product->packaging * $coeff; + if (!empty($tmpproduct->packaging) && $qty > $tmpproduct->packaging) { + $coeff = intval(abs($qty) / $tmpproduct->packaging) + 1; + $qty = price2num((float) $tmpproduct->packaging * $coeff, 'MS'); setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); } } diff --git a/htdocs/compta/facture/class/factureligne.class.php b/htdocs/compta/facture/class/factureligne.class.php index c397b5ddf00..c0b69cb14d3 100644 --- a/htdocs/compta/facture/class/factureligne.class.php +++ b/htdocs/compta/facture/class/factureligne.class.php @@ -215,10 +215,8 @@ class FactureLigne extends CommonInvoiceLine $sql .= ' fd.multicurrency_total_ht,'; $sql .= ' fd.multicurrency_total_tva,'; $sql .= ' fd.multicurrency_total_ttc,'; - $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc'; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $sql .= ', p.packaging'; - } + $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; + $sql .= ' p.packaging'; $sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid'; $sql .= ' WHERE fd.rowid = '.((int) $rowid); @@ -285,9 +283,7 @@ class FactureLigne extends CommonInvoiceLine $this->multicurrency_total_tva = $objp->multicurrency_total_tva; $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; - if (getDolGlobalInt('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $this->packaging = $objp->packaging; - } + $this->packaging = $objp->packaging; $this->fetch_optionals(); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 05d88261d19..46121f12a94 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1596,8 +1596,8 @@ class Product extends CommonObject $sql .= ", fk_price_expression = ".($this->fk_price_expression != 0 ? (int) $this->fk_price_expression : 'NULL'); $sql .= ", fk_user_modif = ".($user->id > 0 ? $user->id : 'NULL'); $sql .= ", mandatory_period = ".($this->mandatory_period); - if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING') && !empty($this->packaging)) { - $sql .= ", packaging = " . (float) $this->packaging; + if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { + $sql .= ", packaging = ".(float) $this->packaging; } // stock field is not here because it is a denormalized value from product_stock. $sql .= " WHERE rowid = ".((int) $id); @@ -2893,15 +2893,12 @@ class Product extends CommonObject $sql .= " p.price_min, p.price_min_ttc, p.price_base_type, p.cost_price, p.default_vat_code, p.tva_tx, p.recuperableonly as tva_npr, p.localtax1_tx, p.localtax2_tx, p.localtax1_type, p.localtax2_type, p.tosell,"; $sql .= " p.tobuy, p.fk_product_type, p.duration, p.fk_default_warehouse, p.fk_default_workstation, p.seuil_stock_alerte, p.canvas, p.net_measure, p.net_measure_units, p.weight, p.weight_units,"; $sql .= " p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.last_main_doc,"; - $sql .= " p.surface, p.surface_units, p.volume, p.volume_units, p.barcode, p.fk_barcode_type, p.finished, p.fk_default_bom, p.mandatory_period,"; + $sql .= " p.surface, p.surface_units, p.volume, p.volume_units, p.barcode, p.fk_barcode_type, p.finished, p.fk_default_bom, p.mandatory_period, p.packaging,"; if (!getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) { $sql .= " p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export,"; } else { $sql .= " ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export, ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export,"; } - if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - $sql .= " p.packaging,"; - } // For MultiCompany // PMP per entity & Stocks Sharings stock_reel includes only stocks shared with this entity @@ -2959,7 +2956,7 @@ class Product extends CommonObject $sql .= " p.price_min, p.price_min_ttc, p.price_base_type, p.cost_price, p.default_vat_code, p.tva_tx, p.recuperableonly, p.localtax1_tx, p.localtax2_tx, p.localtax1_type, p.localtax2_type, p.tosell,"; $sql .= " p.tobuy, p.fk_product_type, p.duration, p.fk_default_warehouse, p.fk_default_workstation, p.seuil_stock_alerte, p.canvas, p.net_measure, p.net_measure_units, p.weight, p.weight_units,"; $sql .= " p.length, p.length_units, p.width, p.width_units, p.height, p.height_units,"; - $sql .= " p.surface, p.surface_units, p.volume, p.volume_units, p.barcode, p.fk_barcode_type, p.finished, p.fk_default_bom, p.mandatory_period,"; + $sql .= " p.surface, p.surface_units, p.volume, p.volume_units, p.barcode, p.fk_barcode_type, p.finished, p.fk_default_bom, p.mandatory_period, p.packaging,"; if (!getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) { $sql .= " p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export,"; } else { @@ -2971,8 +2968,8 @@ class Product extends CommonObject $sql .= " p.pmp,"; } $sql .= " p.datec, p.tms, p.import_key, p.entity, p.desiredstock, p.tobatch, p.sell_or_eat_by_mandatory, p.batch_mask, p.fk_unit,"; - $sql .= " p.fk_price_expression, p.price_autogen, p.model_pdf"; - $sql .= " ,p.price_label"; + $sql .= " p.fk_price_expression, p.price_autogen, p.model_pdf,"; + $sql .= " p.price_label"; if (!$separatedStock) { $sql .= ", p.stock"; } diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 2a3dc750d9b..7e455771536 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -279,12 +279,12 @@ if (empty($reshook)) { $error = 0; $pricestoupdate = array(); - $psq = GETPOST('psqflag'); - $psq = empty($newpsq) ? 0 : $newpsq; + $psq = GETPOSTINT('psqflag'); + $maxpricesupplier = $object->min_recommended_price(); // Packaging - $packaging = getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING') ? GETPOST('packaging') : null; + $packaging = getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING') ? price2num(GETPOST('packaging', 'alpha'), 'MS') : null; if (isModEnabled('dynamicprices')) { $object->fk_price_expression = empty($eid) ? 0 : $eid; //0 discards expression From d1adfb32a453e3f0b8d272d5657820a1812993db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 19:21:44 +0100 Subject: [PATCH 350/602] enhance member types list --- htdocs/adherents/type.php | 51 +++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 5e0a853eaa8..221c76c7bfa 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -369,11 +369,26 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print ''; $totalarray['nbfield']++; } - print ''; - print ''; - print ''; - print ''; - print ''; + if (!empty($arrayfields['t.subscription']['checked'])) { + print ''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.amount']['checked'])) { + print ''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.caneditamount']['checked'])) { + print ''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.vote']['checked'])) { + print ''; + $totalarray['nbfield']++; + } + if (!empty($arrayfields['t.statut']['checked'])) { + print ''; + $totalarray['nbfield']++; + } if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch center '); $totalarray['nbfield']++; @@ -454,17 +469,21 @@ if (!$rowid && $action != 'create' && $action != 'edit') { } print ''; } - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - + if (!empty($arrayfields['t.subscription']['checked'])) { + print ''; + } + if (!empty($arrayfields['t.amount']['checked'])) { + print ''; + } + if (!empty($arrayfields['t.caneditamount']['checked'])) { + print ''; + } + if (!empty($arrayfields['t.vote']['checked'])) { + print ''; + } + if (!empty($arrayfields['t.statut']['checked'])) { + print ''; + } if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { if ($user->hasRight('adherent', 'configurer')) { print ''; From 1c94227320c639e1a6318b2ec89a2ff3636a0e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 19:24:40 +0100 Subject: [PATCH 351/602] fix phan --- htdocs/comm/propal/class/propal.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 070f9914417..eb81c4c084e 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -713,9 +713,9 @@ class Propal extends CommonObject $product = new Product($this->db); $result = $product->fetch($fk_product); if ($qty < $product->packaging) { - $qty = (float) $product->packaging; + $qty = $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); From 7a6b650e828c39b0fae8200d87983548c562c757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 19:25:32 +0100 Subject: [PATCH 352/602] fix phan --- htdocs/commande/class/commande.class.php | 4 ++-- htdocs/compta/facture/class/facture.class.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index ccce40846ce..71e03085f69 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1638,9 +1638,9 @@ class Commande extends CommonOrder $product = new Product($this->db); $result = $product->fetch($fk_product); if ($qty < $product->packaging) { - $qty = (float) $product->packaging; + $qty = $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 68a019043d5..09dddafbbd5 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4003,9 +4003,9 @@ class Facture extends CommonInvoice $product = new Product($this->db); $result = $product->fetch($fk_product); if ($qty < $product->packaging) { - $qty = (float) $product->packaging; + $qty = $product->packaging; } else { - if (!empty($product->packaging) && (fmod((float) $qty, (float) $product->packaging) > 0.000001)) { + if (!empty($product->packaging) && (fmod((float) $qty, $product->packaging) > 0.000001)) { $coeff = intval((float) $qty / $product->packaging) + 1; $qty = (float) $product->packaging * $coeff; setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); From 82eb875fabed66fe5554ac528f9e360a196abbbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 19:34:35 +0100 Subject: [PATCH 353/602] enhance member types list --- htdocs/adherents/type.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 221c76c7bfa..7db9917b1d2 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -286,6 +286,9 @@ $help_url = 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_M llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-member page-type'); $arrayofselected = is_array($toselect) ? $toselect : array(); +$totalarray = [ + 'nbfield' => 0, +]; // List of members type if (!$rowid && $action != 'create' && $action != 'edit') { From 4fc66c6ee16062b44747ce3442e8be307af53570 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 29 Jan 2025 19:44:50 +0100 Subject: [PATCH 354/602] FIX missing quick edit for extrafields --- htdocs/core/tpl/extrafields_view.tpl.php | 3 +++ htdocs/projet/card.php | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 10481b4ad10..26c11f099a6 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -159,6 +159,9 @@ if (empty($reshook) && !empty($object->table_element) && isset($extrafields->att if ($object->element == 'product') { $keyforperm = 'produit'; } + if ($object->element == 'project') { + $keyforperm = 'projet'; + } if (isset($user->rights->$keyforperm)) { $permok = $user->hasRight($keyforperm, 'creer') || $user->hasRight($keyforperm, 'create') || $user->hasRight($keyforperm, 'write'); } diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 1b17aff16af..fd6fa35d136 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -553,6 +553,30 @@ if (empty($reshook)) { } } + // Quick edit for extrafields + if ($action == 'update_extras' && $permissiontoadd) { + $object->oldcopy = dol_clone($object, 2); + + // Fill array 'array_options' with data from update form + $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml')); + if ($ret < 0) { + $error++; + } + + if (!$error) { + // Actions on extra fields + $result = $object->insertExtraFields('PROJECT_MODIFY'); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } + + if ($error) { + $action = 'edit_extras'; + } + } + // Actions to send emails $triggersendname = 'PROJECT_SENTBYMAIL'; $paramname = 'id'; From 65ebb94181d55c268040d50a0292617ee783e21d Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 30 Jan 2025 01:12:50 +0100 Subject: [PATCH 355/602] FIX wrong var name --- htdocs/societe/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index b00bb69b3fb..bc59136f69e 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1578,7 +1578,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio // Vat is used print ''; print ''; if ($conf->browser->layout == 'phone') { print ''; From d831e30869e1e17edc881458d6b8851376a5c377 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 30 Jan 2025 08:29:46 +0100 Subject: [PATCH 356/602] FIX multicompany compatibility --- htdocs/admin/multicurrency.php | 6 +++--- htdocs/multicurrency/multicurrency_rate.php | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index 2a6713ef599..a4b503b3f24 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -130,9 +130,9 @@ if ($action == 'add_currency') { } } elseif ($action == 'setapilayer') { if (GETPOSTISSET('modify_apilayer')) { - dolibarr_set_const($db, 'MULTICURRENCY_APP_ID', GETPOST('MULTICURRENCY_APP_ID', 'alpha')); - dolibarr_set_const($db, 'MULTICURRENCY_APP_SOURCE', GETPOST('MULTICURRENCY_APP_SOURCE', 'alpha')); - //dolibarr_set_const($db, 'MULTICURRENCY_ALTERNATE_SOURCE', GETPOST('MULTICURRENCY_ALTERNATE_SOURCE', 'alpha')); + dolibarr_set_const($db, 'MULTICURRENCY_APP_ID', GETPOST('MULTICURRENCY_APP_ID', 'alpha'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, 'MULTICURRENCY_APP_SOURCE', GETPOST('MULTICURRENCY_APP_SOURCE', 'alpha'), 'chaine', 0, '', $conf->entity); + //dolibarr_set_const($db, 'MULTICURRENCY_ALTERNATE_SOURCE', GETPOST('MULTICURRENCY_ALTERNATE_SOURCE', 'alpha'), 'chaine', 0, '', $conf->entity); } else { $multiurrency = new MultiCurrency($db); $result = $multiurrency->syncRates(getDolGlobalString('MULTICURRENCY_APP_ID')); diff --git a/htdocs/multicurrency/multicurrency_rate.php b/htdocs/multicurrency/multicurrency_rate.php index ef05976018e..7cfe91e5e14 100644 --- a/htdocs/multicurrency/multicurrency_rate.php +++ b/htdocs/multicurrency/multicurrency_rate.php @@ -354,7 +354,8 @@ if ($search_rate) { if ($search_code) { $sql .= natural_search('m.code', $search_code); } -$sql .= " WHERE m.code <> '".$db->escape($conf->currency)."'"; +$sql .= " WHERE cr.entity IN (".getEntity('multicurrency').")"; +$sql .= " AND m.code <> '".$db->escape($conf->currency)."'"; // Add where from hooks $parameters = array(); From c07be3dfc39d892e094e07c7967a0212a8b25a9e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jan 2025 09:30:10 +0100 Subject: [PATCH 357/602] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 136f946a257..607ab21f166 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,12 @@ There is a lot of different solutions to install Dolibarr. ### Using packages -If you have low technical skills and you're looking to install Dolibarr ERP/CRM with just a few clicks, you can use one of the packaged versions: +If you have low technical skills and you're looking to install Dolibarr ERP/CRM with just few clicks, you can use one of the packaged versions (see next chapter if you have IT knowledge) : - [DoliWamp for Windows](https://wiki.dolibarr.org/index.php/Dolibarr_for_Windows_(DoliWamp)) -- [DoliDeb for Debian](https://wiki.dolibarr.org/index.php/Dolibarr_for_Ubuntu_or_Debian) +- [DoliDeb for Debian, Ubuntu](https://wiki.dolibarr.org/index.php/Dolibarr_for_Ubuntu_or_Debian) - DoliRpm for Red Hat, Fedora, OpenSuse, Mandriva or Mageia -- The Docker image (see next chapter) +- The Docker image (see chapter "Using Docker") Releases can be downloaded from [official website](https://www.dolibarr.org/). From 7848d77830373d1881d5f5851f375eb0e6910c49 Mon Sep 17 00:00:00 2001 From: Irvine Fleith Date: Thu, 30 Jan 2025 09:58:29 +0100 Subject: [PATCH 358/602] fix(contrat,facture-rec): undefined properties --- htdocs/compta/facture/class/facture-rec.class.php | 7 +++++++ htdocs/contrat/class/contrat.class.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 228badc04dc..a45feec9cdc 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -125,6 +125,13 @@ class FactureRec extends CommonInvoice public $cond_reglement_code; // Code in llx_c_paiement public $mode_reglement_code; // Code in llx_c_paiement + public $fk_multicurrency; + public $multicurrency_code; + public $multicurrency_tx; + public $multicurrency_total_ht; + public $multicurrency_total_tva; + public $multicurrency_total_ttc; + public $suspended; // status public $auto_validate; // 0 to create in draft, 1 to create and validate the new invoice diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index a29df83b834..d78c636b0f1 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -3097,7 +3097,7 @@ class ContratLigne extends CommonObjectLine $sql .= " t.label,"; // This field is not used. Only label of product $sql .= " p.ref as product_ref,"; $sql .= " p.label as product_label,"; - $sql .= " p.description as product_desc,"; + $sql .= " p.description as product_description,"; $sql .= " p.fk_product_type as product_type,"; $sql .= " t.description,"; $sql .= " t.date_commande,"; From 72604763977f4c32d22feed2b834d4bb508740ec Mon Sep 17 00:00:00 2001 From: Pratush Raj Date: Thu, 30 Jan 2025 15:14:07 +0530 Subject: [PATCH 359/602] Bug Fix: #32206 --- htdocs/core/class/discount.class.php | 6 ++++-- htdocs/societe/class/societe.class.php | 24 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 29e663f4e27..06929becacc 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -278,13 +278,15 @@ class DiscountAbsolute extends CommonObject $sql .= " (entity, datec, fk_soc, discount_type, fk_user, description,"; $sql .= " amount_ht, amount_tva, amount_ttc, tva_tx, vat_src_code,"; $sql .= " multicurrency_amount_ht, multicurrency_amount_tva, multicurrency_amount_ttc,"; - $sql .= " fk_facture_source, fk_invoice_supplier_source"; + $sql .= " fk_facture_source, fk_invoice_supplier_source, multicurrency_code, multicurrency_tx"; $sql .= ")"; $sql .= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec != '' ? $this->datec : dol_now())."', ".((int) $this->socid).", ".(empty($this->discount_type) ? 0 : intval($this->discount_type)).", ".((int) $userid).", '".$this->db->escape($this->description)."',"; $sql .= " ".price2num($this->amount_ht).", ".price2num($this->amount_tva).", ".price2num($this->amount_ttc).", ".price2num($this->tva_tx).", '".$this->db->escape($this->vat_src_code)."',"; $sql .= " ".price2num($this->multicurrency_amount_ht).", ".price2num($this->multicurrency_amount_tva).", ".price2num($this->multicurrency_amount_ttc).", "; $sql .= " ".($this->fk_facture_source ? ((int) $this->fk_facture_source) : "null").","; - $sql .= " ".($this->fk_invoice_supplier_source ? ((int) $this->fk_invoice_supplier_source) : "null"); + $sql .= " ".($this->fk_invoice_supplier_source ? ((int) $this->fk_invoice_supplier_source) : "null").","; + $sql .= " '".($this->multicurrency_code ? $this->multicurrency_code : "null")."',"; + $sql .= " ".($this->multicurrency_tx ? price2num($this->multicurrency_tx) : "null"); $sql .= ")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 1f6e6377ca0..65c0c3e6145 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2505,15 +2505,27 @@ class Societe extends CommonObject $discount->socid = $this->id; $discount->discount_type = $discount_type; + $discount->multicurrency_code = $this->multicurrency_code; + list($this->fk_multicurrency, $this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code); + $discount->multicurrency_tx = $this->multicurrency_tx; if ($price_base_type == 'TTC') { - $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num($remise, 'MT'); - $discount->amount_ht = $discount->multicurrency_amount_ht = price2num((float) $remise / (1 + (float) $vatrate / 100), 'MT'); - $discount->amount_tva = $discount->multicurrency_amount_tva = price2num((float) $discount->amount_ttc - (float) $discount->amount_ht, 'MT'); + $discount->multicurrency_amount_ttc = price2num($remise * (float) $discount->multicurrency_tx, 'MT'); + $discount->multicurrency_amount_ht = price2num(((float) $remise / (1 + (float) $vatrate / 100)) * (float) $discount->multicurrency_tx, 'MT'); + $discount->multicurrency_amount_tva = price2num(((float) $discount->amount_ttc - (float) $discount->amount_ht) * (float) $discount->multicurrency_tx, 'MT'); + + $discount->amount_ttc = price2num($remise, 'MT'); + $discount->amount_ht = price2num((float) $remise / (1 + (float) $vatrate / 100), 'MT'); + $discount->amount_tva = price2num((float) $discount->amount_ttc - (float) $discount->amount_ht, 'MT'); + } else { - $discount->amount_ht = $discount->multicurrency_amount_ht = price2num($remise, 'MT'); - $discount->amount_tva = $discount->multicurrency_amount_tva = price2num((float) $remise * (float) $vatrate / 100, 'MT'); - $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num((float) $discount->amount_ht + (float) $discount->amount_tva, 'MT'); + $discount->amount_ht = price2num($remise, 'MT'); + $discount->amount_tva = price2num((float) $remise * (float) $vatrate / 100, 'MT'); + $discount->amount_ttc = price2num((float) $discount->amount_ht + (float) $discount->amount_tva, 'MT'); + + $discount->multicurrency_amount_ht = price2num($remise * (float)$discount->multicurrency_tx, 'MT'); + $discount->multicurrency_amount_tva = price2num(((float) $remise * (float) $vatrate / 100) * (float) $discount->multicurrency_tx, 'MT'); + $discount->multicurrency_amount_ttc= price2num(((float) $discount->amount_ht + (float) $discount->amount_tva) * (float) $discount->multicurrency_tx, 'MT'); } $discount->tva_tx = (float) price2num($vatrate); From 1298229345a4a9e05c2d3160e8772eaf089ffa9c Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 30 Jan 2025 12:10:21 +0100 Subject: [PATCH 360/602] Doc --- dev/build/makepack-howto.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/dev/build/makepack-howto.txt b/dev/build/makepack-howto.txt index 61a6006f0ae..b23b21e1bd7 100644 --- a/dev/build/makepack-howto.txt +++ b/dev/build/makepack-howto.txt @@ -1,14 +1,14 @@ ----- Dolibarr Makepack How To ----- -This documentation describe steps to build a BETA or RELEASE versions -of Dolibarr. There is a chapter for BETA version and a chapter for RELEASE version. +This documentation describe steps to build a BETA or RELEASE versions of Dolibarr. +There is a chapter for BETA version and a chapter for RELEASE version. -***** Prerequisites For Linux ***** +***** Prerequisites on Linux ***** -Prerequisites to build tgz, debian and rpm packages: +Prerequisites to build the tgz, debian and rpm packages: > apt-get install perl tar dpkg dpatch p7zip-full rpm zip php-cli -Prerequisites to build autoexe DoliWamp package from Linux (solution seems broken since Ubuntu 20.04): +Prerequisites to build autoexe DoliWamp package from Linux (solution seems broken since Ubuntu 20.04+): > apt-get install wine q4wine > Launch "wine cmd" to check a drive Z: pointing to / exists. > Install InnoSetup @@ -23,7 +23,7 @@ Prerequisites to build autoexe DoliWamp package from Linux (solution seems broke The .exe file will be build into directory build. -***** Prerequisites For Windows ***** +***** Prerequisites on Windows ***** Prerequisites to build autoexe DoliWamp package from Windows: @@ -49,9 +49,9 @@ This files describe steps made by Dolibarr packaging team to make a beta version - Check all files are committed. - Update version/info in ChangeLog, for this you can: -To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" -To generate a changelog of a major new version x.y.0 (from a repo on branch x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" -To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" +To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" +To generate a changelog of a major new version x.y.0 (from a repo on branch x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" +To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" Recopy the content of the output file into the file ChangeLog. - Note: To know number of lines changes: git diff --shortstat A B - Update version number with x.y.z-w in file htdocs/filefunc.inc.php @@ -67,15 +67,15 @@ Recopy the content of the output file into the file ChangeLog. ***** Actions to do a RELEASE ***** This files describe steps made by Dolibarr packaging team to make a complete release of Dolibarr, step by step. -We suppose the branch x.y has already been created during the beta (see previous step). +We suppose the branch x.y has already been created during the beta (see previous step) and we want to release a version x.y.z (with z >= 0) - Check all files are committed. -- Update version/info in ChangeLog, for this you can: -To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" -To generate a changelog of a major new version x.y.0 (from a repo pn branch x.y), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" -To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" +- Update version/info in ChangeLog, for this: +To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" +To generate a changelog of a major new version x.y.0 (from a repo pn branch x.y), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" +To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy" Recopy the content of the output file into the file ChangeLog. -- Note: To know the number of lines changes: git diff --shortstat A B +- Note: To know the number of lines changes: git diff --shortstat vA vB - Update version number with x.y.z in file htdocs/filefunc.inc.php - Commit all changes. @@ -84,6 +84,6 @@ Recopy the content of the output file into the file ChangeLog. - Check content of built packages. - Run makepack-dolibarr.pl again with option to publish files on dolibarr foundation server (Dir /home/dolibarr/wwwroot/files/stable on www.dolibarr.org). -- Run makepack-dolibarr.pl again with option to publish files on sourceforge. This will also add official tag. +- Run makepack-dolibarr.pl again with option to publish files on sourceforge. This will also add the official tag x.y.z. -- Post a news on dolibarr.org/dolibarr.fr + social networks +- Post a news in english dolibarr.org/dolibarr.fr web site by cloning a past news (the news will be propagated on social networks) From 4e1a319113b3880e1b3161ce0b74c3dece6c8557 Mon Sep 17 00:00:00 2001 From: Dolibot Date: Thu, 30 Jan 2025 12:06:34 +0000 Subject: [PATCH 361/602] PHPStan > Update baseline --- dev/build/phpstan/phpstan-baseline.neon | 78 ------------------------- 1 file changed, 78 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 2d9c290b25a..740e50d80c5 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -9540,12 +9540,6 @@ parameters: count: 1 path: ../../../htdocs/core/class/dolgraph.class.php - - - message: '#^Comparison operation "\>" between 0 and 0 is always false\.$#' - identifier: greater.alwaysFalse - count: 3 - path: ../../../htdocs/core/class/dolgraph.class.php - - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse @@ -9564,24 +9558,6 @@ parameters: count: 1 path: ../../../htdocs/core/class/dolgraph.class.php - - - message: '#^Loose comparison using \=\= between 0 and 0 will always evaluate to true\.$#' - identifier: equal.alwaysTrue - count: 2 - path: ../../../htdocs/core/class/dolgraph.class.php - - - - message: '#^Loose comparison using \=\= between 1 and 3 will always evaluate to false\.$#' - identifier: equal.alwaysFalse - count: 1 - path: ../../../htdocs/core/class/dolgraph.class.php - - - - message: '#^Offset 0 on array\{array\{stacknum\: int, legend\: mixed, legendwithgroup\: non\-falsy\-string\}\} in empty\(\) always exists and is not falsy\.$#' - identifier: empty.offset - count: 1 - path: ../../../htdocs/core/class/dolgraph.class.php - - message: '#^Ternary operator condition is always true\.$#' identifier: ternary.alwaysTrue @@ -14670,24 +14646,12 @@ parameters: count: 12 path: ../../../htdocs/core/tpl/card_presend.tpl.php - - - message: '#^Variable \$hidedesc might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/tpl/card_presend.tpl.php - - message: '#^Variable \$hidedetails might not be defined\.$#' identifier: variable.undefined count: 1 path: ../../../htdocs/core/tpl/card_presend.tpl.php - - - message: '#^Variable \$hideref might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/core/tpl/card_presend.tpl.php - - message: '#^Variable \$hookmanager might not be defined\.$#' identifier: variable.undefined @@ -15444,12 +15408,6 @@ parameters: count: 1 path: ../../../htdocs/cron/list.php - - - message: '#^Variable \$texttoshow might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/cron/list.php - - message: '#^Offset ''css'' on array\{css\: ''minwidth200'', picto\: mixed\} in empty\(\) always exists and is not falsy\.$#' identifier: empty.offset @@ -15510,12 +15468,6 @@ parameters: count: 1 path: ../../../htdocs/delivery/card.php - - - message: '#^Variable \$arrayoptions might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/delivery/card.php - - message: '#^Variable \$hidedesc might not be defined\.$#' identifier: variable.undefined @@ -15786,42 +15738,12 @@ parameters: count: 1 path: ../../../htdocs/don/paiement/list.php - - - message: '#^Variable \$morecss might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/don/paiement/list.php - - - - message: '#^Variable \$morejs might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/don/paiement/list.php - - - - message: '#^Variable \$outputlangs might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/don/payment/card.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue count: 1 path: ../../../htdocs/don/payment/payment.php - - - message: '#^Variable \$sumpaid might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../../htdocs/don/payment/payment.php - - - - message: '#^Variable \$objectlink might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/don/tpl/linkedobjectblock.tpl.php - - message: '#^Property EcmFiles\:\:\$acl \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property From 7fa1baf1ddbf35d4710f175d1a5ad387672abcc0 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 30 Jan 2025 13:34:26 +0100 Subject: [PATCH 362/602] Fix regression --- htdocs/categories/class/categorie.class.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 305649da4e4..5dd92761cdb 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1785,10 +1785,9 @@ class Categorie extends CommonObject } // Check contrast with background and correct text color - //$forced_color = 'categtextwhite'; // TODO This css class hide the link - $forced_color = 'categtextblack'; + $forced_color = 'categtextwhite'; // We want color white because the background is dark (grey or other) if ($this->color) { - if (colorIsLight($this->color)) { + if (colorIsLight($this->color)) { // If color is light, we force color to dark $forced_color = 'categtextblack'; } } From 09d745057c92804bf27bc18b6813257c4ea49951 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 30 Jan 2025 14:36:43 +0100 Subject: [PATCH 363/602] Fix structured data --- htdocs/core/lib/website.lib.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 697d3f5674d..00de6abe9ae 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -779,13 +779,13 @@ function getStructuredData($type, $data = array()) $pageurl = $websitepage->pageurl; $title = $websitepage->title; - $image = $websitepage->image; + $image = getImageFromHtmlContent($websitepage->content); $companyname = $mysoc->name; $description = $websitepage->description; $pageurl = str_replace('__WEBSITE_KEY__', $website->ref, $pageurl); $title = str_replace('__WEBSITE_KEY__', $website->ref, $title); - $image = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image); + $imagepath = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image); $companyname = str_replace('__WEBSITE_KEY__', $website->ref, $companyname); $description = str_replace('__WEBSITE_KEY__', $website->ref, $description); @@ -798,10 +798,14 @@ function getStructuredData($type, $data = array()) "@type": "WebPage", "@id": "'.dol_escape_json($pageurl).'" }, - "headline": "'.dol_escape_json($title).'", + "headline": "'.dol_escape_json($title).'",'; + if ($image) { + $ret .= ' "image": [ - "'.dol_escape_json($image).'" - ], + "'.dol_escape_json($imagepath).'" + ],'; + } + $ret .= ' "dateCreated": "'.dol_print_date($websitepage->date_creation, 'dayhourrfc').'", "datePublished": "'.dol_print_date($websitepage->date_creation, 'dayhourrfc').'", "dateModified": "'.dol_print_date($websitepage->date_modification, 'dayhourrfc').'", @@ -814,7 +818,7 @@ function getStructuredData($type, $data = array()) "name": "'.dol_escape_json($companyname).'", "logo": { "@type": "ImageObject", - "url": "/wrapper.php?modulepart=mycompany&file=logos%2F'.urlencode($mysoc->logo).'" + "url": "/wrapper.php?modulepart=mycompany&file='.urlencode('logos/'.$mysoc->logo).'" } },'."\n"; if ($websitepage->keywords) { From 0cc2ce2c1190bca56cf0d984e27bdb1bb5ee816d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sol=C3=A8ne?= Date: Thu, 30 Jan 2025 15:48:50 +0100 Subject: [PATCH 364/602] Translations fixed --- htdocs/core/lib/fichinter.lib.php | 2 +- htdocs/langs/en_US/interventions.lang | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/fichinter.lib.php b/htdocs/core/lib/fichinter.lib.php index 64b91da0206..2eeb365cc62 100644 --- a/htdocs/core/lib/fichinter.lib.php +++ b/htdocs/core/lib/fichinter.lib.php @@ -232,7 +232,7 @@ function fichinter_rec_prepare_head($object) $head = array(); $head[$h][0] = DOL_URL_ROOT.'/fichinter/card-rec.php?id='.$object->id; - $head[$h][1] = $langs->trans("CardFichinter"); + $head[$h][1] = $langs->trans("InterventionCard"); $head[$h][2] = 'card'; $h++; diff --git a/htdocs/langs/en_US/interventions.lang b/htdocs/langs/en_US/interventions.lang index 1d7b2ada84f..2e3e1d1f510 100644 --- a/htdocs/langs/en_US/interventions.lang +++ b/htdocs/langs/en_US/interventions.lang @@ -86,3 +86,4 @@ TypeContact_fichinter_external_BILLING=Customer contact of intervention billing TypeContact_fichinter_external_CUSTOMER=Customer contact of intervention follow-up NotARecurringInterventionalTemplate=Not a recurring intervention template ShowInterventionModel=Show intervention model +CreateRepeatableIntervention=Create recurring intervention From e83e318fc92bef80fa98d919ed694ec627e850d7 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 30 Jan 2025 16:04:25 +0100 Subject: [PATCH 365/602] Enhance selectForForms --- htdocs/core/class/commonobject.class.php | 31 +++++++++++------- htdocs/core/class/html.form.class.php | 41 +++++++++++++----------- htdocs/hrm/class/position.class.php | 6 ++-- htdocs/hrm/position_list.php | 14 +++++--- 4 files changed, 55 insertions(+), 37 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3aa18de36e9..6ba5e3e730f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7450,16 +7450,15 @@ abstract class CommonObject * Return HTML string to put an input field into a page * Code very similar with showInputField of extra fields * - * @param ?array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string} $val Array of properties for field to show (used only if ->fields not defined) - * Array of properties of field to show - * @param string $key Key of attribute - * @param string|string[] $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 array type must be array) - * @param string $moreparam To add more parameters on html input tag - * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) - * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) - * @param string|int $morecss Value for css to define style/length of field. May also be a numeric. - * @param int<0,1> $nonewbutton Force to not show the new button on field that are links to object - * @return string + * @param ?array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string} $val Array of properties for field to show (used only if ->fields not defined, so try to keep this null) + * @param string $key Key of attribute + * @param string|string[] $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 array type must be array) + * @param string $moreparam To add more parameters on html input tag + * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string|int $morecss Value for css to define style/length of field. May also be a numeric. + * @param int<0,1> $nonewbutton Force to not show the new button on field that are links to object + * @return string */ public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0) { @@ -8269,7 +8268,17 @@ abstract class CommonObject } } } - $objectfield = $this->element.($this->module ? '@'.$this->module : '').':'.$key.$keysuffix; + + // $param_list_array[0] can be the name of object (Example 'User' the field is linked to). Not as taking the information from the record in ->fields found from $objectfield. + + // $valparent is a string 'dataobject@module:keyoffieldinfieldsarray' to find the record field to link to. + // $valparent = $this->element.($this->module ? '@'.$this->module : '').':'.$key.$keysuffix; + + // $val is already the record field found at same place than found by $valparent but already loaded and may have been modified by parent caller. + + //$objectfield = $valparent; + $objectfield = $val; // Is better than using old method $valparent + $out = $form->selectForForms($param_list_array[0], $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss, $moreparam, 0, (empty($val['disabled']) ? 0 : 1), '', $objectfield); if (!empty($param_list_array[2])) { // If the entry into $fields is set, we must add a create button diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index e611d3ec66f..af533b9474b 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -8486,22 +8486,22 @@ class Form /** * Generic method to select a component from a combo list. - * Can use autocomplete with ajax after x key pressed or a full combo, depending on setup. + * Can use autocomplete with ajax after x key pressed (if $objecttmp->element.'_USE_SEARCH_TO_SELECT' is set) or a full combo, depending on setup. * This is the generic method that will replace all specific existing methods. * - * @param string $objectdesc 'ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]'. For hard coded custom needs. Try to prefer method using $objectfield instead of $objectdesc. - * @param string $htmlname Name of HTML select component - * @param int $preSelectedValue Preselected value (ID of element) + * @param string $objectdesc 'ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]'. For hard coded custom needs. Try to prefer method using $objectfield array instead of $objectdesc. + * @param string $htmlname Name of HTML select component + * @param int $preSelectedValue Preselected value (ID of element) * @param string|int<0,1> $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...) - * @param string $searchkey Search criteria - * @param string $placeholder Place holder - * @param string $morecss More CSS - * @param string $moreparams More params provided to ajax call - * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) - * @param int<0,1> $disabled 1=Html component is disabled - * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param string $objectfield Object:Field that contains the definition of parent (in table $fields or $extrafields). Example: 'Object:xxx' or 'Object@module:xxx' (old syntax 'Module_Object:xxx') or 'Object:options_xxx' or 'Object@module:options_xxx' (old syntax 'Module_Object:options_xxx') - * @return string Return HTML string + * @param string $searchkey Search criteria + * @param string $placeholder Place holder + * @param string $morecss More CSS + * @param string $moreparams More params provided to ajax call + * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) + * @param int<0,1> $disabled 1=Html component is disabled + * @param string $selected_input_value Value of preselected input text (for use with ajax) + * @param string|array $objectfield 'Object:Field' that contains the definition of parent (in table $fields or $extrafields). Example: 'Object:xxx' or 'Object@module:xxx' or 'Object:options_xxx' or 'Object@module:options_xxx' or, better, the full entry array in ->fields + * @return string Return HTML string * @see selectForFormsList(), select_thirdparty_list() */ public function selectForForms($objectdesc, $htmlname, $preSelectedValue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0, $selected_input_value = '', $objectfield = '') @@ -8511,14 +8511,16 @@ class Form // Example of common usage for a link to a thirdparty // We got this in a modulebuilder form of "MyObject" of module "mymodule". - // ->fields is array( ... "fk_soc" => array("type"=>"integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...) + // When ->fields is array( ... "fk_soc" => array("type"=>"integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...), we have // $objectdesc = 'Societe' - // $objectfield = 'myobject@mymodule:fk_soc' ('fk_soc' is code to retrieve myobject->fields['fk_soc']) + // $objectfield = 'myobject@mymodule:fk_soc' ('fk_soc' is code to retrieve myobject->fields['fk_soc']) or it can be an array that is directly + // array("type"=>"integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...) // We got this when showing an extrafields on resource that is a link to societe - // extrafields 'link_to_societe' of Resource is 'link' to 'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...)' + // When extrafields 'link_to_societe' of Resource is 'link' to 'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...)', we have // $objectdesc = 'Societe' - // $objectfield = 'resource:options_link_to_societe' + // $objectfield = 'resource:options_link_to_societe' or it can be an array that is directly + // array("type"=>'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...) // With old usage: // $objectdesc = 'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))' @@ -8534,7 +8536,10 @@ class Form $filter = ''; // Ensure filter has value (for static analysis) $sortfield = ''; // Ensure filter has value (for static analysis) - if ($objectfield) { // We must retrieve the objectdesc from the field or extrafield + if (is_array($objectfield)) { + $objectdesc = $objectfield['type']; + $objectdesc = preg_replace('/^integer[^:]*:/', '', $objectdesc); + } elseif ($objectfield) { // We must retrieve the objectdesc from the field or extrafield. Deprecated, it is better to provide the array record directly. // Example: $objectfield = 'product:options_package' or 'myobject@mymodule:options_myfield' $tmparray = explode(':', $objectfield); diff --git a/htdocs/hrm/class/position.class.php b/htdocs/hrm/class/position.class.php index 50705c1ece5..2059a1d4ff5 100644 --- a/htdocs/hrm/class/position.class.php +++ b/htdocs/hrm/class/position.class.php @@ -207,7 +207,7 @@ class Position extends CommonObject */ public function __construct(DoliDB $db) { - global $conf, $langs; + global $langs; $this->db = $db; @@ -873,7 +873,7 @@ class Position extends CommonObject * Return HTML string to put an input field into a page * Code very similar with showInputField of extra fields * - * @param ?array{type:string,label:string,enabled:int|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string} $val Array of properties for field to show + * @param ?array{type:string,label:string,enabled:int|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array,comment?:string} $val Array of properties for field to show. If ->fields is defined, keep this null. * @param string $key Key of attribute * @param string $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) * @param string $moreparam To add more parameters on html input tag @@ -890,7 +890,7 @@ class Position extends CommonObject if ($key == 'fk_user') { $vacantId = $keyprefix.$key.'vacant'.$keysuffix; - $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss); + $out = parent::showInputField(null, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss); $out .= ''; ?> '."\n"; } - if (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) { - print ''."\n"; - } else { - print ''."\n"; + if (!defined('DISABLE_JQUERY_UI')) { + if (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) { + print '' . "\n"; + } else { + print '' . "\n"; + } } // jQuery jnotify if (!getDolGlobalString('MAIN_DISABLE_JQUERY_JNOTIFY') && !defined('DISABLE_JQUERY_JNOTIFY')) { From 15dec468cb555e43e3454d431b7c23b87e89d093 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 7 Feb 2025 10:05:06 +0100 Subject: [PATCH 545/602] NEW: add const to not include JQuery UI in top_htmlhead DISABLE_JQUERY_UI --- htdocs/main.inc.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 9004839fa99..3ddad620a92 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2120,6 +2120,8 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr } else { print ''."\n"; } + + if (!defined('DISABLE_JQUERY_UI')) { if (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) { print '' . "\n"; From 867215e2eae009af0b4e5f11b84f01363fed2104 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 7 Feb 2025 10:05:17 +0100 Subject: [PATCH 546/602] NEW: add const to not include JQuery UI in top_htmlhead DISABLE_JQUERY_UI --- htdocs/main.inc.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 3ddad620a92..9004839fa99 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2120,8 +2120,6 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr } else { print ''."\n"; } - - if (!defined('DISABLE_JQUERY_UI')) { if (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) { print '' . "\n"; From a8811551092404b7ea028c21001033173884af5d Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 7 Feb 2025 10:10:45 +0100 Subject: [PATCH 547/602] NEW: add const to not include default CSS in top_htmlhead with DISABLE_CSS_DEFAULT_THEME --- htdocs/main.inc.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index d25d87140b9..9b126b49724 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2036,21 +2036,21 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr print ''."\n"; } - if (!defined('DISABLE_CSS_DEFAULT_THEME')) { - print ''."\n"; - // Output style sheets (optioncss='print' or ''). Note: $conf->css looks like '/theme/eldy/style.css.php' - $themepath = dol_buildpath($conf->css, 1); - $themesubdir = ''; - if (!empty($conf->modules_parts['theme'])) { // This slow down - foreach ($conf->modules_parts['theme'] as $reldir) { - if (file_exists(dol_buildpath($reldir.$conf->css, 0))) { - $themepath = dol_buildpath($reldir.$conf->css, 1); - $themesubdir = $reldir; - break; - } + // Output style sheets (optioncss='print' or ''). Note: $conf->css looks like '/theme/eldy/style.css.php' + $themepath = dol_buildpath($conf->css, 1); + $themesubdir = ''; + if (!empty($conf->modules_parts['theme'])) { // This slow down + foreach ($conf->modules_parts['theme'] as $reldir) { + if (file_exists(dol_buildpath($reldir.$conf->css, 0))) { + $themepath = dol_buildpath($reldir.$conf->css, 1); + $themesubdir = $reldir; + break; } } + } + if (!defined('DISABLE_CSS_DEFAULT_THEME')) { + print ''."\n"; print '' . "\n"; } From e0a8caec45b9d9dece3ec63a54a484bc7618d357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 7 Feb 2025 10:45:03 +0100 Subject: [PATCH 548/602] fix phpstan --- dev/build/phpstan/phpstan-baseline.neon | 6 ------ htdocs/core/class/commondocgenerator.class.php | 6 +++--- .../modules/asset/doc/doc_generic_asset_odt.modules.php | 6 +++--- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 4f95b73a9fb..deba1cbbeb2 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -8862,12 +8862,6 @@ parameters: count: 1 path: ../../../htdocs/core/class/commondocgenerator.class.php - - - message: '#^Parameter \#2 \$array_to_fill of method CommonDocGenerator\:\:fill_substitutionarray_with_extrafields\(\) expects array\, array\ given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/class/commondocgenerator.class.php - - message: '#^Property CommonObject\:\:\$element \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 884639b234e..1f52f57bc31 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015 Marcos García * Copyright (C) 2016-2023 Charlene Benke - * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2020 Josep Lluís Amador * Copyright (C) 2024 MDW * Copyright (C) 2024 Mélina Joum @@ -1174,11 +1174,11 @@ abstract class CommonDocGenerator * Note that vars into substitutions array are formatted. * * @param CommonObject $object Object with extrafields (must have $object->array_options filled) - * @param array $array_to_fill Substitution array + * @param array $array_to_fill Substitution array * @param Extrafields $extrafields Extrafields object * @param string $array_key Prefix for name of the keys into returned array * @param Translate $outputlangs Lang object to use for output - * @return array Substitution array + * @return array Substitution array */ public function fill_substitutionarray_with_extrafields($object, $array_to_fill, $extrafields, $array_key, $outputlangs) { diff --git a/htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php b/htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php index 92792da10e8..9848d61fbbd 100644 --- a/htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php +++ b/htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php @@ -4,7 +4,7 @@ * Copyright (C) 2014 Marcos García * Copyright (C) 2016 Charlie Benke * Copyright (C) 2018-2021 Philippe Grand - * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -398,7 +398,7 @@ class doc_generic_asset_odt extends ModelePDFAsset } } // Replace tags of lines - $foundtagforlines = 1; + /*$foundtagforlines = 1; try { $listlines = $odfHandler->setSegment('lines'); } catch (OdfExceptionSegmentNotFound $e) { @@ -431,7 +431,7 @@ class doc_generic_asset_odt extends ModelePDFAsset dol_syslog($this->error, LOG_WARNING); return -1; } - } + }*/ // Replace labels translated $tmparray = $outputlangs->get_translations_for_substitutions(); From 712a2b544a3b4e058934736d21aa1872df2400fb Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 10:46:13 +0100 Subject: [PATCH 549/602] Fix false positive --- htdocs/core/class/commondocgenerator.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index ba37cce06b2..ba2c7d0ae94 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -927,6 +927,7 @@ abstract class CommonDocGenerator foreach ($date_specs as $date_spec) { $propertyname = $date_spec[1]; if (property_exists($line, $propertyname)) { + // @phan-suppress-next-line PhanUndeclaredProperty $resarray[$date_spec[0]] = dol_print_date($line->$propertyname, $date_spec[2], $date_spec[3], $date_spec[4]); } } From 28724db69e1e64e294b3dc871561e5c1b19b1669 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 10:52:23 +0100 Subject: [PATCH 550/602] Try to fix phpstan false positive --- htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php b/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php index f8a99d51d40..006d797f5b6 100644 --- a/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php +++ b/htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php @@ -405,6 +405,7 @@ class doc_generic_bom_odt extends ModelePDFBom if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var BOMLine $line */ $linenumber++; if ($line->fk_product > 0) { From d01274ef4c5966b873476b40d30c75b55590d5d3 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 11:28:13 +0100 Subject: [PATCH 551/602] Fix phan --- .../modules/commande/doc/doc_generic_order_odt.modules.php | 1 + .../contract/doc/doc_generic_contract_odt.modules.php | 1 + .../modules/facture/doc/doc_generic_invoice_odt.modules.php | 1 + htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php | 1 + .../project/task/doc/doc_generic_task_odt.modules.php | 2 +- .../modules/propale/doc/doc_generic_proposal_odt.modules.php | 1 + .../reception/doc/doc_generic_reception_odt.modules.php | 1 + .../doc/doc_generic_supplier_invoice_odt.modules.php | 1 + .../doc/doc_generic_supplier_order_odt.modules.php | 1 + .../doc/doc_generic_supplier_proposal_odt.modules.php | 1 + htdocs/supplier_proposal/class/supplier_proposal.class.php | 5 +++++ 11 files changed, 15 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index 5ee13332781..3495cc57265 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -426,6 +426,7 @@ class doc_generic_order_odt extends ModelePDFCommandes if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var OrderLine $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php index 27a295e61e4..6c68888cebc 100644 --- a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php +++ b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php @@ -420,6 +420,7 @@ class doc_generic_contract_odt extends ModelePDFContract if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var ContratLigne $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index f4435c982ed..7b081f4d4bd 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -482,6 +482,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var FactureLigne $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php index ff22719c4ab..93ce87f2be5 100644 --- a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php +++ b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php @@ -408,6 +408,7 @@ class doc_generic_mo_odt extends ModelePDFMo if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var MoLine $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index a0c7210392a..2eb87a0189f 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -458,7 +458,7 @@ class doc_generic_task_odt extends ModelePDFTask /** * Function to build a document on disk using the generic odt module. * - * @param Project $object Object source to build document + * @param Task $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @return int<-1,1> 1 if OK, <=0 if KO diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index 86266b76b16..4e3f9adb01b 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -463,6 +463,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var PropaleLigne $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php index bf7247fdde8..68b20c45977 100644 --- a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php +++ b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php @@ -412,6 +412,7 @@ class doc_generic_reception_odt extends ModelePdfReception if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var ReceptionLineBatch $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php b/htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php index d59451d9be9..6ec79297018 100644 --- a/htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php +++ b/htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php @@ -417,6 +417,7 @@ class doc_generic_supplier_invoice_odt extends ModelePDFSuppliersInvoices if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var CommonInvoiceLine $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php index fcfa4212862..2c26e3fb876 100644 --- a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php +++ b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php @@ -412,6 +412,7 @@ class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var CommonOrderLine $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php index a17f724a5fa..b207a616be8 100644 --- a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php @@ -441,6 +441,7 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var SupplierProposalLine $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index e33cdc6c377..fd534683010 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -192,7 +192,12 @@ class SupplierProposal extends CommonObject * @var array (Encoded as JSON in database) */ public $extraparams = array(); + + /** + * @var SupplierProposalLine[] + */ public $lines = array(); + /** * @var SupplierProposalLine */ From f05bc70b2e24b2401b6b1e99a600fe78e336c2e3 Mon Sep 17 00:00:00 2001 From: MDW Date: Wed, 5 Feb 2025 22:59:37 +0100 Subject: [PATCH 552/602] Qual: Fix phan notices (modulebuilder) --- dev/tools/phan/baseline.txt | 30 +--------- htdocs/core/lib/functions.lib.php | 7 ++- .../doc/doc_generic_usergroup_odt.modules.php | 4 +- htdocs/modulebuilder/index.php | 60 ++++++++----------- htdocs/modulebuilder/template/admin/setup.php | 4 +- .../modulebuilder/template/ajax/myobject.php | 2 +- .../template/class/api_mymodule.class.php | 26 ++++---- .../template/class/myobject.class.php | 2 +- .../doc/pdf_standard_myobject.modules.php | 12 ++-- .../mymodule/mod_myobject_advanced.php | 4 +- .../modulebuilder/template/myobject_list.php | 18 +++--- 11 files changed, 71 insertions(+), 98 deletions(-) diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 716996e9d84..0da0c9a1237 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -9,9 +9,9 @@ */ return [ // # Issue statistics: - // PhanTypeMismatchArgument : 2560+ occurrences + // PhanTypeMismatchArgument : 2490+ occurrences // PhanUndeclaredProperty : 530+ occurrences - // PhanTypeMismatchArgumentNullable : 450+ occurrences + // PhanTypeMismatchArgumentNullable : 430+ occurrences // PhanUndeclaredGlobalVariable : 190+ occurrences // PhanPluginUnknownArrayMethodReturnType : 180+ occurrences // PhanPossiblyUndeclaredGlobalVariable : 160+ occurrences @@ -84,7 +84,7 @@ return [ 'htdocs/adherents/admin/website.php' => ['PhanTypeMismatchArgument'], 'htdocs/adherents/canvas/actions_adherentcard_common.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/adherents/card.php' => ['PhanTypeMismatchArgument'], - 'htdocs/adherents/class/adherent.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], + 'htdocs/adherents/class/adherent.class.php' => ['PhanTypeMismatchArgumentNullable'], 'htdocs/adherents/class/adherent_type.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/adherents/class/api_members.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/adherents/list.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredGlobalVariable'], @@ -411,20 +411,16 @@ return [ 'htdocs/core/login/functions_dolibarr.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/login/functions_ldap.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/core/menus/standard/auguria.lib.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php' => ['PhanTypeMismatchArgumentNullable'], 'htdocs/core/modules/asset/mod_asset_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/barcode/mod_barcode_product_standard.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/barcode/mod_barcode_thirdparty_standard.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/bom/mod_bom_advanced.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/core/modules/cheque/doc/pdf_blochet.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/core/modules/cheque/modules_chequereceipts.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/commande/doc/pdf_einstein.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/commande/mod_commande_saphir.php' => ['PhanTypeMismatchArgumentNullable'], - 'htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/contract/doc/pdf_strato.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/core/modules/delivery/doc/pdf_storm.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/core/modules/delivery/doc/pdf_typhon.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], @@ -435,7 +431,6 @@ return [ 'htdocs/core/modules/expedition/doc/pdf_rouget.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/core/modules/expensereport/doc/pdf_standard_expensereport.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/core/modules/expensereport/mod_expensereport_jade.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/facture/doc/pdf_crabe.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], 'htdocs/core/modules/facture/doc/pdf_octopus.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], 'htdocs/core/modules/facture/doc/pdf_sponge.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], @@ -471,38 +466,29 @@ return [ 'htdocs/core/modules/modSupplierProposal.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/modTicket.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/core/modules/mrp/mod_mo_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/oauth/github_oauthcallback.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/core/modules/project/doc/pdf_beluga.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/project/doc/pdf_timespent.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/propale/doc/pdf_azur.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], 'htdocs/core/modules/propale/doc/pdf_cyan.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/reception/doc/pdf_squille.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], 'htdocs/core/modules/societe/doc/doc_generic_odt.modules.php' => ['PhanTypeMismatchArgumentNullable'], - 'htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/core/modules/stocktransfer/doc/pdf_eagle_proforma.modules.php' => ['PhanTypeMismatchArgumentNullable'], 'htdocs/core/modules/stocktransfer/mod_stocktransfer_advanced.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchProperty'], - 'htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], - 'htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/supplier_proposal/doc/pdf_zenith.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'], 'htdocs/core/modules/syslog/mod_syslog_file.php' => ['PhanPluginDuplicateArrayKey'], 'htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php' => ['PhanTypeMismatchArgumentNullable'], - 'htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/workstation/mod_workstation_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/multicompany_page.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/search_page.php' => ['PhanTypeMismatchArgument'], @@ -622,15 +608,6 @@ return [ 'htdocs/loan/document.php' => ['PhanUndeclaredProperty'], 'htdocs/loan/note.php' => ['PhanUndeclaredProperty'], 'htdocs/loan/payment/payment.php' => ['PhanUndeclaredProperty'], - 'htdocs/modulebuilder/index.php' => ['PhanTypeMismatchArgumentNullable'], - 'htdocs/modulebuilder/template/admin/setup.php' => ['PhanTypeMismatchArgument'], - 'htdocs/modulebuilder/template/ajax/myobject.php' => ['PhanTypeMismatchArgument'], - 'htdocs/modulebuilder/template/class/api_mymodule.class.php' => ['PhanTypeMismatchArgument'], - 'htdocs/modulebuilder/template/class/myobject.class.php' => ['PhanTypeMismatchArgument'], - 'htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php' => ['PhanTypeMismatchArgument'], - 'htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], - 'htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php' => ['PhanTypeMismatchArgument'], - 'htdocs/modulebuilder/template/myobject_list.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/mrp/ajax/ajax_bom.php' => ['PhanTypeMismatchArgument'], 'htdocs/mrp/class/api_mos.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgument'], 'htdocs/mrp/class/mo.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchProperty'], @@ -802,7 +779,6 @@ return [ 'htdocs/recruitment/class/api_recruitments.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/recruitment/class/recruitmentcandidature.class.php' => ['PhanUndeclaredProperty'], 'htdocs/recruitment/class/recruitmentjobposition.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 3695a1eeb69..567eb7e4b86 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1207,7 +1207,7 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options = /** * Return a sanitized or empty value after checking value against a rule. * - * @param string|array $out Value to check/clear. + * @param string|mixed[]|null $out Value to check/clear. * @param string $check Type of check/sanitizing * @param ?int $filter Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails) * @param ?mixed $options Options to pass to filter_var when $check is set to 'custom' @@ -1217,6 +1217,9 @@ function sanitizeVal($out = '', $check = 'alphanohtml', $filter = null, $options { // TODO : use class "Validate" to perform tests (and add missing tests) if needed for factorize // Check is done after replacement + if ($out === null) { + $out = ''; + } switch ($check) { case 'none': case 'password': @@ -9895,7 +9898,7 @@ function make_substitutions($text, $substitutionarray, $outputlangs = null, $con * Complete the $substitutionarray with more entries coming from external module that had set the "substitutions=1" into module_part array. * In this case, method completesubstitutionarray provided by module is called. * - * @param array $substitutionarray Array substitution old value => new value value + * @param array $substitutionarray Array substitution old value => new value value * @param Translate $outputlangs Output language * @param ?CommonObject $object Source object * @param ?mixed $parameters Add more parameters (useful to pass product lines) 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 da30d9a0b21..55015b96550 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 @@ -2,7 +2,7 @@ /* Copyright (C) 2010-2012 Laurent Destailleur * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -447,7 +447,7 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup $reshook = $hookmanager->executeHooks('ODTSubstitutionLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks foreach ($tmparray as $key => $val) { try { - if (!is_array($val)) { + if (!is_array($val)) { // @phpstan-ignore-line $listlines->setVars($key, $val, true, 'UTF-8'); } } catch (SegmentException $e) { diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 86726bb5543..a947d497024 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -2,7 +2,7 @@ /* Copyright (C) 2004-2023 Laurent Destailleur * Copyright (C) 2018-2019 Nicolas ZABOURI * Copyright (C) 2023 Alexandre Janniaux - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -67,7 +67,7 @@ $sortfield = GETPOST('sortfield', 'alpha'); $sortorder = GETPOST('sortorder', 'aZ09'); $module = GETPOST('module', 'alpha'); -$tab = GETPOST('tab', 'aZ09'); +$tab = (string) GETPOST('tab', 'aZ09'); $tabobj = GETPOST('tabobj', 'alpha'); $tabdic = GETPOST('tabdic', 'alpha'); $propertykey = GETPOST('propertykey', 'alpha'); @@ -77,6 +77,7 @@ if (empty($module)) { if (empty($tab)) { $tab = 'description'; } +'@phan-var-force string $tab'; // Workaround 'empty()' bug of phan if (empty($tabobj)) { $tabobj = 'newobjectifnoobj'; } @@ -850,6 +851,7 @@ if ($dirins && $action == 'initcli' && !empty($module) && $user->hasRight("modul $moduledescriptorfile = '/not_set/'; +$modulelowercase = null; // init Doc if ($dirins && $action == 'initdoc' && !empty($module) && $user->hasRight("modulebuilder", "run")) { @@ -1288,7 +1290,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname && $user->hasRi $position = 900; } // $alwayseditable - $alwayseditable=0; + $alwayseditable = 0; if ($fieldname == 'label') { $alwayseditable = 1; } else { @@ -2347,15 +2349,12 @@ if ($dirins && $action == 'generatepackage' && $user->hasRight("modulebuilder", $dirofmodule = dol_buildpath($modulelowercase, 0).'/bin'; $outputfilezip = $dirofmodule.'/'.$FILENAMEZIP; - if ($dirofmodule) { - if (!dol_is_dir($dirofmodule)) { - dol_mkdir($dirofmodule); - } - // Note: We exclude /bin/ to not include the already generated zip - $result = dol_compress_dir($dir, $outputfilezip, 'zip', '/\/bin\/|\.git|\.old|\.back|\.ssh/', $modulelowercase); - } else { - $result = -1; + + if (!dol_is_dir($dirofmodule)) { + dol_mkdir($dirofmodule); } + // Note: We exclude /bin/ to not include the already generated zip + $result = dol_compress_dir($dir, $outputfilezip, 'zip', '/\/bin\/|\.git|\.old|\.back|\.ssh/', $modulelowercase); if ($result > 0) { setEventMessages($langs->trans("ZipFileGeneratedInto", $outputfilezip), null); @@ -2706,12 +2705,9 @@ if ($action == 'set' && $user->admin && $user->hasRight("modulebuilder", "run")) if ($module) { $param .= '&module='.urlencode($module); } - if ($tab) { - $param .= '&tab='.urlencode($tab); - } - if ($tabobj) { - $param .= '&tabobj='.urlencode($tabobj); - } + + $param .= '&tab='.urlencode($tab); + $param .= '&tabobj='.urlencode($tabobj); $value = GETPOST('value', 'alpha'); $resarray = activateModule($value); @@ -2744,12 +2740,8 @@ if ($action == 'reset' && $user->admin && $user->hasRight("modulebuilder", "run" if ($module) { $param .= '&module='.urlencode($module); } - if ($tab) { - $param .= '&tab='.urlencode($tab); - } - if ($tabobj) { - $param .= '&tabobj='.urlencode($tabobj); - } + $param .= '&tab='.urlencode($tab); + $param .= '&tabobj='.urlencode($tabobj); $value = GETPOST('value', 'alpha'); $result = unActivateModule($value); @@ -3310,15 +3302,12 @@ if (is_array($listofmodules) && count($listofmodules) > 0) { $modulelowercase = strtolower($module); $param = ''; - if ($tab) { - $param .= '&tab='.urlencode($tab); - } if ($module) { $param .= '&module='.urlencode($module); } - if ($tabobj) { - $param .= '&tabobj='.urlencode($tabobj); - } + + $param .= '&tab='.urlencode($tab); + $param .= '&tabobj='.urlencode($tabobj); $urltomodulesetup = ''.$langs->trans('Home').'-'.$langs->trans("Setup").'-'.$langs->trans("Modules").''; @@ -3333,9 +3322,7 @@ if (is_array($listofmodules) && count($listofmodules) > 0) { $objMod = $moduleobj; $backtourlparam = ''; $backtourlparam .= ($backtourlparam ? '&' : '?').'module='.$module; // No urlencode here, done later - if ($tab) { - $backtourlparam .= ($backtourlparam ? '&' : '?').'tab='.$tab; // No urlencode here, done later - } + $backtourlparam .= ($backtourlparam ? '&' : '?').'tab='.$tab; // No urlencode here, done later $backtourl = $_SERVER["PHP_SELF"].$backtourlparam; $regs = array(); @@ -3493,7 +3480,7 @@ if ($module == 'initmodule') { print ''; print ''; print ''; -} elseif (!empty($module) && isset($modulelowercase)) { +} elseif (!empty($module) && $modulelowercase !== null) { // Tabs for module if (!$error) { $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; @@ -3848,6 +3835,7 @@ if ($module == 'initmodule') { } else { // Edit text file $fullpathoffile = dol_buildpath($file, 0, 1); // Description - level 2 + $content = ''; if ($fullpathoffile) { $content = file_get_contents($fullpathoffile); } @@ -4377,7 +4365,7 @@ if ($module == 'initmodule') { print $form->textwithpicto('', $langs->trans("InfoForApiFile"), 1, 'warning'); print '   '; // Comparing to null (phan considers $modulelowercase can be null here) - if ($modulelowercase !== null && !isModEnabled($modulelowercase)) { // If module is not activated + if (!isModEnabled($modulelowercase)) { // If module is not activated print ''.$langs->trans("ApiExplorer").''; } else { print ''.$langs->trans("ApiExplorer").''; @@ -6418,7 +6406,7 @@ if ($module == 'initmodule') { print ''; print ''; print "\n"; @@ -589,7 +589,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); print ''; // Preview diff --git a/htdocs/modulebuilder/template/ajax/myobject.php b/htdocs/modulebuilder/template/ajax/myobject.php index d4ca191942b..98bd1909bde 100644 --- a/htdocs/modulebuilder/template/ajax/myobject.php +++ b/htdocs/modulebuilder/template/ajax/myobject.php @@ -66,7 +66,7 @@ dol_include_once('/mymodule/class/myobject.class.php'); */ $mode = GETPOST('mode', 'aZ09'); -$objectId = GETPOST('objectId', 'aZ09'); +$objectId = GETPOSTINT('objectId'); $field = GETPOST('field', 'aZ09'); $value = GETPOST('value', 'aZ09'); diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php index a57d497ea30..11da9de8345 100644 --- a/htdocs/modulebuilder/template/class/api_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php @@ -38,7 +38,7 @@ dol_include_once('/mymodule/class/myobject.class.php'); class MyModuleApi extends DolibarrApi { /** - * @var MyObject $myobject {@type MyObject} + * @var MyObject {@type MyObject} */ public $myobject; @@ -46,7 +46,6 @@ class MyModuleApi extends DolibarrApi * Constructor * * @url GET / - * */ public function __construct() { @@ -194,8 +193,8 @@ class MyModuleApi extends DolibarrApi * Create myobject object * * @param array $request_data Request data - * @phan-param array{string,mixed} $request_data - * @phpstan-param array{string,mixed} $request_data + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return int ID of myobject * * @throws RestException 403 Not allowed @@ -215,7 +214,7 @@ class MyModuleApi extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller @phan-suppress-next-line PhanTypeInvalidDimOffset - $this->myobject->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + $this->myobject->context['caller'] = sanitizeVal((string) $request_data['caller'], 'aZ09'); continue; } @@ -243,8 +242,8 @@ class MyModuleApi extends DolibarrApi * * @param int $id Id of myobject to update * @param array $request_data Data - * @phan-param mixed[] $request_data - * @phpstan-param mixed[] $request_data + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return Object Object after update * @phan-return MyObject * @phpstan-return MyObject @@ -301,7 +300,7 @@ class MyModuleApi extends DolibarrApi // Clean data // $this->myobject->abc = sanitizeVal($this->myobject->abc, 'alphanohtml'); - if ($this->myobject->update(DolibarrApiAccess::$user, false) > 0) { + if ($this->myobject->update(DolibarrApiAccess::$user, 0) > 0) { return $this->get($id); } else { throw new RestException(500, $this->myobject->error); @@ -356,16 +355,19 @@ class MyModuleApi extends DolibarrApi * Validate fields before creating or updating object * * @param array $data Array of data to validate - * @phan-param array $data - * @phpstan-param array $data + * @phan-param ?array $data + * @phpstan-param ?array $data * @return array - * @phan-return array|array{} - * @phpstan-return array|array{} + * @phan-return array|array{} + * @phpstan-return array|array{} * * @throws RestException */ private function _validateMyObject($data) { + if (!is_array($data)) { + $data = array(); + } $myobject = array(); foreach ($this->myobject->fields as $field => $propfield) { if (in_array($field, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat')) || $propfield['notnull'] != 1) { diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index ceefd2998b0..500cdcaa476 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -802,7 +802,7 @@ class MyObject extends CommonObject $result = ''; $params = [ - 'id' => $this->id, + 'id' => (string) $this->id, 'objecttype' => $this->element.($this->module ? '@'.$this->module : ''), 'option' => $option, ]; diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php index 7ac4f25e47e..9abc8daff75 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php @@ -9,7 +9,7 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) ---Replace with your own copyright and developer email--- * @@ -431,12 +431,12 @@ class pdf_standard_myobject extends ModelePDFMyObject // $this->_pagefoot($pdf,$object,$outputlangs,1); $pdf->setTopMargin($tab_top_newpage); // The only function to edit the bottom margin of current page to set it. - $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext); } // back to start $pdf->setPage($pageposbeforenote); - $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext); $pdf->SetFont('', '', $default_font_size - 1); $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); $pageposafternote = $pdf->getPage(); @@ -450,7 +450,7 @@ class pdf_standard_myobject extends ModelePDFMyObject $pdf->setPage($pageposafternote); $pdf->setTopMargin($tab_top_newpage); // The only function to edit the bottom margin of current page to set it. - $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->setPageOrientation('', true, $heightforfooter + $heightforfreetext); //$posyafter = $tab_top_newpage; } @@ -472,7 +472,7 @@ class pdf_standard_myobject extends ModelePDFMyObject } // Add footer - $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it. $this->_pagefoot($pdf, $object, $outputlangs, 1); $i++; @@ -1174,7 +1174,7 @@ class pdf_standard_myobject extends ModelePDFMyObject $pdf->SetXY($posx + 2, $posy + 3); $pdf->SetFont('', 'B', $default_font_size); // @phan-suppress-next-line PhanPluginSuspiciousParamOrder - $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, $ltrdirection); + $pdf->MultiCell($widthrecbox, 2, (string) $carac_client_name, 0, $ltrdirection); $posy = $pdf->getY(); diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php index c8117863f12..b900878417c 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2008i Raphael Bertrand (Resultic) * Copyright (C) 2019-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) ---Replace with your own copyright and developer email--- * * This program is free software; you can redistribute it and/or modify @@ -83,7 +83,7 @@ class mod_myobject_advanced extends ModeleNumRefMyObject // prefix configuration $text .= ''; - $text .= ''; + $text .= ''; $text .= ''; $text .= ''; diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 2451c35d972..6972f0f2567 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -336,14 +336,18 @@ foreach ($search as $key => $val) { if ($key == 'status' && $search[$key] == -1) { continue; } - $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); - if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { - if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { + $field_spec = $object->fields[$key]; + if ($field_spec === null) { + continue; + } + $mode_search = (($object->isInt($field_spec) || $object->isFloat($field_spec)) ? 1 : 0); + if ((strpos($field_spec['type'], 'integer:') === 0) || (strpos($field_spec['type'], 'sellist:') === 0) || !empty($field_spec['arrayofkeyval'])) { + if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($field_spec['arrayofkeyval']) || !array_key_exists('0', $field_spec['arrayofkeyval'])))) { $search[$key] = ''; } $mode_search = 2; } - if (empty($object->fields[$key]['searchmulti'])) { + if (empty($field_spec['searchmulti'])) { if (!is_array($search[$key]) && $search[$key] != '') { $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search)); } @@ -829,15 +833,15 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['t.'.$key]['checked'])) { print '$key) && !in_array($key, array('ref'))) { - print ' title="'.dol_escape_htmltag($object->$key).'"'; + print ' title="'.dol_escape_htmltag((string) $object->$key).'"'; } print '>'; if ($key == 'status') { print $object->getLibStatut(5); } elseif ($key == 'rowid') { - print $object->showOutputField($val, $key, $object->id, ''); + print $object->showOutputField($val, $key, (string) $object->id, ''); } else { - print $object->showOutputField($val, $key, $object->$key, ''); + print $object->showOutputField($val, $key, (string) $object->$key, ''); } print ''; if (!$i) { From 68ffd2b6a8011bd176b4570d41c27d4555fa3573 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 12:51:44 +0100 Subject: [PATCH 553/602] Doc --- htdocs/install/mysql/migration/repair.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index 8262a3e1c98..dfae51fd352 100644 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -602,6 +602,10 @@ DELETE FROM llx_rights_def WHERE module = 'hrm' AND perms = 'employee'; -- UPDATE llx_bank as b SET b.amount_main_currency = -b.amount_main_currency WHERE b.amount IS NOT NULL AND b.amount_main_currency IS NOT NULL AND SIGN(b.amount_main_currency) <> SIGN(b.amount); +-- Sequence to fix the table llx_paiement_facture and llx_paiement for payment record on a bank account that does not exists anymore. +-- delete from llx_paiement_facture where fk_paiement in (select rowid from llx_paiement WHERE fk_bank is not null AND fk_bank not in (select rowid from llx_bank)); +-- delete from llx_paiement WHERE fk_bank is not null AND fk_bank not in (select rowid from llx_bank); + -- Delete duplicate entries into llx_c_transport_mode -- VMYSQL4.1 DELETE T1 FROM llx_c_transport_mode as T1, llx_c_transport_mode as T2 where T1.entity = T2.entity AND T1.code = T2.code and T1.rowid > T2.rowid; From 0b67bf4dad96eb0bc42c8a7b77684eb32e11fb50 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 13:00:24 +0100 Subject: [PATCH 554/602] Fix phan --- htdocs/core/modules/project/modules_project.php | 2 +- .../modules/project/task/doc/doc_generic_task_odt.modules.php | 2 ++ .../modules/mymodule/doc/doc_generic_myobject_odt.modules.php | 1 + .../doc/doc_generic_recruitmentjobposition_odt.modules.php | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/project/modules_project.php b/htdocs/core/modules/project/modules_project.php index 48885f0e4c7..f0f8bdf6cb1 100644 --- a/htdocs/core/modules/project/modules_project.php +++ b/htdocs/core/modules/project/modules_project.php @@ -68,7 +68,7 @@ abstract class ModelePDFProjects extends CommonDocGenerator /** * Function to build pdf project onto disk * - * @param Project $object Object source to build document + * @param Task $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @return int<-1,1> 1 if OK, <=0 if KO diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index 2eb87a0189f..6c9f3b43861 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -606,6 +606,8 @@ class doc_generic_task_odt extends ModelePDFTask } } + /** var Task $object */ + // Replace tags of lines for tasks try { // Security check diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php index e4f82b3a537..59ae7b1ec71 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php @@ -445,6 +445,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var CommonObjectLine $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); diff --git a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php index f40dcf70b41..637ba4f0cba 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php @@ -437,6 +437,7 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi if ($foundtagforlines) { $linenumber = 0; foreach ($object->lines as $line) { + /** @var CommonObjectLine $line */ $linenumber++; $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); From c01c49074c4f11a636bc38ba0044c5813e73f5ea Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 14:12:42 +0100 Subject: [PATCH 555/602] Fix phan --- .../modules/project/task/doc/doc_generic_task_odt.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index 6c9f3b43861..e45ce84f946 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -606,7 +606,7 @@ class doc_generic_task_odt extends ModelePDFTask } } - /** var Task $object */ + /** @var Task $object */ // Replace tags of lines for tasks try { From 568a7723c92584b05294b79e5a3f5df0dc7bb329 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 14:16:48 +0100 Subject: [PATCH 556/602] Fix phan --- htdocs/core/modules/project/modules_project.php | 8 ++++---- htdocs/core/modules/project/task/modules_task.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/project/modules_project.php b/htdocs/core/modules/project/modules_project.php index f0f8bdf6cb1..26ffc207484 100644 --- a/htdocs/core/modules/project/modules_project.php +++ b/htdocs/core/modules/project/modules_project.php @@ -68,10 +68,10 @@ abstract class ModelePDFProjects extends CommonDocGenerator /** * Function to build pdf project onto disk * - * @param Task $object Object source to build document - * @param Translate $outputlangs Lang output object - * @param string $srctemplatepath Full path of source filename for generator using a template file - * @return int<-1,1> 1 if OK, <=0 if KO + * @param Project $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @return int<-1,1> 1 if OK, <=0 if KO */ abstract public function write_file($object, $outputlangs, $srctemplatepath = ''); // phpcs:enable diff --git a/htdocs/core/modules/project/task/modules_task.php b/htdocs/core/modules/project/task/modules_task.php index 4bc906f6fae..5409b887914 100644 --- a/htdocs/core/modules/project/task/modules_task.php +++ b/htdocs/core/modules/project/task/modules_task.php @@ -60,7 +60,7 @@ abstract class ModelePDFTask extends CommonDocGenerator /** * Function to build a document on disk using the generic odt module. * - * @param Project $object Object source to build document + * @param Task $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @return int<-1,1> 1 if OK, <=0 if KO From baa6a7928e5fab30d1e7f8b5702a30eb3fab39bd Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 14:38:28 +0100 Subject: [PATCH 557/602] Fix type --- htdocs/societe/class/societe.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 27fb8fd3c27..21eb8e910d6 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2525,7 +2525,7 @@ class Societe extends CommonObject // Position current discount $sql = "UPDATE ".MAIN_DB_PREFIX."societe "; - $sql .= " SET remise_supplier = '".$this->db->escape($remise)."'"; + $sql .= " SET remise_supplier = ".((float) $remise); $sql .= " WHERE rowid = ".((int) $this->id); $resql = $this->db->query($sql); if (!$resql) { @@ -2574,7 +2574,7 @@ class Societe extends CommonObject global $langs; // Clean parameters - $remise = price2num($remise); + $remise = (float) price2num($remise); $desc = trim($desc); // Check parameters From e57e185ef15e6b12a29cd67e0c075e62b2b75d99 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 7 Feb 2025 14:39:37 +0100 Subject: [PATCH 558/602] Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop --- htdocs/societe/class/societe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 21eb8e910d6..cb7cc1ad018 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2537,7 +2537,7 @@ class Societe extends CommonObject // Writes trace in discount history $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_supplier"; $sql .= " (entity, datec, fk_soc, remise_supplier, note, fk_user_author)"; - $sql .= " VALUES (".((int) $conf->entity).", '".$this->db->idate($now)."', ".((int) $this->id).", '".$this->db->escape($remise)."',"; + $sql .= " VALUES (".((int) $conf->entity).", '".$this->db->idate($now)."', ".((int) $this->id).", ".((float) $remise).","; $sql .= " '".$this->db->escape($note)."',"; $sql .= " ".((int) $user->id); $sql .= ")"; From 96dd84ce8b9a5b9b066f0d1a97d2f228690c4037 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 7 Feb 2025 14:39:50 +0100 Subject: [PATCH 559/602] QUAL add hook "loadDictionaryCache" --- htdocs/core/class/html.form.class.php | 48 ++++++++++++++++++++------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 8772968c774..067a3eeb738 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4304,7 +4304,7 @@ class Form public function load_cache_conditions_paiements() { // phpcs:enable - global $langs; + global $langs, $hookmanager; $num = count($this->cache_conditions_paiements); if ($num > 0) { @@ -4313,7 +4313,9 @@ class Form dol_syslog(__METHOD__, LOG_DEBUG); - $sql = "SELECT rowid, code, libelle as label, deposit_percent"; + $this->cache_conditions_paiements = array(); + + $sql = "SELECT rowid, code, libelle as label, deposit_percent, entity"; $sql .= " FROM " . $this->db->prefix() . 'c_payment_term'; $sql .= " WHERE entity IN (" . getEntity('c_payment_term') . ")"; $sql .= " AND active > 0"; @@ -4328,12 +4330,23 @@ class Form // Si traduction existe, on l'utilise, sinon on prend le libelle par default $label = ($langs->trans("PaymentConditionShort" . $obj->code) != "PaymentConditionShort" . $obj->code ? $langs->trans("PaymentConditionShort" . $obj->code) : ($obj->label != '-' ? $obj->label : '')); - $this->cache_conditions_paiements[$obj->rowid]['code'] = $obj->code; - $this->cache_conditions_paiements[$obj->rowid]['label'] = $label; - $this->cache_conditions_paiements[$obj->rowid]['deposit_percent'] = $obj->deposit_percent; + $this->cache_conditions_paiements[$obj->rowid]['code'] = (string) $obj->code; + $this->cache_conditions_paiements[$obj->rowid]['label'] = (string) $label; + $this->cache_conditions_paiements[$obj->rowid]['deposit_percent'] = (string) $obj->deposit_percent; + $this->cache_conditions_paiements[$obj->rowid]['entity'] = (int) $obj->entity; $i++; } + $parameters = array('context' => 'paymentterm', 'cache_conditions_paiements' => $this->cache_conditions_paiements); + $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters, $obj); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) { + $this->cache_conditions_paiements = array_merge($this->cache_conditions_paiements, $hookmanager->resArray); + } + } else { + $this->cache_conditions_paiements = $hookmanager->resArray; + } + //$this->cache_conditions_paiements=dol_sort_array($this->cache_conditions_paiements, 'label', 'asc', 0, 0, 1); // We use the field sortorder of table return $num; @@ -4534,7 +4547,7 @@ class Form public function load_cache_types_paiements() { // phpcs:enable - global $langs; + global $langs, $hookmanager; $num = count($this->cache_types_paiements); // TODO Use $conf->cache['payment_mode'] instead of $this->cache_types_paiements if ($num > 0) { @@ -4545,7 +4558,7 @@ class Form $this->cache_types_paiements = array(); - $sql = "SELECT id, code, libelle as label, type, active"; + $sql = "SELECT id, code, libelle as label, type, entity, active"; $sql .= " FROM " . $this->db->prefix() . "c_paiement"; $sql .= " WHERE entity IN (" . getEntity('c_paiement') . ")"; @@ -4558,14 +4571,25 @@ class Form // Si traduction existe, on l'utilise, sinon on prend le libelle par default $label = ($langs->transnoentitiesnoconv("PaymentTypeShort" . $obj->code) != "PaymentTypeShort" . $obj->code ? $langs->transnoentitiesnoconv("PaymentTypeShort" . $obj->code) : ($obj->label != '-' ? $obj->label : '')); - $this->cache_types_paiements[$obj->id]['id'] = $obj->id; - $this->cache_types_paiements[$obj->id]['code'] = $obj->code; - $this->cache_types_paiements[$obj->id]['label'] = $label; - $this->cache_types_paiements[$obj->id]['type'] = $obj->type; - $this->cache_types_paiements[$obj->id]['active'] = $obj->active; + $this->cache_types_paiements[$obj->id]['id'] = (int) $obj->id; + $this->cache_types_paiements[$obj->id]['code'] = (string) $obj->code; + $this->cache_types_paiements[$obj->id]['label'] = (string) $label; + $this->cache_types_paiements[$obj->id]['type'] = (int) $obj->type; + $this->cache_types_paiements[$obj->id]['entity'] = (int) $obj->entity; + $this->cache_types_paiements[$obj->id]['active'] = (int) $obj->active; $i++; } + $parameters = array('context' => 'paymenttype', 'cache_types_paiements' => $this->cache_types_paiements); + $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters, $obj); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) { + $this->cache_types_paiements = array_merge($this->cache_types_paiements, $hookmanager->resArray); + } + } else { + $this->cache_types_paiements = $hookmanager->resArray; + } + $this->cache_types_paiements = dol_sort_array($this->cache_types_paiements, 'label', 'asc', 0, 0, 1); return $num; From 8a2eb0824833f28a81154534d9c35001f473276e Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 7 Feb 2025 14:54:05 +0100 Subject: [PATCH 560/602] FXI phan error --- htdocs/core/class/html.form.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 067a3eeb738..de8ff559d11 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4338,7 +4338,7 @@ class Form } $parameters = array('context' => 'paymentterm', 'cache_conditions_paiements' => $this->cache_conditions_paiements); - $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters, $obj); // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters); // Note that $action and $object may have been modified by hook if (empty($reshook)) { if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) { $this->cache_conditions_paiements = array_merge($this->cache_conditions_paiements, $hookmanager->resArray); @@ -4581,7 +4581,7 @@ class Form } $parameters = array('context' => 'paymenttype', 'cache_types_paiements' => $this->cache_types_paiements); - $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters, $obj); // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters); // Note that $action and $object may have been modified by hook if (empty($reshook)) { if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) { $this->cache_types_paiements = array_merge($this->cache_types_paiements, $hookmanager->resArray); From cbe214d9f60f4d7f07ac9b00098de3b2f53c0ef8 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 7 Feb 2025 15:03:58 +0100 Subject: [PATCH 561/602] FIX add $this in $object and remove parameter --- htdocs/core/class/html.form.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index de8ff559d11..520642233a1 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4337,8 +4337,8 @@ class Form $i++; } - $parameters = array('context' => 'paymentterm', 'cache_conditions_paiements' => $this->cache_conditions_paiements); - $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('context' => 'paymentterm'); + $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters, $this); // Note that $action and $object may have been modified by hook if (empty($reshook)) { if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) { $this->cache_conditions_paiements = array_merge($this->cache_conditions_paiements, $hookmanager->resArray); @@ -4580,8 +4580,8 @@ class Form $i++; } - $parameters = array('context' => 'paymenttype', 'cache_types_paiements' => $this->cache_types_paiements); - $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('context' => 'paymenttype'); + $reshook = $hookmanager->executeHooks('loadDictionaryCache', $parameters, $this); // Note that $action and $object may have been modified by hook if (empty($reshook)) { if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) { $this->cache_types_paiements = array_merge($this->cache_types_paiements, $hookmanager->resArray); From be255c72a5378227e0d2cf7deb8886c5eb6a4935 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 7 Feb 2025 15:30:34 +0100 Subject: [PATCH 562/602] FIX travis error --- htdocs/core/class/discount.class.php | 2 +- test/phpunit/DiscountTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index d2234352d4f..131acc5ead5 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -354,7 +354,7 @@ class DiscountAbsolute extends CommonObject $sql .= " ".price2num($this->multicurrency_amount_ht).", ".price2num($this->multicurrency_amount_tva).", ".price2num($this->multicurrency_amount_ttc).", "; $sql .= " ".($this->fk_facture_source ? ((int) $this->fk_facture_source) : "null").","; $sql .= " ".($this->fk_invoice_supplier_source ? ((int) $this->fk_invoice_supplier_source) : "null").","; - $sql .= " '".($this->multicurrency_code ? $this->multicurrency_code : "null")."',"; + $sql .= " ".($this->multicurrency_code ? "'".$this->multicurrency_code."'" : "null").","; $sql .= " ".($this->multicurrency_tx ? price2num($this->multicurrency_tx) : "null"); $sql .= ")"; diff --git a/test/phpunit/DiscountTest.php b/test/phpunit/DiscountTest.php index e7ed4908d8a..530d6f8eff2 100644 --- a/test/phpunit/DiscountTest.php +++ b/test/phpunit/DiscountTest.php @@ -69,7 +69,7 @@ class DiscountTest extends CommonClassTest $localobject = new DiscountAbsolute($db); $localobject->initAsSpecimen(); - $localobject->fk_soc = $socid; + $localobject->socid = $socid; $result = $localobject->create($user); $this->assertLessThan($result, 0); From 59c3d3a0efe12382a70b53e6c681f768af08c607 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 7 Feb 2025 15:40:17 +0100 Subject: [PATCH 563/602] FIX missing escape --- htdocs/core/class/discount.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 131acc5ead5..dfdac04b9a4 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -354,7 +354,7 @@ class DiscountAbsolute extends CommonObject $sql .= " ".price2num($this->multicurrency_amount_ht).", ".price2num($this->multicurrency_amount_tva).", ".price2num($this->multicurrency_amount_ttc).", "; $sql .= " ".($this->fk_facture_source ? ((int) $this->fk_facture_source) : "null").","; $sql .= " ".($this->fk_invoice_supplier_source ? ((int) $this->fk_invoice_supplier_source) : "null").","; - $sql .= " ".($this->multicurrency_code ? "'".$this->multicurrency_code."'" : "null").","; + $sql .= " ".($this->multicurrency_code ? "'".$this->db->escape($this->multicurrency_code)."'" : "null").","; $sql .= " ".($this->multicurrency_tx ? price2num($this->multicurrency_tx) : "null"); $sql .= ")"; From f3e7e69107839db2e60d2853a6aa42f582b2294d Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 7 Feb 2025 16:26:26 +0100 Subject: [PATCH 564/602] FIX travis error --- htdocs/core/class/discount.class.php | 2 +- test/phpunit/DiscountTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index d2234352d4f..dfdac04b9a4 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -354,7 +354,7 @@ class DiscountAbsolute extends CommonObject $sql .= " ".price2num($this->multicurrency_amount_ht).", ".price2num($this->multicurrency_amount_tva).", ".price2num($this->multicurrency_amount_ttc).", "; $sql .= " ".($this->fk_facture_source ? ((int) $this->fk_facture_source) : "null").","; $sql .= " ".($this->fk_invoice_supplier_source ? ((int) $this->fk_invoice_supplier_source) : "null").","; - $sql .= " '".($this->multicurrency_code ? $this->multicurrency_code : "null")."',"; + $sql .= " ".($this->multicurrency_code ? "'".$this->db->escape($this->multicurrency_code)."'" : "null").","; $sql .= " ".($this->multicurrency_tx ? price2num($this->multicurrency_tx) : "null"); $sql .= ")"; diff --git a/test/phpunit/DiscountTest.php b/test/phpunit/DiscountTest.php index e7ed4908d8a..530d6f8eff2 100644 --- a/test/phpunit/DiscountTest.php +++ b/test/phpunit/DiscountTest.php @@ -69,7 +69,7 @@ class DiscountTest extends CommonClassTest $localobject = new DiscountAbsolute($db); $localobject->initAsSpecimen(); - $localobject->fk_soc = $socid; + $localobject->socid = $socid; $result = $localobject->create($user); $this->assertLessThan($result, 0); From ce2f46379a360f11fcb7a0331cf317afad4dd4c2 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Fri, 7 Feb 2025 16:52:46 +0100 Subject: [PATCH 565/602] NEW shipment with product in cache --- htdocs/expedition/card.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index a19523f9d7b..0802d1b9b32 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2409,6 +2409,7 @@ if ($action == 'create') { print ''; // Loop on each product to send/sent + $conf->cache['product'] = array(); for ($i = 0; $i < $num_prod; $i++) { $parameters = array('i' => $i, 'line' => $lines[$i], 'line_id' => $line_id, 'num' => $num_prod, 'alreadysent' => $alreadysent, 'editColspan' => !empty($editColspan) ? $editColspan : 0, 'outputlangs' => $outputlangs); $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $object, $action); @@ -2429,8 +2430,14 @@ if ($action == 'create') { if ($lines[$i]->fk_product > 0) { // Define output language if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) { - $prod = new Product($db); - $prod->fetch($lines[$i]->fk_product); + $product_id = $lines[$i]->fk_product; + if (!isset($conf->cache['product'][$product_id])) { + $prod = new Product($db); + $prod->fetch($product_id); + $conf->cache['product'][$product_id] = $prod; + } else { + $prod = $conf->cache['product'][$product_id]; + } $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["label"])) ? $prod->multilangs[$outputlangs->defaultlang]["label"] : $lines[$i]->product_label; } else { $label = (!empty($lines[$i]->label) ? $lines[$i]->label : $lines[$i]->product_label); From 936311ff27a7ff206324e5d87b92b0efadab3af0 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 7 Feb 2025 23:49:57 +0100 Subject: [PATCH 566/602] FIX try to fix phpstan error --- htdocs/core/class/html.form.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 520642233a1..149e23b3f9f 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4375,6 +4375,8 @@ class Form dol_syslog(__METHOD__, LOG_DEBUG); + $this->cache_availability = array(); + $langs->load('propal'); $sql = "SELECT rowid, code, label, position"; From 395fdbf39bfd25e5a3a335b02f7d1ba7ea964977 Mon Sep 17 00:00:00 2001 From: MDW Date: Thu, 6 Feb 2025 22:16:48 +0100 Subject: [PATCH 567/602] Qual: Fix phan notices (mrp) --- dev/tools/phan/baseline.txt | 26 +++-------- htdocs/admin/mrp.php | 13 +++--- .../modules/mrp/doc/pdf_vinci.modules.php | 6 +-- htdocs/mrp/ajax/ajax_bom.php | 3 +- htdocs/mrp/class/api_mos.class.php | 42 +++++++++++------- htdocs/mrp/class/mo.class.php | 10 ++--- htdocs/mrp/class/moline.class.php | 4 +- htdocs/mrp/index.php | 5 ++- htdocs/mrp/mo_agenda.php | 4 +- htdocs/mrp/mo_card.php | 16 +++---- htdocs/mrp/mo_document.php | 3 +- htdocs/mrp/mo_list.php | 41 ++++++++--------- htdocs/mrp/mo_movements.php | 44 +++++++++---------- htdocs/mrp/mo_note.php | 3 +- htdocs/mrp/mo_production.php | 22 +++++----- htdocs/mrp/tpl/linkedobjectblock.tpl.php | 4 +- htdocs/mrp/tpl/originproductline.tpl.php | 12 +++-- .../stock/class/mouvementstock.class.php | 12 ++--- 18 files changed, 140 insertions(+), 130 deletions(-) diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 0da0c9a1237..dcfbfa73dda 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -9,11 +9,11 @@ */ return [ // # Issue statistics: - // PhanTypeMismatchArgument : 2490+ occurrences + // PhanTypeMismatchArgument : 2450+ occurrences // PhanUndeclaredProperty : 530+ occurrences // PhanTypeMismatchArgumentNullable : 430+ occurrences // PhanUndeclaredGlobalVariable : 190+ occurrences - // PhanPluginUnknownArrayMethodReturnType : 180+ occurrences + // PhanPluginUnknownArrayMethodReturnType : 170+ occurrences // PhanPossiblyUndeclaredGlobalVariable : 160+ occurrences // PhanTypeMismatchProperty : 130+ occurrences // PhanTypeMismatchArgumentProbablyReal : 120+ occurrences @@ -27,8 +27,8 @@ return [ // PhanUndeclaredConstant : 15+ occurrences // PhanTypeComparisonFromArray : 10+ occurrences // PhanUndeclaredMethod : 10+ occurrences - // PhanPluginUnknownObjectMethodCall : 8 occurrences // PhanPluginSuspiciousParamPosition : 7 occurrences + // PhanPluginUnknownObjectMethodCall : 7 occurrences // PhanPluginDuplicateExpressionBinaryOp : 6 occurrences // PhanPluginEmptyStatementIf : 6 occurrences // PhanTypeArraySuspiciousNull : 6 occurrences @@ -123,7 +123,6 @@ return [ 'htdocs/admin/mails_templates.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/admin/mails_ticket.php' => ['PhanTypeMismatchArgumentNullable'], 'htdocs/admin/menus/index.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/mrp.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/multicurrency.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/order.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/payment.php' => ['PhanTypeMismatchArgument'], @@ -466,7 +465,7 @@ return [ 'htdocs/core/modules/modSupplierProposal.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/modTicket.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/movement/doc/pdf_standard_movementstock.modules.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/mrp/mod_mo_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/oauth/github_oauthcallback.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php' => ['PhanTypeMismatchArgument'], @@ -608,20 +607,9 @@ return [ 'htdocs/loan/document.php' => ['PhanUndeclaredProperty'], 'htdocs/loan/note.php' => ['PhanUndeclaredProperty'], 'htdocs/loan/payment/payment.php' => ['PhanUndeclaredProperty'], - 'htdocs/mrp/ajax/ajax_bom.php' => ['PhanTypeMismatchArgument'], - 'htdocs/mrp/class/api_mos.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgument'], - 'htdocs/mrp/class/mo.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchProperty'], - 'htdocs/mrp/class/moline.class.php' => ['PhanTypeMismatchArgument'], - 'htdocs/mrp/index.php' => ['PhanTypeMismatchArgument'], - 'htdocs/mrp/mo_agenda.php' => ['PhanTypeMismatchArgument'], - 'htdocs/mrp/mo_card.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/mrp/mo_document.php' => ['PhanTypeMismatchArgument'], - 'htdocs/mrp/mo_list.php' => ['PhanTypeMismatchArgument'], - 'htdocs/mrp/mo_movements.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanTypeMismatchArgument', 'PhanUndeclaredGlobalVariable'], - 'htdocs/mrp/mo_note.php' => ['PhanTypeMismatchArgument'], - 'htdocs/mrp/mo_production.php' => ['PhanTypeMismatchArgument'], - 'htdocs/mrp/tpl/linkedobjectblock.tpl.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], - 'htdocs/mrp/tpl/originproductline.tpl.php' => ['PhanUndeclaredProperty'], + 'htdocs/mrp/class/mo.class.php' => ['PhanTypeMismatchProperty'], + 'htdocs/mrp/mo_movements.php' => ['PhanUndeclaredGlobalVariable'], + 'htdocs/mrp/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'], 'htdocs/multicurrency/class/api_multicurrencies.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgument'], 'htdocs/multicurrency/class/multicurrency.class.php' => ['PhanTypeExpectedObjectPropAccess', 'PhanTypeMismatchArgument'], 'htdocs/multicurrency/multicurrency_rate.php' => ['PhanTypeMismatchArgument'], diff --git a/htdocs/admin/mrp.php b/htdocs/admin/mrp.php index 0b343459e3d..bc5a9c33f4d 100644 --- a/htdocs/admin/mrp.php +++ b/htdocs/admin/mrp.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -35,7 +35,6 @@ require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp.lib.php'; * @var Conf $conf * @var DoliDB $db * @var HookManager $hookmanager - * @var Societe $mysoc * @var Translate $langs * @var User $user */ @@ -263,13 +262,15 @@ foreach ($dirmodels as $reldir) { $mrp = new Mo($db); $mrp->initAsSpecimen(); + $product = new Product($db); + $product->initAsSpecimen(); // Info $htmltooltip = ''; $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; $mrp->type = 0; - $nextval = $module->getNextValue($mysoc, $mrp); - if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $nextval = $module->getNextValue($product, $mrp); + if ((string) $nextval != $langs->trans("NotAvailable")) { $htmltooltip .= ''.$langs->trans("NextValue").': '; if ($nextval) { if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') { @@ -282,7 +283,7 @@ foreach ($dirmodels as $reldir) { } print '
'; print "\n"; @@ -417,7 +418,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php b/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php index 8dcb13bcfb9..7a102ff9649 100644 --- a/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php +++ b/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php @@ -543,7 +543,7 @@ class pdf_vinci extends ModelePDFMo // Enough for 6 chars if ($this->getColumnStatus('qty')) { $qty = $bom->lines[$i]->qty; - $this->printStdColumnContent($pdf, $curY, 'qty', $qty); + $this->printStdColumnContent($pdf, $curY, 'qty', (string) $qty); $nexY = max($pdf->GetY(), $nexY); } @@ -551,7 +551,7 @@ class pdf_vinci extends ModelePDFMo // Enough for 6 chars if ($this->getColumnStatus('qtytot')) { $qtytot = $object->qty * $bom->lines[$i]->qty; - $this->printStdColumnContent($pdf, $curY, 'qtytot', $qtytot); + $this->printStdColumnContent($pdf, $curY, 'qtytot', (string) $qtytot); $nexY = max($pdf->GetY(), $nexY); } @@ -1108,7 +1108,7 @@ class pdf_vinci extends ModelePDFMo $pdf->SetFont('', 'B', $default_font_size + 3); $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); - $pdf->MultiCell($w, 3, html_entity_decode($prodToMake->description), '', 'R', false, 1, '', '', true, 0, false, true, 51, 'T', true); + $pdf->MultiCell($w, 3, html_entity_decode($prodToMake->description), '', 'R', false, 1, null, null, true, 0, false, true, 51, 'T', true); $posy = $pdf->GetY() - 5; // dimensions diff --git a/htdocs/mrp/ajax/ajax_bom.php b/htdocs/mrp/ajax/ajax_bom.php index 5fc84d5e76e..500018293af 100644 --- a/htdocs/mrp/ajax/ajax_bom.php +++ b/htdocs/mrp/ajax/ajax_bom.php @@ -1,6 +1,7 @@ * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -52,7 +53,7 @@ require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; * @var User $user */ -$idbom = GETPOST('idbom', 'alpha'); +$idbom = GETPOSTINT('idbom'); //$action = GETPOST('action', 'aZ09'); $object = new BOM($db); diff --git a/htdocs/mrp/class/api_mos.class.php b/htdocs/mrp/class/api_mos.class.php index 7b267902f66..df79b76fdb6 100644 --- a/htdocs/mrp/class/api_mos.class.php +++ b/htdocs/mrp/class/api_mos.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2019 Maxime Kohlhaas - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -38,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php'; class Mos extends DolibarrApi { /** - * @var Mo $mo {@type Mo} + * @var Mo {@type Mo} */ public $mo; @@ -94,6 +94,8 @@ class Mos extends DolibarrApi * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names * @return array Array of order objects + * @phan-return Mo[] + * @phpstan-return Mo[] * * @throws RestException */ @@ -175,6 +177,8 @@ class Mos extends DolibarrApi * Create MO object * * @param array $request_data Request datas + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return int ID of MO */ public function post($request_data = null) @@ -208,6 +212,8 @@ class Mos extends DolibarrApi * * @param int $id Id of MO to update * @param array $request_data Datas + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * @return Object Updated object */ public function put($id, $request_data = null) @@ -259,6 +265,8 @@ class Mos extends DolibarrApi * * @param int $id MO ID * @return array + * @phan-return array + * @phpstan-return array */ public function delete($id) { @@ -312,6 +320,8 @@ class Mos extends DolibarrApi * * @param int $id ID of state * @param array $request_data Request datas + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * * @url POST {id}/produceandconsumeall * @@ -431,7 +441,7 @@ class Mos extends DolibarrApi $error++; throw new RestException(500, $moline->error); } - $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $value["objectid"], $value["fk_warehouse"], $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $value["objectid"], $value["fk_warehouse"], $qtytoprocess, 0, $labelmovement, dol_now(), '', '', (string) $tmpproduct->status_batch, $id_product_batch, $codemovement); } else { $moline = new MoLine($this->db); $moline->fk_mo = $this->mo->id; @@ -450,7 +460,7 @@ class Mos extends DolibarrApi $error++; throw new RestException(500, $moline->error); } - $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $value["objectid"], $value["fk_warehouse"], $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $value["objectid"], $value["fk_warehouse"], $qtytoprocess, 0, $labelmovement, '', '', (string) $tmpproduct->status_batch, dol_now(), $id_product_batch, $codemovement); } if ($idstockmove < 0) { $error++; @@ -519,9 +529,9 @@ class Mos extends DolibarrApi $stockmove->origin_type = 'mo'; $stockmove->origin_id = $this->mo->id; if ($qtytoprocess >= 0) { - $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', (string) $tmpproduct->status_batch, $id_product_batch, $codemovement); } else { - $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, '', '', (string) $tmpproduct->status_batch, dol_now(), $id_product_batch, $codemovement); } if ($idstockmove < 0) { $error++; @@ -579,9 +589,9 @@ class Mos extends DolibarrApi $stockmove->origin_type = 'mo'; $stockmove->origin_id = $this->mo->id; if ($qtytoprocess >= 0) { - $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, '', '', (string) $tmpproduct->status_batch, dol_now(), $id_product_batch, $codemovement); } else { - $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', (string) $tmpproduct->status_batch, $id_product_batch, $codemovement); } if ($idstockmove < 0) { $error++; @@ -688,6 +698,8 @@ class Mos extends DolibarrApi * * @param int $id ID of state * @param array $request_data Request datas + * @phan-param ?array $request_data + * @phpstan-param ?array $request_data * * @url POST {id}/produceandconsume * @@ -803,15 +815,15 @@ class Mos extends DolibarrApi $stockmove->origin_id = $this->mo->id; if ($arrayname == "arraytoconsume") { if ($qtytoprocess >= 0) { - $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', (string) $tmpproduct->status_batch, $id_product_batch, $codemovement); } else { - $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement, '', '', (string) $tmpproduct->status_batch, dol_now(), $id_product_batch, $codemovement); } } else { if ($qtytoprocess >= 0) { - $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, $pricetoproduce, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, $pricetoproduce, $labelmovement, '', '', (string) $tmpproduct->status_batch, dol_now(), $id_product_batch, $codemovement); } else { - $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); + $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', (string) $tmpproduct->status_batch, $id_product_batch, $codemovement); } } if ($idstockmove <= 0) { @@ -962,10 +974,10 @@ class Mos extends DolibarrApi } /** - * Validate fields before create or update object + * Validate fields before creating or updating an object * - * @param array $data Array of data to validate - * @return array + * @param ?array $data Data to validate + * @return array * * @throws RestException */ diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index afbd022789f..86f72c71d2b 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -537,7 +537,7 @@ class Mo extends CommonObject if ($key == 't.rowid') { $sqlwhere[] = $this->db->sanitize($key)." = ".((int) $value); } elseif (strpos($key, 'date') !== false) { - $sqlwhere[] = $this->db->sanitize($key)." = '".$this->db->idate($value)."'"; + $sqlwhere[] = $this->db->sanitize($key)." = '".$this->db->idate((int) $value)."'"; } else { $sqlwhere[] = $this->db->sanitize($key)." LIKE '%".$this->db->escape($this->db->escapeforlike($value))."%'"; } @@ -768,7 +768,7 @@ class Mo extends CommonObject } } - $resultline = $moline->create($user, false); // Never use triggers here + $resultline = $moline->create($user, 0); // Never use triggers here if ($resultline <= 0) { $error++; $this->error = $moline->error; @@ -808,7 +808,7 @@ class Mo extends CommonObject $moline->fk_default_workstation = $line->fk_default_workstation; } - $resultline = $moline->create($user, false); // Never use triggers here + $resultline = $moline->create($user, 0); // Never use triggers here if ($resultline <= 0) { $error++; $this->error = $moline->error; @@ -1747,9 +1747,9 @@ class Mo extends CommonObject // Qty print ''; - print ''; + print ''; print ''; print ''; print ''; @@ -263,7 +264,7 @@ if ($resql) { $staticmo->status = $obj->status; print ''; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/mrp/mo_agenda.php b/htdocs/mrp/mo_agenda.php index bbff7b188f3..b657aa4b124 100644 --- a/htdocs/mrp/mo_agenda.php +++ b/htdocs/mrp/mo_agenda.php @@ -2,7 +2,7 @@ /* Copyright (C) 2017 Laurent Destailleur * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -180,7 +180,7 @@ if ($object->id > 0) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index 69c26b9f185..cd97ddf76be 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -1,7 +1,7 @@ * Copyright (C) 2024 Alexandre Spangaro - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -170,7 +170,7 @@ if (empty($reshook)) { $objectbomchildline->fetch($id_bom_line); - $TMoLines = $moline->fetchAll('DESC', 'rowid', '1', '', array('origin_id' => $id_bom_line)); + $TMoLines = $moline->fetchAll('DESC', 'rowid', 1, 0, array('origin_id' => $id_bom_line)); foreach ($TMoLines as $tmpmoline) { $_POST['fk_bom'] = $objectbomchildline->fk_bom_child; @@ -188,7 +188,7 @@ if (empty($reshook)) { exit; } elseif ($action == 'confirm_cancel' && $confirm == 'yes' && !empty($permissiontoadd)) { $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0); - $result = $object->cancel($user, 0, $also_cancel_consumed_and_produced_lines); + $result = $object->cancel($user, 0, (bool) $also_cancel_consumed_and_produced_lines); if ($result > 0) { header("Location: " . dol_buildpath('/mrp/mo_card.php?id=' . $object->id, 1)); exit; @@ -198,7 +198,7 @@ if (empty($reshook)) { } } elseif ($action == 'confirm_delete' && $confirm == 'yes' && !empty($permissiontodelete)) { $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0); - $result = $object->delete($user, 0, $also_cancel_consumed_and_produced_lines); + $result = $object->delete($user, 0, (bool) $also_cancel_consumed_and_produced_lines); if ($result > 0) { header("Location: " . $backurlforlist); exit; @@ -342,9 +342,9 @@ $help_url = 'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication|DE:M llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-mrp page-card'); - // Part to create if ($action == 'create') { + $titlelist = null; if (GETPOSTINT('fk_bom') > 0) { $titlelist = $langs->trans("ToConsume"); if ($objectbom->bomtype == 1) { @@ -439,7 +439,7 @@ if ($action == 'create') { print $form->buttonsSaveCancel("Create"); if ($objectbom->id > 0) { - print load_fiche_titre($titlelist); + print load_fiche_titre((string) $titlelist); print ''."\n"; print '
'; @@ -642,7 +642,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); @@ -873,7 +873,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $htmltoenteralink = $tmparray['htmltoenteralink']; print $htmltoenteralink; - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, false); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, array()); print '
'; diff --git a/htdocs/mrp/mo_document.php b/htdocs/mrp/mo_document.php index 9e5219d316f..b4e950d82e0 100644 --- a/htdocs/mrp/mo_document.php +++ b/htdocs/mrp/mo_document.php @@ -2,6 +2,7 @@ /* Copyright (C) 2007-2017 Laurent Destailleur * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro + * Copyright (C) 2025 MDW * * 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 @@ -156,7 +157,7 @@ if ($object->id) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); diff --git a/htdocs/mrp/mo_list.php b/htdocs/mrp/mo_list.php index ea434e1187e..da3b60f5033 100644 --- a/htdocs/mrp/mo_list.php +++ b/htdocs/mrp/mo_list.php @@ -2,6 +2,7 @@ /* Copyright (C) 2007-2017 Laurent Destailleur * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -122,22 +123,22 @@ foreach ($object->fields as $key => $val) { if (!empty($val['visible'])) { $visible = (int) dol_eval((string) $val['visible'], 1); $arrayfields['t.'.$key] = array( - 'label'=>$val['label'], - 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>(abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)), - 'position'=>$val['position'], - 'help'=> isset($val['help']) ? $val['help'] : '' + 'label' => $val['label'], + 'checked' => (($visible < 0) ? 0 : 1), + 'enabled' => (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)), + 'position' => $val['position'], + 'help' => isset($val['help']) ? $val['help'] : '' ); } if ($key == 'fk_parent_line') { $visible = (int) dol_eval((string) $val['visible'], 1); $arrayfields['t.'.$key] = array( - 'label'=>$val['label'], - 'checked'=>(($visible <= 0) ? 0 : 1), - 'enabled'=>(abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)), - 'position'=>$val['position'], - 'help'=> isset($val['help']) ? $val['help'] : '' + 'label' => $val['label'], + 'checked' => (($visible <= 0) ? 0 : 1), + 'enabled' => (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)), + 'position' => $val['position'], + 'help' => isset($val['help']) ? $val['help'] : '' ); } } @@ -270,7 +271,7 @@ foreach ($search as $key => $val) { } if ($key == 'status') { - $sql .= natural_search('t.status', $search[$key], 0); + $sql .= natural_search('t.status', (string) $search[$key], 0); continue; } @@ -445,8 +446,8 @@ print ''; print ''; $newcardbutton = ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); -$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition')); $newcardbutton .= dolGetButtonTitleSeparator(); $newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/mrp/mo_card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); @@ -545,7 +546,7 @@ foreach ($object->fields as $key => $val) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook -$parameters = array('arrayfields'=>$arrayfields); +$parameters = array('arrayfields' => $arrayfields); $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column @@ -659,7 +660,7 @@ while ($i < $imaxinloop) { $selected = 1; } } - print $object->getKanbanView('', array('bom'=>($obj->fk_bom > 0 ? $bom : null), 'product'=>($obj->fk_product > 0 ? $product : null), 'selected' => $selected)); + print $object->getKanbanView('', array('bom' => ($obj->fk_bom > 0 ? $bom : null), 'product' => ($obj->fk_product > 0 ? $product : null), 'selected' => $selected)); if ($i == ($imaxinloop - 1)) { print '
'; print ''; @@ -708,7 +709,7 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['t.'.$key]['checked'])) { print '$key)) { - print ' title="'.dol_escape_htmltag($object->$key).'"'; + print ' title="'.dol_escape_htmltag((string) $object->$key).'"'; } print '>'; if ($key == 'status') { @@ -719,9 +720,9 @@ while ($i < $imaxinloop) { print $moparent->getNomUrl(1); } } elseif ($key == 'rowid') { - print $object->showOutputField($val, $key, $object->id, ''); + print $object->showOutputField($val, $key, (string) $object->id, ''); } else { - print $object->showOutputField($val, $key, $object->$key, ''); + print $object->showOutputField($val, $key, (string) $object->$key, ''); } print ''; if (!$i) { @@ -744,7 +745,7 @@ while ($i < $imaxinloop) { // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $parameters = array('arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; @@ -787,7 +788,7 @@ if ($num == 0) { $db->free($resql); -$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql); $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; diff --git a/htdocs/mrp/mo_movements.php b/htdocs/mrp/mo_movements.php index 5120d8a3c98..fabcca4d0e1 100644 --- a/htdocs/mrp/mo_movements.php +++ b/htdocs/mrp/mo_movements.php @@ -3,7 +3,7 @@ * Copyright (C) 2022 Ferran Marcet * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -130,24 +130,24 @@ $objectlist = new MouvementStock($db); // Definition of fields for list $arrayfields = array( - 'm.rowid' => array('label' => "Ref", 'checked' => 1, 'position' => 1), - 'm.datem' => array('label' => "Date", 'checked' => 1, 'position' => 2), - 'p.ref' => array('label' => "ProductRef", 'checked' => 1, 'css' => 'maxwidth100', 'position' => 3), - 'p.label' => array('label' => "ProductLabel", 'checked' => 0, 'position' => 5), - 'm.batch' => array('label' => "BatchNumberShort", 'checked' => 1, 'position' => 8, 'enabled' => (isModEnabled('productbatch'))), - 'pl.eatby' => array('label' => "EatByDate", 'checked' => 0, 'position' => 9, 'enabled' => (isModEnabled('productbatch'))), - 'pl.sellby' => array('label' => "SellByDate", 'checked' => 0, 'position' => 10, 'enabled' => (isModEnabled('productbatch'))), - 'e.ref' => array('label' => "Warehouse", 'checked' => 1, 'position' => 100, 'enabled' => (!($id > 0))), // If we are on specific warehouse, we hide it - 'm.fk_user_author' => array('label' => "Author", 'checked' => 0, 'position' => 120), - 'm.inventorycode' => array('label' => "InventoryCodeShort", 'checked' => 1, 'position' => 130), - 'm.label' => array('label' => "MovementLabel", 'checked' => 1, 'position' => 140), - 'm.type_mouvement' => array('label' => "TypeMovement", 'checked' => 0, 'position' => 150), - 'origin' => array('label' => "Origin", 'checked' => 1, 'position' => 155), - 'm.fk_projet' => array('label' => 'Project', 'checked' => 0, 'position' => 180), - 'm.value' => array('label' => "Qty", 'checked' => 1, 'position' => 200), - 'm.price' => array('label' => "UnitPurchaseValue", 'checked' => 0, 'position' => 210) - //'m.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), - //'m.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500) + 'm.rowid' => array('label' => "Ref", 'checked' => '1', 'position' => 1), + 'm.datem' => array('label' => "Date", 'checked' => '1', 'position' => 2), + 'p.ref' => array('label' => "ProductRef", 'checked' => '1', 'css' => 'maxwidth100', 'position' => 3), + 'p.label' => array('label' => "ProductLabel", 'checked' => '0', 'position' => 5), + 'm.batch' => array('label' => "BatchNumberShort", 'checked' => '1', 'position' => 8, 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'pl.eatby' => array('label' => "EatByDate", 'checked' => '0', 'position' => 9, 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'pl.sellby' => array('label' => "SellByDate", 'checked' => '0', 'position' => 10, 'enabled' => (string) (int) (isModEnabled('productbatch'))), + 'e.ref' => array('label' => "Warehouse", 'checked' => '1', 'position' => 100, 'enabled' => (string) (int) (!($id > 0))), // If we are on specific warehouse, we hide it + 'm.fk_user_author' => array('label' => "Author", 'checked' => '0', 'position' => 120), + 'm.inventorycode' => array('label' => "InventoryCodeShort", 'checked' => '1', 'position' => 130), + 'm.label' => array('label' => "MovementLabel", 'checked' => '1', 'position' => 140), + 'm.type_mouvement' => array('label' => "TypeMovement", 'checked' => '0', 'position' => 150), + 'origin' => array('label' => "Origin", 'checked' => '1', 'position' => 155), + 'm.fk_projet' => array('label' => 'Project', 'checked' => '0', 'position' => 180), + 'm.value' => array('label' => "Qty", 'checked' => '1', 'position' => 200), + 'm.price' => array('label' => "UnitPurchaseValue", 'checked' => '0', 'position' => 210) + //'m.datec'=>array('label'=>"DateCreation", 'checked'=>'0', 'position'=>500), + //'m.tms'=>array('label'=>"DateModificationShort", 'checked'=>'0', 'position'=>500) ); if (getDolGlobalString('PRODUCT_DISABLE_SELLBY')) { unset($arrayfields['pl.sellby']); @@ -169,7 +169,7 @@ $permissiontoproduce = $permissiontoadd; $permissiontoupdatecost = $user->hasRight('bom', 'write'); // User who can define cost must have knowledge of pricing if ($permissiontoupdatecost) { - $arrayfields['m.price']['enabled'] = 1; + $arrayfields['m.price']['enabled'] = '1'; } $arrayofselected = array(); @@ -360,7 +360,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); @@ -1016,7 +1016,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // fk_project print '
'; } diff --git a/htdocs/mrp/mo_note.php b/htdocs/mrp/mo_note.php index 304457df234..c2ba92da2ca 100644 --- a/htdocs/mrp/mo_note.php +++ b/htdocs/mrp/mo_note.php @@ -2,6 +2,7 @@ /* Copyright (C) 2007-2017 Laurent Destailleur * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro + * Copyright (C) 2025 MDW * * 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 @@ -133,7 +134,7 @@ if ($id > 0 || !empty($ref)) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index bf68267ee2b..53d383ba51a 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -3,7 +3,7 @@ * Copyright (C) 2023 Christian Humpel * Copyright (C) 2023 Vincent de Grandpré * Copyright (C) 2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify @@ -142,7 +142,7 @@ if (empty($reshook)) { if ($action == 'confirm_cancel' && $confirm == 'yes' && !empty($permissiontoadd)) { $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0); - $result = $object->cancel($user, 0, $also_cancel_consumed_and_produced_lines); + $result = $object->cancel($user, 0, (bool) $also_cancel_consumed_and_produced_lines); if ($result > 0) { header("Location: " . DOL_URL_ROOT.'/mrp/mo_card.php?id=' . $object->id); exit; @@ -152,7 +152,7 @@ if (empty($reshook)) { } } elseif ($action == 'confirm_delete' && $confirm == 'yes' && !empty($permissiontodelete)) { $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0); - $result = $object->delete($user, 0, $also_cancel_consumed_and_produced_lines); + $result = $object->delete($user, 0, (bool) $also_cancel_consumed_and_produced_lines); if ($result > 0) { header("Location: " . $backurlforlist); exit; @@ -244,7 +244,7 @@ if (empty($reshook)) { $moline->array_options = $array_options; } - $resultline = $moline->create($user, false); // Never use triggers here + $resultline = $moline->create($user, 0); // Never use triggers here if ($resultline <= 0) { $error++; setEventMessages($moline->error, $moline->errors, 'errors'); @@ -297,9 +297,9 @@ if (empty($reshook)) { $stockmove->context['mrp_role'] = 'toconsume'; if ($qtytoprocess >= 0) { - $idstockmove = $stockmove->livraison($user, $line->fk_product, GETPOST('idwarehouse-'.$line->id.'-'.$i), $qtytoprocess, 0, $labelmovement, dol_now(), '', '', GETPOST('batch-'.$line->id.'-'.$i), $id_product_batch, $codemovement); + $idstockmove = $stockmove->livraison($user, $line->fk_product, GETPOSTINT('idwarehouse-'.$line->id.'-'.$i), $qtytoprocess, 0, $labelmovement, dol_now(), '', '', GETPOST('batch-'.$line->id.'-'.$i), $id_product_batch, $codemovement); } else { - $idstockmove = $stockmove->reception($user, $line->fk_product, GETPOST('idwarehouse-'.$line->id.'-'.$i), $qtytoprocess * -1, 0, $labelmovement, dol_now(), '', '', GETPOST('batch-'.$line->id.'-'.$i), $id_product_batch, $codemovement); + $idstockmove = $stockmove->reception($user, $line->fk_product, GETPOSTINT('idwarehouse-'.$line->id.'-'.$i), $qtytoprocess * -1, 0, $labelmovement, dol_now(), '', '', GETPOST('batch-'.$line->id.'-'.$i), $id_product_batch, $codemovement); } if ($idstockmove < 0) { $error++; @@ -372,7 +372,7 @@ if (empty($reshook)) { $stockmove->origin_id = $object->id; $stockmove->context['mrp_role'] = 'toproduce'; - $idstockmove = $stockmove->reception($user, $line->fk_product, GETPOST('idwarehousetoproduce-'.$line->id.'-'.$i), $qtytoprocess, $pricetoprocess, $labelmovement, '', '', GETPOST('batchtoproduce-'.$line->id.'-'.$i), dol_now(), $id_product_batch, $codemovement); + $idstockmove = $stockmove->reception($user, $line->fk_product, GETPOSTINT('idwarehousetoproduce-'.$line->id.'-'.$i), $qtytoprocess, $pricetoprocess, $labelmovement, '', '', GETPOST('batchtoproduce-'.$line->id.'-'.$i), dol_now(), $id_product_batch, $codemovement); if ($idstockmove < 0) { $error++; setEventMessages($stockmove->error, $stockmove->errors, 'errors'); @@ -680,7 +680,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); @@ -986,7 +986,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Extrafields Line if (is_object($objectline)) { $extrafields->fetch_name_optionals_label($object->table_element_line); - $temps = $objectline->showOptionals($extrafields, 'edit', array(), '', '', 1, 'line'); + $temps = $objectline->showOptionals($extrafields, 'edit', array(), '', '', '1', 'line'); if (!empty($temps)) { print ''; echo ''; diff --git a/htdocs/mrp/tpl/originproductline.tpl.php b/htdocs/mrp/tpl/originproductline.tpl.php index 7b6a0436080..9b61917fe86 100644 --- a/htdocs/mrp/tpl/originproductline.tpl.php +++ b/htdocs/mrp/tpl/originproductline.tpl.php @@ -1,7 +1,7 @@ * Copyright (C) 2017 Charlie Benke - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -22,10 +22,14 @@ * @var CommonObject $this * @var Conf $conf * @var Form $form - * @var MoLine $line + * @var BOMLine $line * @var Translate $langs */ +' +@phan-var-force BOMLine $line +'; + // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { print "Error, template page can't be called as URL"; @@ -54,8 +58,8 @@ if ($line->fk_product > 0) { } $tmpbom = new BOM($db); $res = 0; -if ($line->fk_bom_child > 0) { - $res = $tmpbom->fetch($line->fk_bom_child); +if ((int) $line->fk_bom_child > 0) { + $res = $tmpbom->fetch((int) $line->fk_bom_child); } ?> diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 5794ace75d3..1c96b0284e3 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -208,15 +208,15 @@ class MouvementStock extends CommonObject * @param int $price Unit price HT of product, used to calculate average weighted price (AWP or PMP in french). If 0, average weighted price is not changed. * @param string $label Label of stock movement * @param string $inventorycode Inventory code - * @param integer|string $datem Force date of movement - * @param integer|string $eatby eat-by date. Will be used if lot does not exists yet and will be created. - * @param integer|string $sellby sell-by date. Will be used if lot does not exists yet and will be created. + * @param int|string $datem Force date of movement + * @param int|string $eatby eat-by date. Will be used if lot does not exists yet and will be created. + * @param int|string $sellby sell-by date. Will be used if lot does not exists yet and will be created. * @param string $batch batch number * @param boolean $skip_batch If set to true, stock movement is done without impacting batch record * @param int $id_product_batch Id product_batch (when skip_batch is false and we already know which record of product_batch to use) - * @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (useful only if product is a subproduct) - * @param int $donotcleanemptylines Do not clean lines in stock table with qty=0 (because we want to have this done by the caller) - * @param boolean $force_update_batch Allows to add batch stock movement even if $product doesn't use batch anymore + * @param int<0,1> $disablestockchangeforsubproduct Disable stock change for sub-products of kit (useful only if product is a subproduct) + * @param int<0,1> $donotcleanemptylines Do not clean lines in stock table with qty=0 (because we want to have this done by the caller) + * @param bool $force_update_batch Allows to add batch stock movement even if $product doesn't use batch anymore * @return int Return integer <0 if KO, 0 if fk_product is null or product id does not exists, >0 if OK */ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false, $id_product_batch = 0, $disablestockchangeforsubproduct = 0, $donotcleanemptylines = 0, $force_update_batch = false) From fd7fee2e8f2809f6b64c60667c6188ea969420ef Mon Sep 17 00:00:00 2001 From: MDW Date: Sat, 8 Feb 2025 01:49:29 +0100 Subject: [PATCH 568/602] Qual: Fix textwithpicto $type argument (0->info,1->help) --- dev/tools/phan/baseline.txt | 47 +---- dev/tools/phan/config_fixer.php | 3 +- dev/tools/phan/plugins/textwithpictoFixer.php | 177 ++++++++++++++++++ htdocs/adherents/admin/member.php | 4 +- htdocs/admin/agenda_other.php | 4 +- htdocs/admin/bank.php | 4 +- htdocs/admin/bom.php | 6 +- htdocs/admin/chequereceipts.php | 4 +- htdocs/admin/contract.php | 6 +- htdocs/admin/delivery.php | 6 +- htdocs/admin/expedition.php | 6 +- htdocs/admin/expensereport.php | 6 +- htdocs/admin/fichinter.php | 6 +- htdocs/admin/holiday.php | 6 +- htdocs/admin/hrm.php | 6 +- htdocs/admin/invoice.php | 6 +- htdocs/admin/knowledgemanagement.php | 6 +- htdocs/admin/order.php | 6 +- htdocs/admin/payment.php | 4 +- htdocs/admin/propal.php | 6 +- htdocs/admin/reception_setup.php | 6 +- htdocs/admin/stock.php | 4 +- htdocs/admin/stocktransfer.php | 6 +- htdocs/admin/supplier_invoice.php | 6 +- htdocs/admin/supplier_order.php | 6 +- htdocs/admin/supplier_payment.php | 6 +- htdocs/admin/supplier_proposal.php | 6 +- htdocs/admin/user.php | 4 +- htdocs/admin/usergroup.php | 4 +- htdocs/admin/workstation.php | 6 +- htdocs/asset/admin/setup.php | 6 +- .../modules/mailings/modules_mailings.php | 4 +- htdocs/core/tpl/admin_extrafields_add.tpl.php | 13 +- .../core/tpl/admin_extrafields_edit.tpl.php | 37 ++-- .../partnership/mod_partnership_advanced.php | 4 +- htdocs/product/admin/product.php | 6 +- htdocs/product/admin/product_lot.php | 8 +- htdocs/product/card.php | 16 +- htdocs/product/price.php | 16 +- htdocs/projet/admin/project.php | 10 +- htdocs/recruitment/admin/setup.php | 6 +- .../recruitment/admin/setup_candidatures.php | 6 +- htdocs/societe/admin/societe.php | 4 +- .../canvas/actions_card_common.class.php | 4 +- htdocs/societe/list.php | 16 +- htdocs/societe/price.php | 13 +- htdocs/takepos/admin/setup.php | 4 +- 47 files changed, 350 insertions(+), 196 deletions(-) create mode 100644 dev/tools/phan/plugins/textwithpictoFixer.php diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index dcfbfa73dda..6c27b5a85b5 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -9,7 +9,7 @@ */ return [ // # Issue statistics: - // PhanTypeMismatchArgument : 2450+ occurrences + // PhanTypeMismatchArgument : 2340+ occurrences // PhanUndeclaredProperty : 530+ occurrences // PhanTypeMismatchArgumentNullable : 430+ occurrences // PhanUndeclaredGlobalVariable : 190+ occurrences @@ -92,29 +92,20 @@ return [ 'htdocs/adherents/subscription.php' => ['PhanTypeMismatchArgument'], 'htdocs/adherents/type.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchProperty'], 'htdocs/adherents/vcard.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/agenda_other.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/admin/agenda_other.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/admin/agenda_reminder.php' => ['PhanTypeMismatchArgumentNullable'], - 'htdocs/admin/bank.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/barcode.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/bom.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/chequereceipts.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/company.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/contract.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/defaultvalues.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/admin/delivery.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/dict.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/emailcollector_card.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/emailcollector_list.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/eventorganization.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/expedition.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/expensereport.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/expensereport_rules.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/external_rss.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/fckeditor.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/fichinter.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/holiday.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/hrm.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/invoice.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/knowledgemanagement.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/mails.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/mails_emailing.php' => ['PhanTypeMismatchArgumentNullable'], @@ -124,32 +115,19 @@ return [ 'htdocs/admin/mails_ticket.php' => ['PhanTypeMismatchArgumentNullable'], 'htdocs/admin/menus/index.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/multicurrency.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/order.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/payment.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/paymentbybanktransfer.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/pdf_other.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/prelevement.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/propal.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/receiptprinter.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/reception_setup.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/remotestore/class/PSWebServiceLibrary.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/admin/remotestore/class/dolistore.class.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/stock.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/stocktransfer.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/supplier_invoice.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/supplier_order.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/supplier_payment.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/supplier_proposal.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/system/filecheck.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/system/modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/taxes.php' => ['PhanTypeMismatchArgumentNullable'], 'htdocs/admin/ticket.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/tools/export.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/user.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/usergroup.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/webhook.php' => ['PhanTypeMismatchArgument'], 'htdocs/admin/website.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/workstation.php' => ['PhanTypeMismatchArgument'], 'htdocs/api/class/api_access.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanUndeclaredProperty'], 'htdocs/api/class/api_documents.class.php' => ['PhanPluginDuplicateExpressionBinaryOp', 'PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgument'], 'htdocs/api/class/api_login.class.php' => ['PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgument'], @@ -442,7 +420,6 @@ return [ 'htdocs/core/modules/import/import_csv.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchProperty'], 'htdocs/core/modules/import/import_xlsx.modules.php' => ['PhanTypeMismatchProperty'], 'htdocs/core/modules/mailings/eventorganization.modules.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/mailings/modules_mailings.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/member/doc/pdf_standard_member.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/member/modules_cards.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/modAdherent.class.php' => ['PhanTypeMismatchArgument'], @@ -470,10 +447,10 @@ return [ 'htdocs/core/modules/oauth/github_oauthcallback.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/project/doc/pdf_beluga.modules.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/modules/project/doc/pdf_timespent.modules.php' => ['PhanUndeclaredProperty'], - 'htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], + 'htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php' => ['PhanUndeclaredProperty'], 'htdocs/core/modules/propale/doc/pdf_azur.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], 'htdocs/core/modules/propale/doc/pdf_cyan.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], 'htdocs/core/modules/reception/doc/pdf_squille.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredProperty'], @@ -491,8 +468,6 @@ return [ 'htdocs/core/modules/workstation/mod_workstation_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/core/multicompany_page.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/search_page.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/tpl/admin_extrafields_add.tpl.php' => ['PhanTypeMismatchArgument'], - 'htdocs/core/tpl/admin_extrafields_edit.tpl.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/tpl/extrafields_list_array_fields.tpl.php' => ['PhanTypeMismatchArgument'], 'htdocs/core/tpl/extrafields_list_print_fields.tpl.php' => ['PhanTypeMismatchArgumentNullable'], 'htdocs/core/tpl/extrafields_view.tpl.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], @@ -623,14 +598,13 @@ return [ 'htdocs/opensurvey/wizard/create_survey.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/partnership/class/api_partnerships.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanTypeMismatchArgument'], 'htdocs/partnership/class/partnership.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/partnership/core/modules/partnership/mod_partnership_advanced.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], + 'htdocs/partnership/core/modules/partnership/mod_partnership_advanced.php' => ['PhanUndeclaredProperty'], 'htdocs/partnership/partnership_card.php' => ['PhanUndeclaredGlobalVariable'], 'htdocs/partnership/partnership_contact.php' => ['PhanTypeMismatchArgument'], 'htdocs/partnership/partnership_list.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/printing/index.php' => ['PhanUndeclaredProperty'], 'htdocs/product/admin/price_rules.php' => ['PhanTypeMismatchArgument'], - 'htdocs/product/admin/product.php' => ['PhanPluginEmptyStatementIf', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/product/admin/product_lot.php' => ['PhanTypeMismatchArgument'], + 'htdocs/product/admin/product.php' => ['PhanPluginEmptyStatementIf', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/product/admin/product_tools.php' => ['PhanTypeMismatchArgument'], 'htdocs/product/ajax/products.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/product/canvas/product/actions_card_product.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], @@ -671,7 +645,7 @@ return [ 'htdocs/product/stock/class/entrepot.class.php' => ['PhanUndeclaredProperty'], 'htdocs/product/stock/class/mouvementstock.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/product/stock/info.php' => ['PhanPluginUnknownObjectMethodCall', 'PhanTypeMismatchArgument', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], - 'htdocs/product/stock/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/product/stock/list.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/product/stock/massstockmove.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/product/stock/movement_card.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/product/stock/movement_list.php' => ['PhanPluginBothLiteralsBinaryOp', 'PhanPluginUndeclaredVariableIsset', 'PhanTypeMismatchArgument', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], @@ -693,7 +667,7 @@ return [ 'htdocs/projet/activity/perday.php' => ['PhanTypeMismatchArgument'], 'htdocs/projet/activity/permonth.php' => ['PhanTypeMismatchArgument'], 'htdocs/projet/activity/perweek.php' => ['PhanTypeMismatchArgument'], - 'htdocs/projet/admin/project.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal'], + 'htdocs/projet/admin/project.php' => ['PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/admin/website.php' => ['PhanTypeMismatchArgument'], 'htdocs/projet/ajax/projects.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/projet/card.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredGlobalVariable'], @@ -762,8 +736,8 @@ return [ 'htdocs/reception/list.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], 'htdocs/reception/note.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanUndeclaredGlobalVariable'], 'htdocs/reception/stats/index.php' => ['PhanTypeMismatchArgument'], - 'htdocs/recruitment/admin/setup.php' => ['PhanEmptyForeach', 'PhanTypeMismatchArgument'], - 'htdocs/recruitment/admin/setup_candidatures.php' => ['PhanEmptyForeach', 'PhanTypeMismatchArgument'], + 'htdocs/recruitment/admin/setup.php' => ['PhanEmptyForeach'], + 'htdocs/recruitment/admin/setup_candidatures.php' => ['PhanEmptyForeach'], 'htdocs/recruitment/class/api_recruitments.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'], 'htdocs/recruitment/class/recruitmentcandidature.class.php' => ['PhanUndeclaredProperty'], 'htdocs/recruitment/class/recruitmentjobposition.class.php' => ['PhanUndeclaredProperty'], @@ -826,7 +800,6 @@ return [ 'htdocs/supplier_proposal/list.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchArgumentProbablyReal'], 'htdocs/supplier_proposal/note.php' => ['PhanTypeMismatchArgument'], 'htdocs/takepos/admin/bar.php' => ['PhanTypeMismatchArgument'], - 'htdocs/takepos/admin/setup.php' => ['PhanTypeMismatchArgument'], 'htdocs/takepos/admin/terminal.php' => ['PhanTypeMismatchArgument'], 'htdocs/takepos/ajax/ajax.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/takepos/floors.php' => ['PhanTypeMismatchArgumentProbablyReal'], diff --git a/dev/tools/phan/config_fixer.php b/dev/tools/phan/config_fixer.php index 8f5df967bca..e9a0fa36763 100644 --- a/dev/tools/phan/config_fixer.php +++ b/dev/tools/phan/config_fixer.php @@ -14,7 +14,8 @@ $config = include __DIR__.DIRECTORY_SEPARATOR."config.php"; //require_once __DIR__.'/plugins/PriceFormFixer.php'; //require_once __DIR__.'/plugins/UrlEncodeStringifyFixer.php'; //require_once __DIR__.'/plugins/SelectDateFixer.php'; -require_once __DIR__.'/plugins/setPageOrientationFixer.php'; +//require_once __DIR__.'/plugins/setPageOrientationFixer.php'; +require_once __DIR__.'/plugins/textwithpictoFixer.php'; //require_once __DIR__.'/plugins/MultiCellFixer.php'; //require_once __DIR__.'/plugins/setAutoPageBreakFixer.php'; //require_once __DIR__.'/plugins/CellFixer.php'; diff --git a/dev/tools/phan/plugins/textwithpictoFixer.php b/dev/tools/phan/plugins/textwithpictoFixer.php new file mode 100644 index 00000000000..484b02cf675 --- /dev/null +++ b/dev/tools/phan/plugins/textwithpictoFixer.php @@ -0,0 +1,177 @@ + + * + * For 'price()', replace $form parameter that is '' with 0. + */ + +declare(strict_types=1); + +use ast\flags; +use Microsoft\PhpParser\Node\Expression\CallExpression; +use Microsoft\PhpParser\Node\QualifiedName; +use Phan\AST\TolerantASTConverter\NodeUtils; +use Phan\CodeBase; +use Phan\IssueInstance; +use Phan\Library\FileCacheEntry; +use Phan\Plugin\Internal\IssueFixingPlugin\FileEdit; +use Phan\Plugin\Internal\IssueFixingPlugin\FileEditSet; +use Phan\Plugin\Internal\IssueFixingPlugin\IssueFixer; +use Microsoft\PhpParser\Node\Expression\ArgumentExpression; +use Microsoft\PhpParser\Node\DelimitedList\ArgumentExpressionList; +use Microsoft\PhpParser\Node\StringLiteral; +use Microsoft\PhpParser\Node\NumericLiteral; +use Microsoft\PhpParser\Node\ReservedWord; +use Microsoft\PhpParser\Token; + +/** + * This is a prototype, there are various features it does not implement. + */ + +call_user_func(static function (): void { + /** + * @param $code_base @unused-param + * @return ?FileEditSet a representation of the edit to make to replace a call to a function alias with a call to the original function + */ + $fix = static function (CodeBase $code_base, FileCacheEntry $contents, IssueInstance $instance): ?FileEditSet { + + // Argument {INDEX} (${PARAMETER}) is {CODE} of type {TYPE}{DETAILS} but + // {FUNCTIONLIKE} takes {TYPE}{DETAILS} defined at {FILE}:{LINE} (the inferred real argument type has nothing in common with the parameter's phpdoc type) + + //htdocs\supplier_proposal\card.php:1705 PhanTypeMismatchArgumentProbablyReal Argument 3 ($h) is '' of type '' but \Form::selectDate() takes int (no real type) defined at htdocs\core\class\html.form.class.php:6799 (the inferred real argument type has nothing in common with the parameter's phpdoc type) + //htdocs\supplier_proposal\card.php:1705 PhanTypeMismatchArgumentProbablyReal Argument 4 ($m) is '' of type '' but \Form::selectDate() takes int (no real type) defined at htdocs\core\class\html.form.class.php:6799 (the inferred real argument type has nothing in common with the parameter's phpdoc type) + // var_dump($instance->getTemplateParameters()); + $argument_index = (string) $instance->getTemplateParameters()[0]; + $argument_name = (string) $instance->getTemplateParameters()[1]; + $argument_code = (string) $instance->getTemplateParameters()[2]; + $argument_type = (string) $instance->getTemplateParameters()[3]; + $functionlike = (string) $instance->getTemplateParameters()[4]; + $functiontype = (string) $instance->getTemplateParameters()[5]; + + $expected_functionlike = "\\Form::textwithpicto()"; + $expected_name = "textwithpicto"; + if ($functionlike !== $expected_functionlike) { + //print "$functionlike != '$expected_functionlike'".PHP_EOL; + return null; + } + + $toBoolReplaceArray = array("0" => "'info'","1" => "'help'"); + // Check if we fix any of this + if ( + ($argument_name === 'type' && in_array($argument_code, array_keys($toBoolReplaceArray))) + //|| ($argument_name === 'm' && $argument_code === "''") + //|| ($argument_name === 'empty' && $argument_code === "''") + ) { + $replacement = $toBoolReplaceArray[$argument_code]; + $argIdx = ($argument_index - 1) * 2; + $expectedStringValue = $argument_code; + } else { + print "ARG$argument_index:$argument_name CODE:$argument_name".PHP_EOL; + return null; + } + + // At this point we established that the notification + // matches some we fix. + + $line = $instance->getLine(); + + $edits = []; + foreach ($contents->getNodesAtLine($line) as $node) { + if (!$node instanceof ArgumentExpressionList) { + continue; + } + $arguments = $node->children; + if (count($arguments) <= $argIdx) { + // print "Arg Count is ".count($arguments)." - Skip $instance".PHP_EOL; + continue; + } + + $is_actual_call = $node->parent instanceof CallExpression; + if (!$is_actual_call) { + // print "Not actual call - Skip $instance".PHP_EOL; + continue; + } + + print "Actual call - $instance".PHP_EOL; + $callable = $node->parent; + + $callableExpression = $callable->callableExpression; + + if ($callableExpression instanceof Microsoft\PhpParser\Node\QualifiedName) { + $actual_name = $callableExpression->getResolvedName(); + } elseif ($callableExpression instanceof Microsoft\PhpParser\Node\Expression\MemberAccessExpression) { + $memberNameToken = $callableExpression->memberName; + $actual_name = (new NodeUtils($contents->getContents()))->tokenToString($memberNameToken); + } else { + print "Callable expression is ".get_class($callableExpression)."- Skip $instance".PHP_EOL; + continue; + } + + if ((string) $actual_name !== (string) $expected_name) { + // print "Name unexpected '$actual_name'!='$expected_name' - Skip $instance".PHP_EOL; + continue; + } + + foreach ($arguments as $i => $argument) { + if ($argument instanceof ArgumentExpression) { + // print "Type$i: ".get_class($argument->expression).PHP_EOL; + } + } + + $fieldValue = null; + + + $arg = $arguments[$argIdx]; + + if ( + $arg instanceof ArgumentExpression + && $arg->expression instanceof NumericLiteral + ) { + // Get the string value of the NumericLiteral + $fieldValue = (string) $arg->expression; + //print "Field is '$fieldValue'".PHP_EOL; + } elseif ($arg instanceof ArgumentExpression && $arg->expression instanceof ReservedWord) { + $child = $arg->expression->children; + if (!$child instanceof Token) { + continue; + } + $token_str = (new NodeUtils($contents->getContents()))->tokenToString($child); + print "$token_str KIND:".($child->kind ?? 'no kind')." ".get_class($child).PHP_EOL; + + if ($token_str !== 'null') { + continue; + } + + $fieldValue = ''; // Fake empty + } else { + // print "Expression is not expected type ".get_class($arg)."/".get_class($arg->expression)."- Skip $instance".PHP_EOL; + continue; + } + + if ($fieldValue !== $expectedStringValue) { + // print "Not replacing '$argument_name' which is '$fieldValue'/".get_class($arg)."/".get_class($arg->expression)."- Skip $instance".PHP_EOL; + continue; + } + + print "Fixture elem on $line - $actual_name(...'$fieldValue'...) - $instance".PHP_EOL; + + + + // Get the first argument (delimiter) + $argument_to_replace = $arg; + + $arg_start_pos = $argument_to_replace->getStartPosition(); + $arg_end_pos = $argument_to_replace->getEndPosition(); + + // Set edit instruction + $edits[] = new FileEdit($arg_start_pos, $arg_end_pos, $replacement); + } + if ($edits) { + return new FileEditSet($edits); + } + return null; + }; + IssueFixer::registerFixerClosure( + 'PhanTypeMismatchArgument', + $fix + ); +}); diff --git a/htdocs/adherents/admin/member.php b/htdocs/adherents/admin/member.php index 8bd3a2013ea..31a1597eeed 100644 --- a/htdocs/adherents/admin/member.php +++ b/htdocs/adherents/admin/member.php @@ -10,7 +10,7 @@ * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2020-2024 Frédéric France * Copyright (C) 2023 Waël Almoman - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify @@ -461,7 +461,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php index 5f50050e53c..fddb1cf8566 100644 --- a/htdocs/admin/agenda_other.php +++ b/htdocs/admin/agenda_other.php @@ -5,7 +5,7 @@ * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2016 Charlie Benke * Copyright (C) 2017 Open-DSI - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -320,7 +320,7 @@ if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); print '
'; print ''; // Preview diff --git a/htdocs/admin/bom.php b/htdocs/admin/bom.php index 1c4f0b4377a..de147fc81d3 100644 --- a/htdocs/admin/bom.php +++ b/htdocs/admin/bom.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -283,7 +283,7 @@ foreach ($dirmodels as $reldir) { } print ''; print "\n"; @@ -420,7 +420,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/chequereceipts.php b/htdocs/admin/chequereceipts.php index a26f0f33af2..75b0e216b27 100644 --- a/htdocs/admin/chequereceipts.php +++ b/htdocs/admin/chequereceipts.php @@ -3,7 +3,7 @@ * Copyright (C) 2010-2016 Juanjo Menent * Copyright (C) 2013-2018 Philippe Grand * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -226,7 +226,7 @@ foreach ($dirmodels as $reldir) { } print ''; print ''; @@ -456,7 +456,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/delivery.php b/htdocs/admin/delivery.php index fa05a39c472..95ef16efbad 100644 --- a/htdocs/admin/delivery.php +++ b/htdocs/admin/delivery.php @@ -8,7 +8,7 @@ * Copyright (C) 2011-2013 Juanjo Menent * Copyright (C) 2011-2018 Philippe Grand * Copyright (C) 2015 Claudio Aschieri - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -328,7 +328,7 @@ if (getDolGlobalString('MAIN_SUBMODULE_DELIVERY')) { } print ''; print ''; @@ -456,7 +456,7 @@ if (getDolGlobalString('MAIN_SUBMODULE_DELIVERY')) { $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); print ''; // Preview diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 5ad30fc921f..1f03a708917 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -7,7 +7,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011-2012 Juanjo Menent * Copyright (C) 2011-2018 Philippe Grand - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -272,7 +272,7 @@ foreach ($dirmodels as $reldir) { } print ''; print ''; @@ -408,7 +408,7 @@ foreach ($dirmodels as $reldir) { $htmltooltip .= '
'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark, 1, 1); print ''; // Preview diff --git a/htdocs/admin/expensereport.php b/htdocs/admin/expensereport.php index 31087976ffc..e9d5c01acd8 100644 --- a/htdocs/admin/expensereport.php +++ b/htdocs/admin/expensereport.php @@ -7,7 +7,7 @@ * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2011-2013 Juanjo Menent * Copyright (C) 2011-2022 Philippe Grand - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -298,7 +298,7 @@ foreach ($dirmodels as $reldir) { } print ''; print "\n"; @@ -427,7 +427,7 @@ foreach ($dirmodels as $reldir) { $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); $htmltooltip .= '
'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark, 1, 1); print ''; // Preview diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index edcd0469c1a..18c72b62051 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -7,7 +7,7 @@ * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2011-2013 Juanjo Menent * Copyright (C) 2011-2018 Philippe Grand - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -364,7 +364,7 @@ foreach ($dirmodels as $reldir) { } } print ''; print ''; @@ -503,7 +503,7 @@ foreach ($dirmodels as $reldir) { $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); $htmltooltip .= '
'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark, 1, 1); print ''; // Preview diff --git a/htdocs/admin/holiday.php b/htdocs/admin/holiday.php index b6fc587032d..4eb9e2f5dbd 100644 --- a/htdocs/admin/holiday.php +++ b/htdocs/admin/holiday.php @@ -3,7 +3,7 @@ * Copyright (C) 2011-2018 Philippe Grand * Copyright (C) 2018 Charlene Benke * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -274,7 +274,7 @@ foreach ($dirmodels as $reldir) { } print ''; print ''; @@ -419,7 +419,7 @@ if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { print ''; // Preview diff --git a/htdocs/admin/hrm.php b/htdocs/admin/hrm.php index e80962f6d25..de8dfabaa18 100644 --- a/htdocs/admin/hrm.php +++ b/htdocs/admin/hrm.php @@ -4,7 +4,7 @@ * Copyright (C) 2021 Greg Rastklan * Copyright (C) 2021 Jean-Pascal BOUDET * Copyright (C) 2021 Grégory BLEMAND - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software: you can redistribute it and/or modify @@ -331,7 +331,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } print ''; print "\n"; @@ -471,7 +471,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); print ''; // Preview diff --git a/htdocs/admin/invoice.php b/htdocs/admin/invoice.php index e9dc88c9b96..1beac2929ee 100644 --- a/htdocs/admin/invoice.php +++ b/htdocs/admin/invoice.php @@ -7,7 +7,7 @@ * Copyright (C) 2012-2013 Juanjo Menent * Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com> * Copyright (C) 2022 Anthony Berton - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro * @@ -451,7 +451,7 @@ foreach ($dirmodels as $reldir) { } print ''; // Preview diff --git a/htdocs/admin/knowledgemanagement.php b/htdocs/admin/knowledgemanagement.php index 7c7458a6901..953f7958bd7 100644 --- a/htdocs/admin/knowledgemanagement.php +++ b/htdocs/admin/knowledgemanagement.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software: you can redistribute it and/or modify @@ -450,7 +450,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } print ''; print "\n"; @@ -589,7 +589,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); print ''; // Preview diff --git a/htdocs/admin/order.php b/htdocs/admin/order.php index 38b4dd721cf..27e6f623a62 100644 --- a/htdocs/admin/order.php +++ b/htdocs/admin/order.php @@ -10,7 +10,7 @@ * Copyright (C) 2011-2016 Philippe Grand * Copyright (C) 2013 Florian Henry * Copyright (C) 2021-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -368,7 +368,7 @@ foreach ($dirmodels as $reldir) { } print ''; print "\n"; @@ -509,7 +509,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/payment.php b/htdocs/admin/payment.php index f60bed8f0c9..f40c357e13e 100644 --- a/htdocs/admin/payment.php +++ b/htdocs/admin/payment.php @@ -1,7 +1,7 @@ * Copyright (C) 2020 Maxime DEMAREST - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -230,7 +230,7 @@ foreach ($dirmodels as $reldir) { } print ''; print "\n"; @@ -486,7 +486,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/reception_setup.php b/htdocs/admin/reception_setup.php index 7c1c855dc0a..b783d9e07df 100644 --- a/htdocs/admin/reception_setup.php +++ b/htdocs/admin/reception_setup.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -279,7 +279,7 @@ foreach ($dirmodels as $reldir) { } print ''; print ''; @@ -421,7 +421,7 @@ foreach ($dirmodels as $reldir) { $htmltooltip .= '
'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark, 1, 1); print ''; // Preview diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 952bccf2074..10df54ee44d 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -5,7 +5,7 @@ * Copyright (C) 2012-2013 Juanjo Menent * Copyright (C) 2013-2018 Philippe Grand * Copyright (C) 2013 Florian Henry - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -656,7 +656,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index 6a14e25c466..8dc65bc920e 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -2,7 +2,7 @@ /* Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2021 Gauthier VERDOL * Copyright (C) 2021 SuperAdmin - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software: you can redistribute it and/or modify @@ -337,7 +337,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } print ''; print "\n"; @@ -473,7 +473,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); print ''; // Preview diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php index 8dab80b8157..b0c05b8bbea 100644 --- a/htdocs/admin/supplier_invoice.php +++ b/htdocs/admin/supplier_invoice.php @@ -6,7 +6,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2011-2018 Philippe Grand - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -303,7 +303,7 @@ foreach ($dirmodels as $reldir) { } print ''; print ''; @@ -441,7 +441,7 @@ foreach ($dirmodels as $reldir) { $htmltooltip .= '
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg, 1, 1); $htmltooltip .= '
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg, 1, 1); print ''; print ''; print ''; @@ -446,7 +446,7 @@ foreach ($dirmodels as $reldir) { $htmltooltip .= '
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg, 1, 1); $htmltooltip .= '
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg, 1, 1); print ''; print ''; print ''; print "\n"; @@ -475,7 +475,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index 0c957617ce1..8055e5fdcde 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -7,7 +7,7 @@ * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2015 Juanjo Menent * Copyright (C) 2020-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -317,7 +317,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/usergroup.php b/htdocs/admin/usergroup.php index fbaa912385a..15939c806c2 100644 --- a/htdocs/admin/usergroup.php +++ b/htdocs/admin/usergroup.php @@ -6,7 +6,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2015 Juanjo Menent - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -236,7 +236,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php index dc6017c33ed..b93b8e0bb0c 100644 --- a/htdocs/admin/workstation.php +++ b/htdocs/admin/workstation.php @@ -1,7 +1,7 @@ * Copyright (C) 2020 Gauthier VERDOL - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software: you can redistribute it and/or modify @@ -281,7 +281,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } print ''; print "\n"; @@ -415,7 +415,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); print ''; // Preview diff --git a/htdocs/asset/admin/setup.php b/htdocs/asset/admin/setup.php index 22e36b47bda..4930864aa71 100644 --- a/htdocs/asset/admin/setup.php +++ b/htdocs/asset/admin/setup.php @@ -1,7 +1,7 @@ * Copyright (C) 2018-2024 Alexandre Spangaro - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software: you can redistribute it and/or modify @@ -301,7 +301,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } print ''; print "\n"; @@ -439,7 +439,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); print ''; // Preview diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php index 9605cbe9019..49818e9f766 100644 --- a/htdocs/core/modules/mailings/modules_mailings.php +++ b/htdocs/core/modules/mailings/modules_mailings.php @@ -2,7 +2,7 @@ /* Copyright (C) 2003-2004 Rodolphe Quiedeville * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -111,7 +111,7 @@ class MailingTargets // This can't be abstract as it is used for some method } if ($this->tooltip && is_object($form)) { - $s .= ' '.$form->textwithpicto('', $langs->trans($this->tooltip), 1, 1); + $s .= ' '.$form->textwithpicto('', $langs->trans($this->tooltip), 1, 'help'); } return $s; } diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index 25452bca8db..7c770e4ea77 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -3,6 +3,7 @@ * Copyright (C) 2012 Regis Houssin * Copyright (C) 2016 Charlie Benke * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2025 MDW * * 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 @@ -194,12 +195,12 @@ print $formadmin->selectTypeOfFields('type', GETPOST('type', 'alpha'));
'.$langs->trans("Description").''; - print dol_htmlentitiesbr($projectstatic->description); - print '
'.$langs->trans("Categories").''; @@ -559,6 +554,16 @@ if ($projectstatic->id > 0 || $confOrBooth > 0) { print "
'.$langs->trans("Description").'
'; + print '
'; + print dolPrintHTML($projectstatic->description); + print '
'; + print '
'; $typeofdata = 'checkbox:'.($projectstatic->accept_conference_suggestions ? ' checked="checked"' : ''); $htmltext = $langs->trans("AllowUnknownPeopleSuggestConfHelp"); diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 80af93b7cd0..f416f4fc55d 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -311,7 +311,7 @@ if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJ print '
'.$langs->trans("OpportunityStatus").''; $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code'); From 5b1c5397bac1056c6bc58948806495861b9371f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20de=20Grandpr=C3=A9?= Date: Wed, 29 Jan 2025 09:34:16 -0500 Subject: [PATCH 336/602] Adding global variables to have more flexibility on external calendars location. --- htdocs/comm/action/class/ical.class.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/action/class/ical.class.php b/htdocs/comm/action/class/ical.class.php index da003149657..3024513dfed 100644 --- a/htdocs/comm/action/class/ical.class.php +++ b/htdocs/comm/action/class/ical.class.php @@ -96,7 +96,16 @@ class ICal $file_text = ''; //$tmpresult = getURLContent($file, 'GET', '', 1, [], ['http', 'https'], 2, 0); // To test with any URL - $tmpresult = getURLContent($file, 'GET'); + $localip = 0; + $sslverify = -1; + if(getDolGlobalString('AGENDA_EXT_CALENDAR_IP_MODE')) { + $localip = intval(getDolGlobalString('AGENDA_EXT_CALENDAR_IP_MODE')); + } + if(getDolGlobalString('AGENDA_EXT_CALENDAR_SSLVERIFY_MODE')) { + $sslverify = intval(getDolGlobalString('AGENDA_EXT_CALENDAR_SSLVERIFY_MODE')); + } + // See documentation of getURLContent function for $localip and $sslverify possible values + $tmpresult = getURLContent($file, 'GET', '', 1, [], ['http', 'https'], $localip, $sslverify); if ($tmpresult['http_code'] != 200) { $file_text = null; $this->error = 'Error: '.$tmpresult['http_code'].' '.$tmpresult['content']; From 841356613e24a05566e50ecc8d74f16179d75de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20de=20Grandpr=C3=A9?= Date: Wed, 29 Jan 2025 09:40:57 -0500 Subject: [PATCH 337/602] code format --- htdocs/comm/action/class/ical.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/class/ical.class.php b/htdocs/comm/action/class/ical.class.php index 3024513dfed..405c84d1046 100644 --- a/htdocs/comm/action/class/ical.class.php +++ b/htdocs/comm/action/class/ical.class.php @@ -98,10 +98,10 @@ class ICal //$tmpresult = getURLContent($file, 'GET', '', 1, [], ['http', 'https'], 2, 0); // To test with any URL $localip = 0; $sslverify = -1; - if(getDolGlobalString('AGENDA_EXT_CALENDAR_IP_MODE')) { + if (getDolGlobalString('AGENDA_EXT_CALENDAR_IP_MODE')) { $localip = intval(getDolGlobalString('AGENDA_EXT_CALENDAR_IP_MODE')); } - if(getDolGlobalString('AGENDA_EXT_CALENDAR_SSLVERIFY_MODE')) { + if (getDolGlobalString('AGENDA_EXT_CALENDAR_SSLVERIFY_MODE')) { $sslverify = intval(getDolGlobalString('AGENDA_EXT_CALENDAR_SSLVERIFY_MODE')); } // See documentation of getURLContent function for $localip and $sslverify possible values From 71d13cc77af248fc01148ec32a96fd6bf4fcc632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20de=20Grandpr=C3=A9?= Date: Wed, 29 Jan 2025 10:13:01 -0500 Subject: [PATCH 338/602] added cpr --- htdocs/comm/action/class/ical.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/action/class/ical.class.php b/htdocs/comm/action/class/ical.class.php index 405c84d1046..648f96aba4d 100644 --- a/htdocs/comm/action/class/ical.class.php +++ b/htdocs/comm/action/class/ical.class.php @@ -4,7 +4,8 @@ * Copyright (C) 2013-2014 Laurent Destailleur * Copyright (C) 2012 Regis Houssin * Copyright (C) 2019-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024 MDW + * Copyright (C) 2024 Vincent de Grandpré * * 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 From 8f3b814aaf2febfa4a4b4b7b65d398d3c42d946a Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:31:07 +0100 Subject: [PATCH 339/602] Update llx_c_forme_juridique.sql added new Austrian business entity type FlexKapG #32803 --- htdocs/install/mysql/data/llx_c_forme_juridique.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/data/llx_c_forme_juridique.sql b/htdocs/install/mysql/data/llx_c_forme_juridique.sql index fd094e387ef..38140954e39 100644 --- a/htdocs/install/mysql/data/llx_c_forme_juridique.sql +++ b/htdocs/install/mysql/data/llx_c_forme_juridique.sql @@ -10,7 +10,7 @@ -- Copyright (C) 2012 Tommaso Basilici -- Copyright (C) 2012 Ricardo Schluter -- Copyright (C) 2013 Cedric GROSS --- Copyright (C) 2020-2021 Udo Tamm +-- Copyright (C) 2020-2025 Udo Tamm -- Copyright (C) 2022 Miro Sertić -- -- This program is free software; you can redistribute it and/or modify @@ -83,6 +83,7 @@ INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (41, ' INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (41, '4112', 'GesbR - Gesellschaft nach bürgerlichem Recht', 1); INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (41, '4113', 'GesnbR - Gesellschaft nach bürgerlichem Recht', 1); INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (41, '4114', 'e.U. - eingetragener Einzelunternehmer', 1); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (41, '4115', 'FlexKapG - Flexible Kapitalgesellschaft', 1); -- Belgium From 40567ce7f680e422b90f138859dc9a7f5ad0bbca Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 29 Jan 2025 18:13:03 +0100 Subject: [PATCH 340/602] FIX E_STRICT is deprecated since PHP 8.4 --- htdocs/filefunc.inc.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index aa03bc81bd9..abba0355be6 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -205,10 +205,19 @@ if (!$result && !empty($_SERVER["GATEWAY_INTERFACE"])) { // If install not do } // Force PHP error_reporting setup (Dolibarr may report warning without this) -if (!empty($dolibarr_strict_mode)) { - error_reporting(E_ALL | E_STRICT); +if (version_compare(phpversion(), '8.4', '<')) { + if (!empty($dolibarr_strict_mode)) { + error_reporting(E_ALL | E_STRICT); + } else { + error_reporting(E_ALL & ~(E_STRICT | E_NOTICE | E_DEPRECATED)); + } } else { - error_reporting(E_ALL & ~(E_STRICT | E_NOTICE | E_DEPRECATED)); + // E_STRICT is deprecated since PHP 8.4 + if (!empty($dolibarr_strict_mode)) { + error_reporting(E_ALL); + } else { + error_reporting(E_ALL & ~(E_NOTICE | E_DEPRECATED)); + } } // Disable php display errors From 9cb16ea555ee945da759107f8b16c229013204d5 Mon Sep 17 00:00:00 2001 From: sonikf <93765174+sonikf@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:34:18 +0200 Subject: [PATCH 341/602] fix trans --- htdocs/langs/en_US/datapolicy.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/datapolicy.lang b/htdocs/langs/en_US/datapolicy.lang index 38a4f48f39f..3f8e33544fa 100644 --- a/htdocs/langs/en_US/datapolicy.lang +++ b/htdocs/langs/en_US/datapolicy.lang @@ -19,7 +19,7 @@ Module4100Desc = Module to manage Data Privacy (Conformity with the GDPR) datapolicySetup = Module Data Privacy Policy Setup DataDeletion=Deletion of data DataAnonymization=Anonymization of data -datapolicySetupPage = Depending on the laws of your countries (Example Article 5 of the GDPR), personal data must be kept for a period not exceeding the duration the data is needed for the purpose for which it was collected, except for archival purposes.
This module will make an anonymization automatically after a certain duration without events (the duration which you will have indicated below) and if the object has no existing business object children. +datapolicySetupPage = Depending on the laws of your country (Example Article 5 of the GDPR), personal data must be kept for a period not exceeding the duration the data is needed for the purpose for which it was collected, except for archival purposes.
This module will make an anonymization automatically after a certain duration without events (the duration which you will have indicated below) and if the object has no existing business object children. NB_MONTHS = %s months ONE_YEAR = 1 year NB_YEARS = %s years From a4c397a68b723cb4390eef76f2fcb83cd4d4a33e Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 29 Jan 2025 18:35:54 +0100 Subject: [PATCH 342/602] fix: php 8 warning --- htdocs/expensereport/tpl/expensereport_linktofile.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php b/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php index 2e02e7b8808..b789360e3f2 100644 --- a/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php +++ b/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php @@ -95,7 +95,7 @@ if (!getDolGlobalString('EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES')) { } print '
'; - print $thumbshown ? $thumbshown : img_mime($minifile); + print $thumbshown ? $thumbshown : ($minifile ? img_mime($minifile): ''); print '
'; if (empty($urlforhref) || empty($thumbshown)) { From 4d8f28f22bd42202cbd981b0a23d49e3f5bf7dcb Mon Sep 17 00:00:00 2001 From: sonikf <93765174+sonikf@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:36:31 +0200 Subject: [PATCH 343/602] fix typo --- htdocs/langs/en_US/website.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 212147881ff..892960dc610 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -92,7 +92,7 @@ DisableSiteFirst=Put website offline first MyContainerTitle=My web site title AnotherContainer=This is how to include content of another page/container (you may have an error here if you enable dynamic code because the embedded subcontainer may not exists) SorryWebsiteIsCurrentlyOffLine=Sorry, this website is currently off line. Please comme back later... -WEBSITE_USE_WEBSITE_ACCOUNTS=Enable the table of web site account fo thirdparties +WEBSITE_USE_WEBSITE_ACCOUNTS=Enable the table of web site account for thirdparties WEBSITE_USE_WEBSITE_ACCOUNTSTooltip=Enable the table to store the web site accounts (login/pass) for each third party YouMustDefineTheHomePage=You must first define the default Home page OnlyEditionOfSourceForGrabbedContentFuture=Warning: Creating a web page by importing an external web page is reserved for experienced users. Depending on the complexity of source page, the result of importation may differ from the original. Also if the source page uses common CSS styles or conflicting JavaScript, it may break the look or features of the Website editor when working on this page. This method is a quicker way to create a page but it is recommended to create your new page from scratch or from a suggested page template.
Note also that the inline editor might not work correctly when used on a grabbed external page. From d66ff94c72f89e5521a63c46ea1ccb9c0315214e Mon Sep 17 00:00:00 2001 From: sonikf <93765174+sonikf@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:38:49 +0200 Subject: [PATCH 344/602] fix trans --- htdocs/langs/en_US/members.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 4d1c90f9e1b..f730d33d5f4 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -191,7 +191,7 @@ MembersStatisticsByRegion=Members statistics by region NbOfMembers=Total number of members NbOfActiveMembers=Total number of current active members NoValidatedMemberYet=No validated members found -MembersByCountryDesc=This screen shows you the statistics of members by countries. +MembersByCountryDesc=This screen shows you the statistics of members by country. MembersByCountryDesc2=Graphs and charts depend on the availability of the Google online graph service as well as on the availability of a working internet connection. MembersByStateDesc=This screen show you statistics of members by state/provinces/canton. MembersByTownDesc=This screen show you statistics of members by town. From 9984652a4502bc47d9472179279577502f6f2230 Mon Sep 17 00:00:00 2001 From: sonikf <93765174+sonikf@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:43:00 +0200 Subject: [PATCH 345/602] fix trans --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index a5e14c17cb8..4166884bdf2 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2606,5 +2606,5 @@ AttributeCodeHelp=A code of your choice (without special chars and spaces) to id ThereIsMoreThanXAnswers=There is more than %s answers with your filter. Please add more filters... PdfAddTermOfSaleHelp=You can upload the terms and conditions of sale file at the bottom of this setup page WarningOnlineSignature=Please note that this function allows a person (customer, supplier...) to insert, online, the image of his signature in the PDF document. As for a handwritten signature, such a signature can be made by anyone and might not have the same legal value as a legal electronic signature system going through an authorized trusted third party. If you need this level of security, you can contact an integrator for more information or check for addons on www.dolistore.org. -UploadExtensionRestriction=File exension list forbidden to upload +UploadExtensionRestriction=List of forbidden file extensions to upload UploadExtensionRestrictionExemple=htm, html, shtml, js, php From 841cd5f570ad44c9fabdc4b30ce73c3bf8e26445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 19:08:08 +0100 Subject: [PATCH 346/602] enhance member types list --- htdocs/adherents/type.php | 45 +++++++++++++++++++++++---------- htdocs/langs/en_US/members.lang | 4 ++- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 91f105c48b8..25bdae150a5 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -9,7 +9,7 @@ * Copyright (C) 2020 Josep Lluís Amador * Copyright (C) 2021 Waël Almoman * Copyright (C) 2024 MDW - * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024-2025 Frédéric France * * 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 @@ -136,6 +136,9 @@ $result = restrictedArea($user, 'adherent', $rowid, 'adherent_type'); */ $error = 0; +// Selection of new fields +include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers $search_ref = ""; $search_lastname = ""; @@ -329,8 +332,14 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print ''; print ''; print ''; + print ''; + print ''; print ''; + $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; + $htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields with user setup + $selectedfields = ($mode != 'kanban' ? $htmlofselectarray : ''); + // $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print_barre_liste($langs->trans("MembersTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'members', 0, $newcardbutton, '', $limit, 0, 0, 1); @@ -341,11 +350,18 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print '
 '.$langs->trans("Ref").''.$langs->trans($arrayfields['t.libelle']['label']).''.$langs->trans("MembersNature").''.$langs->trans("Ref").''.$langs->trans("Label").''.$langs->trans("MembersNature").''.$langs->trans("MembershipDuration").''.$langs->trans("SubscriptionRequired").''.$langs->trans("Amount").''.$langs->trans("VoteAllowed").''.$langs->trans("Status").' 
rowid.'">'.img_edit().''; - print $membertype->getNomUrl(1); - //'.img_object($langs->trans("ShowType"),'group').' '.$objp->rowid.' - print ''.dol_escape_htmltag($objp->label).''; + print $membertype->getNomUrl(1); + //'.img_object($langs->trans("ShowType"),'group').' '.$objp->rowid.' + print ''.dol_escape_htmltag($objp->label).''; if ($objp->morphy == 'phy') { diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 4d1c90f9e1b..a4cecf6be82 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -191,7 +191,7 @@ MembersStatisticsByRegion=Members statistics by region NbOfMembers=Total number of members NbOfActiveMembers=Total number of current active members NoValidatedMemberYet=No validated members found -MembersByCountryDesc=This screen shows you the statistics of members by countries. +MembersByCountryDesc=This screen shows you the statistics of members by countries. MembersByCountryDesc2=Graphs and charts depend on the availability of the Google online graph service as well as on the availability of a working internet connection. MembersByStateDesc=This screen show you statistics of members by state/provinces/canton. MembersByTownDesc=This screen show you statistics of members by town. @@ -251,3 +251,5 @@ XSubsriptionErrors=%s subscription(s) where in error CreateSubscription=Create subscription WarningNoComplementaryActionDone=No Complementary action on recording will be executed with this massaction NewMembership=New membership +Caneditamount=Can edit amount +Morphy=Moral or physical From 0338b5c65851f490b3458113a642b57a43910ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 19:11:03 +0100 Subject: [PATCH 347/602] enhance member types list --- htdocs/adherents/type.php | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 25bdae150a5..c1584085f12 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -355,12 +355,15 @@ if (!$rowid && $action != 'create' && $action != 'edit') { } if (!empty($arrayfields['t.rowid']['checked'])) { print ''.$langs->trans("Ref").''.$langs->trans($arrayfields['t.libelle']['label']).''.$langs->trans("MembersNature").''.$langs->trans("MembershipDuration").''.$langs->trans("SubscriptionRequired").''.dol_escape_htmltag($objp->label).''; - if ($objp->morphy == 'phy') { - print $langs->trans("Physical"); - } elseif ($objp->morphy == 'mor') { - print $langs->trans("Moral"); - } else { - print $langs->trans("MorAndPhy"); + if (!empty($arrayfields['t.morphy']['checked'])) { + print ''; + if ($objp->morphy == 'phy') { + print $langs->trans("Physical"); + } elseif ($objp->morphy == 'mor') { + print $langs->trans("Moral"); + } else { + print $langs->trans("MorAndPhy"); + } + print ''; if ($objp->duration) { From de131d7d8ef262862c7dd18af426a82f4fbc3df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 29 Jan 2025 19:13:23 +0100 Subject: [PATCH 348/602] enhance member types list --- htdocs/adherents/type.php | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index c1584085f12..5e0a853eaa8 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -365,7 +365,10 @@ if (!$rowid && $action != 'create' && $action != 'edit') { print ''.$langs->trans("MembersNature").''.$langs->trans("MembershipDuration").''.$langs->trans("MembershipDuration").''.$langs->trans("SubscriptionRequired").''.$langs->trans("Amount").''.$langs->trans("CanEditAmountShort").''; - if ($objp->duration) { - $duration_value = intval($objp->duration); - if ($duration_value > 1) { - $dur = array("i" => $langs->trans("Minutes"), "h" => $langs->trans("Hours"), "d" => $langs->trans("Days"), "w" => $langs->trans("Weeks"), "m" => $langs->trans("Months"), "y" => $langs->trans("Years")); - } else { - $dur = array("i" => $langs->trans("Minute"), "h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year")); + if (!empty($arrayfields['t.duration']['checked'])) { + print ''; + if ($objp->duration) { + $duration_value = intval($objp->duration); + if ($duration_value > 1) { + $dur = array("i" => $langs->trans("Minutes"), "h" => $langs->trans("Hours"), "d" => $langs->trans("Days"), "w" => $langs->trans("Weeks"), "m" => $langs->trans("Months"), "y" => $langs->trans("Years")); + } else { + $dur = array("i" => $langs->trans("Minute"), "h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year")); + } + $unit = preg_replace("/[^a-zA-Z]+/", "", $objp->duration); + print max(1, $duration_value).' '.$dur[$unit]; } - $unit = preg_replace("/[^a-zA-Z]+/", "", $objp->duration); - print max(1, $duration_value).' '.$dur[$unit]; + print ''.yn($objp->subscription).''.$langs->trans("MembershipDuration").''.$langs->trans("SubscriptionRequired").''.$langs->trans("Amount").''.$langs->trans("CanEditAmountShort").''.$langs->trans("VoteAllowed").''.$langs->trans("Status").''.$langs->trans("SubscriptionRequired").''.$langs->trans("Amount").''.$langs->trans("CanEditAmountShort").''.$langs->trans("VoteAllowed").''.$langs->trans("Status").''.yn($objp->subscription).''.(is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount)).''.yn($objp->caneditamount).''.yn($objp->vote).''.$membertype->getLibStatut(5).''.yn($objp->subscription).''.(is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount)).''.yn($objp->caneditamount).''.yn($objp->vote).''.$membertype->getLibStatut(5).'rowid.'">'.img_edit().'
'.$form->editfieldkey('VATIsUsed', 'assujtva_value', '', $object, 0).''; - print ''; // Assujeti par default en creation + print ''; // Assujeti par default en creation print '
'; - $texttoshow = null; + $texttoshow = ''; if ($cron['jobtype'] == 'method') { $text = $langs->trans("CronClass"); $texttoshow = $langs->trans('CronModule').': '.$module.'
'; @@ -6658,7 +6646,7 @@ if ($module == 'initmodule') { print '
'; print ' '.$langs->trans("PathToModulePackage").' : '; - if (!dol_is_file($outputfilezip)) { + if ($outputfilezip === null || !dol_is_file($outputfilezip)) { print ''.$langs->trans("FileNotYetGenerated").''; } else { $relativepath = $modulelowercase.'/bin/'.$FILENAMEZIP; diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index ad7fc9de5de..8825d6419ea 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -453,7 +453,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { } print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help').' 
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''.$langs->trans('Qty'); if ($this->bom->bomtype == 0) { - print ' ('.$langs->trans("ForAQuantityOf", $this->bom->qty).')'; + print ' ('.$langs->trans("ForAQuantityOf", (string) $this->bom->qty).')'; } else { - print ' ('.$langs->trans("ForAQuantityToConsumeOf", $this->bom->qty).')'; + print ' ('.$langs->trans("ForAQuantityToConsumeOf", (string) $this->bom->qty).')'; } // Unit print ''.$langs->trans('Unit'); diff --git a/htdocs/mrp/class/moline.class.php b/htdocs/mrp/class/moline.class.php index fc157e805a3..a7758c292cd 100644 --- a/htdocs/mrp/class/moline.class.php +++ b/htdocs/mrp/class/moline.class.php @@ -2,7 +2,7 @@ /* Copyright (C) 2017 Laurent Destailleur * Copyright (C) 2020 Lenin Rivas * Copyright (C) 2023-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 William Mead * * This program is free software; you can redistribute it and/or modify @@ -301,7 +301,7 @@ class MoLine extends CommonObjectLine if ($key == 't.rowid') { $sqlwhere[] = $this->db->sanitize($key)." = ".((int) $value); } elseif (strpos($key, 'date') !== false) { - $sqlwhere[] = $this->db->sanitize($key)." = '".$this->db->idate($value)."'"; + $sqlwhere[] = $this->db->sanitize($key)." = '".$this->db->idate((int) $value)."'"; } else { $sqlwhere[] = $this->db->sanitize($key)." LIKE '%".$this->db->escape($this->db->escapeforlike($value))."%'"; } diff --git a/htdocs/mrp/index.php b/htdocs/mrp/index.php index 2bc3b1432af..eeaa7f8acf7 100644 --- a/htdocs/mrp/index.php +++ b/htdocs/mrp/index.php @@ -6,6 +6,7 @@ * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2019-2024 Frédéric France * Copyright (C) 2024 Alexandre Spangaro + * Copyright (C) 2025 MDW * * 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 @@ -207,7 +208,7 @@ if ($resql) { $staticbom->status = $obj->status; print '
'.$staticbom->getNomUrl(1, 32).''.$staticbom->getNomUrl(1, '32').''.dol_print_date($db->jdate($obj->datem), 'dayhour').''.$staticbom->getLibStatut(3).'
'.$staticmo->getNomUrl(1, 32).''.$staticmo->getNomUrl(1, '32').''.dol_print_date($db->jdate($obj->datem), 'dayhour').''.$staticmo->getLibStatut(3).'
'; if ($objp->fk_project != 0) { - print $movement->get_origin($objp->fk_project, 'project'); + print $objectlist->get_origin($objp->fk_project, 'project'); } print '
'; print $temps; @@ -1146,7 +1146,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Extrafields Line if (!empty($extrafields)) { $line->fetch_optionals(); - $temps = $line->showOptionals($extrafields, 'edit', array(), '', '', 1, 'line'); + $temps = $line->showOptionals($extrafields, 'edit', array(), '', '', '1', 'line'); if (!empty($temps)) { $colspan = 10; print '
'; @@ -1307,7 +1307,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Extrafields Line if (!empty($extrafields)) { $line->fetch_optionals(); - $temps = $line->showOptionals($extrafields, 'view', array(), '', '', 1, 'line'); + $temps = $line->showOptionals($extrafields, 'view', array(), '', '', '1', 'line'); if (!empty($temps)) { $colspan = 10; print '
'; diff --git a/htdocs/mrp/tpl/linkedobjectblock.tpl.php b/htdocs/mrp/tpl/linkedobjectblock.tpl.php index e4cfc5b8435..3ba0e580b5b 100644 --- a/htdocs/mrp/tpl/linkedobjectblock.tpl.php +++ b/htdocs/mrp/tpl/linkedobjectblock.tpl.php @@ -3,7 +3,7 @@ * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2014 Marcos García * Copyright (C) 2013-2020 Charlene BENKE - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * * 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 @@ -60,7 +60,7 @@ if ($object->element == 'mo') { echo '
' . $langs->trans("ManufacturingOrder"); if (!empty($showImportButton) && $conf->global->MAIN_ENABLE_IMPORT_LINKED_OBJECT_LINES) { - print ' '; echo '' . $objectlink->getNomUrl(1) . ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; print ''.img_object($langs->trans("Preview"), 'pdf').''; diff --git a/htdocs/admin/bank.php b/htdocs/admin/bank.php index 2e1afa189cc..a01086727f0 100644 --- a/htdocs/admin/bank.php +++ b/htdocs/admin/bank.php @@ -3,7 +3,7 @@ * Copyright (C) 2010-2016 Juanjo Menent * Copyright (C) 2013-2018 Philippe Grand * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -413,7 +413,7 @@ foreach ($dirmodels as $reldir) { //$htmltooltip .= '
' . $langs->trans("WatermarkOnDraftOrders") . ': ' . yn($module->option_draft_watermark, 1, 1); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); if (getDolGlobalString('CHEQUERECEIPTS_ADDON').'.php' == $file) { // If module is the one used, we show existing errors if (!empty($module->error)) { diff --git a/htdocs/admin/contract.php b/htdocs/admin/contract.php index ae676a142fd..d9bd0289527 100644 --- a/htdocs/admin/contract.php +++ b/htdocs/admin/contract.php @@ -1,7 +1,7 @@ * Copyright (C) 2011-2018 Philippe Grand - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -316,7 +316,7 @@ foreach ($dirmodels as $reldir) { } print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, -1, 0); + print $form->textwithpicto('', $htmltooltip, -1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, -1, 0); + print $form->textwithpicto('', $htmltooltip, -1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); if (getDolGlobalString('FACTURE_ADDON') . '.php' == $file) { // If module is the one used, we show existing errors if (!empty($module->error)) { @@ -608,7 +608,7 @@ foreach ($dirmodels as $reldir) { print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); if (getDolGlobalString('PAYMENT_ADDON') . '.php' == $file) { // If module is the one used, we show existing errors if (!empty($module->error)) { diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index 49ca75ee0a1..f9c26ab8616 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -7,7 +7,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2011-2013 Juanjo Menent - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -346,7 +346,7 @@ foreach ($dirmodels as $reldir) { } print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; print ''.img_object($langs->trans("Preview"), 'pdf').''; diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index ba4886573f3..c10d59f2939 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -6,7 +6,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2011-2018 Philippe Grand - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -320,7 +320,7 @@ foreach ($dirmodels as $reldir) { } print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; print ''.img_object($langs->trans("Preview"), 'pdf').''; diff --git a/htdocs/admin/supplier_payment.php b/htdocs/admin/supplier_payment.php index 3419f734977..20d89893d8e 100644 --- a/htdocs/admin/supplier_payment.php +++ b/htdocs/admin/supplier_payment.php @@ -2,7 +2,7 @@ /* Copyright (C) 2015 Juanjo Menent * Copyright (C) 2016 Laurent Destailleur * Copyright (C) 2020 Maxime DEMAREST - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -307,7 +307,7 @@ foreach ($dirmodels as $reldir) { } print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); if (getDolGlobalString("PAYMENT_ADDON").'.php' == $file) { // If module is the one used, we show existing errors if (!empty($module->error)) { @@ -421,7 +421,7 @@ foreach ($dirmodels as $reldir) { $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; print ''.img_object($langs->trans("Preview"), 'pdf').''; diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 4c3fc9ee12c..c642ff20383 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -8,7 +8,7 @@ * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2011-2013 Juanjo Menent * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2024 MDW + * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -336,7 +336,7 @@ foreach ($dirmodels as $reldir) { } print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
- textwithpicto('', $langs->trans("ExtrafieldParamHelpselect"), 1, 0, '', 0, 2, 'helpvalue1')?> - textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '
'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 0, '', 0, 2, 'helpvalue2')?>
- textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '
'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 0, '', 0, 2, 'helpvalue3')?>
- textwithpicto('', $langs->trans("ExtrafieldParamHelplink").'

'.$langs->trans("Examples").':
'.$listofexamplesforlink, 1, 0, '', 0, 2, 'helpvalue4')?>
- textwithpicto('', $langs->trans("ExtrafieldParamHelpPassword"), 1, 0, '', 0, 2, 'helpvalue5')?> - textwithpicto('', $langs->trans("ExtrafieldParamHelpSeparator"), 1, 0, '', 0, 2, 'helpvalue6')?> + textwithpicto('', $langs->trans("ExtrafieldParamHelpselect"), 1, 'info', '', 0, 2, 'helpvalue1')?> + textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '
'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 'info', '', 0, 2, 'helpvalue2')?>
+ textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '
'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 'info', '', 0, 2, 'helpvalue3')?>
+ textwithpicto('', $langs->trans("ExtrafieldParamHelplink").'

'.$langs->trans("Examples").':
'.$listofexamplesforlink, 1, 'info', '', 0, 2, 'helpvalue4')?>
+ textwithpicto('', $langs->trans("ExtrafieldParamHelpPassword"), 1, 'info', '', 0, 2, 'helpvalue5')?> + textwithpicto('', $langs->trans("ExtrafieldParamHelpSeparator"), 1, 'info', '', 0, 2, 'helpvalue6')?>
- textwithpicto('', $langs->trans("ExtrafieldParamHelpselect"), 1, 0, '', 0, 2, 'helpvalue1')?> - textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '
'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 0, '', 0, 2, 'helpvalue2')?>
- textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '
'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 0, '', 0, 2, 'helpvalue3')?>
- textwithpicto('', $langs->trans("ExtrafieldParamHelplink").'

'.$langs->trans("Examples").':
'.$listofexamplesforlink, 1, 0, '', 0, 2, 'helpvalue4')?>
- textwithpicto('', $langs->trans("ExtrafieldParamHelpPassword"), 1, 0, '', 0, 2, 'helpvalue5')?> - textwithpicto('', $langs->trans("ExtrafieldParamHelpSeparator"), 1, 0, '', 0, 2, 'helpvalue6')?> + textwithpicto('', $langs->trans("ExtrafieldParamHelpselect"), 1, 'info', '', 0, 2, 'helpvalue1')?> + textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '
'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 'info', '', 0, 2, 'helpvalue2')?>
+ textwithpicto('', $langs->trans("ExtrafieldParamHelpsellist").(getDolGlobalInt('MAIN_FEATUREES_LEVEL') > 0 ? '
'.$langs->trans("ExtrafieldParamHelpsellist2") : ''), 1, 'info', '', 0, 2, 'helpvalue3')?>
+ textwithpicto('', $langs->trans("ExtrafieldParamHelplink").'

'.$langs->trans("Examples").':
'.$listofexamplesforlink, 1, 'info', '', 0, 2, 'helpvalue4')?>
+ textwithpicto('', $langs->trans("ExtrafieldParamHelpPassword"), 1, 'info', '', 0, 2, 'helpvalue5')?> + textwithpicto('', $langs->trans("ExtrafieldParamHelpSeparator"), 1, 'info', '', 0, 2, 'helpvalue6')?>
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).''.$form->textwithpicto('', $tooltip, 1, 'help').'  '; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print '
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, 'info'); print ''; - print $form->textwithpicto('', $tooltip, 1, 1); + print $form->textwithpicto('', $tooltip, 1, 'help'); print ''."\n"; - $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $object->fk_element, 'fk_element', 24, 0, 0, 1, 0, 0, 'maxwidth500', $object->fk_project); + $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $object->fk_element, 'fk_element', 24, 0, '', 1, 0, 0, 'maxwidth500', (string) $object->fk_project); print ''; print '
'.$langs->trans("Project").''; - print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); + print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(($soc->id > 0 ? $soc->id : -1), (string) $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); print ' id).'">'; print '
'.$langs->trans("Project").''; print img_picto('', 'project', 'class="pictofixedwidth"'); - print $formproject->select_projects(-1, $projectid, 'fk_project', 0, 0, 1, 1, 0, 0, 0, '', 1); + print $formproject->select_projects(-1, (string) $projectid, 'fk_project', 0, 0, 1, 1, 0, 0, 0, '', 1); print '
'.$langs->trans('Project').''; print img_picto('', 'project', 'class="pictofixedwidth"'); - print $formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); + print $formproject->select_projects(($socid > 0 ? $socid : -1), (string) $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); print ' id.($fac_rec ? '&fac_rec='.$fac_rec : '')).'">'; print '
'.$langs->trans("Project").''; - print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(-1, $fk_project, 'fk_project', 0, 0, 1, 1, 0, 0, 0, '', 1); + print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(-1, (string) $fk_project, 'fk_project', 0, 0, 1, 1, 0, 0, 0, '', 1); print '
'.$langs->trans("Parent").''; print img_picto('', 'project', 'class="pictofixedwidth"'); - $formproject->select_projects(-1, $object->fk_project, 'fk_project', 64, 0, 1, 1, 0, 0, 0, '', 0, 0, '', '', ''); + $formproject->select_projects(-1, (string) $object->fk_project, 'fk_project', 64, 0, 1, 1, 0, 0, 0, '', 0, 0, '', '', ''); print '
'.$langs->trans("OpportunityStatus").''; print '
'; - print $formproject->selectOpportunityStatus('opp_status', $object->opp_status, 1, 0, 0, 0, 'minwidth150 inline-block valignmiddle', 1, 1); + print $formproject->selectOpportunityStatus('opp_status', (string) $object->opp_status, 1, 0, 0, 0, 'minwidth150 inline-block valignmiddle', 1, 1); // Opportunity probability print ' %'; @@ -1442,8 +1442,8 @@ if ($action == 'create' && $user->hasRight('projet', 'creer')) { print '
'; $html_name_status = ($action == 'edit_opp_status') ? 'opp_status' : 'none'; $html_name_percent = ($action == 'edit_opp_status') ? 'opp_percent' : 'none'; - $percent_value = (GETPOSTISSET('opp_percent') ? GETPOST('opp_percent') : (strcmp($object->opp_percent, '') ? vatrate($object->opp_percent) : '')); - $formproject->formOpportunityStatus($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->opp_status, $percent_value, $html_name_status, $html_name_percent); + $percent_value = (GETPOSTISSET('opp_percent') ? GETPOSTINT('opp_percent') : (strcmp($object->opp_percent, '') ? vatrate($object->opp_percent) : '')); + $formproject->formOpportunityStatus($_SERVER['PHP_SELF'].'?socid='.$object->id, (string) $object->opp_status, $percent_value, $html_name_status, $html_name_percent); print '
'.$mvsProd->getNomUrl(1).''; if ($tablename == 'actioncomm') { + '@phan-var-force ActionComm $element'; print dol_print_date($element->datep, 'dayhour'); if ($element->datef && $element->datef > $element->datep) { print " - ".dol_print_date($element->datef, 'dayhour'); } } elseif (in_array($tablename, array('projet_task'))) { - $tmpprojtime = $element->getSumOfAmount($idofelementuser ? $elementuser : '', $dates, $datee); // $element is a task. $elementuser may be empty + '@phan-var-force Task $element'; + $tmpprojtime = $element->getSumOfAmount($idofelementuser ? $elementuser : '', (string) $dates, (string) $datee); // $element is a task. $elementuser may be empty print ''; print convertSecondToTime($tmpprojtime['nbseconds'], 'allhourmin'); print ''; @@ -1466,6 +1490,7 @@ foreach ($listofreferent as $key => $value) { $tmpuser->fetch($element->fk_user); print $tmpuser->getNomUrl(1, '', 48); } elseif ($tablename == 'don' || $tablename == 'stock_mouvement') { + '@phan-var-force Don|MouvementStock $element'; if ($element->fk_user_author > 0) { $tmpuser2 = new User($db); $tmpuser2->fetch($element->fk_user_author); @@ -1474,12 +1499,14 @@ foreach ($listofreferent as $key => $value) { } elseif ($tablename == 'projet_task' && $key == 'element_time') { // if $key == 'project_task', we don't want details per user print $elementuser->getNomUrl(1); } elseif ($tablename == 'payment_various') { // payment label + '@phan-var-force PaymentVarious $element'; print $element->label; } print ''; print convertSecondToTime($element->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY); $total_duration += $element->duration; @@ -1492,10 +1519,13 @@ foreach ($listofreferent as $key => $value) { $total_ht_by_line = null; $othermessage = ''; if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') { + '@phan-var-force Don|ChargeSociales|PaymentVarious|Salary $element'; $total_ht_by_line = $element->amount; } elseif ($tablename == 'fichinter') { + '@phan-var-force FichInter $element'; $total_ht_by_line = $element->getAmount(); } elseif ($tablename == 'stock_mouvement') { + '@phan-var-force MouvementStock $element'; $total_ht_by_line = $element->price * abs($element->qty); } elseif (in_array($tablename, array('projet_task'))) { if (isModEnabled('salaries')) { @@ -1509,6 +1539,7 @@ foreach ($listofreferent as $key => $value) { $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled")); } } elseif ($key == 'loan') { + '@phan-var-force Loan $element'; $total_ht_by_line = $element->capital; } else { $total_ht_by_line = $element->total_ht; @@ -1546,10 +1577,13 @@ foreach ($listofreferent as $key => $value) { if (empty($value['disableamount'])) { $total_ttc_by_line = null; if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') { + '@phan-var-force Don|ChargeSociales|PaymentVarious $element'; $total_ttc_by_line = $element->amount; } elseif ($tablename == 'fichinter') { + '@phan-var-force Fichinter $element'; $total_ttc_by_line = $element->getAmount(); } elseif ($tablename == 'stock_mouvement') { + '@phan-var-force MouvementStock $element'; $total_ttc_by_line = $element->price * abs($element->qty); } elseif ($tablename == 'projet_task') { if (isModEnabled('salaries')) { @@ -1560,6 +1594,7 @@ foreach ($listofreferent as $key => $value) { $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled")); } } elseif ($key == 'loan') { + '@phan-var-force Loan $element'; $total_ttc_by_line = $element->capital - $element->getSumPayment(); } else { $total_ttc_by_line = $element->total_ttc; @@ -1605,6 +1640,7 @@ foreach ($listofreferent as $key => $value) { print $element->progress.' %'; } } elseif ($tablename == 'stock_mouvement') { + '@phan-var-force MouvementStock $element'; print $element->getLibStatut(3); } else { print $element->getLibStatut(5); @@ -1662,7 +1698,7 @@ foreach ($listofreferent as $key => $value) { print '
'.$langs->trans("Number").': '.$i.''; - print convertSecondToTime($total_time, 'allhourmin'); + print convertSecondToTime((int) $total_time, 'allhourmin'); print ''; print '