From e64d1f6e468d0727147ad3d296a90de255979f59 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 6 Nov 2023 00:16:26 +0100 Subject: [PATCH 01/27] Fix phpcs --- htdocs/product/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 7dc9483b00a..4f30e146f56 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -589,7 +589,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); */ - + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; From cf3f741d4bc69b268d6562e7e7e833eaaeb438f2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 6 Nov 2023 11:02:24 +0100 Subject: [PATCH 02/27] Close #26440 --- htdocs/theme/eldy/dropdown.inc.php | 3 +++ htdocs/theme/md/dropdown.inc.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/htdocs/theme/eldy/dropdown.inc.php b/htdocs/theme/eldy/dropdown.inc.php index 87681ac023c..aa5db4c2250 100644 --- a/htdocs/theme/eldy/dropdown.inc.php +++ b/htdocs/theme/eldy/dropdown.inc.php @@ -549,6 +549,9 @@ dropdown-holder { background: none; color: #000 !important; } +.dropdown-content a.butAction { + display: flex; +} .dropdown-content .butAction:hover { box-shadow: none; text-decoration: underline; diff --git a/htdocs/theme/md/dropdown.inc.php b/htdocs/theme/md/dropdown.inc.php index 56d7e20b4f4..611760de81e 100644 --- a/htdocs/theme/md/dropdown.inc.php +++ b/htdocs/theme/md/dropdown.inc.php @@ -553,6 +553,9 @@ dropdown-holder { background: none; color: #000 !important; } +.dropdown-content a.butAction { + display: flex; +} .dropdown-content .butAction:hover { box-shadow: none; text-decoration: underline; From e94dceb0ef3be025ab7344b300b84a2b0b23dc8e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 6 Nov 2023 15:24:22 +0100 Subject: [PATCH 03/27] Fix css --- htdocs/projet/tasks/time.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 2876cadc9fb..58995267410 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -2210,7 +2210,6 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } if (!empty($arrayfields['p.project_label']['checked'])) { - print ''; if (empty($conf->cache['project'][$task_time->fk_projet])) { $tmpproject = new Project($db); $tmpproject->fetch($task_time->fk_projet); @@ -2218,7 +2217,8 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } else { $tmpproject = $conf->cache['project'][$task_time->fk_projet]; } - print $tmpproject->title; + print ''; + print dol_escape_htmltag($tmpproject->title); print ''; if (!$i) { $totalarray['nbfield']++; @@ -2250,7 +2250,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Task label if (!empty($arrayfields['t.element_label']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task - print ''; + print ''; print dol_escape_htmltag($task_time->label); print ''; if (!$i) { From 613aa3b292227b4ec3a27ab45e66a07be60e5da4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Nov 2023 02:40:30 +0100 Subject: [PATCH 04/27] Better link --- htdocs/projet/list.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 36cc92ec90c..cc3bba8129e 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -936,6 +936,9 @@ if (!empty($socid)) { } if ($search_usage_event_organization == 1) { $url .= '&usage_organize_event=1'; + if (((int) $search_usage_opportunity) < 1) { + $url .= '&usage_opportunity=0'; + } } $newcardbutton = ''; From b5e5b1d4c63de0861f7d0c98abb91c95501672ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Fali=C3=A8re?= <121813548+altairis-benjamin@users.noreply.github.com> Date: Tue, 7 Nov 2023 17:50:48 +0100 Subject: [PATCH 05/27] FIX commande context (#26497) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Benjamin Falière --- htdocs/commande/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index a8325503060..bf39beba029 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -469,7 +469,7 @@ if (empty($reshook)) { $array_options = $lines[$i]->array_options; } - $objecttmp->context['createfromclone']; + $objecttmp->context['createfromclone'] = 'createfromclone'; $rang = ($nbOrders > 1) ? -1 : $lines[$i]->rang; //there may already be rows from previous orders From 7a7869aeb346b3dab6ca0160c1aec02b1b9eb567 Mon Sep 17 00:00:00 2001 From: Pichi1966 <57623859+josett225@users.noreply.github.com> Date: Tue, 7 Nov 2023 18:10:37 +0100 Subject: [PATCH 06/27] FIX # Bug Estimated Stock at date value in V14 (#26479) In stockatdate page, the estimatedvalue is wrong. Backport of V17 solution as explained in #23782 --- htdocs/product/stock/stockatdate.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php index 4892004db72..f8c9437b928 100644 --- a/htdocs/product/stock/stockatdate.php +++ b/htdocs/product/stock/stockatdate.php @@ -242,7 +242,7 @@ $num = 0; $title = $langs->trans('StockAtDate'); -$sql = 'SELECT p.rowid, p.ref, p.label, p.description, p.price,'; +$sql = 'SELECT p.rowid, p.ref, p.label, p.description, p.price, p.pmp,'; $sql .= ' p.price_ttc, p.price_base_type, p.fk_product_type, p.desiredstock, p.seuil_stock_alerte,'; $sql .= ' p.tms as datem, p.duration, p.tobuy, p.stock, '; if ($fk_warehouse > 0) { @@ -562,8 +562,8 @@ while ($i < ($limit ? min($num, $limit) : $num)) { // PMP value print ''; - if (price2num($objp->estimatedvalue, 'MT')) { - print price(price2num($objp->estimatedvalue, 'MT'), 1); + if (price2num($stock * $objp->pmp, 'MT')) { + print ''.price(price2num($stock * $objp->pmp, 'MT'), 1).''; } else { print ''; } From 0ec3c5754d7e058c7959b468c23ae93348a45341 Mon Sep 17 00:00:00 2001 From: Pichi1966 <57623859+josett225@users.noreply.github.com> Date: Tue, 7 Nov 2023 18:13:14 +0100 Subject: [PATCH 07/27] FIX Warehouse Global Amounts not displayed (#26478) This fix is to repaired the Global Amounts that are not displayed anymore strating from v18.x --- htdocs/product/stock/list.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 8d2a5c115d4..41ee4189a3d 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -613,7 +613,6 @@ if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { } print ''."\n"; -$totalarray = array(); $totalarray['nbfield'] = 0; // Fields title label @@ -686,7 +685,6 @@ $warehouse = new Entrepot($db); // -------------------------------------------------------------------- $i = 0; $savnbfield = $totalarray['nbfield']; -$totalarray = array(); $totalarray['nbfield'] = 0; $imaxinloop = ($limit ? min($num, $limit) : $num); while ($i < $imaxinloop) { From 56e9df909126a04c97a109290eb5cef771b0b5b4 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 7 Nov 2023 18:53:37 +0100 Subject: [PATCH 08/27] FIX avoid warning : Cannot use a scalar value as an array (#26437) --- htdocs/core/class/html.formadmin.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index a0d0dd2758e..1b8f075a7b2 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -62,12 +62,15 @@ class FormAdmin * @param int $mainlangonly 1=Show only main languages ('fr_FR' no' fr_BE', 'es_ES' not 'es_MX', ...) * @return string Return HTML select string with list of languages */ - public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0, $onlykeys = null, $mainlangonly = 0) + public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = array(), $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0, $onlykeys = array(), $mainlangonly = 0) { // phpcs:enable global $conf, $langs; if (!empty($conf->global->MAIN_DEFAULT_LANGUAGE_FILTER)) { + if (!is_array($filter)) { + $filter = array(); + } $filter[$conf->global->MAIN_DEFAULT_LANGUAGE_FILTER] = 1; } From 835cf9bbc75a8fe7631bd57603a75e48c6325c57 Mon Sep 17 00:00:00 2001 From: Florian Mortgat <50440633+atm-florianm@users.noreply.github.com> Date: Tue, 7 Nov 2023 19:02:18 +0100 Subject: [PATCH 09/27] FIX v17: Param $notrigger in $societe->create() causes method to return true regardless of actual result of database functions (#26499) --- htdocs/societe/class/societe.class.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index d84673cee76..27ba1d7252b 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1010,13 +1010,15 @@ class Societe extends CommonObject $this->add_commercial($user, $user->id); } - if ($ret >= 0 && !$notrigger) { - // Call trigger - $result = $this->call_trigger('COMPANY_CREATE', $user); - if ($result < 0) { - $error++; + if ($ret >= 0) { + if (! $notrigger) { + // Call trigger + $result = $this->call_trigger('COMPANY_CREATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers } - // End call triggers } else { $error++; } From 05f42d1341fb4166295f97f6609ca2b324fb32d6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Nov 2023 11:15:23 +0100 Subject: [PATCH 10/27] Fix phpcs --- htdocs/product/stock/stockatdate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php index f8c9437b928..86c1b89eb95 100644 --- a/htdocs/product/stock/stockatdate.php +++ b/htdocs/product/stock/stockatdate.php @@ -563,7 +563,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { // PMP value print ''; if (price2num($stock * $objp->pmp, 'MT')) { - print ''.price(price2num($stock * $objp->pmp, 'MT'), 1).''; + print ''.price(price2num($stock * $objp->pmp, 'MT'), 1).''; } else { print ''; } From e8b45a1ea935d0e06418d684fe429a543b4a6046 Mon Sep 17 00:00:00 2001 From: sonikf <93765174+sonikf@users.noreply.github.com> Date: Wed, 8 Nov 2023 18:27:52 +0200 Subject: [PATCH 11/27] Fix #26050 #26225 and fiscal year report (backport v 18) (#26474) --- htdocs/compta/resultat/clientfourn.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php index 0a969dd3e79..584ece47079 100644 --- a/htdocs/compta/resultat/clientfourn.php +++ b/htdocs/compta/resultat/clientfourn.php @@ -74,11 +74,11 @@ $year = GETPOST('year', 'int'); // this is used for navigation previous/next. I if (empty($year)) { $year_current = dol_print_date(dol_now(), "%Y"); $month_current = dol_print_date(dol_now(), "%m"); - $year_start = $year_current - ($nbofyear - 1); + $year_start = $year_current; } else { $year_current = $year; $month_current = dol_print_date(dol_now(), "%m"); - $year_start = $year - $nbofyear + (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); + $year_start = $year; } $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); @@ -88,14 +88,17 @@ if (empty($date_start) || empty($date_end)) { // We define date_start and date_e $q = GETPOST("q") ? GETPOST("q", 'int') : 0; if ($q == 0) { // We define date_start and date_end - $year_end = $year_start + $nbofyear - (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); + $year_end = $year_start; $month_start = GETPOST("month") ? GETPOST("month", 'int') : getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1); if (!GETPOST('month')) { if (!$year && $month_start > $month_current) { $year_start--; $year_end--; } - $month_end = $month_start - 1; + if (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1) { + $month_end = $month_start - 1; + $year_end = $year_start + 1; + } if ($month_end < 1) { $month_end = 12; } From 785c85205bf3860473044602ffc73086ac1c7165 Mon Sep 17 00:00:00 2001 From: lvessiller-opendsi Date: Wed, 8 Nov 2023 17:32:23 +0100 Subject: [PATCH 12/27] FIX substitute project variables in invoice documents (#26445) * FIX substitute project variables in invoice documents * Keep key to substitute if no link with project --- htdocs/compta/facture/card.php | 3 +++ htdocs/core/lib/functions.lib.php | 15 ++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 69155ecd8c7..7fc8ba9721e 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -118,6 +118,9 @@ if ($id > 0 || !empty($ref)) { $fetch_situation = true; } $ret = $object->fetch($id, $ref, '', '', $fetch_situation); + if ($ret > 0 && isset($object->fk_project)) { + $ret = $object->fetch_project(); + } } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c95c93b67d4..7c0583519bd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7116,15 +7116,16 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__CANDIDATE_LASTNAME__'] = $object->lastname; } + $project = null; if (is_object($object->project)) { - $substitutionarray['__PROJECT_ID__'] = (is_object($object->project) ? $object->project->id : ''); - $substitutionarray['__PROJECT_REF__'] = (is_object($object->project) ? $object->project->ref : ''); - $substitutionarray['__PROJECT_NAME__'] = (is_object($object->project) ? $object->project->title : ''); + $project = $object->project; + } elseif (is_object($object->projet)) { // Deprecated, for backward compatibility + $project = $object->projet; } - if (is_object($object->projet)) { // Deprecated, for backward compatibility - $substitutionarray['__PROJECT_ID__'] = (is_object($object->projet) ? $object->projet->id : ''); - $substitutionarray['__PROJECT_REF__'] = (is_object($object->projet) ? $object->projet->ref : ''); - $substitutionarray['__PROJECT_NAME__'] = (is_object($object->projet) ? $object->projet->title : ''); + if ($project) { + $substitutionarray['__PROJECT_ID__'] = $project->id; + $substitutionarray['__PROJECT_REF__'] = $project->ref; + $substitutionarray['__PROJECT_NAME__'] = $project->title; } if (is_object($object) && $object->element == 'project') { $substitutionarray['__PROJECT_NAME__'] = $object->title; From 5a23bb27b05e385a39def227975dc5beaf55063a Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Thu, 9 Nov 2023 14:51:42 +0100 Subject: [PATCH 13/27] fix: bad sql on delete discount (#26517) --- htdocs/core/class/discount.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index dd5c4451b60..8f7f126f4ac 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -373,7 +373,7 @@ class DiscountAbsolute if ($this->fk_facture_source) { $sql = "UPDATE ".$this->db->prefix()."facture"; $sql .= " set paye=0, fk_statut=1"; - $sql .= " WHERE (type IN (".$this->db->sanitize(CommonInvoice::TYPE_CREDIT_NOTE.", ".CommonInvoice::TYPE_DEPOSIT).") AND rowid = ".((int) $this->fk_facture_source); + $sql .= " WHERE type IN (".$this->db->sanitize(CommonInvoice::TYPE_CREDIT_NOTE.", ".CommonInvoice::TYPE_DEPOSIT).") AND rowid = ".((int) $this->fk_facture_source); dol_syslog(get_class($this)."::delete Update credit note or deposit invoice statut", LOG_DEBUG); $result = $this->db->query($sql); @@ -388,7 +388,7 @@ class DiscountAbsolute } elseif ($this->fk_invoice_supplier_source) { $sql = "UPDATE ".$this->db->prefix()."facture_fourn"; $sql .= " set paye=0, fk_statut=1"; - $sql .= " WHERE (type IN (".$this->db->sanitize(CommonInvoice::TYPE_CREDIT_NOTE.", ".CommonInvoice::TYPE_DEPOSIT).") AND rowid = ".((int) $this->fk_invoice_supplier_source); + $sql .= " WHERE type IN (".$this->db->sanitize(CommonInvoice::TYPE_CREDIT_NOTE.", ".CommonInvoice::TYPE_DEPOSIT).") AND rowid = ".((int) $this->fk_invoice_supplier_source); dol_syslog(get_class($this)."::delete Update credit note or deposit invoice statut", LOG_DEBUG); $result = $this->db->query($sql); From a69fd2bc0937a313c1d00a705b8da7e4ec3b6de3 Mon Sep 17 00:00:00 2001 From: thibdrev Date: Thu, 9 Nov 2023 14:52:09 +0100 Subject: [PATCH 14/27] Fix PR #26501 (#26515) --- htdocs/compta/sociales/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index df226ad807e..7a8be178efa 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -334,7 +334,7 @@ if (isModEnabled('project')) { $now = dol_now(); $title = $langs->trans("SocialContribution").' - '.$langs->trans("Card"); -$help_url = 'EN:Module_Taxes_and_social_contributions|FR:Module Taxes et dividendes|ES:Módulo Impuestos y cargas sociales (IVA, impuestos)'; +$help_url = 'EN:Module_Taxes_and_social_contributions|FR:Module_Taxes_et_charges_spéciales|ES:Módulo Impuestos y cargas sociales (IVA, impuestos)'; llxHeader("", $title, $help_url); From 0946220e9bea5823111ca3d7821936157e0f955d Mon Sep 17 00:00:00 2001 From: atm-lena <52402938+atm-lena@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:41:39 +0100 Subject: [PATCH 15/27] Check price base type (#26503) Co-authored-by: atm-lena --- htdocs/comm/propal/card.php | 8 ++++---- htdocs/commande/card.php | 8 ++++---- htdocs/compta/facture/card.php | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index fec1d829ec6..2f358d6f988 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1279,11 +1279,11 @@ if (empty($reshook)) { // Check price is not lower than minimum if ($usermustrespectpricemin) { - if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min))) { + if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min)) && $price_base_type == 'HT') { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; - } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc))) { + } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc)) && $price_base_type == 'TTC') { $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; @@ -1452,12 +1452,12 @@ if (empty($reshook)) { // Check price is not lower than minimum if ($usermustrespectpricemin) { - if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min))) { + if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min)) && $price_base_type == 'HT') { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; $action = 'editline'; - } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc))) { + } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc)) && $price_base_type == 'TTC') { $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index d5a5d4ae967..00a1c819782 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1019,11 +1019,11 @@ if (empty($reshook)) { // Check price is not lower than minimum if ($usermustrespectpricemin) { - if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min))) { + if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min)) && $price_base_type == 'HT') { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; - } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc))) { + } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc)) && $price_base_type == 'TTC') { $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; @@ -1188,12 +1188,12 @@ if (empty($reshook)) { // Check price is not lower than minimum if ($usermustrespectpricemin) { - if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min))) { + if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min)) && $price_base_type == 'HT') { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; $action = 'editline'; - } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc))) { + } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc)) && $price_base_type == 'TTC') { $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index a5357ea0013..db6d4bdcfe6 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2346,11 +2346,11 @@ if (empty($reshook)) { // Check price is not lower than minimum (check is done only for standard or replacement invoices) if ($usermustrespectpricemin && ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT)) { - if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min))) { + if ($pu_equivalent && $price_min && ((price2num($pu_equivalent) * (1 - $remise_percent / 100)) < price2num($price_min)) && $price_base_type == 'HT') { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; - } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc))) { + } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc)) && $price_base_type == 'TTC') { $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; @@ -2565,12 +2565,12 @@ if (empty($reshook)) { // Check price is not lower than minimum (check is done only for standard or replacement invoices) if ($usermustrespectpricemin && ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT)) { - if ($pu_equivalent && $price_min && (((float) price2num($pu_equivalent) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min))) { + if ($pu_equivalent && $price_min && (((float) price2num($pu_equivalent) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min)) && $price_base_type == 'HT') { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; $action = 'editline'; - } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - (float) $remise_percent / 100)) < price2num($price_min_ttc))) { + } elseif ($pu_equivalent_ttc && $price_min_ttc && ((price2num($pu_equivalent_ttc) * (1 - (float) $remise_percent / 100)) < price2num($price_min_ttc)) && $price_base_type == 'TTC') { $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); $error++; From b7599afc4d9256b29d3b2f7b649c45359ee999b6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Nov 2023 14:05:36 +0100 Subject: [PATCH 16/27] Add log --- dev/initdemo/initdemopassword.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/initdemo/initdemopassword.sh b/dev/initdemo/initdemopassword.sh index a67dec61785..bcf2b14887e 100755 --- a/dev/initdemo/initdemopassword.sh +++ b/dev/initdemo/initdemopassword.sh @@ -171,6 +171,7 @@ fi if [ -s "$mydir/initdemopostsql.sql" ]; then echo A file initdemopostsql.sql was found, we execute it. + echo "mysql -P$port $base < \"$mydir/initdemopostsql.sql\"" mysql -P$port $base < "$mydir/initdemopostsql.sql" else echo No file initdemopostsql.sql found, so no extra sql action done. From caf41ca9ff54fde8f34165d98b7216e8e9abbbc4 Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Fri, 10 Nov 2023 18:51:22 +0100 Subject: [PATCH 17/27] fix: display stock mvt in inventories done (#26527) --- htdocs/product/inventory/inventory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 5f72928ed13..4b2ea3e93c0 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -1153,6 +1153,7 @@ if ($resql) { print $obj->qty_view; // qty found print ''; } + print ''; if ($obj->fk_movement > 0) { $stockmovment = new MouvementStock($db); $stockmovment->fetch($obj->fk_movement); From 09696078f37da3b5e37e72b3d3ea42fa205a8f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 10 Nov 2023 19:05:17 +0100 Subject: [PATCH 18/27] overall percentage of advancement is false if specials lines (#26522) --- htdocs/core/modules/facture/doc/pdf_sponge.modules.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 8d283756653..bb01f8bfd0b 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -1509,8 +1509,10 @@ class pdf_sponge extends ModelePDFFactures $percent = 0; $i = 0; foreach ($object->lines as $line) { - $percent += $line->situation_percent; - $i++; + if ($line->product_type != 9) { + $percent += $line->situation_percent; + $i++; + } } if (!empty($i)) { From 129927047a24cdfe9d8bd359ebea03fc336e911b Mon Sep 17 00:00:00 2001 From: daraelmin Date: Sun, 12 Nov 2023 21:36:25 +0100 Subject: [PATCH 19/27] FIX regression on planned bank entries (#26556) --- htdocs/compta/bank/treso.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index a861acb303f..61f8fcf2936 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -172,7 +172,7 @@ if (GETPOST("account") || GETPOST("ref")) { $error = 0; $tab_sqlobjOrder = array(); $tab_sqlobj = array(); - $nbtotalofrecords = ''; + $nbtotalofrecords = 0; foreach ($sqls as $sql) { $resql = $db->query($sql); From 390260640ae4b76545f583c434b1a1566d048729 Mon Sep 17 00:00:00 2001 From: thibdrev Date: Sun, 12 Nov 2023 21:44:42 +0100 Subject: [PATCH 20/27] fix #26551 Supplier Invoice - Display the error message when trying to delete an already reconciled payment (#26552) * fix #26551 * fix white space at the end of lines --- htdocs/fourn/facture/card.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 4da8efe076d..9d5b0601432 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -702,8 +702,10 @@ if (empty($reshook)) { $paiementfourn = new PaiementFourn($db); $result = $paiementfourn->fetch(GETPOST('paiement_id')); if ($result > 0) { - $result = $paiementfourn->delete(); // If fetch ok and found - header("Location: ".$_SERVER['PHP_SELF']."?id=".$id); + $result = $paiementfourn->delete(); + if ($result > 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$id); + } } if ($result < 0) { setEventMessages($paiementfourn->error, $paiementfourn->errors, 'errors'); From d6179c74f1ff0c50d41f7c5e789ad0980cd95639 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 12 Nov 2023 21:48:06 +0100 Subject: [PATCH 21/27] Fix add exit after redirect header --- htdocs/fourn/facture/card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 9d5b0601432..ffb3641d06b 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -705,6 +705,7 @@ if (empty($reshook)) { $result = $paiementfourn->delete(); if ($result > 0) { header("Location: ".$_SERVER['PHP_SELF']."?id=".$id); + exit; } } if ($result < 0) { From 2e458d9390bd75132f82fa3a3a14813a3abc11e5 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 12 Nov 2023 21:52:47 +0100 Subject: [PATCH 22/27] FIX #26536 Accountancy - Balance - Not divided lines by label & account, only by account (#26547) --- htdocs/accountancy/bookkeeping/balance.php | 4 ++-- htdocs/accountancy/class/bookkeeping.class.php | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 319ac308802..30020319813 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -434,8 +434,8 @@ if ($action != 'export_csv') { if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder); } - print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder); - print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder); + print_liste_field_titre("AccountingDebit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder); + print_liste_field_titre("AccountingCredit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'class="right"', $sortfield, $sortorder); // Hook fields diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 81229ca39da..1733340a901 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -1167,7 +1167,6 @@ class BookKeeping extends CommonObject $sql = 'SELECT'; $sql .= " t.numero_compte,"; - $sql .= " t.label_compte,"; if (!empty($option)) { $sql .= " t.subledger_account,"; $sql .= " t.subledger_label,"; @@ -1212,11 +1211,11 @@ class BookKeeping extends CommonObject if (!empty($option)) { $sql .= ' AND t.subledger_account IS NOT NULL'; $sql .= ' AND t.subledger_account != ""'; - $sql .= ' GROUP BY t.numero_compte, t.label_compte, t.subledger_account, t.subledger_label'; + $sql .= ' GROUP BY t.numero_compte, t.subledger_account, t.subledger_label'; $sortfield = 't.subledger_account'.($sortfield ? ','.$sortfield : ''); $sortorder = 'ASC'.($sortfield ? ','.$sortfield : ''); } else { - $sql .= ' GROUP BY t.numero_compte, t.label_compte'; + $sql .= ' GROUP BY t.numero_compte'; $sortfield = 't.numero_compte'.($sortfield ? ','.$sortfield : ''); $sortorder = 'ASC'.($sortorder ? ','.$sortorder : ''); } From a1c295185d545de990718cfe60ef3085bf8132b8 Mon Sep 17 00:00:00 2001 From: Klaas Oldenburger Date: Sun, 12 Nov 2023 21:59:28 +0100 Subject: [PATCH 23/27] Update main.lang (#26546) correcting date short format to dutch settings --- htdocs/langs/nl_NL/main.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/nl_NL/main.lang b/htdocs/langs/nl_NL/main.lang index cd362326eaf..269170130d2 100644 --- a/htdocs/langs/nl_NL/main.lang +++ b/htdocs/langs/nl_NL/main.lang @@ -25,8 +25,8 @@ FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y FormatDateText=%B %d, %Y -FormatDateHourShort=%m/%d/%Y %I:%M %p -FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p +FormatDateHourShort=%d-%m-%Y %I:%M %p +FormatDateHourSecShort=%d-%m-%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p DatabaseConnection=Databaseverbinding From 65b9f4e6defede20d488e62f11083c4c0ef5d20b Mon Sep 17 00:00:00 2001 From: sonikf <93765174+sonikf@users.noreply.github.com> Date: Sun, 12 Nov 2023 23:08:46 +0200 Subject: [PATCH 24/27] NEW: Add invoice subtype in customer template invoice (#26543) * Add invoice subtype in template invoice * Add invoice subtype in template invoice * Add invoice subtype in template invoice --- htdocs/compta/facture/card-rec.php | 44 +++++++++++++------ .../facture/class/facture-rec.class.php | 10 ++++- htdocs/core/class/commoninvoice.class.php | 21 +++++++++ 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index a14eff9a1bb..7473eb9044b 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -204,21 +204,22 @@ if (empty($reshook)) { } if (!$error) { - $object->title = GETPOST('title', 'alphanohtml'); - $object->note_private = GETPOST('note_private', 'restricthtml'); - $object->note_public = GETPOST('note_public', 'restricthtml'); - $object->model_pdf = GETPOST('modelpdf', 'alphanohtml'); - $object->usenewprice = GETPOST('usenewprice', 'alphanohtml'); + $object->subtype = GETPOST('subtype'); + $object->title = GETPOST('title', 'alphanohtml'); + $object->note_private = GETPOST('note_private', 'restricthtml'); + $object->note_public = GETPOST('note_public', 'restricthtml'); + $object->model_pdf = GETPOST('modelpdf', 'alphanohtml'); + $object->usenewprice = GETPOST('usenewprice', 'alphanohtml'); - $object->mode_reglement_id = GETPOST('mode_reglement_id', 'int'); - $object->cond_reglement_id = GETPOST('cond_reglement_id', 'int'); + $object->mode_reglement_id = GETPOST('mode_reglement_id', 'int'); + $object->cond_reglement_id = GETPOST('cond_reglement_id', 'int'); - $object->frequency = $frequency; - $object->unit_frequency = GETPOST('unit_frequency', 'alpha'); - $object->nb_gen_max = $nb_gen_max; - $object->auto_validate = GETPOST('auto_validate', 'int'); - $object->generate_pdf = GETPOST('generate_pdf', 'int'); - $object->fk_project = $projectid; + $object->frequency = $frequency; + $object->unit_frequency = GETPOST('unit_frequency', 'alpha'); + $object->nb_gen_max = $nb_gen_max; + $object->auto_validate = GETPOST('auto_validate', 'int'); + $object->generate_pdf = GETPOST('generate_pdf', 'int'); + $object->fk_project = $projectid; $date_next_execution = dol_mktime($rehour, $remin, 0, $remonth, $reday, $reyear); $object->date_when = $date_next_execution; @@ -1002,6 +1003,13 @@ if ($action == 'create') { print ''.$langs->trans("Customer").''.$object->thirdparty->getNomUrl(1, 'customer').''; print ''; + // Invoice subtype + if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) { + print "".$langs->trans("InvoiceSubtype").""; + print $form->getSelectInvoiceSubtype(GETPOSTISSET('subtype') ? GETPOST('subtype') : $object->subtype, 'subtype', -1, 0, 0, ''); + print ""; + } + $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $object->note_public; $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $object->note_private; @@ -1285,14 +1293,24 @@ if ($action == 'create') { print ''; + // Invoice subtype + if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) { + print ""; + } + + // Author print '"; + // Amount (excl. tax) print ''; print ''; print ''; + // Amount tax print ''; print ''; diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index e526b4049f2..0a6ad7c2423 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -7,6 +7,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Marcos García * Copyright (C) 2017-2020 Frédéric France + * Copyright (C) 2023 Nick Fragoulis * * 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 @@ -174,7 +175,8 @@ class FactureRec extends CommonInvoice 'titre' =>array('type'=>'varchar(100)', 'label'=>'Titre', 'enabled'=>1, 'showoncombobox' => 1, 'visible'=>-1, 'position'=>15), 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>20, 'index'=>1), 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'isModEnabled("societe")', 'visible'=>-1, 'notnull'=>1, 'position'=>25), - 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>30), + 'subtype' =>array('type'=>'smallint(6)', 'label'=>'InvoiceSubtype', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>30), + 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>35), 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>55, 'isameasure'=>1), 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'isameasure'=>1), 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>65, 'isameasure'=>1), @@ -273,6 +275,7 @@ class FactureRec extends CommonInvoice $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture_rec ("; $sql .= "titre"; $sql .= ", fk_soc"; + $sql .= ", subtype"; $sql .= ", entity"; $sql .= ", datec"; $sql .= ", amount"; @@ -301,6 +304,7 @@ class FactureRec extends CommonInvoice $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($this->titre ? $this->titre : $this->title)."'"; $sql .= ", ".((int) $this->socid); + $sql .= ", ".($this->subtype ? "'".$this->db->escape($this->subtype)."'" : "null"); $sql .= ", ".((int) $conf->entity); $sql .= ", '".$this->db->idate($now)."'"; $sql .= ", ".(!empty($facsrc->total_ttc) ? ((float) $facsrc->total_ttc) : '0'); @@ -545,7 +549,7 @@ class FactureRec extends CommonInvoice { dol_syslog('FactureRec::fetch', LOG_DEBUG); - $sql = 'SELECT f.rowid, f.entity, f.titre as title, f.suspended, f.fk_soc, f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc'; + $sql = 'SELECT f.rowid, f.entity, f.titre as title, f.suspended, f.fk_soc, f.subtype, f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc'; $sql .= ', f.date_lim_reglement as dlr'; $sql .= ', f.note_private, f.note_public, f.fk_user_author'; $sql .= ', f.modelpdf as model_pdf'; @@ -583,6 +587,7 @@ class FactureRec extends CommonInvoice $this->titre = $obj->title; // deprecated $this->title = $obj->title; $this->ref = $obj->title; + $this->subtype = $obj->subtype; $this->suspended = $obj->suspended; $this->total_ht = $obj->total_ht; $this->total_tva = $obj->total_tva; @@ -1345,6 +1350,7 @@ class FactureRec extends CommonInvoice $facture->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice $facture->type = self::TYPE_STANDARD; + $facture->subtype = $facturerec->subtype; $facture->statut = self::STATUS_DRAFT; // deprecated $facture->status = self::STATUS_DRAFT; $facture->date = (empty($facturerec->date_when) ? $now : $facturerec->date_when); // We could also use dol_now here but we prefer date_when so invoice has real date when we would like even if we generate later. diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index c1e9c9afeae..e4e072e87b3 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -694,6 +694,27 @@ abstract class CommonInvoice extends CommonObject $resql = $this->db->query($sql); + if ($resql) { + $subtypeLabel = ''; + + while ($obj = $this->db->fetch_object($resql)) { + $subtypeLabel = $obj->label; + } + + if (!empty($subtypeLabel)) { + print ' ' . $subtypeLabel; + } + } else { + dol_print_error($this->db); + return -1; + } + } elseif ($table === 'facture_rec' || $table === 'facture_fourn_rec') { + $sql = "SELECT s.label FROM " . MAIN_DB_PREFIX . $table . " AS f"; + $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "c_invoice_subtype AS s ON f.subtype = s.rowid"; + $sql .= " WHERE f.titre = '".$this->db->escape($this->titre)."'"; + + $resql = $this->db->query($sql); + if ($resql) { $subtypeLabel = ''; From cc452f2136cf85e4ec3c3c68f598465d7819b194 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 12 Nov 2023 22:16:47 +0100 Subject: [PATCH 25/27] FIX Accountancy - Possibility to write in bookkeeping expense report operation with some line not bound (#26545) * FIX Accountancy - Possibility to write in bookkeeping expense report operation with some line not bound * Update expensereportsjournal.php --------- Co-authored-by: Laurent Destailleur --- .../journal/expensereportsjournal.php | 85 ++++++++++++++++--- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php index 8a2bbcdf81c..16435e10d50 100644 --- a/htdocs/accountancy/journal/expensereportsjournal.php +++ b/htdocs/accountancy/journal/expensereportsjournal.php @@ -3,11 +3,11 @@ * Copyright (C) 2007-2010 Jean Heimburger * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin - * Copyright (C) 2013-2021 Alexandre Spangaro + * Copyright (C) 2013-2023 Alexandre Spangaro * Copyright (C) 2013-2016 Olivier Geffroy * Copyright (C) 2013-2016 Florian Henry * Copyright (C) 2018 Frédéric France - * Copyright (C) 2018 Eric Seigne + * Copyright (C) 2018 Eric Seigne * * 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 @@ -68,6 +68,7 @@ if (empty($user->rights->accounting->mouvements->lire)) { accessforbidden(); } +$error = 0; /* * Actions @@ -201,8 +202,27 @@ if ($result) { dol_print_error($db); } +// Load all unbound lines +$sql = "SELECT fk_expensereport, COUNT(erd.rowid) as nb"; +$sql .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd"; +$sql .= " WHERE erd.fk_code_ventilation <= 0"; +$sql .= " AND erd.total_ttc <> 0"; +$sql .= " AND fk_expensereport IN (".$db->sanitize(join(",", array_keys($taber))).")"; +$sql .= " GROUP BY fk_expensereport"; +$resql = $db->query($sql); + +$num = $db->num_rows($resql); +$i = 0; +while ($i < $num) { + $obj = $db->fetch_object($resql); + if ($obj->nb > 0) { + $errorforinvoice[$obj->fk_expensereport] = 'somelinesarenotbound'; + } + $i++; +} + // Bookkeeping Write -if ($action == 'writebookkeeping') { +if ($action == 'writebookkeeping' && !$error) { $now = dol_now(); $error = 0; @@ -217,6 +237,13 @@ if ($action == 'writebookkeeping') { $db->begin(); + // Error if some lines are not binded/ready to be journalized + if ($errorforinvoice[$key] == 'somelinesarenotbound') { + $error++; + $errorforline++; + setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors'); + } + // Thirdparty if (!$errorforline) { foreach ($tabttc[$key] as $k => $mt) { @@ -253,10 +280,12 @@ if ($action == 'writebookkeeping') { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists $error++; $errorforline++; + $errorforinvoice[$key] = 'alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; + $errorforinvoice[$key] = 'other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -302,10 +331,12 @@ if ($action == 'writebookkeeping') { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists $error++; $errorforline++; + $errorforinvoice[$key] = 'alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; + $errorforinvoice[$key] = 'other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -364,10 +395,12 @@ if ($action == 'writebookkeeping') { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists $error++; $errorforline++; + $errorforinvoice[$key] = 'alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; + $errorforinvoice[$key] = 'other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -376,10 +409,11 @@ if ($action == 'writebookkeeping') { } } - // Protection against a bug on line before - if (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT')) { + // Protection against a bug on lines before + if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) { $error++; $errorforline++; + $errorforinvoice[$key] = 'amountsnotbalanced'; setEventMessages('Try to insert a non balanced transaction in book for '.$val["ref"].'. Canceled. Surely a bug.', null, 'errors'); } @@ -433,7 +467,7 @@ $form = new Form($db); $userstatic = new User($db); // Export -if ($action == 'exportcsv') { // ISO and not UTF8 ! +if ($action == 'exportcsv' && !$error) { // ISO and not UTF8 ! $sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV; $filename = 'journal'; @@ -503,7 +537,7 @@ if (empty($action) || $action == 'view') { $periodlink = ''; $exportlink = ''; $builddate = dol_now(); - $description .= $langs->trans("DescJournalOnlyBindedVisible").'
'; + $description = $langs->trans("DescJournalOnlyBindedVisible").'
'; $listofchoices = array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger")); $period = $form->selectDate($date_start ? $date_start : -1, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end ? $date_end : -1, 'date_end', 0, 0, 0, '', 1, 0); @@ -567,11 +601,11 @@ if (empty($action) || $action == 'view') { print "
"; print ""; print ""; - print '"; - print '"; + print '"; + print '"; print "\n"; - $r = ''; + $i = 0; $expensereportstatic = new ExpenseReport($db); $expensereportlinestatic = new ExpenseReportLine($db); @@ -583,6 +617,27 @@ if (empty($action) || $action == 'view') { $date = dol_print_date($val["date"], 'day'); + if ($errorforinvoice[$key] == 'somelinesarenotbound') { + print ''; + print ""; + print ""; + print ""; + // Account + print "'; + // Subledger account + print "'; + print ""; + print ''; + print ''; + print ""; + + $i++; + } + // Fees foreach ($tabht[$key] as $k => $mt) { $accountingaccount = new AccountingAccount($db); @@ -613,6 +668,8 @@ if (empty($action) || $action == 'view') { print '"; print '"; print ""; + + $i++; } } @@ -647,6 +704,8 @@ if (empty($action) || $action == 'view') { print '"; print '"; print ""; + + $i++; } // VAT @@ -683,11 +742,17 @@ if (empty($action) || $action == 'view') { print '"; print '"; print ""; + + $i++; } } } } + if (!$i) { + print ''; + } + print "
".$langs->trans("InvoiceSubtype").""; + print $object->getSubtypeLabel('facture_rec'); + print "
'.$langs->trans("Author").''; print $author->getNomUrl(-1); print "
'.$langs->trans("AmountHT").''.price($object->total_ht, '', $langs, 1, -1, -1, $conf->currency).'
'.$langs->trans("AmountVAT").''.price($object->total_tva, '', $langs, 1, -1, -1, $conf->currency).'
".$langs->trans("AccountAccounting")."".$langs->trans("SubledgerAccount")."".$langs->trans("LabelOperation")."'.$langs->trans("Debit")."'.$langs->trans("Credit")."'.$langs->trans("Debit")."'.$langs->trans("Credit")."
".$date."".$expensereportstatic->getNomUrl(1).""; + print ''.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).''; + print '"; + print '"; + print "
'.($mt >= 0 ? price($mt) : '')."'.($mt < 0 ? price(-$mt) : '')."
'.($mt < 0 ? price(-$mt) : '')."'.($mt >= 0 ? price($mt) : '')."
'.($mt >= 0 ? price($mt) : '')."'.($mt < 0 ? price(-$mt) : '')."
'.$langs->trans("NoRecordFound").'
"; print ''; From 79b7b9486b0b21ead7ee72876a5a70a67e2fd01d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 12 Nov 2023 22:40:23 +0100 Subject: [PATCH 26/27] Doc --- htdocs/accountancy/class/accountingaccount.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index c541f28411e..d049eb4763d 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -401,6 +401,7 @@ class AccountingAccount extends CommonObject { global $langs; + // TODO Looks a stupid check $sql = "(SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facturedet"; $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")"; $sql .= "UNION"; From 7fa9fb80fa7daadb013326aace254353febb704e Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 12 Nov 2023 23:33:28 +0100 Subject: [PATCH 27/27] FIX #25967 Supplier export - Missing filter on accountancy buy account (#26559) --- htdocs/core/modules/modFournisseur.class.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index d58a208b606..656ebf8181e 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -313,6 +313,8 @@ class modFournisseur extends DolibarrModules $langs->loadLangs(array("suppliers", "multicurrency")); + $alias_product_perentity = empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED) ? "p" : "ppe"; + $r++; $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = 'Vendor invoices and lines of invoices'; @@ -327,7 +329,7 @@ class modFournisseur extends DolibarrModules 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", 'fd.total_ttc'=>"LineTotalTTC", 'fd.tva'=>"LineTotalVAT", 'fd.date_start'=>"DateStart", 'fd.date_end'=>"DateEnd", 'fd.special_code'=>'SpecialCode', 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.fk_product'=>'ProductId', - 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'p.accountancy_code_buy'=>'ProductAccountancyBuyCode', 'project.rowid'=>'ProjectId', + 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', $alias_product_perentity.'.accountancy_code_buy'=>'ProductAccountancyBuyCode', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' ); if (isModEnabled("multicurrency")) { @@ -348,7 +350,7 @@ class modFournisseur extends DolibarrModules 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>'Date', 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', 'f.note_public'=>"Text", 'fd.description'=>"Text", 'fd.tva_tx'=>"Text", 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.tva'=>"Numeric", 'fd.date_start'=>"Date", 'fd.date_end'=>"Date", 'fd.special_code'=>"Numeric", - 'fd.product_type'=>'Numeric', 'fd.fk_product'=>'List:product:label', + 'fd.product_type'=>'Numeric', 'fd.fk_product'=>'List:product:label', $alias_product_perentity . '.accountancy_code_buy'=>'Text', 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text' ); $this->export_entities_array[$r] = array( @@ -358,7 +360,7 @@ class modFournisseur extends DolibarrModules 'f.paye'=>"invoice", 'f.fk_statut'=>'invoice', 'f.note_public'=>"invoice", 'fd.rowid'=>'invoice_line', 'fd.description'=>"invoice_line", 'fd.tva_tx'=>"invoice_line", 'fd.qty'=>"invoice_line", 'fd.remise_percent'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva'=>"invoice_line", 'fd.date_start'=>"invoice_line", 'fd.date_end'=>"invoice_line", 'fd.special_code'=>"invoice_line", 'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product', - 'p.ref'=>'product', 'p.label'=>'product', 'p.accountancy_code_buy'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' + 'p.ref'=>'product', 'p.label'=>'product', $alias_product_perentity.'.accountancy_code_buy'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' ); $this->export_dependencies_array[$r] = array('invoice_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them // Add extra fields object