diff --git a/ChangeLog b/ChangeLog
index a5d8b7c967e..0458780eeab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -254,6 +254,44 @@ The following changes may create regressions for some external modules, but were
* A very high number of class properties (with old name in french) are now deprecated in favor of the property name in english.
+***** ChangeLog for 18.0.4 compared to 18.0.3 *****
+FIX: $this->newref already exists and could have been modified by trigger but we still use a local variable for the filesystem-based renaming
+FIX: 16.0 only, backport fix for SQL error on global search product
+FIX: #25399 (#26694)
+FIX: #25458 intervention localizations (backport v17) (#26757)
+FIX: #26518
+FIX: #26536 Accountancy - Balance - Not divided lines by label & account, only by account (#26547)
+FIX: #26553 Supplier invoice - Do not display the delete button for reconciled payment (#26554)
+FIX: #26735
+FIX: #26994
+FIX: Accountancy - Possibility to write in bookkeeping expense report operation with some line not bound (#26545)
+FIX: add display of an error when attempting to delete a committed transaction (#26573)
+FIX: avoid warning : Cannot use a scalar value as an array (#26437)
+FIX: backport SQL error on global search product
+FIX: # Bug Estimated Stock at date value in V14 (#26479)
+FIX: commande context (#26497)
+FIX: delivery note disappear after generation
+FIX: double hook and paging search param in product list (#26767)
+FIX: Email reminder template must not be visible when option is off
+FIX: escape HTML tags in return value of getFullName() (#26735)
+FIX: Fix set private note (#26610)
+FIX: Fix when options FAC_FORCE_DATE_VALIDATION and INVOICE_CHECK_POSTERIOR_DATE enabled. The date is forced after the test and not before
+FIX: menu auguria
+FIX: pagination parameters on save and cancel buttons (#26605)
+FIX: pdf cornas page head multicell width (backport v17)
+FIX: php8 fatal on edit supplier order when multicurrency is activated (#26758)
+FIX: possible inconsistency between llx_ecm_files and file system when BILL_SUPPLIER_VALIDATES changes ref
+FIX: regression on planned bank entries (#26556)
+FIX: Social contribution - Payment list - Wrong information in type column (#26561)
+FIX: special_code update line keep old value. (#26819)
+FIX: substitute project variables in invoice documents (#26445)
+FIX: Test on permission for holiday tooltips
+FIX: v17: Param $notrigger in $societe->create() causes method to return true regardless of actual result of database functions (#26499)
+FIX: v18 SQL error in llx_c_forme_juridique.sql when installing
+FIX: Warehouse Global Amounts not displayed (#26478)
+FIX: warning param $lineID getSpecialCode is negatif (#26826)
+FIX: warning php8.2 undefined_array_key (#26830)
+
***** ChangeLog for 18.0.3 compared to 18.0.2 *****
FIX: #25793 Cannot add time spent (#26405)
FIX: #26100 Ticket - On edit, list of closed project must be excluded (#26223)
diff --git a/dev/initdata/purge-data.php b/dev/initdata/purge-data.php
index d75c9fae8b2..442d991a453 100755
--- a/dev/initdata/purge-data.php
+++ b/dev/initdata/purge-data.php
@@ -148,8 +148,8 @@ $sqls=array(
"DELETE FROM ".MAIN_DB_PREFIX."product where datec < '__DATE__'",
),
'project'=>array(
- // TODO set fk_project to null on object that refer to project
- "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time WHERE fk_task IN (select rowid FROM ".MAIN_DB_PREFIX."projet_task WHERE fk_projet IN (select rowid FROM ".MAIN_DB_PREFIX."projet where datec < '__DATE__'))",
+ // TODO set fk_project to null on all objects/tables that refer to project
+ "DELETE FROM ".MAIN_DB_PREFIX."element_time WHERE elementtype = 'task' AND fk_element IN (select rowid FROM ".MAIN_DB_PREFIX."projet_task WHERE fk_projet IN (select rowid FROM ".MAIN_DB_PREFIX."projet where datec < '__DATE__'))",
"DELETE FROM ".MAIN_DB_PREFIX."projet_task WHERE fk_projet IN (select rowid FROM ".MAIN_DB_PREFIX."projet where datec < '__DATE__')",
"DELETE FROM ".MAIN_DB_PREFIX."projet where datec < '__DATE__'",
),
diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php
index c92d0032176..245e011d6bc 100644
--- a/htdocs/admin/company.php
+++ b/htdocs/admin/company.php
@@ -84,6 +84,11 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha'))
$s = $mysoc->country_id.':'.$mysoc->country_code.':'.$mysoc->country_label;
dolibarr_set_const($db, "MAIN_INFO_SOCIETE_COUNTRY", $s, 'chaine', 0, '', $conf->entity);
+ if($mysoc->country_code == 'FR' && !isset($conf->global->MAIN_PROFID1_IN_ADDRESS)){
+ // For FR, default value of option to show profid SIREN is on by default
+ $res = dolibarr_set_const($db, "MAIN_PROFID1_IN_ADDRESS", 1, 'chaine', 0, '', $conf->entity);
+ }
+
activateModulesRequiredByCountry($mysoc->country_code);
}
diff --git a/htdocs/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php
index 4b9ccda6b09..658543e68c3 100644
--- a/htdocs/bom/class/api_boms.class.php
+++ b/htdocs/bom/class/api_boms.class.php
@@ -559,7 +559,7 @@ class Boms extends DolibarrApi
*
* @return void
*/
- private function checkRefNumbering(): void
+ private function checkRefNumbering()
{
$ref = substr($this->bom->ref, 1, 4);
if ($this->bom->status > 0 && $ref == 'PROV') {
diff --git a/htdocs/bom/tpl/linkedobjectblock.tpl.php b/htdocs/bom/tpl/linkedobjectblock.tpl.php
index d00340a1322..082936be50a 100644
--- a/htdocs/bom/tpl/linkedobjectblock.tpl.php
+++ b/htdocs/bom/tpl/linkedobjectblock.tpl.php
@@ -62,7 +62,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) {
$product_static->getNomUrl(1);
}
print '';
- echo '
'.dol_print_date($objectlink->date_creation, 'day').' | ';
+ echo ''.dol_print_date($objectlink->date_creation, 'day').' | ';
echo '';
if ($user->hasRight('commande', 'lire')) {
$total = $total + $objectlink->total_ht;
diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php
index 652f60552ff..5e403dff7a8 100644
--- a/htdocs/comm/action/list.php
+++ b/htdocs/comm/action/list.php
@@ -575,6 +575,7 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
/* The fast and low memory method to get and count full list converts the sql into a sql count */
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
+
$resql = $db->query($sqlforcount);
if ($resql) {
$objforcount = $db->fetch_object($resql);
diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php
index 5b10b742d87..4ac22405287 100644
--- a/htdocs/compta/bank/class/account.class.php
+++ b/htdocs/compta/bank/class/account.class.php
@@ -701,6 +701,15 @@ class Account extends CommonObject
}
// Load librairies to check BAN
+ $balance = $this->balance;
+ if (empty($balance) && !empty($this->solde)) {
+ $balance = $this->solde;
+ }
+ if (empty($balance)) {
+ $balance = 0;
+ }
+
+ // Load the library to validate/check a BAN account
require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
$now = dol_now();
@@ -779,7 +788,7 @@ class Account extends CommonObject
$accline = new AccountLine($this->db);
$accline->datec = $now;
$accline->label = '('.$langs->trans("InitialBankBalance").')';
- $accline->amount = price2num($this->solde);
+ $accline->amount = price2num($balance);
$accline->fk_user_author = $user->id;
$accline->fk_account = $this->id;
$accline->datev = $this->date_solde;
diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
index d58a1cf15d4..055cede7593 100644
--- a/htdocs/compta/facture/list.php
+++ b/htdocs/compta/facture/list.php
@@ -925,6 +925,7 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
/* The fast and low memory method to get and count full list converts the sql into a sql count */
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
+
$resql = $db->query($sqlforcount);
if ($resql) {
$objforcount = $db->fetch_object($resql);
@@ -932,7 +933,7 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
} else {
dol_print_error($db);
}
-
+
if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
$page = 0;
$offset = 0;
diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php
index 9e45515a15e..940a4f09a6d 100644
--- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php
+++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php
@@ -6,6 +6,7 @@
* Copyright (C) 2015 Marcos García
* Copyright (C) 2017 Ferran Marcet
* Copyright (C) 2018-2022 Frédéric France
+ * Copyright (C) 2023 William Mead
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1197,9 +1198,9 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$pdf->SetTextColor(0, 0, 60);
$pdf->SetFont('', 'B', $default_font_size + 3);
- $w = 100;
+ $w = 110;
- $posx = $this->page_largeur - $this->marge_droite - 100;
+ $posx = $this->page_largeur - $this->marge_droite - $w;
$posy = $this->marge_haute;
$pdf->SetXY($this->marge_gauche, $posy);
diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php
index 98f5c15c5ce..87127b34010 100644
--- a/htdocs/fourn/class/api_supplier_invoices.class.php
+++ b/htdocs/fourn/class/api_supplier_invoices.class.php
@@ -235,7 +235,7 @@ class SupplierInvoices extends DolibarrApi
}
if ($this->invoice->create(DolibarrApiAccess::$user) < 0) {
- throw new RestException(500, "Error creating order", array_merge(array($this->invoice->error), $this->invoice->errors));
+ throw new RestException(500, "Error creating invoice ", array_merge(array($this->invoice->error), $this->invoice->errors));
}
return $this->invoice->id;
}
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index 05f91cdb6af..65a00f8affc 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -1916,19 +1916,18 @@ class FactureFournisseur extends CommonInvoice
// We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
$oldref = dol_sanitizeFileName($this->ref);
- $newref = dol_sanitizeFileName($num);
$dirsource = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$oldref;
- $dirdest = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$newref;
+ $dirdest = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$this->newref;
if (!$error && file_exists($dirsource)) {
dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest);
if (@rename($dirsource, $dirdest)) {
dol_syslog("Rename ok");
- // Rename docs starting with $oldref with $newref
- $listoffiles = dol_dir_list($conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
+ // Rename docs starting with $oldref with $this->newref
+ $listoffiles = dol_dir_list($conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$this->newref, 'files', 1, '^'.preg_quote($oldref, '/'));
foreach ($listoffiles as $fileentry) {
$dirsource = $fileentry['name'];
- $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
+ $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $this->newref, $dirsource);
$dirsource = $fileentry['path'].'/'.$dirsource;
$dirdest = $fileentry['path'].'/'.$dirdest;
@rename($dirsource, $dirdest);
diff --git a/htdocs/install/mysql/data/llx_c_forme_juridique.sql b/htdocs/install/mysql/data/llx_c_forme_juridique.sql
index f17ba7b1b21..fd094e387ef 100644
--- a/htdocs/install/mysql/data/llx_c_forme_juridique.sql
+++ b/htdocs/install/mysql/data/llx_c_forme_juridique.sql
@@ -110,7 +110,7 @@ insert into llx_c_forme_juridique (fk_pays, code, libelle) values (2, '229', 'VS
-- France: Catégories niveau II - Extrait de https://www.insee.fr/fr/information/2028129 - Dernière mise à jour Septembre 2022
-insert into llx_c_forme_juridique (fk_pays, code, libelle) values (1,'00','Organisme de placement collectif en valeurs mobilières sans personnalité morale');
+insert into llx_c_forme_juridique (fk_pays, code, libelle) values (1,'09','Organisme de placement collectif en valeurs mobilières sans personnalité morale');
insert into llx_c_forme_juridique (fk_pays, code, libelle) values (1,'10','Entrepreneur individuel');
insert into llx_c_forme_juridique (fk_pays, code, libelle) values (1,'21','Indivision');
insert into llx_c_forme_juridique (fk_pays, code, libelle) values (1,'22','Société créée de fait');
diff --git a/htdocs/langs/en_US/recruitment.lang b/htdocs/langs/en_US/recruitment.lang
index d46ddaf389a..50085bd578f 100644
--- a/htdocs/langs/en_US/recruitment.lang
+++ b/htdocs/langs/en_US/recruitment.lang
@@ -79,3 +79,4 @@ WeAreRecruiting=We are recruiting. This is a list of open positions to be filled
NoPositionOpen=No positions open at the moment
ConfirmClose=Confirm cancellation
ConfirmCloseAsk=Are you sure you want to cancel this recruitment candidature
+recruitment=Recruitment
diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php
index 4e19a517e6c..a2e5d7fd27b 100644
--- a/htdocs/master.inc.php
+++ b/htdocs/master.inc.php
@@ -219,10 +219,6 @@ if (!defined('NOREQUIREDB') && !defined('NOREQUIRESOC')) {
// For DE, we need to invert our address with customer address
$conf->global->MAIN_INVERT_SENDER_RECIPIENT = 1;
}
- if ($mysoc->country_code == 'FR' && !isset($conf->global->MAIN_PROFID1_IN_ADDRESS)) {
- // For FR, default value of option to show profid SIRET is on by default. Decret n°2099-1299 2022-10-07
- $conf->global->MAIN_PROFID1_IN_ADDRESS = 1;
- }
if ($mysoc->country_code == 'FR' && !isset($conf->global->INVOICE_CATEGORY_OF_OPERATION)) {
// For FR, default value of option to show category of operations is on by default. Decret n°2099-1299 2022-10-07
$conf->global->INVOICE_CATEGORY_OF_OPERATION = 1;
@@ -249,6 +245,7 @@ if (!defined('NOREQUIREDB') && !defined('NOREQUIRESOC')) {
// Invoice subtype is a requirement for Greece.
$conf->global->INVOICE_SUBTYPE_ENABLED = 1;
}
+
if (($mysoc->localtax1_assuj || $mysoc->localtax2_assuj) && !isset($conf->global->MAIN_NO_INPUT_PRICE_WITH_TAX)) {
// For countries using the 2nd or 3rd tax, we disable input/edit of lines using the price including tax (because 2nb and 3rd tax not yet taken into account).
// Work In Progress to support all taxes into unit price entry when MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES is set.
diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php
index c64d042485b..e0b191c195a 100644
--- a/htdocs/modulebuilder/template/myobject_list.php
+++ b/htdocs/modulebuilder/template/myobject_list.php
@@ -299,7 +299,6 @@ $parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
-//$sql .= ", COUNT(rc.rowid) as anotherfield";
$sqlfields = $sql; // $sql fields to remove for count total
@@ -388,6 +387,7 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
/* The fast and low memory method to get and count full list converts the sql into a sql count */
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
+
$resql = $db->query($sqlforcount);
if ($resql) {
$objforcount = $db->fetch_object($resql);
diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php
index ce24972023f..d0e65765b35 100644
--- a/htdocs/product/stock/productlot_list.php
+++ b/htdocs/product/stock/productlot_list.php
@@ -229,6 +229,9 @@ $parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
+
+$sqlfields = $sql;
+
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
@@ -317,7 +320,9 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
}
}*/
/* The fast and low memory method to get and count full list converts the sql into a sql count */
- $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql);
+ $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
+ $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
+
$resql = $db->query($sqlforcount);
if ($resql) {
$objforcount = $db->fetch_object($resql);
@@ -325,7 +330,7 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
} else {
dol_print_error($db);
}
-
+
if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
$page = 0;
$offset = 0;
diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php
index f2d3946579a..8e7c81d1200 100644
--- a/htdocs/projet/contact.php
+++ b/htdocs/projet/contact.php
@@ -158,6 +158,11 @@ if (empty($reshook)) {
// Add new contact
if ($action == 'addcontact_confirm' && $user->hasRight('projet', 'creer')) {
+ if (GETPOST('confirm', 'alpha') == 'no') {
+ header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+ exit;
+ }
+
$contactid = (GETPOST('userid') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int'));
$typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
diff --git a/htdocs/public/agenda/agendaexport.php b/htdocs/public/agenda/agendaexport.php
index 9f62c6265c5..873f5a80e50 100644
--- a/htdocs/public/agenda/agendaexport.php
+++ b/htdocs/public/agenda/agendaexport.php
@@ -86,7 +86,7 @@ require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
$object = new ActionComm($db);
// Not older than
-if (!isset($conf->global->MAIN_AGENDA_EXPORT_PAST_DELAY)) {
+if (empty($conf->global->MAIN_AGENDA_EXPORT_PAST_DELAY)) {
$conf->global->MAIN_AGENDA_EXPORT_PAST_DELAY = 100; // default limit
}
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index 2d6e1991846..ae4fe3dd971 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -1775,7 +1775,7 @@ class Societe extends CommonObject
global $langs;
global $conf;
- if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($barcode) && empty($idprof1) && empty($idprof2) && empty($idprof3) && empty($idprof4) && empty($idprof5) && empty($idprof6) && empty($email)) {
+ if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($barcode) && empty($idprof1) && empty($idprof2) && empty($idprof3) && empty($idprof4) && empty($idprof5) && empty($idprof6) && empty($email) && empty($ref_alias)) {
return -1;
}
diff --git a/htdocs/website/index.php b/htdocs/website/index.php
index aa7ea1f78e7..e25f1d4b2ab 100644
--- a/htdocs/website/index.php
+++ b/htdocs/website/index.php
@@ -4808,7 +4808,7 @@ if ($mode == 'replacesite' || $massaction == 'replace') {
print ' | ';
// Categories - Tags
- print '';
+ print ' | ';
if (isModEnabled('categorie') && $user->hasRight('categorie', 'lire')) {
// Get current categories
$existing = $c->containing($answerrecord->id, Categorie::TYPE_WEBSITE_PAGE, 'object');
|