From 3417d79a428bf9881ec01a77f4c5181c3f56abac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Fri, 14 Feb 2025 16:26:39 +0100 Subject: [PATCH 01/16] FIX: Don't show and action of product extrafields on product price --- htdocs/product/price.php | 132 --------------------------------------- 1 file changed, 132 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 006c8710770..ebd12482081 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -500,52 +500,6 @@ if (empty($reshook)) { // If price has changed, we update it if (!array_key_exists($key, $object->multiprices) || $object->multiprices[$key] != $newprice || $object->multiprices_min[$key] != $newprice_min || $object->multiprices_base_type[$key] != $val['price_base_type'] || $object->multiprices_tva_tx[$key] != $newvattx) { $res = $object->updatePrice($newprice, $val['price_base_type'], $user, $val['vat_tx'], $newprice_min, $key, $val['npr'], $psq, 0, $val['localtaxes_array'], $val['default_vat_code'], $val['price_label']); - if ($res > 0) { - $extralabels = $extrafields->fetch_name_optionals_label("product"); - if (!getDolGlobalString('PRODUIT_MULTIPRICES') && !getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES') && !empty($extralabels)) { - // Default price - $extrafield_values = $extrafields->getOptionalsFromPost("product"); - foreach ($extrafield_values as $efkey => $value) { - $object->array_options[$efkey] = $value; - } - $result = $object->insertExtraFields(); - if ($result < 0) { - $error++; - } - } elseif ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) && !empty($extralabels)) { - $price_extralabels = $extrafields->fetch_name_optionals_label("product_price"); - $sql = "SELECT rowid"; - $sql .= " FROM ".$object->db->prefix()."product_price"; - $sql .= " WHERE entity IN (".getEntity('productprice').")"; - $sql .= " AND price_level=".((int) $key); // $i - $sql .= " AND fk_product = ".((int) $object->id); - $sql .= " ORDER BY date_price DESC, rowid DESC"; - $sql .= " LIMIT 1"; - $resql = $object->db->query($sql); - if ($resql) { - $lineid = $object->db->fetch_object($resql); - $db->free($resql); - } - if (!empty($lineid->rowid)) { - if (!empty($price_extralabels) && is_array($price_extralabels)) { - foreach ($price_extralabels as $code => $label) { - $code_array = GETPOST($code, 'array'); - $object->array_options['options_'.$code] = $code_array[$key]; - } - // We need to force table to update product_price and not product extrafields - $object->id = $lineid->rowid; - $object->table_element = 'product_price'; - $result = $object->insertExtraFields(); - } - // Back to product table - $object->id = $id; - $object->table_element = 'product'; - if ($result < 0) { - $error++; - } - } - } - } } else { $res = 0; } @@ -1515,39 +1469,6 @@ if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUS } print ''; } - - // Extrafields - $extrafields->fetch_name_optionals_label("product"); - $extralabels = !empty($extrafields->attributes["product"]['label']) ? $extrafields->attributes["product"]['label'] : []; - $extrafield_values = $extrafields->getOptionalsFromPost("product"); - $sql = "SELECT"; - $sql .= " fk_object"; - foreach ($extralabels as $key => $value) { - $sql .= ", ".$key; - } - $sql .= " FROM ".MAIN_DB_PREFIX."product_extrafields"; - $sql .= " WHERE fk_object = ".((int) $object->id); - $resql = $db->query($sql); - if ($resql) { - $obj = $db->fetch_object($resql); - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product"]['list'][$key]) && ($extrafields->attributes["product"]['list'][$key] == 1 || $extrafields->attributes["product"]['list'][$key] == 3 || ($action == "edit_price" && $extrafields->attributes["product"]['list'][$key] == 4))) { - if (!empty($extrafields->attributes["product"]['langfile'][$key])) { - $langs->load($extrafields->attributes["product"]['langfile'][$key]); - } - - print 'attributes["product"]['required'][$key] ? ' class="fieldrequired"' : '').'>'; - if (!empty($extrafields->attributes["product"]['help'][$key])) { - print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product"]['help'][$key])); - } else { - print $langs->trans($value); - } - - print ''.$extrafields->showOutputField($key, $obj->{$key}, '', 'product').""; - } - } - $db->free($resql); - } } print "\n"; @@ -1751,59 +1672,6 @@ if (($action == 'edit_price' || $action == 'edit_level_price') && $object->getRi print ''; print ''; - // Extrafields - $extrafields->fetch_name_optionals_label("product"); - $extralabels = !empty($extrafields->attributes["product"]['label']) ? $extrafields->attributes["product"]['label'] : ''; - $extrafield_values = $extrafields->getOptionalsFromPost("product"); - if (!empty($extralabels)) { - if (empty($object->id)) { - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product"]['list'][$key]) && ($extrafields->attributes["product"]['list'][$key] == 1 || $extrafields->attributes["product"]['list'][$key] == 3 || ($action == "edit_price" && $extrafields->attributes["product"]['list'][$key] == 4))) { - if (!empty($extrafields->attributes["product"]['langfile'][$key])) { - $langs->load($extrafields->attributes["product"]['langfile'][$key]); - } - - print 'attributes["product"]['required'][$key] ? ' class="fieldrequired"' : '').'>'; - if (!empty($extrafields->attributes["product"]['help'][$key])) { - print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product"]['help'][$key])); - } else { - print $langs->trans($value); - } - print ''.$extrafields->showInputField($key, GETPOSTISSET('options_'.$key) ? $extrafield_values['options_'.$key] : '', '', '', '', '', 0, 'product').''; - } - } - } else { - $sql = "SELECT"; - $sql .= " fk_object"; - foreach ($extralabels as $key => $value) { - $sql .= ", ".$key; - } - $sql .= " FROM ".MAIN_DB_PREFIX."product_extrafields"; - $sql .= " WHERE fk_object = ".((int) $object->id); - $resql = $db->query($sql); - if ($resql) { - $obj = $db->fetch_object($resql); - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product"]['list'][$key]) && ($extrafields->attributes["product"]['list'][$key] == 1 || $extrafields->attributes["product"]['list'][$key] == 3 || ($action == "edit_price" && $extrafields->attributes["product"]['list'][$key] == 4))) { - if (!empty($extrafields->attributes["product"]['langfile'][$key])) { - $langs->load($extrafields->attributes["product"]['langfile'][$key]); - } - - print 'attributes["product"]['required'][$key] ? ' class="fieldrequired"' : '').'>'; - if (!empty($extrafields->attributes["product"]['help'][$key])) { - print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product"]['help'][$key])); - } else { - print $langs->trans($value); - } - print ''.$extrafields->showInputField($key, GETPOSTISSET('options_'.$key) ? $extrafield_values['options_'.$key] : $obj->{$key}, '', '', '', '', 0, 'product'); - - print ''; - } - } - $db->free($resql); - } - } - } $parameters = array(); $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook From d4237652043f9514bc4bae0829289e61625aef40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Fri, 14 Feb 2025 16:30:11 +0100 Subject: [PATCH 02/16] FIX: Update level price extrafields --- htdocs/product/price.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index ebd12482081..398a5c3de42 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -509,6 +509,41 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); break; } + + // Update level price extrafields + $price_extralabels = $extrafields->fetch_name_optionals_label("product_price"); + if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) && !empty($price_extralabels)) { + $sql = "SELECT rowid"; + $sql .= " FROM ".$object->db->prefix()."product_price"; + $sql .= " WHERE entity IN (".getEntity('productprice').")"; + $sql .= " AND price_level=".((int) $key); // $i + $sql .= " AND fk_product = ".((int) $object->id); + $sql .= " ORDER BY date_price DESC, rowid DESC"; + $sql .= " LIMIT 1"; + $resql = $object->db->query($sql); + if ($resql) { + $lineid = $object->db->fetch_object($resql); + $db->free($resql); + } + if (!empty($lineid->rowid)) { + if (!empty($price_extralabels) && is_array($price_extralabels)) { + foreach ($price_extralabels as $code => $label) { + $code_array = GETPOST($code, 'array'); + $object->array_options['options_'.$code] = $code_array[$key]; + } + // We need to force table to update product_price and not product extrafields + $object->id = $lineid->rowid; + $object->table_element = 'product_price'; + $result = $object->insertExtraFields(); + } + // Back to product table + $object->id = $id; + $object->table_element = 'product'; + if ($result < 0) { + $error++; + } + } + } } } From b862380e6f13df9bd1987777abdf55c3c144064b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lina=20JOUM?= Date: Fri, 14 Feb 2025 16:33:21 +0100 Subject: [PATCH 03/16] FIX: Count colspan for table different prices for each customer --- htdocs/product/price.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 398a5c3de42..3ea695504da 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -2361,6 +2361,8 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT print ''."\n"; if (count($prodcustprice->lines) > 0 || $search_soc) { + $extrafields->fetch_name_optionals_label("product_customer_price"); + $custom_price_extralabels = !empty($extrafields->attributes["product_customer_price"]['label']) ? $extrafields->attributes["product_customer_price"]['label'] : ''; if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) { $colspan = 10; } else { @@ -2369,8 +2371,8 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { $colspan++; } - if (!empty($price_extralabels) && is_array($price_extralabels)) { - $colspan += count($price_extralabels); + if (!empty($custom_price_extralabels) && is_array($custom_price_extralabels)) { + $colspan += count($custom_price_extralabels); } print ''; From bfa5aaf9ac6a5d30012390fb84b67f972f24326e Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 17 Feb 2025 16:01:22 +0100 Subject: [PATCH 04/16] FIX php warning + look and feel --- htdocs/product/admin/product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 82759e7a8d5..e016add79f0 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -657,7 +657,7 @@ if (empty($conf->use_javascript_ajax)) { '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', ); - print $form->selectarray("activate_usesearchtoselectproduct", $arrval, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); + print $form->selectarray("activate_usesearchtoselectproduct", $arrval, getDolGlobalString('PRODUIT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth400'); print ''; } print ''; From 36a082e5434a00fcb740654ea63ae8267418ff29 Mon Sep 17 00:00:00 2001 From: yannis Date: Mon, 17 Feb 2025 17:21:35 +0100 Subject: [PATCH 05/16] Fix PDF generation --- htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php | 2 +- htdocs/core/modules/facture/doc/pdf_sponge.modules.php | 2 +- htdocs/core/modules/propale/doc/pdf_cyan.modules.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index 48c6e2f1f89..3b8c769b14a 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -778,7 +778,7 @@ class pdf_eratosthene extends ModelePDFCommandes // Add last page for document footer if there are not enough size left $afterPosData = $this->getMaxAfterColsLinePositionsData(); - if ($afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot) ) { + if (isset($afterPosData['y']) && $afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot) ) { $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index f3039d6fc2b..f5457fc919d 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -968,7 +968,7 @@ class pdf_sponge extends ModelePDFFactures $afterPosData = $this->getMaxAfterColsLinePositionsData(); $page_bottom_margin = $this->heightforfooter + $this->heightforfreetext + $this->heightforinfotot + $this->getHeightForQRInvoice($pdf->getPage(), $object, $langs); - if ($afterPosData['y'] > $this->page_hauteur - $page_bottom_margin) { + if (isset($afterPosData['y']) && $afterPosData['y'] > $this->page_hauteur - $page_bottom_margin) { $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index bb025e78755..8865c2cf8e0 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -804,7 +804,7 @@ class pdf_cyan extends ModelePDFPropales // Add last page for document footer if there are not enough size left $afterPosData = $this->getMaxAfterColsLinePositionsData(); - if ($afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot) ) { + if (isset($afterPosData['y']) && $afterPosData['y'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot) ) { $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); From 8b2e95ba27b84818bd780a7bacc7393e6a157b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Cendrier?= Date: Tue, 18 Feb 2025 10:07:58 +0100 Subject: [PATCH 06/16] FIX: ExtraFields::fetch_name_optionls_label() always returns an array --- htdocs/product/price.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 3ea695504da..5876b017095 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -526,7 +526,7 @@ if (empty($reshook)) { $db->free($resql); } if (!empty($lineid->rowid)) { - if (!empty($price_extralabels) && is_array($price_extralabels)) { + if (!empty($price_extralabels)) { foreach ($price_extralabels as $code => $label) { $code_array = GETPOST($code, 'array'); $object->array_options['options_'.$code] = $code_array[$key]; From 4ba96540aaacd72e1423599a4043549e48a8ca53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Cendrier?= Date: Tue, 18 Feb 2025 10:28:27 +0100 Subject: [PATCH 07/16] FIX: we already tested that $price_extrafield is not empty --- htdocs/product/price.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 5876b017095..19a7aff8528 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -526,16 +526,14 @@ if (empty($reshook)) { $db->free($resql); } if (!empty($lineid->rowid)) { - if (!empty($price_extralabels)) { - foreach ($price_extralabels as $code => $label) { - $code_array = GETPOST($code, 'array'); - $object->array_options['options_'.$code] = $code_array[$key]; - } - // We need to force table to update product_price and not product extrafields - $object->id = $lineid->rowid; - $object->table_element = 'product_price'; - $result = $object->insertExtraFields(); + foreach ($price_extralabels as $code => $label) { + $code_array = GETPOST($code, 'array'); + $object->array_options['options_'.$code] = $code_array[$key]; } + // We need to force table to update product_price and not product extrafields + $object->id = $lineid->rowid; + $object->table_element = 'product_price'; + $result = $object->insertExtraFields(); // Back to product table $object->id = $id; $object->table_element = 'product'; From fa1fa10a6e13c9fe36d8f75aa2d52307098b1a18 Mon Sep 17 00:00:00 2001 From: alsoft10 Date: Wed, 19 Feb 2025 16:23:57 +0530 Subject: [PATCH 08/16] FeatureUpdate#33130 --- htdocs/core/lib/functions.lib.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index cb6b009f99f..8e36fd56a6d 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4259,6 +4259,14 @@ function dol_print_phone($phone, $countrycode = '', $cid = 0, $socid = 0, $addli $newphonewa = $newphone; $newphone = substr($newphone, 0, 3).$separ.substr($newphone, 3, 3).$separ.substr($newphone, 6, 3).$separ.substr($newphone, 10, 3).$separ.substr($newphone, 14, 3); } + } elseif (strtoupper($countrycode) == "IN") {//India + if (dol_strlen($phone) == 13) { + if ($withpicto == 'phone') {//ex: +91_AB_CDEF_GHIJ + $newphone = substr($newphone, 0, 3).$separ.substr($newphone, 3, 2).$separ.substr($newphone, 5, 4).$separ.substr($newphone, 9, 4); + } else {//ex: +91_ABCDE_FGHIJ + $newphone = substr($newphone, 0, 3).$separ.substr($newphone, 3, 5).$separ.substr($newphone, 8, 5); + } + } } $newphoneastart = $newphoneaend = ''; From 5890046d8bf11f2e293d53f8785e211ec1f8cb0c Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 20 Feb 2025 07:46:45 +0100 Subject: [PATCH 09/16] Add hidden constants to remove some export file of the archive --- .../class/accountancyexport.class.php | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 03f62a7f83a..a310700cee4 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -1,19 +1,19 @@ - * Copyright (C) 2014 Juanjo Menent - * Copyright (C) 2015 Florian Henry - * Copyright (C) 2015 Raphaël Doursenaud - * Copyright (C) 2016 Pierre-Henry Favre - * Copyright (C) 2016-2024 Alexandre Spangaro - * Copyright (C) 2022 Lionel Vessiller - * Copyright (C) 2013-2017 Olivier Geffroy - * Copyright (C) 2017 Elarifr. Ari Elbaz - * Copyright (C) 2017-2024 Frédéric France - * Copyright (C) 2017 André Schild - * Copyright (C) 2020 Guillaume Alexandre - * Copyright (C) 2022 Joachim Kueter - * Copyright (C) 2022 Progiseize + * Copyright (C) 2007-2012 Laurent Destailleur + * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2015 Florian Henry + * Copyright (C) 2015 Raphaël Doursenaud + * Copyright (C) 2016 Pierre-Henry Favre + * Copyright (C) 2016-2025 Alexandre Spangaro + * Copyright (C) 2022 Lionel Vessiller + * Copyright (C) 2013-2017 Olivier Geffroy + * Copyright (C) 2017 Elarifr. Ari Elbaz + * Copyright (C) 2017-2024 Frédéric France + * Copyright (C) 2017 André Schild + * Copyright (C) 2020 Guillaume Alexandre + * Copyright (C) 2022 Joachim Kueter + * Copyright (C) 2022 Progiseize * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -1501,14 +1501,20 @@ class AccountancyExport $objectDirPath = ''; $objectFileName = dol_sanitizeFileName($line->doc_ref); if ($line->doc_type == 'customer_invoice') { - $objectDirPath = !empty($conf->invoice->multidir_output[$conf->entity]) ? $conf->invoice->multidir_output[$conf->entity] : $conf->invoice->dir_output; + if (getDolGlobalInt('ACCOUNTING_EXPORT_REMOVE_INVOICE_SOURCE_FILE')) { + $objectDirPath = !empty($conf->invoice->multidir_output[$conf->entity]) ? $conf->invoice->multidir_output[$conf->entity] : $conf->invoice->dir_output; + } } elseif ($line->doc_type == 'expense_report') { - $objectDirPath = !empty($conf->expensereport->multidir_output[$conf->entity]) ? $conf->expensereport->multidir_output[$conf->entity] : $conf->expensereport->dir_output; + if (getDolGlobalInt('ACCOUNTING_EXPORT_REMOVE_EXPENSEREPORT_SOURCE_FILE')) { + $objectDirPath = !empty($conf->expensereport->multidir_output[$conf->entity]) ? $conf->expensereport->multidir_output[$conf->entity] : $conf->expensereport->dir_output; + } } elseif ($line->doc_type == 'supplier_invoice') { - '@phan-var-force FactureFournisseur $invoice'; - /** @var FactureFournisseur $invoice */ - $objectDirPath = !empty($conf->fournisseur->facture->multidir_output[$conf->entity]) ? $conf->fournisseur->facture->multidir_output[$conf->entity] : $conf->fournisseur->facture->dir_output; - $objectDirPath .= '/'.rtrim(get_exdir($invoice->id, 2, 0, 0, $invoice, 'invoice_supplier'), '/'); + if (getDolGlobalInt('ACCOUNTING_EXPORT_REMOVE_SUPPLIERINVOICE_SOURCE_FILE')) { + '@phan-var-force FactureFournisseur $invoice'; + /** @var FactureFournisseur $invoice */ + $objectDirPath = !empty($conf->fournisseur->facture->multidir_output[$conf->entity]) ? $conf->fournisseur->facture->multidir_output[$conf->entity] : $conf->fournisseur->facture->dir_output; + $objectDirPath .= '/' . rtrim(get_exdir($invoice->id, 2, 0, 0, $invoice, 'invoice_supplier'), '/'); + } } $arrayofinclusion = array(); // If it is a supplier invoice, we want to use last uploaded file @@ -1715,14 +1721,20 @@ class AccountancyExport $objectDirPath = ''; $objectFileName = dol_sanitizeFileName($line->doc_ref); if ($line->doc_type == 'customer_invoice') { - $objectDirPath = !empty($conf->invoice->multidir_output[$conf->entity]) ? $conf->invoice->multidir_output[$conf->entity] : $conf->invoice->dir_output; + if (getDolGlobalInt('ACCOUNTING_EXPORT_REMOVE_INVOICE_SOURCE_FILE')) { + $objectDirPath = !empty($conf->invoice->multidir_output[$conf->entity]) ? $conf->invoice->multidir_output[$conf->entity] : $conf->invoice->dir_output; + } } elseif ($line->doc_type == 'expense_report') { - $objectDirPath = !empty($conf->expensereport->multidir_output[$conf->entity]) ? $conf->expensereport->multidir_output[$conf->entity] : $conf->expensereport->dir_output; + if (getDolGlobalInt('ACCOUNTING_EXPORT_REMOVE_EXPENSEREPORT_SOURCE_FILE')) { + $objectDirPath = !empty($conf->expensereport->multidir_output[$conf->entity]) ? $conf->expensereport->multidir_output[$conf->entity] : $conf->expensereport->dir_output; + } } elseif ($line->doc_type == 'supplier_invoice') { - '@phan-var-force FactureFournisseur $invoice'; - /** @var FactureFournisseur $invoice */ - $objectDirPath = !empty($conf->fournisseur->facture->multidir_output[$conf->entity]) ? $conf->fournisseur->facture->multidir_output[$conf->entity] : $conf->fournisseur->facture->dir_output; - $objectDirPath .= '/'.rtrim(get_exdir($invoice->id, 2, 0, 0, $invoice, 'invoice_supplier'), '/'); + if (getDolGlobalInt('ACCOUNTING_EXPORT_REMOVE_SUPPLIERINVOICE_SOURCE_FILE')) { + '@phan-var-force FactureFournisseur $invoice'; + /** @var FactureFournisseur $invoice */ + $objectDirPath = !empty($conf->fournisseur->facture->multidir_output[$conf->entity]) ? $conf->fournisseur->facture->multidir_output[$conf->entity] : $conf->fournisseur->facture->dir_output; + $objectDirPath .= '/' . rtrim(get_exdir($invoice->id, 2, 0, 0, $invoice, 'invoice_supplier'), '/'); + } } $arrayofinclusion = array(); // If it is a supplier invoice, we want to use last uploaded file From f1878af359828262c2c00a0eafe56e1e0bd2f1fb Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Thu, 20 Feb 2025 19:12:03 +0100 Subject: [PATCH 10/16] Debug CSS --- htdocs/index.php | 4 ++-- htdocs/theme/eldy/info-box.inc.php | 4 +++- htdocs/theme/md/info-box.inc.php | 6 +++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 5e2b667dbae..f09fd621607 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -570,7 +570,7 @@ if (!getDolGlobalString('MAIN_DISABLE_GLOBAL_WORKBOARD') && getDolGlobalInt('MAI $openedDashBoard .= ''."\n"; $openedDashBoard .= '
'."\n"; - $openedDashBoard .= '
'.$groupName.'
'."\n"; + $openedDashBoard .= '
'.$groupName.'
'."\n"; $openedDashBoard .= '
'."\n"; foreach ($boards as $board) { @@ -592,7 +592,7 @@ if (!getDolGlobalString('MAIN_DISABLE_GLOBAL_WORKBOARD') && getDolGlobalInt('MAI $textLate = ''; if ($board->nbtodolate > 0) { $textLate .= ''; - $textLate .= ' '.$board->nbtodolate; + $textLate .= ' '.$board->nbtodolate; $textLate .= ''; } diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index 24f981291a5..99930748d22 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -298,7 +298,7 @@ a.info-box-text-a i.fa.fa-exclamation-triangle { @media only screen and (max-width: 480px) { .info-box-text { - font-size: 0.82em; + font-size: 0.85em; } .info-box-line { line-height: 1.25em; @@ -694,8 +694,10 @@ a.vmenu span, span.vmenu, span.vmenu span { padding-left: 10px; padding-right: 2px; } + /* .info-box-line-text { width: calc(100% - 98px); max-width: calc(100% - 88px); } + */ } diff --git a/htdocs/theme/md/info-box.inc.php b/htdocs/theme/md/info-box.inc.php index a0588f5656b..c8ea748a5ba 100644 --- a/htdocs/theme/md/info-box.inc.php +++ b/htdocs/theme/md/info-box.inc.php @@ -430,12 +430,14 @@ a.info-box-text-a i.fa.fa-exclamation-triangle { font-size: 0.90em; } /* Force values for small screen 480 */ +/* @media only screen and (max-width: 480px) { .info-box-text { font-size: 0.85em; } } +*/ .info-box-text:first-letter{text-transform: uppercase} a.info-box-text{ text-decoration: none;} @@ -644,7 +646,7 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) { @media only screen and (max-width: 767px) { .box-flex-container { - margin: 0 0 0 -8px !important; + margin: 0 0 0 0 !important; } } @@ -684,10 +686,12 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) { padding-left: 10px; padding-right: 2px; } + /* .info-box-line-text { width: calc(100% - 92px); max-width: calc(100% - 82px); } + */ } @media only screen and (max-width: 480px) { From f7d449d22d60f67fde53d1cdb9d904da9161b9ba Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Thu, 20 Feb 2025 19:20:11 +0100 Subject: [PATCH 11/16] CSS --- htdocs/theme/md/style.css.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index afa4c41ddf7..1da6838385a 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -4547,7 +4547,7 @@ form.tagtable { } table.liste td, table.noborder td, div.noborder form div { - padding: 8px 6px 8px 6px; /* t r b l */ + padding: 8px 8px 8px 8px; /* t r b l */ } div.liste_titre_bydiv .divsearchfield { padding: 2px 1px 2px 6px; /* t r b l */ From 0f40c0cb7f69a83d231ba645e7cd08bce6c95534 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 20 Feb 2025 20:28:20 +0100 Subject: [PATCH 12/16] Debug v21 --- htdocs/cron/list.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index c65e63af98b..7bd54e70d1c 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -580,7 +580,7 @@ if ($num > 0) { print '
'; // Next run date - print ''; - // Update all child soc - print ''; - print ''; - print ''; - // Extrafields $extrafields->fetch_name_optionals_label("product_customer_price"); $extralabels = !empty($extrafields->attributes["product_customer_price"]['label']) ? $extrafields->attributes["product_customer_price"]['label'] : ''; @@ -571,6 +562,12 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT print '
'; if (!empty($object->label)) { $object->ref = $langs->trans($object->label); - print '
'; + print '
'; print $object->getNomUrl(0, '', 1); print '
'; $object->ref = $obj->rowid; @@ -665,7 +665,7 @@ if ($num > 0) { $datefromto = (empty($datelastrun) ? '' : dol_print_date($datelastrun, 'dayhoursec', 'tzserver')).' - '.(empty($datelastresult) ? '' : dol_print_date($datelastresult, 'dayhoursec', 'tzserver')); // Date start last run - print '
'; + print ''; if (!empty($datelastrun)) { print dol_print_date($datelastrun, 'dayhoursec', 'tzserver'); } @@ -693,14 +693,14 @@ if ($num > 0) { // Output of last run print ''; if (!empty($obj->lastoutput)) { - print '
'; + print '
'; print dol_trunc(dolGetFirstLineOfText($obj->lastoutput, 2), 100); print '
'; } print '
'; + print ''; if (!empty($obj->datenextrun)) { $datenextrun = $db->jdate($obj->datenextrun); if (empty($obj->status)) { From 7b9038ed9dac66b8e5bddaece1dc143f959698de Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 21 Feb 2025 13:21:51 +0100 Subject: [PATCH 13/16] FIX Missing quotes when using __NOW__ --- htdocs/core/lib/functions.lib.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0dff2f95581..6dd2b17f5a9 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -13955,7 +13955,7 @@ function forgeSQLFromUniversalSearchCriteria($filter, &$errorstr = '', $noand = $ret = ($noand ? "" : " AND ").($nopar ? "" : '(').preg_replace_callback('/'.$regexstring.'/i', 'dolForgeSQLCriteriaCallback', $filter).($nopar ? "" : ')'); if (is_object($db)) { - $ret = str_replace('__NOW__', $db->idate(dol_now()), $ret); + $ret = str_replace('__NOW__', "'".$db->idate(dol_now())."'", $ret); } if (is_object($user)) { $ret = str_replace('__USER_ID__', (string) $user->id, $ret); @@ -14186,8 +14186,10 @@ function dolForgeSQLCriteriaCallback($matches) $tmpescaped = 'NULL'; } elseif (ctype_digit((string) $tmpescaped)) { // if only 0-9 chars, no . $tmpescaped = (int) $tmpescaped; - } else { + } elseif (is_numeric((string) $tmpescaped)) { // it can be a float with a . $tmpescaped = (float) $tmpescaped; + } else { + $tmpescaped = preg_replace('/[^a-z0-9_]/i', '', $tmpescaped); // it can be a name of field or a substitution variable like '__NOW__' } } From c5b455e38e70cd74e05e850a77d1d3f931fbb38c Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 21 Feb 2025 15:18:25 +0100 Subject: [PATCH 14/16] Debug v21 --- htdocs/societe/price.php | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php index 24a7f838ad8..1a0890de567 100644 --- a/htdocs/societe/price.php +++ b/htdocs/societe/price.php @@ -506,15 +506,6 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT } print '
'; - print $langs->trans('ForceUpdateChildPriceSoc'); - print ''; - print ''; - print '
'; + // Update all child soc + print '
'; + print ' '; + print ''; + print '
'; + print $form->buttonsSaveCancel(); print ''; @@ -758,19 +755,26 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT } print ''; + + $colspan = 0; + foreach ($prodcustprice->fields as $key => $val) { if (!empty($arrayfields['t.'.$key]['checked'])) { print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], $key, '', $param, '', $sortfield, $sortorder)."\n"; + $colspan++; } } if (!empty($extralabels) && is_array($extralabels)) { foreach ($extralabels as $key => $val) { if (!empty($arrayfields['ef.'.$key]['checked'])) { print getTitleFieldOfList($arrayfields['ef.'.$key]['label'], 0, $_SERVER['PHP_SELF'], $key, '', $param, '', $sortfield, $sortorder)."\n"; + $colspan++; } } } print ''; + $colspan++; + print ''; if (count($prodcustprice->lines) > 0 || $search_prod) { @@ -825,6 +829,7 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT print ''; print $userstatic->getNomUrl(-1); print ''; + // Extrafields $extrafields->fetch_name_optionals_label("product_customer_price"); $extralabels = $extrafields->attributes["product_customer_price"]['label']; @@ -875,11 +880,10 @@ if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES') || getDolGlobalString('PRODUIT print "\n"; } } else { - $colspan = 10; if ($user->hasRight('produit', 'supprimer') || $user->hasRight('service', 'supprimer')) { $colspan += 1; } - print ''.$langs->trans('None').''; + print ''.$langs->trans('None').''; } print ""; From 344eca46efa37efd84135c0f76fc132031d3c8d6 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Fri, 21 Feb 2025 15:34:58 +0100 Subject: [PATCH 15/16] Debug v21 - Fix pb with detection of situation invoices --- htdocs/compta/facture/card.php | 20 +++++++++---------- htdocs/compta/facture/class/facture.class.php | 17 +++++++++++----- htdocs/compta/journal/sellsjournal.php | 4 ++-- .../facture/doc/pdf_octopus.modules.php | 2 +- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index b872a4a33a6..6b726c71d02 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1195,7 +1195,7 @@ if (empty($reshook)) { $facture_source = new Facture($db); // fetch origin object if ($facture_source->fetch($object->fk_facture_source) > 0) { - if ($facture_source->type == Facture::TYPE_SITUATION) { + if ($facture_source->isSituationInvoice()) { $object->situation_counter = $facture_source->situation_counter; $object->situation_cycle_ref = $facture_source->situation_cycle_ref; $facture_source->fetchPreviousNextSituationInvoice(); @@ -1240,7 +1240,7 @@ if (empty($reshook)) { } - if ($facture_source->type == Facture::TYPE_SITUATION) { + if ($facture_source->isSituationInvoice()) { $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id $line->fk_prev_id = $line->id; // The new line of the new credit note we are creating must be linked to the situation invoice line it is created from @@ -2942,7 +2942,7 @@ if (empty($reshook)) { $object->fetch($id, '', '', 0, true); if (in_array($object->status, array(Facture::STATUS_CLOSED, Facture::STATUS_VALIDATED)) - && $object->type == Facture::TYPE_SITUATION + && $object->isSituationInvoice() && $usercancreate && !$objectidnext && $object->is_last_in_cycle() @@ -2998,7 +2998,7 @@ if (empty($reshook)) { $lineIndex = count($object->tab_previous_situation_invoice) - 1; $searchPreviousInvoice = true; while ($searchPreviousInvoice) { - if ($object->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_SITUATION || $lineIndex < 1) { + if ($object->tab_previous_situation_invoice[$lineIndex]->isSituationInvoice() || $lineIndex < 1) { $searchPreviousInvoice = false; // find, exit; break; } else { @@ -3097,7 +3097,7 @@ if (empty($reshook)) { $pa_ht = $originLine->pa_ht; $label = $originLine->label; $array_options = $originLine->array_options; - if ($object->type == Facture::TYPE_SITUATION) { + if ($object->isSituationInvoice()) { $situation_percent = 0; } else { $situation_percent = 100; @@ -3722,12 +3722,12 @@ if ($action == 'create') { $opt = $form->selectSituationInvoices(GETPOSTINT('originid'), $socid); print '
'; - $tmp = ''.$langs->trans('NoSituations').'') || (GETPOST('origin') && GETPOST('origin') != 'facture' && GETPOST('origin') != 'commande')) { $tmp .= ' disabled'; } $tmp .= '> '; - $text = $tmp.' '; + $text = $tmp.' '; $text .= '