From 0d00a27a1cd800f7815743abf7a975ea9e274082 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 29 Jun 2025 12:43:14 +0200 Subject: [PATCH 01/73] QUAL Use GetDolGlobalString (#34662) * Typo comment * Use getGlobalString --- htdocs/accountancy/class/bookkeeping.class.php | 2 +- htdocs/accountancy/journal/bankjournal.php | 4 ++-- htdocs/eventorganization/class/conferenceorbooth.class.php | 2 +- .../class/conferenceorboothattendee.class.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index b3c557845f8..1a334eff40c 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -1193,7 +1193,7 @@ class BookKeeping extends CommonObject // Manage filter if (is_array($filter)) { // deprecated, use $filter = USF syntax - dol_syslog("You are using a deprecated use of fetchAll. filter parameter mus be an USF string now.", LOG_WARNING); + dol_syslog("You are using a deprecated use of fetchAll. filter parameter must be an USF string now.", LOG_WARNING); $sqlwhere = array(); if (count($filter) > 0) { foreach ($filter as $key => $value) { diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index fa3573ae087..663b9d04d3f 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -5,7 +5,7 @@ * Copyright (C) 2012 Regis Houssin * Copyright (C) 2013 Christophe Battarel * Copyright (C) 2013-2022 Open-DSI - * Copyright (C) 2013-2024 Alexandre Spangaro + * Copyright (C) 2013-2025 Alexandre Spangaro * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2013-2014 Olivier Geffroy * Copyright (C) 2017-2025 Frédéric France @@ -673,7 +673,7 @@ if (!$error && $action == 'writebookkeeping' && $user->hasRight('accounting', 'b $accountingaccountpayment->fetch(0, getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT'), true); $accountingaccountexpensereport = new AccountingAccount($db); - $accountingaccountexpensereport->fetch(0, $conf->global->ACCOUNTING_ACCOUNT_EXPENSEREPORT, true); + $accountingaccountexpensereport->fetch(0, getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT'), true); $accountingaccountsuspense = new AccountingAccount($db); $accountingaccountsuspense->fetch(0, getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE'), true); diff --git a/htdocs/eventorganization/class/conferenceorbooth.class.php b/htdocs/eventorganization/class/conferenceorbooth.class.php index 1d0110bc8ac..09017e310b3 100644 --- a/htdocs/eventorganization/class/conferenceorbooth.class.php +++ b/htdocs/eventorganization/class/conferenceorbooth.class.php @@ -332,7 +332,7 @@ class ConferenceOrBooth extends ActionComm // Manage filter if (is_array($filter)) { // deprecated, use $filter = USF syntax - dol_syslog("You are using a deprecated use of fetchAll. filter parameter mus be an USF string now.", LOG_WARNING); + dol_syslog("You are using a deprecated use of fetchAll. filter parameter must be an USF string now.", LOG_WARNING); $sqlwhere = array(); if (count($filter) > 0) { foreach ($filter as $key => $value) { diff --git a/htdocs/eventorganization/class/conferenceorboothattendee.class.php b/htdocs/eventorganization/class/conferenceorboothattendee.class.php index 9b25b5cd546..c13ff500b44 100644 --- a/htdocs/eventorganization/class/conferenceorboothattendee.class.php +++ b/htdocs/eventorganization/class/conferenceorboothattendee.class.php @@ -476,7 +476,7 @@ class ConferenceOrBoothAttendee extends CommonObject // Manage filter if (is_array($filter)) { // deprecated, use $filter = USF syntax - dol_syslog("You are using a deprecated use of fetchAll. filter parameter mus be an USF string now.", LOG_WARNING); + dol_syslog("You are using a deprecated use of fetchAll. filter parameter must be an USF string now.", LOG_WARNING); $sqlwhere = array(); if (count($filter) > 0) { foreach ($filter as $key => $value) { From 621b91097a834498298a7e1e8fbfaf8d178b63f7 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 29 Jun 2025 12:45:29 +0200 Subject: [PATCH 02/73] Translate term Incoterm (#34661) --- htdocs/core/class/commonincoterm.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonincoterm.class.php b/htdocs/core/class/commonincoterm.class.php index 35aad528570..97e10e0724e 100644 --- a/htdocs/core/class/commonincoterm.class.php +++ b/htdocs/core/class/commonincoterm.class.php @@ -91,6 +91,8 @@ trait CommonIncoterm */ public function getIncotermsForPDF() { + global $langs; + $sql = "SELECT code FROM ".$this->db->prefix()."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; $resql = $this->db->query($sql); if ($resql) { @@ -98,7 +100,7 @@ trait CommonIncoterm if ($num > 0) { $res = $this->db->fetch_object($resql); if ($res) { - return 'Incoterm : '.$res->code.' - '.$this->location_incoterms; + return $langs->trans("IncotermLabel").': '.$res->code.' - '.$this->location_incoterms; } else { return $res; } From 95027c5dfd09bc423595ce3f51f3726ef2056964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charl=C3=A8ne=20Benke?= <1179011+defrance@users.noreply.github.com> Date: Sun, 29 Jun 2025 12:45:52 +0200 Subject: [PATCH 03/73] php error on takepos admin (#34660) --- htdocs/takepos/receipt.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/receipt.php b/htdocs/takepos/receipt.php index b393e095dad..f60be35d0b3 100644 --- a/htdocs/takepos/receipt.php +++ b/htdocs/takepos/receipt.php @@ -79,7 +79,7 @@ if (!$user->hasRight('takepos', 'run')) { top_htmlhead('', '', 1); -if ((string) $place != '') { +if ((string) $place != '' && !empty($_SESSION["takeposterminal"])) { $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture"; $sql .= " WHERE ref = '(PROV-POS".$db->escape($_SESSION["takeposterminal"]."-".$place).")'"; $sql .= " AND entity IN (".getEntity('invoice').")"; From 5253346fca00d795c718102a94fa778744bef55e Mon Sep 17 00:00:00 2001 From: atm-lena <52402938+atm-lena@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:21:03 +0200 Subject: [PATCH 04/73] Delete entity filter in user fetch (#34348) * Delete entity filter in user fetch * Fetch without entity if fetch by id --------- Co-authored-by: atm-lena Co-authored-by: Laurent Destailleur --- htdocs/user/class/user.class.php | 33 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index ff614aeeea6..518f2418bc6 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -590,21 +590,25 @@ class User extends CommonObject $sql .= " LEFT JOIN ".$this->db->prefix()."c_departements as d ON u.fk_state = d.rowid"; $sql .= " LEFT JOIN ".$this->db->prefix()."establishment as s ON u.fk_establishment = s.rowid"; - if ($entity < 0) { - if ((!isModEnabled('multicompany') || !getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) && (!empty($user->entity))) { - $sql .= " WHERE u.entity IN (0, ".((int) $conf->entity).")"; - } else { - $sql .= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database - } + if ($id > 0) { + $sql .= " WHERE u.rowid = ".((int) $id); } else { - // The fetch was forced on an entity - if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) { - $sql .= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database + if ($entity < 0) { + if ((! isModEnabled('multicompany') || ! getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) && (! empty($user->entity))) { + $sql .= " WHERE u.entity IN (0, " . ((int) $conf->entity) . ")"; + } else { + $sql .= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database + } } else { - if ($entity != '' && $entity == 0) { // If $entity = 0 - $sql .= " WHERE u.entity = 0"; - } else { // if $entity is -1 or > 0 - $sql .= " WHERE u.entity IN (0, ".((int) ($entity > 0 ? $entity : $conf->entity)).")"; + // The fetch was forced on an entity + if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) { + $sql .= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database + } else { + if ($entity != '' && $entity == 0) { // If $entity = 0 + $sql .= " WHERE u.entity = 0"; + } else { // if $entity is -1 or > 0 + $sql .= " WHERE u.entity IN (0, " . ((int) ($entity > 0 ? $entity : $conf->entity)) . ")"; + } } } } @@ -622,9 +626,8 @@ class User extends CommonObject $sql .= ")"; } elseif ($fk_socpeople > 0) { $sql .= " AND u.fk_socpeople = ".((int) $fk_socpeople); - } else { - $sql .= " AND u.rowid = ".((int) $id); } + $sql .= " ORDER BY u.entity ASC"; // Avoid random result when there is 2 login in 2 different entities if ($sid) { From 1d37671c67f6bbc83e1e57b6d26fcb2d1e86844f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 15:35:03 +0300 Subject: [PATCH 05/73] PHPStan > Update baseline (#34664) Co-authored-by: Dolibot --- dev/build/phpstan/phpstan-baseline.neon | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index a079a1d0cc9..eb215259415 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -1854,12 +1854,6 @@ parameters: count: 2 path: ../../../htdocs/api/class/api_documents.class.php - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 1 - path: ../../../htdocs/api/class/api_documents.class.php - - message: '#^Variable \$disablevirusscan in empty\(\) always exists and is always falsy\.$#' identifier: empty.variable From 00ff8d490a85ae36d797b7da9579710fa33a5e9a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 30 Jun 2025 15:14:09 +0200 Subject: [PATCH 06/73] Debug v22 --- .../societe/doc/doc_generic_odt.modules.php | 2 +- htdocs/societe/admin/societe.php | 26 ++----------------- 2 files changed, 3 insertions(+), 25 deletions(-) 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 0f55fbda3d3..949c8abf977 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -95,7 +95,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc */ public function info($langs) { - global $conf, $langs; + global $langs; // Load traductions files required by page $langs->loadLangs(array("companies", "errors")); diff --git a/htdocs/societe/admin/societe.php b/htdocs/societe/admin/societe.php index d36aeb1222e..51bb8c4a407 100644 --- a/htdocs/societe/admin/societe.php +++ b/htdocs/societe/admin/societe.php @@ -206,21 +206,6 @@ if ($action == "setaccountancycodecustomerinvoicemandatory") { setEventMessages($langs->trans("Error"), null, 'errors'); } } -/* This code is not needed anymore as we can use the setprofid functions instead with key = 'VAT_INTRA' -//Activate Set vat id unique -if ($action == "setvatintraunique") { - $setvatintraunique = GETPOSTINT('value'); - $res = dolibarr_set_const($db, "SOCIETE_VAT_INTRA_UNIQUE", $setvatintraunique, 'yesno', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - if (!$error) { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } else { - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} -*/ //Activate Set ref in list if ($action == "setaddrefinlist") { @@ -627,22 +612,15 @@ foreach ($dirsociete as $dirroot) { // Activate / Disable if (in_array($name, $def)) { - print "\n"; - //if ($conf->global->COMPANY_ADDON_PDF != "$name") - //{ + print ''."\n"; print 'scandir.'&label='.urlencode($module->name).'">'; print img_picto($langs->trans("Enabled"), 'switch_on'); print ''; - //} - //else - //{ - // print img_picto($langs->trans("Enabled"),'on'); - //} print ""; } else { if (versioncompare($module->phpmin, versionphparray()) > 0) { print ''."\n"; - print img_picto(dol_escape_htmltag($langs->trans("ErrorModuleRequirePHPVersion", implode('.', $module->phpmin))), 'switch_off'); + print img_picto(dol_escape_htmltag($langs->trans("ErrorModuleRequirePHPVersion", implode('.', $module->phpmin))), 'switch_off', 'class="opacitymedium"'); print ""; } else { print ''."\n"; From fae0093b51b2dae6e02369b65552ddecd5f6ef7f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 30 Jun 2025 15:47:49 +0200 Subject: [PATCH 07/73] Debug v22 --- htdocs/api/class/api_access.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php index c7c92f9514d..6a81b2e5975 100644 --- a/htdocs/api/class/api_access.class.php +++ b/htdocs/api/class/api_access.class.php @@ -124,7 +124,7 @@ class DolibarrApiAccess implements iAuthenticate $api_key = preg_replace('/^Bearer\s+/i', '', empty($headers['Authorization']) ? '' : $headers['Authorization']); }; - $api_key = dol_string_nounprintableascii($api_key); + $api_key = dol_string_nounprintableascii($api_key, 1); if (preg_match('/^dolcrypt:/i', $api_key)) { throw new RestException(503, 'Bad value for the API key. An API key should not start with dolcrypt:'); From 8c8a45a191b134a0ee40684e9c4e429fed8ff2b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 30 Jun 2025 15:49:20 +0200 Subject: [PATCH 08/73] Doc --- 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 0f49eebe26b..cecf472c14b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1996,7 +1996,7 @@ function dol_string_nounprintableascii($str, $removetabcrlf = 1) } /** - * Returns text slugified (no special char, separator is "-". + * Returns text slugified (lowercase and no special char, separator is "-"). * * @param string $stringtoslugify String to slugify * @return string Slugified string From c0b4af32befb25911b16cfb255a41d29544344ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charl=C3=A8ne=20Benke?= <1179011+defrance@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:25:44 +0200 Subject: [PATCH 09/73] FIX some error on donation list (#34666) * fix some error on donation list * Update list.php --------- Co-authored-by: Laurent Destailleur --- htdocs/don/paiement/list.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/don/paiement/list.php b/htdocs/don/paiement/list.php index 03ccaf366d2..5251af4c646 100644 --- a/htdocs/don/paiement/list.php +++ b/htdocs/don/paiement/list.php @@ -87,6 +87,8 @@ if (!$sortfield) { $search_all = trim(GETPOST('search_all', 'alphanohtml')); +$object = new Don($db); + $morejs = array(); $morecss = array(); @@ -163,7 +165,6 @@ if (empty($reshook)) { */ $form = new Form($db); -$donationstatic = new Don($db); $companystatic = new Societe($db); $bankline = new AccountLine($db); $accountstatic = new Account($db); @@ -471,7 +472,7 @@ if (!empty($arrayfields['c.code']['checked'])) { $totalarray['nbfield']++; } if (!empty($arrayfields['pd.num_paiement']['checked'])) { - print_liste_field_titre($arrayfields['pd.num_paiement']['label'], $_SERVER["PHP_SELF"], "pd.num_payment", '', $param, '', $sortfield, $sortorder, '', $arrayfields['p.num_paiement']['tooltip']); + print_liste_field_titre($arrayfields['pd.num_paiement']['label'], $_SERVER["PHP_SELF"], "pd.num_payment", '', $param, '', $sortfield, $sortorder, '', $arrayfields['pd.num_paiement']['tooltip']); $totalarray['nbfield']++; } if (!empty($arrayfields['transaction']['checked'])) { @@ -565,7 +566,7 @@ while ($i < $imaxinloop) { if ($obj->soc_id > 0) { print $companystatic->getNomUrl(1, '', 24); } else { - print $donationstatic->societe = $obj->societe; + print $object->societe = $obj->societe; } print ''; if (!$i) { From e5aae4d7e3ca0e4e87465534f49310e6594b479d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 30 Jun 2025 17:39:38 +0200 Subject: [PATCH 10/73] Debug v22 --- htdocs/holiday/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index a3563b839e4..5ea2ef1dfe6 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -90,7 +90,7 @@ if (!$sortorder) { $sortorder = "DESC"; } if (!$sortfield) { - $sortfield = "cp.ref"; + $sortfield = "cp.date_debut"; } $search_all = trim(GETPOST('search_all', 'alphanohtml')); From 2941cf1c1930510559cdecbb358d1ac1322a0a32 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Jul 2025 15:29:15 +0200 Subject: [PATCH 11/73] Fix CI --- htdocs/core/lib/ftp.lib.php | 64 ++++++++++++++----------------------- 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/htdocs/core/lib/ftp.lib.php b/htdocs/core/lib/ftp.lib.php index e071b2c0de5..96e4caf9996 100644 --- a/htdocs/core/lib/ftp.lib.php +++ b/htdocs/core/lib/ftp.lib.php @@ -1,7 +1,7 @@ +/* Copyright (C) 2022-2025 Laurent Destailleur * Copyright (C) 2022 Anthony Berton - * 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 @@ -122,9 +122,9 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect /** * Tell if an entry is a FTP directory * - * @param resource $connect_id Connection handler - * @param string $dir Directory - * @return int 1=directory, 0=not a directory + * @param resource|FTP\Connection $connect_id Connection handler + * @param string $dir Directory + * @return int 1=directory, 0=not a directory */ function ftp_isdir($connect_id, $dir) { @@ -139,13 +139,11 @@ function ftp_isdir($connect_id, $dir) /** * Tell if an entry is a FTP directory * - * @param resource $connect_id Connection handler - * @return boolean Result of closing + * @param resource|FTP\Connection $connect_id Connection handler + * @return boolean Result of closing */ function dol_ftp_close($connect_id) { - global $conf; - // Close FTP connection if ($connect_id) { if (!getDolGlobalString('FTP_CONNECT_WITH_SFTP')) { @@ -158,21 +156,18 @@ function dol_ftp_close($connect_id) /** * Delete a FTP file * - * @param resource $connect_id Connection handler - * @param string $file File - * @param string $newsection $newsection + * @param resource|FTP\Connection $connect_id Connection handler + * @param string $file File + * @param string $newsection Directory * @return bool */ function dol_ftp_delete($connect_id, $file, $newsection) { - global $conf; - if (getDolGlobalString('FTP_CONNECT_WITH_SFTP')) { $newsection = ssh2_sftp_realpath($connect_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 } // Remote file - $filename = $file; $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; $newremotefileiso = mb_convert_encoding($remotefile, 'ISO-8859-1'); @@ -188,22 +183,19 @@ function dol_ftp_delete($connect_id, $file, $newsection) /** * Download a FTP file * - * @param resource $connect_id Connection handler - * @param string $localfile The local file path - * @param string $file The remote file path - * @param string $newsection $newsection + * @param resource|FTP\Connection $connect_id Connection handler + * @param string $localfile The local file path + * @param string $file The remote file path + * @param string $newsection Directory * @return bool|resource */ function dol_ftp_get($connect_id, $localfile, $file, $newsection) { - global $conf; - if (getDolGlobalString('FTP_CONNECT_WITH_SFTP')) { $newsection = ssh2_sftp_realpath($connect_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 } // Remote file - $filename = $file; $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; $newremotefileiso = mb_convert_encoding($remotefile, 'ISO-8859-1'); @@ -217,22 +209,19 @@ function dol_ftp_get($connect_id, $localfile, $file, $newsection) /** * Upload a FTP file * - * @param resource $connect_id Connection handler - * @param string $file File name - * @param string $localfile The path to the local file - * @param string $newsection $newsection + * @param resource|FTP\Connection $connect_id Connection handler + * @param string $file File name + * @param string $localfile The path to the local file + * @param string $newsection Directory * @return bool */ function dol_ftp_put($connect_id, $file, $localfile, $newsection) { - global $conf; - if (getDolGlobalString('FTP_CONNECT_WITH_SFTP')) { $newsection = ssh2_sftp_realpath($connect_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 } // Remote file - $filename = $file; $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; $newremotefileiso = mb_convert_encoding($remotefile, 'ISO-8859-1'); @@ -246,21 +235,18 @@ function dol_ftp_put($connect_id, $file, $localfile, $newsection) /** * Remove FTP directory * - * @param resource $connect_id Connection handler - * @param string $file File - * @param string $newsection $newsection + * @param resource|FTP\Connection $connect_id Connection handler + * @param string $file File + * @param string $newsection Directory * @return bool */ function dol_ftp_rmdir($connect_id, $file, $newsection) { - global $conf; - if (getDolGlobalString('FTP_CONNECT_WITH_SFTP')) { $newsection = ssh2_sftp_realpath($connect_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 } // Remote file - $filename = $file; $remotefile = $newsection.(preg_match('@[\\\/]$@', $newsection) ? '' : '/').$file; $newremotefileiso = mb_convert_encoding($remotefile, 'ISO-8859-1'); @@ -275,15 +261,13 @@ function dol_ftp_rmdir($connect_id, $file, $newsection) /** * Remove FTP directory * - * @param resource $connect_id Connection handler - * @param string $newdir Dir create - * @param string $newsection $newsection + * @param resource|FTP\Connection $connect_id Connection handler + * @param string $newdir Dir create + * @param string $newsection Directory * @return bool|string */ function dol_ftp_mkdir($connect_id, $newdir, $newsection) { - global $conf; - if (getDolGlobalString('FTP_CONNECT_WITH_SFTP')) { $newsection = ssh2_sftp_realpath($connect_id, ".").'/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 } From e2c2f73e9c1d784c9ff271b2ea97c88d166047bf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Jul 2025 15:39:16 +0200 Subject: [PATCH 12/73] Fix CI --- htdocs/admin/agenda_extsites.php | 2 +- htdocs/admin/bank.php | 2 +- htdocs/core/ajax/fetchCategories.php | 2 +- htdocs/core/lib/admin.lib.php | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/admin/agenda_extsites.php b/htdocs/admin/agenda_extsites.php index e0cff71b11e..b57ce438207 100644 --- a/htdocs/admin/agenda_extsites.php +++ b/htdocs/admin/agenda_extsites.php @@ -292,7 +292,7 @@ while ($i <= $MAXAGENDA) { print ''; // Color (Possible colors are limited by Google) print ''; - print $formother->selectColor((GETPOST("AGENDA_EXT_COLOR" . $key) ? GETPOST("AGENDA_EXT_COLOR" . $key) : getDolGlobalString($color)), "AGENDA_EXT_COLOR" . $key, 'extsitesconfig', 1, array(), 'hideifnotset'); + print $formother->selectColor((GETPOST("AGENDA_EXT_COLOR" . $key) ? GETPOST("AGENDA_EXT_COLOR" . $key) : getDolGlobalString($color)), "AGENDA_EXT_COLOR" . $key, '', 1, array(), 'hideifnotset'); print ''; // Calendar active by default print ''; diff --git a/htdocs/admin/bank.php b/htdocs/admin/bank.php index cf979b7991e..3df9ef80fde 100644 --- a/htdocs/admin/bank.php +++ b/htdocs/admin/bank.php @@ -478,7 +478,7 @@ if (getDolGlobalInt('BANK_COLORIZE_MOVEMENT')) { print ''.$langs->trans("BankColorizeMovementName".$key).""; // Color print ''; - print $formother->selectColor((GETPOST("BANK_COLORIZE_MOVEMENT_COLOR".$key) ? GETPOST("BANK_COLORIZE_MOVEMENT_COLOR".$key) : getDolGlobalString($color)), "BANK_COLORIZE_MOVEMENT_COLOR".$key, 'bankmovementcolorconfig', 1, array(), 'right hideifnotset'); + print $formother->selectColor((GETPOST("BANK_COLORIZE_MOVEMENT_COLOR".$key) ? GETPOST("BANK_COLORIZE_MOVEMENT_COLOR".$key) : getDolGlobalString($color)), "BANK_COLORIZE_MOVEMENT_COLOR".$key, '', 1, array(), 'right hideifnotset'); print ''; print ""; $i++; diff --git a/htdocs/core/ajax/fetchCategories.php b/htdocs/core/ajax/fetchCategories.php index 046dad57967..11bda9a2628 100644 --- a/htdocs/core/ajax/fetchCategories.php +++ b/htdocs/core/ajax/fetchCategories.php @@ -102,7 +102,7 @@ if ($action == "getCategories") { } */ foreach ($cate_arbo as $categ) { - $response[] = array('id' => $categ['id'], 'label' => $categ['label'], 'fulllabel' => $categ['fulllabel'], 'htmlforoption' => dolPrintHTML($categ['fulllabel']), 'htmlforattribute' => dolPrintHTMLForAttribute($categ['data-html']), 'color' => $categ['color']); + $response[] = array('id' => $categ['id'], 'label' => $categ['label'], 'fulllabel' => $categ['fulllabel'], 'htmlforoption' => dolPrintHTML((string) $categ['fulllabel']), 'htmlforattribute' => dolPrintHTMLForAttribute((string) $categ['data-html']), 'color' => $categ['color']); } $response =json_encode($response); echo $response; diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 79a6b011f48..008d593686b 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1736,8 +1736,8 @@ function complete_elementList_with_modules(&$elementList) /** * Show array with constants to edit * - * @param array|array $tableau Array of constants array('key'=>array('type'=>type, 'label'=>label) - * where type can be 'string', 'text', 'textarea', 'html', 'yesno', 'emailtemplate:xxx', ... + * @param array|array $tableau Array of constants array('key'=>array('type'=>type, 'label'=>label, 'tooltip'=>tooltip) + * where type can be 'string', 'text', 'textarea', 'html', 'yesno', 'emailtemplate:xxx', ... * @param int<2,3> $strictw3c 0=Include form into table (deprecated), 1=Form is outside table to respect W3C (deprecated), 2=No form nor button at all, 3=No form nor button at all and each field has a unique name (form is output by caller, recommended) (typed as int<2,3> to highlight the deprecated values) * @param string $helptext Tooltip help to use for the column name of values * @param string $text Text to use for the column name of values From ac892efb42e5cdba01f3c0555a652fbfddb97da2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Jul 2025 16:22:21 +0200 Subject: [PATCH 13/73] Fix CI --- htdocs/core/ajax/fetchCategories.php | 1 + htdocs/core/class/html.form.class.php | 26 ++++++++-------- htdocs/core/lib/admin.lib.php | 2 +- htdocs/core/lib/company.lib.php | 2 +- htdocs/projet/tasks/time.php | 6 ++-- htdocs/stripe/class/stripe.class.php | 43 +++++++++++++++------------ htdocs/webservices/server_user.php | 1 - 7 files changed, 43 insertions(+), 38 deletions(-) diff --git a/htdocs/core/ajax/fetchCategories.php b/htdocs/core/ajax/fetchCategories.php index 11bda9a2628..edf01744795 100644 --- a/htdocs/core/ajax/fetchCategories.php +++ b/htdocs/core/ajax/fetchCategories.php @@ -1,5 +1,6 @@ + * Copyright (C) 2025 Laurent Destailleur * * 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/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 4b1bb5c5ba1..66463f273b9 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5823,7 +5823,7 @@ class Form * @param int<0,1> $include [=0] Removed or 1=Keep only * @param string $morecss More CSS * @param int<0,2> $useempty 0=No empty value, 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. Default is 1. - * @return string|array|array|array String list or Array of categories + * @return string|array|array|array String list or Array of categories * @see select_categories() */ public function select_all_categories($type, $selected = '', $htmlname = "parent", $maxlength = 64, $fromid = 0, $outputmode = 0, $include = 0, $morecss = '', $useempty = 1) @@ -10821,18 +10821,18 @@ class Form /** * Return HTML code to output a photo * - * @param string $modulepart Key to define module concerned ('societe', 'userphoto', 'memberphoto') + * @param string $modulepart Key to define module concerned ('societe', 'userphoto', 'memberphoto') * @param Societe|Adherent|Contact|User|CommonObject $object Object containing data to retrieve file name - * @param int $width Width of photo - * @param int $height Height of photo (auto if 0) - * @param int<0,1> $caneditfield Add edit fields - * @param string $cssclass CSS name to use on img for photo - * @param string $imagesize 'mini', 'small' or '' (original) - * @param int<0,1> $addlinktofullsize Add link to fullsize image - * @param int<0,1> $cache 1=Accept to use image in cache - * @param ''|'user'|'environment' $forcecapture '', 'user' or 'environment'. Force parameter capture on HTML input file element to ask a smartphone to allow to open camera to take photo. Auto if ''. - * @param int<0,1> $noexternsourceoverwrite No overwrite image with extern source (like 'gravatar' or other module) - * @return string HTML code to output photo + * @param int $width Width of photo + * @param int $height Height of photo (auto if 0) + * @param int<0,1> $caneditfield Add edit fields + * @param string $cssclass CSS name to use on img for photo + * @param string $imagesize 'mini', 'small' or '' (original) + * @param int<0,1> $addlinktofullsize Add link to fullsize image + * @param int<0,1> $cache 1=Accept to use image in cache + * @param ''|'user'|'environment' $forcecapture '', 'user' (user-facing camera) or 'environment' ('outward-facing camera'). Force the parameter capture on HTML input file element to ask a smartphone to allow to open camera to take photo. Auto if ''. + * @param int<0,1> $noexternsourceoverwrite No overwrite image with extern source (like 'gravatar' or other module) + * @return string HTML code to output photo * @see getImagePublicURLOfObject() */ public static function showphoto($modulepart, $object, $width = 100, $height = 0, $caneditfield = 0, $cssclass = 'photowithmargin', $imagesize = '', $addlinktofullsize = 1, $cache = 0, $forcecapture = '', $noexternsourceoverwrite = 0) @@ -11010,7 +11010,7 @@ class Form if ($maxmin > 0) { $ret .= ''; // MAX_FILE_SIZE must precede the field type=file } - $ret .= ''; + $ret .= ''; $ret .= ''; $ret .= ''; } diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 008d593686b..fc051325f7e 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1736,7 +1736,7 @@ function complete_elementList_with_modules(&$elementList) /** * Show array with constants to edit * - * @param array|array $tableau Array of constants array('key'=>array('type'=>type, 'label'=>label, 'tooltip'=>tooltip) + * @param array|array $tableau Array of constants array('key'=>array('type'=>type, 'label'=>label, 'tooltip'=>tooltip) * where type can be 'string', 'text', 'textarea', 'html', 'yesno', 'emailtemplate:xxx', ... * @param int<2,3> $strictw3c 0=Include form into table (deprecated), 1=Form is outside table to respect W3C (deprecated), 2=No form nor button at all, 3=No form nor button at all and each field has a unique name (form is output by caller, recommended) (typed as int<2,3> to highlight the deprecated values) * @param string $helptext Tooltip help to use for the column name of values diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index cb6b48a3178..2b0973b36f7 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1657,7 +1657,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl // Photo - Name if (!empty($arrayfields['t.name']['checked'])) { print ''; - print $form->showphoto('contact', $contactstatic, 0, 0, 0, 'photorefnoborder valignmiddle marginrightonly', 'small', 1, 0, '1'); + print $form->showphoto('contact', $contactstatic, 0, 0, 0, 'photorefnoborder valignmiddle marginrightonly', 'small', 1, 0, 'user'); print $contactstatic->getNomUrl(0, '', 0, '&backtopage='.urlencode($backtopage)); print ''; } diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 8dba6c5297d..a4a3044a3cc 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1490,7 +1490,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print $langs->trans('ServiceToUseOnLines'); print ''; print ''; - $form->select_produits(0, 'productid', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500'); + $form->select_produits(0, 'productid', 1, 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500'); print ''; print ''; } @@ -1884,7 +1884,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (isModEnabled("service") && !empty($projectstatic->thirdparty) && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) { print ''; print img_picto('', 'service'); - print $form->select_produits((GETPOSTISSET('fk_product') ? GETPOSTINT("fk_product") : ''), 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth150', 0, '', null, 1); + print $form->select_produits((GETPOSTISSET('fk_product') ? GETPOSTINT("fk_product") : ''), 'fk_product', 1, 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth150', 0, '', null, 1); print ''; } } @@ -2415,7 +2415,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; if ($action == 'editline' && GETPOSTINT('lineid') == $task_time->rowid) { print img_picto('', 'service'); - print $form->select_produits($task_time->fk_product, 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500', 0, '', null, 1); + print $form->select_produits($task_time->fk_product, 'fk_product', 1, 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500', 0, '', null, 1); } elseif (!empty($task_time->fk_product)) { $product = new Product($db); $resultFetch = $product->fetch($task_time->fk_product); diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index cc08b6dfb19..384053a2e02 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -345,22 +345,22 @@ class Stripe extends CommonObject * Note: This is used when option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is on when making a payment from the public/payment/newpayment.php page * but not when using the STRIPE_USE_NEW_CHECKOUT. * - * @param float $amount Amount - * @param string $currency_code Currency code - * @param string $tag Tag - * @param string $description Description - * @param ?CommonObject $object Object to pay with Stripe - * @param ?string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() - * @param ?string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect - * @param int<0,1> $status Status (0=test, 1=live) - * @param int<0,1> $usethirdpartyemailforreceiptemail 1=use thirdparty email for receipt - * @param 'automatic'|'manual' $mode automatic=automatic confirmation/payment when conditions are ok, manual=need to call confirm() on intent - * @param bool $confirmnow false=default, true=try to confirm immediately after create (if conditions are ok) - * @param ?string $payment_method 'pm_....' (if known) - * @param int<0,1> $off_session If we use an already known payment method to pay when customer is not available during the checkout flow. - * @param int<0,1> $noidempotency_key Do not use the idempotency_key when creating the PaymentIntent - * @param int $did ID of an existing line into llx_prelevement_demande (Dolibarr intent). If provided, no new line will be created. - * @return ?\Stripe\PaymentIntent Stripe PaymentIntent or null if not found and failed to create + * @param float $amount Amount + * @param string $currency_code Currency code + * @param string $tag Tag + * @param string $description Description + * @param ?CommonObject $object Object to pay with Stripe + * @param ?string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() + * @param ?string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect + * @param int<0,1> $status Status (0=test, 1=live) + * @param int<0,1> $usethirdpartyemailforreceiptemail 1=use thirdparty email for receipt + * @param 'automatic'|'manual'|'terminal' $mode Automatic=automatic confirmation/payment when conditions are ok, manual=need to call confirm() on intent, terminal=manual + * @param bool $confirmnow False=default, true=try to confirm immediately after create (if conditions are ok) + * @param ?string $payment_method 'pm_....' (if known) + * @param int<0,1> $off_session If we use an already known payment method to pay when customer is not available during the checkout flow. + * @param int<0,1> $noidempotency_key Do not use the idempotency_key when creating the PaymentIntent + * @param int $did ID of an existing line into llx_prelevement_demande (Dolibarr intent). If provided, no new line will be created. + * @return ?\Stripe\PaymentIntent Stripe PaymentIntent or null if not found and failed to create */ public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false, $payment_method = null, $off_session = 0, $noidempotency_key = 1, $did = 0) { @@ -454,6 +454,8 @@ class Stripe extends CommonObject } } + $stripemode = $mode; + // list of payment method types $paymentmethodtypes = array("card"); $descriptor = dol_trunc($tag, 10, 'right', 'UTF-8', 1); @@ -476,8 +478,11 @@ class Stripe extends CommonObject if (getDolGlobalInt('STRIPE_SOFORT')) { $paymentmethodtypes[] = "sofort"; } - if (getDolGlobalInt('STRIPE_CARD_PRESENT') && $mode == 'terminal') { - $paymentmethodtypes = array("card_present"); + if ($mode == 'terminal') { + if (getDolGlobalInt('STRIPE_CARD_PRESENT')) { + $paymentmethodtypes = array("card_present"); + } + $stripemode = 'manual'; } global $dolibarr_main_url_root; @@ -486,7 +491,7 @@ class Stripe extends CommonObject $dataforintent = array( "confirm" => $confirmnow, // try to confirm immediately after create (if conditions are ok) - "confirmation_method" => $mode, + "confirmation_method" => $stripemode, "amount" => $stripeamount, "currency" => $currency_code, "payment_method_types" => $paymentmethodtypes, // When payment_method_types is set, return_url is not required but payment mode can't be managed from dashboard diff --git a/htdocs/webservices/server_user.php b/htdocs/webservices/server_user.php index 2dad6640085..d94ea65c236 100644 --- a/htdocs/webservices/server_user.php +++ b/htdocs/webservices/server_user.php @@ -575,7 +575,6 @@ function createUserFromThirdparty($authentication, $thirdpartywithuser) $thirdparty->fax = $thirdpartywithuser['fax']; $thirdparty->email = $thirdpartywithuser['email']; $thirdparty->url = $thirdpartywithuser['url']; - $thirdparty->ape = $thirdpartywithuser['ape']; $thirdparty->idprof1 = $thirdpartywithuser['prof1']; $thirdparty->idprof2 = $thirdpartywithuser['prof2']; $thirdparty->idprof3 = $thirdpartywithuser['prof3']; From 60feb166c0dd108d7abc28a1e0dd6850a96610d7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Jul 2025 16:35:26 +0200 Subject: [PATCH 14/73] Fix CI --- htdocs/webservices/server_user.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/webservices/server_user.php b/htdocs/webservices/server_user.php index d94ea65c236..2dec629eae3 100644 --- a/htdocs/webservices/server_user.php +++ b/htdocs/webservices/server_user.php @@ -561,7 +561,7 @@ function createUserFromThirdparty($authentication, $thirdpartywithuser) $sql = "SELECT rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."c_country"; $sql .= " WHERE active = 1"; - $sql .= " AND code='".$db->escape($thirdparty->country_code)."'"; + $sql .= " AND code = '".$db->escape($thirdparty->country_code)."'"; $resql = $db->query($sql); if ($resql) { @@ -575,12 +575,12 @@ function createUserFromThirdparty($authentication, $thirdpartywithuser) $thirdparty->fax = $thirdpartywithuser['fax']; $thirdparty->email = $thirdpartywithuser['email']; $thirdparty->url = $thirdpartywithuser['url']; - $thirdparty->idprof1 = $thirdpartywithuser['prof1']; - $thirdparty->idprof2 = $thirdpartywithuser['prof2']; - $thirdparty->idprof3 = $thirdpartywithuser['prof3']; - $thirdparty->idprof4 = $thirdpartywithuser['prof4']; - $thirdparty->idprof5 = $thirdpartywithuser['prof5']; - $thirdparty->idprof6 = $thirdpartywithuser['prof6']; + $thirdparty->idprof1 = $thirdpartywithuser['profid1']; + $thirdparty->idprof2 = $thirdpartywithuser['profid2']; + $thirdparty->idprof3 = $thirdpartywithuser['profid3']; + $thirdparty->idprof4 = $thirdpartywithuser['profid4']; + $thirdparty->idprof5 = $thirdpartywithuser['profid5']; + $thirdparty->idprof6 = $thirdpartywithuser['profid6']; $thirdparty->client = (int) $thirdpartywithuser['client']; $thirdparty->fournisseur = (int) $thirdpartywithuser['fournisseur']; From 24e3f31ba1e36d51455cccf3a6cda8c136f21b4a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Jul 2025 20:32:31 +0200 Subject: [PATCH 15/73] Fix CI --- htdocs/core/class/html.form.class.php | 3 +-- htdocs/core/lib/admin.lib.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 66463f273b9..49a7f816320 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1,5 +1,4 @@ * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2004 Benoit Mortier @@ -5823,7 +5822,7 @@ class Form * @param int<0,1> $include [=0] Removed or 1=Keep only * @param string $morecss More CSS * @param int<0,2> $useempty 0=No empty value, 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. Default is 1. - * @return string|array|array|array String list or Array of categories + * @return string|array|array|array String list or Array of categories * @see select_categories() */ public function select_all_categories($type, $selected = '', $htmlname = "parent", $maxlength = 64, $fromid = 0, $outputmode = 0, $include = 0, $morecss = '', $useempty = 1) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index fc051325f7e..04856a3fe5c 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1736,7 +1736,7 @@ function complete_elementList_with_modules(&$elementList) /** * Show array with constants to edit * - * @param array|array $tableau Array of constants array('key'=>array('type'=>type, 'label'=>label, 'tooltip'=>tooltip) + * @param array|array $tableau Array of constants array('key'=>array('type'=>type, 'label'=>label, 'tooltip'=>tooltip) * where type can be 'string', 'text', 'textarea', 'html', 'yesno', 'emailtemplate:xxx', ... * @param int<2,3> $strictw3c 0=Include form into table (deprecated), 1=Form is outside table to respect W3C (deprecated), 2=No form nor button at all, 3=No form nor button at all and each field has a unique name (form is output by caller, recommended) (typed as int<2,3> to highlight the deprecated values) * @param string $helptext Tooltip help to use for the column name of values From 787bd1d278f30b5afeb4cf51c3f8bb24db77015b Mon Sep 17 00:00:00 2001 From: Jyhere Date: Tue, 1 Jul 2025 20:34:09 +0200 Subject: [PATCH 16/73] CHANGE: ternary simplification (#34675) --- htdocs/bom/class/api_boms.class.php | 2 +- htdocs/comm/action/class/api_agendaevents.class.php | 2 +- htdocs/comm/propal/class/api_proposals.class.php | 2 +- htdocs/commande/class/api_orders.class.php | 2 +- htdocs/compta/facture/class/api_invoices.class.php | 2 +- htdocs/contrat/class/api_contracts.class.php | 2 +- htdocs/don/class/api_donations.class.php | 2 +- htdocs/expedition/class/api_shipments.class.php | 2 +- .../expensereport/class/api_expensereports.class.php | 2 +- htdocs/fichinter/class/api_interventions.class.php | 2 +- htdocs/fourn/class/api_supplier_invoices.class.php | 2 +- htdocs/fourn/class/api_supplier_orders.class.php | 2 +- .../class/api_knowledgemanagement.class.php | 2 +- .../template/class/api_mymodule.class.php | 2 +- htdocs/mrp/class/api_mos.class.php | 2 +- htdocs/partnership/class/api_partnerships.class.php | 2 +- htdocs/product/class/api_products.class.php | 10 +++++----- htdocs/projet/class/api_projects.class.php | 2 +- htdocs/projet/class/api_tasks.class.php | 2 +- htdocs/reception/class/api_receptions.class.php | 2 +- htdocs/recruitment/class/api_recruitments.class.php | 4 ++-- htdocs/societe/class/api_contacts.class.php | 2 +- .../class/api_supplier_proposals.class.php | 2 +- htdocs/ticket/class/api_tickets.class.php | 2 +- htdocs/user/class/api_users.class.php | 4 ++-- htdocs/workstation/class/api_workstations.class.php | 2 +- htdocs/zapier/class/api_zapier.class.php | 2 +- 27 files changed, 33 insertions(+), 33 deletions(-) diff --git a/htdocs/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php index 9b03c33ea48..d1b0561cb73 100644 --- a/htdocs/bom/class/api_boms.class.php +++ b/htdocs/bom/class/api_boms.class.php @@ -116,7 +116,7 @@ class Boms extends DolibarrApi $obj_ret = array(); $tmpobject = new BOM($this->db); - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; + $socid = DolibarrApiAccess::$user->socid ?: ''; $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object diff --git a/htdocs/comm/action/class/api_agendaevents.class.php b/htdocs/comm/action/class/api_agendaevents.class.php index aacc32d6ddc..ebe9174c1b1 100644 --- a/htdocs/comm/action/class/api_agendaevents.class.php +++ b/htdocs/comm/action/class/api_agendaevents.class.php @@ -130,7 +130,7 @@ class AgendaEvents extends DolibarrApi } // case of external user - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socid = DolibarrApiAccess::$user->socid ?: 0; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 43a182561dc..d004b27175f 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -193,7 +193,7 @@ class Proposals extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index ab01d260763..3c45c5f3362 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -186,7 +186,7 @@ class Orders extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 514a399ed66..8123044ea62 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -203,7 +203,7 @@ class Invoices extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php index e4fbcca102e..d6ecec7a5ef 100644 --- a/htdocs/contrat/class/api_contracts.class.php +++ b/htdocs/contrat/class/api_contracts.class.php @@ -114,7 +114,7 @@ class Contracts extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index 6b7ad5b0444..27a422c2f2d 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -110,7 +110,7 @@ class Donations extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->hasRight('societe', 'client', 'voir') && !$socids)) { diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php index d5b6382ef0f..fac4ccb9de4 100644 --- a/htdocs/expedition/class/api_shipments.class.php +++ b/htdocs/expedition/class/api_shipments.class.php @@ -112,7 +112,7 @@ class Shipments extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index d74a8a7a09a..462b76623d7 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -131,7 +131,7 @@ class ExpenseReports extends DolibarrApi $obj_ret = array(); // case of external user, $societe param is ignored and replaced by user's socid - //$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $societe; + //$socid = DolibarrApiAccess::$user->socid ?: $societe; $sql = "SELECT t.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."expensereport AS t LEFT JOIN ".MAIN_DB_PREFIX."expensereport_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php index da498e6159e..023c1604c95 100644 --- a/htdocs/fichinter/class/api_interventions.class.php +++ b/htdocs/fichinter/class/api_interventions.class.php @@ -147,7 +147,7 @@ class Interventions extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index bfdd2adc449..0e8a46dffd6 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -117,7 +117,7 @@ class SupplierInvoices extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index ab61fee4f25..9cf52085dfe 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -111,7 +111,7 @@ class SupplierOrders extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php index 3d64ee58d55..12d387ab09c 100644 --- a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php +++ b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php @@ -147,7 +147,7 @@ class KnowledgeManagement extends DolibarrApi throw new RestException(403); } - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socid = DolibarrApiAccess::$user->socid ?: 0; $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php index 6292c20020c..a264a2b668c 100644 --- a/htdocs/modulebuilder/template/class/api_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php @@ -121,7 +121,7 @@ class MyModuleApi extends DolibarrApi throw new RestException(403); } - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socid = DolibarrApiAccess::$user->socid ?: 0; $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object diff --git a/htdocs/mrp/class/api_mos.class.php b/htdocs/mrp/class/api_mos.class.php index 11e68b4c722..6fb2532df67 100644 --- a/htdocs/mrp/class/api_mos.class.php +++ b/htdocs/mrp/class/api_mos.class.php @@ -108,7 +108,7 @@ class Mos extends DolibarrApi $obj_ret = array(); $tmpobject = new Mo($this->db); - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socid = DolibarrApiAccess::$user->socid ?: 0; $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object diff --git a/htdocs/partnership/class/api_partnerships.class.php b/htdocs/partnership/class/api_partnerships.class.php index 0b3cd1513d1..119e2931a0f 100644 --- a/htdocs/partnership/class/api_partnerships.class.php +++ b/htdocs/partnership/class/api_partnerships.class.php @@ -113,7 +113,7 @@ class Partnerships extends DolibarrApi throw new RestException(403); } - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socid = DolibarrApiAccess::$user->socid ?: 0; $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 07e4d544378..79034aaf5b3 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -204,7 +204,7 @@ class Products extends DolibarrApi $obj_ret = array(); - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; + $socid = DolibarrApiAccess::$user->socid ?: ''; $sql = "SELECT t.rowid, t.ref, t.ref_ext"; $sql .= " FROM ".$this->db->prefix()."product as t"; @@ -798,7 +798,7 @@ class Products extends DolibarrApi throw new RestException(400, 'API not available: this mode of pricing is not enabled by setup'); } - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; + $socid = DolibarrApiAccess::$user->socid ?: ''; if ($socid > 0 && $socid != $thirdparty_id) { throw new RestException(403, 'Getting prices for all customers or for the customer ID '.$thirdparty_id.' is not allowed for login '.DolibarrApiAccess::$user->login); } @@ -918,7 +918,7 @@ class Products extends DolibarrApi throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; + $socid = DolibarrApiAccess::$user->socid ?: ''; if ($socid > 0 && $socid != $fourn_id) { throw new RestException(403, 'Adding purchase price for the supplier ID '.$fourn_id.' is not allowed for login '.DolibarrApiAccess::$user->login); } @@ -1016,7 +1016,7 @@ class Products extends DolibarrApi $obj_ret = array(); // Force id of company for external users - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; + $socid = DolibarrApiAccess::$user->socid ?: ''; if ($socid > 0) { if ($supplier != $socid || empty($supplier)) { throw new RestException(403, 'As an external user, you can request only for your supplier id = '.$socid); @@ -1129,7 +1129,7 @@ class Products extends DolibarrApi throw new RestException(403); } - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; + $socid = DolibarrApiAccess::$user->socid ?: ''; $result = $this->product->fetch($id, $ref, $ref_ext, $barcode); if (!$result) { diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 842522ff561..b1395c436d4 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -209,7 +209,7 @@ class Projects extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index 508d3eff782..0c2b1c6b859 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -120,7 +120,7 @@ class Tasks extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socids = DolibarrApiAccess::$user->socid ?: 0; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/reception/class/api_receptions.class.php b/htdocs/reception/class/api_receptions.class.php index f860207193a..05eb602f526 100644 --- a/htdocs/reception/class/api_receptions.class.php +++ b/htdocs/reception/class/api_receptions.class.php @@ -112,7 +112,7 @@ class Receptions extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/recruitment/class/api_recruitments.class.php b/htdocs/recruitment/class/api_recruitments.class.php index 29e908f1e91..d8ec32e7405 100644 --- a/htdocs/recruitment/class/api_recruitments.class.php +++ b/htdocs/recruitment/class/api_recruitments.class.php @@ -152,7 +152,7 @@ class Recruitments extends DolibarrApi throw new RestException(403); } - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socid = DolibarrApiAccess::$user->socid ?: 0; $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object @@ -268,7 +268,7 @@ class Recruitments extends DolibarrApi throw new RestException(403); } - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socid = DolibarrApiAccess::$user->socid ?: 0; $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index f53e7d323fb..5a449dc3a81 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -193,7 +193,7 @@ class Contacts extends DolibarrApi } // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/supplier_proposal/class/api_supplier_proposals.class.php b/htdocs/supplier_proposal/class/api_supplier_proposals.class.php index d2fa85fa69d..308f899886b 100644 --- a/htdocs/supplier_proposal/class/api_supplier_proposals.class.php +++ b/htdocs/supplier_proposal/class/api_supplier_proposals.class.php @@ -238,7 +238,7 @@ class SupplierProposals extends DolibarrApi $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids; // If the internal user must only see his customers, force searching by him $search_sale = 0; diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php index da0eb4c4d87..4586e5b375d 100644 --- a/htdocs/ticket/class/api_tickets.class.php +++ b/htdocs/ticket/class/api_tickets.class.php @@ -213,7 +213,7 @@ class Tickets extends DolibarrApi $obj_ret = array(); - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $socid; + $socid = DolibarrApiAccess::$user->socid ?: $socid; $search_sale = null; // If the internal user must only see his customers, force searching by him diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index 1a3f1c458d8..c77e65b6966 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -90,7 +90,7 @@ class Users extends DolibarrApi $obj_ret = array(); // case of external user, $societe param is ignored and replaced by user's socid - //$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $societe; + //$socid = DolibarrApiAccess::$user->socid ?: $societe; $sql = "SELECT t.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."user AS t LEFT JOIN ".MAIN_DB_PREFIX."user_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields @@ -645,7 +645,7 @@ class Users extends DolibarrApi } // case of external user, $societe param is ignored and replaced by user's socid - //$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $societe; + //$socid = DolibarrApiAccess::$user->socid ?: $societe; $sql = "SELECT t.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."usergroup AS t LEFT JOIN ".MAIN_DB_PREFIX."usergroup_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields diff --git a/htdocs/workstation/class/api_workstations.class.php b/htdocs/workstation/class/api_workstations.class.php index 1a70145db60..5e1661e08f9 100644 --- a/htdocs/workstation/class/api_workstations.class.php +++ b/htdocs/workstation/class/api_workstations.class.php @@ -117,7 +117,7 @@ class Workstations extends DolibarrApi $obj_ret = array(); - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; + $socid = DolibarrApiAccess::$user->socid ?: ''; $sql = "SELECT t.rowid, t.ref"; $sql .= " FROM ".$this->db->prefix()."workstation_workstation as t"; diff --git a/htdocs/zapier/class/api_zapier.class.php b/htdocs/zapier/class/api_zapier.class.php index 859d2f7a598..fa4eea88769 100644 --- a/htdocs/zapier/class/api_zapier.class.php +++ b/htdocs/zapier/class/api_zapier.class.php @@ -155,7 +155,7 @@ class Zapier extends DolibarrApi $obj_ret = array(); - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : 0; + $socid = DolibarrApiAccess::$user->socid ?: 0; // Set to 1 if there is a field socid in table of object $restrictonsocid = 0; From 8c1d90519c50474d10e46d2acb4e77ab236782ea Mon Sep 17 00:00:00 2001 From: MDW Date: Tue, 1 Jul 2025 20:43:03 +0200 Subject: [PATCH 17/73] qual: Update phan baseline (#34670) # qual: Update phan baselin Several phan notices were fixed. Co-authored-by: Laurent Destailleur --- dev/tools/phan/baseline.txt | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 8309224fd7b..f0115791839 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -9,24 +9,24 @@ */ return [ // # Issue statistics: - // PhanUndeclaredProperty : 450+ occurrences + // PhanUndeclaredProperty : 440+ occurrences // PhanTypeMismatchProperty : 100+ occurrences - // PhanTypeMismatchArgument : 90+ occurrences // PhanUndeclaredGlobalVariable : 90+ occurrences + // PhanTypeMismatchArgument : 85+ occurrences // PhanTypeMismatchArgumentNullable : 30+ occurrences // PhanTypeExpectedObjectPropAccess : 20+ occurrences // PhanTypeInvalidDimOffset : 20+ occurrences // PhanTypeMismatchDimFetch : 15+ occurrences // PhanUndeclaredConstant : 15+ occurrences - // PhanTypeMismatchArgumentProbablyReal : 10+ occurrences + // PhanTypeMismatchArgumentProbablyReal : 9 occurrences // PhanUndeclaredMethod : 9 occurrences // PhanPossiblyUndeclaredGlobalVariable : 6 occurrences // PhanTypeArraySuspiciousNull : 6 occurrences // PhanTypeComparisonFromArray : 6 occurrences - // PhanPluginDuplicateExpressionBinaryOp : 5 occurrences // PhanPluginUndeclaredVariableIsset : 5 occurrences // PhanParamTooMany : 4 occurrences // PhanPluginDuplicateArrayKey : 4 occurrences + // PhanPluginDuplicateExpressionBinaryOp : 4 occurrences // PhanTypeMismatchDimAssignment : 2 occurrences // PhanTypeMismatchReturn : 2 occurrences // PhanTypeSuspiciousStringExpression : 2 occurrences @@ -36,12 +36,7 @@ return [ // Currently, file_suppressions and directory_suppressions are the only supported suppressions 'file_suppressions' => [ - 'htdocs/accountancy/class/accountancyexport.class.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'], - 'htdocs/adherents/list.php' => ['PhanUndeclaredGlobalVariable'], - 'htdocs/admin/agenda_other.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/admin/bom.php' => ['PhanTypeMismatchArgument'], - 'htdocs/admin/defaultvalues.php' => ['PhanTypeMismatchArgumentProbablyReal'], - 'htdocs/api/class/api_documents.class.php' => ['PhanPluginDuplicateExpressionBinaryOp'], + 'htdocs/accountancy/class/accountancyexport.class.php' => ['PhanTypeMismatchArgument'], 'htdocs/api/class/api_setup.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchReturn'], 'htdocs/asset/class/asset.class.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanTypeInvalidDimOffset'], 'htdocs/asset/class/assetdepreciationoptions.class.php' => ['PhanTypeInvalidDimOffset'], @@ -336,9 +331,6 @@ return [ 'htdocs/webservices/server_thirdparty.php' => ['PhanUndeclaredProperty'], 'htdocs/webservices/server_user.php' => ['PhanUndeclaredProperty'], 'htdocs/website/websiteaccount_card.php' => ['PhanUndeclaredProperty'], - 'htdocs/workstation/class/workstation.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/workstation/workstation_card.php' => ['PhanUndeclaredProperty'], - 'htdocs/zapier/class/hook.class.php' => ['PhanUndeclaredProperty'], 'internal' => ['PhanUndeclaredConstant'], ], // 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed. From 19a9be927e506bde3b01a72ff705338d6523b1eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Jul 2025 21:08:44 +0200 Subject: [PATCH 18/73] Fix Add a protection when 2 users are allowed (should not happen) --- htdocs/core/login/functions_openid_connect.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/core/login/functions_openid_connect.php b/htdocs/core/login/functions_openid_connect.php index 82689da653c..4dc4bf54290 100644 --- a/htdocs/core/login/functions_openid_connect.php +++ b/htdocs/core/login/functions_openid_connect.php @@ -121,7 +121,7 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit return false; } - // Step 3: retrieve user info using token + // Step 3: retrieve user info (login, email, ...) from OIDC server using token $userinfo_headers = array('Authorization: Bearer '.$token_content->access_token); $userinfo_response = getURLContent(getDolGlobalString('MAIN_AUTHENTICATION_OIDC_USERINFO_URL'), 'GET', '', 1, $userinfo_headers, array('https'), 2); $userinfo_content = json_decode($userinfo_response['content']); @@ -169,6 +169,11 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit dol_syslog("functions_openid_connect::check_user_password_openid_connect::Error with sql query (".$db->error().")"); return false; } + $numres = $db->num_rows($resql); + if ($numres > 1) { + dol_syslog("functions_openid_connect::check_user_password_openid_connect::Error more than 1 result from the query"); + return false; + } $obj = $db->fetch_object($resql); if (!$obj) { dol_syslog("functions_openid_connect::check_user_password_openid_connect::Error no result from the query"); From 167ef49faef2fe2cce5a79886c462b1aefb131f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Jul 2025 22:26:16 +0200 Subject: [PATCH 19/73] Debug v22 --- htdocs/compta/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 2d23643eebc..208e1931924 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -5251,7 +5251,7 @@ if ($action == 'create') { print ''; - if ($action != 'editposinfo' && $object->status == $object::STATUS_DRAFT && $usercancreate) { + if ($action != 'editposinfo' && $usercancreate) { print ''; } print '
'; print $form->textwithpicto($langs->trans('PointOfSale'), $langs->trans('POSInfo')); print 'id.'">'.img_edit($langs->trans('SetPOSInfo'), 1).'
'; From 723a0187598fa35d77038480f750b59e65fb1841 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Jul 2025 22:46:00 +0200 Subject: [PATCH 20/73] Debug v22 --- htdocs/commande/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 1f857748af7..2e607757191 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2978,7 +2978,7 @@ if ($action == 'create' && $usercancreate) { print ''; - if ($action != 'editposinfo' && $object->status == $object::STATUS_DRAFT && $usercancreate) { + if ($action != 'editposinfo' && $usercancreate) { print ''; } print '
'; print $form->textwithpicto($langs->trans('PointOfSale'), $langs->trans('POSInfo')); print 'id.'">'.img_edit($langs->trans('SetPOSInfo'), 1).'
'; From a2d42ebb0808e18ed5ae92a19bf186db4d37b65d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Jul 2025 00:08:51 +0200 Subject: [PATCH 21/73] Debug v22 --- htdocs/compta/prelevement/card.php | 7 +++--- htdocs/compta/prelevement/fiche-rejet.php | 27 +++++++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index 2bc0c95932c..9f24558a6dd 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -80,8 +80,11 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'inclu $hookmanager->initHooks(array('directdebitprevcard', 'globalcard', 'directdebitprevlist')); $type = $object->type; -// check if salary pl + +// Check if salary or invoice $salaryBonPl = $object->checkIfSalaryBonPrelevement(); + +// Security check if ($type == 'bank-transfer') { $result = restrictedArea($user, 'paymentbybanktransfer', '', '', ''); @@ -99,7 +102,6 @@ if ($type == 'bank-transfer') { } - /* * Actions */ @@ -197,7 +199,6 @@ if (empty($reshook)) { } - /* * View */ diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index e7ba1a6d487..6261052b93c 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -1,9 +1,9 @@ - * Copyright (C) 2005 Laurent Destailleur + * Copyright (C) 2005-2025 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2010-2012 Juanjo Menent - * 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 @@ -46,7 +46,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; */ // Load translation files required by the page -$langs->loadLangs(array("banks", "categories", 'withdrawals', 'bills')); +$langs->loadLangs(array("banks", "categories", "companies", 'withdrawals', 'bills')); // Security check if ($user->socid > 0) { @@ -76,6 +76,9 @@ $object = new BonPrelevement($db); // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'. Include fetch and fetch_thirdparty but not fetch_optionals +// Check if salary or invoice +$salaryBonPl = $object->checkIfSalaryBonPrelevement(); + // Security check if ($user->socid > 0) { accessforbidden(); @@ -89,7 +92,6 @@ if ($type == 'bank-transfer') { } - /* * View */ @@ -225,11 +227,8 @@ $sql .= " WHERE p.rowid=".((int) $object->id); $sql .= " AND pl.fk_prelevement_bons = p.rowid"; $sql .= " AND p.entity IN (".getEntity('facture').")"; $sql .= " AND pl.fk_soc = s.rowid"; -$sql .= " AND pl.statut = 3 "; +$sql .= " AND pl.statut = 3"; $sql .= " AND pr.fk_prelevement_lignes = pl.rowid"; -/*if ($socid) { - $sql .= " AND s.rowid = ".((int) $socid); -}*/ $sql .= " ORDER BY pl.amount DESC"; // Count total nb of records @@ -252,16 +251,20 @@ if ($resql) { // @phan-suppress-next-line PhanPluginSuspiciousParamOrder print_barre_liste($langs->trans("Rejects"), $page, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', $num, $nbtotalofrecords, ''); + $param = '&id='.((int) $object->id); + print"\n\n"; print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table print ''; print ''; - print ''; - print ''; - print ''; print ''; $total = 0; From 20c327b1d3b48031b90d0f67d1c45e47c11344cd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Jul 2025 00:50:04 +0200 Subject: [PATCH 22/73] Debug v22 --- htdocs/expensereport/card.php | 194 +++++++++--------- .../class/expensereport.class.php | 6 +- 2 files changed, 107 insertions(+), 93 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index a99db15abe6..85c56e65113 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -174,6 +174,7 @@ $permissiontoadd = $user->hasRight('expensereport', 'creer'); // Used by the inc /* * Actions */ + $error = 0; $value_unit_ht = price2num(GETPOST('value_unit_ht', 'alpha'), 'MU'); @@ -410,9 +411,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -529,9 +530,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -643,9 +644,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -761,9 +762,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -879,9 +880,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -995,9 +996,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -1036,9 +1037,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -1049,9 +1050,13 @@ if (empty($reshook)) { $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); } + + header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); + exit; } } + if ($action == 'set_paid' && $id > 0 && $user->hasRight('expensereport', 'to_paid')) { $object = new ExpenseReport($db); $object->fetch($id); @@ -1067,9 +1072,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -1083,74 +1088,78 @@ if (empty($reshook)) { } if ($result > 0) { - // Send mail + // TODO We must never send an email without a setup or confirm option to choose if email is + // sent or not. So we add a hidden constant to avoid this for the moment. + if (getDolGlobalString('EXPENSEREPORT_SEND_EMAIL_ON_STATUS_PAID')) { + // Send mail - // TO - $destinataire = new User($db); - $destinataire->fetch($object->fk_user_author); - $emailTo = $destinataire->email; + // TO + $destinataire = new User($db); + $destinataire->fetch($object->fk_user_author); + $emailTo = $destinataire->email; - // FROM - $expediteur = new User($db); - $expediteur->fetch($user->id); - $emailFrom = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); + // FROM + $expediteur = new User($db); + $expediteur->fetch($user->id); + $emailFrom = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); - if ($emailFrom && $emailTo) { - $filename = array(); - $filedir = array(); - $mimetype = array(); + if ($emailFrom && $emailTo) { + $filename = array(); + $filedir = array(); + $mimetype = array(); - // SUBJECT - $societeName = getDolGlobalString('MAIN_INFO_SOCIETE_NOM'); - if (getDolGlobalString('MAIN_APPLICATION_TITLE')) { - $societeName = getDolGlobalString('MAIN_APPLICATION_TITLE'); - } + // SUBJECT + $societeName = getDolGlobalString('MAIN_INFO_SOCIETE_NOM'); + if (getDolGlobalString('MAIN_APPLICATION_TITLE')) { + $societeName = getDolGlobalString('MAIN_APPLICATION_TITLE'); + } - $subject = $societeName." - ".$langs->transnoentities("ExpenseReportPaid"); + $subject = $societeName." - ".$langs->transnoentities("ExpenseReportPaid"); - // CONTENT - $link = $urlwithroot.'/expensereport/card.php?id='.$object->id; - $link = ''.$link.''; - $message = $langs->transnoentities("ExpenseReportPaidMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $link); + // CONTENT + $link = $urlwithroot.'/expensereport/card.php?id='.$object->id; + $link = ''.$link.''; + $message = $langs->transnoentities("ExpenseReportPaidMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $link); - // Generate pdf before attachment - $object->setDocModel($user, ""); - $resultPDF = expensereport_pdf_create($db, $object, '', "", $langs); + // Generate pdf before attachment + $object->setDocModel($user, ""); + $resultPDF = expensereport_pdf_create($db, $object, '', "", $langs); - // PREPARE SEND - $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1); + // PREPARE SEND + $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1); - if (empty($mailfile->error)) { - // SEND - $result = $mailfile->sendfile(); - if ($result) { - $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2)); - setEventMessages($mesg, null, 'mesgs'); - header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); - exit; - } else { - $langs->load("other"); - if ($mailfile->error) { - $mesg = ''; - $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo); - $mesg .= '
'.$mailfile->error; - setEventMessages($mesg, null, 'errors'); + if (empty($mailfile->error)) { + // SEND + $result = $mailfile->sendfile(); + if ($result) { + $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2)); + setEventMessages($mesg, null, 'mesgs'); + + header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); + exit; } else { - setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings'); + $langs->load("other"); + if ($mailfile->error) { + $mesg = ''; + $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo); + $mesg .= '
'.$mailfile->error; + setEventMessages($mesg, null, 'errors'); + } else { + setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings'); + } } + } else { + setEventMessages($mailfile->error, $mailfile->errors, 'errors'); } } else { - setEventMessages($mailfile->error, $mailfile->errors, 'errors'); - $action = ''; + setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings'); } - } else { - setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings'); - $action = ''; } } else { setEventMessages($langs->trans("FailedToSetPaid"), null, 'warnings'); - $action = ''; } + + $action = ''; } if ($action == "addline" && $user->hasRight('expensereport', 'creer')) { @@ -1245,9 +1254,9 @@ if (empty($reshook)) { $outputlangs = $langs; $newlang = GETPOST('lang_id', 'alpha'); if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (empty($newlang)) { $newlang = $langs; @@ -1303,9 +1312,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -1402,9 +1411,9 @@ if (empty($reshook)) { $newlang = GETPOST('lang_id', 'aZ09'); } if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { - $user = new User($db); - $user->fetch($object->fk_user_author); - $newlang = $user->lang; + $tmpuser = new User($db); + $tmpuser->fetch($object->fk_user_author); + $newlang = $tmpuser->lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); @@ -1425,9 +1434,6 @@ if (empty($reshook)) { unset($fk_project); unset($date); } - - //header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); - //exit; } else { setEventMessages($object->error, $object->errors, 'errors'); } @@ -1603,6 +1609,7 @@ if ($action == 'create') { // End of page llxFooter(); + $db->close(); exit; @@ -1611,7 +1618,7 @@ if ($action == 'create') { $head = expensereport_prepare_head($object); - if ($action == 'edit' && ($object->status < 3 || $object->status == ExpenseReport::STATUS_REFUSED)) { + if ($action == 'edit' && ($object->status <= ExpenseReport::STATUS_VALIDATED || $object->status == ExpenseReport::STATUS_REFUSED)) { print "
\n"; print ''; print ''; @@ -2803,11 +2810,11 @@ if ($action != 'create' && $action != 'edit' && $action != 'editline') { } } - /* Si l'état est "Brouillon" + /* If status is "Draft" * ET user à droit "creer/supprimer" - * ET fk_user_author == user courant - * Afficher : "Enregistrer" / "Modifier" / "Supprimer" - */ + * ET fk_user_author == user courant + * Afficher : "Enregistrer" / "Modifier" / "Supprimer" + */ if ($user->hasRight('expensereport', 'creer') && $object->status == ExpenseReport::STATUS_DRAFT) { if (in_array($object->fk_user_author, $childids) || $user->hasRight('expensereport', 'writeall_advance')) { // Modify @@ -2820,7 +2827,7 @@ if ($action != 'create' && $action != 'edit' && $action != 'editline') { } } - /* Si l'état est "Refusée" + /* If status if "Refused" * ET user à droit "creer/supprimer" * ET fk_user_author == user courant * Afficher : "Enregistrer" / "Modifier" / "Supprimer" @@ -2902,6 +2909,9 @@ if ($action != 'create' && $action != 'edit' && $action != 'editline') { print ''; } + // If status is Closed + // --------------------- + // TODO Replace this. It should be SetUnpaid and should go back to status unpaid not canceled. if (($user->hasRight('expensereport', 'approve') || $user->hasRight('expensereport', 'to_paid')) && $object->status == ExpenseReport::STATUS_CLOSED) { // Cancel diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index f52a41fe28a..fa7ed2cea6c 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -815,7 +815,7 @@ class ExpenseReport extends CommonObject $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."expensereport"; - $sql .= " SET fk_statut = ".self::STATUS_CLOSED.", paid=1"; + $sql .= " SET fk_statut = ".self::STATUS_CLOSED.", paid = 1"; $sql .= " WHERE rowid = ".((int) $id)." AND fk_statut = ".self::STATUS_APPROVED; dol_syslog(get_class($this)."::setPaid", LOG_DEBUG); @@ -834,6 +834,10 @@ class ExpenseReport extends CommonObject if (empty($error)) { $this->db->commit(); + + $this->status = self::STATUS_CLOSED; + $this->paid = 1; + return 1; } else { $this->db->rollback(); From bf6c9110ca156970d2a74bfe7f3347d737792b1e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Jul 2025 01:03:18 +0200 Subject: [PATCH 23/73] Debug v22 --- htdocs/expensereport/card.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 85c56e65113..13db338951e 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -2074,19 +2074,22 @@ if ($action == 'create') { $remaintopay = price2num($object->total_ttc - (float) $totalpaid); $resteapayeraffiche = $remaintopay; - $cssforamountpaymentcomplete = 'amountpaymentcomplete'; + if ($remaintopay > 0) { + $cssforamountpaymentcomplete = 'amountremaintopay'; + } else { + $cssforamountpaymentcomplete = 'amountpaymentcomplete'; + } if ($object->status == ExpenseReport::STATUS_REFUSED) { - $cssforamountpaymentcomplete = 'amountpaymentneutral'; - $resteapayeraffiche = 0; - } elseif ($object->paid == 0) { - $cssforamountpaymentcomplete = 'amountpaymentneutral'; + $cssforamountpaymentcomplete = 'amountpaymentneutral strikefordisabled'; + } elseif ($object->paid == 1 && $remaintopay > 0) { + $cssforamountpaymentcomplete = 'amountpaymentneutral strikefordisabled'; } print '
'; print ''; print ''; - print ''; + print ''; $db->free($resql); } else { From 641c6d8b240405405f7715af0b4be9430327aea7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Jul 2025 01:12:16 +0200 Subject: [PATCH 24/73] Debug v22 --- htdocs/expensereport/index.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index 7f89fdb71b8..1ef37048f54 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -89,7 +89,7 @@ $help_url = "EN:Module_Expense_Reports|FR:Module_Notes_de_frais"; llxHeader('', $langs->trans("TripsAndExpenses"), $help_url); -$label = $somme = $nb = array(); +$label = $somme = array(); $totalnb = $totalsum = 0; $sql = "SELECT tf.code, tf.label, count(de.rowid) as nb, sum(de.total_ht) as km"; @@ -102,7 +102,6 @@ if (!$user->hasRight('expensereport', 'readall') && !$user->hasRight('expenserep $childids[] = $user->id; $sql .= " AND d.fk_user_author IN (".$db->sanitize(implode(',', $childids)).")\n"; } - $sql .= " GROUP BY tf.code, tf.label"; $result = $db->query($sql); @@ -230,8 +229,8 @@ if ($result) { print ''; print ''; print ''; print ''; From 5161b631d5b517371f37c965739725a72811a2b3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Jul 2025 01:32:07 +0200 Subject: [PATCH 25/73] Doc --- htdocs/install/mysql/tables/llx_c_ziptown.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_c_ziptown.sql b/htdocs/install/mysql/tables/llx_c_ziptown.sql index 741ec51c373..a9046a8b604 100644 --- a/htdocs/install/mysql/tables/llx_c_ziptown.sql +++ b/htdocs/install/mysql/tables/llx_c_ziptown.sql @@ -19,7 +19,7 @@ create table llx_c_ziptown ( rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY, - code varchar(5) DEFAULT NULL, -- ex: code insee pour la France + code varchar(5) DEFAULT NULL, -- ex: code insee pour la France (not always used) fk_county integer, -- State id in llx_c_departements fk_pays integer NOT NULL DEFAULT 0, -- Country id in llx_c_country zip varchar(10) NOT NULL, -- Zip code From d065f25e2b55f85ad24202a39977b183207d8946 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 13:09:13 +0300 Subject: [PATCH 26/73] PHPStan > Update baseline (#34679) Co-authored-by: Dolibot --- dev/build/phpstan/phpstan-baseline.neon | 48 ------------------------- 1 file changed, 48 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index eb215259415..19fcdb5d3c3 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -9390,54 +9390,6 @@ parameters: count: 1 path: ../../../htdocs/core/lib/files.lib.php - - - message: '#^Parameter \#1 \$ftp of function ftp_cdup expects FTP\\Connection, resource given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/lib/ftp.lib.php - - - - message: '#^Parameter \#1 \$ftp of function ftp_chdir expects FTP\\Connection, resource given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/lib/ftp.lib.php - - - - message: '#^Parameter \#1 \$ftp of function ftp_close expects FTP\\Connection, resource given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/lib/ftp.lib.php - - - - message: '#^Parameter \#1 \$ftp of function ftp_delete expects FTP\\Connection, resource given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/lib/ftp.lib.php - - - - message: '#^Parameter \#1 \$ftp of function ftp_get expects FTP\\Connection, resource given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/lib/ftp.lib.php - - - - message: '#^Parameter \#1 \$ftp of function ftp_mkdir expects FTP\\Connection, resource given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/lib/ftp.lib.php - - - - message: '#^Parameter \#1 \$ftp of function ftp_put expects FTP\\Connection, resource given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/lib/ftp.lib.php - - - - message: '#^Parameter \#1 \$ftp of function ftp_rmdir expects FTP\\Connection, resource given\.$#' - identifier: argument.type - count: 1 - path: ../../../htdocs/core/lib/ftp.lib.php - - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType From b506f03c62424d1281df560df5f99db78b0c6c19 Mon Sep 17 00:00:00 2001 From: Mohamed DAOUD Date: Fri, 4 Jul 2025 08:54:01 +0200 Subject: [PATCH 27/73] Improve error messages returned by getURLContent (#34689) * enhance getURLContent error messages * fix CI --- htdocs/admin/remotestore/class/externalModules.class.php | 4 ++-- htdocs/core/class/conf.class.php | 2 +- htdocs/core/lib/geturl.lib.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/admin/remotestore/class/externalModules.class.php b/htdocs/admin/remotestore/class/externalModules.class.php index 6869d9357a4..4657a3a1e68 100644 --- a/htdocs/admin/remotestore/class/externalModules.class.php +++ b/htdocs/admin/remotestore/class/externalModules.class.php @@ -778,8 +778,8 @@ class ExternalModules } } - if (!empty($request['response']['curl_error_msg'])) { - $error_message .= ' - ' . $request['response']['curl_error_msg']; + if (!empty($request['curl_error_msg'])) { + $error_message .= ' - ' . $request['curl_error_msg']; } // Return the formatted error message diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 77598f5b200..cf0e5b886a5 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -1293,7 +1293,7 @@ class Conf extends stdClass $this->global->MAIN_MODULE_DOLISTORE_API_SRV = 'https://www.dolistore.com/api/'; } if (empty($this->global->MAIN_MODULE_DOLISTORE_API_KEY)) { - $this->global->MAIN_MODULE_DOLISTORE_API_KEY = 'dolistorecatalogpublickey1234567'; + $this->global->MAIN_MODULE_DOLISTORE_API_KEY = 'dolistorepublicapi'; } // Enable by default the CSRF protection by token. diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index e36744e50cb..83563401120 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -178,7 +178,7 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation = do { if ($maxRedirection < 1) { - break; + return array('http_code' => 400, 'content' => 'Maximum number of redirections reached', 'curl_error_no' => 1, 'curl_error_msg' => 'Maximum number of redirections reached'); } curl_setopt($ch, CURLOPT_URL, $newUrl); @@ -192,7 +192,7 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation = if (in_array($hosttocheck, array('metadata.google.internal'))) { $info['http_code'] = 400; $info['content'] = 'Error bad hostname '.$hosttocheck.' (Used by Google metadata). This value for hostname is not allowed.'; - break; + return array('http_code' => 400, 'content' => $info['content'], 'curl_error_no' => 1, 'curl_error_msg' => $info['content']); } // Clean host name $hosttocheck to convert it into an IP $iptocheck @@ -220,7 +220,7 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation = if ($tmpresult) { $info['http_code'] = 400; $info['content'] = $tmpresult; - break; + return array('http_code' => 400, 'content' => $tmpresult, 'curl_error_no' => 1, 'curl_error_msg' => $tmpresult); } } From 8772306b60b87aa6b0319bbc6cc22a10d54d2044 Mon Sep 17 00:00:00 2001 From: Alain Rihs Date: Fri, 4 Jul 2025 08:56:07 +0200 Subject: [PATCH 28/73] Update card.php (#34677) Since the improvement of the Prospect/Client/Supplier selection, the THIRDPARTY_CUSTOMERTYPE_BY_DEFAULT variable is no longer taken into account. This code restores this functionality when creating a new third party. --- htdocs/societe/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 4d5361f9f49..eb9f28c26fc 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1449,8 +1449,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio // Prospect/Customer/Supplier $selected = $object->client; - $selectedcustomer = 0; - $selectedprospect = 0; + $selectedcustomer = (getDolGlobalInt('THIRDPARTY_CUSTOMERTYPE_BY_DEFAULT')==1 || getDolGlobalInt('THIRDPARTY_CUSTOMERTYPE_BY_DEFAULT')==3 ? 1 : 0); + $selectedprospect = (getDolGlobalInt('THIRDPARTY_CUSTOMERTYPE_BY_DEFAULT')==2 || getDolGlobalInt('THIRDPARTY_CUSTOMERTYPE_BY_DEFAULT')==3 ? 1 : 0); switch ($selected) { case 1: $selectedcustomer = 1; From 6c6846ed6e41199f21dab532c1a5abce716bfb58 Mon Sep 17 00:00:00 2001 From: atm-corentin <165782689+atm-corentin@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:00:31 +0200 Subject: [PATCH 29/73] fix fatal when u try to add a newline on expensereport object we try to do a explode on Translate object (#34697) --- htdocs/expensereport/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 13db338951e..963d5d861a7 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1259,7 +1259,7 @@ if (empty($reshook)) { $newlang = $tmpuser->lang; } if (empty($newlang)) { - $newlang = $langs; + $newlang = $langs->defaultlang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); From 6608e972aba77d531d52ecf2b87e53691f80ee3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Cendrier?= <81741011+altairis-noe@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:05:34 +0200 Subject: [PATCH 30/73] FIX: Trigger should be the same for same action (#34698) --- htdocs/expedition/card.php | 4 ++-- htdocs/expedition/shipment.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 565e20ced65..ff48e5e66f0 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -213,7 +213,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } - $result = $object->setValueFrom('ref_customer', GETPOST('ref_customer', 'alpha'), '', null, 'text', '', $user, 'SHIPMENT_MODIFY'); + $result = $object->setValueFrom('ref_customer', GETPOST('ref_customer', 'alpha'), '', null, 'text', '', $user, 'SHIPPING_MODIFY'); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $action = 'editref_customer'; @@ -236,7 +236,7 @@ if (empty($reshook)) { if (!$error) { // Actions on extra fields - $result = $object->updateExtraField($attribute_name, 'SHIPMENT_MODIFY'); + $result = $object->updateExtraField($attribute_name, 'SHIPPING_MODIFY'); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index 4dd45ab12a9..26f8cdeb4f8 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -209,7 +209,7 @@ if (empty($reshook)) { } if (!$error) { - $result = $object->updateExtraField($attribute_name, 'SHIPMENT_MODIFY'); + $result = $object->updateExtraField($attribute_name, 'SHIPPING_MODIFY'); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; From 31517fdc9c3726e51182cca8a3af76f1fd5c29e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 4 Jul 2025 19:07:03 +0200 Subject: [PATCH 31/73] situation_counter is nullable (#34693) * situation_counter is nullable * Update phpstan-baseline.neon --- dev/build/phpstan/phpstan-baseline.neon | 2 +- htdocs/compta/facture/class/facture.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 19fcdb5d3c3..9d8572699e5 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -13401,7 +13401,7 @@ parameters: - message: '#^Result of && is always false\.$#' identifier: booleanAnd.alwaysFalse - count: 2 + count: 3 path: ../../../htdocs/expensereport/card.php - diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index b53a12edfcf..d2ad124f7eb 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -213,7 +213,7 @@ class Facture extends CommonInvoice public $situation_cycle_ref; /** - * @var int Situation counter inside the cycle + * @var ?int Situation counter inside the cycle */ public $situation_counter; From 7b8601d4851be762a5a9c2abda22a4154d8471ab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Jul 2025 20:29:29 +0300 Subject: [PATCH 32/73] Update card.php --- htdocs/expensereport/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 963d5d861a7..15ecd11df68 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -2089,7 +2089,7 @@ if ($action == 'create') { print ''; print ''; - print ''; + print ''; $db->free($resql); } else { From fe19745458c00e0c77213b01b7de838612022542 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 00:14:23 +0200 Subject: [PATCH 33/73] Add warning to avoid confusion. --- htdocs/admin/translation.php | 15 +++++++++++---- htdocs/langs/en_US/admin.lang | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index f67f78fb5c4..fd5c40ed526 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -363,15 +363,22 @@ if ($mode == 'overwrite') { $disablededit = ' disabled'; } - $infoOnTransProcess = '
'; - $infoOnTransProcess .= img_info().' '.$langs->trans("SomeTranslationAreUncomplete"); + $text = $langs->trans("SomeTranslationAreUncomplete"); $urlwikitranslatordoc = 'https://wiki.dolibarr.org/index.php/Translator_documentation'; - $infoOnTransProcess .= ' ('.str_replace('{s1}', ''.$langs->trans("Here").'', $langs->trans("SeeAlso", '{s1}')).')
'; - $infoOnTransProcess .= '
'; + $text .= ' - '.$langs->trans("SeeAlso", $langs->transnoentitiesnoconv("Here")).' '.img_picto('', 'url').'.
'; + $infoOnTransProcess = info_admin($text); + + $infoOnTransProcess .= '
'; + $infoOnTransProcess .= ''; $infoOnTransProcess .= $langs->trans("TranslationOverwriteDesc", $langs->transnoentitiesnoconv("Language"), $langs->transnoentitiesnoconv("TranslationKey"), $langs->transnoentitiesnoconv("NewTranslationStringToShow"))."\n"; $infoOnTransProcess .= ' ('.$langs->trans("TranslationOverwriteDesc2").').'."
\n"; $infoOnTransProcess .= '
'; + // If a cache for translation is on, show a warning. + if (isModEnabled('memcached') || getDolGlobalInt('MAIN_USE_CACHE_FOR_TRANSLATION')) { + $infoOnTransProcess .= info_admin($langs->trans("CacheForTranslationIsUsed"), 0, 0, 1, 'warning'); + } + print $infoOnTransProcess; print '
'; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 47c14dc52b1..9903ea6d859 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2677,3 +2677,4 @@ Synchronize=Synchronize ByDefault=By default Sources=Sources XYearSupport=%s-year support +CacheForTranslationIsUsed=Warning, translation files seems loaded into a cache system. If you force some translations from here, think to reset the cache to have the change effective. From dff214402ec71a3e145ca72bf3d1a0f7442813ea Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 01:21:45 +0200 Subject: [PATCH 34/73] Fix warning --- ...nterface_50_modEventOrganization_EventOrganization.class.php | 2 +- .../core/triggers/interface_50_modTicket_TicketEmail.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/triggers/interface_50_modEventOrganization_EventOrganization.class.php b/htdocs/core/triggers/interface_50_modEventOrganization_EventOrganization.class.php index f0b8b419825..727f980f24e 100644 --- a/htdocs/core/triggers/interface_50_modEventOrganization_EventOrganization.class.php +++ b/htdocs/core/triggers/interface_50_modEventOrganization_EventOrganization.class.php @@ -71,7 +71,7 @@ class InterfaceEventOrganization extends DolibarrTriggers */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) { - if (empty($conf->eventorganization) || empty($conf->eventorganization->enabled)) { + if (!isModEnabled('eventorganization')) { return 0; // Module not active, we do nothing } diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index 398f4e65351..cdd09250bec 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -65,7 +65,7 @@ class InterfaceTicketEmail extends DolibarrTriggers $ok = 0; - if (empty($conf->ticket) || !isModEnabled('ticket')) { + if (!isModEnabled('ticket')) { return 0; // Module not active, we do nothing } From 75593e84b2bb94624f8020c78b9b5642b67bf80f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 10:21:25 +0200 Subject: [PATCH 35/73] FIX #34591 FIX #34692 --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 26883fe797d..9ded07a8059 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2593,7 +2593,7 @@ class Product extends CommonObject $this->price_min = $obj->price_min; $this->price_min_ttc = $obj->price_min_ttc; $this->price_base_type = $obj->price_base_type; - $this->cost_price = $obj->cost_price; + $this->cost_price = (float) $obj->cost_price; $this->default_vat_code = $obj->default_vat_code; $this->tva_tx = $obj->tva_tx; //! French VAT NPR From 704173f4a6150693b4308ad017b2b1c7ada84b1f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 10:32:59 +0200 Subject: [PATCH 36/73] FIX #34591 FIX #34692 --- htdocs/bom/class/bom.class.php | 2 +- htdocs/product/class/product.class.php | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index b4b1f977414..b8503c9ea14 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1443,7 +1443,7 @@ class BOM extends CommonObject $this->error = $tmpproduct->error; return -1; } - $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); + $line->unit_cost = price2num(is_null($tmpproduct->cost_price) ? $tmpproduct->pmp : $tmpproduct->cost_price); if (empty($line->unit_cost)) { if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { if ($productFournisseur->fourn_remise_percent != "0") { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 9ded07a8059..fb24f95a81b 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -252,11 +252,15 @@ class Product extends CommonObject /** * Cost price * - * @var float + * @var ?float */ public $cost_price; - //! Average price value for product entry into stock (PMP) + /** + * Average price value for product entry into stock (PMP) + * + * @var ?float + */ public $pmp; /** @@ -2593,7 +2597,7 @@ class Product extends CommonObject $this->price_min = $obj->price_min; $this->price_min_ttc = $obj->price_min_ttc; $this->price_base_type = $obj->price_base_type; - $this->cost_price = (float) $obj->cost_price; + $this->cost_price = isset($obj->cost_price) ? (float) $obj->cost_price : null; $this->default_vat_code = $obj->default_vat_code; $this->tva_tx = $obj->tva_tx; //! French VAT NPR From 7572b33f6faa4156e1a36d8e0bee74d5cd28e7e6 Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller <45882981+Hystepik@users.noreply.github.com> Date: Sat, 5 Jul 2025 10:49:56 +0200 Subject: [PATCH 37/73] Fix clean code + phan warnings (#34688) Co-authored-by: Laurent Destailleur --- htdocs/comm/propal/card.php | 4 ++-- htdocs/commande/customer.php | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 5d0353245d7..cb9af128383 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -525,7 +525,7 @@ if (empty($reshook)) { $object->contact_id = GETPOSTINT('contactid'); $object->fk_project = GETPOSTINT('projectid'); $object->model_pdf = GETPOST('model', 'alphanohtml'); - $object->author = $user->id; // deprecated + $object->author = $user; // deprecated $object->user_author_id = $user->id; $object->note_private = GETPOST('note_private', 'restricthtml'); $object->note_public = GETPOST('note_public', 'restricthtml'); @@ -555,7 +555,7 @@ if (empty($reshook)) { $object->contact_id = GETPOSTINT('contactid'); $object->fk_project = GETPOSTINT('projectid'); $object->model_pdf = GETPOST('model'); - $object->author = $user->id; // deprecated + $object->author = $user; // deprecated $object->note_private = GETPOST('note_private', 'restricthtml'); $object->note_public = GETPOST('note_public', 'restricthtml'); $object->fk_incoterms = GETPOSTINT('incoterm_id'); diff --git a/htdocs/commande/customer.php b/htdocs/commande/customer.php index 843a55e0112..29a38dbc502 100644 --- a/htdocs/commande/customer.php +++ b/htdocs/commande/customer.php @@ -73,7 +73,8 @@ if (!$sortfield) { $sortfield = "nom"; } - +$addu = GETPOST("addu"); +$maxlen = GETPOSTISSET("maxlensocname") ? GETPOSTINT("maxlensocname") : 40; /* * View */ @@ -86,7 +87,7 @@ $thirdpartystatic = new Societe($db); * Mode List */ -$sql = "SELECT s.rowid, s.nom as name, s.client, s.town, s.datec, s.datea,"; +$sql = "SELECT s.rowid, s.nom as name, s.client, s.town, s.datec,"; $sql .= " st.libelle as stcomm, s.prefix_comm, s.code_client, s.code_compta as code_compta_client"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."c_stcomm as st, ".MAIN_DB_PREFIX."commande as c"; $sql .= " WHERE s.fk_stcomm = st.id AND c.fk_soc = s.rowid"; @@ -100,9 +101,9 @@ if (GETPOST("search_compta")) { if (GETPOST("search_code_client")) { $sql .= natural_search("s.code_client", GETPOST("search_code_client")); } -if (dol_strlen($begin)) { +/*if (dol_strlen($begin)) { // Useless already done line 97 $sql .= " AND s.nom LIKE '".$db->escape($begin)."'"; -} +}*/ // If the internal user must only see his customers, force searching by him $search_sale = 0; if (!$user->hasRight('societe', 'client', 'voir')) { @@ -121,7 +122,7 @@ if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } $sql .= " AND c.fk_statut in (1, 2) AND c.facture = 0"; -$sql .= " GROUP BY s.nom"; +$sql .= " GROUP BY s.nom, s.rowid"; $sql .= $db->order($sortfield, $sortorder); // Count total nb of records From 4cbc1e012d126f3cb158fcb32a26594bc17a5b09 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 10:51:22 +0200 Subject: [PATCH 38/73] Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into develop --- htdocs/comm/propal/card.php | 1 + htdocs/comm/propal/class/propal.class.php | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 5d0353245d7..5ec0925e52c 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -556,6 +556,7 @@ if (empty($reshook)) { $object->fk_project = GETPOSTINT('projectid'); $object->model_pdf = GETPOST('model'); $object->author = $user->id; // deprecated + $object->user_author_id = $user->id; $object->note_private = GETPOST('note_private', 'restricthtml'); $object->note_public = GETPOST('note_public', 'restricthtml'); $object->fk_incoterms = GETPOSTINT('incoterm_id'); diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 32e44dc58f0..4d69cbf17ae 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -197,6 +197,7 @@ class Propal extends CommonObject /** * @var User user identified by user_author_id + * @deprecated Set only $user_author_id */ public $author; From 6b68f5aad0d37fa8a6c0807ae25dd9dc4812f10f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 11:33:46 +0200 Subject: [PATCH 39/73] Fix CI --- htdocs/admin/translation.php | 2 +- htdocs/compta/facture/class/facture.class.php | 2 +- htdocs/core/class/commonobject.class.php | 5 +++-- htdocs/core/lib/functions.lib.php | 4 ++-- htdocs/fourn/ajax/getSupplierPrices.php | 2 +- htdocs/product/inventory/inventory.php | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index fd5c40ed526..33ea4691b88 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -376,7 +376,7 @@ if ($mode == 'overwrite') { // If a cache for translation is on, show a warning. if (isModEnabled('memcached') || getDolGlobalInt('MAIN_USE_CACHE_FOR_TRANSLATION')) { - $infoOnTransProcess .= info_admin($langs->trans("CacheForTranslationIsUsed"), 0, 0, 1, 'warning'); + $infoOnTransProcess .= info_admin($langs->trans("CacheForTranslationIsUsed"), 0, 0, '1', 'warning'); } print $infoOnTransProcess; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index d2ad124f7eb..3eea9d109c3 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1080,7 +1080,7 @@ class Facture extends CommonInvoice 0, $fk_parent_line, $fk_product_fournisseur_price, - $buyprice, + is_null($buyprice) ? '' : $buyprice, // do not use (float) here, it may be '' $_facrec->lines[$i]->label, empty($_facrec->lines[$i]->array_options) ? null : $_facrec->lines[$i]->array_options, 100, // situation percent is undefined on recurring invoice lines diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 954c7bf66e9..5ed546716da 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -9773,7 +9773,7 @@ abstract class CommonObject * @param float $unitPrice Product unit price * @param float $discountPercent Line discount percent * @param int $fk_product Product id - * @return float|int<-1,-1> Return buy price if OK, integer <0 if KO + * @return float|int<-2,-1> Return buy price if OK, integer <0 if KO */ public function defineBuyPrice($unitPrice = 0.0, $discountPercent = 0.0, $fk_product = 0) { @@ -9826,7 +9826,8 @@ abstract class CommonObject } } } - return $buyPrice; + + return (float) $buyPrice; } /** diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index cecf472c14b..9628d02ecaa 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7058,7 +7058,7 @@ function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0, * Function to format a value into an amount for visual output * Function used into PDF and HTML pages * - * @param string|float $amount Amount value to format + * @param int|float[string $amount Amount value to format * @param int<0,1> $form Type of formatting: 1=HTML, 0=no formatting (no by default) * @param Translate|string|null $outlangs Object langs for output. '' use default lang. 'none' use international separators. * @param int $trunc 1=Truncate if there is more decimals than MAIN_MAX_DECIMALS_SHOWN (default), 0=Does not truncate. Deprecated because amount are rounded (to unit or total amount accuracy) before being inserted into database or after a computation, so this parameter should be useless. @@ -7178,7 +7178,7 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $ * Function to use on each input amount before any numeric test or database insert. A better name for this function * should be roundtext2num(). * - * @param string|float $amount Amount to convert/clean or round + * @param int|float|string $amount Amount to convert/clean or round * @param ''|'MU'|'MT'|'MS'|'CU'|'CT'|int<0,max> $rounding ''=No rounding * 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT) * 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT) diff --git a/htdocs/fourn/ajax/getSupplierPrices.php b/htdocs/fourn/ajax/getSupplierPrices.php index 019c4809039..ef4663d724e 100644 --- a/htdocs/fourn/ajax/getSupplierPrices.php +++ b/htdocs/fourn/ajax/getSupplierPrices.php @@ -122,7 +122,7 @@ if ($idprod > 0) { } } - $prices[] = array("id" => 'pmpprice', "price" => price2num($price), "label" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency), "title" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency)); // For price field, we must use price2num(), for label or title, price() + $prices[] = array("id" => 'pmpprice', "price" => price2num((float) $price), "label" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency), "title" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency)); // For price field, we must use price2num(), for label or title, price() } // Add price for costprice (at end) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 5e69da95eed..73f6fd0134f 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -1149,7 +1149,7 @@ if ($resql) { } $pmp_valuation = $pmp_expected * $valuetoshow; print '
'; print ''; print ''; } else { if (getDolGlobalString('INVENTORY_MANAGE_REAL_PMP')) { - //PMP Expected + // PMP Expected if (!empty($obj->pmp_expected)) { $pmp_expected = $obj->pmp_expected; } else { @@ -1206,7 +1206,7 @@ if ($resql) { } $pmp_valuation = $pmp_expected * $valuetoshow; print ''; print ''; - //PMP Real + // PMP Real print ''; print ''; diff --git a/htdocs/product/stock/movement_card.php b/htdocs/product/stock/movement_card.php deleted file mode 100644 index 14c7458be81..00000000000 --- a/htdocs/product/stock/movement_card.php +++ /dev/null @@ -1,1255 +0,0 @@ - - * Copyright (C) 2004-2020 Laurent Destailleur - * Copyright (C) 2005-2014 Regis Houssin - * Copyright (C) 2015 Juanjo Menent - * Copyright (C) 2018 Ferran Marcet - * Copyright (C) 2019-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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/product/stock/movement_card.php - * \ingroup stock - * \brief Page to list stock movements - */ - -// Load Dolibarr environment -require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/stock.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/date.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'; -} - -/** - * @var Conf $conf - * @var DoliDB $db - * @var HookManager $hookmanager - * @var Translate $langs - * @var User $user - */ - -// Load translation files required by the page -$langs->loadLangs(array('products', 'stocks', 'orders')); -if (isModEnabled('productbatch')) { - $langs->load("productbatch"); -} - -$id = GETPOSTINT('id'); -$ref = GETPOST('ref', 'alpha'); -$msid = GETPOSTINT('msid'); -$product_id = GETPOSTINT("product_id"); -$action = GETPOST('action', 'aZ09'); -$cancel = GETPOST('cancel', 'alpha'); -$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'movementlist'; -$optioncss = GETPOST('optioncss', 'alpha'); -$backtopage = GETPOST('backtopage', 'alpha'); - -$idproduct = GETPOSTINT('idproduct'); -$year = GETPOSTINT("year"); -$month = GETPOSTINT("month"); -$search_ref = GETPOST('search_ref', 'alpha'); -$search_movement = GETPOST("search_movement", 'alpha'); -$search_product_ref = trim(GETPOST("search_product_ref", 'alpha')); -$search_product = trim(GETPOST("search_product", 'alpha')); -$search_warehouse = trim(GETPOST("search_warehouse", 'alpha')); -$search_inventorycode = trim(GETPOST("search_inventorycode", 'alpha')); -$search_user = trim(GETPOST("search_user", 'alpha')); -$search_batch = trim(GETPOST("search_batch", 'alpha')); -$search_qty = trim(GETPOST("search_qty", 'alpha')); -$search_type_mouvement = GETPOST('search_type_mouvement', "intcomma"); - -$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; -$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page"); -$sortfield = GETPOST('sortfield', 'aZ09comma'); -$sortorder = GETPOST('sortorder', 'aZ09comma'); -if (empty($page) || $page == -1) { - $page = 0; -} // If $page is not defined, or '' or -1 -$offset = $limit * $page; -if (!$sortfield) { - $sortfield = "m.datem"; -} -if (!$sortorder) { - $sortorder = "DESC"; -} - -$pdluoid = GETPOSTINT('pdluoid'); - -$hookmanager->initHooks(array('movementlist')); - -// Security check -$result = restrictedArea($user, 'stock'); - -// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context -$object = new MouvementStock($db); -$extrafields = new ExtraFields($db); -$formfile = new FormFile($db); - -// fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label($object->table_element); - -$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); - -$arrayfields = array( - 'm.rowid' => array('label' => $langs->trans("Ref"), 'checked' => '1'), - 'm.datem' => array('label' => $langs->trans("Date"), 'checked' => '1'), - 'p.ref' => array('label' => $langs->trans("ProductRef"), 'checked' => '1', 'css' => 'maxwidth100'), - 'p.label' => array('label' => $langs->trans("ProductLabel"), 'checked' => '1'), - 'm.batch' => array('label' => $langs->trans("BatchNumberShort"), 'checked' => '1', 'enabled' => (string) (int) (isModEnabled('productbatch'))), - 'pl.eatby' => array('label' => $langs->trans("EatByDate"), 'checked' => '0', 'position' => 10, 'enabled' => (string) (int) (isModEnabled('productbatch'))), - 'pl.sellby' => array('label' => $langs->trans("SellByDate"), 'checked' => '0', 'position' => 10, 'enabled' => (string) (int) (isModEnabled('productbatch'))), - 'e.ref' => array('label' => $langs->trans("Warehouse"), 'checked' => '1', 'enabled' => (string) (int) (!($id > 0))), // If we are on specific warehouse, we hide it - 'm.fk_user_author' => array('label' => $langs->trans("Author"), 'checked' => '0'), - 'm.inventorycode' => array('label' => $langs->trans("InventoryCodeShort"), 'checked' => '1'), - 'm.label' => array('label' => $langs->trans("MovementLabel"), 'checked' => '1'), - 'm.type_mouvement' => array('label' => $langs->trans("TypeMovement"), 'checked' => '1'), - 'origin' => array('label' => $langs->trans("Origin"), 'checked' => '1'), - 'm.value' => array('label' => $langs->trans("Qty"), 'checked' => '1'), - 'm.price' => array('label' => $langs->trans("UnitPurchaseValue"), 'checked' => '0'), - //'m.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked' => '0', 'position'=>500), - //'m.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked' => '0', 'position'=>500) -); - -$usercanread = (($user->hasRight('stock', 'mouvement', 'lire'))); -$usercancreate = (($user->hasRight('stock', 'mouvement', 'creer'))); -$usercandelete = (($user->hasRight('stock', 'mouvement', 'supprimer'))); - - - -/* - * Actions - */ - -if (GETPOST('cancel', 'alpha')) { - $action = 'list'; - $massaction = ''; -} -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { - $massaction = ''; -} - -$parameters = array(); -$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks -if ($reshook < 0) { - setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -} - -include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; - -// Do we click on purge search criteria ? -if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // Both test are required to be compatible with all browsers - $year = ''; - $month = ''; - $search_ref = ''; - $search_movement = ""; - $search_type_mouvement = ""; - $search_inventorycode = ""; - $search_product_ref = ""; - $search_product = ""; - $search_warehouse = ""; - $search_user = ""; - $search_batch = ""; - $search_qty = ''; - $sall = ""; - $toselect = array(); - $search_array_options = array(); -} - -// Correct stock -if ($action == "correct_stock" && !$cancel && $usercancreate) { - $product = new Product($db); - if (!empty($product_id)) { - $result = $product->fetch($product_id); - } - - $error = 0; - - if (empty($product_id)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors'); - $action = 'correction'; - } - if (!is_numeric(GETPOST("nbpiece"))) { - $error++; - setEventMessages($langs->trans("ErrorFieldMustBeANumeric", $langs->transnoentitiesnoconv("NumberOfUnit")), null, 'errors'); - $action = 'correction'; - } - - if (!$error) { - $origin_element = ''; - $origin_id = null; - - if (GETPOSTINT('projectid')) { - $origin_element = 'project'; - $origin_id = GETPOSTINT('projectid'); - } - - if ($product->hasbatch()) { - $batch = GETPOST('batch_number', 'alpha'); - - //$eatby=GETPOST('eatby'); - //$sellby=GETPOST('sellby'); - $eatby = dol_mktime(0, 0, 0, GETPOSTINT('eatbymonth'), GETPOSTINT('eatbyday'), GETPOSTINT('eatbyyear')); - $sellby = dol_mktime(0, 0, 0, GETPOSTINT('sellbymonth'), GETPOSTINT('sellbyday'), GETPOSTINT('sellbyyear')); - - $result = $product->correct_stock_batch( - $user, - $id, - GETPOSTFLOAT("nbpiece"), - GETPOSTINT("mouvement"), - GETPOST("label", 'san_alpha'), - GETPOSTFLOAT('unitprice'), - $eatby, - $sellby, - $batch, - GETPOST('inventorycode', 'alpha'), - $origin_element, - $origin_id - ); // We do not change value of stock for a correction - } else { - $result = $product->correct_stock( - $user, - $id, - GETPOSTFLOAT("nbpiece"), - GETPOSTINT("mouvement"), - GETPOST("label", 'san_alpha'), - GETPOSTFLOAT('unitprice'), - GETPOST('inventorycode', 'alpha'), - $origin_element, - $origin_id - ); // We do not change value of stock for a correction - } - - if ($result > 0) { - header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); - exit; - } else { - $error++; - setEventMessages($product->error, $product->errors, 'errors'); - $action = 'correction'; - } - } - - if (!$error) { - $action = ''; - } -} - -// Transfer stock from a warehouse to another warehouse -if ($action == "transfert_stock" && !$cancel && $usercancreate) { - $error = 0; - $product = new Product($db); - if (!empty($product_id)) { - $result = $product->fetch($product_id); - } - - if (!(GETPOSTINT("id_entrepot_destination") > 0)) { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Warehouse")), null, 'errors'); - $error++; - $action = 'transfert'; - } - if (empty($product_id)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors'); - $action = 'transfert'; - } - if (!GETPOSTFLOAT("nbpiece")) { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumberOfUnit")), null, 'errors'); - $error++; - $action = 'transfert'; - } - if ($id == GETPOSTINT("id_entrepot_destination")) { - setEventMessages($langs->trans("ErrorSrcAndTargetWarehouseMustDiffers"), null, 'errors'); - $error++; - $action = 'transfert'; - } - - if (isModEnabled('productbatch')) { - $product = new Product($db); - $result = $product->fetch($product_id); - - if ($product->hasbatch() && !GETPOST("batch_number", 'alpha')) { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("batch_number")), null, 'errors'); - $error++; - $action = 'transfert'; - } - } - - if (!$error) { - if ($id) { - $object = new Entrepot($db); - $result = $object->fetch($id); - - $db->begin(); - - $product->load_stock('novirtual'); // Load array product->stock_warehouse - - // Define value of products moved - $pricesrc = 0; - if (isset($product->pmp)) { - $pricesrc = $product->pmp; - } - $pricedest = $pricesrc; - - $result1 = -1; - $result2 = -1; - - if ($product->hasbatch()) { - $pdluo = new Productbatch($db); - - $batch = ''; - $eatby = 0; - $sellby = 0; - $srcwarehouseid = 0; - - if ($pdluoid > 0) { - $result = $pdluo->fetch($pdluoid); - if ($result) { - $srcwarehouseid = $pdluo->warehouseid; - $batch = (string) $pdluo->batch; - $eatby = $pdluo->eatby; - $sellby = $pdluo->sellby; - } else { - setEventMessages($pdluo->error, $pdluo->errors, 'errors'); - $error++; - } - } else { - $srcwarehouseid = $id; - $batch = (string) GETPOST('batch_number', 'alpha'); - $eatby = GETPOSTDATE('eatby'); - $sellby = GETPOSTDATE('sellby'); - } - - if (!$error) { - // Remove stock - $result1 = $product->correct_stock_batch( - $user, - $srcwarehouseid, - GETPOSTFLOAT("nbpiece"), - 1, - GETPOST("label", 'san_alpha'), - (float) $pricesrc, - $eatby, - $sellby, - $batch, - GETPOST('inventorycode', 'alpha') - ); - // Add stock - $result2 = $product->correct_stock_batch( - $user, - GETPOSTINT("id_entrepot_destination"), - GETPOSTFLOAT("nbpiece"), - 0, - GETPOST("label", 'san_alpha'), - (float) $pricedest, - $eatby, - $sellby, - $batch, - GETPOST('inventorycode', 'alpha') - ); - } - } else { - // Remove stock - $result1 = $product->correct_stock( - $user, - $id, - GETPOSTFLOAT("nbpiece"), - 1, - GETPOST("label", 'alpha'), - (float) $pricesrc, - GETPOST('inventorycode', 'alpha') - ); - - // Add stock - $result2 = $product->correct_stock( - $user, - GETPOSTINT("id_entrepot_destination"), - GETPOSTFLOAT("nbpiece"), - 0, - GETPOST("label", 'alpha'), - (float) $pricedest, - GETPOST('inventorycode', 'alpha') - ); - } - if (!$error && $result1 >= 0 && $result2 >= 0) { - $db->commit(); - - if ($backtopage) { - header("Location: ".$backtopage); - exit; - } else { - header("Location: movement_list.php?id=".$object->id); - exit; - } - } else { - setEventMessages($product->error, $product->errors, 'errors'); - $db->rollback(); - $action = 'transfert'; - } - } - } -} - - -/* - * Build document - */ -// The builddoc action for object of a movement must be on the movement card -// Actions to build doc -$upload_dir = $conf->stock->dir_output."movement/"; -$permissiontoadd = $user->hasRight('stock', 'creer'); -include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - - -if (empty($reshook) && $action != 'remove_file') { - $objectclass = 'MouvementStock'; - $objectlabel = 'Movements'; - $permissiontoread = $user->hasRight('stock', 'lire'); - $permissiontodelete = $user->hasRight('stock', 'supprimer'); - $uploaddir = $conf->stock->dir_output."/movement/"; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; -} - - - -/* - * View - */ - -$productlot = new Productlot($db); -$productstatic = new Product($db); -$warehousestatic = new Entrepot($db); -$movement = new MouvementStock($db); -$userstatic = new User($db); -$form = new Form($db); -$formother = new FormOther($db); -$formproduct = new FormProduct($db); -if (isModEnabled('project')) { - $formproject = new FormProjets($db); -} - -$sql = "SELECT p.rowid, p.ref as product_ref, p.label as produit, p.tobatch, p.fk_product_type as type, p.entity,"; -$sql .= " e.ref as warehouse_ref, e.rowid as entrepot_id, e.lieu,"; -$sql .= " m.rowid as mid, m.value as qty, m.datem, m.fk_user_author, m.label, m.inventorycode, m.fk_origin, m.origintype,"; -$sql .= " m.batch, m.price,"; -$sql .= " m.type_mouvement,"; -$sql .= " pl.rowid as lotid, pl.eatby, pl.sellby,"; -$sql .= " u.login, u.photo, u.lastname, u.firstname"; -// Add fields from extrafields -if (!empty($extrafields->attributes[$object->table_element]['label'])) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : ''); - } -} -// Add fields from hooks -$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."entrepot as e,"; -$sql .= " ".MAIN_DB_PREFIX."product as p,"; -$sql .= " ".MAIN_DB_PREFIX."stock_mouvement as m"; -if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (m.rowid = ef.fk_object)"; -} -$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON m.fk_user_author = u.rowid"; -$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot as pl ON m.batch = pl.batch AND m.fk_product = pl.fk_product"; -$sql .= " WHERE m.fk_product = p.rowid"; -if ($msid > 0) { - $sql .= " AND m.rowid = ".((int) $msid); -} -$sql .= " AND m.fk_entrepot = e.rowid"; -$sql .= " AND e.entity IN (".getEntity('stock').")"; -if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { - $sql .= " AND p.fk_product_type = 0"; -} -if ($id > 0) { - $sql .= " AND e.rowid = ".((int) $id); -} -$sql .= dolSqlDateFilter('m.datem', 0, $month, $year); -if ($idproduct > 0) { - $sql .= " AND p.rowid = ".((int) $idproduct); -} -if (!empty($search_ref)) { - $sql .= natural_search('m.rowid', $search_ref, 1); -} -if (!empty($search_movement)) { - $sql .= natural_search('m.label', $search_movement); -} -if (!empty($search_inventorycode)) { - $sql .= natural_search('m.inventorycode', $search_inventorycode); -} -if (!empty($search_product_ref)) { - $sql .= natural_search('p.ref', $search_product_ref); -} -if (!empty($search_product)) { - $sql .= natural_search('p.label', $search_product); -} -if ($search_warehouse != '' && $search_warehouse != '-1') { - $sql .= natural_search('e.rowid', $search_warehouse, 2); -} -if (!empty($search_user)) { - $sql .= natural_search(array('u.lastname', 'u.firstname', 'u.login'), $search_user); -} -if (!empty($search_batch)) { - $sql .= natural_search('m.batch', $search_batch); -} -if ($search_qty != '') { - $sql .= natural_search('m.value', $search_qty, 1); -} -if ($search_type_mouvement != '' && $search_type_mouvement != '-1') { - $sql .= natural_search('m.type_mouvement', $search_type_mouvement, 2); -} -// Add where from extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; -// Add where from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook -$sql .= $hookmanager->resPrint; -$sql .= $db->order($sortfield, $sortorder); - -$nbtotalofrecords = ''; -if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 - $page = 0; - $offset = 0; - } -} - -//print $sql; - -$resql = $db->query($sql); - -if ($resql) { - $product = new Product($db); - $object = new Entrepot($db); - - if ($idproduct > 0) { - $product->fetch($idproduct); - } - if ($id > 0 || $ref) { - $result = $object->fetch($id, $ref); - if ($result < 0) { - dol_print_error($db); - } - } - - $num = $db->num_rows($resql); - - $arrayofselected = is_array($toselect) ? $toselect : array(); - - - $i = 0; - $help_url = 'EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; - if ($msid) { - $texte = $langs->trans('StockMovementForId', $msid); - } else { - $texte = $langs->trans("StockMovements"); - if ($id) { - $texte .= ' ('.$langs->trans("ForThisWarehouse").')'; - } - } - llxHeader("", $texte, $help_url, '', 0, 0, '', '', '', 'mod-product page-stock_movement_card'); - - /* - * Show tab only if we ask a particular warehouse - */ - if ($object->id > 0) { - $head = stock_prepare_head($object); - - print dol_get_fiche_head($head, 'movements', $langs->trans("Warehouse"), -1, 'stock'); - - - $linkback = ''.$langs->trans("BackToList").''; - - $morehtmlref = '
'; - $morehtmlref .= $langs->trans("LocationSummary").' : '.$object->lieu; - $morehtmlref .= '
'; - - $shownav = 1; - if ($user->socid && !in_array('stock', explode(',', getDolGlobalString('MAIN_MODULES_FOR_EXTERNAL')))) { - $shownav = 0; - } - - dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', 'ref', $morehtmlref); - - - print '
'; - print '
'; - print '
'; - - print '
'.$langs->trans("Line").''.$langs->trans("ThirdParty").''.$langs->trans("Amount").''.$langs->trans("Reason").''.$langs->trans("ToBill").''; + print_liste_field_titre("Line", $_SERVER["PHP_SELF"], "pl.rowid", '', $param, '', $sortfield, $sortorder); + print_liste_field_titre((!$salaryBonPl ? "ThirdParty" : "Employee"), $_SERVER["PHP_SELF"], "s.nom", '', $param, '', $sortfield, $sortorder); + print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "pl.amount", '', $param, '', $sortfield, $sortorder, 'right '); + print_liste_field_titre("Reason", $_SERVER["PHP_SELF"], "pr.motif", '', $param, '', $sortfield, $sortorder); + print_liste_field_titre("ToBill", $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center '); + print_liste_field_titre(""); // Invoice to charge the error. No yet implemented. //print $langs->trans("Invoice"); - print '
'.$langs->trans("AlreadyPaid").':'.price($totalpaid).'
'.$langs->trans("AmountExpected").':'.price($object->total_ttc).'
'.$langs->trans("RemainderToPay").':'.price($resteapayeraffiche).'
'.price($resteapayeraffiche).'
'.$langs->trans("AmountTTC").''.$langs->trans("DateModificationShort").''; - print ''; - print img_picto($langs->trans("FullList"), 'expensereport'); + print ''; + print '...'; print ''; print '
'.$langs->trans("AmountExpected").':'.price($object->total_ttc).'
'.$langs->trans("RemainderToPay").':'.price($resteapayeraffiche).'
'.price($resteapayeraffiche).'
'; - print price($pmp_expected); + print is_null($pmp_expected) ? '' : price($pmp_expected); print ''; print ''; @@ -1171,7 +1171,7 @@ if ($resql) { $pmp_real = $product_static->pmp; } $pmp_valuation_real = $pmp_real * $qty_view; - print ''; + print ''; print ''; print ''; From ce91aed92c1445939243566832b2833d4f6f19ef Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 11:36:56 +0200 Subject: [PATCH 40/73] Fix warning --- htdocs/fourn/ajax/getSupplierPrices.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/ajax/getSupplierPrices.php b/htdocs/fourn/ajax/getSupplierPrices.php index ef4663d724e..2d0d838cabc 100644 --- a/htdocs/fourn/ajax/getSupplierPrices.php +++ b/htdocs/fourn/ajax/getSupplierPrices.php @@ -122,7 +122,7 @@ if ($idprod > 0) { } } - $prices[] = array("id" => 'pmpprice', "price" => price2num((float) $price), "label" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency), "title" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency)); // For price field, we must use price2num(), for label or title, price() + $prices[] = array("id" => 'pmpprice', "price" => price2num((float) $price, 'MU'), "label" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency), "title" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency)); // For price field, we must use price2num(), for label or title, price() } // Add price for costprice (at end) From b70943db5940e90efe0b470d8ac855022d62f6ce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 11:45:25 +0200 Subject: [PATCH 41/73] Fix typo --- 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 9628d02ecaa..1b497120e54 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7058,7 +7058,7 @@ function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0, * Function to format a value into an amount for visual output * Function used into PDF and HTML pages * - * @param int|float[string $amount Amount value to format + * @param int|float|string $amount Amount value to format * @param int<0,1> $form Type of formatting: 1=HTML, 0=no formatting (no by default) * @param Translate|string|null $outlangs Object langs for output. '' use default lang. 'none' use international separators. * @param int $trunc 1=Truncate if there is more decimals than MAIN_MAX_DECIMALS_SHOWN (default), 0=Does not truncate. Deprecated because amount are rounded (to unit or total amount accuracy) before being inserted into database or after a computation, so this parameter should be useless. From 84879c15e91344a966daf287f8c4ecc7bb52a7b7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 12:09:45 +0200 Subject: [PATCH 42/73] Fix CI --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/fourn/ajax/getSupplierPrices.php | 2 +- htdocs/product/class/product.class.php | 2 +- htdocs/product/inventory/inventory.php | 8 ++++---- htdocs/product/stock/massstockmove.php | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1b497120e54..48be736362c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7178,7 +7178,7 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $ * Function to use on each input amount before any numeric test or database insert. A better name for this function * should be roundtext2num(). * - * @param int|float|string $amount Amount to convert/clean or round + * @param int|float|string|null $amount Amount to convert/clean or round * @param ''|'MU'|'MT'|'MS'|'CU'|'CT'|int<0,max> $rounding ''=No rounding * 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT) * 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT) diff --git a/htdocs/fourn/ajax/getSupplierPrices.php b/htdocs/fourn/ajax/getSupplierPrices.php index 2d0d838cabc..08385b342a4 100644 --- a/htdocs/fourn/ajax/getSupplierPrices.php +++ b/htdocs/fourn/ajax/getSupplierPrices.php @@ -122,7 +122,7 @@ if ($idprod > 0) { } } - $prices[] = array("id" => 'pmpprice', "price" => price2num((float) $price, 'MU'), "label" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency), "title" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency)); // For price field, we must use price2num(), for label or title, price() + $prices[] = array("id" => 'pmpprice', "price" => price2num($price, 'MU'), "label" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency), "title" => $langs->trans("PMPValueShort").': '.price($price, 0, $langs, 0, 0, -1, $conf->currency)); // For price field, we must use price2num(), for label or title, price() } // Add price for costprice (at end) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index f9834f88e51..cecda57430f 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -6111,7 +6111,7 @@ class Product extends CommonObject * @param float $nbpiece nb of units (should be always positive, use $movement to decide if we add or remove) * @param int<0,1> $movement 0 = add, 1 = remove * @param string $label Label of stock movement - * @param float $price Unit price HT of product, used to calculate average weighted price (PMP in french). If 0, average weighted price is not changed. + * @param int|float $price Unit price HT of product, used to calculate average weighted price (PMP in french). If 0, average weighted price is not changed. * @param string $inventorycode Inventory code * @param string $origin_element Origin element type * @param ?int $origin_id Origin id of element diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 73f6fd0134f..a0835b81ffb 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -1198,7 +1198,7 @@ if ($resql) { print ''; - print price($pmp_expected); + print is_null($pmp_expected) ? '' : price($pmp_expected); print ''; print price($pmp_valuation); @@ -1216,7 +1216,7 @@ if ($resql) { print $obj->qty_view; // qty found print ''; if (!empty($obj->pmp_real)) { $pmp_real = $obj->pmp_real; @@ -1224,7 +1224,7 @@ if ($resql) { $pmp_real = $product_static->pmp; } $pmp_valuation_real = $pmp_real * $obj->qty_view; - print price($pmp_real); + print is_null($pmp_real) ? '' : price($pmp_real); print ''; print price($pmp_valuation_real); diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php index 362cd716b9b..9abd5d83716 100644 --- a/htdocs/product/stock/massstockmove.php +++ b/htdocs/product/stock/massstockmove.php @@ -216,7 +216,7 @@ if ($action == 'createmovements' && $user->hasRight('stock', 'mouvement', 'creer // Define value of products moved $pricesrc = 0; if (!empty($product->pmp)) { - $pricesrc = $product->pmp; + $pricesrc = (float) $product->pmp; } $pricedest = $pricesrc; From 6748d3a14b24a9a16dee3f7ddd8c9915ce894a6e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 12:31:08 +0200 Subject: [PATCH 43/73] Fix CI --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/product/class/product.class.php | 2 +- htdocs/product/stock/class/mouvementstock.class.php | 2 +- htdocs/product/stock/movement_card.php | 13 +++++++------ htdocs/product/stock/movement_list.php | 8 ++++---- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 48be736362c..3b0bbbc926d 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7058,7 +7058,7 @@ function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0, * Function to format a value into an amount for visual output * Function used into PDF and HTML pages * - * @param int|float|string $amount Amount value to format + * @param int|float|string|null $amount Amount value to format * @param int<0,1> $form Type of formatting: 1=HTML, 0=no formatting (no by default) * @param Translate|string|null $outlangs Object langs for output. '' use default lang. 'none' use international separators. * @param int $trunc 1=Truncate if there is more decimals than MAIN_MAX_DECIMALS_SHOWN (default), 0=Does not truncate. Deprecated because amount are rounded (to unit or total amount accuracy) before being inserted into database or after a computation, so this parameter should be useless. diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index cecda57430f..0c0d61400e1 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -6172,7 +6172,7 @@ class Product extends CommonObject * @param float $nbpiece nb of units (should be always positive, use $movement to decide if we add or remove) * @param int<0,1> $movement 0 = add, 1 = remove * @param string $label Label of stock movement - * @param float $price Price to use for stock eval + * @param int|float $price Price to use for stock eval * @param int|string $dlc eat-by date * @param int|string $dluo sell-by date * @param string $lot Lot number diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 72cc98c9f6e..e7b0755c3cd 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -205,7 +205,7 @@ class MouvementStock extends CommonObject * 0=input (stock increase by a stock transfer), 1=output (stock decrease by a stock transfer), * 2=output (stock decrease), 3=input (stock increase) * Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2. - * @param float $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 int|float $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 int|string $datem Force date of movement diff --git a/htdocs/product/stock/movement_card.php b/htdocs/product/stock/movement_card.php index 2e19b6b9a83..14c7458be81 100644 --- a/htdocs/product/stock/movement_card.php +++ b/htdocs/product/stock/movement_card.php @@ -66,6 +66,7 @@ $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'movementlist'; $optioncss = GETPOST('optioncss', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); $idproduct = GETPOSTINT('idproduct'); $year = GETPOSTINT("year"); @@ -339,8 +340,8 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { } else { $srcwarehouseid = $id; $batch = (string) GETPOST('batch_number', 'alpha'); - $eatby = $d_eatby; - $sellby = $d_sellby; + $eatby = GETPOSTDATE('eatby'); + $sellby = GETPOSTDATE('sellby'); } if (!$error) { @@ -351,7 +352,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { GETPOSTFLOAT("nbpiece"), 1, GETPOST("label", 'san_alpha'), - $pricesrc, + (float) $pricesrc, $eatby, $sellby, $batch, @@ -364,7 +365,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { GETPOSTFLOAT("nbpiece"), 0, GETPOST("label", 'san_alpha'), - $pricedest, + (float) $pricedest, $eatby, $sellby, $batch, @@ -379,7 +380,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { GETPOSTFLOAT("nbpiece"), 1, GETPOST("label", 'alpha'), - $pricesrc, + (float) $pricesrc, GETPOST('inventorycode', 'alpha') ); @@ -390,7 +391,7 @@ if ($action == "transfert_stock" && !$cancel && $usercancreate) { GETPOSTFLOAT("nbpiece"), 0, GETPOST("label", 'alpha'), - $pricedest, + (float) $pricedest, GETPOST('inventorycode', 'alpha') ); } diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php index f50ad707cc7..495ce2c4375 100644 --- a/htdocs/product/stock/movement_list.php +++ b/htdocs/product/stock/movement_list.php @@ -542,7 +542,7 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { GETPOSTFLOAT("nbpiece"), 1, GETPOST("label", 'san_alpha'), - $pricesrc, + (float) $pricesrc, $eatby, $sellby, $batch, @@ -559,7 +559,7 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { GETPOSTFLOAT("nbpiece"), 0, GETPOST("label", 'san_alpha'), - $pricedest, + (float) $pricedest, $eatby, $sellby, $batch, @@ -578,7 +578,7 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { GETPOSTFLOAT("nbpiece"), 1, GETPOST("label", 'san_alpha'), - $pricesrc, + (float) $pricesrc, GETPOST('inventorycode', 'alphanohtml'), '', null, @@ -593,7 +593,7 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { GETPOSTFLOAT("nbpiece"), 0, GETPOST("label", 'san_alpha'), - $pricedest, + (float) $pricedest, GETPOST('inventorycode', 'alphanohtml'), '', null, From 4f679f06d72c24ca269dcac14260b37fc7b4c5c0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 12:41:00 +0200 Subject: [PATCH 44/73] Fix CI --- htdocs/core/lib/admin.lib.php | 2 +- htdocs/product/class/product.class.php | 32 +++++++++++++------------- htdocs/product/stock/product.php | 6 ++--- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 04856a3fe5c..f97e72c959d 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1575,7 +1575,7 @@ function complete_dictionary_with_modules(&$taborder, &$tabname, &$tablib, &$tab */ function activateModulesRequiredByCountry($country_code) { - global $db, $conf, $langs; + global $db; $modulesdir = dolGetModulesDirs(); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 0c0d61400e1..782f388df43 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -6167,22 +6167,22 @@ class Product extends CommonObject /** * Adjust stock in a warehouse for product with batch number * - * @param User $user user asking change - * @param int $id_entrepot id of warehouse - * @param float $nbpiece nb of units (should be always positive, use $movement to decide if we add or remove) - * @param int<0,1> $movement 0 = add, 1 = remove - * @param string $label Label of stock movement - * @param int|float $price Price to use for stock eval - * @param int|string $dlc eat-by date - * @param int|string $dluo sell-by date - * @param string $lot Lot number - * @param string $inventorycode Inventory code - * @param string $origin_element Origin element type - * @param ?int $origin_id Origin id of element - * @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (useful only if product is a subproduct) - * @param ?ExtraFields $extrafields Array of extrafields - * @param boolean $force_update_batch Force update batch - * @return int Return integer <0 if KO, >0 if OK + * @param User $user User asking change + * @param int $id_entrepot Id of warehouse + * @param float $nbpiece Nb of units (should be always positive, use $movement to decide if we add or remove) + * @param int<0,1> $movement 0 = add, 1 = remove + * @param string $label Label of stock movement + * @param int|float $price Price to use for stock eval + * @param int|string $dlc eat-by date + * @param int|string $dluo sell-by date + * @param string $lot Lot number + * @param string $inventorycode Inventory code + * @param string $origin_element Origin element type + * @param ?int $origin_id Origin id of element + * @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (useful only if product is a subproduct) + * @param ?ExtraFields $extrafields Array of extrafields + * @param boolean $force_update_batch Force update batch + * @return int Return integer <0 if KO, >0 if OK */ public function correct_stock_batch($user, $id_entrepot, $nbpiece, $movement, $label = '', $price = 0, $dlc = '', $dluo = '', $lot = '', $inventorycode = '', $origin_element = '', $origin_id = null, $disablestockchangeforsubproduct = 0, $extrafields = null, $force_update_batch = false) { diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 4492f47b215..1680c20293a 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -434,7 +434,7 @@ if ($action == "transfert_stock" && !$cancel && $usercanupdatestock) { (float) $nbpiece, 1, GETPOST("label", 'alphanohtml'), - $pricesrc, + (float) $pricesrc, $eatby, $sellby, $batch, @@ -452,7 +452,7 @@ if ($action == "transfert_stock" && !$cancel && $usercanupdatestock) { (float) $nbpiece, 0, GETPOST("label", 'alphanohtml'), - $pricedest, + (float) $pricedest, $eatby, $sellby, (string) $batch, @@ -486,7 +486,7 @@ if ($action == "transfert_stock" && !$cancel && $usercanupdatestock) { (float) $nbpiece, 0, GETPOST("label", 'alphanohtml'), - $pricedest, + (float) $pricedest, GETPOST('inventorycode', 'alphanohtml') ); if ($result2 < 0) { From 1380b94fb0c34c05354188452557d7de02ce740e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 13:02:17 +0200 Subject: [PATCH 45/73] Fix CI --- htdocs/mrp/mo_movements.php | 2 +- htdocs/product/stock/movement_card.php | 1255 ------------------------ htdocs/product/stock/product.php | 2 +- 3 files changed, 2 insertions(+), 1257 deletions(-) delete mode 100644 htdocs/product/stock/movement_card.php diff --git a/htdocs/mrp/mo_movements.php b/htdocs/mrp/mo_movements.php index 44a6aa194dc..f899c8308b7 100644 --- a/htdocs/mrp/mo_movements.php +++ b/htdocs/mrp/mo_movements.php @@ -966,7 +966,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Inventory code if (!empty($arrayfields['m.inventorycode']['checked'])) { print ''; - //print ''; + //print ''; print dol_escape_htmltag($objp->inventorycode); //print ''; print '
'; - - print ''; - - // Description - print ''; - - $calcproductsunique = $object->nb_different_products(); - $calcproducts = $object->nb_products(); - - // Total nb of different products - print '"; - - // Nb of products - print '"; - - print '
'.$langs->trans("Description").''.dol_htmlentitiesbr($object->description).'
'.$langs->trans("NumberOfDifferentProducts").''; - print empty($calcproductsunique['nb']) ? '0' : $calcproductsunique['nb']; - print "
'.$langs->trans("NumberOfProducts").''; - $valtoshow = price2num($calcproducts['nb'], 'MS'); - print empty($valtoshow) ? '0' : $valtoshow; - print "
'; - - print '
'; - print '
'; - print '
'; - - print ''; - - // Value - print '"; - - // Last movement - $sql = "SELECT MAX(m.datem) as datem"; - $sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m"; - $sql .= " WHERE m.fk_entrepot = ".(int) $object->id; - $lastmovementdate = 0; - $resqlbis = $db->query($sql); - if ($resqlbis) { - $obj = $db->fetch_object($resqlbis); - $lastmovementdate = $db->jdate($obj->datem); - } else { - dol_print_error($db); - } - - print '"; - - print "
'.$langs->trans("EstimatedStockValueShort").''; - print price((empty($calcproducts['value']) ? '0' : price2num($calcproducts['value'], 'MT')), 0, $langs, 0, -1, -1, $conf->currency); - print "
'.$langs->trans("LastMovement").''; - if ($lastmovementdate) { - print dol_print_date($lastmovementdate, 'dayhour'); - } else { - print $langs->trans("None"); - } - print "
"; - - print '
'; - print ''; - - print '
'; - - print dol_get_fiche_end(); - } - - - /* - * Correct stock - */ - if ($action == "correction") { - include DOL_DOCUMENT_ROOT.'/product/stock/tpl/stockcorrection.tpl.php'; - print '
'; - } - - /* - * Transfer of units - */ - if ($action == "transfert") { - include DOL_DOCUMENT_ROOT.'/product/stock/tpl/stocktransfer.tpl.php'; - print '
'; - } - - - /* - * Action bar - */ - if ((empty($action) || $action == 'list') && $id > 0) { - print "
\n"; - - if ($user->hasRight('stock', 'mouvement', 'creer')) { - print ''.$langs->trans("CorrectStock").''; - } - - if ($user->hasRight('stock', 'mouvement', 'creer')) { - print ''.$langs->trans("TransferStock").''; - } - - print '

'; - } - - $param = ''; - if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { - $param .= '&contextpage='.urlencode($contextpage); - } - if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.((int) $limit); - } - if ($id > 0) { - $param .= '&id='.urlencode((string) ($id)); - } - if ($search_movement) { - $param .= '&search_movement='.urlencode($search_movement); - } - if ($search_inventorycode) { - $param .= '&search_inventorycode='.urlencode($search_inventorycode); - } - if ($search_type_mouvement) { - $param .= '&search_type_mouvement='.urlencode($search_type_mouvement); - } - if ($search_product_ref) { - $param .= '&search_product_ref='.urlencode($search_product_ref); - } - if ($search_product) { - $param .= '&search_product='.urlencode($search_product); - } - if ($search_batch) { - $param .= '&search_batch='.urlencode($search_batch); - } - if ($search_warehouse > 0) { - $param .= '&search_warehouse='.urlencode($search_warehouse); - } - if ($search_user) { - $param .= '&search_user='.urlencode($search_user); - } - if ($idproduct > 0) { - $param .= '&idproduct='.urlencode((string) ($idproduct)); - } - // Add $param from extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; - - // List of mass actions available - $arrayofmassactions = array( - // 'presend'=>$langs->trans("SendByMail"), - // 'builddoc'=>$langs->trans("PDFMerge"), - ); - //if ($user->rights->stock->supprimer) $arrayofmassactions['predelete']=''.$langs->trans("Delete"); - if (in_array($massaction, array('presend', 'predelete'))) { - $arrayofmassactions = array(); - } - $massactionbutton = $form->selectMassAction('', $arrayofmassactions); - - print ''; - if ($optioncss != '') { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if ($id > 0) { - print ''; - } - - if ($id > 0) { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, '', '', $limit); - } else { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, '', '', $limit); - } - - if ($sall) { - if (!isset($fieldstosearchall) || !is_array($fieldstosearchall)) { - // Ensure $fieldstosearchall is array - $fieldstosearchall = array(); - } - foreach ($fieldstosearchall as $key => $val) { - $fieldstosearchall[$key] = $langs->trans($val); - } - print '
'.$langs->trans("FilterOnInto", $sall).implode(', ', $fieldstosearchall).'
'; - } - - $moreforfilter = ''; - - $parameters = array(); - $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook - if (empty($reshook)) { - $moreforfilter .= $hookmanager->resPrint; - } else { - $moreforfilter = $hookmanager->resPrint; - } - - if (!empty($moreforfilter)) { - print '
'; - print $moreforfilter; - print '
'; - } - - $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; - $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - - print '
'; - print ''."\n"; - - // Fields title search - print ''; - if (!empty($arrayfields['m.rowid']['checked'])) { - // Ref - print ''; - } - if (!empty($arrayfields['m.datem']['checked'])) { - print ''; - } - if (!empty($arrayfields['p.ref']['checked'])) { - // Product Ref - print ''; - } - if (!empty($arrayfields['p.label']['checked'])) { - // Product label - print ''; - } - // Batch - if (!empty($arrayfields['m.batch']['checked'])) { - print ''; - } - if (!empty($arrayfields['pl.eatby']['checked'])) { - print ''; - } - if (!empty($arrayfields['pl.sellby']['checked'])) { - print ''; - } - // Warehouse - if (!empty($arrayfields['e.ref']['checked'])) { - print ''; - } - if (!empty($arrayfields['m.fk_user_author']['checked'])) { - // Author - print ''; - } - if (!empty($arrayfields['m.inventorycode']['checked'])) { - // Inventory code - print ''; - } - if (!empty($arrayfields['m.label']['checked'])) { - // Label of movement - print ''; - } - if (!empty($arrayfields['m.type_mouvement']['checked'])) { - // Type of movement - print ''; - } - if (!empty($arrayfields['origin']['checked'])) { - // Origin of movement - print ''; - } - if (!empty($arrayfields['m.value']['checked'])) { - // Qty - print ''; - } - if (!empty($arrayfields['m.price']['checked'])) { - // Price - print ''; - } - - - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; - - // Fields from hook - $parameters = array('arrayfields' => $arrayfields); - $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Date creation - if (!empty($arrayfields['m.datec']['checked'])) { - print ''; - } - // Date modification - if (!empty($arrayfields['m.tms']['checked'])) { - print ''; - } - // Actions - print ''; - print "\n"; - - print ''; - if (!empty($arrayfields['m.rowid']['checked'])) { - print_liste_field_titre($arrayfields['m.rowid']['label'], $_SERVER["PHP_SELF"], 'm.rowid', '', $param, '', $sortfield, $sortorder); - } - if (!empty($arrayfields['m.datem']['checked'])) { - print_liste_field_titre($arrayfields['m.datem']['label'], $_SERVER["PHP_SELF"], 'm.datem', '', $param, '', $sortfield, $sortorder); - } - if (!empty($arrayfields['p.ref']['checked'])) { - print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], 'p.ref', '', $param, '', $sortfield, $sortorder); - } - if (!empty($arrayfields['p.label']['checked'])) { - print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"], 'p.label', '', $param, '', $sortfield, $sortorder); - } - if (!empty($arrayfields['m.batch']['checked'])) { - print_liste_field_titre($arrayfields['m.batch']['label'], $_SERVER["PHP_SELF"], 'm.batch', '', $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['pl.eatby']['checked'])) { - print_liste_field_titre($arrayfields['pl.eatby']['label'], $_SERVER["PHP_SELF"], 'pl.eatby', '', $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['pl.sellby']['checked'])) { - print_liste_field_titre($arrayfields['pl.sellby']['label'], $_SERVER["PHP_SELF"], 'pl.sellby', '', $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['e.ref']['checked'])) { - // We are on a specific warehouse card, no filter on other should be possible - print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"], "e.ref", "", $param, "", $sortfield, $sortorder); - } - if (!empty($arrayfields['m.fk_user_author']['checked'])) { - print_liste_field_titre($arrayfields['m.fk_user_author']['label'], $_SERVER["PHP_SELF"], "m.fk_user_author", "", $param, "", $sortfield, $sortorder); - } - if (!empty($arrayfields['m.inventorycode']['checked'])) { - print_liste_field_titre($arrayfields['m.inventorycode']['label'], $_SERVER["PHP_SELF"], "m.inventorycode", "", $param, "", $sortfield, $sortorder); - } - if (!empty($arrayfields['m.label']['checked'])) { - print_liste_field_titre($arrayfields['m.label']['label'], $_SERVER["PHP_SELF"], "m.label", "", $param, "", $sortfield, $sortorder); - } - if (!empty($arrayfields['m.type_mouvement']['checked'])) { - print_liste_field_titre($arrayfields['m.type_mouvement']['label'], $_SERVER["PHP_SELF"], "m.type_mouvement", "", $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['origin']['checked'])) { - print_liste_field_titre($arrayfields['origin']['label'], $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); - } - if (!empty($arrayfields['m.value']['checked'])) { - print_liste_field_titre($arrayfields['m.value']['label'], $_SERVER["PHP_SELF"], "m.value", "", $param, '', $sortfield, $sortorder, 'right '); - } - if (!empty($arrayfields['m.price']['checked'])) { - print_liste_field_titre($arrayfields['m.price']['label'], $_SERVER["PHP_SELF"], "m.price", "", $param, '', $sortfield, $sortorder, 'right '); - } - - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; - - // Hook fields - $parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder); - $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (!empty($arrayfields['m.datec']['checked'])) { - print_liste_field_titre($arrayfields['m.datec']['label'], $_SERVER["PHP_SELF"], "m.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap '); - } - if (!empty($arrayfields['m.tms']['checked'])) { - print_liste_field_titre($arrayfields['m.tms']['label'], $_SERVER["PHP_SELF"], "m.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap '); - } - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); - print "\n"; - - - $arrayofuniqueproduct = array(); - while ($i < ($limit ? min($num, $limit) : $num)) { - $objp = $db->fetch_object($resql); - - $userstatic->id = $objp->fk_user_author; - $userstatic->login = $objp->login; - $userstatic->lastname = $objp->lastname; - $userstatic->firstname = $objp->firstname; - $userstatic->photo = $objp->photo; - - $productstatic->id = $objp->rowid; - $productstatic->ref = $objp->product_ref; - $productstatic->label = $objp->produit; - $productstatic->type = $objp->type; - $productstatic->entity = $objp->entity; - $productstatic->status_batch = $objp->tobatch; - - $productlot->id = $objp->lotid; - $productlot->batch = $objp->batch; - $productlot->eatby = $objp->eatby; - $productlot->sellby = $objp->sellby; - - $warehousestatic->id = $objp->entrepot_id; - $warehousestatic->label = $objp->warehouse_ref; - $warehousestatic->lieu = $objp->lieu; - - $arrayofuniqueproduct[$objp->rowid] = $objp->produit; - if (!empty($objp->fk_origin)) { - $origin = $movement->get_origin($objp->fk_origin, $objp->origintype); - } else { - $origin = ''; - } - - print ''; - // Id movement - if (!empty($arrayfields['m.rowid']['checked'])) { - // This is primary not movement id - print ''; - } - if (!empty($arrayfields['m.datem']['checked'])) { - // Date - print ''; - } - if (!empty($arrayfields['p.ref']['checked'])) { - // Product ref - print '\n"; - } - if (!empty($arrayfields['p.label']['checked'])) { - // Product label - print '\n"; - } - if (!empty($arrayfields['m.batch']['checked'])) { - print ''; - } - if (!empty($arrayfields['pl.eatby']['checked'])) { - print ''; - } - if (!empty($arrayfields['pl.sellby']['checked'])) { - print ''; - } - // Warehouse - if (!empty($arrayfields['e.ref']['checked'])) { - print '\n"; - } - // Author - if (!empty($arrayfields['m.fk_user_author']['checked'])) { - print '\n"; - } - if (!empty($arrayfields['m.inventorycode']['checked'])) { - // Inventory code - print ''; - } - if (!empty($arrayfields['m.label']['checked'])) { - // Label of movement - print ''; - } - if (!empty($arrayfields['m.type_mouvement']['checked'])) { - // Type of movement - switch ($objp->type_mouvement) { - case "0": - print ''; - break; - case "1": - print ''; - break; - case "2": - print ''; - break; - case "3": - print ''; - break; - } - } - if (!empty($arrayfields['origin']['checked'])) { - // Origin of movement - print ''; - } - if (!empty($arrayfields['m.value']['checked'])) { - // Qty - print ''; - } - if (!empty($arrayfields['m.price']['checked'])) { - // Price - $usercancreadsupplierprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS') ? $user->hasRight('product', 'product_advance', 'read_supplier_prices') : $user->hasRight('product', 'lire'); - if ($productstatic->isService()) { - $usercancreadsupplierprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS') ? $user->hasRight('service', 'service_advance', 'read_supplier_prices') : $user->hasRight('service', 'lire'); - } - print ''; - } - // Action column - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - print "\n"; - $i++; - } - $db->free($resql); - - print "
'; - print ''; - print ''; - print ''; - if (empty($conf->productbatch->enabled)) { - print ' '; - } - //else print '
'; - $syear = $year ? $year : -1; - print ''; - //print $formother->selectyear($syear,'year',1, 20, 5); - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'maxwidth200'); - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ajax_combobox('search_type_mouvement'); - // TODO: add new function $formentrepot->selectTypeOfMovement(...) like - // print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'maxwidth200'); - print ''; - print '  '; - print ''; - print ''; - print ''; - print '  '; - print ''; - print ''; - print ''; - $searchpicto = $form->showFilterAndCheckAddButtons(0); - print $searchpicto; - print '
'.$objp->mid.''.dol_print_date($db->jdate($objp->datem), 'dayhour').''; - print $productstatic->getNomUrl(1, 'stock', 16); - print "'; - /*$productstatic->id=$objp->rowid; - $productstatic->ref=$objp->produit; - $productstatic->type=$objp->type; - print $productstatic->getNomUrl(1,'',16);*/ - print $productstatic->label; - print "'; - if ($productlot->id > 0) { - print $productlot->getNomUrl(1); - } else { - print $productlot->batch; // the id may not be defined if movement was entered when lot was not saved or if lot was removed after movement. - } - print ''.dol_print_date($objp->eatby, 'day').''.dol_print_date($objp->sellby, 'day').''; - print $warehousestatic->getNomUrl(1); - print "'; - print $userstatic->getNomUrl(-1); - print "' - .$objp->inventorycode - .''.$objp->label.''.$langs->trans('StockIncreaseAfterCorrectTransfer').''.$langs->trans('StockDecreaseAfterCorrectTransfer').''.$langs->trans('StockDecrease').''.$langs->trans('StockIncrease').''.$origin.''; - if ($objp->qt > 0) { - print '+'; - } - print $objp->qty; - print ''; - if ($objp->price != 0 && $usercancreadsupplierprice) { - print price($objp->price); - } - print ''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($obj->rowid, $arrayofselected)) { - $selected = 1; - } - print ''; - } - print '
"; - print '
'; - print ""; - - // Add number of product when there is a filter on period - if (count($arrayofuniqueproduct) == 1 && is_numeric($year)) { - print "
"; - - $productidselected = 0; - foreach ($arrayofuniqueproduct as $key => $val) { - $productidselected = $key; - $productlabelselected = $val; - } - $datebefore = dol_get_first_day($year ? $year : dol_print_date(time(), "%Y"), $month ? $month : 1, true); - $dateafter = dol_get_last_day($year ? $year : dol_print_date(time(), "%Y"), $month ? $month : 12, true); - $balancebefore = $movement->calculateBalanceForProductBefore($productidselected, $datebefore); - $balanceafter = $movement->calculateBalanceForProductBefore($productidselected, $dateafter); - - //print ''; - print $langs->trans("NbOfProductBeforePeriod", $productlabelselected, dol_print_date($datebefore, 'day', 'gmt')); - //print ''; - //print ''; - print ': '.$balancebefore; - print "
\n"; - //print ''; - //print ''; - print $langs->trans("NbOfProductAfterPeriod", $productlabelselected, dol_print_date($dateafter, 'day', 'gmt')); - //print ''; - //print ''; - print ': '.$balanceafter; - print "
\n"; - //print ''; - } -} else { - dol_print_error($db); -} - - - -/* - * Generated documents - */ -//Area for doc and last events of warehouse are stored on the main card of warehouse -$modulepart = 'movement'; - -if ($action != 'create' && $action != 'edit' && $action != 'delete' && $id > 0) { - print '
'; - print '
'; - print ''; // ancre - - // Documents - $objectref = dol_sanitizeFileName($object->ref); - // Add inventorycode & type_mouvement to filename of the pdf - if (!empty($search_inventorycode)) { - $objectref .= "_".$id."_".$search_inventorycode; - } - if ($search_type_mouvement) { - $objectref .= "_".$search_type_mouvement; - } - $relativepath = $comref.'/'.$objectref.'.pdf'; - $filedir = $conf->stock->dir_output.'/movement/'.$objectref; - - $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id."&search_inventorycode=".$search_inventorycode."&search_type_mouvement=$search_type_mouvement"; - $genallowed = $usercanread; - $delallowed = $usercancreate; - - $genallowed = $user->hasRight('stock', 'lire'); - $delallowed = $user->hasRight('stock', 'creer'); - - print $formfile->showdocuments($modulepart, $objectref, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', '', '', $object->default_lang, '', $object); - $somethingshown = $formfile->numoffiles; - - print '
'; - - $MAXEVENT = 10; - - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/product/agenda.php?id='.$object->id); - - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'mouvement', 0, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for product - - print '
'; -} - - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 1680c20293a..6dc3dde32e7 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -471,7 +471,7 @@ if ($action == "transfert_stock" && !$cancel && $usercanupdatestock) { (float) $nbpiece, 1, GETPOST("label", 'alphanohtml'), - $pricesrc, + (float) $pricesrc, GETPOST('inventorycode', 'alphanohtml') ); if ($result1 < 0) { From 0923600aee01fe28c7552d066a07c0caaae591bb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 13:12:17 +0200 Subject: [PATCH 46/73] Fix CI --- htdocs/bom/class/bom.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index f33d3b7a23a..77aae9a98f4 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1444,7 +1444,7 @@ class BOM extends CommonObject } $unit_cost = is_null($tmpproduct->cost_price) ? $tmpproduct->pmp : $tmpproduct->cost_price; - if (is_null($unit_cost)) { + if (empty($unit_cost)) { if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { if ($productFournisseur->fourn_remise_percent != "0") { $line->unit_cost = $productFournisseur->fourn_unitprice_with_discount; From d05a9bbc28c187a47f3de5ffd280b74531999066 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 13:38:17 +0200 Subject: [PATCH 47/73] Debug v22 --- htdocs/product/stock/movement_list.php | 19 ++++++------------- .../product/stock/tpl/stocktransfer.tpl.php | 14 +++++++------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php index 495ce2c4375..8fd8dc250c7 100644 --- a/htdocs/product/stock/movement_list.php +++ b/htdocs/product/stock/movement_list.php @@ -400,8 +400,6 @@ if ($action == "correct_stock" && $permissiontoadd) { if ($product->hasbatch()) { $batch = GETPOST('batch_number', 'alphanohtml'); - //$eatby=GETPOST('eatby'); - //$sellby=GETPOST('sellby'); $eatby = dol_mktime(0, 0, 0, GETPOSTINT('eatbymonth'), GETPOSTINT('eatbyday'), GETPOSTINT('eatbyyear')); $sellby = dol_mktime(0, 0, 0, GETPOSTINT('sellbymonth'), GETPOSTINT('sellbyday'), GETPOSTINT('sellbyyear')); @@ -510,17 +508,16 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { if ($product->hasbatch()) { $pdluo = new Productbatch($db); - $srcwarehouseid = 0; - $eatby = -1; - $sellby = -1; + + $eatby = dol_mktime(0, 0, 0, GETPOSTINT('eatbymonth'), GETPOSTINT('eatbyday'), GETPOSTINT('eatbyyear')); + $sellby = dol_mktime(0, 0, 0, GETPOSTINT('sellbymonth'), GETPOSTINT('sellbyday'), GETPOSTINT('sellbyyear')); + if ($pdluoid > 0) { $result = $pdluo->fetch($pdluoid); if ($result) { $srcwarehouseid = $pdluo->warehouseid; $batch = $pdluo->batch; - $eatby = $pdluo->eatby; - $sellby = $pdluo->sellby; } else { setEventMessages($pdluo->error, $pdluo->errors, 'errors'); $error++; @@ -528,8 +525,6 @@ if ($action == "transfert_stock" && $permissiontoadd && !$cancel) { } else { $srcwarehouseid = $id; $batch = GETPOST('batch_number', 'alphanohtml'); - $eatby = $d_eatby; - $sellby = $d_sellby; } $result1 = -1; @@ -831,10 +826,6 @@ if ($id > 0 || $ref) { } } - -// Output page -// -------------------------------------------------------------------- - $i = 0; $help_url = 'EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; if ($msid) { @@ -1001,6 +992,8 @@ if ($action == "correction") { // Transfer of units if ($action == "transfert") { + $d_eatby = GETPOSTDATE('eatby'); // used by the tpl + $d_sellby = GETPOSTDATE('sellby'); // used by the tpl include DOL_DOCUMENT_ROOT.'/product/stock/tpl/stocktransfer.tpl.php'; print '
'; } diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php index 764795219f6..601e1be3c6f 100644 --- a/htdocs/product/stock/tpl/stocktransfer.tpl.php +++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php @@ -15,20 +15,20 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * - * $object must be defined - * $backtopage */ /** * @var Conf $conf * @var DoliDB $db * @var Form $form - * @var Product|MouvementStock $object * @var FormProduct $formproduct * @var Translate $langs + * @var Product|Entrepot|MouvementStock $object * - * @var string $backtopage + * @var string $backtopage + * @var ?int $id + * @var int $d_eatby + * @var int $d_sellby */ // Protection to avoid direct call of template @@ -38,7 +38,7 @@ if (empty($conf) || !is_object($conf)) { } ' -@phan-var-force Entrepot|MouvementStock $object +@phan-var-force Entrepot|Product|MouvementStock $object @phan-var-force FormProduct $formproduct @phan-var-force string $backtopage '; @@ -86,7 +86,7 @@ if ($pdluoid) { } print ''; -// Source warehouse or product +// Source product or stock movement print ''; if ($object->element == 'product') { /** @var Product $object */ From 7d02de2abf1ab3a975abb58ef02a8911d404faf9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 16:04:56 +0200 Subject: [PATCH 48/73] Fix CI --- htdocs/bom/class/bom.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 77aae9a98f4..5ef0a9acf22 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1443,7 +1443,7 @@ class BOM extends CommonObject return -1; } - $unit_cost = is_null($tmpproduct->cost_price) ? $tmpproduct->pmp : $tmpproduct->cost_price; + $unit_cost = (float) (is_null($tmpproduct->cost_price) ? $tmpproduct->pmp : $tmpproduct->cost_price); if (empty($unit_cost)) { if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { if ($productFournisseur->fourn_remise_percent != "0") { From bf470c4b5ded4ea4fb992d311ae46a91df855fcb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 18:40:14 +0200 Subject: [PATCH 49/73] Fix CI --- htdocs/bom/class/bom.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 5ef0a9acf22..0ba39eef43b 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1444,7 +1444,7 @@ class BOM extends CommonObject } $unit_cost = (float) (is_null($tmpproduct->cost_price) ? $tmpproduct->pmp : $tmpproduct->cost_price); - if (empty($unit_cost)) { + if (empty($unit_cost)) { // @phpstan-ignore-line phpstan thinks this is always false. No,if unit_cost is 0, it is not. if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { if ($productFournisseur->fourn_remise_percent != "0") { $line->unit_cost = $productFournisseur->fourn_unitprice_with_discount; From 195677641532d5d15843f514f802cc1d851827e6 Mon Sep 17 00:00:00 2001 From: F-Node-Karlsruhe <41575897+F-Node-Karlsruhe@users.noreply.github.com> Date: Sat, 5 Jul 2025 19:11:47 +0200 Subject: [PATCH 50/73] Allow email claim in oidc (#34669) * allow email claim in oidc Signed-off-by: F-Node-Karlsruhe * switch to allow mail address in login Signed-off-by: F-Node-Karlsruhe * revert back to first draft Signed-off-by: F-Node-Karlsruhe --------- Signed-off-by: F-Node-Karlsruhe Co-authored-by: Laurent Destailleur --- htdocs/core/login/functions_openid_connect.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/core/login/functions_openid_connect.php b/htdocs/core/login/functions_openid_connect.php index 4dc4bf54290..bf75d373fbd 100644 --- a/htdocs/core/login/functions_openid_connect.php +++ b/htdocs/core/login/functions_openid_connect.php @@ -159,7 +159,12 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit // Success: retrieve claim to return to Dolibarr as login $sql = 'SELECT login, entity, datestartvalidity, dateendvalidity'; $sql .= ' FROM '.MAIN_DB_PREFIX.'user'; - $sql .= " WHERE login = '".$db->escape($userinfo_content->$login_claim)."'"; + if ($login_claim === 'email') { + // If login claim is email, check both login and email fields + $sql .= " WHERE (login = '".$db->escape($userinfo_content->$login_claim)."' OR email = '".$db->escape($userinfo_content->$login_claim)."')"; + } else { + $sql .= " WHERE login = '".$db->escape($userinfo_content->$login_claim)."'"; + } $sql .= ' AND entity IN (0,'.(array_key_exists('dol_entity', $_SESSION) ? ((int) $_SESSION["dol_entity"]) : 1).')'; dol_syslog("functions_openid::check_user_password_openid", LOG_DEBUG); From f047007c19138259149070d8a422961338160556 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 22:48:36 +0200 Subject: [PATCH 51/73] Clean code --- htdocs/commande/customer.php | 15 +++++---------- htdocs/core/lib/functions.lib.php | 13 ++++--------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/htdocs/commande/customer.php b/htdocs/commande/customer.php index 29a38dbc502..3179ec952ce 100644 --- a/htdocs/commande/customer.php +++ b/htdocs/commande/customer.php @@ -73,19 +73,14 @@ if (!$sortfield) { $sortfield = "nom"; } -$addu = GETPOST("addu"); -$maxlen = GETPOSTISSET("maxlensocname") ? GETPOSTINT("maxlensocname") : 40; + /* * View */ llxHeader('', '', '', '', 0, 0, '', '', '', 'mod-commande page-customer'); -$thirdpartystatic = new Societe($db); - -/* - * Mode List - */ +// Mode List $sql = "SELECT s.rowid, s.nom as name, s.client, s.town, s.datec,"; $sql .= " st.libelle as stcomm, s.prefix_comm, s.code_client, s.code_compta as code_compta_client"; @@ -156,7 +151,7 @@ if ($resql) { print_liste_field_titre("Town", $_SERVER["PHP_SELF"], "s.town", "", "", 'valign="center"', $sortfield, $sortorder); print_liste_field_titre("CustomerCode", $_SERVER["PHP_SELF"], "s.code_client", "", "", 'align="left"', $sortfield, $sortorder); print_liste_field_titre("AccountancyCode", $_SERVER["PHP_SELF"], "s.code_compta", "", "", 'align="left"', $sortfield, $sortorder); - print_liste_field_titre("DateCreation", $_SERVER["PHP_SELF"], "datec", $addu, "", 'class="right"', $sortfield, $sortorder); + print_liste_field_titre("DateCreation", $_SERVER["PHP_SELF"], "datec", "", "", 'class="right"', $sortfield, $sortorder); print "\n"; // Fields title search @@ -185,7 +180,7 @@ if ($resql) { $obj = $db->fetch_object($resql); print ''; - print ''; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 3b0bbbc926d..c7a06e59e68 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6514,7 +6514,7 @@ function print_liste_field_titre($name, $file = "", $field = "", $begin = "", $m * @param int<0,2> $thead 0=To use with standard table format, 1=To use inside , 2=To use with
* @param string $file Url used when we click on sort picto * @param string $field Field to use for new sorting. Empty if this field is not sortable. Example "t.abc" or "t.abc,t.def" - * @param string $begin ("" by default) + * @param string $begin ("" by default) * @param string $moreparam Add more parameters on sort url links ("" by default) * @param string $moreattrib Add more attributes on th ("" by default). To add more css class, use param $prefix. * @param ?string $sortfield Current field used to sort (Ex: 'd.datep,d.id') @@ -6588,8 +6588,8 @@ function getTitleFieldOfList($name, $thead = 0, $file = "", $field = "", $begin } } $sortordertouseinlink = preg_replace('/,$/', '', $sortordertouseinlink); - $out .= 'global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : ''); + $out .= ''.img_down("A-Z",0).''; - //$out.= ''.img_up("Z-A",0).''; + // Nothing } else { if (preg_match('/^DESC/', $sortorder)) { - //$out.= ''.img_down("A-Z",0).''; - //$out.= ''.img_up("Z-A",1).''; $sortimg .= ''.img_up("Z-A", 0, 'paddingright').''; } if (preg_match('/^ASC/', $sortorder)) { - //$out.= ''.img_down("A-Z",1).''; - //$out.= ''.img_up("Z-A",0).''; $sortimg .= ''.img_down("A-Z", 0, 'paddingright').''; } } From ebf4548616d4ebed24c63771088be2196bb08b57 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 22:52:27 +0200 Subject: [PATCH 52/73] Clean code --- htdocs/commande/customer.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/htdocs/commande/customer.php b/htdocs/commande/customer.php index 3179ec952ce..b1d2eca7706 100644 --- a/htdocs/commande/customer.php +++ b/htdocs/commande/customer.php @@ -96,9 +96,6 @@ if (GETPOST("search_compta")) { if (GETPOST("search_code_client")) { $sql .= natural_search("s.code_client", GETPOST("search_code_client")); } -/*if (dol_strlen($begin)) { // Useless already done line 97 - $sql .= " AND s.nom LIKE '".$db->escape($begin)."'"; -}*/ // If the internal user must only see his customers, force searching by him $search_sale = 0; if (!$user->hasRight('societe', 'client', 'voir')) { From dda0849a466afa482a63a78ff63e40e576432872 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 5 Jul 2025 22:58:39 +0200 Subject: [PATCH 53/73] Clean code --- htdocs/contact/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 3d21addc6d8..22643e528b3 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -845,7 +845,7 @@ if ($limit > 0 && $limit != $conf->liste_limit) { if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); } -$param .= '&begin='.urlencode((string) ($begin)).'&userid='.urlencode((string) ($userid)).'&contactname='.urlencode((string) ($search_all)); +$param .= '&userid='.urlencode((string) $userid).'&contactname='.urlencode((string) $search_all); $param .= '&type='.urlencode($type).'&view='.urlencode($view); if (!empty($search_sale) && $search_sale != '-1') { $param .= '&search_sale='.urlencode($search_sale); From 38203fd6942c22790788e76872972769c1f125e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 6 Jul 2025 12:45:11 +0200 Subject: [PATCH 54/73] add substitutions for year of previous or next month (#34691) * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * add substitutions for year of previous or next month * fix --------- Co-authored-by: Laurent Destailleur --- htdocs/adherents/class/adherent.class.php | 33 ++++++++++++----------- htdocs/core/lib/functions.lib.php | 22 +++++++++++++++ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 2f3cc68ab96..d1c95cf6199 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -70,12 +70,12 @@ class Adherent extends CommonObject public $mesgs; /** - * @var string login of member + * @var ?string login of member */ public $login; /** - * @var string Clear password in memory + * @var ?string Clear password in memory */ public $pass; @@ -186,7 +186,7 @@ class Adherent extends CommonObject public $default_lang; /** - * @var string photo of member + * @var ?string photo of member */ public $photo; @@ -225,7 +225,7 @@ class Adherent extends CommonObject public $typeid; /** - * @var string label type member + * @var ?string label type member */ public $type; @@ -536,6 +536,10 @@ class Adherent extends CommonObject global $langs; $birthday = dol_print_date($this->birth, 'day'); + $photo = isset($this->photo) ? $this->photo : ''; + $login = isset($this->login) ? $this->login : ''; + $type = isset($this->type) ? $this->type : ''; + $pass = isset($this->pass) ? $this->pass : ''; $msgishtml = 0; if (dol_textishtml($text, 1)) { @@ -560,11 +564,11 @@ class Adherent extends CommonObject $infos .= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n"; $infos .= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n"; if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) { - $infos .= $langs->transnoentities("Login").": ".$this->login."\n"; - $infos .= $langs->transnoentities("Password").": ".$this->pass."\n"; + $infos .= $langs->transnoentities("Login").": ".$login."\n"; + $infos .= $langs->transnoentities("Password").": ".$pass."\n"; } $infos .= $langs->transnoentities("Birthday").": ".$birthday."\n"; - $infos .= $langs->transnoentities("Photo").": ".$this->photo."\n"; + $infos .= $langs->transnoentities("Photo").": ".$photo."\n"; $infos .= $langs->transnoentities("Public").": ".yn($this->public); // Substitutions @@ -583,13 +587,13 @@ class Adherent extends CommonObject '__COUNTRY__' => $msgishtml ? dol_htmlentitiesbr($this->country) : ($this->country ? $this->country : ''), '__EMAIL__' => $msgishtml ? dol_htmlentitiesbr((string) $this->email) : ($this->email ? $this->email : ''), '__BIRTH__' => $msgishtml ? dol_htmlentitiesbr($birthday) : ($birthday ? $birthday : ''), - '__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($this->photo) : ($this->photo ? $this->photo : ''), - '__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($this->login) : ($this->login ? $this->login : ''), - '__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($this->pass) : ($this->pass ? $this->pass : ''), + '__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($photo) : $photo, + '__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($login) : $login, + '__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($pass) : $pass, '__PHONE__' => $msgishtml ? dol_htmlentitiesbr($this->phone) : ($this->phone ? $this->phone : ''), '__PHONEPRO__' => $msgishtml ? dol_htmlentitiesbr($this->phone_perso) : ($this->phone_perso ? $this->phone_perso : ''), '__PHONEMOBILE__' => $msgishtml ? dol_htmlentitiesbr($this->phone_mobile) : ($this->phone_mobile ? $this->phone_mobile : ''), - '__TYPE__' => $msgishtml ? dol_htmlentitiesbr($this->type) : ($this->type ? $this->type : '') + '__TYPE__' => $msgishtml ? dol_htmlentitiesbr($type) : $type, ); complete_substitutions_array($substitutionarray, $langs, $this); @@ -956,9 +960,6 @@ class Adherent extends CommonObject $result = $luser->fetch($this->user_id); if ($result >= 0) { - //var_dump($this->user_login);exit; - //var_dump($this->login);exit; - // If option ADHERENT_LOGIN_NOT_REQUIRED is on, there is no login of member, so we do not overwrite user login to keep existing one. if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) { $luser->login = $this->login; @@ -969,7 +970,7 @@ class Adherent extends CommonObject $luser->firstname = $this->firstname; $luser->lastname = $this->lastname; $luser->gender = $this->gender; - $luser->pass = $this->pass; + $luser->pass = isset($this->pass) ? $this->pass : ''; //$luser->socid=$this->fk_soc; // We do not enable this. This may transform a user into an external user. $luser->birth = $this->birth; @@ -2463,7 +2464,7 @@ class Adherent extends CommonObject ($morecss ? ' usertext'.$morecss : '').'">'; } if ($mode == 'login') { - $result .= dol_trunc($this->login, $maxlen); + $result .= dol_trunc(isset($this->login) ? $this->login : '', $maxlen); } elseif ($mode == 'ref') { $result .= $this->ref; } else { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c7a06e59e68..483bfb4fd72 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9423,6 +9423,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, } } else { '@phan-var-force Adherent|Delivery $object'; + /** @var Adherent|Delivery $object */ $substitutionarray['__ID__'] = $object->id; $substitutionarray['__REF__'] = $object->ref; $substitutionarray['__NEWREF__'] = $object->newref; @@ -9463,6 +9464,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, if (is_object($object) && ($object->element == 'adherent' || $object->element == 'member') && $object->id > 0) { '@phan-var-force Adherent $object'; + /** @var Adherent $object */ $birthday = (empty($object->birth) ? '' : dol_print_date($object->birth, 'day')); $substitutionarray['__MEMBER_ID__'] = (isset($object->id) ? $object->id : ''); @@ -9561,12 +9563,14 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, if (is_object($object) && $object->element == 'recruitmentcandidature') { '@phan-var-force RecruitmentCandidature $object'; + /** @var RecruitmentCandidature $object */ $substitutionarray['__CANDIDATE_FULLNAME__'] = $object->getFullName($outputlangs); $substitutionarray['__CANDIDATE_FIRSTNAME__'] = isset($object->firstname) ? $object->firstname : ''; $substitutionarray['__CANDIDATE_LASTNAME__'] = isset($object->lastname) ? $object->lastname : ''; } if (is_object($object) && $object->element == 'conferenceorboothattendee') { '@phan-var-force ConferenceOrBoothAttendee $object'; + /** ConferenceOrBoothAttendee $object */ $substitutionarray['__ATTENDEE_FULLNAME__'] = $object->getFullName($outputlangs); $substitutionarray['__ATTENDEE_FIRSTNAME__'] = isset($object->firstname) ? $object->firstname : ''; $substitutionarray['__ATTENDEE_LASTNAME__'] = isset($object->lastname) ? $object->lastname : ''; @@ -9574,6 +9578,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, if (is_object($object) && $object->element == 'project') { '@phan-var-force Project $object'; + /** @var Project $object */ $substitutionarray['__PROJECT_ID__'] = $object->id; $substitutionarray['__PROJECT_REF__'] = $object->ref; $substitutionarray['__PROJECT_NAME__'] = $object->title; @@ -9607,22 +9612,26 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, if (is_object($object) && $object->element == 'facture') { '@phan-var-force Facture $object'; + /** @var Facture $object */ $substitutionarray['__INVOICE_SITUATION_NUMBER__'] = isset($object->situation_counter) ? $object->situation_counter : ''; } if (is_object($object) && $object->element == 'shipping') { '@phan-var-force Expedition $object'; + /** @var Expedition $object */ $substitutionarray['__SHIPPINGTRACKNUM__'] = $object->tracking_number; $substitutionarray['__SHIPPINGTRACKNUMURL__'] = $object->tracking_url; $substitutionarray['__SHIPPINGMETHOD__'] = $object->shipping_method; } if (is_object($object) && $object->element == 'reception') { '@phan-var-force Reception $object'; + /** @var Reception $object */ $substitutionarray['__RECEPTIONTRACKNUM__'] = $object->tracking_number; $substitutionarray['__RECEPTIONTRACKNUMURL__'] = $object->tracking_url; } if (is_object($object) && $object->element == 'contrat' && $object->id > 0 && is_array($object->lines)) { '@phan-var-force Contrat $object'; + /** @var Contrat $object */ $dateplannedstart = ''; $datenextexpiration = ''; foreach ($object->lines as $line) { @@ -9644,6 +9653,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, // add substitution variables for ticket if (is_object($object) && $object->element == 'ticket') { '@phan-var-force Ticket $object'; + /** @var Ticket $object */ $substitutionarray['__TICKET_TRACKID__'] = $object->track_id; $substitutionarray['__TICKET_SUBJECT__'] = $object->subject; $substitutionarray['__TICKET_TYPE__'] = $object->type_code; @@ -9774,46 +9784,55 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, if (is_object($object) && $object->element == 'propal') { '@phan-var-force Propal $object'; + /** @var Propal $object */ $substitutionarray['__URL_PROPOSAL__'] = DOL_MAIN_URL_ROOT."/comm/propal/card.php?id=".$object->id; require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php'; $substitutionarray['__ONLINE_SIGN_URL__'] = getOnlineSignatureUrl(0, 'proposal', $object->ref, 1, $object); } if (is_object($object) && $object->element == 'commande') { '@phan-var-force Commande $object'; + /** @var Commande $object */ $substitutionarray['__URL_ORDER__'] = DOL_MAIN_URL_ROOT."/commande/card.php?id=".$object->id; } if (is_object($object) && $object->element == 'facture') { '@phan-var-force Facture $object'; + /** @var Facture $object */ $substitutionarray['__URL_INVOICE__'] = DOL_MAIN_URL_ROOT."/compta/facture/card.php?id=".$object->id; } if (is_object($object) && $object->element == 'contrat') { '@phan-var-force Contrat $object'; + /** @var Contrat $object */ $substitutionarray['__URL_CONTRACT__'] = DOL_MAIN_URL_ROOT."/contrat/card.php?id=".$object->id; require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php'; $substitutionarray['__ONLINE_SIGN_URL__'] = getOnlineSignatureUrl(0, 'contract', $object->ref, 1, $object); } if (is_object($object) && $object->element == 'fichinter') { '@phan-var-force Fichinter $object'; + /** @var Fichinter $object */ $substitutionarray['__URL_FICHINTER__'] = DOL_MAIN_URL_ROOT."/fichinter/card.php?id=".$object->id; require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php'; $substitutionarray['__ONLINE_SIGN_FICHINTER_URL__'] = getOnlineSignatureUrl(0, 'fichinter', $object->ref, 1, $object); } if (is_object($object) && $object->element == 'supplier_proposal') { '@phan-var-force SupplierProposal $object'; + /** @var SupplierProposal $object */ $substitutionarray['__URL_SUPPLIER_PROPOSAL__'] = DOL_MAIN_URL_ROOT."/supplier_proposal/card.php?id=".$object->id; } if (is_object($object) && $object->element == 'invoice_supplier') { '@phan-var-force FactureFournisseur $object'; + /** @var FactureFournisseur $object */ $substitutionarray['__URL_SUPPLIER_INVOICE__'] = DOL_MAIN_URL_ROOT."/fourn/facture/card.php?id=".$object->id; } if (is_object($object) && $object->element == 'shipping') { '@phan-var-force Expedition $object'; + /** @var Expedition $object */ $substitutionarray['__URL_SHIPMENT__'] = DOL_MAIN_URL_ROOT."/expedition/card.php?id=".$object->id; } } if (is_object($object) && $object->element == 'action') { '@phan-var-force ActionComm $object'; + /** @var ActionComm $object */ $substitutionarray['__EVENT_LABEL__'] = $object->label; $substitutionarray['__EVENT_TYPE__'] = $outputlangs->trans("Action".$object->type_code); $substitutionarray['__EVENT_DATE__'] = dol_print_date($object->datep, 'day', 'auto', $outputlangs); @@ -9823,6 +9842,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, } if ((empty($exclude) || !in_array('objectamount', $exclude)) && (empty($include) || in_array('objectamount', $include))) { '@phan-var-force Facture|FactureRec $object'; + /** @var Facture|FactureRec|null $object */ include_once DOL_DOCUMENT_ROOT.'/core/lib/functionsnumtoword.lib.php'; $substitutionarray['__DATE_YMD__'] = is_object($object) ? (isset($object->date) ? dol_print_date($object->date, 'day', false, $outputlangs) : null) : ''; @@ -9921,6 +9941,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, '__MONTH_TEXT_SHORT__' => $outputlangs->trans('MonthShort'.sprintf("%02d", $tmp['mon'])), '__MONTH_TEXT_MIN__' => $outputlangs->trans('MonthVeryShort'.sprintf("%02d", $tmp['mon'])), '__YEAR__' => (string) $tmp['year'], + '__YEAR_PREVIOUS_MONTH__' => (string) $tmp3['year'], + '__YEAR_NEXT_MONTH__' => (string) $tmp5['year'], '__PREVIOUS_DAY__' => (string) $tmp2['day'], '__PREVIOUS_MONTH__' => (string) $tmp3['month'], '__PREVIOUS_MONTH_TEXT__' => $outputlangs->trans('Month'.sprintf("%02d", $tmp3['month'])), From a23ad6e91b26576a187ad2357af80665253fb09a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 6 Jul 2025 18:00:46 +0200 Subject: [PATCH 55/73] Fix label of fieldand tooltip --- htdocs/langs/en_US/resource.lang | 3 ++- htdocs/resource/card.php | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/langs/en_US/resource.lang b/htdocs/langs/en_US/resource.lang index 4d97d479f4a..70d838fac03 100644 --- a/htdocs/langs/en_US/resource.lang +++ b/htdocs/langs/en_US/resource.lang @@ -34,5 +34,6 @@ ResourceTypeCode=Resource type code ImportDataset_resource_1=Resources ErrorResourcesAlreadyInUse=Some resources are in use ErrorResourceUseInEvent=%s used in %s event -MaxUsers=Maximum users (places, seats, etc.) +MaxUsers=Maximum number of users +MaxUsersResourceDesc=If the resource can be used by several people at once (car, room, ...), you can enter here the maximum number of users allowed to use the resource at the same time (number of seats, places, ...). MaxUsersLabel=Maximum users diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php index 04fd0678aa3..af36e3dfdea 100644 --- a/htdocs/resource/card.php +++ b/htdocs/resource/card.php @@ -46,9 +46,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $langs->loadLangs(array('resource', 'companies', 'other', 'main')); // Get parameters -$id = GETPOSTINT('id'); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$id = GETPOSTINT('id'); $ref = GETPOST('ref', 'alpha'); $address = GETPOST('address', 'alpha'); $zip = GETPOST('zipcode', 'alpha'); @@ -347,7 +349,7 @@ if ($action == 'create' || $object->fetch($id, $ref) > 0) { print '
'; // Max users - print ''; + print ''; print ''; @@ -357,7 +359,7 @@ if ($action == 'create' || $object->fetch($id, $ref) > 0) { print ''; print ''; + print ''; print ''; // Other attributes From feba6a45791ed5814134b714d5a5ac1a44a3a4ad Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 6 Jul 2025 18:19:20 +0200 Subject: [PATCH 56/73] Close #34623 --- htdocs/resource/card.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php index af36e3dfdea..4a153fe4288 100644 --- a/htdocs/resource/card.php +++ b/htdocs/resource/card.php @@ -60,7 +60,7 @@ $state_id = GETPOSTINT('state_id'); $description = GETPOST('description', 'restricthtml'); $phone = GETPOST('phone', 'alpha'); $email = GETPOST('email', 'alpha'); -$max_users = GETPOSTINT('max_users'); +$max_users = GETPOSTINT('max_users'); // Can be an int or '' $url = GETPOST('url', 'alpha'); $confirm = GETPOST('confirm', 'aZ09'); $fk_code_type_resource = GETPOST('fk_code_type_resource', 'aZ09'); @@ -166,6 +166,8 @@ if (empty($reshook)) { if (!$error) { $res = $object->fetch($id); if ($res > 0) { + $oldref = $object->ref; + $object->ref = $ref; $object->address = $address; $object->zip = $zip; @@ -187,6 +189,14 @@ if (empty($reshook)) { $result = $object->update($user); if ($result > 0) { + if ($oldref != $ref) { + // We renamed the ref so we must change the directory too + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $srcdir = $conf->resource->dir_output.'/'.dol_sanitizeFileName($oldref); + $destdir = $conf->resource->dir_output.'/'.dol_sanitizeFileName($ref); + dol_move_dir($srcdir, $destdir); + } + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); exit; } else { @@ -271,7 +281,7 @@ if ($action == 'create' || $object->fetch($id, $ref) > 0) { // Ref print ''; - print ''; + print ''; // Type print ''; @@ -345,21 +355,21 @@ if ($action == 'create' || $object->fetch($id, $ref) > 0) { print ''; print ''; + print ''; print ''; // Max users print ''; print ''; + print ''; print ''; // URL print ''; print ''; + print ''; print ''; // Other attributes @@ -422,7 +432,7 @@ if ($action == 'create' || $object->fetch($id, $ref) > 0) { print ''; print ''; print ''; print ''; From 63787265145ceae4820b68351d8f56d026d84393 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 6 Jul 2025 18:28:23 +0200 Subject: [PATCH 57/73] Fix warning --- htdocs/resource/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php index 4a153fe4288..949ecc18a24 100644 --- a/htdocs/resource/card.php +++ b/htdocs/resource/card.php @@ -60,7 +60,7 @@ $state_id = GETPOSTINT('state_id'); $description = GETPOST('description', 'restricthtml'); $phone = GETPOST('phone', 'alpha'); $email = GETPOST('email', 'alpha'); -$max_users = GETPOSTINT('max_users'); // Can be an int or '' +$max_users = GETPOSTINT('max_users'); $url = GETPOST('url', 'alpha'); $confirm = GETPOST('confirm', 'aZ09'); $fk_code_type_resource = GETPOST('fk_code_type_resource', 'aZ09'); @@ -402,7 +402,7 @@ if ($action == 'create' || $object->fetch($id, $ref) > 0) { print $formconfirm; - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'ref', $linkback, 1, 'ref'); From 1e7d7f67fc191f586ce0db19fb133add908a32e7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 6 Jul 2025 22:50:27 +0200 Subject: [PATCH 58/73] Debug v22 --- htdocs/contrat/list.php | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index c7a26f17e28..2e19777d092 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -149,10 +149,7 @@ $hookmanager->initHooks(array('contractlist')); $result = restrictedArea($user, 'contrat', $id); -$diroutputmassaction = $conf->contrat->dir_output.'/temp/massgeneration/'.$user->id; - -$staticcontrat = new Contrat($db); -$staticcontratligne = new ContratLigne($db); +$diroutputmassaction = $conf->contract->dir_output.'/temp/massgeneration/'.$user->id; if ($search_status == '') { $search_status = 1; @@ -161,6 +158,7 @@ if ($search_status == '') { // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context $object = new Contrat($db); $extrafields = new ExtraFields($db); +$staticcontratligne = new ContratLigne($db); // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); @@ -252,7 +250,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_town = ''; $search_zip = ""; $search_state = ""; - $search_type = ''; + $search_type_thirdparty = ''; $search_country = ''; $search_contract = ""; $search_ref_customer = ""; @@ -288,7 +286,6 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_status = ""; $search_signed_status = ''; $toselect = array(); - $search_type_thirdparty = ''; $searchCategoryCustomerList = array(); $search_array_options = array(); } @@ -296,7 +293,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' if (empty($reshook)) { $objectclass = 'Contrat'; $objectlabel = 'Contracts'; - $uploaddir = $conf->contrat->dir_output; + $uploaddir = $conf->contract->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -343,11 +340,11 @@ $sql = preg_replace('/,\s*$/', '', $sql); $sqlfields = $sql; // $sql fields to remove for count total -$sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; +$sql .= " FROM ".MAIN_DB_PREFIX."contrat as c"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON (c.fk_soc = s.rowid)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)"; -$sql .= ", ".MAIN_DB_PREFIX."contrat as c"; if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (c.rowid = ef.fk_object)"; } @@ -356,8 +353,11 @@ if ($search_user > 0) { $sql .= ", ".MAIN_DB_PREFIX."element_contact as ec"; $sql .= ", ".MAIN_DB_PREFIX."c_type_contact as tc"; } -$sql .= " WHERE c.fk_soc = s.rowid "; -$sql .= ' AND c.entity IN ('.getEntity('contract').')'; +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +$sql .= " WHERE c.entity IN (".getEntity('contract').")"; if ($search_type_thirdparty != '' && $search_type_thirdparty > 0) { $sql .= " AND s.fk_typent IN (".$db->sanitize($db->escape($search_type_thirdparty)).')'; } @@ -394,9 +394,6 @@ if ($search_town) { if ($search_country && $search_country != '-1') { $sql .= " AND s.fk_pays IN (".$db->sanitize($search_country).')'; } -/*if ($search_sale > 0) { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $search_sale); -}*/ if ($search_all) { $sql .= natural_search(array_keys($fieldstosearchall), $search_all); } From 9e9893ac724b996da2de41788f4303c2fda990bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charl=C3=A8ne=20Benke?= <1179011+defrance@users.noreply.github.com> Date: Mon, 7 Jul 2025 18:12:47 +0200 Subject: [PATCH 59/73] fix typo documentation error on api stockmovement (#34703) --- htdocs/product/stock/class/api_stockmovements.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/class/api_stockmovements.class.php b/htdocs/product/stock/class/api_stockmovements.class.php index 7d611017be6..c9db69f0095 100644 --- a/htdocs/product/stock/class/api_stockmovements.class.php +++ b/htdocs/product/stock/class/api_stockmovements.class.php @@ -89,7 +89,7 @@ class StockMovements extends DolibarrApi * @param string $sortorder Sort order * @param int $limit Limit for list * @param int $page Page number - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.product_id:=:1) and (t.date_creation:<:'20160101')" + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.fk_product:=:1) 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 warehouse objects * @phan-return MouvementStock[] From dac95c340b6be43be73b459a81a1ef0d0e062758 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 19:13:28 +0300 Subject: [PATCH 60/73] PHPStan > Update baseline (#34701) Co-authored-by: Dolibot --- dev/build/phpstan/phpstan-baseline.neon | 158 +----------------------- 1 file changed, 1 insertion(+), 157 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 9d8572699e5..7bc6689a9f9 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -3816,24 +3816,6 @@ parameters: count: 1 path: ../../../htdocs/commande/contact.php - - - message: '#^Variable \$addu might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/commande/customer.php - - - - message: '#^Variable \$begin might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../../htdocs/commande/customer.php - - - - message: '#^Variable \$maxlen might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/commande/customer.php - - message: '#^Variable \$socid might not be defined\.$#' identifier: variable.undefined @@ -9486,36 +9468,6 @@ parameters: count: 1 path: ../../../htdocs/core/lib/functions.lib.php - - - message: '#^Property CommonObject\:\:\$firstname \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 3 - path: ../../../htdocs/core/lib/functions.lib.php - - - - message: '#^Property CommonObject\:\:\$id \(int\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/core/lib/functions.lib.php - - - - message: '#^Property CommonObject\:\:\$lastname \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 3 - path: ../../../htdocs/core/lib/functions.lib.php - - - - message: '#^Property CommonObject\:\:\$multicurrency_code \(array\\|string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/core/lib/functions.lib.php - - - - message: '#^Property CommonObject\:\:\$multicurrency_total_ttc \(float\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 3 - path: ../../../htdocs/core/lib/functions.lib.php - - message: '#^Result of && is always true\.$#' identifier: booleanAnd.alwaysTrue @@ -10644,12 +10596,6 @@ parameters: count: 2 path: ../../../htdocs/core/modules/member/doc/pdf_standard_member.class.php - - - message: '#^Property Adherent\:\:\$photo \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/core/modules/member/doc/pdf_standard_member.class.php - - message: '#^Property DolibarrModules\:\:\$import_convertvalue_array \(array\\>\) does not accept non\-empty\-array\\>\.$#' identifier: assign.propertyType @@ -13401,7 +13347,7 @@ parameters: - message: '#^Result of && is always false\.$#' identifier: booleanAnd.alwaysFalse - count: 3 + count: 2 path: ../../../htdocs/expensereport/card.php - @@ -18588,78 +18534,6 @@ parameters: count: 1 path: ../../../htdocs/product/stock/massstockmove.php - - - message: '#^Negated boolean expression is always false\.$#' - identifier: booleanNot.alwaysFalse - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Property Product\:\:\$pmp \(float\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$backtopage might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$comref might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#' - identifier: empty.variable - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$d_eatby might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$d_sellby might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$massaction might not be defined\.$#' - identifier: variable.undefined - count: 4 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$obj might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$sall might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$toselect might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - - - message: '#^Variable \$totalarray might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_card.php - - message: '#^Loose comparison using \=\= between 1 and 2 will always evaluate to false\.$#' identifier: equal.alwaysFalse @@ -18678,12 +18552,6 @@ parameters: count: 2 path: ../../../htdocs/product/stock/movement_list.php - - - message: '#^Property Product\:\:\$pmp \(float\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/product/stock/movement_list.php - - message: '#^Result of && is always false\.$#' identifier: booleanAnd.alwaysFalse @@ -18696,18 +18564,6 @@ parameters: count: 1 path: ../../../htdocs/product/stock/movement_list.php - - - message: '#^Variable \$d_eatby might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_list.php - - - - message: '#^Variable \$d_sellby might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../../htdocs/product/stock/movement_list.php - - message: '#^Variable \$diroutputmassaction in empty\(\) always exists and is not falsy\.$#' identifier: empty.variable @@ -18750,12 +18606,6 @@ parameters: count: 1 path: ../../../htdocs/product/stock/product.php - - - message: '#^Property Product\:\:\$pmp \(float\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/product/stock/product.php - - message: '#^Variable \$sortfield might not be defined\.$#' identifier: variable.undefined @@ -19986,12 +19836,6 @@ parameters: count: 1 path: ../../../htdocs/public/members/new.php - - - message: '#^Property Adherent\:\:\$photo \(string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../../htdocs/public/members/public_card.php - - message: '#^Call to function is_numeric\(\) with int will always evaluate to true\.$#' identifier: function.alreadyNarrowedType From 8c0f2a089b5795c13f8fbdba59405edea5b8da37 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Jul 2025 22:54:59 +0200 Subject: [PATCH 61/73] Debug v22 --- htdocs/public/payment/paymentok.php | 104 ++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 20 deletions(-) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 81339fb370c..bd1e9b5d480 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -290,7 +290,7 @@ if (empty($doactionsthenredirect)) { // Add steps to validate payment is complete when we enter this page - +$service = $paymentmethod; // to have a default value. We may change it later for 'StripeLive' or 'StripeTest'... // For Paypal: validate the payment (Paypal need another step after the callback return to validate the payment). if (isModEnabled('paypal') && $paymentmethod === 'paypal') { // We call this page only if payment is ok on payment system @@ -371,23 +371,87 @@ if (isModEnabled('paypal') && $paymentmethod === 'paypal') { // We call this pag } // For Paybox -if (isModEnabled('paybox')) { - if ($paymentmethod === 'paybox') { - // TODO Add a check to validate that payment is ok. - $ispaymentok = true; // We call this page only if payment is ok on payment system - } +if (isModEnabled('paybox') && $paymentmethod === 'paybox') { + // TODO Add a check to validate that payment is ok. + $ispaymentok = true; // We will do the rest of code } // For Stripe -if (isModEnabled('stripe')) { - if ($paymentmethod === 'stripe') { - // Check we are coming from the newpaymentpage - if (GETPOST('paymentoksessionkey') == $_SESSION['paymentoksessionkey']) { - // We can also request Stripe with payment_intent and payment_intent_client_secret the sameway we do in newpayment after comment "// Get here amount and currency used for payment". - $ispaymentok = true; // We call this page only if payment is ok on payment system - } else { - $ispaymentok = false; // We call this page only if payment is ok on payment system +if (isModEnabled('stripe') && $paymentmethod === 'stripe') { + $service = 'StripeTest'; + $servicestatus = 0; + if (getDolGlobalString('STRIPE_LIVE') && !GETPOSTINT('forcesandbox')) { + $service = 'StripeLive'; + $servicestatus = 1; + } + + // Check we are coming from the newpaymentpage + if (GETPOST('paymentoksessioncode') !== $_SESSION['paymentoksessioncode']) { + $error++; + $errmsg = 'Attempted direct access to the paymentok page without a valid session.'; + dol_syslog($errmsg, LOG_ERR, 0, '_payment'); + } + + // Check on payment platform that the payment has been really validated + if (!$error && $TRANSACTIONID) { + // Stripe payment verification via Stripe API + try { + include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + + // Use the correct Stripe API key + global $stripearrayofkeysbyenv; + \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']); + + try { + if (empty($stripeacc)) { + $paymentIntent = \Stripe\PaymentIntent::retrieve($TRANSACTIONID); + } else { + $paymentIntent = \Stripe\PaymentIntent::retrieve($TRANSACTIONID, array("stripe_account" => $stripeacc)); + } + + // Check amount and currency + $expectedAmount = (int) round($FinalPaymentAmt * 100); // Stripe uses cents + $expectedCurrency = strtolower($currencyCodeType); + + if ((int) $paymentIntent->amount !== $expectedAmount || strtolower($paymentIntent->currency) !== $expectedCurrency) { + $error++; + $errmsg = 'Stripe payment information mismatch: expected amount ' . $expectedAmount . ' and currency ' . $expectedCurrency . ', got amount ' . $paymentIntent->amount . ' and currency ' . $paymentIntent->currency; + dol_syslog($errmsg, LOG_ERR, 0, '_payment'); + } + if ($paymentIntent->status !== 'succeeded') { + $error++; + $errmsg = 'Stripe payment not succeeded. Status: ' . $paymentIntent->status; + dol_syslog($errmsg, LOG_ERR, 0, '_payment'); + } + } catch (\Stripe\Exception\ApiErrorException $e) { + $error++; + $errormessage = "Stripe API error: ".$e->getMessage(); + dol_syslog($errormessage, LOG_ERR, 0, '_payment'); + setEventMessages($e->getMessage(), null, 'errors'); + } catch (Exception $e) { + $error++; + $errormessage = "CantRetrievePaymentIntent: ".$e->getMessage(); + dol_syslog($errormessage, LOG_ERR, 0, '_payment'); + setEventMessages($e->getMessage(), null, 'errors'); + } + } catch (Exception $e) { + $error++; + $errmsg = 'Stripe API error: ' . $e->getMessage(); + dol_syslog($errmsg, LOG_ERR, 0, '_payment'); } + } else { + $error++; + $errmsg = 'Stripe payment verification failed: TRANSACTIONID is not set or session key does not match.'; + dol_syslog($errmsg, LOG_ERR, 0, '_payment'); + setEventMessages($errmsg, null, 'errors'); + } + + if (!$error) { + $ispaymentok = true; // We will do the rest of code + } else { + $ispaymentok = false; // We won't do the rest of code } } @@ -716,7 +780,7 @@ if ($ispaymentok) { } if (!$error) { - // If payment using Strip, save the Stripe payment info into societe_account + // If payment using Stripe, save the Stripe payment info into societe_account if ($paymentmethod == 'stripe' && $autocreatethirdparty && $option == 'bankviainvoice') { $thirdparty_id = ($object->socid ? $object->socid : $object->fk_soc); @@ -1117,7 +1181,7 @@ if ($ispaymentok) { $paiement->paiementid = $paymentTypeId; $paiement->num_payment = ''; $paiement->note_public = 'Online payment ' . dol_print_date($now, 'standard') . ' from ' . $ipaddress; - $paiement->ext_payment_id = $TRANSACTIONID; // pi_... for Stripe, ... + $paiement->ext_payment_id = $TRANSACTIONID; // 'pi_...' for Stripe, ... TODO Use 'pi_...:cus_...@pk_...' $paiement->ext_payment_site = $service; // 'StripeLive' or 'Stripe', or ... if (!$error) { @@ -1251,8 +1315,8 @@ if ($ispaymentok) { $paiement->paymenttype = $paymentTypeId; $paiement->num_payment = ''; $paiement->note_public = 'Online payment '.dol_print_date($now, 'standard').' from '.$ipaddress; - $paiement->ext_payment_id = $TRANSACTIONID; - $paiement->ext_payment_site = $service; + $paiement->ext_payment_id = $TRANSACTIONID; // 'pi_...' for Stripe, ... TODO Use 'pi_...:cus_...@pk_...' + $paiement->ext_payment_site = $service; // 'StripeLive' or 'Stripe', or ... if (!$error) { $paiement_id = $paiement->create($user, 1); @@ -1386,8 +1450,8 @@ if ($ispaymentok) { $paiement->paiementid = $paymentTypeId; $paiement->num_payment = ''; $paiement->note_public = 'Online payment '.dol_print_date($now, 'standard').' from '.$ipaddress.' for event registration'; - $paiement->ext_payment_id = $TRANSACTIONID; - $paiement->ext_payment_site = $service; + $paiement->ext_payment_id = $TRANSACTIONID; // 'pi_...' for Stripe, ... TODO Use 'pi_...:cus_...@pk_...' + $paiement->ext_payment_site = $service; // 'StripeLive' or 'Stripe', or ... if (!$error) { $paiement_id = $paiement->create($user, 1); // This include closing invoices and regenerating documents From 8910f0a174a3c3fdd4c1cd70a6956c22bec5db50 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Jul 2025 22:55:14 +0200 Subject: [PATCH 62/73] Doc --- htdocs/adherents/class/adherent.class.php | 2 +- htdocs/compta/paiement/class/paiement.class.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index d1c95cf6199..d5ed7459a75 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1777,7 +1777,7 @@ class Adherent extends CommonObject * @param string $emetteur_banque Name of bank of cheque * @param int $autocreatethirdparty Auto create new thirdparty if member not yet linked to a thirdparty and we request an option that generate invoice. * @param string $ext_payment_id External id of payment (for example Stripe charge id) - * @param string $ext_payment_site Name of external paymentmode (for example 'stripe') + * @param string $ext_payment_site Name of external paymentmode (for example 'StripeLive', 'StripeTest', 'paypal', ...) * @return int Return integer <0 if KO, >0 if OK */ public function subscriptionComplementaryActions($subscriptionid, $option, $accountid, $datesubscription, $paymentdate, $operation, $label, $amount, $num_chq, $emetteur_nom = '', $emetteur_banque = '', $autocreatethirdparty = 0, $ext_payment_id = '', $ext_payment_site = '') diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 1132ef25da1..ad461f0e919 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -170,11 +170,6 @@ class Paiement extends CommonObject */ public $num_payment; - /** - * @var string Id of external payment mode - */ - public $ext_payment_id; - /** * @var int Id of prelevement */ @@ -186,7 +181,12 @@ class Paiement extends CommonObject public $num_prelevement; /** - * @var string Name of external payment mode + * @var string Id of external payment mode (With Stripe: 'pi_xxx:cus_ccc@pk_ppp', ...) + */ + public $ext_payment_id; + + /** + * @var string Name of external payment mode ('StripeLive', 'StripeTest', 'stripe' on old version, 'paypal', ...) */ public $ext_payment_site; From 163aafa552c847d28f5a14e5ee28f09b5a5f9f3a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Jul 2025 23:12:17 +0200 Subject: [PATCH 63/73] Fix doxygen --- htdocs/product/stock/class/api_stockmovements.class.php | 6 ++---- htdocs/product/stock/class/api_warehouses.class.php | 7 +------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/htdocs/product/stock/class/api_stockmovements.class.php b/htdocs/product/stock/class/api_stockmovements.class.php index c9db69f0095..cb40f8d6241 100644 --- a/htdocs/product/stock/class/api_stockmovements.class.php +++ b/htdocs/product/stock/class/api_stockmovements.class.php @@ -48,7 +48,7 @@ class StockMovements extends DolibarrApi */ public function __construct() { - global $db, $conf; + global $db; $this->db = $db; $this->stockmovement = new MouvementStock($this->db); } @@ -99,8 +99,6 @@ class StockMovements extends DolibarrApi */ public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '', $properties = '') { - global $conf; - $obj_ret = array(); if (!DolibarrApiAccess::$user->hasRight('stock', 'lire')) { @@ -172,8 +170,8 @@ class StockMovements extends DolibarrApi * @param string $dluo Sell-by date. {@from body} {@type date} * @param string $origin_type Origin type (Element of source object, like 'project', 'inventory', ...) * @param int $origin_id Origin id (Id of source object) - * * @return int ID of stock movement + * * @throws RestException */ public function post($product_id, $warehouse_id, $qty, $type = 2, $lot = '', $movementcode = '', $movementlabel = '', $price = '', $datem = '', $dlc = '', $dluo = '', $origin_type = '', $origin_id = 0) diff --git a/htdocs/product/stock/class/api_warehouses.class.php b/htdocs/product/stock/class/api_warehouses.class.php index 6c7c8011298..1cd4f21f0bd 100644 --- a/htdocs/product/stock/class/api_warehouses.class.php +++ b/htdocs/product/stock/class/api_warehouses.class.php @@ -46,7 +46,7 @@ class Warehouses extends DolibarrApi */ public function __construct() { - global $db, $conf; + global $db; $this->db = $db; $this->warehouse = new Entrepot($this->db); } @@ -99,8 +99,6 @@ class Warehouses extends DolibarrApi */ public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $category = 0, $sqlfilters = '', $properties = '') { - global $db, $conf; - $obj_ret = array(); if (!DolibarrApiAccess::$user->hasRight('stock', 'lire')) { @@ -288,9 +286,6 @@ class Warehouses extends DolibarrApi // phpcs:enable $object = parent::_cleanObjectDatas($object); - // Remove the subscriptions because they are handled as a subresource. - //unset($object->subscriptions); - return $object; } From 34f02f0061b2dfebf08323a6124079180419b0d1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Jul 2025 23:27:39 +0200 Subject: [PATCH 64/73] Doc --- htdocs/product/class/api_products.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 79034aaf5b3..0ea4976941a 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -196,8 +196,6 @@ class Products extends DolibarrApi */ public function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $ids_only = false, $variant_filter = 0, $pagination_data = false, $includestockdata = 0, $properties = '') { - global $db, $conf; - if (!DolibarrApiAccess::$user->hasRight('produit', 'lire')) { throw new RestException(403); } From 421802cc87154fa956526ea073b4e78ea9446d19 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Jul 2025 23:40:20 +0200 Subject: [PATCH 65/73] Doc --- htdocs/public/stripe/ipn.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 110799270b0..fb8799fc9b4 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -360,14 +360,14 @@ if ($event->type == 'payout.created' && getDolGlobalString('STRIPE_AUTO_RECORD_P global $stripearrayofkeysbyenv; $error = 0; $object = $event->data->object; - $TRANSACTIONID = $object->id; // Example pi_123456789... + $TRANSACTIONID = $object->id; // Example 'pi_123456789...' $ipaddress = $object->metadata->ipaddress; $now = dol_now(); $currencyCodeType = strtoupper($object->currency); $paymentmethodstripeid = $object->payment_method; $customer_id = $object->customer; $invoice_id = ""; - $paymentTypeCode = ""; // payment type according to Stripe + $paymentTypeCode = ""; // payment type according to Stripe $paymentTypeCodeInDolibarr = ""; // payment type according to Dolibarr $payment_amount = 0; $payment_amountInDolibarr = 0; @@ -449,7 +449,9 @@ if ($event->type == 'payout.created' && getDolGlobalString('STRIPE_AUTO_RECORD_P } $payment_amount = $payment_amountInDolibarr; - // TODO Check payment_amount in Stripe (received) is same than the one in Dolibarr + // TODO Add this checks ? May not be required because the message is already decoded with $event = \Stripe\Webhook::constructEvent($payload, $sig_header, $endpoint_secret); + // - Check payment_amount in Stripe (received) is same than the one in Dolibarr + // - Check that payment intent is succeed (to avoid forged json webhook sent by malicious users) $postactionmessages = array(); From 226a50e1f6a80c546f7f503038a6b7894086f960 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Jul 2025 23:53:51 +0200 Subject: [PATCH 66/73] More logs --- htdocs/public/stripe/ipn.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index fb8799fc9b4..f3350d36a7a 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -133,10 +133,16 @@ try { $event = \Stripe\Webhook::constructEvent($payload, $sig_header, $endpoint_secret); } catch (UnexpectedValueException $e) { // Invalid payload + dol_syslog("***** Stripe IPN was called with UnexpectedValueException (invalid payload) service=".$service); + dol_syslog("***** Stripe IPN was called with UnexpectedValueException (invalid payload) service=".$service, LOG_DEBUG, 0, '_payment'); httponly_accessforbidden('Invalid payload', 400); } catch (\Stripe\Exception\SignatureVerificationException $e) { - httponly_accessforbidden('Invalid signature. May be a hook for an event created by another Stripe env ? Check setup of your keys whsec_...', 400); + dol_syslog("***** Stripe IPN was called with SignatureVerificationException service=".$service); + dol_syslog("***** Stripe IPN was called with SignatureVerificationException service=".$service, LOG_DEBUG, 0, '_payment'); + httponly_accessforbidden('Invalid signature. May be a hook for an event created by another Stripe env or a hack attempt ? Check setup of your keys whsec_...', 400); } catch (Exception $e) { + dol_syslog("***** Stripe IPN was called with Exception ('.$e->getMessage().') service=".$service); + dol_syslog("***** Stripe IPN was called with Exception ('.$e->getMessage().') service=".$service, LOG_DEBUG, 0, '_payment'); httponly_accessforbidden('Error '.$e->getMessage(), 400); } From 86208b9be2467ca3103e45b3f49fb9aa56ca1ead Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Jul 2025 23:57:35 +0200 Subject: [PATCH 67/73] Debug v22 --- htdocs/datapolicy/admin/setup.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/datapolicy/admin/setup.php b/htdocs/datapolicy/admin/setup.php index 5351f256011..f1cad850870 100644 --- a/htdocs/datapolicy/admin/setup.php +++ b/htdocs/datapolicy/admin/setup.php @@ -2,7 +2,7 @@ /* Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2018 Nicolas ZABOURI * 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 @@ -39,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/datapolicy/lib/datapolicy.lib.php'; */ // Translations -$langs->loadLangs(array('admin', 'companies', 'members', 'datapolicy')); +$langs->loadLangs(array('admin', 'companies', 'cron', 'members', 'datapolicy')); // Parameters $action = GETPOST('action', 'aZ09'); From 6e871343facbff16d659548dbc0bdc64cc0d9b84 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 8 Jul 2025 00:15:42 +0200 Subject: [PATCH 68/73] CSS --- htdocs/theme/eldy/global.inc.php | 3 +++ htdocs/theme/md/style.css.php | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 025f16e20bb..c956704492a 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -7800,6 +7800,9 @@ dd.dropdowndd ul li { white-space: nowrap; } +div.kanban.column div.ui-sortable-helper { + transform: rotate(4deg); +} /* ============================================================================== */ /* Markdown rendering */ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index a5c1dff160c..13cd736b7ca 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -7680,6 +7680,10 @@ dd.dropdowndd ul li { white-space: nowrap; } +div.kanban.column div.ui-sortable-helper { + transform: rotate(4deg); +} + /* ============================================================================== */ /* Markdown rendering */ From 77ce4ebc39ba0f608fb697fcb240973902e0ec64 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 8 Jul 2025 00:56:55 +0200 Subject: [PATCH 69/73] Debug v22 --- htdocs/projet/class/project.class.php | 10 ++++-- htdocs/projet/class/task.class.php | 10 ++++-- htdocs/projet/tasks/time.php | 48 +++++++++++++++++---------- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 3da24577f92..c2f60c5cebe 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1415,7 +1415,7 @@ class Project extends CommonObject * * @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 int $addlabel 0=Default, 1=Add label into string, n>1=Add the n first chars of label in ref, -1=Label replace the ref * @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 @@ -1505,11 +1505,15 @@ class Project extends CommonObject $result .= img_object(($notooltip ? '' : $label), $picto, 'class="pictofixedwidth em088"', 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { - $result .= $this->ref; + if ($addlabel >= 0) { + $result .= $this->ref; + } else { + $result .= $this->title; + } } $result .= $linkend; if ($withpicto != 2) { - $result .= (($addlabel && $this->title) ? ''.$sep.dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)).'' : ''); + $result .= (($addlabel > 0 && $this->title) ? ''.$sep.dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)).'' : ''); } global $action; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 7d84661d70b..88172a3c5bb 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1010,7 +1010,7 @@ class Task extends CommonObjectLine * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto * @param string $option 'withproject' or '' * @param string $mode Mode 'task', 'time', 'contact', 'note', document' define page to link to. - * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string + * @param int $addlabel 0=Default, 1=Add label into string, >1=Add first chars into string, -1=Label replace the ref * @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 @@ -1072,11 +1072,15 @@ class Task extends CommonObjectLine $result .= img_object(($notooltip ? '' : $label), $picto, 'class="paddingright"', 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { - $result .= $this->ref; + if ($addlabel >= 0) { + $result .= $this->ref; + } else { + $result .= $this->label; + } } $result .= $linkend; if ($withpicto != 2) { - $result .= (($addlabel && $this->label) ? $sep.dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + $result .= (($addlabel > 0 && $this->label) ? ''.$sep.dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)).'' : ''); } $parameters = array('id' => $this->id, 'getnomurl' => &$result); diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index a4a3044a3cc..c5249b2e79f 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -2065,11 +2065,11 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } if (!empty($allprojectforuser)) { if (!empty($arrayfields['p.project_ref']['checked'])) { - print_liste_field_titre("Project", $_SERVER['PHP_SELF'], 'p.ref', '', $param, '', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['p.project_ref']['label'], $_SERVER['PHP_SELF'], 'p.ref', '', $param, '', $sortfield, $sortorder); $totalarray['nbfield']++; } if (!empty($arrayfields['p.project_label']['checked'])) { - print_liste_field_titre("ProjectLabel", $_SERVER['PHP_SELF'], 'p.title', '', $param, '', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['p.project_label']['label'], $_SERVER['PHP_SELF'], 'p.title', '', $param, '', $sortfield, $sortorder); $totalarray['nbfield']++; } } @@ -2260,10 +2260,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } - // Project ref & label if (!empty($allprojectforuser)) { + // Project ref if (!empty($arrayfields['p.project_ref']['checked'])) { - print ''; if (!$i) { $totalarray['nbfield']++; } } + // Project label if (!empty($arrayfields['p.project_label']['checked'])) { if (empty($conf->cache['project'][$task_time->fk_projet])) { $tmpproject = new Project($db); @@ -2285,8 +2286,12 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } else { $tmpproject = $conf->cache['project'][$task_time->fk_projet]; } - print ''; if (!$i) { $totalarray['nbfield']++; @@ -2318,8 +2323,15 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Task label if (!empty($arrayfields['t.element_label']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task - print ''; if (!$i) { $totalarray['nbfield']++; @@ -2327,9 +2339,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } - // By User + // User if (!empty($arrayfields['author']['checked'])) { - print ''; } // Thirdparty alias if (!empty($arrayfields['s.name_alias']['checked'])) { - print ''; } // Project ref if (!empty($allprojectforuser)) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task - print ''; } } @@ -2780,7 +2792,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Task ref if (!empty($arrayfields['t.element_ref']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task - print ''; } @@ -2861,7 +2873,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Value spent if (!empty($arrayfields['value']['checked'])) { print ''; if (!$i) {
'; + print ''; $result = ''; $link = $linkend = ''; @@ -193,7 +188,7 @@ if ($resql) { $linkend = ''; $name = $obj->name; $result .= ($link.img_object($langs->trans("ShowCompany").': '.$name, 'company').$linkend); - $result .= $link.(dol_trunc($name, $maxlen)).$linkend; + $result .= $link.$name.$linkend; print $result; print '
'.$form->editfieldkey('MaxUsers', 'max_users', '', $object, 0).'
'.$form->editfieldkey('MaxUsers', 'max_users', '', $object, 0, 'string', '', 0, 0, 'id', $langs->trans('MaxUsersResourceDesc')).''; print img_picto('', 'object_user', 'class="pictofixedwidth"'); print '
'.$form->editfieldkey('URL', 'url', '', $object, 0).''; print img_picto('', 'object_url', 'class="pictofixedwidth"'); - print '
'.$langs->trans("ResourceFormLabel_ref").'
'.$langs->trans("ResourceType").'
'.$form->editfieldkey('EMail', 'email', '', $object, 0).''; print img_picto('', 'object_email', 'class="pictofixedwidth"'); - print '
'.$form->editfieldkey('MaxUsers', 'max_users', '', $object, 0, 'string', '', 0, 0, 'id', $langs->trans('MaxUsersResourceDesc')).''; print img_picto('', 'object_user', 'class="pictofixedwidth"'); - print '
'.$form->editfieldkey('URL', 'url', '', $object, 0).''; print img_picto('', 'object_url', 'class="pictofixedwidth"'); - print '
'.$langs->trans("MaxUsers").''; - print $object->max_users; + print $object->max_users > 0 ? $object->max_users : ''; print '
'; if (empty($conf->cache['project'][$task_time->fk_projet])) { $tmpproject = new Project($db); $tmpproject->fetch($task_time->fk_projet); @@ -2271,12 +2270,14 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } else { $tmpproject = $conf->cache['project'][$task_time->fk_projet]; } + print ''; print $tmpproject->getNomUrl(1); print ''; - print dol_escape_htmltag($tmpproject->title); + print ''; + if (!empty($arrayfields['p.project_ref']['checked'])) { + print dolPrintHTML($tmpproject->title); + } else { + print $tmpproject->getNomUrl(1, 0, -1); + } print ''; - print dol_escape_htmltag($task_time->label); + print ''; + if (!empty($arrayfields['t.element_ref']['checked'])) { + print dolPrintHTML($task_time->label); + } else { + $tasktmp->id = $task_time->fk_element; + $tasktmp->ref = $task_time->ref; + $tasktmp->label = $task_time->label; + print $tasktmp->getNomUrl(1, 'withproject', 'time', -1); + } print ''; + print ''; if ($action == 'editline' && GETPOSTINT('lineid') == $task_time->rowid) { // Here $object is task. TODO Add a cache if (empty($object->id)) { @@ -2744,7 +2756,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Date if (!empty($arrayfields['t.element_date']['checked'])) { - print ''; + print ''; if ($action == 'splitline' && GETPOSTINT('lineid') == $task_time->rowid) { if (empty($task_time->element_date_withhour)) { print $form->selectDate(($date2 ? $date2 : $date1), 'timeline_2', 3, 3, 2, "timespent_date", 1, 0); @@ -2759,20 +2771,20 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Thirdparty if (!empty($arrayfields['p.fk_soc']['checked'])) { - print ''; + print ''; print ''; + print ''; print ''; + print ''; print ''; + print ''; $tasktmp->id = $task_time->fk_element; $tasktmp->ref = $task_time->ref; $tasktmp->label = $task_time->label; @@ -2792,7 +2804,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Task label if (!empty($arrayfields['t.element_label']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task - print ''; + print ''; print dol_escape_htmltag($task_time->label); print ''; - print ''; + print ''; $value = 0; print price($value, 1, $langs, 1, -1, -1, $conf->currency); print ''; @@ -2873,7 +2885,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; $valuebilled = price2num($task_time->total_ht, '', 1); if (isset($task_time->total_ht)) { - print ''; + print ''; print price($valuebilled, 1, $langs, 1, -1, -1, $conf->currency); print ''; } From 0a8efe53b174f13df660f12336cda77a0927f27b Mon Sep 17 00:00:00 2001 From: Mohamed DAOUD Date: Tue, 8 Jul 2025 13:14:29 +0200 Subject: [PATCH 70/73] enhance payment checks (#34712) --- htdocs/public/payment/paymentok.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index bd1e9b5d480..1e350218e1f 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -295,6 +295,7 @@ $service = $paymentmethod; // to have a default value. We may change it later fo // For Paypal: validate the payment (Paypal need another step after the callback return to validate the payment). if (isModEnabled('paypal') && $paymentmethod === 'paypal') { // We call this page only if payment is ok on payment system if (!empty($PAYPALTOKEN)) { + // TODO: Move this block to the top to ensure all session variables (e.g., TRANSACTIONID, FinalPaymentAmt, currencyCodeType, etc.) are loaded before executing checks for any payment module. // Get on url call $onlinetoken = $PAYPALTOKEN; $fulltag = $FULLTAG; @@ -378,6 +379,17 @@ if (isModEnabled('paybox') && $paymentmethod === 'paybox') { // For Stripe if (isModEnabled('stripe') && $paymentmethod === 'stripe') { + // TODO: Move this block to the top to ensure all session variables (e.g., TRANSACTIONID, FinalPaymentAmt, currencyCodeType, etc.) are loaded before executing checks for any payment module. + if (empty($TRANSACTIONID)) { + $TRANSACTIONID = empty($_SESSION['TRANSACTIONID']) ? '' : $_SESSION['TRANSACTIONID']; // pi_... or ch_... + if (empty($TRANSACTIONID) && GETPOST('payment_intent', 'alphanohtml')) { + // For the case we use STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION = 2 + $TRANSACTIONID = GETPOST('payment_intent', 'alphanohtml'); + } + } + $FinalPaymentAmt = empty($_SESSION["FinalPaymentAmt"]) ? '' : $_SESSION["FinalPaymentAmt"]; + $currencyCodeType = empty($_SESSION['currencyCodeType']) ? '' : $_SESSION['currencyCodeType']; + $service = 'StripeTest'; $servicestatus = 0; if (getDolGlobalString('STRIPE_LIVE') && !GETPOSTINT('forcesandbox')) { @@ -471,6 +483,7 @@ if (!in_array($paymentmethod, array('paypal', 'paybox', 'stripe'))) { } } +// TODO: Move this block to the top to ensure all session variables (e.g., TRANSACTIONID, FinalPaymentAmt, currencyCodeType, etc.) are loaded before executing checks for any payment module. // Get variable into the session env if (empty($ipaddress)) { $ipaddress = $_SESSION['ipaddress']; From 2a2322067bc0f8289e685242dc7b3efb408c58e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:48:06 +0200 Subject: [PATCH 71/73] PHPStan > Update baseline (#34713) Co-authored-by: Dolibot --- dev/build/phpstan/phpstan-baseline.neon | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dev/build/phpstan/phpstan-baseline.neon b/dev/build/phpstan/phpstan-baseline.neon index 7bc6689a9f9..d1ffd383538 100644 --- a/dev/build/phpstan/phpstan-baseline.neon +++ b/dev/build/phpstan/phpstan-baseline.neon @@ -19986,12 +19986,6 @@ parameters: count: 1 path: ../../../htdocs/public/payment/paymentok.php - - - message: '#^Variable \$service might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../../htdocs/public/payment/paymentok.php - - message: '#^Call to function is_numeric\(\) with int will always evaluate to true\.$#' identifier: function.alreadyNarrowedType From 3f10bd2b7ebba382da1e67fc4b659f52861ef57c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 8 Jul 2025 15:32:27 +0200 Subject: [PATCH 72/73] Fix warning --- htdocs/public/stripe/ipn.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index f3350d36a7a..123d571243e 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -141,8 +141,8 @@ try { dol_syslog("***** Stripe IPN was called with SignatureVerificationException service=".$service, LOG_DEBUG, 0, '_payment'); httponly_accessforbidden('Invalid signature. May be a hook for an event created by another Stripe env or a hack attempt ? Check setup of your keys whsec_...', 400); } catch (Exception $e) { - dol_syslog("***** Stripe IPN was called with Exception ('.$e->getMessage().') service=".$service); - dol_syslog("***** Stripe IPN was called with Exception ('.$e->getMessage().') service=".$service, LOG_DEBUG, 0, '_payment'); + dol_syslog("***** Stripe IPN was called with Exception (".$e->getMessage().") service=".$service); + dol_syslog("***** Stripe IPN was called with Exception (".$e->getMessage().") service=".$service, LOG_DEBUG, 0, '_payment'); httponly_accessforbidden('Error '.$e->getMessage(), 400); } From edd5ddbb927da672682de4de486f92a8e2a0d3ed Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 8 Jul 2025 15:34:24 +0200 Subject: [PATCH 73/73] Fix CI --- htdocs/projet/tasks/time.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index c5249b2e79f..5633f9a8ad2 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1,5 +1,4 @@ * Copyright (C) 2006-2023 Laurent Destailleur * Copyright (C) 2010-2012 Regis Houssin @@ -2290,7 +2289,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (!empty($arrayfields['p.project_ref']['checked'])) { print dolPrintHTML($tmpproject->title); } else { - print $tmpproject->getNomUrl(1, 0, -1); + print $tmpproject->getNomUrl(1, '', -1); } print '