Browse Source

Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into develop

Conflicts:
	ChangeLog
	htdocs/compta/bank/class/account.class.php
	htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php
	htdocs/langs/en_US/recruitment.lang
	htdocs/master.inc.php
	htdocs/projet/contact.php
Laurent Destailleur 1 year ago
parent
commit
98009ea6be

+ 38 - 0
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)

+ 2 - 2
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__'",
 	),

+ 5 - 0
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);
 	}
 

+ 1 - 1
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') {

+ 1 - 1
htdocs/bom/tpl/linkedobjectblock.tpl.php

@@ -62,7 +62,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) {
 		$product_static->getNomUrl(1);
 	}
 	print '</td>';
-	echo '<td class="linkedcol-date">'.dol_print_date($objectlink->date_creation, 'day').'</td>';
+	echo '<td class="linkedcol-date center">'.dol_print_date($objectlink->date_creation, 'day').'</td>';
 	echo '<td class="linkedcol-amount right">';
 	if ($user->hasRight('commande', 'lire')) {
 		$total = $total + $objectlink->total_ht;

+ 1 - 0
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);

+ 10 - 1
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;

+ 2 - 1
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;

+ 3 - 2
htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php

@@ -6,6 +6,7 @@
  * Copyright (C) 2015      Marcos García         <marcosgdf@gmail.com>
  * Copyright (C) 2017      Ferran Marcet         <fmarcet@2byte.es>
  * Copyright (C) 2018-2022 Frédéric France       <frederic.france@netlogic.fr>
+ * Copyright (C) 2023		William Mead		<william.mead@manchenumerique.fr>
  *
  * 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);

+ 1 - 1
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;
 	}

+ 4 - 5
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);

+ 1 - 1
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');

+ 1 - 0
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

+ 1 - 4
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.

+ 1 - 1
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);

+ 7 - 2
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;

+ 5 - 0
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'));
 

+ 1 - 1
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
 }
 

+ 1 - 1
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;
 		}
 

+ 1 - 1
htdocs/website/index.php

@@ -4808,7 +4808,7 @@ if ($mode == 'replacesite' || $massaction == 'replace') {
 					print '</td>';
 
 					// Categories - Tags
-					print '<td>';
+					print '<td class="center">';
 					if (isModEnabled('categorie') && $user->hasRight('categorie', 'lire')) {
 						// Get current categories
 						$existing = $c->containing($answerrecord->id, Categorie::TYPE_WEBSITE_PAGE, 'object');