From 52446678d083da7eee86f27dfc374ff85fc16968 Mon Sep 17 00:00:00 2001 From: Ryad ABANI Date: Mon, 20 Oct 2025 16:23:22 +0200 Subject: [PATCH 01/40] FIX: php8.1 warning in syslog message --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index f6897b6a2d1..18424785ffe 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -319,7 +319,7 @@ class CMailFile foreach ($filename_list as $i => $val) { if ($filename_list[$i]) { $this->atleastonefile = 1; - dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]." cid_list[$i]=".$cid_list[$i], LOG_DEBUG); + dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]. (empty($cid_list[$i]) ? 'Not an image' : $cid_list[$i]), LOG_DEBUG); } } } From 2153dbb0f175e62eee0bd4815cf829c29c476eae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Oct 2025 02:09:51 +0200 Subject: [PATCH 02/40] Update CMailFile.class.php --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 18424785ffe..5ccd242bf1f 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -319,7 +319,7 @@ class CMailFile foreach ($filename_list as $i => $val) { if ($filename_list[$i]) { $this->atleastonefile = 1; - dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]. (empty($cid_list[$i]) ? 'Not an image' : $cid_list[$i]), LOG_DEBUG); + dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]. (empty($cid_list[$i]) ? 'Not an embedded image' : $cid_list[$i]), LOG_DEBUG); } } } From 1eed0e18a9581318f7071ff1e3d061f0f6a82089 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Oct 2025 02:11:56 +0200 Subject: [PATCH 03/40] Update CMailFile.class.php --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 5ccd242bf1f..9e096d27f64 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -319,7 +319,7 @@ class CMailFile foreach ($filename_list as $i => $val) { if ($filename_list[$i]) { $this->atleastonefile = 1; - dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]. (empty($cid_list[$i]) ? 'Not an embedded image' : $cid_list[$i]), LOG_DEBUG); + dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]." cid_list[$i]=".(empty($cid_list[$i]) ? 'Not an embedded image' : $cid_list[$i]), LOG_DEBUG); } } } From 9319059349ac4cb8fb916b004cd3936977c26ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9?= Date: Thu, 20 Nov 2025 14:01:29 +0100 Subject: [PATCH 04/40] FIX: Sometimes socid = undefined --- htdocs/takepos/index.php | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index fe9c34946a4..3ae0da797c4 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -93,6 +93,8 @@ if ($conf->browser->layout == 'phone') { $MAXCATEG = (empty($conf->global->TAKEPOS_NB_MAXCATEG) ? $maxcategbydefaultforthisdevice : $conf->global->TAKEPOS_NB_MAXCATEG); $MAXPRODUCT = (empty($conf->global->TAKEPOS_NB_MAXPRODUCT) ? $maxproductbydefaultforthisdevice : $conf->global->TAKEPOS_NB_MAXPRODUCT); +$term = empty($_SESSION['takeposterminal']) ? 1 : $_SESSION['takeposterminal']; +$socid = getDolGlobalString('CASHDESK_ID_THIRDPARTY' . $term); /* $constforcompanyid = 'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]; $soc = new Societe($db); @@ -329,8 +331,15 @@ function LoadProducts(position, issubcat) { if (maxproduct >= 1) { limit = maxproduct-1; } + + // Get socid + let socid = jQuery('#thirdpartyid').val(); + if ((socid === undefined || socid === "") && parseInt("") > 0) { + socid = parseInt(""); + } + // Only show products for sale (tosell=1) - $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&thirdpartyid=' + jQuery('#thirdpartyid').val() + '&category='+currentcat+'&tosell=1&limit='+limit+'&offset=0', function(data) { + $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&thirdpartyid=' + socid + '&category='+currentcat+'&tosell=1&limit='+limit+'&offset=0', function(data) { console.log("Call ajax.php (in LoadProducts) to get Products of category "+currentcat+" then loop on result to fill image thumbs"); console.log(data); while (ishow < maxproduct) { @@ -437,8 +446,15 @@ function MoreProducts(moreorless) { limit = maxproduct-1; } var offset = * pageproducts; + + // Get socid + let socid = jQuery('#thirdpartyid').val(); + if ((socid === undefined || socid === "") && parseInt("") > 0) { + socid = parseInt(""); + } + // Only show products for sale (tosell=1) - $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&thirdpartyid=' + jQuery('#thirdpartyid').val() + '&category='+currentcat+'&tosell=1&limit='+limit+'&offset='+offset, function(data) { + $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&thirdpartyid=' + socid + '&category='+currentcat+'&tosell=1&limit='+limit+'&offset='+offset, function(data) { console.log("Call ajax.php (in MoreProducts) to get Products of category "+currentcat); if (typeof (data[0]) == "undefined" && moreorless=="more"){ // Return if no more pages @@ -662,7 +678,14 @@ function Search2(keyCodeForEnter, moreorless) { pageproducts = 0; jQuery(".wrapper2 .catwatermark").hide(); var nbsearchresults = 0; - $.getJSON('/takepos/ajax/ajax.php?action=search&token=&term=' + search_term + '&thirdpartyid=' + jQuery('#thirdpartyid').val() + '&search_start=' + search_start + '&search_limit=' + search_limit, function (data) { + + // Only show products for sale (tosell=1) + let socid = jQuery('#thirdpartyid').val(); + if ((socid === undefined || socid === "") && parseInt("") > 0) { + socid = parseInt(""); + } + + $.getJSON('/takepos/ajax/ajax.php?action=search&token=&term=' + search_term + '&thirdpartyid=' + socid + '&search_start=' + search_start + '&search_limit=' + search_limit, function (data) { for (i = 0; i < ; i++) { if (typeof (data[i]) == "undefined") { $("#prowatermark" + i).html(""); From 92197cb100c5cdce53b17cba22e66ec5f6516cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9?= Date: Fri, 21 Nov 2025 16:06:09 +0100 Subject: [PATCH 05/40] FIX: php echo instead of ") > 0) { + if ((socid === undefined || socid === "") && parseInt("") > 0) { socid = parseInt(""); } @@ -449,7 +449,7 @@ function MoreProducts(moreorless) { // Get socid let socid = jQuery('#thirdpartyid').val(); - if ((socid === undefined || socid === "") && parseInt("") > 0) { + if ((socid === undefined || socid === "") && parseInt("") > 0) { socid = parseInt(""); } @@ -681,7 +681,7 @@ function Search2(keyCodeForEnter, moreorless) { // Only show products for sale (tosell=1) let socid = jQuery('#thirdpartyid').val(); - if ((socid === undefined || socid === "") && parseInt("") > 0) { + if ((socid === undefined || socid === "") && parseInt("") > 0) { socid = parseInt(""); } From 3416c6ccc03053566be5e67868de4f676123efde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9?= Date: Thu, 27 Nov 2025 10:00:43 +0100 Subject: [PATCH 06/40] FIX: getDolGlobalInt --- htdocs/takepos/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index cf999b7ecc7..bafe040f50c 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -94,7 +94,7 @@ $MAXCATEG = (empty($conf->global->TAKEPOS_NB_MAXCATEG) ? $maxcategbydefaultforth $MAXPRODUCT = (empty($conf->global->TAKEPOS_NB_MAXPRODUCT) ? $maxproductbydefaultforthisdevice : $conf->global->TAKEPOS_NB_MAXPRODUCT); $term = empty($_SESSION['takeposterminal']) ? 1 : $_SESSION['takeposterminal']; -$socid = getDolGlobalString('CASHDESK_ID_THIRDPARTY' . $term); +$socid = getDolGlobalInt('CASHDESK_ID_THIRDPARTY' . $term); /* $constforcompanyid = 'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]; $soc = new Societe($db); From 2ee07bb0494bf5a95e33c6f1cfed5bbcd2271554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9?= Date: Thu, 4 Dec 2025 17:27:57 +0100 Subject: [PATCH 07/40] FIX: Remove ") > 0) { - socid = parseInt(""); + if ((socid === undefined || socid === "") && parseInt("") > 0) { + socid = parseInt(""); } // Only show products for sale (tosell=1) @@ -449,8 +449,8 @@ function MoreProducts(moreorless) { // Get socid let socid = jQuery('#thirdpartyid').val(); - if ((socid === undefined || socid === "") && parseInt("") > 0) { - socid = parseInt(""); + if ((socid === undefined || socid === "") && parseInt("") > 0) { + socid = parseInt(""); } // Only show products for sale (tosell=1) @@ -681,8 +681,8 @@ function Search2(keyCodeForEnter, moreorless) { // Only show products for sale (tosell=1) let socid = jQuery('#thirdpartyid').val(); - if ((socid === undefined || socid === "") && parseInt("") > 0) { - socid = parseInt(""); + if ((socid === undefined || socid === "") && parseInt("") > 0) { + socid = parseInt(""); } $.getJSON('/takepos/ajax/ajax.php?action=search&token=&term=' + search_term + '&thirdpartyid=' + socid + '&search_start=' + search_start + '&search_limit=' + search_limit, function (data) { From 8d84cec3ca7718c77d825634be0c87e6889c422b Mon Sep 17 00:00:00 2001 From: Eric Seigne Date: Thu, 11 Dec 2025 10:43:24 +0100 Subject: [PATCH 08/40] remove slash like other parts of dolibarr code for TICKET_URL_PUBLIC_INTERFACE --- htdocs/ticket/class/ticket.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 6d1ee87f93e..a18d23266dd 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2767,7 +2767,7 @@ class Ticket extends CommonObject } // If public interface is not enable, use link to internal page into mail - $url_public_ticket = getDolGlobalString('TICKET_URL_PUBLIC_INTERFACE', dol_buildpath('/public/ticket/view.php', 2)) . '/view.php?track_id='.$object->track_id; + $url_public_ticket = getDolGlobalString('TICKET_URL_PUBLIC_INTERFACE', dol_buildpath('/public/ticket/view.php', 2)) . 'view.php?track_id='.$object->track_id; $message .= '
'.$langs->trans('TicketNewEmailBodyInfosTrackUrlCustomer').' : '.$object->track_id.'
'; // Build final message From eb4d9dec53450aa28d7404a1eecf9fc42118aaf6 Mon Sep 17 00:00:00 2001 From: Eric Seigne Date: Thu, 18 Dec 2025 09:36:45 +0100 Subject: [PATCH 09/40] thanks to lionel : remove view.php in default value like other part of dolibarr --- htdocs/ticket/class/ticket.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index a18d23266dd..1ee21cca17d 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2767,7 +2767,7 @@ class Ticket extends CommonObject } // If public interface is not enable, use link to internal page into mail - $url_public_ticket = getDolGlobalString('TICKET_URL_PUBLIC_INTERFACE', dol_buildpath('/public/ticket/view.php', 2)) . 'view.php?track_id='.$object->track_id; + $url_public_ticket = getDolGlobalString('TICKET_URL_PUBLIC_INTERFACE', dol_buildpath('/public/ticket/', 2)) . 'view.php?track_id='.$object->track_id; $message .= '
'.$langs->trans('TicketNewEmailBodyInfosTrackUrlCustomer').' : '.$object->track_id.'
'; // Build final message From c33b7e0bf1d163673ce4cd9398b71eed72a53dd6 Mon Sep 17 00:00:00 2001 From: lvessiller-opendsi Date: Tue, 30 Dec 2025 11:03:20 +0100 Subject: [PATCH 10/40] FIX finished regex in product import (#36770) --- htdocs/core/modules/modProduct.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index e5b0473597b..9ae50528f6f 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -656,7 +656,6 @@ class modProduct extends DolibarrModules 'p.fk_product_type'=>'^[0|1]$', 'p.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 'p.recuperableonly' => '^[0|1]$', - 'p.finished' => '^[0|1]$' ); // field order as per structure of table llx_product $import_sample = array( From ad3304832dd95cef3ad2c33ec3135987c339c8cc Mon Sep 17 00:00:00 2001 From: Mathieu Moulin Date: Tue, 6 Jan 2026 15:32:59 +0100 Subject: [PATCH 11/40] FIX : remove stock correctly when reception is deleted (like 82e092f) --- htdocs/reception/class/reception.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 8e98cfe639e..6915dc1ded4 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -12,6 +12,7 @@ * Copyright (C) 2016-2022 Ferran Marcet * Copyright (C) 2018 Quentin Vial-Gouteyron * Copyright (C) 2022-2023 Frédéric France + * Copyright (C) 2026 Mathieu Moulin * * 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 @@ -1033,7 +1034,10 @@ class Reception extends CommonObject $this->db->begin(); // Stock control - if (isModEnabled('stock') && $conf->global->STOCK_CALCULATE_ON_RECEPTION && $this->statut > 0) { + if (isModEnabled('stock') && + ((getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') && $this->statut > self::STATUS_DRAFT) || + (getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION_CLOSE') && $this->statut == self::STATUS_CLOSED)) + ) { require_once DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php"; $langs->load("agenda"); From d5cab67f4c669f6f3b214f56f7c55f901fba4585 Mon Sep 17 00:00:00 2001 From: Eric - CAP-REL <1468823+rycks@users.noreply.github.com> Date: Thu, 8 Jan 2026 09:55:28 +0100 Subject: [PATCH 12/40] Fix log message for empty cid_list apply same fix as 20.0 to avoid conflicts on next merges --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 9e096d27f64..337876482fe 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -319,7 +319,7 @@ class CMailFile foreach ($filename_list as $i => $val) { if ($filename_list[$i]) { $this->atleastonefile = 1; - dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]." cid_list[$i]=".(empty($cid_list[$i]) ? 'Not an embedded image' : $cid_list[$i]), LOG_DEBUG); + dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]." cid_list[$i]=".(empty($cid_list[$i]) ? '' : $cid_list[$i]), LOG_DEBUG); } } } From f497a6a4fe3beea00ea3671d99a8e1fa471fa65b Mon Sep 17 00:00:00 2001 From: lvessiller-opendsi Date: Thu, 8 Jan 2026 18:54:15 +0100 Subject: [PATCH 13/40] FIX warning accountancy export from external module (#36832) --- htdocs/accountancy/class/accountancyexport.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 472f5b5ce38..3ed4c1c7583 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -181,7 +181,7 @@ class AccountancyExport ); global $hookmanager; - $code = $formatcode[$type]; + $code = $formatcode[$type] ?? ''; $parameters = array('type' => $type); $reshook = $hookmanager->executeHooks('getFormatCode', $parameters, $code); From a5b106fe70e90c7b229257bfd7d932c80a8a620c Mon Sep 17 00:00:00 2001 From: Mathieu Moulin Date: Sat, 10 Jan 2026 17:30:45 +0100 Subject: [PATCH 14/40] Fix error removing reception with product batches (eatby/sellby) (#36846) --- htdocs/reception/class/reception.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 6915dc1ded4..9b2870eb769 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1061,7 +1061,7 @@ class Reception extends CommonObject // we do not log origin because it will be deleted $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 + $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans("ReceptionDeletedInDolibarr", $this->ref), '', $obj->eatby ? $this->db->jdate($obj->eatby) : null, $obj->sellby ? $this->db->jdate($obj->sellby) : null, $obj->batch); // Price is set to 0, because we don't want to see WAP changed if ($result < 0) { $error++; $this->error = $mouvS->error; From b3669d4333187b626b294cc4b1422feafe4bfcbf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 10 Jan 2026 17:45:20 +0100 Subject: [PATCH 15/40] Try to fix script --- .github/workflows/pr-18.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-18.yaml b/.github/workflows/pr-18.yaml index d12d7002844..733a3e788dc 100644 --- a/.github/workflows/pr-18.yaml +++ b/.github/workflows/pr-18.yaml @@ -42,9 +42,11 @@ jobs: env: GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} url: ${{ github.event.pull_request.html_url }} + url2: ${{ github.event.pull_request_target.html_url }} run: | echo "env.url=${{env.url}}" - gh pr edit "${{env.url}}" --add-label "Issue for v18 maintenance Team" + echo "env.url2=${{env.url2}}" + gh pr edit "${{env.url}}" --add-label "Issue for v18 maintenance Team" - name: Set reviewers except PR author id: set-reviewers @@ -58,6 +60,7 @@ jobs: FINAL_REVIEWERS+=("$reviewer") fi done + echo "AUTHOR=$AUTHOR" echo "reviewers=$(IFS=, ; echo "${FINAL_REVIEWERS[*]}")" >> $GITHUB_OUTPUT - name: Assign reviewers From 7b6051a0d0869990e4ad0e473d26bc37b622b45c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Fali=C3=A8re?= <121813548+BenjaminFlr@users.noreply.github.com> Date: Sat, 10 Jan 2026 17:46:45 +0100 Subject: [PATCH 16/40] FIX(ticket): check on TICKET_IMAGE_PUBLIC_INTERFACE (#36833) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * FIX(ticket): check on TICKET_IMAGE_PUBLIC_INTERFACE Must use getDolGlobalString instead of getDolGlobalInt here * Add contributor --------- Co-authored-by: Benjamin Falière --- htdocs/core/lib/ticket.lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php index fd777fbac2b..e46da88f5b5 100644 --- a/htdocs/core/lib/ticket.lib.php +++ b/htdocs/core/lib/ticket.lib.php @@ -2,6 +2,7 @@ /* Copyright (C) 2013-2018 Jean-François FERRY * Copyright (C) 2016 Christophe Battarel * Copyright (C) 2019-2022 Frédéric France + * Copyright (C) 2025 Benjamin Falière * * 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 @@ -261,7 +262,7 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $ print ''; } - if (getDolGlobalInt('TICKET_IMAGE_PUBLIC_INTERFACE')) { + if (getDolGlobalString('TICKET_IMAGE_PUBLIC_INTERFACE')) { print '
'; print ''; print '
'; From 2e7ab21d017e72d5d3812c018426db818e571039 Mon Sep 17 00:00:00 2001 From: ThomasNgr-OpenDSI Date: Tue, 13 Jan 2026 11:37:36 +0100 Subject: [PATCH 17/40] FIX #GHSA-w5j3-8fcr-h87w (#36868) Co-authored-by: Laurent Destailleur --- htdocs/includes/odtphp/odf.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 39f595f4934..4fd29562183 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -833,7 +833,7 @@ IMG; // using windows libreoffice that must be in path // using linux/mac libreoffice that must be in path // Note PHP Config "fastcgi.impersonate=0" must set to 0 - Default is 1 - $command ='soffice --headless -env:UserInstallation=file:\''.$conf->user->dir_temp.'/odtaspdf\' --convert-to pdf --outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name); + $command ='soffice --headless -env:UserInstallation=file:\''.dol_sanitizePathName($conf->user->dir_temp).'/odtaspdf\' --convert-to pdf --outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name); } elseif (preg_match('/unoconv/', getDolGlobalString('MAIN_ODT_AS_PDF'))) { // If issue with unoconv, see https://github.com/dagwieers/unoconv/issues/87 @@ -859,17 +859,19 @@ IMG; // - set shell of user to bash instead of nologin. // - set permission to read/write to user on home directory /var/www so user can create the libreoffice , dconf and .cache dir and files then set permission back - $command = getDolGlobalString('MAIN_ODT_AS_PDF').' '.escapeshellcmd($name); + $command = getDolGlobalString('MAIN_ODT_AS_PDF').' '.escapeshellarg($name); //$command = '/usr/bin/unoconv -vvv '.escapeshellcmd($name); } else { // deprecated old method using odt2pdf.sh (native, jodconverter, ...) $tmpname=preg_replace('/\.odt/i', '', $name); if (getDolGlobalString('MAIN_DOL_SCRIPTS_ROOT')) { - $command = getDolGlobalString('MAIN_DOL_SCRIPTS_ROOT').'/scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($tmpname).' '.(is_numeric(getDolGlobalString('MAIN_ODT_AS_PDF'))?'jodconverter':getDolGlobalString('MAIN_ODT_AS_PDF')); + $command = dol_sanitizePathName(getDolGlobalString('MAIN_DOL_SCRIPTS_ROOT')).'/scripts/odt2pdf/odt2pdf.sh '.escapeshellarg($tmpname).' '.escapeshellarg(is_numeric(getDolGlobalString('MAIN_ODT_AS_PDF')) ? 'jodconverter' : getDolGlobalString('MAIN_ODT_AS_PDF')); } else { dol_syslog(get_class($this).'::exportAsAttachedPDF is used but the constant MAIN_DOL_SCRIPTS_ROOT with path to script directory was not defined.', LOG_WARNING); - $command = '../../scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($tmpname).' '.(is_numeric(getDolGlobalString('MAIN_ODT_AS_PDF'))?'jodconverter':getDolGlobalString('MAIN_ODT_AS_PDF')); + $paramodt2pdf = (is_numeric(getDolGlobalString('MAIN_ODT_AS_PDF')) ? 'jodconverter' : getDolGlobalString('MAIN_ODT_AS_PDF')); + $paramodt2pdf = dol_sanitizePathName($paramodt2pdf); + $command = '../../scripts/odt2pdf/odt2pdf.sh '.escapeshellarg($tmpname).' '.escapeshellarg($paramodt2pdf); } } @@ -877,6 +879,7 @@ IMG; //$command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name.' '.$dirname; dol_syslog(get_class($this).'::exportAsAttachedPDF $execmethod='.$execmethod.' Run command='.$command, LOG_DEBUG); + // TODO Use: // $outputfile = DOL_DATA_ROOT.'/odt2pdf.log'; // $result = $utils->executeCLI($command, $outputfile); and replace test on $execmethod. @@ -884,17 +887,17 @@ IMG; // $errorstring will be $result['output'] $retval=0; $output_arr=array(); if ($execmethod == 1) { - exec($command, $output_arr, $retval); + exec(escapeshellcmd($command), $output_arr, $retval); } if ($execmethod == 2) { $outputfile = DOL_DATA_ROOT.'/odt2pdf.log'; - $ok=0; $handle = fopen($outputfile, 'w'); if ($handle) { dol_syslog(get_class($this)."Run command ".$command, LOG_DEBUG); + dol_syslog(get_class($this)."escapeshellcmd(command) = ".escapeshellcmd($command), LOG_DEBUG); fwrite($handle, $command."\n"); - $handlein = popen($command, 'r'); + $handlein = popen(escapeshellcmd($command), 'r'); while (!feof($handlein)) { $read = fgets($handlein); fwrite($handle, $read); @@ -937,7 +940,7 @@ IMG; foreach ($output_arr as $line) { $errorstring.= $line."
"; } - throw new OdfException('ODT to PDF convert fail (option MAIN_ODT_AS_PDF is '.$conf->global->MAIN_ODT_AS_PDF.', command was '.$command.', retval='.$retval.') : ' . $errorstring); + throw new OdfException('ODT to PDF convert fail (option MAIN_ODT_AS_PDF is '.getDolGlobalString('MAIN_ODT_AS_PDF').', command was '.$command.', retval='.$retval.') : ' . $errorstring); } } } From 2cfdbd6b5ff2c29d632eeff79a18c44e29ccd230 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Jan 2026 16:04:20 +0100 Subject: [PATCH 18/40] Try to use PR ID instead of PR url --- .github/workflows/pr-18.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-18.yaml b/.github/workflows/pr-18.yaml index 733a3e788dc..ef651ffa8e6 100644 --- a/.github/workflows/pr-18.yaml +++ b/.github/workflows/pr-18.yaml @@ -41,12 +41,14 @@ jobs: - name: Assign Tag env: GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} + prid: ${{ github.event.pull_request.number }} url: ${{ github.event.pull_request.html_url }} url2: ${{ github.event.pull_request_target.html_url }} run: | + echo "env.prid=${{env.prid}}" echo "env.url=${{env.url}}" echo "env.url2=${{env.url2}}" - gh pr edit "${{env.url}}" --add-label "Issue for v18 maintenance Team" + gh pr edit "${{env.prid}}" --add-label "Issue for v18 maintenance Team" - name: Set reviewers except PR author id: set-reviewers @@ -67,8 +69,9 @@ jobs: if: steps.set-reviewers.outputs.reviewers != '' env: GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} + prid: ${{ github.event.pull_request.number }} url: ${{ github.event.pull_request.html_url }} reviewers: ${{ steps.set-reviewers.outputs.reviewers }} run: | echo "Assigning reviewers: ${{env.reviewers}}" - gh pr edit "${{env.url}}" --add-reviewer "${{env.reviewers}}" + gh pr edit "${{env.prid}}" --add-reviewer "${{env.reviewers}}" From 39d30a23fe3c7b8cf8ffc5619b3654fba2425830 Mon Sep 17 00:00:00 2001 From: atm-lucas <121817516+atm-lucasmantegari@users.noreply.github.com> Date: Mon, 19 Jan 2026 13:44:09 +0100 Subject: [PATCH 19/40] Duplicates in the result of the SQL query (#36913) --- htdocs/compta/resultat/clientfourn.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php index cf2a26979a9..197d0a7bfc5 100644 --- a/htdocs/compta/resultat/clientfourn.php +++ b/htdocs/compta/resultat/clientfourn.php @@ -292,16 +292,19 @@ if ($modecompta == 'BOOKKEEPING') { if ($showaccountdetail == 'no') { $sql .= ", f.thirdparty_code as name"; } - $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as f"; - $sql .= ", ".MAIN_DB_PREFIX."accounting_account as aa"; - $sql .= " WHERE f.numero_compte = aa.account_number"; + $sql .= " FROM ".$db->prefix()."accounting_bookkeeping as f"; + $sql .= " INNER JOIN ".$db->prefix()."accounting_account as aa"; + $sql .= " ON aa.account_number = f.numero_compte"; + $sql .= " AND aa.entity = f.entity"; // Security prevents duplicate. + $sql .= " WHERE 1=1"; $sql .= " AND ".$predefinedgroupwhere; - $sql .= " AND fk_pcg_version = '".$db->escape($charofaccountstring)."'"; + $sql .= " AND aa.fk_pcg_version = '".$db->escape($charofaccountstring)."'"; $sql .= " AND f.entity = ".$conf->entity; if (!empty($date_start) && !empty($date_end)) { - $sql .= " AND f.doc_date >= '".$db->idate($date_start)."' AND f.doc_date <= '".$db->idate($date_end)."'"; + $sql .= " AND f.doc_date >= '".$db->idate($date_start)."'"; + $sql .= " AND f.doc_date <= '".$db->idate($date_end)."'"; } - $sql .= " GROUP BY pcg_type"; + $sql .= " GROUP BY aa.pcg_type"; if ($showaccountdetail == 'no') { $sql .= ", name, socid"; // group by "accounting group" (INCOME/EXPENSE), then "customer". } From 926ed04ebe3b9fd152dde6584b1dcd6366eb920e Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Tue, 20 Jan 2026 13:58:17 +0100 Subject: [PATCH 20/40] fix: PHP fatal error on php 8.2 Unsupported operand types: string * string (#36930) --- htdocs/mrp/mo_production.php | 2 +- htdocs/product/stock/class/mouvementstock.class.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 4a48a1fbaab..b883cd48316 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -250,7 +250,7 @@ if (empty($reshook)) { $i = 1; while (GETPOSTISSET('qty-'.$line->id.'-'.$i)) { - $qtytoprocess = price2num(GETPOST('qty-'.$line->id.'-'.$i)); + $qtytoprocess = (float) price2num(GETPOST('qty-'.$line->id.'-'.$i)); if ($qtytoprocess != 0) { // Check warehouse is set if we should have to diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 9506db38c4a..a6ed0bc0d15 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -505,6 +505,7 @@ class MouvementStock extends CommonObject // Test if there is already a record for couple (warehouse / product), so later we will make an update or create. $alreadyarecord = 0; + $fk_product_stock = 0; if (!$error) { $sql = "SELECT rowid, reel FROM ".$this->db->prefix()."product_stock"; $sql .= " WHERE fk_entrepot = ".((int) $entrepot_id)." AND fk_product = ".((int) $fk_product); // This is a unique key @@ -535,7 +536,7 @@ class MouvementStock extends CommonObject if ($price > 0 || (getDolGlobalString('STOCK_UPDATE_AWP_EVEN_WHEN_ENTRY_PRICE_IS_NULL') && $price == 0 && in_array($this->origin_type, array('order_supplier', 'invoice_supplier')))) { $oldqtytouse = ($oldqty >= 0 ? $oldqty : 0); // We make a test on oldpmp>0 to avoid to use normal rule on old data with no pmp field defined - if ($oldpmp > 0) { + if ($oldpmp > 0 && ($oldqtytouse + $qty) != 0) { $newpmp = price2num((($oldqtytouse * $oldpmp) + ($qty * $price)) / ($oldqtytouse + $qty), 'MU'); } else { $newpmp = $price; // For this product, PMP was not yet set. We set it to input price. From 835d3811a41a1c1e40f20c5a21c135c7cfd994ed Mon Sep 17 00:00:00 2001 From: Joachim Kueter Date: Fri, 23 Jan 2026 17:55:03 +0100 Subject: [PATCH 21/40] FIX #36960 - User can access some data (product price, invoice amount) without having the respective rights (#36962) * FIX #36960 - User can access some data (product price, invoice amount) without having the respective rights See detailed description in issue #36960 Product price and invoice amount was shown to users without checking right to read. * removed white space * Minor change to trigger checks again --------- Co-authored-by: Laurent Destailleur --- htdocs/projet/tasks/time.php | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 16958f25097..690b2bccea2 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -10,6 +10,7 @@ * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Vincent de Grandpré * Copyright (C) 2024 Solution Libre SAS + * Copyright (C) 2026 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 @@ -1887,7 +1888,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (isModEnabled("service") && !empty($projectstatic->thirdparty) && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) { print ''; print img_picto('', 'service'); - print $form->select_produits((GETPOSTISSET('fk_product') ? GETPOSTINT("fk_product") : ''), 'fk_product', 1, 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth150', 0, '', null, 1); + print $form->select_produits((GETPOSTISSET('fk_product') ? GETPOSTINT("fk_product") : ''), 'fk_product', 1, 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth150', ($user->hasRight('produit', 'lire') ? 0 : 1), '', null, 1); print ''; } } @@ -2430,7 +2431,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; if ($action == 'editline' && GETPOSTINT('lineid') == $task_time->rowid) { print img_picto('', 'service'); - print $form->select_produits($task_time->fk_product, 'fk_product', 1, 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500', 0, '', null, 1); + print $form->select_produits($task_time->fk_product, 'fk_product', 1, 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500', ($user->hasRight('produit', 'lire') ? 0 : 1), '', null, 1); } elseif (!empty($task_time->fk_product)) { $product = new Product($db); $resultFetch = $product->fetch($task_time->fk_product); @@ -2485,18 +2486,22 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($task_time->invoice_id) { $result = $tmpinvoice->fetch($task_time->invoice_id); if ($result > 0) { - if ($action == 'editline' && GETPOSTINT('lineid') == $task_time->rowid) { - print $formproject->selectInvoiceAndLine($task_time->invoice_id, $task_time->invoice_line_id, 'invoiceid', 'invoicelineid', 'maxwidth500', array('p.rowid' => $projectstatic->id)); - } else { - print $tmpinvoice->getNomUrl(1); - if (!empty($task_time->invoice_line_id)) { - $invoiceLine = new FactureLigne($db); - $invoiceLine->fetch($task_time->invoice_line_id); - if (!empty($invoiceLine->id)) { - print '
'.$langs->trans('Qty').':'.$invoiceLine->qty; - print ' '.$langs->trans('TotalHT').':'.price($invoiceLine->total_ht); + if ($user->hasRight('facture', 'lire')) { + if ($action == 'editline' && GETPOSTINT('lineid') == $task_time->rowid) { + print $formproject->selectInvoiceAndLine($task_time->invoice_id, $task_time->invoice_line_id, 'invoiceid', 'invoicelineid', 'maxwidth500', array('p.rowid' => $projectstatic->id)); + } else { + print $tmpinvoice->getNomUrl(1); + if (!empty($task_time->invoice_line_id)) { + $invoiceLine = new FactureLigne($db); + $invoiceLine->fetch($task_time->invoice_line_id); + if (!empty($invoiceLine->id)) { + print '
'.$langs->trans('Qty').':'.$invoiceLine->qty; + print ' '.$langs->trans('TotalHT').':'.price($invoiceLine->total_ht); + } } } + } else { + print $langs->trans("Yes"); } } $invoiced = true; From c19e4e33cbe2f079dc12b42ac6c438d05d39b89a Mon Sep 17 00:00:00 2001 From: noec764 <58433943+noec764@users.noreply.github.com> Date: Fri, 23 Jan 2026 18:29:12 +0100 Subject: [PATCH 22/40] FIX: Massaction Create Bills from expedition (#36958) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Noé Co-authored-by: Laurent Destailleur --- htdocs/expedition/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 4527c8189c5..82895dec519 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -299,7 +299,7 @@ if (empty($reshook)) { } if ($objecttmp->id > 0) { - $res = $objecttmp->add_object_linked($objecttmp->origin, $id_sending); + $res = $objecttmp->add_object_linked($objecttmp->origin_type, $id_sending); if ($res == 0) { $errors[] = $expd->ref.' : '.$langs->trans($objecttmp->errors[0]); From 63fd9d326d8b9adea1af3403bc2fc9c44a374c9d Mon Sep 17 00:00:00 2001 From: NicolasL-SCOPEN Date: Fri, 23 Jan 2026 19:53:30 +0100 Subject: [PATCH 23/40] Fix: subtotal lines from order to purchase order break lines on new document (#36973) * Added a fix to prevent origin subtotal order lines from breaking purchase order lines * Refactored code and fixed formating --- htdocs/core/class/commonobject.class.php | 2 ++ htdocs/fourn/commande/card.php | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index a6927c1b87f..aa32ced0b84 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5742,6 +5742,8 @@ abstract class CommonObject $this->tpl['strike'] = 0; if ($restrictlist == 'services' && $line->product_type != Product::TYPE_SERVICE) { $this->tpl['strike'] = 1; + } elseif ($line->special_code == SUBTOTALS_SPECIAL_CODE) { + $this->tpl['strike'] = 1; } // Output template part (modules that overwrite templates must declare this into descriptor) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 87e6e7d2401..df24bc83789 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1372,14 +1372,18 @@ if (empty($reshook)) { $num = count($lines); for ($i = 0; $i < $num; $i++) { - if (empty($lines[$i]->subprice) || $lines[$i]->qty < 0 || !in_array($lines[$i]->id, $selectedLines)) { + if ( + empty($lines[$i]->subprice) + || $lines[$i]->qty < 0 + || !in_array($lines[$i]->id, $selectedLines) + || $lines[$i]->special_code == SUBTOTALS_SPECIAL_CODE + ) { continue; } $label = (!empty($lines[$i]->label) ? $lines[$i]->label : ''); $desc = (!empty($lines[$i]->desc) ? $lines[$i]->desc : ''); $product_type = (!empty($lines[$i]->product_type) ? $lines[$i]->product_type : 0); - // Reset fk_parent_line for no child products and special product if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { $fk_parent_line = 0; From 364a3d3614317081b714412afcc9aca07173b306 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 23 Jan 2026 20:44:18 +0100 Subject: [PATCH 24/40] Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 --- htdocs/product/stock/class/mouvementstock.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 2653a8b5547..fa683df49f4 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -325,7 +325,7 @@ class MouvementStock extends CommonObject if (getDolGlobalInt('PRODUIT_SOUSPRODUITS')) { $productChildrenNb = $product->hasFatherOrChild(1); } - if (($product->type != Product::TYPE_SERVICE || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) && $productChildrenNb == 0) { + if (($product->type != Product::TYPE_SERVICE || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) && ($productChildrenNb == 0 || getDolGlobalInt('PRODUIT_SOUSPRODUITS_ALSO_ENABLE_PARENT_STOCK_MOVE'))) { $movestock = 1; } From ee32411d6a00b39d006a7102d31d1d990788e7de Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sat, 24 Jan 2026 00:00:14 +0100 Subject: [PATCH 25/40] FIX Contract - Wrong button to edit contract odt path (#36965) Co-authored-by: Laurent Destailleur --- .../modules/contract/doc/doc_generic_contract_odt.modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php index 92882228e17..2678a9777a5 100644 --- a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php +++ b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php @@ -145,7 +145,7 @@ class doc_generic_contract_odt extends ModelePDFContract $texte .= getDolGlobalString('CONTRACT_ADDON_PDF_ODT_PATH'); $texte .= ''; $texte .= '
'; - $texte .= ''; + $texte .= ''; $texte .= '
'; // Scan directories @@ -153,7 +153,7 @@ class doc_generic_contract_odt extends ModelePDFContract if (getDolGlobalString('CONTRACT_ADDON_PDF_ODT_PATH')) { $texte .= $langs->trans("NumberOfModelFilesFound").': '; //$texte.=$nbofiles?'':''; - $texte .= count($listoffiles); + $texte .= $nbofiles; //$texte.=$nbofiles?'':''; $texte .= ''; } From 9f972a7b4fbe76e02d97cf1afedb689662926036 Mon Sep 17 00:00:00 2001 From: Anthony Berton <34568357+BB2A-Anthony@users.noreply.github.com> Date: Sat, 24 Jan 2026 16:23:36 +0100 Subject: [PATCH 26/40] FIX - Select warehouse on propal list (#36746) * FIX - Select warehouse on propal list * Solve CI error --------- Co-authored-by: Anthony Berton --- htdocs/comm/propal/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index a5e917d9cf4..b6cd8ea0d30 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -1220,7 +1220,7 @@ if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ $formproduct = new FormProduct($db); $moreforfilter .= '
'; $tmptitle = $langs->trans('Warehouse'); - $moreforfilter .= img_picto($tmptitle, 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($search_warehouse, 'search_warehouse'); + $moreforfilter .= img_picto($tmptitle, 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', $tmptitle, 0, 0, '', 0, 0, array(), 'maxwidth250 widthcentpercentminusx'); $moreforfilter .= '
'; } $parameters = array(); From adc4405d98d1e94f1e5b2d2a4cb77110092bb677 Mon Sep 17 00:00:00 2001 From: Anthony Berton <34568357+BB2A-Anthony@users.noreply.github.com> Date: Sat, 24 Jan 2026 16:26:14 +0100 Subject: [PATCH 27/40] FIX - Select warehouse on propal create (#36745) * FIX - Select warehouse on propal create * Solve CI Errror * clean * clean --------- Co-authored-by: Anthony Berton Co-authored-by: Laurent Destailleur --- htdocs/comm/propal/card.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 081f58a5798..8ed43cb19cd 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -20,6 +20,7 @@ * Copyright (C) 2024-2025 MDW * Copyright (C) 2024 Alexandre Spangaro * Copyright (C) 2025 Benjamin Falière + * Copyright (C) 2025 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -159,6 +160,8 @@ if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->tabl } $price_base_type = null; +$shipping_method_id = null; +$warehouse_id = -1; // Security check if (!empty($user->socid)) { @@ -2261,7 +2264,7 @@ if ($action == 'create') { $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0)); $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0)); - $warehouse_id = (!empty($objectsrc->warehouse_id) ? $objectsrc->warehouse_id : (!empty($soc->warehouse_id) ? $soc->warehouse_id : 0)); + $warehouse_id = (!empty($objectsrc->warehouse_id) ? $objectsrc->warehouse_id : (!empty($soc->warehouse_id) ? $soc->warehouse_id : -1)); // Replicate extrafields $objectsrc->fetch_optionals(); @@ -2285,7 +2288,7 @@ if ($action == 'create') { $mode_reglement_id = empty($soc->mode_reglement_id) ? $mode_reglement_id : $soc->mode_reglement_id; $fk_account = empty($soc->fk_account) ? $fk_account : $soc->fk_account; $shipping_method_id = $soc->shipping_method_id; - $warehouse_id = $soc->fk_warehouse; + $warehouse_id = !empty($soc->fk_warehouse) ? $soc->fk_warehouse : $warehouse_id; $remise_percent = $soc->remise_percent; if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) { @@ -2313,7 +2316,7 @@ if ($action == 'create') { if ($soc->fk_warehouse > 0) { $warehouse_id = $soc->fk_warehouse; } - if (isModEnabled('stock') && empty($warehouse_id) && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL')) { + if (isModEnabled('stock') && $warehouse_id < 0 && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL')) { if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) { $warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE'); } @@ -2354,8 +2357,6 @@ if ($action == 'create') { // Third party print ''; print ''.$langs->trans('Customer').''; - $shipping_method_id = 0; - $warehouse_id = 0; if ($socid > 0) { print ''; print $soc->getNomUrl(1, 'customer'); @@ -2364,7 +2365,6 @@ if ($action == 'create') { if (getDolGlobalString('SOCIETE_ASK_FOR_SHIPPING_METHOD') && !empty($soc->shipping_method_id)) { $shipping_method_id = $soc->shipping_method_id; } - //$warehouse_id = $soc->warehouse_id; } else { print ''; $filter = '((s.client:IN:1,2,3) AND (s.status:=:1))'; From 8dafeb0984909a2f440b3f0b525fd9491d26007a Mon Sep 17 00:00:00 2001 From: Anthony Berton <34568357+BB2A-Anthony@users.noreply.github.com> Date: Sat, 24 Jan 2026 16:28:08 +0100 Subject: [PATCH 28/40] FIX - Save param SYSTEMTOOLS_MYSQLDUMP and SYSTEMTOOLS_POSTGRESQLDUMP (#36791) * FIX - Save param SYSTEMTOOLS_MYSQLDUMP and SYSTEMTOOLS_POSTGRESQLDUMP * Fix copyright formatting for Anthony Berton --------- Co-authored-by: Anthony Berton --- htdocs/admin/tools/export.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/htdocs/admin/tools/export.php b/htdocs/admin/tools/export.php index f0276835c66..04a59374055 100644 --- a/htdocs/admin/tools/export.php +++ b/htdocs/admin/tools/export.php @@ -1,10 +1,11 @@ - * Copyright (C) 2011 Juanjo Menent - * Copyright (C) 2015 Raphaël Doursenaud +/* Copyright (C) 2006-2014 Laurent Destailleur + * Copyright (C) 2011 Juanjo Menent + * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2021 Regis Houssin - * Copyright (C) 2024 Frédéric France - * Copyright (C) 2025 MDW + * Copyright (C) 2024 Frédéric France + * Copyright (C) 2025 MDW + * Copyright (C) 2025 Anthony Berton * * 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 @@ -152,7 +153,7 @@ if ($what == 'mysql') { } if (!$errormsg && $cmddump) { - dolibarr_set_const($db, 'SYSTEMTOOLS_MYSQLDUMP', $cmddump, 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, 'SYSTEMTOOLS_MYSQLDUMP', $cmddump, 'chaine', 0, '', 0); } if (!$errormsg) { @@ -192,7 +193,7 @@ if ($what == 'postgresql') { } */ if (!$errormsg && $cmddump) { - dolibarr_set_const($db, 'SYSTEMTOOLS_POSTGRESQLDUMP', $cmddump, 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, 'SYSTEMTOOLS_POSTGRESQLDUMP', $cmddump, 'chaine', 0, '', 0); } if (!$errormsg) { From 685ec968070298567bf767224e7210863f09231d Mon Sep 17 00:00:00 2001 From: Joachim Kueter Date: Sun, 25 Jan 2026 14:12:40 +0100 Subject: [PATCH 29/40] FIX #36961 - not showing financial data related to task times (#36963) * FIX #36961 - not showing financial data related to task times see detailed description in issue #36961 when users have minimal rights to just record their task times, they should not see the calculated hourly rates * Minor change * Update element.php --------- Co-authored-by: Laurent Destailleur --- htdocs/projet/element.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 5174ce0b36b..40d2234d902 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -9,7 +9,9 @@ * Copyright (C) 2021-2023 Gauthier VERDOL * Copyright (C) 2021 Noé Cendrier * Copyright (C) 2023-2024 Frédéric France - * Copyright (C) 2024-2025 MDW + * Copyright (C) 2024-2025 MDW + * Copyright (C) 2026 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 * the Free Software Foundation; either version 3 of the License, or @@ -196,6 +198,17 @@ $hookmanager->initHooks(array('projectOverview')); //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignment. $result = restrictedArea($user, 'projet', $object->id, 'projet&project'); +// Check if user has access to any financial module (not just project time) +$canSeeFinancials = ( + (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) + || (isModEnabled('supplier_invoice') && ($user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'lire'))) + || (isModEnabled('salaries') && $user->hasRight('salaries', 'read')) + || (isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire')) + || (isModEnabled('don') && $user->hasRight('don', 'lire')) + || (isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) + || (isModEnabled('bank') && $user->hasRight('banque', 'lire')) +); + $total_duration = 0; $total_ttc_by_line = 0; $total_ht_by_line = 0; @@ -632,7 +645,7 @@ $listofreferent = array( 'margin' => 'minus', 'table' => 'projet_task', 'datefieldname' => 'element_date', - 'disableamount' => 0, + 'disableamount' => ($canSeeFinancials ? 0 : 1), 'urlnew' => DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&action=createtime&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id), 'buttonnew' => 'AddTimeSpent', 'testnew' => $user->hasRight('project', 'creer'), @@ -842,6 +855,10 @@ foreach ($listofreferent as $key => $value) { $tablename = $value['table']; $datefieldname = $value['datefieldname']; $qualified = $value['test']; + // Hide project_task amounts in profit section for users without financial access + if ($key === 'project_task' && !$canSeeFinancials) { + $qualified = false; + } $margin = empty($value['margin']) ? 0 : $value['margin']; $project_field = empty($value['project_field']) ? '' : $value['project_field']; if ($qualified) { // If this element must be included into profit summary table ($margin is '', 'minus' or 'add') From c1ab24f227e44f21af48cfaf07399b6bf58efcb0 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 25 Jan 2026 14:14:24 +0100 Subject: [PATCH 30/40] FIX #36980 Accounting - Error on create return operation (#36982) --- htdocs/accountancy/class/bookkeeping.class.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 3422cbbe455..51a9d8844da 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -1,11 +1,11 @@ - * Copyright (C) 2015-2025 Alexandre Spangaro + * Copyright (C) 2015-2026 Alexandre Spangaro * Copyright (C) 2015-2020 Florian Henry * Copyright (C) 2018-2025 Frédéric France * Copyright (C) 2024-2025 MDW - * Copyright (C) 2024 Jose MARTINEZ - * Copyright (C) 2025 Nicolas Barrouillet + * Copyright (C) 2024 Jose MARTINEZ + * Copyright (C) 2025 Nicolas Barrouillet * * 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 @@ -3756,7 +3756,7 @@ class BookKeeping extends CommonObject $newBookKeeping->sens = 'D'; } - $newBookKeeping->label_operation = "Extourne " . $bookKeeping->piece_num . " - " . $bookKeeping->numero_compte . " - " . date('d/m/Y', dol_now()) . " - " . $i; + $newBookKeeping->label_operation = $langs->trans("ReturnAccount") . " " . $bookKeeping->piece_num . " - " . $bookKeeping->numero_compte . " - " . date('d/m/Y', dol_now()) . " - " . $i; $newBookKeeping->numero_compte = $bookKeeping->numero_compte; $newBookKeeping->label_compte = $bookKeeping->label_compte; @@ -3772,14 +3772,14 @@ class BookKeeping extends CommonObject } $createResult = $newBookKeeping->create($user); - if ($createResult > 0) { + if ($createResult >= 0) { $newBookKeeping->piece_num = $pieceNumNext; $newBookKeeping->fk_doc = $bookKeeping->fk_doc; $newBookKeeping->fk_docdet = $bookKeeping->fk_docdet; - $result = $newBookKeeping->update($user); + $newBookKeeping->update($user); setEventMessages($langs->trans("SuccessReturnedAccount", $bookKeeping->piece_num), null, 'mesgs'); } else { - setEventMessages($langs->trans("ErrorWhileCreating", $newBookKeeping->error), null, 'errors'); + setEventMessages($langs->trans("ErrorWhileCreating", $newBookKeeping->error), $newBookKeeping->errors, 'errors'); $error++; } } From 3822ae8e77e94679a7b27aaf42acca4bba924967 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 25 Jan 2026 15:49:44 +0100 Subject: [PATCH 31/40] Debug v23 --- htdocs/langs/en_US/products.lang | 7 +++---- htdocs/product/admin/product.php | 23 ++++++++++------------- htdocs/product/price.php | 14 +++++++------- htdocs/product/price_suppliers.php | 4 ++-- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index bbb5b39ec6e..c475828d075 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -345,12 +345,11 @@ PossibleValues=Possible values GoOnMenuToCreateVairants=Go on menu %s - %s to prepare attribute variants (like colors, size, ...) UseProductFournDesc=Add a feature to define the product description defined by the vendors (for each vendor reference) in addition to the description for customers ProductSupplierDescription=Vendor description for the product -UseProductSupplierPackaging=Use the "%s" feature to round the quantities to some given multiples. +UseProductSupplierPackaging=Use the "%s" feature to round the quantities to some given multiples (for Purchases). PackagingForThisProduct=Round quantities up to a multiple -PackagingForThisProductDesc=When adding/updating line in a vendor documents, the quantity is adjusted to match the nearest higher multiple of the value defined on product. -UseProductCustomerPackaging=Use the "packaging" feature to round the quantities to some given multiples (when adding/updating line in a customer documents, the quantity is adjusted to match the nearest higher multiple of the "packaging" value of the product) +PackagingForThisProductDesc=When adding/updating a line in a documents, the quantity is adjusted to match the nearest higher multiple of the value defined on product. +UseProductCustomerPackaging=Use the "%s" feature to round the quantities to some given multiples (for Sales) PackagingForThisProductSell=Packaging of quantities (sale) -PackagingForThisProductSellDesc=You will automatically sell a multiple of this quantity. QtyRecalculatedWithPackaging=The quantity of the line were recalculated according to supplier packaging #Attributes diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index dda84bb9504..b0107d05e78 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -643,13 +643,22 @@ print $form->selectPriceBaseType($conf->global->PRODUCT_PRICE_BASE_TYPE, "price_ print ''; print ''; +// Use packaging during your sales +if (isModEnabled("order") || isModEnabled("invoice")) { + print ''; + print ''.$form->textwithpicto($langs->trans("UseProductCustomerPackaging", $langs->transnoentities("PackagingForThisProduct")), $langs->trans("PackagingForThisProductDesc")).''; + print ''; + print ajax_constantonoff("PRODUCT_USE_CUSTOMER_PACKAGING", array(), $conf->entity, 0, 0, 0, 0); + print ''; + print ''; +} + // Use conditionnement in buying if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { print ''; print ''.$form->textwithpicto($langs->trans("UseProductSupplierPackaging", $langs->transnoentities("PackagingForThisProduct")), $langs->trans("PackagingForThisProductDesc")).''; print ''; print ajax_constantonoff("PRODUCT_USE_SUPPLIER_PACKAGING", array(), $conf->entity, 0, 0, 0, 0); - //print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING) ? $conf->global->PRODUCT_USE_SUPPLIER_PACKAGING : 0), 1); print ''; print ''; @@ -657,18 +666,6 @@ if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { print ''.$langs->trans("UseProductFournDesc").''; print ''; print ajax_constantonoff("PRODUIT_FOURN_TEXTS", array(), $conf->entity, 0, 0, 0, 0); - //print $form->selectyesno("activate_useProdFournDesc", (!empty($conf->global->PRODUIT_FOURN_TEXTS) ? $conf->global->PRODUIT_FOURN_TEXTS : 0), 1); - print ''; - print ''; -} - -// Use packaging during your sales -if (isModEnabled("order") || isModEnabled("invoice")) { - print ''; - print ''.$form->textwithpicto($langs->trans("UseProductCustomerPackaging"), $langs->trans("PackagingForThisProductSellDesc")).''; - print ''; - print ajax_constantonoff("PRODUCT_USE_CUSTOMER_PACKAGING", array(), $conf->entity, 0, 0, 0, 0); - //print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_CUSTOMER_PACKAGING) ? $conf->global->PRODUCT_USE_CUSTOMER_PACKAGING : 0), 1); print ''; print ''; } diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 2f74e87986a..56963d174bf 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1444,7 +1444,7 @@ if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUS // Packaging if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { - print ''.$form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductSellDesc")).''; + print ''.$form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductDesc")).''; print $object->packaging; print ''; } @@ -1725,9 +1725,9 @@ if (($action == 'edit_price' || $action == 'edit_level_price') && $object->getRi print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", getDolGlobalString('MAIN_MAX_DECIMALS_UNIT')), 1, 'help'); print ''; if ($object->price_base_type == 'TTC') { - print ''; + print ''; } else { - print ''; + print ''; } if (getDolGlobalString('PRODUCT_MINIMUM_RECOMMENDED_PRICE')) { print '   '.$langs->trans("MinimumRecommendedPrice", price((float) $maxpricesupplier, 0, '', 1, -1, -1, 'auto')).' '.img_warning().''; @@ -1738,10 +1738,10 @@ if (($action == 'edit_price' || $action == 'edit_level_price') && $object->getRi // Packaging if (getDolGlobalString('PRODUCT_USE_CUSTOMER_PACKAGING')) { print ''; - print $form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductSellDesc")); + print $form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductDesc")); print ''; $packaging = $object->packaging; - print ''; + print ''; print ''; print ''; } @@ -2761,8 +2761,8 @@ if ((!getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || $action == 'showlog_defau if (!$num) { $db->free($result); - // Il doit au moins y avoir la ligne de prix initial. - // On l'ajoute donc pour remettre a niveau (pb vieilles versions) + // We must have at least one initial line + // We add it to fix this if not (trouble with old versions) // We emulate the change of the price from interface with the same value than the one into table llx_product if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { $ret = $object->updatePrice(($object->multiprices_base_type[1] == 'TTC' ? $object->multiprices_ttc[1] : $object->multiprices[1]), $object->multiprices_base_type[1], $user, (empty($object->multiprices_tva_tx[1]) ? 0 : $object->multiprices_tva_tx[1]), ($object->multiprices_base_type[1] == 'TTC' ? $object->multiprices_min_ttc[1] : $object->multiprices_min[1]), 1); diff --git a/htdocs/product/price_suppliers.php b/htdocs/product/price_suppliers.php index d04fb5feaf3..c3cd53b467c 100644 --- a/htdocs/product/price_suppliers.php +++ b/htdocs/product/price_suppliers.php @@ -613,9 +613,9 @@ if ($id > 0 || $ref) { // Packaging/Conditionnement print ''; - print ''.$form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductDesc")).''; + print ''.$form->textwithpicto($langs->trans("PackagingForThisProduct"), $langs->trans("PackagingForThisProductDesc")).''; print ''; - $packaging = GETPOSTISSET('packaging') ? price2num(GETPOST('packaging', 'alphanohtml'), 'MS') : ((empty($rowid)) ? "1" : price2num($object->packaging, 'MS')); + $packaging = GETPOSTISSET('packaging') ? price2num(GETPOST('packaging', 'alphanohtml'), 'MS') : ((empty($rowid)) ? "" : price2num($object->packaging, 'MS')); print ''; // Units From 98cba6a94a5140a9131d449d79912e12b460d6f6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 25 Jan 2026 16:01:31 +0100 Subject: [PATCH 32/40] Trans --- htdocs/categories/class/categorie.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 0847d1f75c7..777b59b4536 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -2040,7 +2040,7 @@ class Categorie extends CommonObject * Return an array with all photos inside the directory * * @param string $dir Dir to scan - * @param int $nbmax Nombre maximum de photos (0=pas de max) + * @param int $nbmax Maximum number of photos (0=no max) * @return array Table with images */ public function liste_photos($dir, $nbmax = 0) From 7efb82fc796fb2d3d97ba867c1315329549f4c53 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 26 Jan 2026 11:48:34 +0100 Subject: [PATCH 33/40] Update VAT rate by default (#36988) * Update VAT rate for Nederland * Update VAT rate for Italy --- htdocs/install/mysql/data/llx_c_tva.sql | 31 +++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql index 88b3afc8d4d..7f99eb8f9ed 100644 --- a/htdocs/install/mysql/data/llx_c_tva.sql +++ b/htdocs/install/mysql/data/llx_c_tva.sql @@ -1,14 +1,15 @@ --- Copyright (C) 2001-2004 Rodolphe Quiedeville --- Copyright (C) 2003 Jean-Louis Bergamo --- Copyright (C) 2004-2011 Laurent Destailleur --- Copyright (C) 2004 Benoit Mortier --- Copyright (C) 2004 Guillaume Delecourt --- Copyright (C) 2005-2025 Regis Houssin --- Copyright (C) 2007 Patrick Raguin --- Copyright (C) 2010-2016 Juanjo Menent --- Copyright (C) 2012 Sebastian Neuwert --- Copyright (C) 2012 Ricardo Schluter --- Copyright (C) 2022 Miro Sertić +-- Copyright (C) 2001-2004 Rodolphe Quiedeville +-- Copyright (C) 2003 Jean-Louis Bergamo +-- Copyright (C) 2004-2011 Laurent Destailleur +-- Copyright (C) 2004 Benoit Mortier +-- Copyright (C) 2004 Guillaume Delecourt +-- Copyright (C) 2005-2025 Regis Houssin +-- Copyright (C) 2007 Patrick Raguin +-- Copyright (C) 2010-2016 Juanjo Menent +-- Copyright (C) 2012 Sebastian Neuwert +-- Copyright (C) 2012 Ricardo Schluter +-- Copyright (C) 2022 Miro Sertić +-- Copyright (C) 2026 Alexandre Spangaro -- -- 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 @@ -188,7 +189,8 @@ insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (8 -- ITALY (id country=3) insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (3, '0','0','VAT rate 0',1,__ENTITY__); -insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (3, '10','0','VAT rate - reduced',1,__ENTITY__); +insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (3, '10','0','VAT rate - reduced 1',1,__ENTITY__); +insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (3, '5','0','VAT rate - reduced 2',1,__ENTITY__); insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (3, '4','0','VAT rate - super-reduced',1,__ENTITY__); insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (3, '22','0','VAT rate - standard',1,__ENTITY__); @@ -235,9 +237,8 @@ insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (1 -- NEDERLAND (id country=17) insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (17, '0','0','0 BTW tarief', 1,__ENTITY__); -insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (17, '6','0','Verlaagd BTW tarief', 1,__ENTITY__); -insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (17, '19','0','Algemeen BTW tarief',1,__ENTITY__); -insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (17, '21','0','Algemeen BTW tarief (vanaf 1 oktober 2012)',0,__ENTITY__); +insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (17, '9','0','Verlaagd BTW tarief', 1,__ENTITY__); +insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (17, '21','0','Algemeen BTW tarief',0,__ENTITY__); -- NEW CALEDONIA (id country=165) insert into llx_c_tva(fk_pays,taux,recuperableonly,note,active,entity) values (165, '0','0','VAT rate 0', 1,__ENTITY__); From e3323c3ff17a655b48928cfbbac8dd52e9c6a09d Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 26 Jan 2026 11:49:46 +0100 Subject: [PATCH 34/40] Remove message for Invoice Situation level 2 - Need more test (#36987) --- htdocs/accountancy/index.php | 2 ++ htdocs/index.php | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php index 0577cac80fa..c10ca3155c1 100644 --- a/htdocs/accountancy/index.php +++ b/htdocs/accountancy/index.php @@ -122,12 +122,14 @@ if (isModEnabled('accounting')) { print load_fiche_titre($langs->trans("AccountancyArea"), empty($resultboxes['selectboxlist']) ? '' : $resultboxes['selectboxlist'], 'accountancy', 0, '', '', $showtutorial); + /* if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) { $messagewarning = $langs->trans("SorryThisModuleIsNotCompatibleWithTheExperimentalFeatureOfSituationInvoices"); $messagewarning .= ' '.$langs->trans("WarningExperimentalFeatureInvoiceSituationNeedToUpgradeToProgressiveMode", 'https://partners.dolibarr.org'); print info_admin($messagewarning); print "
"; } + */ if (!$helpisexpanded && empty($resultboxes['boxlista']) && empty($resultboxes['boxlistb'])) { print '

'.$langs->trans("ClickOnUseTutorialForHelp", $langs->transnoentities("ShowTutorial"))."
\n"; diff --git a/htdocs/index.php b/htdocs/index.php index 68fce7df62d..b8a68617714 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -118,11 +118,13 @@ if (getDolGlobalString('MAIN_MOTD')) { */ // Specific warning to propose to upgrade invoice situation to progressive mode -if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1 && (float) DOL_VERSION >= 22.0) { +/* +if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) { $langs->loadLangs(array("admin")); print info_admin($langs->trans("WarningExperimentalFeatureInvoiceSituationNeedToUpgradeToProgressiveMode", 'https://partners.dolibarr.org')); //print "
"; } +*/ /* * Show security warnings From 35847a94f099fa8ba186fb6e48872f3d37aff7f2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 26 Jan 2026 14:32:30 +0100 Subject: [PATCH 35/40] Debug v23 --- htdocs/admin/boxes.php | 4 +++- htdocs/core/boxes/modules_boxes.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/boxes.php b/htdocs/admin/boxes.php index 1fb6989ddcb..bf411ab481e 100644 --- a/htdocs/admin/boxes.php +++ b/htdocs/admin/boxes.php @@ -459,7 +459,9 @@ print ''; print ''; // Activate FileCache (so content of file boxes are stored into a cache file int boxes/temp for 3600 seconds) -print ''.$langs->trans("EnableFileCache").''; +print ''.$langs->trans("EnableFileCache"); +print ' ('.getDolGlobalInt('MAIN_ACTIVATE_FILECACHE_DELAY', 900)." ".$langs->trans("seconds").")"; +print ''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('MAIN_ACTIVATE_FILECACHE', array(), null, 0, 0, 0, 2, 0, 1); } else { diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 7a81d210e88..d7d85fbe8b6 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -265,7 +265,7 @@ class ModeleBoxes // Can't be abstract as it is instantiated to build "empty" bo $MAXLENGTHBOX = 0; // When set to 0: no length limit - $cachetime = 900; // 900 : 15mn + $cachetime = getDolGlobalInt('MAIN_ACTIVATE_FILECACHE_DELAY', 900); // 900 : 15mn $cachedir = DOL_DATA_ROOT.'/users/temp/widgets'; $fileid = get_class($this).'id-'.$this->box_id.'-e'.$conf->entity.'-u'.$user->id.'-s'.$user->socid.'.cache'; $filename = '/box-'.$fileid; From e6fc3833558163a93bd48006e49f21c2b13c4168 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 26 Jan 2026 15:06:18 +0100 Subject: [PATCH 36/40] CSS v23 --- .../adherents/class/adherent_type.class.php | 2 +- htdocs/main.inc.php | 218 +++++++++--------- htdocs/theme/eldy/global.inc.php | 10 + htdocs/theme/md/style.css.php | 14 ++ 4 files changed, 135 insertions(+), 109 deletions(-) diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index f03d1099c41..3c203d5aea8 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -1183,7 +1183,7 @@ class AdherentType extends CommonObject //$return .= ''; if ($user->hasRight('adherent', 'configurer')) { - $return .= 'ref).'">'.img_edit().''; + $return .= 'ref).'">'.img_edit().''; } else { $return .= ' '; } diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 6ccd99fd547..1e2c15dd3ae 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -3257,121 +3257,123 @@ function left_menu($menu_array_before, $helppagename = '', $notused = '', $menu_ } // Dolibarr version + help + bug report link - print "\n"; - print "\n"; - print '
'."\n"; + if (getDolGlobalString('MAIN_SHOW_VERSION') || getDolGlobalString('MAIN_BUGTRACK_ENABLELINK')) { + print "\n"; + print "\n"; + print '
'."\n"; - // Version - if (getDolGlobalString('MAIN_SHOW_VERSION')) { // Version is already on help picto and on login page. - $doliurl = 'https://www.dolibarr.org'; - //local communities - if (preg_match('/fr/i', $langs->defaultlang)) { - $doliurl = 'https://www.dolibarr.fr'; - } - if (preg_match('/es/i', $langs->defaultlang)) { - $doliurl = 'https://www.dolibarr.es'; - } - if (preg_match('/de/i', $langs->defaultlang)) { - $doliurl = 'https://www.dolibarr.de'; - } - if (preg_match('/it/i', $langs->defaultlang)) { - $doliurl = 'https://www.dolibarr.it'; - } - if (preg_match('/gr/i', $langs->defaultlang)) { - $doliurl = 'https://www.dolibarr.gr'; + // Version + if (getDolGlobalString('MAIN_SHOW_VERSION')) { // Version is already on help picto and on login page. + $doliurl = 'https://www.dolibarr.org'; + //local communities + if (preg_match('/fr/i', $langs->defaultlang)) { + $doliurl = 'https://www.dolibarr.fr'; + } + if (preg_match('/es/i', $langs->defaultlang)) { + $doliurl = 'https://www.dolibarr.es'; + } + if (preg_match('/de/i', $langs->defaultlang)) { + $doliurl = 'https://www.dolibarr.de'; + } + if (preg_match('/it/i', $langs->defaultlang)) { + $doliurl = 'https://www.dolibarr.it'; + } + if (preg_match('/gr/i', $langs->defaultlang)) { + $doliurl = 'https://www.dolibarr.gr'; + } + + $appli = constant('DOL_APPLICATION_TITLE'); + $applicustom = getDolGlobalString('MAIN_APPLICATION_TITLE'); + if ($applicustom) { + $appli = (preg_match('/^\+/', $applicustom) ? $appli : '').$applicustom; + } else { + $appli .= " ".DOL_VERSION; + } + + // Clean doliurl if we use a custom application name + if ($applicustom) { + $doliurl = ''; + } + + print '
'; + if ($doliurl) { + print ''; + } else { + print ''; + } + print $appli; + if ($doliurl) { + print ''; + } else { + print ''; + } + print '
'."\n"; } - $appli = constant('DOL_APPLICATION_TITLE'); - $applicustom = getDolGlobalString('MAIN_APPLICATION_TITLE'); - if ($applicustom) { - $appli = (preg_match('/^\+/', $applicustom) ? $appli : '').$applicustom; - } else { - $appli .= " ".DOL_VERSION; + // Link to bugtrack + if (getDolGlobalString('MAIN_BUGTRACK_ENABLELINK')) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + + if (getDolGlobalString('MAIN_BUGTRACK_ENABLELINK') == 'github') { + $bugbaseurl = 'https://github.com/Dolibarr/dolibarr/issues/new?labels=Bug'; + $bugbaseurl .= '&title='; + $bugbaseurl .= urlencode("Bug: "); + $bugbaseurl .= '&body='; + $bugbaseurl .= urlencode("# Instructions\n"); + $bugbaseurl .= urlencode("*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.*\n"); + $bugbaseurl .= urlencode("*Please:*\n"); + $bugbaseurl .= urlencode("- *replace the bracket enclosed texts with meaningful information*\n"); + $bugbaseurl .= urlencode("- *remove any unused sub-section*\n"); + $bugbaseurl .= urlencode("\n"); + $bugbaseurl .= urlencode("\n"); + $bugbaseurl .= urlencode("# Bug\n"); + $bugbaseurl .= urlencode("[*Short description*]\n"); + $bugbaseurl .= urlencode("\n"); + $bugbaseurl .= urlencode("## Environment\n"); + $bugbaseurl .= urlencode("- **Version**: ".DOL_VERSION."\n"); + $bugbaseurl .= urlencode("- **OS**: ".php_uname('s')."\n"); + $bugbaseurl .= urlencode("- **Web server**: ".$_SERVER["SERVER_SOFTWARE"]."\n"); + $bugbaseurl .= urlencode("- **PHP**: ".php_sapi_name().' '.phpversion()."\n"); + $bugbaseurl .= urlencode("- **Database**: ".$db::LABEL.' '.$db->getVersion()."\n"); + $bugbaseurl .= urlencode("- **URL(s)**: ".$_SERVER["REQUEST_URI"]."\n"); + $bugbaseurl .= urlencode("\n"); + $bugbaseurl .= urlencode("## Expected and actual behavior\n"); + $bugbaseurl .= urlencode("[*Verbose description*]\n"); + $bugbaseurl .= urlencode("\n"); + $bugbaseurl .= urlencode("## Steps to reproduce the behavior\n"); + $bugbaseurl .= urlencode("[*Verbose description*]\n"); + $bugbaseurl .= urlencode("\n"); + $bugbaseurl .= urlencode("## [Attached files](https://help.github.com/articles/issue-attachments) (Screenshots, screencasts, dolibarr.log, debugging information…)\n"); + $bugbaseurl .= urlencode("[*Files*]\n"); + $bugbaseurl .= urlencode("\n"); + + $bugbaseurl .= urlencode("\n"); + $bugbaseurl .= urlencode("## Report\n"); + } elseif (getDolGlobalString('MAIN_BUGTRACK_ENABLELINK')) { + $bugbaseurl = getDolGlobalString('MAIN_BUGTRACK_ENABLELINK'); + } else { + $bugbaseurl = ""; + } + + // Execute hook printBugtrackInfo + $parameters = array('bugbaseurl' => $bugbaseurl); + $reshook = $hookmanager->executeHooks('printBugtrackInfo', $parameters); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) { + $bugbaseurl .= $hookmanager->resPrint; + } else { + $bugbaseurl = $hookmanager->resPrint; + } + + print '
'; + print ' '.$langs->trans("FindBug").''; + print '
'; } - // Clean doliurl if we use a custom application name - if ($applicustom) { - $doliurl = ''; - } - - print '
'; - if ($doliurl) { - print ''; - } else { - print ''; - } - print $appli; - if ($doliurl) { - print ''; - } else { - print ''; - } - print '
'."\n"; + print "
\n"; + print "\n"; + print "\n"; } - // Link to bugtrack - if (getDolGlobalString('MAIN_BUGTRACK_ENABLELINK')) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - - if (getDolGlobalString('MAIN_BUGTRACK_ENABLELINK') == 'github') { - $bugbaseurl = 'https://github.com/Dolibarr/dolibarr/issues/new?labels=Bug'; - $bugbaseurl .= '&title='; - $bugbaseurl .= urlencode("Bug: "); - $bugbaseurl .= '&body='; - $bugbaseurl .= urlencode("# Instructions\n"); - $bugbaseurl .= urlencode("*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.*\n"); - $bugbaseurl .= urlencode("*Please:*\n"); - $bugbaseurl .= urlencode("- *replace the bracket enclosed texts with meaningful information*\n"); - $bugbaseurl .= urlencode("- *remove any unused sub-section*\n"); - $bugbaseurl .= urlencode("\n"); - $bugbaseurl .= urlencode("\n"); - $bugbaseurl .= urlencode("# Bug\n"); - $bugbaseurl .= urlencode("[*Short description*]\n"); - $bugbaseurl .= urlencode("\n"); - $bugbaseurl .= urlencode("## Environment\n"); - $bugbaseurl .= urlencode("- **Version**: ".DOL_VERSION."\n"); - $bugbaseurl .= urlencode("- **OS**: ".php_uname('s')."\n"); - $bugbaseurl .= urlencode("- **Web server**: ".$_SERVER["SERVER_SOFTWARE"]."\n"); - $bugbaseurl .= urlencode("- **PHP**: ".php_sapi_name().' '.phpversion()."\n"); - $bugbaseurl .= urlencode("- **Database**: ".$db::LABEL.' '.$db->getVersion()."\n"); - $bugbaseurl .= urlencode("- **URL(s)**: ".$_SERVER["REQUEST_URI"]."\n"); - $bugbaseurl .= urlencode("\n"); - $bugbaseurl .= urlencode("## Expected and actual behavior\n"); - $bugbaseurl .= urlencode("[*Verbose description*]\n"); - $bugbaseurl .= urlencode("\n"); - $bugbaseurl .= urlencode("## Steps to reproduce the behavior\n"); - $bugbaseurl .= urlencode("[*Verbose description*]\n"); - $bugbaseurl .= urlencode("\n"); - $bugbaseurl .= urlencode("## [Attached files](https://help.github.com/articles/issue-attachments) (Screenshots, screencasts, dolibarr.log, debugging information…)\n"); - $bugbaseurl .= urlencode("[*Files*]\n"); - $bugbaseurl .= urlencode("\n"); - - $bugbaseurl .= urlencode("\n"); - $bugbaseurl .= urlencode("## Report\n"); - } elseif (getDolGlobalString('MAIN_BUGTRACK_ENABLELINK')) { - $bugbaseurl = getDolGlobalString('MAIN_BUGTRACK_ENABLELINK'); - } else { - $bugbaseurl = ""; - } - - // Execute hook printBugtrackInfo - $parameters = array('bugbaseurl' => $bugbaseurl); - $reshook = $hookmanager->executeHooks('printBugtrackInfo', $parameters); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) { - $bugbaseurl .= $hookmanager->resPrint; - } else { - $bugbaseurl = $hookmanager->resPrint; - } - - print '
'; - print ' '.$langs->trans("FindBug").''; - print '
'; - } - - print "
\n"; - print "\n"; - print "\n"; - print "\n"; print "\n"; print "\n"; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 36754b99083..f36c3ebdd63 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1892,6 +1892,15 @@ select.flat.selectlimit { width: 250px; } +.showonhover:hover *::before { + visibility: visible !important; + display: inline-block !important; +} +.showonhover:not(:hover) *::before { + visibility: hidden; + display: inline-block !important; +} + /* Styles for amount on card */ table.paymenttable td.amountpaymentcomplete, table.paymenttable td.amountremaintopay, table.paymenttable td.amountremaintopayback { padding-top: 0px; @@ -2608,6 +2617,7 @@ td.showDragHandle { display: table-cell; border-: 1px solid #ECECEC; + border-bottom: 1px solid #ECECEC; box-shadow: 3px 0 6px -2px #eee; background: var(--colorbackvmenu1); transition: left 0.5s ease; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index f9cfea0c09c..af98d7a9715 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2014,6 +2014,10 @@ select.flat.selectlimit { .tablelistofcalendars { margin-top: 25px !important; } +.navselectiondate { + width: 250px; +} + .amountalreadypaid { white-space: nowrap; } @@ -2063,6 +2067,16 @@ select.flat.selectlimit { border-radius: 5px; } +.showonhover:hover *::before { + visibility: visible !important; + display: inline-block !important; +} +.showonhover:not(:hover) *::before { + visibility: hidden; + display: inline-block !important; +} + + .savingdocmask { margin-top: 6px; margin-bottom: 12px; From 1db633ee4346b1f01a7bb82afd5529a4e2d6a928 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 26 Jan 2026 15:09:45 +0100 Subject: [PATCH 37/40] Debug v23 --- htdocs/don/admin/website.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/htdocs/don/admin/website.php b/htdocs/don/admin/website.php index ef87706c6d2..dfcf86178ac 100644 --- a/htdocs/don/admin/website.php +++ b/htdocs/don/admin/website.php @@ -29,12 +29,6 @@ // Load Dolibarr environment require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/donation.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -44,6 +38,11 @@ require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; * * @var string $dolibarr_main_url_root */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/donation.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; // Load translation files required by the page $langs->loadLangs(array("admin", "donations")); @@ -120,7 +119,7 @@ print '
'; print ''; print ''; -print dol_get_fiche_head($head, 'website', $langs->trans("Donations"), -1, 'user'); +print dol_get_fiche_head($head, 'website', $langs->trans("Donations"), -1, 'payment'); if ($conf->use_javascript_ajax) { print "\n".'