From 4a0035085975424fd049b25b550a9307a2885b67 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 19 Oct 2024 20:46:10 +0200 Subject: [PATCH 001/178] Fix test on malware --- htdocs/admin/modules.php | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index bf4cdaffd4a4f..b561267b5cb94 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -267,6 +267,30 @@ } } + /* + if (!$error) { + if (GETPOST('checkforcompliance')) { + $dir = $dirins; + $file = $modulenameval; + // $installedmodule + try { + $res = include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error. + $modName = substr($file, 0, dol_strlen($file) - 10); + if ($modName) { + if (class_exists($modName)) { + $objMod = new $modName($db); + '@phan-var-force DolibarrModules $objMod'; + + //var_dump($objMod); + } + } + } catch(Exception $e) { + // Nothing done + } + } + } + */ + if (!$error) { setEventMessages($langs->trans("SetupIsReadyForUse", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentitiesnoconv("Home").' - '.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Modules")), null, 'warnings'); } @@ -845,7 +869,7 @@ } } - if ($objMod->isCoreOrExternalModule() == 'external' && !getDolGlobalString('DISABLE_CHECK_ON_MALWARE_MODULES')) { + if ($objMod->isCoreOrExternalModule() == 'external' && $action == 'checklastversion' && !getDolGlobalString('DISABLE_CHECK_ON_MALWARE_MODULES')) { $checkRes = $objMod->checkForCompliance(); // Check if module is reported as non compliant with Dolibarr rules and law if (!is_numeric($checkRes) && $checkRes != '') { $langs->load("errors"); From df2211e9f21eb90319a9a70991329a1e7c5c7b00 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 20 Oct 2024 00:03:46 +0200 Subject: [PATCH 002/178] Fix phan --- htdocs/core/db/mysqli.class.php | 72 +++++++++++++++------------------ 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index f1fa63374009f..fcca43a491898 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -261,6 +261,7 @@ public function connect($host, $login, $passwd, $name, $port = 0) try { if (!class_exists('mysqli')) { dol_print_error(null, 'Driver mysqli for PHP not available'); + return false; } if (strpos($host, 'ssl://') === 0) { $tmp = new mysqliDoli($host, $login, $passwd, $name, $port); @@ -1289,49 +1290,40 @@ public function getServerStatusValues($filter = '') } -// Protection if class mysqli doe not exists to avoid error -if (!class_exists('mysqli')) { - /** - * A dummy class to avoid error when class is not available - */ - class mysqli - { - // Empty content - } -} - -/** - * Class to make SSL connection - */ -class mysqliDoli extends mysqli -{ +if (class_exists('myslqi')) { /** - * Constructor. - * This create an opened connection to a database server and eventually to a database - * - * @param string $host Address of database server - * @param string $user Name of database user - * @param string $pass Password of database user - * @param string $name Name of database - * @param int $port Port of database server - * @param string $socket Socket + * Class to make SSL connection */ - public function __construct($host, $user, $pass, $name, $port = 0, $socket = "") + class mysqliDoli extends mysqli { - $flags = 0; - if (PHP_VERSION_ID >= 80100) { - parent::__construct(); - } else { - // @phan-suppress-next-line PhanDeprecatedFunctionInternal - parent::init(); - } - if (strpos($host, 'ssl://') === 0) { - $host = substr($host, 6); - parent::options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, false); - // Suppress false positive @phan-suppress-next-line PhanTypeMismatchArgumentInternalProbablyReal - parent::ssl_set(null, null, "", null, null); - $flags = MYSQLI_CLIENT_SSL; + /** + * Constructor. + * This create an opened connection to a database server and eventually to a database + * + * @param string $host Address of database server + * @param string $user Name of database user + * @param string $pass Password of database user + * @param string $name Name of database + * @param int $port Port of database server + * @param string $socket Socket + */ + public function __construct($host, $user, $pass, $name, $port = 0, $socket = "") + { + $flags = 0; + if (PHP_VERSION_ID >= 80100) { + parent::__construct(); + } else { + // @phan-suppress-next-line PhanDeprecatedFunctionInternal + parent::init(); + } + if (strpos($host, 'ssl://') === 0) { + $host = substr($host, 6); + parent::options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, false); + // Suppress false positive @phan-suppress-next-line PhanTypeMismatchArgumentInternalProbablyReal + parent::ssl_set(null, null, "", null, null); + $flags = MYSQLI_CLIENT_SSL; + } + parent::real_connect($host, $user, $pass, $name, $port, $socket, $flags); } - parent::real_connect($host, $user, $pass, $name, $port, $socket, $flags); } } From eb3bba03cdaa43996149dfdff2e59f5af04e7188 Mon Sep 17 00:00:00 2001 From: Joachim Kueter Date: Sat, 19 Oct 2024 01:18:55 +0200 Subject: [PATCH 003/178] Merge branch '19.0' of git@github.com:Dolibarr/dolibarr.git into 20.0 --- .../core/modules/commande/doc/pdf_eratosthene.modules.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index 5e4f0f16462e7..23ef65337e3df 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -8,7 +8,9 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024 MDW + * Copyright (C) 2024 Nick Fragoulis + * Copyright (C) 2024 Joachim Kueter * * 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 @@ -1847,7 +1849,7 @@ public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hide 'border-left' => true, // add left line separator ); - if (!getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) { + if (!getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT') && !getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN')) { $this->cols['vat']['status'] = true; } From b0c7b8750a429f99e955cde3880a6734bfc8afad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 20 Oct 2024 00:10:54 +0200 Subject: [PATCH 004/178] fix overwritten value (#31470) --- htdocs/commande/list_det.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/list_det.php b/htdocs/commande/list_det.php index 9fc9e4059a77b..86a30b9cfc954 100644 --- a/htdocs/commande/list_det.php +++ b/htdocs/commande/list_det.php @@ -2016,7 +2016,7 @@ $productstat_cachevirtual[$obj->fk_product]['stock_reel'] = $generic_product->stock_theorique; } else { $generic_product->stock_reel = $productstat_cache[$obj->fk_product]['stock_reel']; - $generic_product->stock_theorique = $productstat_cachevirtual[$obj->fk_product]['stock_reel'] = $generic_product->stock_theorique; + $generic_product->stock_theorique = $productstat_cachevirtual[$obj->fk_product]['stock_reel']; } if ($reliquat > $generic_product->stock_reel) { From 1d197e42bbe2ab6c5fecce36ca6181c4156d3e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 20 Oct 2024 00:11:04 +0200 Subject: [PATCH 005/178] fix shippable tooltip value overwritten (#31468) --- htdocs/commande/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index bf39beba029f8..ef7f802c61bf4 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -2508,7 +2508,7 @@ $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; } else { $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; - $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; + $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel']; } if ($reliquat > $generic_product->stock_reel) { From 710905470bd014fc105826213757dcced2ffe88b Mon Sep 17 00:00:00 2001 From: sonikf <93765174+sonikf@users.noreply.github.com> Date: Sun, 20 Oct 2024 01:11:53 +0300 Subject: [PATCH 006/178] fix translation for non latin languages (#31473) --- htdocs/admin/modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index b561267b5cb94..8cd9320b6dc64 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -1337,7 +1337,7 @@ $(document).ready(function() { jQuery("#fileinstall").on("change", function() { if(this.files[0].size > '.($maxmin * 1024).') { - alert("'.dol_escape_js($langs->trans("ErrorFileSizeTooLarge")).'"); + alert("'.dol_escape_js($langs->transnoentitiesnoconv("ErrorFileSizeTooLarge")).'"); this.value = ""; } }); From 58c0b97300d7663ecadd8e8e10302c9b9b38fedd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Oct 2024 20:17:40 +0200 Subject: [PATCH 007/178] FIX for #31237 #31524 --- htdocs/societe/class/societe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index eb49f75e8da6c..6931f6d7d7656 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2077,7 +2077,7 @@ public function fetch($rowid, $ref = '', $ref_ext = '', $barcode = '', $idprof1 $this->model_pdf = $obj->model_pdf; $this->last_main_doc = $obj->last_main_doc; - $result = 1; + $result = $this->id; // fetch optionals attributes and labels $this->fetch_optionals(); From 4d047feca7163f83c328838832d8ecc5ec6a3e23 Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller <45882981+Hystepik@users.noreply.github.com> Date: Wed, 23 Oct 2024 20:20:54 +0200 Subject: [PATCH 008/178] Fix bad sql whe exporting salaries (#31526) Co-authored-by: Hystepik --- htdocs/core/modules/modSalaries.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/modSalaries.class.php b/htdocs/core/modules/modSalaries.class.php index f2c1cba7aad9e..48d5c82111f44 100644 --- a/htdocs/core/modules/modSalaries.class.php +++ b/htdocs/core/modules/modSalaries.class.php @@ -158,7 +158,8 @@ public function __construct($db) $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'user as u'; - $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'payment_salary as p ON p.fk_user = u.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'salary as s ON s.fk_user = u.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'payment_salary as p ON p.fk_salary = s.rowid'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_typepayment = cp.id'; $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('user').')'; } From 201d7bf90113dfb348eb5bff38b3f5b2c3d425e9 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 23 Oct 2024 20:25:48 +0200 Subject: [PATCH 009/178] FIX #31452 Predefined supplier invoice - Langage key & link to supplier card (#31514) --- htdocs/fourn/facture/card-rec.php | 34 +++++++++++++++---------------- htdocs/langs/en_US/errors.lang | 1 + 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/htdocs/fourn/facture/card-rec.php b/htdocs/fourn/facture/card-rec.php index 9655de0b780bb..8998a54eb5468 100644 --- a/htdocs/fourn/facture/card-rec.php +++ b/htdocs/fourn/facture/card-rec.php @@ -1,16 +1,16 @@ - * Copyright (C) 2004-2016 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013 Juanjo Menent - * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2012 Cedric Salvador - * Copyright (C) 2015 Alexandre Spangaro - * Copyright (C) 2016 Meziane Sof - * Copyright (C) 2017-2018 Frédéric France - * Copyright (C) 2023-2024 Nick Fragoulis - * Copyright (C) 2024 MDW +/* Copyright (C) 2002-2003 Rodolphe Quiedeville + * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2015-2024 Alexandre Spangaro + * Copyright (C) 2016 Meziane Sof + * Copyright (C) 2017-2018 Frédéric France + * Copyright (C) 2023-2024 Nick Fragoulis + * 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 @@ -28,7 +28,7 @@ /** * \file htdocs/fourn/facture/card-rec.php - * \ingroup invoice fournisseurs + * \ingroup supplier invoice * \brief Page to show predefined invoice */ @@ -478,7 +478,7 @@ } if ($qty < 0) { $langs->load("errors"); - setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors'); + setEventMessages($langs->trans('ErrorQtyForSupplierInvoiceCantBeNegative'), null, 'errors'); $error++; } @@ -819,7 +819,7 @@ } if ($qty < 0) { $langs->load("errors"); - setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors'); + setEventMessages($langs->trans('ErrorQtyForSupplierInvoiceCantBeNegative'), null, 'errors'); $error++; } @@ -931,7 +931,7 @@ print ''; // Third party - print '' . $langs->trans("Customer") . '' . $object->thirdparty->getNomUrl(1, 'customer') . ''; + print '' . $langs->trans("Supplier") . '' . $object->thirdparty->getNomUrl(1, 'supplier') . ''; print ''; // Invoice subtype @@ -944,7 +944,7 @@ $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $object->note_public; $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $object->note_private; - // Help of substitution key + // Help for substitution key $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object); $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%m') . ')'; diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index ac68295b535d2..bbaa74bba2db3 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -141,6 +141,7 @@ ErrorFieldCantBeNegativeOnInvoice=Field %s cannot be negative o ErrorLinesCantBeNegativeForOneVATRate=Total of lines (net of tax) can't be negative for a given not null VAT rate (Found a negative total for VAT rate %s%%). ErrorLinesCantBeNegativeOnDeposits=Lines can't be negative in a deposit. You will face problems when you will need to consume the deposit in final invoice if you do so. ErrorQtyForCustomerInvoiceCantBeNegative=Quantity for line into customer invoices can't be negative +ErrorQtyForSupplierInvoiceCantBeNegative=Quantity for line into supplier invoices can't be negative ErrorWebServerUserHasNotPermission=User account %s used to execute web server has no permission for that ErrorNoActivatedBarcode=No barcode type activated ErrUnzipFails=Failed to unzip %s with ZipArchive From a11e369e5c3c92e1677c3b116ea32eb6fb1142c4 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 23 Oct 2024 20:49:49 +0200 Subject: [PATCH 010/178] FIX Salary - Payment card - Missing date (#31512) * FIX Salary - Payment card - Missing date * Coryright --- htdocs/salaries/class/paymentsalary.class.php | 9 +++++---- htdocs/salaries/payment_salary/card.php | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/salaries/class/paymentsalary.class.php b/htdocs/salaries/class/paymentsalary.class.php index 96d414b1d120c..cea7ce1948f24 100644 --- a/htdocs/salaries/class/paymentsalary.class.php +++ b/htdocs/salaries/class/paymentsalary.class.php @@ -1,8 +1,8 @@ - * Copyright (C) 2014 Juanjo Menent - * Copyright (C) 2021 Gauthier VERDOL - * Copyright (C) 2024 Frédéric France +/* Copyright (C) 2011-2024 Alexandre Spangaro + * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2024 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -343,6 +343,7 @@ public function fetch($id) $this->datec = $this->db->jdate($obj->datec); $this->tms = $this->db->jdate($obj->tms); $this->datepaye = $this->db->jdate($obj->datep); + $this->datep = $this->db->jdate($obj->datep); $this->amount = $obj->amount; $this->fk_typepayment = $obj->fk_typepayment; $this->num_paiement = $obj->num_payment; diff --git a/htdocs/salaries/payment_salary/card.php b/htdocs/salaries/payment_salary/card.php index 5f30b4fb11821..a15fb006e1057 100644 --- a/htdocs/salaries/payment_salary/card.php +++ b/htdocs/salaries/payment_salary/card.php @@ -4,7 +4,9 @@ * Copyright (C) 2005 Marc Barilley / Ocebo * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2024 MDW * Copyright (C) 2024 Alexandre SPANGARO + * 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 From c48b035a1552fd05f589607c70947e5e82d91699 Mon Sep 17 00:00:00 2001 From: atm-corentin <165782689+atm-corentin@users.noreply.github.com> Date: Wed, 23 Oct 2024 22:59:46 +0200 Subject: [PATCH 011/178] =?UTF-8?q?FIX=20issue=20on=20action=20set=20condi?= =?UTF-8?q?tion=20in=20particular=20when=20you=20set=20a=20deposi=E2=80=A6?= =?UTF-8?q?=20(#31518)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix issue on action set condition in particular when you set a deposit cond on propal * fix some identation issues * fix retour github actions pre commit * Update card.php --------- Co-authored-by: Laurent Destailleur --- htdocs/comm/propal/card.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 97ed893601d0f..63dd1ae743655 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -146,7 +146,6 @@ if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } - if (empty($reshook)) { $backurlforlist = DOL_URL_ROOT.'/comm/propal/list.php'; @@ -1614,7 +1613,20 @@ $result = $object->set_demand_reason($user, GETPOST('demand_reason_id', 'int')); } elseif ($action == 'setconditions' && $usercancreate) { // Terms of payment - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha')); + $sql = "SELECT code "; + $sql .= "FROM " . $db->prefix() . "c_payment_term"; + $sql .= " WHERE rowid = " . ((int) GETPOST('cond_reglement_id', 'int')); + $result = $db->query($sql); + if ($result) { + $obj = $db->fetch_object($result); + if ($obj->code == 'DEP30PCTDEL') { + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha')); + } else { + $object->deposit_percent = 0; + $object->update($user); + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), $object->deposit_percent); + } + } } elseif ($action == 'setremisepercent' && $usercancreate) { $result = $object->set_remise_percent($user, price2num(GETPOST('remise_percent'), '', 2)); } elseif ($action == 'setremiseabsolue' && $usercancreate) { From 1778401423447338d93ea79c0144fb07812d587b Mon Sep 17 00:00:00 2001 From: Anthony Berton <34568357+BB2A-Anthony@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:06:00 +0200 Subject: [PATCH 012/178] FIX---PHP-warning-multiprice-in-liste-product-if-level-is-not-defined-on-product (#31507) * FIX - PHP warning multiprice in liste product if level is not defined on product * Update list.php --------- Co-authored-by: Anthony Berton Co-authored-by: Laurent Destailleur --- htdocs/product/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 09eb8cc08e986..f4dbed9b1561a 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -1949,7 +1949,7 @@ foreach ($arraypricelevel as $key => $value) { if (!empty($arrayfields['p.sellprice'.$key]['checked'])) { print ''; - if (!empty($productpricescache[$obj->rowid])) { + if (!empty($productpricescache[$obj->rowid]) && isset($productpricescache[$obj->rowid][$key]['price_base_type'])) { if ($productpricescache[$obj->rowid][$key]['price_base_type'] == 'TTC') { print ''.price($productpricescache[$obj->rowid][$key]['price_ttc']).' '.$langs->trans("TTC").''; } else { From b37b2ba76fad3a66f4de914c66dd366c1287ff3d Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Wed, 23 Oct 2024 23:08:05 +0200 Subject: [PATCH 013/178] fix: test on const with space.... (#31505) --- 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 804451777b84b..90555b00b0cc3 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -321,7 +321,7 @@ $object->date = dol_now(); } - if (!empty($conf->global-> INVOICE_CHECK_POSTERIOR_DATE)) { + if (!empty($conf->global->INVOICE_CHECK_POSTERIOR_DATE)) { $last_of_type = $object->willBeLastOfSameType(true); if (empty($object->date_validation) && !$last_of_type[0]) { setEventMessages($langs->transnoentities("ErrorInvoiceIsNotLastOfSameType", $object->ref, dol_print_date($object->date, 'day'), dol_print_date($last_of_type[1], 'day')), null, 'errors'); From 39afafc5859ffa5534171732315a4ff7a35ba8d2 Mon Sep 17 00:00:00 2001 From: "Thomas C." <56068416+Thomas905@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:11:02 +0200 Subject: [PATCH 014/178] FIX: If you have no stock of your product, an error is displayed when you delete the reception. (#31504) * fix * delete * f * indent * indent --- htdocs/reception/class/reception.class.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index ca1d87b076f7c..cc8c0923e85db 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1058,6 +1058,11 @@ public function delete(User $user) $mouvS->origin = null; $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans("ReceptionDeletedInDolibarr", $this->ref), '', $obj->eatby, $obj->sellby, $obj->batch); // Price is set to 0, because we don't want to see WAP changed + if ($result < 0) { + $error++; + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + } } } else { $error++; $this->errors[] = "Error ".$this->db->lasterror(); From e8f7237c63d6f7e69521d7e0a621a8c10daa1f32 Mon Sep 17 00:00:00 2001 From: mikygee Date: Wed, 23 Oct 2024 23:52:08 +0200 Subject: [PATCH 015/178] Bug fix #31369 date_solde not taken into account when sent through API (#31490) * Bug fix #31369 date_solde not taken into account when sent through API * Move $account->date_solde = time() above --------- Co-authored-by: mikael Co-authored-by: Laurent Destailleur --- htdocs/compta/bank/class/api_bankaccounts.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index 663eef6f6f391..1726f6395a730 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -159,6 +159,8 @@ public function post($request_data = null) $result = $this->_validate($request_data); $account = new Account($this->db); + // Date of the initial balance (required to create an account). + $account->date_solde = time(); foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller @@ -168,8 +170,6 @@ public function post($request_data = null) $account->$field = $this->_checkValForAPI($field, $value, $account); } - // Date of the initial balance (required to create an account). - $account->date_solde = time(); // courant and type are the same thing but the one used when // creating an account is courant $account->courant = $account->type; // deprecated From 23722b3db8d60f82f30b3e952b13aeb4a5fe75b3 Mon Sep 17 00:00:00 2001 From: John BOTELLA <68917336+thersane-john@users.noreply.github.com> Date: Thu, 24 Oct 2024 02:54:31 +0200 Subject: [PATCH 016/178] Fix v20 linked doc note info repeated (#31462) * FIX : space used by linked elements in PDF notes * fix data repeated on object public note --- htdocs/core/lib/pdf.lib.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index a3d2a9ebdedfb..e5f6695c92908 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -2501,10 +2501,12 @@ function pdf_getLinkedObjects(&$object, $outputlangs) $outputlangs->load('orders'); if (count($objects) > 1 && count($objects) <= (getDolGlobalInt("MAXREFONDOC") ? getDolGlobalInt("MAXREFONDOC") : 10)) { - $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' :'); - foreach ($objects as $elementobject) { - $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).(empty($elementobject->ref_client) ? '' : ' ('.$elementobject->ref_client.')').(empty($elementobject->ref_supplier) ? '' : ' ('.$elementobject->ref_supplier.')').' '); - $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '.dol_print_date($elementobject->date, 'day', '', $outputlangs)); + if (empty($object->context['DolPublicNoteAppendedGetLinkedObjects'])) { // Check if already appended before add to avoid repeat data + $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("RefOrder").' :'); + foreach ($objects as $elementobject) { + $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).(empty($elementobject->ref_client) ? '' : ' ('.$elementobject->ref_client.')').(empty($elementobject->ref_supplier) ? '' : ' ('.$elementobject->ref_supplier.')').' '); + $object->note_public = dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '.dol_print_date($elementobject->date, 'day', '', $outputlangs)); + } } } elseif (count($objects) == 1) { $elementobject = array_shift($objects); @@ -2563,7 +2565,9 @@ function pdf_getLinkedObjects(&$object, $outputlangs) } } - $object->note_public = dol_concatdesc($object->note_public, $refListsTxt); + if (empty($object->context['DolPublicNoteAppendedGetLinkedObjects'])) { // Check if already appended before add to avoid repeat data + $object->note_public = dol_concatdesc($object->note_public, $refListsTxt); + } } elseif (count($objects) == 1) { $elementobject = array_shift($objects); $order = null; @@ -2601,6 +2605,8 @@ function pdf_getLinkedObjects(&$object, $outputlangs) } } + $object->context['DolPublicNoteAppendedGetLinkedObjects'] = 1; + // For add external linked objects if (is_object($hookmanager)) { $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs); From d9d0618eec42f549e82c21d3178f8221a8077550 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Oct 2024 03:06:23 +0200 Subject: [PATCH 017/178] Fix avoid unexpected deletion on accounting account when using multicompany --- htdocs/install/mysql/migration/repair.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index d7fba7d6918fd..ef8989f34da0c 100644 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -310,7 +310,7 @@ drop table tmp_societe_double; -- Sequence to removed duplicated values of llx_accounting_account. Run several times if you still have duplicate. drop table tmp_accounting_account_double; --select account_number, fk_pcg_version, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_accounting_account where label is not null group by account_number, fk_pcg_version having count(rowid) >= 2; -create table tmp_accounting_account_double as (select account_number, fk_pcg_version, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_accounting_account where label is not null group by account_number, fk_pcg_version having count(rowid) >= 2); +create table tmp_accounting_account_double as (select account_number, fk_pcg_version, entity, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_accounting_account where label is not null group by account_number, fk_pcg_version, entity having count(rowid) >= 2); --select * from tmp_accounting_account_double; delete from llx_accounting_account where (rowid) in (select max_rowid from tmp_accounting_account_double); --update to avoid duplicate, delete to delete drop table tmp_accounting_account_double; From 399d778a7e337ceb1977038f09661bb5d66e7a60 Mon Sep 17 00:00:00 2001 From: ATM-NicolasV <92087862+ATM-NicolasV@users.noreply.github.com> Date: Thu, 24 Oct 2024 03:14:23 +0200 Subject: [PATCH 018/178] Fix:edition rapide de la date de livraison et propagation vers la commande (#31437) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pouvoir modifier la date de livraison au statut brouillon et propagation de la valeur lors de la création d'une commande * remove comment --------- Co-authored-by: ATM-nicolasV --- htdocs/fourn/commande/card.php | 2 +- htdocs/supplier_proposal/card.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 10683c77d9ac6..29f547e5da15d 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1814,7 +1814,7 @@ $usehourmin = 1; } print img_picto('', 'action', 'class="pictofixedwidth"'); - print $form->selectDate($datelivraison ? $datelivraison : -1, 'liv_', $usehourmin, $usehourmin, '', "set"); + print $form->selectDate($datedelivery ?: -1, 'liv_', $usehourmin, $usehourmin, '', "set"); print ''; // Bank Account diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 2a9841bad76fb..8d831e96da19e 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1692,7 +1692,7 @@ print ''; - if ($action != 'editdate_livraison' && $object->statut == SupplierProposal::STATUS_VALIDATED) { + if ($action != 'editdate_livraison' && $object->statut != SupplierProposal::STATUS_NOTSIGNED) { print ''; } print '
'; print $langs->trans('DeliveryDate'); print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetDeliveryDate'), 1).'
'; From 6b6d2398e146b0130b3649649943e84cfbc92447 Mon Sep 17 00:00:00 2001 From: omogenot Date: Thu, 24 Oct 2024 03:16:23 +0200 Subject: [PATCH 019/178] Update pdf.lib.php (#31530) Fix pdf_build_address function to use company address information should the contact information be empty. This could occurs should a user define a hook that sets the contact object to null from the passed by reference $Parameters['targetcontact'] --- htdocs/core/lib/pdf.lib.php | 98 ++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 2532ccdfe8c7c..1a8bd763a3d84 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -540,63 +540,61 @@ function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $t } if ($mode == 'target' || preg_match('/targetwithdetails/', $mode)) { - if ($usecontact) { - if (is_object($targetcontact)) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($targetcontact->getFullName($outputlangs, 1)); + if ($usecontact && (is_object($targetcontact))) { + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($targetcontact->getFullName($outputlangs, 1)); - if (!empty($targetcontact->address)) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n"; - } else { - $companytouseforaddress = $targetcompany; - - // Contact on a thirdparty that is a different thirdparty than the thirdparty of object - if ($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) { - $targetcontact->fetch_thirdparty(); - $companytouseforaddress = $targetcontact->thirdparty; - } + if (!empty($targetcontact->address)) { + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcontact))."\n"; + } else { + $companytouseforaddress = $targetcompany; - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($companytouseforaddress))."\n"; - } - // Country - if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcontact->country_code)); - } elseif (empty($targetcontact->country_code) && !empty($targetcompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code)); + // Contact on a thirdparty that is a different thirdparty than the thirdparty of object + if ($targetcontact->socid > 0 && $targetcontact->socid != $targetcompany->id) { + $targetcontact->fetch_thirdparty(); + $companytouseforaddress = $targetcontact->thirdparty; } - if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) { - // Phone - if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) { - if (!empty($targetcontact->phone_pro) || !empty($targetcontact->phone_mobile)) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": "; - } - if (!empty($targetcontact->phone_pro)) { - $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_pro); - } - if (!empty($targetcontact->phone_pro) && !empty($targetcontact->phone_mobile)) { - $stringaddress .= " / "; - } - if (!empty($targetcontact->phone_mobile)) { - $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_mobile); - } + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($companytouseforaddress))."\n"; + } + // Country + if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) { + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcontact->country_code)); + } elseif (empty($targetcontact->country_code) && !empty($targetcompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) { + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code)); + } + + if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || preg_match('/targetwithdetails/', $mode)) { + // Phone + if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/', $mode)) { + if (!empty($targetcontact->phone_pro) || !empty($targetcontact->phone_mobile)) { + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Phone").": "; } - // Fax - if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) { - if ($targetcontact->fax) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcontact->fax); - } + if (!empty($targetcontact->phone_pro)) { + $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_pro); } - // EMail - if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) { - if ($targetcontact->email) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcontact->email); - } + if (!empty($targetcontact->phone_pro) && !empty($targetcontact->phone_mobile)) { + $stringaddress .= " / "; } - // Web - if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) { - if ($targetcontact->url) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcontact->url); - } + if (!empty($targetcontact->phone_mobile)) { + $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_mobile); + } + } + // Fax + if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/', $mode)) { + if ($targetcontact->fax) { + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcontact->fax); + } + } + // EMail + if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/', $mode)) { + if ($targetcontact->email) { + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcontact->email); + } + } + // Web + if (getDolGlobalString('MAIN_PDF_ADDALSOTARGETDETAILS') || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/', $mode)) { + if ($targetcontact->url) { + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcontact->url); } } } From 3bc1d352365ac2ed29dd18e9db16daa17d6e7e96 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Oct 2024 12:38:41 +0200 Subject: [PATCH 020/178] QUAL The property ->domiciliation and ->propio on bank accounts has been deprecated and replaced with property ->address and ->owner_name --- ChangeLog | 1 + htdocs/admin/paymentbybanktransfer.php | 2 +- htdocs/admin/prelevement.php | 2 +- htdocs/compta/bank/card.php | 3 -- htdocs/compta/bank/class/account.class.php | 27 ++++++----------- .../class/bonprelevement.class.php | 4 +-- .../core/class/commondocgenerator.class.php | 2 +- htdocs/core/class/commoninvoice.class.php | 2 +- htdocs/core/lib/pdf.lib.php | 4 +-- htdocs/core/lib/security.lib.php | 4 +-- .../facture/doc/pdf_octopus.modules.php | 2 +- htdocs/public/stripe/ipn.php | 21 +++++++------- .../class/companybankaccount.class.php | 12 +++----- .../class/companypaymentmode.class.php | 7 +++++ htdocs/societe/paymentmodes.php | 29 ++++++++++--------- htdocs/stripe/class/stripe.class.php | 4 +-- htdocs/user/bank.php | 12 ++++---- htdocs/user/class/userbankaccount.class.php | 8 ++--- 18 files changed, 71 insertions(+), 75 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4fc1a6136811f..e205c90cda546 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,7 @@ The following changes may create regressions for some external modules, but were be set (not allowed by PHP 8.2). A module can already return an array with key 'no_button_delete', 'no_button_edit', 'no_button_copy' for same purpose. * The old function dol_bc($var, $moreclass = '') has been removed. If you called it, just stop to call it. * The trigger code CATEGORY_LINK and CATEGORY_UNLINK has been replaced with code CATEGORY_MODIFY. You can read ->context['linkto'] or ->context['unlinkoff' to detect we want to make a link or unlink. +* The property ->domiciliation and ->propio on bank accounts has been deprecated and replaced with property ->address and ->owner_name ***** ChangeLog for 20.0.1 compared to 20.0.0 ***** diff --git a/htdocs/admin/paymentbybanktransfer.php b/htdocs/admin/paymentbybanktransfer.php index 9e397724dcbb3..01b5175304230 100644 --- a/htdocs/admin/paymentbybanktransfer.php +++ b/htdocs/admin/paymentbybanktransfer.php @@ -71,7 +71,7 @@ if (! $res > 0) $error++; $res = dolibarr_set_const($db, "PRELEVEMENT_BIC", $account->bic,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; - $res = dolibarr_set_const($db, "PRELEVEMENT_RAISON_SOCIALE", $account->proprio,'chaine',0,'',$conf->entity); + $res = dolibarr_set_const($db, "PRELEVEMENT_RAISON_SOCIALE", $account->owner_address,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; */ } else { diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index 9435eacd0c908..9553528474da7 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -72,7 +72,7 @@ if (! $res > 0) $error++; $res = dolibarr_set_const($db, "PRELEVEMENT_BIC", $account->bic,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; - $res = dolibarr_set_const($db, "PRELEVEMENT_RAISON_SOCIALE", $account->proprio,'chaine',0,'',$conf->entity); + $res = dolibarr_set_const($db, "PRELEVEMENT_RAISON_SOCIALE", $account->owner_address,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; */ } else { diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index d4de338baaaaf..089ce2d53193b 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -145,9 +145,7 @@ $object->pti_in_ctti = empty(GETPOST("pti_in_ctti")) ? 0 : 1; $object->address = trim(GETPOST("account_address", "alphanohtml")); - $object->domiciliation = $object->address; // deprecated - $object->proprio = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_name = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_address = trim(GETPOST("owner_address", 'alphanohtml')); $object->owner_zip = trim(GETPOST("owner_zip", 'alphanohtml')); @@ -263,7 +261,6 @@ $object->iban = trim(GETPOST("iban")); $object->pti_in_ctti = empty(GETPOST("pti_in_ctti")) ? 0 : 1; - $object->proprio = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_name = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_address = trim(GETPOST("owner_address", 'alphanohtml')); $object->owner_zip = trim(GETPOST("owner_zip", 'alphanohtml')); diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index ef4d39c06f732..91f1a0644cdef 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -737,20 +737,11 @@ public function create($user, $notrigger = 0) if (empty($balance)) { $balance = 0; } - if (empty($this->address && !empty($this->domiciliation))) { - dol_syslog(get_class($this)."::create domiciliation is deprecated use address", LOG_NOTICE); - $this->address = $this->domiciliation; - } if (empty($this->status && !empty($this->clos))) { dol_syslog(get_class($this)."::create clos is deprecated use status", LOG_NOTICE); $this->status = $this->clos; } - if (empty($this->address && !empty($this->domiciliation))) { - dol_syslog(get_class($this)."::create domiciliation is deprecated use address", LOG_NOTICE); - $this->address = $this->domiciliation; - } - // Load the library to validate/check a BAN account require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; @@ -804,7 +795,7 @@ public function create($user, $notrigger = 0) $sql .= ", '".$this->db->escape($this->iban)."'"; $sql .= ", '".$this->db->escape($this->address)."'"; $sql .= ", ".((int) $this->pti_in_ctti); - $sql .= ", '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'"; + $sql .= ", '".$this->db->escape($this->owner_name)."'"; $sql .= ", '".$this->db->escape($this->owner_address)."'"; $sql .= ", '".$this->db->escape($this->owner_zip)."'"; $sql .= ", '".$this->db->escape($this->owner_town)."'"; @@ -928,7 +919,7 @@ public function update($user, $notrigger = 0) $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'"; $sql .= ",domiciliation='".$this->db->escape($this->address)."'"; $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti); - $sql .= ",proprio = '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'"; + $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'"; $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'"; $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'"; $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'"; @@ -1035,8 +1026,8 @@ public function update_bban($user = null) $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'"; $sql .= ",bic='".$this->db->escape($this->bic)."'"; $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'"; - $sql .= ",domiciliation='".$this->db->escape($this->address ? $this->address : $this->domiciliation)."'"; - $sql .= ",proprio = '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'"; + $sql .= ",domiciliation='".$this->db->escape($this->address)."'"; + $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'"; $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'"; $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'"; $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'"; @@ -1108,7 +1099,7 @@ public function fetch($id, $ref = '') $this->courant = $obj->type; $this->bank = $obj->bank; $this->clos = $obj->status; - $this->status = $obj->status; + $this->status = $obj->status; $this->rappro = $obj->rappro; $this->url = $obj->url; @@ -1118,16 +1109,17 @@ public function fetch($id, $ref = '') $this->cle_rib = $obj->cle_rib; $this->bic = $obj->bic; $this->iban = $obj->iban; - $this->domiciliation = $obj->address; $this->address = $obj->address; - $this->pti_in_ctti = $obj->pti_in_ctti; - $this->proprio = $obj->owner_name; + $this->owner_name = $obj->owner_name; + $this->proprio = $this->owner_name; $this->owner_address = $obj->owner_address; $this->owner_zip = $obj->owner_zip; $this->owner_town = $obj->owner_town; $this->owner_country_id = $obj->owner_country_id; + $this->pti_in_ctti = $obj->pti_in_ctti; + $this->state_id = $obj->state_id; $this->state_code = $obj->state_code; $this->state = $obj->state; @@ -1961,7 +1953,6 @@ public function initAsSpecimen() $this->bank = 'MyBank'; $this->address = 'Rue de Paris'; - $this->proprio = 'Owner'; $this->owner_name = 'Owner'; $this->owner_address = 'Owner address'; $this->owner_zip = 'Owner zip'; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 89919a8b1d519..5a4faa32e628f 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1458,7 +1458,7 @@ public function create($banque = 0, $agence = 0, $mode = 'real', $format = 'ALL' $this->emetteur_ics = (($type == 'bank-transfer' && getDolGlobalString("SEPA_USE_IDS")) ? $account->ics_transfer : $account->ics); // Example "FR78ZZZ123456" - $this->raison_sociale = $account->proprio; + $this->raison_sociale = $account->owner_name; } $this->factures = $factures_prev_id; $this->context['factures_prev'] = $factures_prev; @@ -2533,7 +2533,7 @@ public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrL $this->emetteur_ics = (($type == 'bank-transfer' && getDolGlobalString("SEPA_USE_IDS")) ? $account->ics_transfer : $account->ics); // Ex: PRELEVEMENT_ICS = "FR78ZZZ123456"; - $this->raison_sociale = $account->proprio; + $this->raison_sociale = $account->owner_name; } // Get pending payments diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index ca60491f6d1d1..b1124c9ff8d62 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -760,7 +760,7 @@ public function get_substitutionarray_object($object, $outputlangs, $array_key = $resarray[$array_key.'_bank_bic'] = (empty($bank_account) ? '' : $bank_account->bic); $resarray[$array_key.'_bank_label'] = (empty($bank_account) ? '' : $bank_account->label); $resarray[$array_key.'_bank_number'] = (empty($bank_account) ? '' : $bank_account->number); - $resarray[$array_key.'_bank_proprio'] = (empty($bank_account) ? '' : $bank_account->proprio); + $resarray[$array_key.'_bank_proprio'] = (empty($bank_account) ? '' : $bank_account->owner_name); $resarray[$array_key.'_bank_address'] = (empty($bank_account) ? '' : $bank_account->address); $resarray[$array_key.'_bank_state'] = (empty($bank_account) ? '' : $bank_account->state); $resarray[$array_key.'_bank_country'] = (empty($bank_account) ? '' : $bank_account->country); diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 64d2223ec1ee1..52de45fcc92ab 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -1884,7 +1884,7 @@ public function buildSwitzerlandQRString() // If a bank account is provided and we ask to use it as creditor, we use the bank address // TODO In a future, we may always use this address, and if name/address/zip/town/country differs from $mysoc, we can use the address of $mysoc into the final seller field ? $s .= "S\n"; - $s .= dol_trunc($bankaccount->proprio, 70, 'right', 'UTF-8', 1)."\n"; + $s .= dol_trunc($bankaccount->owner_name, 70, 'right', 'UTF-8', 1)."\n"; $addresslinearray = explode("\n", $bankaccount->owner_address); $s .= dol_trunc(empty($addresslinearray[1]) ? '' : $addresslinearray[1], 70, 'right', 'UTF-8', 1)."\n"; // address line 1 $s .= dol_trunc(empty($addresslinearray[2]) ? '' : $addresslinearray[2], 70, 'right', 'UTF-8', 1)."\n"; // address line 2 diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 2532ccdfe8c7c..5401717a869c6 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -951,9 +951,9 @@ function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $pdf->SetFont('', '', $default_font_size - $diffsizecontent); - if (empty($onlynumber) && (!empty($account->domiciliation) || !empty($account->address))) { + if (empty($onlynumber) && !empty($account->address)) { $pdf->SetXY($curx, $cury); - $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset(empty($account->address) ? $account->domiciliation : $account->address); + $val = $outputlangs->transnoentities("Residence").': '.$outputlangs->convToOutputCharset($account->address); $pdf->MultiCell(100, 3, $val, 0, 'L', 0); //$nboflines=dol_nboflines_bis($val,120); //$cury+=($nboflines*3)+2; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 58b96ef605712..f66206c50af7b 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -34,7 +34,7 @@ * @param string $chain string to encode * @param string $key rule to use for delta ('0', '1' or 'myownkey') * @return string encoded string - * @see dol_decode() + * @see dol_decode(), dolEncrypt() */ function dol_encode($chain, $key = '1') { @@ -65,7 +65,7 @@ function dol_encode($chain, $key = '1') * @param string $chain string to decode * @param string $key rule to use for delta ('0', '1' or 'myownkey') * @return string decoded string - * @see dol_encode() + * @see dol_encode(), dolDecrypt */ function dol_decode($chain, $key = '1') { diff --git a/htdocs/core/modules/facture/doc/pdf_octopus.modules.php b/htdocs/core/modules/facture/doc/pdf_octopus.modules.php index de620ae12d3e1..b688c5f223202 100644 --- a/htdocs/core/modules/facture/doc/pdf_octopus.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_octopus.modules.php @@ -1491,7 +1491,7 @@ protected function drawInfoTable(&$pdf, $object, $posy, $outputlangs, $outputlan $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle); - $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->owner_name), 0, 'L', 0); $posy = $pdf->GetY() + 1; if (!getDolGlobalString('MAIN_PDF_HIDE_CHQ_ADDRESS')) { diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 80d605a79ad4f..3d8db1970c640 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -708,21 +708,22 @@ if ($idthirdparty > 0) { // If the payment mode attached is to a stripe account owned by an external customer in societe_account (so a thirdparty that has a Stripe account), // we can create the payment mode - $companypaymentmode->stripe_card_ref = $db->escape($event->data->object->id); + $companypaymentmode->stripe_card_ref = $event->data->object->id; $companypaymentmode->fk_soc = $idthirdparty; $companypaymentmode->bank = null; $companypaymentmode->label = ''; - $companypaymentmode->number = $db->escape($event->data->object->id); - $companypaymentmode->last_four = $db->escape($event->data->object->card->last4); - $companypaymentmode->card_type = $db->escape($event->data->object->card->branding); - $companypaymentmode->proprio = $db->escape($event->data->object->billing_details->name); - $companypaymentmode->exp_date_month = $db->escape($event->data->object->card->exp_month); - $companypaymentmode->exp_date_year = $db->escape($event->data->object->card->exp_year); + $companypaymentmode->number = $event->data->object->id; + $companypaymentmode->last_four = $event->data->object->card->last4; + $companypaymentmode->card_type = $event->data->object->card->branding; + $companypaymentmode->owner_name = $event->data->object->billing_details->name; + $companypaymentmode->proprio = $companypaymentmode->owner_name; // We still need this formodulebuilder because name of field is "proprio" + $companypaymentmode->exp_date_month = $event->data->object->card->exp_month; + $companypaymentmode->exp_date_year = $event->data->object->card->exp_year; $companypaymentmode->cvn = null; - $companypaymentmode->datec = $db->escape($event->data->object->created); + $companypaymentmode->datec = $event->data->object->created; $companypaymentmode->default_rib = 0; - $companypaymentmode->type = $db->escape($event->data->object->type); - $companypaymentmode->country_code = $db->escape($event->data->object->card->country); + $companypaymentmode->type = $event->data->object->type; + $companypaymentmode->country_code = $event->data->object->card->country; $companypaymentmode->status = $servicestatus; // TODO Check that a payment mode $companypaymentmode->stripe_card_ref does not exists yet to avoid to create duplicates diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 006eaad69c0f3..27196d2f0863c 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -390,9 +390,6 @@ public function update($user = null, $notrigger = 0) return -1; } - if (!empty($this->domiciliation) && dol_strlen($this->domiciliation) > 255) { - $this->domiciliation = dol_trunc($this->domiciliation, 254, 'right', 'UTF-8', 1); - } if (!empty($this->address) && dol_strlen($this->address) > 255) { $this->address = dol_trunc($this->address, 254, 'right', 'UTF-8', 1); } @@ -413,9 +410,9 @@ public function update($user = null, $notrigger = 0) $sql .= ",number='".$this->db->escape($this->number)."'"; $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'"; $sql .= ",bic='".$this->db->escape($this->bic)."'"; - $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'"; - $sql .= ",domiciliation = '".$this->db->escape($this->address ? $this->address : $this->domiciliation)."'"; - $sql .= ",proprio = '".$this->db->escape($this->proprio)."'"; + $sql .= ",iban_prefix = '".$this->db->escape(dolEncrypt($this->iban))."'"; + $sql .= ",domiciliation = '".$this->db->escape($this->address)."'"; + $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'"; $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'"; $sql .= ",default_rib = ".((int) $this->default_rib); if (isModEnabled('prelevement')) { @@ -517,11 +514,10 @@ public function fetch($id, $ref = '', $socid = 0, $default = 1, $type = 'ban') $this->bic = $obj->bic; $this->iban = $obj->iban; - $this->domiciliation = $obj->address; $this->address = $obj->address; + $this->owner_name = $obj->owner_name; $this->proprio = $obj->owner_name; - $this->owner_name = $obj->owner_name; $this->owner_address = $obj->owner_address; $this->label = $obj->label; $this->default_rib = $obj->default_rib; diff --git a/htdocs/societe/class/companypaymentmode.class.php b/htdocs/societe/class/companypaymentmode.class.php index f8ac46a6598aa..c10425cba799c 100644 --- a/htdocs/societe/class/companypaymentmode.class.php +++ b/htdocs/societe/class/companypaymentmode.class.php @@ -150,9 +150,16 @@ class CompanyPaymentMode extends CommonObject * @var string */ public $iban_prefix; + + /** @deprecated Use address */ public $domiciliation; + public $address; + /** @deprecated Use owner_name*/ public $proprio; + public $owner_name; + public $owner_address; + public $default_rib; public $rum; public $date_rum; diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 4ab780cfabfd3..5ccbee75ebab1 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -184,7 +184,6 @@ $companybankaccount->iban = GETPOST('iban', 'alpha'); $companybankaccount->address = GETPOST('address', 'alpha'); - $companybankaccount->domiciliation = $companybankaccount->address; $companybankaccount->owner_name = GETPOST('proprio', 'alpha'); $companybankaccount->proprio = $companybankaccount->owner_name; @@ -254,7 +253,8 @@ $companypaymentmode->label = GETPOST('label', 'alpha'); $companypaymentmode->number = GETPOST('cardnumber', 'alpha'); $companypaymentmode->last_four = substr(GETPOST('cardnumber', 'alpha'), -4); - $companypaymentmode->proprio = GETPOST('proprio', 'alpha'); + $companypaymentmode->owner_name = GETPOST('proprio', 'alpha'); + $companypaymentmode->proprio = $companypaymentmode->owner_name; $companypaymentmode->exp_date_month = GETPOSTINT('exp_date_month'); $companypaymentmode->exp_date_year = GETPOSTINT('exp_date_year'); $companypaymentmode->cvn = GETPOST('cvn', 'alpha'); @@ -315,10 +315,10 @@ $companybankaccount->bic = GETPOST('bic', 'alpha'); $companybankaccount->iban = GETPOST('iban', 'alpha'); - $companybankaccount->domiciliation = GETPOST('address', 'alpha'); $companybankaccount->address = GETPOST('address', 'alpha'); - $companybankaccount->proprio = GETPOST('proprio', 'alpha'); + $companybankaccount->owner_name = GETPOST('proprio', 'alpha'); + $companybankaccount->proprio = $companybankaccount->owner_name; $companybankaccount->owner_address = GETPOST('owner_address', 'alpha'); $companybankaccount->frstrecur = GETPOST('frstrecur', 'alpha'); $companybankaccount->rum = GETPOST('rum', 'alpha'); @@ -1276,8 +1276,8 @@ print ''; // Information (Owner, ...) print ''; - if ($companypaymentmodetemp->proprio) { - print ''.$companypaymentmodetemp->proprio.'
'; + if ($companypaymentmodetemp->owner_name) { + print ''.$companypaymentmodetemp->owner_name.'
'; } if ($companypaymentmodetemp->last_four) { print '....'.$companypaymentmodetemp->last_four; @@ -1819,28 +1819,28 @@ print ''; print''; // Account number - print ''; + print ''; print ''; // IBAN - print ''; + print ''; //var_dump($src); print ''; // BIC - print ''; + print ''; //var_dump($src); print ''; if (isModEnabled('prelevement')) { // RUM - print ''; + print ''; //var_dump($src); print ''; // Date - print ''; + print ''; //var_dump($src); print ''; // Mode mandate - print ''; + print ''; //var_dump($src); print ''; } @@ -1889,6 +1889,9 @@ if (isModEnabled('prelevement')) { $colspan += 3; } + if (!getDolGlobalInt('SOCIETE_DISABLE_BANKACCOUNT') && getDolGlobalInt("SOCIETE_RIB_ALLOW_ONLINESIGN")) { + $colspan++; + } print ''.$langs->trans("NoBANRecord").''; } @@ -2111,7 +2114,7 @@ print ''; print ''.$langs->trans("NameOnCard").''; - print ''; + print ''; print ''.$langs->trans("CardNumber").''; print ''; diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 89fa5273b8880..3915a4b60caa0 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -845,7 +845,7 @@ public function cardStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $st $card = null; - $sql = "SELECT sa.stripe_card_ref, sa.proprio, sa.exp_date_month, sa.exp_date_year, sa.number, sa.cvn"; // stripe_card_ref is card_.... + $sql = "SELECT sa.stripe_card_ref, sa.proprio as owner_name, sa.exp_date_month, sa.exp_date_year, sa.number, sa.cvn"; // stripe_card_ref is card_.... $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib as sa"; $sql .= " WHERE sa.rowid = ".((int) $object->id); // We get record from ID, no need for filter on entity $sql .= " AND sa.type = 'card'"; @@ -885,7 +885,7 @@ public function cardStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $st $exp_date_year = $obj->exp_date_year; $number = $obj->number; $cvc = $obj->cvn; // cvn in database, cvc for stripe - $cardholdername = $obj->proprio; + $cardholdername = $obj->owner_name; $ipaddress = getUserRemoteIP(); diff --git a/htdocs/user/bank.php b/htdocs/user/bank.php index 884874982cddd..ea453dbe9abaf 100644 --- a/htdocs/user/bank.php +++ b/htdocs/user/bank.php @@ -130,10 +130,10 @@ $account->cle_rib = GETPOST('cle_rib', 'alpha'); $account->bic = GETPOST('bic', 'alpha'); $account->iban = GETPOST('iban', 'alpha'); - $account->domiciliation = GETPOST('address', 'alpha'); $account->address = GETPOST('address', 'alpha'); - $account->owner_name = GETPOST('proprio', 'alpha'); - $account->proprio = $account->owner_name; + + $account->owner_name = GETPOST('proprio', 'alpha'); + $account->proprio = $account->owner_name; $account->owner_address = GETPOST('owner_address', 'alpha'); $account->currency_code = trim(GETPOST("account_currency_code")); @@ -163,9 +163,9 @@ $account->cle_rib = GETPOST('cle_rib', 'alpha'); $account->bic = GETPOST('bic', 'alpha'); $account->iban = GETPOST('iban', 'alpha'); - $account->domiciliation = GETPOST('address', 'alpha'); $account->address = GETPOST('address', 'alpha'); - $account->proprio = GETPOST('proprio', 'alpha'); + $account->owner_name = GETPOST('proprio', 'alpha'); + $account->proprio = $account->owner_name; $account->owner_address = GETPOST('owner_address', 'alpha'); $account->currency_code = trim(GETPOST("account_currency_code")); @@ -1018,7 +1018,7 @@ print ""; print ''.$langs->trans("BankAccountOwner").''; - print ''; + print ''; print "\n"; print ''.$langs->trans("BankAccountOwnerAddress").''; diff --git a/htdocs/user/class/userbankaccount.class.php b/htdocs/user/class/userbankaccount.class.php index d9a65fb521226..b97e8bb0c4c71 100644 --- a/htdocs/user/class/userbankaccount.class.php +++ b/htdocs/user/class/userbankaccount.class.php @@ -137,8 +137,8 @@ public function update($user = null, $notrigger = 0) $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'"; $sql .= ",bic='".$this->db->escape($this->bic)."'"; $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'"; - $sql .= ",domiciliation='".$this->db->escape($this->address ? $this->address : $this->domiciliation)."'"; - $sql .= ",proprio = '".$this->db->escape($this->proprio)."'"; + $sql .= ",domiciliation='".$this->db->escape($this->address)."'"; + $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'"; $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'"; $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'"; $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null"); @@ -227,12 +227,12 @@ public function fetch($id, $ref = '', $userid = 0) $this->courant = self::TYPE_CURRENT; $this->type = self::TYPE_CURRENT; - $this->domiciliation = $obj->address; $this->address = $obj->address; - $this->proprio = $obj->owner_name; $this->owner_name = $obj->owner_name; + $this->proprio = $obj->owner_name; $this->owner_address = $obj->owner_address; + $this->label = $obj->label; $this->datec = $this->db->jdate($obj->datec); $this->datem = $this->db->jdate($obj->datem); From 830029dd0525d987914439ad53189766146092e2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Oct 2024 13:03:52 +0200 Subject: [PATCH 021/178] NEW Iban is saved encrypted --- htdocs/core/lib/security.lib.php | 2 +- .../doc/pdf_standard_supplierpayment.modules.php | 2 +- htdocs/install/mysql/migration/20.0.0-21.0.0.sql | 2 ++ htdocs/install/mysql/tables/llx_societe_rib.sql | 2 +- htdocs/societe/class/api_thirdparties.class.php | 6 +++++- htdocs/societe/class/companybankaccount.class.php | 12 ++++++------ htdocs/societe/class/companypaymentmode.class.php | 2 +- htdocs/societe/class/societe.class.php | 2 +- htdocs/societe/paymentmodes.php | 5 +++-- htdocs/stripe/class/stripe.class.php | 2 +- 10 files changed, 22 insertions(+), 15 deletions(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index f66206c50af7b..ec6de2992d2a5 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -110,7 +110,7 @@ function dolGetRandomBytes($length) /** * Encode a string with a symmetric encryption. Used to encrypt sensitive data into database. * Note: If a backup is restored onto another instance with a different $conf->file->instance_unique_id, then decoded value will differ. - * This function is called for example by dol_set_const() when saving a sensible data into database configuration table llx_const. + * This function is called for example by dol_set_const() when saving a sensible data into database, like into configuration table llx_const, or societe_rib, ... * * @param string $chain String to encode * @param string $key If '', we use $conf->file->instance_unique_id (so $dolibarr_main_instance_unique_id in conf.php) diff --git a/htdocs/core/modules/supplier_payment/doc/pdf_standard_supplierpayment.modules.php b/htdocs/core/modules/supplier_payment/doc/pdf_standard_supplierpayment.modules.php index cdbf0b9f13f6a..27b79ba5c41e1 100644 --- a/htdocs/core/modules/supplier_payment/doc/pdf_standard_supplierpayment.modules.php +++ b/htdocs/core/modules/supplier_payment/doc/pdf_standard_supplierpayment.modules.php @@ -800,7 +800,7 @@ protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs) if ($resql) { $obj = $this->db->fetch_object($resql); if ($obj) { - $iban = $obj->iban; + $iban = dolDecrypt($obj->iban); } } diff --git a/htdocs/install/mysql/migration/20.0.0-21.0.0.sql b/htdocs/install/mysql/migration/20.0.0-21.0.0.sql index 04f14b80010a6..e158fed274f24 100644 --- a/htdocs/install/mysql/migration/20.0.0-21.0.0.sql +++ b/htdocs/install/mysql/migration/20.0.0-21.0.0.sql @@ -53,6 +53,8 @@ ALTER TABLE llx_hrm_evaluation MODIFY COLUMN modelpdf varchar(255) DEFAULT NULL; DROP TABLE llx_contratdet_log; +ALTER TABLE llx_societe_rib MODIFY COLUMN iban_prefix varchar(60); + -- add billable attribute to project task ALTER TABLE llx_projet_task ADD COLUMN billable smallint DEFAULT 1; diff --git a/htdocs/install/mysql/tables/llx_societe_rib.sql b/htdocs/install/mysql/tables/llx_societe_rib.sql index f9657e797629f..064cc20313144 100644 --- a/htdocs/install/mysql/tables/llx_societe_rib.sql +++ b/htdocs/install/mysql/tables/llx_societe_rib.sql @@ -39,7 +39,7 @@ create table llx_societe_rib bic varchar(20), -- 11 according to ISO 9362 (we keep 20 for backward compatibility) bic_intermediate varchar(11), -- 11 according to ISO 9362. Same as bic but for intermediate bank - iban_prefix varchar(34), -- full iban. 34 according to ISO 13616 + iban_prefix varchar(60), -- full iban. 34 according to ISO 13616 ut we set 60 to allow to store it with encryption information domiciliation varchar(255), proprio varchar(60), diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 2362599a432d1..91195e6010ef3 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -1429,7 +1429,11 @@ public function getCompanyBankAccount($id) $object = array(); foreach ($account as $key => $value) { if (in_array($key, $fields)) { - $object[$key] = $value; + if ($key == 'iban') { + $object[$key] = dolDecrypt($value); + } else { + $object[$key] = $value; + } } } $returnAccounts[] = $object; diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 27196d2f0863c..3ee8442bf3d00 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -302,7 +302,7 @@ public function __construct(DoliDB $db) /** * Create bank information record. * - * @param $user User + * @param ?User $user User * @param int<0,1> $notrigger 1=Disable triggers * @return int Return integer <0 if KO, > 0 if OK (ID of newly created company bank account information) */ @@ -325,7 +325,8 @@ public function create($user = null, $notrigger = 0) // Correct ->default_rib to not set the new account as default, if there is already 1. We want to be sure to have always 1 default for type = 'ban'. // If we really want the new bank account to be the default, we must set it by calling setDefault() after creation. - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib where fk_soc = ".((int) $this->socid)." AND default_rib = 1 AND type = 'ban'"; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib"; + $sql .= " WHERE fk_soc = ".((int) $this->socid)." AND default_rib = 1 AND type = 'ban'"; $result = $this->db->query($sql); if ($result) { $numrows = $this->db->num_rows($result); @@ -512,7 +513,7 @@ public function fetch($id, $ref = '', $socid = 0, $default = 1, $type = 'ban') $this->number = $obj->number; $this->cle_rib = $obj->cle_rib; $this->bic = $obj->bic; - $this->iban = $obj->iban; + $this->iban = dolDecrypt($obj->iban); $this->address = $obj->address; @@ -615,7 +616,7 @@ public function getRibLabel($displayriblabel = true) public function setAsDefault($rib = 0, $resetolddefaultfor = 'ban') { $sql1 = "SELECT rowid as id, fk_soc as socid FROM ".MAIN_DB_PREFIX."societe_rib"; - $sql1 .= " WHERE rowid = ".($rib ? $rib : $this->id); + $sql1 .= " WHERE rowid = ".((int) ($rib ? $rib : $this->id)); dol_syslog(get_class($this).'::setAsDefault', LOG_DEBUG); $result1 = $this->db->query($sql1); @@ -679,8 +680,7 @@ public function initAsSpecimen() $this->address = 'Rue de Paris'; $this->country_id = 1; - $this->proprio = 'Owner'; - $this->owner_name = 'Owner'; + $this->owner_name = 'Owner'; $this->owner_address = 'Owner address'; $this->owner_country_id = 1; diff --git a/htdocs/societe/class/companypaymentmode.class.php b/htdocs/societe/class/companypaymentmode.class.php index c10425cba799c..4b6da9bbcab6c 100644 --- a/htdocs/societe/class/companypaymentmode.class.php +++ b/htdocs/societe/class/companypaymentmode.class.php @@ -431,7 +431,7 @@ public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss public function setAsDefault($id = 0, $alltypes = 0) { $sql1 = "SELECT rowid as id, fk_soc, type FROM ".MAIN_DB_PREFIX."societe_rib"; - $sql1 .= " WHERE rowid = ".($id ? $id : $this->id); + $sql1 .= " WHERE rowid = ".((int) ($id ? $id : $this->id)); dol_syslog(get_class($this).'::setAsDefault', LOG_DEBUG); $result1 = $this->db->query($sql1); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 8bfd1a6f37241..5a0a138705de0 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -3498,7 +3498,7 @@ public function get_all_rib() { // phpcs:enable require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib WHERE type='ban' AND fk_soc = ".((int) $this->id); + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib WHERE type = 'ban' AND fk_soc = ".((int) $this->id); $result = $this->db->query($sql); if (!$result) { $this->error = $this->db->lasterror(); diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 5ccbee75ebab1..c12b9d268ac6a 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -816,6 +816,7 @@ $sql = "UPDATE ".MAIN_DB_PREFIX."societe_rib as sr "; $sql .= " SET stripe_card_ref = null"; $sql .= " WHERE sr.stripe_card_ref = '".$db->escape($source)."'"; + $resql = $db->query($sql); } else { $card->delete($user); @@ -2157,10 +2158,10 @@ print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; // Show fields of bank account foreach ($companybankaccount->getFieldsToShow(1) as $val) { diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 3915a4b60caa0..8efe8ad7ad94c 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -1034,7 +1034,7 @@ public function sepaStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $st dol_syslog($this->error, LOG_WARNING); } } elseif ($createifnotlinkedtostripe) { - $iban = $obj->iban; + $iban = dolDecrypt($obj->iban); $ipaddress = getUserRemoteIP(); $metadata = array('dol_version' => DOL_VERSION, 'dol_entity' => $conf->entity, 'ipaddress' => $ipaddress); if (is_object($object)) { From e31adc98faefc3afc352a3fa8fb64d7f7c9d9649 Mon Sep 17 00:00:00 2001 From: John BOTELLA <68917336+thersane-john@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:57:57 +0200 Subject: [PATCH 022/178] Fix watermark alpha transparency (#31535) --- htdocs/core/lib/pdf.lib.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index e5f6695c92908..92b538c5824ed 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -814,17 +814,24 @@ function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text) $watermark_x = $w / 2; $watermark_y = $h / 3; $pdf->SetFont('', 'B', 40); - $pdf->SetTextColor(255, 192, 203); + $pdf->SetTextColor(255, 0, 0); //rotate $pdf->_out(sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm', cos($watermark_angle), sin($watermark_angle), -sin($watermark_angle), cos($watermark_angle), $watermark_x * $k, ($h - $watermark_y) * $k, -$watermark_x * $k, -($h - $watermark_y) * $k)); //print watermark $pdf->SetXY($watermark_x_pos, $watermark_y_pos); + + // set alpha to semi-transparency + $pdf->SetAlpha(0.3); $pdf->Cell($w - 20, 25, $outputlangs->convToOutputCharset($text), "", 2, "C", 0); + //antirotate $pdf->_out('Q'); $pdf->SetXY($savx, $savy); + + // Restore alpha + $pdf->SetAlpha(1); } From 57614cc4666cff48da6ea6c318927fccf40a816a Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 24 Oct 2024 13:59:02 +0200 Subject: [PATCH 023/178] FIX #31365 Bank - Card - Ref haven't max length in edit mode (#31533) --- htdocs/compta/bank/card.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 3c5b4534a1158..5f853b553bde6 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -1,13 +1,13 @@ - * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2004-2016 Laurent Destailleur - * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2014-2017 Alexandre Spangaro - * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2016 Marcos García - * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2022 Charlene Benke +/* Copyright (C) 2002-2003 Rodolphe Quiedeville + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2014-2024 Alexandre Spangaro + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2016 Marcos García + * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2022 Charlene Benke * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -950,7 +950,7 @@ // Ref print ''; - print ''; + print ''; // Label print ''; From 0d2f1cf666283aa71b3deaf9ec8b8400c2d65747 Mon Sep 17 00:00:00 2001 From: MDW Date: Thu, 24 Oct 2024 14:01:30 +0200 Subject: [PATCH 024/178] Qual: Fix phpstan notices (int expected) (#31485) # Qual: Fix phpstan notices (int expected) Fix several notices where int was expected (casting/phpdoc/GETPOSTINT). Separate phpstan exceptions for methods containing 'pdf' from other methods/functions. --- htdocs/bom/class/bom.class.php | 2 +- htdocs/core/ajax/box.php | 6 +++++- .../class/commonstickergenerator.class.php | 2 +- htdocs/core/class/infobox.class.php | 2 +- htdocs/core/lib/date.lib.php | 14 +++++++------- htdocs/core/lib/pdf.lib.php | 18 +++++++++--------- htdocs/mrp/mo_production.php | 2 +- htdocs/product/index.php | 3 ++- htdocs/projet/class/task.class.php | 4 ++-- phpstan.neon.dist | 6 ++---- scripts/emailings/mailing-send.php | 3 ++- 11 files changed, 33 insertions(+), 29 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index b3595c3b43f48..ac615c7875186 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1489,7 +1489,7 @@ public function calculateCosts() $reg = array(); $qtyhourservice = 0; if (preg_match('/^(\d+)([a-z]+)$/', $defaultdurationofservice, $reg)) { - $qtyhourservice = convertDurationtoHour((int) $reg[1], $reg[2]); + $qtyhourservice = convertDurationtoHour((float) $reg[1], $reg[2]); } if ($qtyhourservice) { diff --git a/htdocs/core/ajax/box.php b/htdocs/core/ajax/box.php index 1324096d3d534..5771e4edbe905 100644 --- a/htdocs/core/ajax/box.php +++ b/htdocs/core/ajax/box.php @@ -2,6 +2,7 @@ /* Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2007-2012 Laurent Destailleur * Copyright (C) 2024 Frédéric France + * 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 @@ -44,7 +45,10 @@ $boxid = GETPOSTINT('boxid'); $boxorder = GETPOST('boxorder'); -$zone = GETPOST('zone'); // Can be '0' or '1' or 'pagename'... +$zone = GETPOST('zone'); // Can be key for zone +if ($zone !== '') { + $zone = (int) $zone; +} $userid = GETPOSTINT('userid'); // Security check diff --git a/htdocs/core/class/commonstickergenerator.class.php b/htdocs/core/class/commonstickergenerator.class.php index ab048d5ab6a5c..bb7330e6eccf9 100644 --- a/htdocs/core/class/commonstickergenerator.class.php +++ b/htdocs/core/class/commonstickergenerator.class.php @@ -253,7 +253,7 @@ protected function _Croix(&$pdf, $x1 = 0, $y1 = 0, $x2 = 210, $y2 = 297, $epaiss * Convert units (in to mm, mm to in) * $src and $dest must be 'in' or 'mm' * - * @param int $value value + * @param float $value value * @param string $src from ('in' or 'mm') * @param string $dest to ('in' or 'mm') * @return float value value after conversion diff --git a/htdocs/core/class/infobox.class.php b/htdocs/core/class/infobox.class.php index f52675fa21968..e7579678d18a5 100644 --- a/htdocs/core/class/infobox.class.php +++ b/htdocs/core/class/infobox.class.php @@ -218,7 +218,7 @@ public static function listBoxes($dbs, $mode, $zone, $user = null, $excludelist * Save order of boxes for area and user * * @param DoliDB $dbs Database handler - * @param int $zone Name of area (0 for Homepage, ...) + * @param int $zone Key of area (0 for Homepage, ...) * @param string $boxorder List of boxes with correct order 'A:123,456,...-B:789,321...' * @param int $userid Id of user * @return int Return integer <0 if KO, 0=Nothing done, > 0 if OK diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 541cd56bd413a..df027a28200dd 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -116,7 +116,7 @@ function getServerTimeZoneInt($refgmtdate = 'now') * Add a delay to a date * * @param int $time Date timestamp (or string with format YYYY-MM-DD) - * @param int $duration_value Value of delay to add + * @param float $duration_value Value of delay to add * @param string $duration_unit Unit of added delay (d, m, y, w, h, i) * @param int $ruleforendofmonth Change the behavior of PHP over data-interval, 0 or 1 * @return int New timestamp @@ -128,16 +128,16 @@ function dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforend return $time; } if ($duration_unit == 's') { - return $time + ($duration_value); + return $time + (int) ($duration_value); } if ($duration_unit == 'i') { - return $time + (60 * $duration_value); + return $time + (int) (60 * $duration_value); } if ($duration_unit == 'h') { - return $time + (3600 * $duration_value); + return $time + (int) (3600 * $duration_value); } if ($duration_unit == 'w') { - return $time + (3600 * 24 * 7 * $duration_value); + return $time + (int) (3600 * 24 * 7 * $duration_value); } $deltastring = 'P'; @@ -327,9 +327,9 @@ function convertSecondToTime($iSecond, $format = 'all', $lengthOfDay = 86400, $l /** Convert duration to hour * - * @param int $duration_value Duration value + * @param float $duration_value Duration value * @param string $duration_unit Duration unit - * @return int $result + * @return float $result */ function convertDurationtoHour($duration_value, $duration_unit) { diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 57b026a2e8c90..38539b4c7acfd 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1009,7 +1009,7 @@ function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, * @param ?Societe $fromcompany Object company * @param int $marge_basse Margin bottom we use for the autobreak * @param int $marge_gauche Margin left (no more used) - * @param int $page_hauteur Page height + * @param float $page_hauteur Page height * @param CommonObject $object Object shown in PDF * @param int<0,3> $showdetails Show company address details into footer (0=Nothing, 1=Show address, 2=Show managers, 3=Both) * @param int $hidefreetext 1=Hide free text, 0=Show free text @@ -1424,8 +1424,8 @@ function pdf_writeLinkedObjects(&$pdf, $object, $outputlangs, $posx, $posy, $w, * @param Translate $outputlangs Object lang for output * @param int $w Width * @param int $h Height - * @param int $posx Pos x - * @param int $posy Pos y + * @param float $posx Pos x + * @param float $posy Pos y * @param int<0,1> $hideref Hide reference * @param int<0,1> $hidedesc Hide description * @param int<0,1> $issupplierline Is it a line for a supplier object ? @@ -2542,9 +2542,9 @@ function pdf_getLinkedObjects(&$object, $outputlangs) $refListsTxt = ''; if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { - $refListsTxt.= $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :'; + $refListsTxt .= $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :'; } else { - $refListsTxt.=$outputlangs->transnoentities("RefSending").' :'; + $refListsTxt .= $outputlangs->transnoentities("RefSending").' :'; } // We concat this record info into fields xxx_value. title is overwrote. foreach ($objects as $elementobject) { @@ -2559,12 +2559,12 @@ function pdf_getLinkedObjects(&$object, $outputlangs) } } } - $refListsTxt.= (!empty($refListsTxt)?' ':''); + $refListsTxt .= (!empty($refListsTxt) ? ' ' : ''); if (! is_object($order)) { - $refListsTxt.= $outputlangs->transnoentities($elementobject->ref); + $refListsTxt .= $outputlangs->transnoentities($elementobject->ref); } else { - $refListsTxt.= $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''); - $refListsTxt.= ' / '.$outputlangs->transnoentities($elementobject->ref); + $refListsTxt .= $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''); + $refListsTxt .= ' / '.$outputlangs->transnoentities($elementobject->ref); } } diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 95b670ec03079..e6aaf448e6e94 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -1003,7 +1003,7 @@ $reg = []; $qtyhourservice = 0; if (preg_match('/^(\d+)([a-z]+)$/', $tmpproduct->duration, $reg)) { - $qtyhourservice = convertDurationtoHour((int) $reg[1], (string) $reg[2]); + $qtyhourservice = convertDurationtoHour((float) $reg[1], (string) $reg[2]); } $qtyhourforline = 0; if ($line->fk_unit) { diff --git a/htdocs/product/index.php b/htdocs/product/index.php index 50b78c18ae6de..6a98d84eedcfc 100644 --- a/htdocs/product/index.php +++ b/htdocs/product/index.php @@ -7,6 +7,7 @@ * Copyright (C) 2019 Pierre Ardoin * Copyright (C) 2019-2024 Frédéric France * Copyright (C) 2019 Nicolas ZABOURI + * 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 @@ -332,7 +333,7 @@ $sql .= $db->plimit($max, 0); //print $sql; - $lastmodified=""; + $lastmodified = ""; $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index dd89d8023d532..6613ada99f317 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -83,12 +83,12 @@ class Task extends CommonObjectLine public $description; /** - * @var float|'' total of time spent on this task + * @var int|'' total of time spent on this task (in seconds) */ public $duration_effective; /** - * @var float|'' planned workload + * @var int|'' planned workload (in seconds) */ public $planned_workload; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ed685c31da3f9..96c88e5e9cc0a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -82,11 +82,9 @@ parameters: - '#EvalMath::trigger\(\) expects string, int given#' - '# Diff::generatePartialDiff\(\) expects array#' - '# EmailCollector::getpart\(\) expects string#' - - '#(?:convertSecondToTime) expects int, float\|string given#' - - '#(?:Comm(?:(?:ande::updateline|on(?:Invoice::getLibStatut|StickerGenerator::(?:Set_Char_Size|_Croix|convertMetric)))\(\))|Facture(?:(?:::update|FournisseurRec::add)line\(\))|(?:Holiday::addLogCP|Loan::getLibStatut|SupplierProposal::updateline)\(\)|c(?:alcul_price_total|onvert(?:DurationtoHour|SecondToTime))|dol_time_plus_duree|pdf_(?:azur::_tableau_(?:(?:info|tot)\(\))|ban(?:::_tableau\(\)|k)|c(?:anelle::_tableau_(?:(?:tot|versements)\(\))|ornas::_tableau_(?:(?:info|tot)\(\))|rabe::_tableau_(?:(?:info|tot|versements)\(\))|yan::draw(?:(?:Info|Total)Table\(\)))|e(?:agle(?:(?:::_tableau_tot|_proforma::drawTotalTable)\(\))|instein::_tableau_(?:(?:info|tot)\(\))|ratosthene::draw(?:(?:Info|Total)Table\(\))|spadon::_tableau_tot\(\))|muscadet::_tableau_(?:(?:info|tot)\(\))|octopus::(?:_table(?:(?:FirstPage|au)\(\))|draw(?:(?:Info|Total)Table\(\)))|page(?:foot|head)|(?:rouget::_tableau_tot|s(?:epamandate::_tableau(?:_info)?|ponge::draw(?:(?:Info|Total)Table)|quille::_tableau_tot|t(?:andard_(?:e(?:(?:valuation|xpensereport)::_tableau|xpensereport::tablePayments)|(?:myobjec|supplierpaymen)t::_tableau|supplierpayment::_tableau_cheque)|orm::_tableau_info|rato::tabSignature))|t(?:cpdflabel::writeBarcode|yphon::_tableau_info)|vinci::_tableau_info)\(\)|w(?:atermark|rite(?:LinkedObjects|linedesc))|zenith::_tableau_tot\(\))|usleep) expects int, float given\.#' - + - '#(?:(?:CommonStickerGenerator::_Croix|pdf_(?:azur::_tableau_(?:info|tot)|ban::_tableau))\(\)|pdf_(?:bank|c(?:anelle::_tableau_(?:(?:tot|versements)\(\))|ornas::_tableau_(?:(?:info|tot)\(\))|rabe::_tableau_(?:(?:info|tot|versements)\(\))|yan::draw(?:(?:Info|Total)Table\(\)))|e(?:agle(?:(?:::_tableau_tot|_proforma::drawTotalTable)\(\))|instein::_tableau_(?:(?:info|tot)\(\))|ratosthene::draw(?:(?:Info|Total)Table\(\))|spadon::_tableau_tot\(\))|muscadet::_tableau_(?:(?:info|tot)\(\))|octopus::(?:_table(?:(?:FirstPage|au)\(\))|draw(?:(?:Info|Total)Table\(\)))|page(?:foot|head)|(?:rouget::_tableau_tot|s(?:epamandate::_tableau(?:_info)?|ponge::draw(?:(?:Info|Total)Table)|quille::_tableau_tot|t(?:andard_(?:e(?:(?:valuation|xpensereport)::_tableau|xpensereport::tablePayments)|(?:myobjec|supplierpaymen)t::_tableau|supplierpayment::_tableau_cheque)|orm::_tableau_info|rato::tabSignature))|t(?:cpdflabel::writeBarcode|yphon::_tableau_info)|vinci::_tableau_info)\(\)|w(?:atermark|rite(?:LinkedObjects|linedesc))|zenith::_tableau_tot\(\))) expects int, float given\.#' + - '#(?:Comm(?:(?:ande::updateline|on(?:Invoice::getLibStatut|StickerGenerator::Set_Char_Size))\(\))|Facture(?:(?:::update|FournisseurRec::add)line\(\))|(?:Holiday::addLogCP|Loan::getLibStatut|SupplierProposal::updateline)\(\)|calcul_price_total) expects int, float given\.#' - '#(?:dol_(?:mktime|remove_file_process)|fetchObjectByElement|print_actions_filter) expects int, array\|string given\.#' - - '# (CSMSFile) constructor expects int, array\|string given.#' - '#(?:ProductFournisseur::logPrice\(\)) expects float\|null#' - '#(?:(?:Asset::addDepreciationL|Facture(?:(?:(?:Fournisseur)?::add|Fournisseur::update)l))ine\(\)|calcul_price_total|dol_convertToWord|(?:loanCalcMonthlyPaymen|print_paypal_redirec)t) expects float, string given.#' diff --git a/scripts/emailings/mailing-send.php b/scripts/emailings/mailing-send.php index 6e32dd68085dd..85b097ed3d9a9 100755 --- a/scripts/emailings/mailing-send.php +++ b/scripts/emailings/mailing-send.php @@ -6,6 +6,7 @@ * Copyright (C) 2005-2016 Regis Houssin * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2024 Frédéric France + * 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 @@ -396,7 +397,7 @@ } if (getDolGlobalInt('MAILING_DELAY')) { - usleep((float) getDolGlobalInt('MAILING_DELAY') * 1000000); + usleep((int) ((float) getDolGlobalInt('MAILING_DELAY') * 1000000)); } } } else { From 2b0859cbe46a2c86ccb5d7dfe2a4b3868b770dd1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Oct 2024 14:13:25 +0200 Subject: [PATCH 025/178] Trans --- htdocs/admin/system/security.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 9671d5a682858..4ba48e8314506 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -121,7 +121,7 @@ print "PHP short_open_tag = ".((empty(ini_get('short_open_tag')) || ini_get('short_open_tag') == 'Off') ? img_picto('', 'tick').' '.yn(0) : img_warning().' '.yn(1)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No")).')'."
\n"; -print "PHP allow_url_fopen = ".(ini_get('allow_url_fopen') ? img_picto($langs->trans("YouShouldSetThisToOff"), 'warning').' '.ini_get('allow_url_fopen') : yn(0)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No"))." but may be required by some external modules)
\n"; +print "PHP allow_url_fopen = ".(ini_get('allow_url_fopen') ? img_picto($langs->trans("YouShouldSetThisToOff"), 'warning').' '.ini_get('allow_url_fopen') : yn(0)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No")).", except if Yes is required by some external modules)
\n"; print "PHP allow_url_include = ".(ini_get('allow_url_include') ? img_picto($langs->trans("YouShouldSetThisToOff"), 'warning').' '.ini_get('allow_url_include') : img_picto('', 'tick').' '.yn(0)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No")).")
\n"; //print "PHP safe_mode = ".(ini_get('safe_mode') ? ini_get('safe_mode') : yn(0)).'   '.$langs->trans("Deprecated")." (removed in PHP 5.4)
\n"; From 808d5ee16901c6f6aeed742cf244f2cb10ebcd0a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Oct 2024 15:34:02 +0200 Subject: [PATCH 026/178] NEW Add a tool to decrypt data encrypted in database. --- htdocs/admin/system/security.php | 36 ++++++++++++++++++++++++++++---- htdocs/core/lib/security.lib.php | 7 +++++-- htdocs/langs/en_US/admin.lang | 5 +++++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 4ba48e8314506..67b69d3149d95 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -662,8 +662,24 @@ print 'MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE = '.getDolGlobalString('MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': 1)
'; print '
'; +print 'MAIN_SECURITY_ANTI_SSRF_SERVER_IP = '.getDolGlobalString('MAIN_SECURITY_ANTI_SSRF_SERVER_IP', ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': List of static IPs of server separated with coma - '.$langs->trans("Note").': common loopback ip like 127.*.*.*, [::1] are already added)')."
"; +print '
'; + +print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.getDolGlobalString('MAIN_SECURITY_CSRF_WITH_TOKEN', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 2)'."
"; + +print ''; + + +print '
'; +print '
'; + + +print load_fiche_titre($langs->trans("DatabaseEncryption"), '', 'folder'); + +print '
'; + //print ''.$langs->trans("PasswordEncryption").': '; -print 'MAIN_SECURITY_HASH_ALGO = '.getDolGlobalString('MAIN_SECURITY_HASH_ALGO', ''.$langs->trans("Undefined").'')."   "; +print ''.$langs->trans("AlgorithmFor", $langs->transnoentitiesnoconv("Passwords")).' (non reversible encryption, defined into MAIN_SECURITY_HASH_ALGO) = '.getDolGlobalString('MAIN_SECURITY_HASH_ALGO', ''.$langs->trans("Undefined").'')."   "; if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO')) { print '     (If unset: \'md5\')'; } @@ -683,10 +699,22 @@ } print '
'; -print 'MAIN_SECURITY_ANTI_SSRF_SERVER_IP = '.getDolGlobalString('MAIN_SECURITY_ANTI_SSRF_SERVER_IP', ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': List of static IPs of server separated with coma - '.$langs->trans("Note").': common loopback ip like 127.*.*.*, [::1] are already added)')."
"; -print '
'; +$action = GETPOST('action'); +$exampletodecrypt = GETPOST('exampletodecrypt', 'password'); -print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.getDolGlobalString('MAIN_SECURITY_CSRF_WITH_TOKEN', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 2)'."
"; +print ''.$langs->trans("AlgorithmFor", $langs->transnoentitiesnoconv("SensitiveData")).' (reversible encryption done with dolEncrypt/dolDecrypt) = '.constant('MAIN_SECURITY_REVERSIBLE_ALGO').' with key defined into conf.php file in $dolibarr_main_instance_unique_id
'; +print '
'; +print ''; +print ''; +print ''; +print $langs->trans("ToolToDecryptAString").': '; +print ''; +print ''; +if ($action == 'doldecrypt' && $user->admin && $exampletodecrypt) { + usleep(200); + print ' => '; +} +print ''; print '
'; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index ec6de2992d2a5..1f1cb081421fd 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -107,6 +107,9 @@ function dolGetRandomBytes($length) return bin2hex(openssl_random_pseudo_bytes((int) floor($length / 2))); // the bin2hex will double the number of bytes so we take length / 2. May be very slow on Windows. } + +define('MAIN_SECURITY_REVERSIBLE_ALGO', 'AES-256-CTR'); + /** * Encode a string with a symmetric encryption. Used to encrypt sensitive data into database. * Note: If a backup is restored onto another instance with a different $conf->file->instance_unique_id, then decoded value will differ. @@ -120,7 +123,7 @@ function dolGetRandomBytes($length) * @since v17 * @see dolDecrypt(), dol_hash() */ -function dolEncrypt($chain, $key = '', $ciphering = 'AES-256-CTR', $forceseed = '') +function dolEncrypt($chain, $key = '', $ciphering = '', $forceseed = '') { global $conf; global $dolibarr_disable_dolcrypt_for_debug; @@ -139,7 +142,7 @@ function dolEncrypt($chain, $key = '', $ciphering = 'AES-256-CTR', $forceseed = $key = $conf->file->instance_unique_id; } if (empty($ciphering)) { - $ciphering = 'AES-256-CTR'; + $ciphering = constant('MAIN_SECURITY_REVERSIBLE_ALGO'); } $newchain = $chain; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index bcfebcbc286f5..feb598ef0c909 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2576,3 +2576,8 @@ YouHaveALargeAmountOfRecordOnLists=You have a default max size for lists set to RoundBorders=Round borders CheckIfModuleIsNotBlackListed=Block install for modules found into the Remote blacklist CheckIfModuleIsNotBlackListedHelp=Some modules may be provided by some companies that do not respect the project's rules of goodwill (non-compliance with GDPR, violation of the rules tof use the Dolibarr brand name, etc.). By checking this box, a request will be made to the project server to see if a report was received about this module, and will protect you by blocking the deployment of flagged modules +DatabaseEncryption=Encryption in database +AlgorithmFor=Algorithm for: %s +SensitiveData=Sensitive data +ToolToDecryptAString=Tool to decrypt a string +Decrypt=Decrypt From 9499292bad08113e7df8160eb88a0ea99a872e63 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Oct 2024 16:21:58 +0200 Subject: [PATCH 027/178] Debug hidden feature --- htdocs/langs/en_US/products.lang | 2 +- htdocs/product/document.php | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 5ea5e979b7150..25080796a91c0 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -312,7 +312,7 @@ GlobalVariableUpdaterHelpFormat1=Format for request is {"URL": "http://example.c UpdateInterval=Update interval (minutes) LastUpdated=Latest update CorrectlyUpdated=Correctly updated -PropalMergePdfProductActualFile=Files use to add into PDF Azur are/is +PropalMergePdfProductActualFile=PDF file to include into the PDF proposals if the product is part of the proposal... PropalMergePdfProductChooseFile=Select PDF files IncludingProductWithTag=Including products/services with the tag DefaultPriceRealPriceMayDependOnCustomer=Default price, real price may depend on customer diff --git a/htdocs/product/document.php b/htdocs/product/document.php index 3caedef6f8f55..1810189307da6 100644 --- a/htdocs/product/document.php +++ b/htdocs/product/document.php @@ -25,7 +25,7 @@ /** * \file htdocs/product/document.php * \ingroup product - * \brief Page des documents joints sur les produits + * \brief Page of documents attached to products/services */ @@ -211,7 +211,7 @@ llxHeader('', $title, $helpurl, '', 0, 0, '', '', '', 'mod-product page-card_document'); -if ($object->id) { +if ($object->id > 0) { $head = product_prepare_head($object); $titre = $langs->trans("CardProduct".$object->type); $picto = ($object->type == Product::TYPE_SERVICE ? 'service' : 'product'); @@ -317,14 +317,15 @@ print Form::selectarray('lang_id', $langs_available, $default_lang, 0, 0, 0, '', 0, 0, 0, 'ASC'); if (getDolGlobalInt('MAIN_MULTILANGS')) { - print ''; + print ''; } print '
'; } foreach ($filearray as $filetoadd) { - if ($ext = pathinfo($filetoadd['name'], PATHINFO_EXTENSION) == 'pdf') { + $ext = pathinfo($filetoadd['name'], PATHINFO_EXTENSION); + if ($ext == 'pdf') { $checked = ''; $filename = $filetoadd['name']; From 58cbfa8c877f51fe0111cb0dbd496d22d013e1cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Oct 2024 17:59:35 +0200 Subject: [PATCH 028/178] FIX Edit a link --- htdocs/core/class/html.formfile.class.php | 3 +-- htdocs/core/class/link.class.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index de999b305bb2d..8cf0dc801cebb 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -2153,11 +2153,10 @@ public function listOfLinks($object, $permissiontodelete = 1, $action = null, $s if ($nboflinks > 0) { include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; } - foreach ($links as $link) { print ''; //edit mode - if ($action == 'update' && $selected === $link->id) { + if ($action == 'update' && $selected === (int) $link->id) { print ''; + if (!empty($options)) { + $out .= ''; } + $out .= ''; + $out .= ''; + } - $parameters = array('socid' => (isset($GLOBALS['socid']) ? $GLOBALS['socid'] : ''), 'id' => (isset($GLOBALS['id']) ? $GLOBALS['id'] : ''), 'url' => $url, 'perm' => $perm, 'options' => $options); - $res = $hookmanager->executeHooks('formattachOptionsUpload', $parameters, $object); - if (empty($res)) { - $out = '
'.$out.'
'; + $out .= "
'.$langs->trans("Label").'
name).'">
'.$langs->trans("Bank").'
'.$langs->trans("Ref").'
'.$langs->trans("Label").'
'; print ''; print ''; diff --git a/htdocs/core/class/link.class.php b/htdocs/core/class/link.class.php index 34f05db4c1152..8ea08e7d52a6a 100644 --- a/htdocs/core/class/link.class.php +++ b/htdocs/core/class/link.class.php @@ -254,7 +254,7 @@ public function fetchAll(&$links, $objecttype, $objectid, $sortfield = null, $so if ($num > 0) { while ($obj = $this->db->fetch_object($resql)) { $link = new Link($this->db); - $link->id = $obj->rowid; + $link->id = (int) $obj->rowid; $link->entity = $obj->entity; $link->datea = $this->db->jdate($obj->datea); $link->url = $obj->url; From 19e35af0c3e6dccc9c61ef36e14ad7f17d276c27 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Oct 2024 18:05:46 +0200 Subject: [PATCH 029/178] NEW Content of tab "attached files" is more compact. --- htdocs/core/class/html.formfile.class.php | 137 +++++++++++------- htdocs/core/tpl/ajaxrow.tpl.php | 16 +- .../tpl/document_actions_post_headers.tpl.php | 28 +++- htdocs/theme/eldy/global.inc.php | 3 + 4 files changed, 118 insertions(+), 66 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 59001843f2dde..81332c18e91f9 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -91,7 +91,7 @@ public function __construct($db) * @param int<0,1> $capture 1=Add tag capture="capture" to force use of micro or video recording to generate file. When setting this to 1, you must also provide a value for $accept. * @param int<0,1> $disablemulti 0=Default, 1=Disable multiple file upload * @param int<0,1> $nooutput 0=Output result with print, 1=Return result - * @return int|string Return integer <0 if KO, >0 if OK, or string if $noouput=1 + * @return int|string|array Return integer <0 if KO, >0 if OK, or string if $noouput=1 or array if $nooutput=2 */ public function form_attach_new_file($url, $title = '', $addcancel = 0, $sectionid = 0, $perm = 1, $size = 50, $object = null, $options = '', $useajax = 1, $savingdocmask = '', $linkfiles = 1, $htmlname = 'formuserfile', $accept = '', $sectiondir = '', $usewithoutform = 0, $capture = 0, $disablemulti = 0, $nooutput = 0) { @@ -126,13 +126,16 @@ public function form_attach_new_file($url, $title = '', $addcancel = 0, $section } } - $out = "\n\n".'
'."\n"; + // Section to generate the form to upload a new file + $out = "\n".'
'."\n"; - if (empty($title)) { - $title = $langs->trans("AttachANewFile"); - } - if ($title != 'none') { - $out .= load_fiche_titre($title, '', ''); + if ($nooutput != 2) { + if (empty($title)) { + $title = $langs->trans("AttachANewFile"); + } + if ($title != 'none') { + $out .= load_fiche_titre($title, '', ''); + } } if (empty($usewithoutform)) { // Try to avoid this and set instead the form by the caller. @@ -227,62 +230,79 @@ public function form_attach_new_file($url, $title = '', $addcancel = 0, $section } } - $out .= "\n
\n"; + $parameters = array('socid' => (isset($GLOBALS['socid']) ? $GLOBALS['socid'] : ''), 'id' => (isset($GLOBALS['id']) ? $GLOBALS['id'] : ''), 'url' => $url, 'perm' => $perm, 'options' => $options); + $res = $hookmanager->executeHooks('formattachOptionsUpload', $parameters, $object); + if (empty($res)) { + $out = '
'.$out.'
'; + } + $out .= $hookmanager->resPrint; + + $out .= "\n
\n"; + + $out2 = ""; + + // Section to generate the form to upload a new file if ($linkfiles) { - $out .= "\n".'
'."\n"; + $out2 .= "\n".'
'."\n"; $langs->load('link'); - $title = $langs->trans("LinkANewFile"); - $out .= load_fiche_titre($title, '', ''); + + if ($nooutput != 2) { + $title = $langs->trans("LinkANewFile"); + $out2 .= load_fiche_titre($title, '', ''); + } if (empty($usewithoutform)) { - $out .= '
'.$options.''; + $out .= ' '; + $out .= ''; + $out .= '
"; + + if (empty($usewithoutform)) { + $out .= ''; + if (empty($sectionid)) { + $out .= '
'; } - $out .= $hookmanager->resPrint; + } - $out .= "\n\n"; + $parameters = array('socid' => (isset($GLOBALS['socid']) ? $GLOBALS['socid'] : ''), 'id' => (isset($GLOBALS['id']) ? $GLOBALS['id'] : ''), 'url' => $url, 'perm' => $perm, 'options' => $options); + $res = $hookmanager->executeHooks('formattachOptionsUpload', $parameters, $object); + if (empty($res)) { + $out = '
'.$out.'
'; + } + $out .= $hookmanager->resPrint; + $out .= "\n\n"; - $out2 = ""; - // Section to generate the form to upload a new file - if ($linkfiles) { - $out2 .= "\n".'
'."\n"; - $langs->load('link'); + $out2 = ""; - if ($nooutput != 2) { - $title = $langs->trans("LinkANewFile"); - $out2 .= load_fiche_titre($title, '', ''); - } + // Section to generate the form to upload a new file + if ($linkfiles) { + $out2 .= "\n".'
'."\n"; + $langs->load('link'); - if (empty($usewithoutform)) { - $out2 .= '