From b191330a79011f2c41392373aaeb656e80ec06bb Mon Sep 17 00:00:00 2001 From: David Pareja Rodriguez Date: Tue, 28 Feb 2023 13:24:11 +0100 Subject: [PATCH 01/41] Ignore localtaxes if localtax1_type or localtax2_type is 0 --- htdocs/core/lib/functions.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c275e4fd310..73bd7419a8c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5688,7 +5688,7 @@ function isOnlyOneLocalTax($local) function get_localtax_by_third($local) { global $db, $mysoc; - $sql = "SELECT t.localtax1, t.localtax2 "; + $sql = "SELECT t.localtax1_type, t.localtax2_type, t.localtax1, t.localtax2 "; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=t.fk_pays"; $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND t.active = 1 AND t.taux=("; $sql .= " SELECT max(tt.taux) FROM ".MAIN_DB_PREFIX."c_tva as tt inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=tt.fk_pays"; @@ -5698,9 +5698,9 @@ function get_localtax_by_third($local) $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); - if ($local == 1) { + if ($local == 1 && $obj->localtax1_type > 0) { return $obj->localtax1; - } elseif ($local == 2) { + } elseif ($local == 2 && $obj->localtax2_type > 0) { return $obj->localtax2; } } From 590373a620495bcaf5561089e99ca03c3ef1babd Mon Sep 17 00:00:00 2001 From: David Pareja Rodriguez Date: Tue, 28 Feb 2023 13:33:52 +0100 Subject: [PATCH 02/41] Forgot to loop on the results --- htdocs/core/lib/functions.lib.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 73bd7419a8c..e2bbb122176 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5697,11 +5697,12 @@ function get_localtax_by_third($local) $resql = $db->query($sql); if ($resql) { - $obj = $db->fetch_object($resql); - if ($local == 1 && $obj->localtax1_type > 0) { - return $obj->localtax1; - } elseif ($local == 2 && $obj->localtax2_type > 0) { - return $obj->localtax2; + while ($obj = $db->fetch_object($resql)) { + if ($local == 1 && $obj->localtax1_type > 0) { + return $obj->localtax1; + } elseif ($local == 2 && $obj->localtax2_type > 0) { + return $obj->localtax2; + } } } From 927d0a2fa15b61658c58763c0f5c05fed71a0505 Mon Sep 17 00:00:00 2001 From: David Pareja Rodriguez Date: Mon, 13 Mar 2023 11:16:37 +0100 Subject: [PATCH 03/41] ORDER BY rowid --- htdocs/core/lib/functions.lib.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index e2bbb122176..4d0367562df 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5688,22 +5688,20 @@ function isOnlyOneLocalTax($local) function get_localtax_by_third($local) { global $db, $mysoc; - $sql = "SELECT t.localtax1_type, t.localtax2_type, t.localtax1, t.localtax2 "; + + $sql = " SELECT t.localtax$local as localtax"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=t.fk_pays"; $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND t.active = 1 AND t.taux=("; $sql .= " SELECT max(tt.taux) FROM ".MAIN_DB_PREFIX."c_tva as tt inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=tt.fk_pays"; $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND tt.active = 1"; - $sql .= " )"; + $sql .= " ) "; + $sql .= " AND t.localtax${local}_type > 0"; + $sql .= " ORDER BY rowid DESC"; $resql = $db->query($sql); if ($resql) { - while ($obj = $db->fetch_object($resql)) { - if ($local == 1 && $obj->localtax1_type > 0) { - return $obj->localtax1; - } elseif ($local == 2 && $obj->localtax2_type > 0) { - return $obj->localtax2; - } - } + $obj = $db->fetch_object($resql); + return $obj->localtax; } return 0; From 645b0c563ec176ef0055950e4d56665204d30d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Courtier?= Date: Tue, 14 Mar 2023 11:43:36 +0100 Subject: [PATCH 04/41] FIX: Add more context for selectForFormsListWhere Hook --- htdocs/core/class/html.form.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9c14bfeb866..c4ade09e00f 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6782,7 +6782,13 @@ class Form } // Add where from hooks - $parameters = array(); + $parameters = [ + 'object' => $objecttmp, + 'htmlname' => $htmlname, + 'filter' => $filter, + 'searchkey' => $searchkey + ]; + $reshook = $hookmanager->executeHooks('selectForFormsListWhere', $parameters); // Note that $action and $object may have been modified by hook if (!empty($hookmanager->resPrint)) { $sql .= $hookmanager->resPrint; From e618eb3e64252dc0106802c89bfb7845b9b54e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Courtier?= Date: Fri, 17 Mar 2023 10:58:41 +0100 Subject: [PATCH 05/41] FIX: Add missing hook on LibStatut --- htdocs/ticket/class/ticket.class.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index e03bdabe617..e77c7cc2562 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -1273,7 +1273,7 @@ class Ticket extends CommonObject public function LibStatut($status, $mode = 0, $notooltip = 0) { // phpcs:enable - global $langs; + global $langs, $hookmanager; $labelStatus = $this->statuts[$status]; $labelStatusShort = $this->statuts_short[$status]; @@ -1301,6 +1301,18 @@ class Ticket extends CommonObject $mode = 0; } + $parameters = array( + 'status' => $status, + 'mode' => $mode, + ); + + // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('LibStatut', $parameters, $this); + + if ($reshook > 0) { + return $hookmanager->resPrint; + } + $params = array(); if ($notooltip) { $params = array('tooltip' => 'no'); From 5351fe75ac8ff2e9a0bdf1efcdf87f7421217a41 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Fri, 17 Mar 2023 22:13:09 +0100 Subject: [PATCH 06/41] Fix #24240 Dolibarr V17.0.0 PHP8 fatal error --- htdocs/compta/facture/card-rec.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index 06e9a762bca..96faccfd3e5 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2016 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2013-2023 Juanjo Menent * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2015 Alexandre Spangaro @@ -637,7 +637,7 @@ if (empty($reshook)) { $info_bits |= 0x01; } - if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) { + if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num((float)$remise_percent) / 100) < price2num($price_min)))) { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); setEventMessages($mesg, null, 'errors'); } else { From 1073944cf48dbe427458175fe52f6d00147cb5cc Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 17 Mar 2023 21:27:57 +0000 Subject: [PATCH 07/41] Fixing style errors. --- htdocs/compta/facture/card-rec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index 96faccfd3e5..5f90769688b 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -637,7 +637,7 @@ if (empty($reshook)) { $info_bits |= 0x01; } - if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num((float)$remise_percent) / 100) < price2num($price_min)))) { + if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num((float) $remise_percent) / 100) < price2num($price_min)))) { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); setEventMessages($mesg, null, 'errors'); } else { From a4683e614df85f986ccb67d1f9820aee81e1fce7 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Fri, 17 Mar 2023 22:52:01 +0100 Subject: [PATCH 08/41] Fix #24186 V17.0.0 Product listing, Barcode column appears empty --- htdocs/product/list.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 3f26c3bade6..356253cfab7 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2019 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012-2016 Marcos García - * Copyright (C) 2013-2019 Juanjo Menent + * Copyright (C) 2013-2023 Juanjo Menent * Copyright (C) 2013-2015 Raphaël Doursenaud * Copyright (C) 2013 Jean Heimburger * Copyright (C) 2013 Cédric Salvador @@ -1356,6 +1356,7 @@ while ($i < min($num, $limit)) { $product_static->ref_fourn = empty($obj->ref_supplier) ? '' : $obj->ref_supplier; // deprecated $product_static->ref_supplier = empty($obj->ref_supplier) ? '' : $obj->ref_supplier; $product_static->label = $obj->label; + $product_static->barcode = $obj->barcode; $product_static->finished = $obj->finished; $product_static->type = $obj->fk_product_type; $product_static->status_buy = $obj->tobuy; From 66643a0dc6e17533389e34daec126b7f83f2b9fa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 00:33:51 +0100 Subject: [PATCH 09/41] Fix phpcs --- htdocs/ticket/class/ticket.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 9c883296305..e7392c33f1d 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -1306,8 +1306,8 @@ class Ticket extends CommonObject 'mode' => $mode, ); - // Note that $action and $object may have been modified by hook - $reshook = $hookmanager->executeHooks('LibStatut', $parameters, $this); + // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('LibStatut', $parameters, $this); if ($reshook > 0) { return $hookmanager->resPrint; From 926c99f91344bf5efc5e5f50a1cf99e8efafdbd0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 02:35:31 +0100 Subject: [PATCH 10/41] Update html.form.class.php --- htdocs/core/class/html.form.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index c4ade09e00f..36754934a0d 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6782,12 +6782,12 @@ class Form } // Add where from hooks - $parameters = [ + $parameters = array( 'object' => $objecttmp, 'htmlname' => $htmlname, 'filter' => $filter, 'searchkey' => $searchkey - ]; + ); $reshook = $hookmanager->executeHooks('selectForFormsListWhere', $parameters); // Note that $action and $object may have been modified by hook if (!empty($hookmanager->resPrint)) { From 21102244a25d9c07febb57b40b28784d39e86258 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Sat, 18 Mar 2023 07:38:17 +0100 Subject: [PATCH 11/41] Most efficient solution to fatal error --- htdocs/compta/facture/card-rec.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index 5f90769688b..1e7ae045cae 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -437,6 +437,9 @@ if (empty($reshook)) { $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2); $remise_percent = price2num(GETPOST('remise_percent'.$predef), '', 2); + if (empty($remise_percent)) { + $remise_percent = 0; + } // Extrafields $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line); @@ -637,7 +640,7 @@ if (empty($reshook)) { $info_bits |= 0x01; } - if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num((float) $remise_percent) / 100) < price2num($price_min)))) { + if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); setEventMessages($mesg, null, 'errors'); } else { @@ -784,6 +787,9 @@ if (empty($reshook)) { }*/ $remise_percent = price2num(GETPOST('remise_percent'), '', 2); + if (empty($remise_percent)) { + $remise_percent = 0; + } // Check minimum price $productid = GETPOST('productid', 'int'); @@ -803,7 +809,7 @@ if (empty($reshook)) { $typeinvoice = Facture::TYPE_STANDARD; // Check price is not lower than minimum (check is done only for standard or replacement invoices) - if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (($typeinvoice == Facture::TYPE_STANDARD || $typeinvoice == Facture::TYPE_REPLACEMENT) && $price_min && ((float) price2num($pu_ht) * (1 - (float) $remise_percent / 100) < (float) price2num($price_min)))) { + if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (($typeinvoice == Facture::TYPE_STANDARD || $typeinvoice == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - $remise_percent / 100) < price2num($price_min)))) { setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors'); $error++; } From bd027dc71e5f3a25d8fc3995bdf66e817ba2c6df Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 10:31:54 +0100 Subject: [PATCH 12/41] Update card-rec.php --- htdocs/compta/facture/card-rec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index 1e7ae045cae..12567f00f99 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -809,7 +809,7 @@ if (empty($reshook)) { $typeinvoice = Facture::TYPE_STANDARD; // Check price is not lower than minimum (check is done only for standard or replacement invoices) - if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (($typeinvoice == Facture::TYPE_STANDARD || $typeinvoice == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - $remise_percent / 100) < price2num($price_min)))) { + if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (($typeinvoice == Facture::TYPE_STANDARD || $typeinvoice == Facture::TYPE_REPLACEMENT) && $price_min && ((float) price2num($pu_ht) * (1 - $remise_percent / 100) < (float) price2num($price_min)))) { setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors'); $error++; } From d1f79fabfb2ceabc009b3c902b9e2dab3900a837 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 10:32:45 +0100 Subject: [PATCH 13/41] Update card-rec.php --- htdocs/compta/facture/card-rec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index 12567f00f99..27b039d8b4c 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -809,7 +809,7 @@ if (empty($reshook)) { $typeinvoice = Facture::TYPE_STANDARD; // Check price is not lower than minimum (check is done only for standard or replacement invoices) - if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (($typeinvoice == Facture::TYPE_STANDARD || $typeinvoice == Facture::TYPE_REPLACEMENT) && $price_min && ((float) price2num($pu_ht) * (1 - $remise_percent / 100) < (float) price2num($price_min)))) { + if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (($typeinvoice == Facture::TYPE_STANDARD || $typeinvoice == Facture::TYPE_REPLACEMENT) && $price_min && ((float) price2num($pu_ht) * (1 - (float) $remise_percent / 100) < (float) price2num($price_min)))) { setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors'); $error++; } From 91cf865583653ad6e5f79d0c2360b2243cd257df Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 10:41:07 +0100 Subject: [PATCH 14/41] Update functions.lib.php --- htdocs/core/lib/functions.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 4d0367562df..c1459b1206b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5689,13 +5689,13 @@ function get_localtax_by_third($local) { global $db, $mysoc; - $sql = " SELECT t.localtax$local as localtax"; + $sql = " SELECT t.localtax".$local." as localtax"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=t.fk_pays"; $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND t.active = 1 AND t.taux=("; $sql .= " SELECT max(tt.taux) FROM ".MAIN_DB_PREFIX."c_tva as tt inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=tt.fk_pays"; $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND tt.active = 1"; $sql .= " ) "; - $sql .= " AND t.localtax${local}_type > 0"; + $sql .= " AND t.localtax".$local."_type > 0"; $sql .= " ORDER BY rowid DESC"; $resql = $db->query($sql); From 8d2a3a863da8c6ecd97cceff3e164317834e0022 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 10:48:09 +0100 Subject: [PATCH 15/41] Add phpunit for get_localtax_by_third --- test/phpunit/FunctionsLibTest.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 1bf3b6378fb..3b6a4d44942 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1168,7 +1168,7 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase } /** - * testGetDefaultTva + * testGetDefaultLocalTax * * @return void */ @@ -1255,6 +1255,27 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase } + /** + * testGetLocalTaxByThird + * + * @return void + */ + public function testGetLocalTaxByThird() + { + global $mysoc; + + $mysoc->country_code = 'ES'; + + $result = get_localtax_by_third(1); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('5.2', $result); + + $result = get_localtax_by_third(2); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('-19:-15:-9', $result); + } + + /** * testDolExplodeIntoArray * From 6e17c0c96183bfcca015bc415d658b5079887af7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 10:51:07 +0100 Subject: [PATCH 16/41] Merge branch '15.0' of git@github.com:Dolibarr/dolibarr.git into 15.0 --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ef5b837587d..f32d983150f 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5696,7 +5696,7 @@ function get_localtax_by_third($local) $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND tt.active = 1"; $sql .= " ) "; $sql .= " AND t.localtax".$local."_type > 0"; - $sql .= " ORDER BY rowid DESC"; + $sql .= " ORDER BY t.rowid DESC"; $resql = $db->query($sql); if ($resql) { From bfc3ccb56cd43a5358a3a188bc3209e1673246ef Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 16:11:27 +0100 Subject: [PATCH 17/41] Fix label --- htdocs/accountancy/bookkeeping/card.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 4620bf37e4e..651afe93562 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -412,7 +412,11 @@ if ($action == 'create') { if (!empty($object->piece_num)) { $backlink = ''.$langs->trans('BackToList').''; - print load_fiche_titre($langs->trans("UpdateMvts"), $backlink); + if ($mode == '_tmp') { + print load_fiche_titre($langs->trans("CreateMvts"), $backlink); + } else { + print load_fiche_titre($langs->trans("UpdateMvts"), $backlink); + } $head = array(); $h = 0; From 83174ee70321fa4e0144bf684afaab0e1740ca84 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 18 Mar 2023 16:53:40 +0100 Subject: [PATCH 18/41] Fix date --- htdocs/accountancy/bookkeeping/list.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index e28d70e8051..9231ae96a95 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -1460,7 +1460,7 @@ while ($i < min($num, $limit)) { // Creation operation date if (!empty($arrayfields['t.date_creation']['checked'])) { - print ''.dol_print_date($line->date_creation, 'dayhour').''; + print ''.dol_print_date($line->date_creation, 'dayhour', 'tzuserel').''; if (!$i) { $totalarray['nbfield']++; } @@ -1468,7 +1468,7 @@ while ($i < min($num, $limit)) { // Modification operation date if (!empty($arrayfields['t.tms']['checked'])) { - print ''.dol_print_date($line->date_modification, 'dayhour').''; + print ''.dol_print_date($line->date_modification, 'dayhour', 'tzuserel').''; if (!$i) { $totalarray['nbfield']++; } @@ -1476,7 +1476,7 @@ while ($i < min($num, $limit)) { // Exported operation date if (!empty($arrayfields['t.date_export']['checked'])) { - print ''.dol_print_date($line->date_export, 'dayhour').''; + print ''.dol_print_date($line->date_export, 'dayhour', 'tzuserel').''; if (!$i) { $totalarray['nbfield']++; } @@ -1484,7 +1484,7 @@ while ($i < min($num, $limit)) { // Validated operation date if (!empty($arrayfields['t.date_validated']['checked'])) { - print ''.dol_print_date($line->date_validation, 'dayhour').''; + print ''.dol_print_date($line->date_validation, 'dayhour', 'tzuserel').''; if (!$i) { $totalarray['nbfield']++; } From ff1d6ff0401802cff924b58e84578a62fbe0d478 Mon Sep 17 00:00:00 2001 From: priojk Date: Sun, 19 Mar 2023 10:32:39 +0100 Subject: [PATCH 19/41] fixed hook (correct return value, option to change params) --- .../product/dynamic_price/class/price_parser.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/product/dynamic_price/class/price_parser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php index 412d015f8b9..64c92752075 100644 --- a/htdocs/product/dynamic_price/class/price_parser.class.php +++ b/htdocs/product/dynamic_price/class/price_parser.class.php @@ -127,12 +127,12 @@ class PriceParser global $user; global $hookmanager; $action = 'PARSEEXPRESSION'; - if ($result = $hookmanager->executeHooks('doDynamiPrice', array( - 'expression' =>$expression, - 'product' => $product, - 'values' => $values + if ($reshook = $hookmanager->executeHooks('doDynamiPrice', array( + 'expression' => &$expression, + 'product' => &$product, + 'values' => &$values ), $this, $action)) { - return $result; + return $hookmanager->resArray['return']; } //Check if empty $expression = trim($expression); From 72860e3385401eba0f1cf4ce4a23205729640e5d Mon Sep 17 00:00:00 2001 From: priojk Date: Sun, 19 Mar 2023 11:03:05 +0100 Subject: [PATCH 20/41] Fix: loading the extrafields of the related product --- htdocs/product/dynamic_price/class/price_parser.class.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/product/dynamic_price/class/price_parser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php index 412d015f8b9..9bc1fd2a5a4 100644 --- a/htdocs/product/dynamic_price/class/price_parser.class.php +++ b/htdocs/product/dynamic_price/class/price_parser.class.php @@ -156,11 +156,10 @@ class PriceParser //Retrieve all extrafield for product and add it to values $extrafields = new ExtraFields($this->db); + $extralabels = $extrafields->fetch_name_optionals_label($product->table_element); $product->fetch_optionals(); - if (is_array($extrafields->attributes[$product->table_element]['label'])) { - foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) { - $values["extrafield_".$key] = $product->array_options['options_'.$key]; - } + foreach ($extralabels as $key => $label) { + $values["extrafield_".$key] = $product->array_options['options_'.$key]; } //Process any pending updaters From 4a79bf2667dc63fa018013a74d846dea12bce72a Mon Sep 17 00:00:00 2001 From: priojk Date: Sun, 19 Mar 2023 11:10:01 +0100 Subject: [PATCH 21/41] Sickler: indentation --- htdocs/product/dynamic_price/class/price_parser.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/dynamic_price/class/price_parser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php index 9bc1fd2a5a4..0e32613088a 100644 --- a/htdocs/product/dynamic_price/class/price_parser.class.php +++ b/htdocs/product/dynamic_price/class/price_parser.class.php @@ -156,7 +156,7 @@ class PriceParser //Retrieve all extrafield for product and add it to values $extrafields = new ExtraFields($this->db); - $extralabels = $extrafields->fetch_name_optionals_label($product->table_element); + $extralabels = $extrafields->fetch_name_optionals_label($product->table_element); $product->fetch_optionals(); foreach ($extralabels as $key => $label) { $values["extrafield_".$key] = $product->array_options['options_'.$key]; From 502badad4b68e850c6954dd13a6e689ae7cc54d9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 19 Mar 2023 11:25:36 +0100 Subject: [PATCH 22/41] Better error management --- htdocs/core/class/html.formcompany.class.php | 12 ++++++------ htdocs/core/lib/functions.lib.php | 17 +++++++++-------- .../install/mysql/migration/14.0.0-15.0.0.sql | 4 ++++ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index 103db86998c..a42ffc604a3 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -984,15 +984,15 @@ class FormCompany extends Form // phpcs:enable $tax = get_localtax_by_third($local); - $num = $this->db->num_rows($tax); - $i = 0; - if ($num) { + if ($tax) { $valors = explode(":", $tax); + $nbvalues = count($valors); - if (count($valors) > 1) { + if ($nbvalues > 1) { //montar select print ''; + print ''; } } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index f32d983150f..9c3126c3a80 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5682,19 +5682,18 @@ function isOnlyOneLocalTax($local) /** * Get values of localtaxes (1 or 2) for company country for the common vat with the highest value * - * @param int $local LocalTax to get - * @return number Values of localtax + * @param int $local LocalTax to get + * @return string Values of localtax (Can be '20', '-19:-15:-9') */ function get_localtax_by_third($local) { global $db, $mysoc; $sql = " SELECT t.localtax".$local." as localtax"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=t.fk_pays"; - $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND t.active = 1 AND t.taux=("; - $sql .= " SELECT max(tt.taux) FROM ".MAIN_DB_PREFIX."c_tva as tt inner join ".MAIN_DB_PREFIX."c_country as c ON c.rowid=tt.fk_pays"; - $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND tt.active = 1"; - $sql .= " ) "; + $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t INNER JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = t.fk_pays"; + $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND t.active = 1 AND t.taux = ("; + $sql .= "SELECT MAX(tt.taux) FROM ".MAIN_DB_PREFIX."c_tva as tt INNER JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = tt.fk_pays"; + $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND tt.active = 1)"; $sql .= " AND t.localtax".$local."_type > 0"; $sql .= " ORDER BY t.rowid DESC"; @@ -5702,9 +5701,11 @@ function get_localtax_by_third($local) if ($resql) { $obj = $db->fetch_object($resql); return $obj->localtax; + } else { + return 'Error'; } - return 0; + return '0'; } diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index bef7621d282..4b2655818c1 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -533,3 +533,7 @@ ALTER TABLE llx_bank ADD COLUMN amount_main_currency double(24,8) NULL; ALTER TABLE llx_commande_fournisseurdet MODIFY COLUMN ref varchar(128); ALTER TABLE llx_facture_fourn_det MODIFY COLUMN ref varchar(128); + +ALTER TABLE llx_c_tva SET localtax2 = '-19:-15:-9' WHERE localtax2 = '-19' AND localtax2_type = '5' AND fk_pays = 4 AND rowid = 44; + + From c895f366a10f4f8449657d3d58b5690cdb78f635 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 19 Mar 2023 11:36:06 +0100 Subject: [PATCH 23/41] Fix sql --- htdocs/install/mysql/migration/14.0.0-15.0.0.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index 4b2655818c1..67ff6f1fab3 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -534,6 +534,5 @@ ALTER TABLE llx_bank ADD COLUMN amount_main_currency double(24,8) NULL; ALTER TABLE llx_commande_fournisseurdet MODIFY COLUMN ref varchar(128); ALTER TABLE llx_facture_fourn_det MODIFY COLUMN ref varchar(128); -ALTER TABLE llx_c_tva SET localtax2 = '-19:-15:-9' WHERE localtax2 = '-19' AND localtax2_type = '5' AND fk_pays = 4 AND rowid = 44; - +UPDATE llx_c_tva SET localtax2 = '-19:-15:-9' WHERE localtax2 = '-19' AND localtax2_type = '5' AND fk_pays = 4 AND taux = 21; From d3f679f2b1923a9ba4ea1d3353eabf0fe3abb6f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 19 Mar 2023 12:54:11 +0100 Subject: [PATCH 24/41] Fix sql regression --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 9c3126c3a80..4f33a68811c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5694,7 +5694,7 @@ function get_localtax_by_third($local) $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND t.active = 1 AND t.taux = ("; $sql .= "SELECT MAX(tt.taux) FROM ".MAIN_DB_PREFIX."c_tva as tt INNER JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = tt.fk_pays"; $sql .= " WHERE c.code = '".$db->escape($mysoc->country_code)."' AND tt.active = 1)"; - $sql .= " AND t.localtax".$local."_type > 0"; + $sql .= " AND t.localtax".$local."_type <> '0'"; $sql .= " ORDER BY t.rowid DESC"; $resql = $db->query($sql); From ee30114ed90ed386771ad0fa23c59769aa922362 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 19 Mar 2023 14:28:32 +0100 Subject: [PATCH 25/41] Fix extralabels must not be used anymore. #24268 --- .../class/price_parser.class.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/htdocs/product/dynamic_price/class/price_parser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php index fd609a85d27..47e290677c6 100644 --- a/htdocs/product/dynamic_price/class/price_parser.class.php +++ b/htdocs/product/dynamic_price/class/price_parser.class.php @@ -124,8 +124,8 @@ class PriceParser */ public function parseExpression($product, $expression, $values) { - global $user; - global $hookmanager; + global $user, $hookmanager, $extrafields; + $action = 'PARSEEXPRESSION'; if ($reshook = $hookmanager->executeHooks('doDynamiPrice', array( 'expression' => &$expression, @@ -154,12 +154,17 @@ class PriceParser "pmp" => $product->pmp, )); - //Retrieve all extrafield for product and add it to values - $extrafields = new ExtraFields($this->db); - $extralabels = $extrafields->fetch_name_optionals_label($product->table_element); + // Retrieve all extrafields if not already not know (should not happen) + if (! is_object($extrafields)) { + $extrafields = new ExtraFields($this->db); + $extrafields->fetch_name_optionals_label(); + } + $product->fetch_optionals(); - foreach ($extralabels as $key => $label) { - $values["extrafield_".$key] = $product->array_options['options_'.$key]; + if (is_array($extrafields->attributes[$product->table_element]['label'])) { + foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) { + $values["extrafield_".$key] = $product->array_options['options_'.$key]; + } } //Process any pending updaters From 249a6ea9a9c76cbd1aaaf99487a427c0b5301990 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 19 Mar 2023 14:49:54 +0100 Subject: [PATCH 26/41] Remove warning --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 4f33a68811c..3f25d9cdfd0 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5814,7 +5814,7 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi } $sql .= ", ".MAIN_DB_PREFIX."c_country as c"; - if ($mysoc->country_code == 'ES') { + if (!empty($mysoc) && $mysoc->country_code == 'ES') { $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($buyer->country_code)."'"; // local tax in spain use the buyer country ?? } else { $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(empty($seller->country_code) ? $mysoc->country_code : $seller->country_code)."'"; From 88353ee5ba3c2bcf7a840d8ce19e1fea38bdd03c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 19 Mar 2023 17:38:22 +0100 Subject: [PATCH 27/41] Fix tests --- htdocs/compta/facture/class/facture.class.php | 1 + test/phpunit/NumberingModulesTest.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 484b44851fd..ec36314c999 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3192,6 +3192,7 @@ class Facture extends CommonInvoice /** * Add an invoice line into database (linked to product/service or not). + * Note: ->thirdparty must be defined. * Les parametres sont deja cense etre juste et avec valeurs finales a l'appel * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit) diff --git a/test/phpunit/NumberingModulesTest.php b/test/phpunit/NumberingModulesTest.php index ceab1948732..755eeb68956 100644 --- a/test/phpunit/NumberingModulesTest.php +++ b/test/phpunit/NumberingModulesTest.php @@ -152,6 +152,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1915); // we use year 1915 to be sure to not have existing invoice for this year (usefull only if numbering is {0000@1} $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); From b1695085779ecd428430cecb7dfc56b8294ae6ac Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 19 Mar 2023 19:11:16 +0100 Subject: [PATCH 28/41] Removed phpnightly build --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 62d04901e17..15fad8bf01f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,10 +56,6 @@ jobs: if: type = push AND branch = develop php: nightly env: DB=mysql - - stage: PHP Dev - if: type = push AND branch = 15.0 - php: nightly - env: DB=mysql notifications: email: From df001fc01a072994ea4a5b51dedcc253d9d0c6a0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 19 Mar 2023 20:29:34 +0100 Subject: [PATCH 29/41] Try to fix phpunit --- test/phpunit/NumberingModulesTest.php | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/test/phpunit/NumberingModulesTest.php b/test/phpunit/NumberingModulesTest.php index a6c96d2da11..6e482fe75b0 100644 --- a/test/phpunit/NumberingModulesTest.php +++ b/test/phpunit/NumberingModulesTest.php @@ -167,8 +167,11 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result=$localobject->is_erasable(); print __METHOD__." is_erasable=".$result."\n"; $this->assertGreaterThanOrEqual(1, $result, 'Test for is_erasable, 1st invoice'); // Can be deleted + $localobject2=new Facture($this->savdb); $localobject2->initAsSpecimen(); + $localobject2->fetch_thirdparty(); + $localobject2->date=dol_mktime(12, 0, 0, 1, 1, 1916); // we use following year for second invoice (there is no reset into mask) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject2, 'last'); @@ -195,6 +198,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1910); // we use year 1910 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -202,15 +207,21 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result3=$localobject->validate($user, $result); print __METHOD__." result=".$result."\n"; $this->assertEquals('1910-0001', $result, 'Test for {yyyy}-{0000@1} 1st invoice'); // counter must start to 1 + $localobject2=new Facture($this->savdb); $localobject2->initAsSpecimen(); + $localobject2->fetch_thirdparty(); + $localobject2->date=dol_mktime(12, 0, 0, 1, 1, 1910); // we use same year for second invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject2); print __METHOD__." result=".$result."\n"; $this->assertEquals('1910-0002', $result, 'Test for {yyyy}-{0000@1} 2nd invoice, same day'); // counter must be now 2 + $localobject3=new Facture($this->savdb); $localobject3->initAsSpecimen(); + $localobject3->fetch_thirdparty(); + $localobject3->date=dol_mktime(12, 0, 0, 1, 1, 1911); // we use next year for third invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject3); @@ -220,8 +231,11 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase // Same but we add month after year $conf->global->FACTURE_MERCURE_MASK_CREDIT='{yyyy}{mm}-{0000@1}'; $conf->global->FACTURE_MERCURE_MASK_INVOICE='{yyyy}{mm}-{0000@1}'; + $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1920); // we use year 1920 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -232,8 +246,11 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result=$localobject->is_erasable(); print __METHOD__." is_erasable=".$result."\n"; $this->assertGreaterThanOrEqual(1, $result); // Can be deleted + $localobject2=new Facture($this->savdb); $localobject2->initAsSpecimen(); + $localobject2->fetch_thirdparty(); + $localobject2->date=dol_mktime(12, 0, 0, 1, 1, 1921); // we use following year for second invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject2); @@ -253,6 +270,7 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $conf->global->FACTURE_MERCURE_MASK_INVOICE='{mm}{yy}-{0000@1}'; $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1925); // we use year 1925 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -263,8 +281,10 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result=$localobject->is_erasable(); // This call get getNextNumRef with param 'last' print __METHOD__." is_erasable=".$result."\n"; $this->assertGreaterThanOrEqual(1, $result); // Can be deleted + $localobject2=new Facture($this->savdb); $localobject2->initAsSpecimen(); + $localobject2->fetch_thirdparty(); $localobject2->date=dol_mktime(12, 0, 0, 1, 1, 1925); // we use same year 1925 for second invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject2); @@ -278,8 +298,10 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $result=$localobject->is_erasable(); print __METHOD__." is_erasable=".$result."\n"; $this->assertLessThanOrEqual(0, $result); // Case 1 can not be deleted (because there is an invoice 2) + $localobject3=new Facture($this->savdb); $localobject3->initAsSpecimen(); + $localobject3->fetch_thirdparty(); $localobject3->date=dol_mktime(12, 0, 0, 1, 1, 1926); // we use following year for third invoice (and there is a reset required) $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject3); @@ -297,6 +319,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1930); // we use year 1930 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject, 'last'); @@ -313,6 +337,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1930); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject, 'last'); @@ -326,6 +352,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1931); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -336,6 +364,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1931); // we use different fiscal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -350,6 +380,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1940); // we use year 1940 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -360,6 +392,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1940); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -380,6 +414,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1941); // we use different discal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -394,6 +430,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1950); // we use year 1950 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -404,6 +442,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1950); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -414,6 +454,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1951); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -424,6 +466,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1951); // we use different discal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -438,6 +482,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1960); // we use year 1960 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -448,6 +494,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1960); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -458,6 +506,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1961); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -468,6 +518,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1961); // we use different discal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -482,6 +534,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1970); // we use year 1970 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -492,6 +546,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1970); // we use same year but fiscal month after $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -502,6 +558,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1971); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -512,6 +570,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 12, 1, 1971); // we use different fiscal year but same year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -555,6 +615,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1981); // we use year 1981 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -574,6 +636,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1982); // we use year 1982 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($tmpthirdparty, $localobject); From 8ca17bdbc0881b3cd7b232ec6ba6aaeee5f783c7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 20 Mar 2023 01:54:29 +0100 Subject: [PATCH 30/41] Fix warning --- test/phpunit/NumberingModulesTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/phpunit/NumberingModulesTest.php b/test/phpunit/NumberingModulesTest.php index 6e482fe75b0..19d55d7932e 100644 --- a/test/phpunit/NumberingModulesTest.php +++ b/test/phpunit/NumberingModulesTest.php @@ -404,6 +404,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1941); // we use same fiscal year but different year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); From 0c49dc2b464af0ac3c68acfc0a9504cde91e5d67 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 20 Mar 2023 02:26:49 +0100 Subject: [PATCH 31/41] Fix warning --- test/phpunit/NumberingModulesTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/phpunit/NumberingModulesTest.php b/test/phpunit/NumberingModulesTest.php index 19d55d7932e..e5d31df1cf7 100644 --- a/test/phpunit/NumberingModulesTest.php +++ b/test/phpunit/NumberingModulesTest.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2012-2023 Laurent Destailleur * * 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 @@ -587,6 +587,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1980); // we use year 1980 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -597,6 +599,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 1, 1, 1980); // we use year 1980 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); @@ -607,6 +611,8 @@ class NumberingModulesTest extends PHPUnit\Framework\TestCase $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); + $localobject->fetch_thirdparty(); + $localobject->date=dol_mktime(12, 0, 0, 2, 1, 1980); // we use year 1980 to be sure to not have existing invoice for this year $numbering=new mod_facture_mercure(); $result=$numbering->getNextValue($mysoc, $localobject); From 049579f001bcaa2ee9e9352b901d26607d0060a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 20 Mar 2023 09:44:27 +0100 Subject: [PATCH 32/41] doc --- htdocs/core/class/commonobject.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ee8806f267c..c85f66ca2c6 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -12,7 +12,7 @@ * Copyright (C) 2017 ATM Consulting * Copyright (C) 2017-2019 Nicolas ZABOURI * Copyright (C) 2017 Rui Strecht - * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018-2023 Frédéric France * Copyright (C) 2018 Josep Lluís Amador * Copyright (C) 2023 Gauthier VERDOL * Copyright (C) 2021 Grégory Blémand @@ -183,6 +183,7 @@ abstract class CommonObject public $fk_project; /** + * @var Project The related project object * @deprecated * @see project */ From 9ddb7b619814b859a8da162eca466c41bd01e68e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 20 Mar 2023 12:00:21 +0100 Subject: [PATCH 33/41] Debug v17 --- 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 a26d77f947a..35c121536de 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6283,9 +6283,11 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi $sql .= ", ".MAIN_DB_PREFIX."c_country as c"; if (!empty($mysoc) && $mysoc->country_code == 'ES') { - $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($buyer->country_code)."'"; // local tax in spain use the buyer country ?? + $countrycodetouse = ((empty($buyer) || empty($buyer->country_code)) ? $mysoc->country_code : $buyer->country_code); + $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($countrycodetouse)."'"; // local tax in spain use the buyer country ?? } else { - $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape(empty($seller->country_code) ? $mysoc->country_code : $seller->country_code)."'"; + $countrycodetouse = ((empty($seller) || empty($seller->country_code)) ? $mysoc->country_code : $seller->country_code); + $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($countrycodetouse)."'"; } $sql .= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1"; if ($vatratecode) { From 1151a8e65e1ea42d07f14d38d2a35f06aa6c03a3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 20 Mar 2023 12:05:44 +0100 Subject: [PATCH 34/41] Fix more robust phpunit test --- test/phpunit/FunctionsLibTest.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index b573044d1c4..642e36e37c6 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -80,6 +80,7 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase protected $savuser; protected $savlangs; protected $savdb; + protected $savmysoc; /** * Constructor @@ -92,11 +93,12 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase parent::__construct(); //$this->sharedFixture - global $conf,$user,$langs,$db; + global $conf,$user,$langs,$db,$mysoc; $this->savconf=$conf; $this->savuser=$user; $this->savlangs=$langs; $this->savdb=$db; + $this->savmysoc=$mysoc; print __METHOD__." db->type=".$db->type." user->id=".$user->id; //print " - db ".$db->db; @@ -142,17 +144,18 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase } /** - * Init phpunit tests + * Init phpunit tests. Restore variables before each test. * * @return void */ protected function setUp(): void { - global $conf,$user,$langs,$db; + global $conf,$user,$langs,$db,$mysoc; $conf=$this->savconf; $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; + $mysoc=$this->savmysoc; print __METHOD__."\n"; } @@ -1225,7 +1228,6 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase // We do same tests but with option SERVICE_ARE_ECOMMERCE_200238EC on. $conf->global->SERVICE_ARE_ECOMMERCE_200238EC = 1; - // Test RULE 1 (FR-US) $vat=get_default_tva($companyfr, $companyus, 0); $this->assertEquals(0, $vat, 'RULE 1 ECOMMERCE_200238EC'); From d523f91a29a6e5620ac018c80a409e00ddeaa71c Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 20 Mar 2023 12:28:18 +0100 Subject: [PATCH 35/41] NEW limit load products in takepos --- htdocs/categories/class/categorie.class.php | 18 +++++++++- htdocs/takepos/ajax/ajax.php | 10 +++++- htdocs/takepos/index.php | 40 ++++++++++++--------- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 5f1b081c46d..875100b465c 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -845,6 +845,8 @@ class Categorie extends CommonObject * @param int $offset Offset * @param string $sortfield Sort fields * @param string $sortorder Sort order ('ASC' or 'DESC'); + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customsql'=>...) + * @param string $filtermode Filter mode (AND or OR) * @return array|int -1 if KO, array of instance of object if OK * @see containsObject() */ @@ -867,10 +869,24 @@ class Categorie extends CommonObject if (($type == 'customer' || $type == 'supplier') && $user->socid > 0) { $sql .= " AND o.rowid = ".((int) $user->socid); } + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 'o.rowid') { + $sqlwhere[] = $key." = ".((int) $value); + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")"; + } + $sql .= $this->db->order($sortfield, $sortorder); if ($limit > 0 || $offset > 0) { $sql .= $this->db->plimit($limit + 1, $offset); } - $sql .= $this->db->order($sortfield, $sortorder); dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG); $resql = $this->db->query($sql); diff --git a/htdocs/takepos/ajax/ajax.php b/htdocs/takepos/ajax/ajax.php index 87357d10091..1fae90b8a42 100644 --- a/htdocs/takepos/ajax/ajax.php +++ b/htdocs/takepos/ajax/ajax.php @@ -62,6 +62,10 @@ $hookmanager->initHooks(array('takeposproductsearch')); // new context for produ */ if ($action == 'getProducts') { + $tosell = GETPOSTISSET('tosell') ? GETPOST('tosell', 'int') : ''; + $limit = GETPOSTISSET('limit') ? GETPOST('limit', 'int') : 0; + $offset = GETPOSTISSET('offset') ? GETPOST('offset', 'int') : 0; + top_httphead('application/json'); $object = new Categorie($db); @@ -70,7 +74,11 @@ if ($action == 'getProducts') { } $result = $object->fetch($category); if ($result > 0) { - $prods = $object->getObjectsInCateg("product", 0, 0, 0, getDolGlobalString('TAKEPOS_SORTPRODUCTFIELD'), 'ASC'); + $filter = array(); + if ($tosell != '') { + $filter = array('customsql' => 'o.tosell = '.((int) $tosell)); + } + $prods = $object->getObjectsInCateg("product", 0, $limit, $offset, getDolGlobalString('TAKEPOS_SORTPRODUCTFIELD'), 'ASC'); // Removed properties we don't need $res = array(); if (is_array($prods) && count($prods) > 0) { diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index bbbf9e0cd33..84ec7439ca3 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -322,7 +322,12 @@ function LoadProducts(position, issubcat) { }); idata=0; //product data counter - $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&category='+currentcat, function(data) { + var limit = 0; + if (maxproduct >= 1) { + limit = maxproduct-1; + } + // Only show products for sale (tosell=1) + $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&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) { @@ -342,10 +347,7 @@ function LoadProducts(position, issubcat) { $("#proprice"+ishow).html(""); $("#prodiv"+ishow).data("rowid",""); $("#prodiv"+ishow).attr("class","wrapper2 divempty"); - $("#prowatermark"+ishow).hide(); - ishow++; //Next product to show after print data product - } - else if ((data[idata]['status']) == "1") { // Only show products with status=1 (for sell) + } else { transnoentities('Ref').': ')."' + data[idata]['ref']"; $titlestring .= " + ' - ".dol_escape_js($langs->trans("Barcode").': ')."' + data[idata]['barcode']"; @@ -376,8 +378,7 @@ function LoadProducts(position, issubcat) { console.log($('#prodiv4').data('rowid')); $("#prodiv"+ishow).data("iscat", 0); $("#prodiv"+ishow).attr("class","wrapper2"); - $("#prowatermark"+ishow).hide(); - ishow++; //Next product to show after print data product + resPrint; ?> } - //console.log("Hide the prowatermark for ishow="+ishow); + $("#prowatermark"+ishow).hide(); + ishow++; //Next product to show after print data product idata++; //Next data everytime } }); @@ -414,15 +416,22 @@ function MoreProducts(moreorless) { if (pageproducts==0) return; //Return if no less pages pageproducts=pageproducts-1; } - $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&category='+currentcat, function(data) { + + ishow=0; //product to show counter + idata=0; //product data counter + var limit = 0; + if (maxproduct >= 1) { + limit = maxproduct-1; + } + var offset = * pageproducts; + // Only show products for sale (tosell=1) + $.getJSON('/takepos/ajax/ajax.php?action=getProducts&token=&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[(maxproduct * pageproducts)]) == "undefined" && moreorless=="more"){ // Return if no more pages + if (typeof (data[0]) == "undefined" && moreorless=="more"){ // Return if no more pages pageproducts=pageproducts-1; return; } - idata= * pageproducts; //product data counter - ishow=0; //product to show counter while (ishow < maxproduct) { if (typeof (data[idata]) == "undefined") { @@ -434,10 +443,7 @@ function MoreProducts(moreorless) { $("#proprice"+ishow).html(""); $("#proimg"+ishow).attr("src","genimg/empty.png"); $("#prodiv"+ishow).data("rowid",""); - ishow++; //Next product to show after print data product - } - else if ((data[idata]['status']) == "1") { - //Only show products with status=1 (for sell) + } else { $("#prodivdesc"+ishow).show(); @@ -454,9 +460,9 @@ function MoreProducts(moreorless) { $("#proimg"+ishow).attr("src","genimg/index.php?query=pro&id="+data[idata]['id']); $("#prodiv"+ishow).data("rowid",data[idata]['id']); $("#prodiv"+ishow).data("iscat",0); - ishow++; //Next product to show after print data product } $("#prowatermark"+ishow).hide(); + ishow++; //Next product to show after print data product idata++; //Next data everytime } }); From daa34b85fe54fbe6ccd63aede549f7b2327302af Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 20 Mar 2023 13:27:48 +0100 Subject: [PATCH 36/41] New filter products for sale --- htdocs/categories/class/categorie.class.php | 2 +- htdocs/takepos/ajax/ajax.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 875100b465c..6762770d564 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -850,7 +850,7 @@ class Categorie extends CommonObject * @return array|int -1 if KO, array of instance of object if OK * @see containsObject() */ - public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC') + public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC', $filter = array(), $filtermode = 'AND') { global $user; diff --git a/htdocs/takepos/ajax/ajax.php b/htdocs/takepos/ajax/ajax.php index 1fae90b8a42..5b75ef04275 100644 --- a/htdocs/takepos/ajax/ajax.php +++ b/htdocs/takepos/ajax/ajax.php @@ -78,7 +78,7 @@ if ($action == 'getProducts') { if ($tosell != '') { $filter = array('customsql' => 'o.tosell = '.((int) $tosell)); } - $prods = $object->getObjectsInCateg("product", 0, $limit, $offset, getDolGlobalString('TAKEPOS_SORTPRODUCTFIELD'), 'ASC'); + $prods = $object->getObjectsInCateg("product", 0, $limit, $offset, getDolGlobalString('TAKEPOS_SORTPRODUCTFIELD'), 'ASC', $filter); // Removed properties we don't need $res = array(); if (is_array($prods) && count($prods) > 0) { From f1732370743af2e45bafd1403c035ae9089fd11f Mon Sep 17 00:00:00 2001 From: Jyhere Date: Mon, 20 Mar 2023 15:17:32 +0100 Subject: [PATCH 37/41] Add missing hooks on reassortlot and reassort page --- htdocs/product/reassort.php | 23 +++++++++++++++++-- htdocs/product/reassortlot.php | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index bfe12d7efe2..02d8e6e2002 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -151,6 +151,10 @@ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s ON p.rowid = s.fk_produ if (!empty($conf->global->PRODUCT_USE_UNITS)) { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_units as u on p.fk_unit = u.rowid'; } +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= " WHERE p.entity IN (".getEntity('product').")"; if (!empty($search_categ) && $search_categ != '-1') { $sql .= " AND "; @@ -207,10 +211,12 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec $sql .= $hookmanager->resPrint; $sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,"; $sql .= " p.fk_product_type, p.tms, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock"; -// Add fields from hooks + +// Add GROUP BY from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldSelect', $parameters, $object); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + $sql_having = ''; if ($search_toolowstock) { $sql_having .= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte"; @@ -226,6 +232,19 @@ if ($search_stock_physique != '') { } $sql_having .= $natural_search_physique; } + +// Add HAVING from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +if (!empty($hookmanager->resPrint)) { + if (!empty($sql_having)) { + $sql_having .= " AND"; + } else { + $sql_having .= " HAVING"; + } + $sql_having .= $hookmanager->resPrint; +} + if (!empty($sql_having)) { $sql .= $sql_having; } diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index c823379ce31..d24b5282d11 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -126,6 +126,9 @@ if (!empty($canvas)) { $objcanvas->getCanvas('product', 'list', $canvas); } +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('productreassortlotlist')); + // Security check if ($user->socid) { $socid = $user->socid; @@ -222,11 +225,19 @@ $sql .= ' e.ref as warehouse_ref, e.lieu as warehouse_lieu, e.fk_parent as wareh $sql .= ' pb.batch, pb.eatby as oldeatby, pb.sellby as oldsellby,'; $sql .= ' pl.rowid as lotid, pl.eatby, pl.sellby,'; $sql .= ' SUM(pb.qty) as stock_physique, COUNT(pb.rowid) as nbinbatchtable'; +// Add fields from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= ' FROM '.MAIN_DB_PREFIX.'product as p'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as ps on p.rowid = ps.fk_product'; // Detail for each warehouse $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'entrepot as e on ps.fk_entrepot = e.rowid'; // Link on unique key $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_batch as pb on pb.fk_product_stock = ps.rowid'; // Detail for each lot on each warehouse $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot as pl on pl.fk_product = p.rowid AND pl.batch = pb.batch'; // Link on unique key +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= " WHERE p.entity IN (".getEntity('product').") AND e.entity IN (".getEntity('stock').")"; if (!empty($search_categ) && $search_categ != '-1') { $sql .= " AND "; @@ -315,6 +326,10 @@ foreach ($search as $key => $val) { } } } +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,"; $sql .= " p.fk_product_type, p.tms,"; @@ -323,6 +338,10 @@ $sql .= " ps.fk_entrepot, ps.reel,"; $sql .= " e.ref, e.lieu, e.fk_parent,"; $sql .= " pb.batch, pb.eatby, pb.sellby,"; $sql .= " pl.rowid, pl.eatby, pl.sellby"; +// Add GROUP BY from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql_having = ''; if ($search_toolowstock) { $sql_having .= " HAVING SUM(".$db->ifsql('ps.reel IS NULL', '0', 'ps.reel').") < p.seuil_stock_alerte"; // Not used yet @@ -337,6 +356,17 @@ if ($search_stock_physique != '') { } $sql_having .= $natural_search_physique; } +// Add HAVING from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +if (!empty($hookmanager->resPrint)) { + if (!empty($sql_having)) { + $sql_having .= " AND"; + } else { + $sql_having .= " HAVING"; + } + $sql_having .= $hookmanager->resPrint; +} if (!empty($sql_having)) { $sql .= $sql_having; } @@ -563,6 +593,9 @@ print ''; print ' '; print ' '; print ' '; +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; // Action column if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print ''; @@ -602,6 +635,10 @@ print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stock_physique", print_liste_field_titre(''); print_liste_field_titre("ProductStatusOnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ProductStatusOnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'right '); +// Hook fields +$parameters = array('param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print_liste_field_titre(''); } @@ -741,6 +778,11 @@ while ($i < $imaxinloop) { print ''.$product_static->LibStatut($objp->tobuy, 5, 1).''; + // Fields values from hook + $parameters = array('obj'=>$objp); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $product); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print ''; From 8dc1c0c7c2ad6c4d593210b0cf825e92857b5490 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 20 Mar 2023 21:46:17 +0100 Subject: [PATCH 38/41] NEW Can edit account on miscellaneous payment (if not transfered) --- .../bank/class/paymentvarious.class.php | 32 ++++++++++ htdocs/compta/bank/various_payment/card.php | 62 ++++++++++++++----- htdocs/core/class/html.form.class.php | 36 ++++++----- 3 files changed, 97 insertions(+), 33 deletions(-) diff --git a/htdocs/compta/bank/class/paymentvarious.class.php b/htdocs/compta/bank/class/paymentvarious.class.php index 705ff2d20ca..912f46e074a 100644 --- a/htdocs/compta/bank/class/paymentvarious.class.php +++ b/htdocs/compta/bank/class/paymentvarious.class.php @@ -828,4 +828,36 @@ class PaymentVarious extends CommonObject $return .= ''; return $return; } + + /** + * Return General accounting account with defined length (used for product and miscellaneous) + * + * @param string $account General accounting account + * @return string String with defined length + */ + public function lengthAccountg($account) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + + /* + if (isModEnabled('accounting')) { + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('', $valuetoshow, 1); + }*/ + + return length_accountg($account); + } + + /** + * Return Auxiliary accounting account of thirdparties with defined length + * + * @param string $account Auxiliary accounting account + * @return string String with defined length + */ + public function lengthAccounta($account) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + + return length_accounta($account); + } } diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index 1eb552fd711..1409cc90417 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -1,6 +1,7 @@ * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2023 Laurent Destailleur * * 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 @@ -83,14 +84,8 @@ if ($reshook < 0) { } if (empty($reshook)) { - // Link to a project - if ($action == 'classin' && $user->rights->banque->modifier) { - $object->fetch($id); - $object->setProject(GETPOST('projectid')); - } - if ($cancel) { - if ($action != 'addlink') { + if ($action != 'addlink' && $action != 'setaccountancy_code' && $action != 'setsubledger_account') { $urltogo = $backtopage ? $backtopage : dol_buildpath('/compta/bank/various_payment/list.php', 1); header("Location: ".$urltogo); exit; @@ -101,6 +96,12 @@ if (empty($reshook)) { $action = ''; } + // Link to a project + if ($action == 'classin' && $user->rights->banque->modifier) { + $object->fetch($id); + $object->setProject(GETPOST('projectid')); + } + if ($action == 'add') { $error = 0; @@ -214,6 +215,22 @@ if (empty($reshook)) { } } + if ($action == 'setaccountancy_code') { + $db->begin(); + + $result = $object->fetch($id); + + $object->accountancy_code = GETPOST('accountancy_code', 'alpha'); + + $res = $object->update($user); + if ($res > 0) { + $db->commit(); + } else { + $db->rollback(); + setEventMessages($object->error, $object->errors, 'errors'); + } + } + if ($action == 'setsubledger_account') { $db->begin(); @@ -622,25 +639,38 @@ if ($id) { print ''.$langs->trans("Amount").''.price($object->amount, 0, $langs, 1, -1, -1, $conf->currency).''; - // Accountancy code + // Account of Chart of account + /* print ''; - print $langs->trans("AccountAccounting"); + print $form->editfieldkey('AccountAccounting', 'account', $object->accountancy_code, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); print ''; - if (isModEnabled('accounting')) { - $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('', $object->accountancy_code, 1); - - print $accountingaccount->getNomUrl(0, 1, 1, '', 1); + if ($action == 'editaccount') { + if (isModEnabled('accounting')) { + print $formaccounting->select_account($object->accountancy_code, 'accountancy_code', 1, null, 1, 1); + } else { // For external software + print ''; + } } else { - print $object->accountancy_code; + include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + print length_accounta($object->accountancy_code); + }*/ + $editvalue = ''; + if (isModEnabled('accounting')) { + $editvalue = $formaccounting->select_account($object->accountancy_code, 'accountancy_code', 1, null, 1, 1); } + + print ''; + print ''; + print $form->editfieldkey('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); + print ''; + print $form->editfieldval('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'asis', $editvalue, 0, null, '', 1, 'lengthAccountg'); print ''; // Subledger account print ''; print $form->editfieldkey('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); print ''; - print $form->editfieldval('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); + print $form->editfieldval('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0, null, '', 1, 'lengthAccounta'); print ''; $bankaccountnotfound = 0; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 96aa566ab2e..33009ad09ba 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -191,23 +191,23 @@ class Form /** * Output value of a field for an editable field * - * @param string $text Text of label (not used in this function) - * @param string $htmlname Name of select field - * @param string $value Value to show/edit - * @param object $object Object (that we want to show) - * @param boolean $perm Permission to allow button to edit parameter - * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols%', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datehourpicker', 'ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols', 'select;xkey:xval,ykey:yval,...') - * @param string $editvalue When in edit mode, use this value as $value instead of value (for example, you can provide here a formated price instead of numeric value). Use '' to use same than $value - * @param object $extObject External object ??? - * @param mixed $custommsg String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage') - * @param string $moreparam More param to add on the form on action href URL parameter - * @param int $notabletag Do no output table tags - * @param string $formatfunc Call a specific function to output field in view mode (For example: 'dol_print_email') - * @param string $paramid Key of parameter for id ('id', 'socid') - * @param string $gm 'auto' or 'tzuser' or 'tzuserrel' or 'tzserver' (when $typeofdata is a date) - * @param array $moreoptions Array with more options. For example array('addnowlink'=>1), array('valuealreadyhtmlescaped'=>1) - * @param string $editaction [=''] use GETPOST default action or set action to edit mode - * @return string HTML edit field + * @param string $text Text of label (not used in this function) + * @param string $htmlname Name of select field + * @param string $value Value to show/edit + * @param object $object Object (that we want to show) + * @param boolean $perm Permission to allow button to edit parameter + * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols%', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datehourpicker', 'ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols', 'select;xkey:xval,ykey:yval,...') + * @param string $editvalue When in edit mode, use this value as $value instead of value (for example, you can provide here a formated price instead of numeric value, or a select combo). Use '' to use same than $value + * @param object $extObject External object ??? + * @param mixed $custommsg String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage') + * @param string $moreparam More param to add on the form on action href URL parameter + * @param int $notabletag Do no output table tags + * @param string $formatfunc Call a specific method of $object->$formatfunc to output field in view mode (For example: 'dol_print_email') + * @param string $paramid Key of parameter for id ('id', 'socid') + * @param string $gm 'auto' or 'tzuser' or 'tzuserrel' or 'tzserver' (when $typeofdata is a date) + * @param array $moreoptions Array with more options. For example array('addnowlink'=>1), array('valuealreadyhtmlescaped'=>1) + * @param string $editaction [=''] use GETPOST default action or set action to edit mode + * @return string HTML edit field */ public function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 1, $formatfunc = '', $paramid = 'id', $gm = 'auto', $moreoptions = array(), $editaction = '') { @@ -310,6 +310,8 @@ class Form require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; $doleditor = new DolEditor($htmlname, ($editvalue ? $editvalue : $value), (empty($tmp[2]) ? '' : $tmp[2]), (empty($tmp[3]) ? '100' : $tmp[3]), (empty($tmp[1]) ? 'dolibarr_notes' : $tmp[1]), 'In', (empty($tmp[5]) ? 0 : $tmp[5]), (isset($tmp[8]) ? ($tmp[8] ? true : false) : true), true, (empty($tmp[6]) ? '20' : $tmp[6]), (empty($tmp[7]) ? '100' : $tmp[7])); $ret .= $doleditor->Create(1); + } elseif ($typeofdata == 'asis') { + $ret .= ($editvalue ? $editvalue : $value); } if (empty($notabletag)) { $ret .= ''; From 6503d63c5f39c8fe5910fc1b5470437919875de7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 20 Mar 2023 21:59:36 +0100 Subject: [PATCH 39/41] Look and feel v18 --- htdocs/compta/bank/various_payment/card.php | 59 +++++++------------ .../compta/bank/various_payment/document.php | 1 - htdocs/compta/bank/various_payment/info.php | 1 - 3 files changed, 20 insertions(+), 41 deletions(-) diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index 1409cc90417..7fbf2774e85 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -72,6 +72,8 @@ $object = new PaymentVarious($db); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('variouscard', 'globalcard')); +$permissiontoadd = $user->hasRight('banque', 'modifier'); + /** * Actions @@ -97,9 +99,9 @@ if (empty($reshook)) { } // Link to a project - if ($action == 'classin' && $user->rights->banque->modifier) { + if ($action == 'classin' && $permissiontoadd) { $object->fetch($id); - $object->setProject(GETPOST('projectid')); + $object->setProject(GETPOST('projectid', 'int')); } if ($action == 'add') { @@ -253,7 +255,7 @@ if ($action == 'confirm_clone' && $confirm != 'yes') { $action = ''; } -if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->banque->modifier)) { +if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) { $db->begin(); $originalId = $id; @@ -577,32 +579,25 @@ if ($id) { // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= $langs->trans('Project').' '; - if ($user->rights->banque->modifier) { + //$morehtmlref .= '
'; + if ($permissiontoadd) { + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; - } - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref .= '
'; - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects(0, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; - $morehtmlref .= '
'; - } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); $morehtmlref .= $proj->getNomUrl(1); - } else { - $morehtmlref .= ''; + if ($proj->title) { + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; + } } } } + $morehtmlref .= ''; $linkback = ''.$langs->trans("BackToList").''; @@ -640,20 +635,6 @@ if ($id) { print ''.$langs->trans("Amount").''.price($object->amount, 0, $langs, 1, -1, -1, $conf->currency).''; // Account of Chart of account - /* - print ''; - print $form->editfieldkey('AccountAccounting', 'account', $object->accountancy_code, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); - print ''; - if ($action == 'editaccount') { - if (isModEnabled('accounting')) { - print $formaccounting->select_account($object->accountancy_code, 'accountancy_code', 1, null, 1, 1); - } else { // For external software - print ''; - } - } else { - include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; - print length_accounta($object->accountancy_code); - }*/ $editvalue = ''; if (isModEnabled('accounting')) { $editvalue = $formaccounting->select_account($object->accountancy_code, 'accountancy_code', 1, null, 1, 1); @@ -661,16 +642,16 @@ if ($id) { print ''; print ''; - print $form->editfieldkey('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); + print $form->editfieldkey('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0); print ''; - print $form->editfieldval('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'asis', $editvalue, 0, null, '', 1, 'lengthAccountg'); + print $form->editfieldval('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $permissiontoadd), 'asis', $editvalue, 0, null, '', 1, 'lengthAccountg'); print ''; // Subledger account print ''; - print $form->editfieldkey('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0); + print $form->editfieldkey('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0); print ''; - print $form->editfieldval('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0, null, '', 1, 'lengthAccounta'); + print $form->editfieldval('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0, null, '', 1, 'lengthAccounta'); print ''; $bankaccountnotfound = 0; @@ -719,13 +700,13 @@ if ($id) { // Add button modify // Clone - if ($user->rights->banque->modifier) { + if ($permissiontoadd) { print '"; } // Delete if (empty($object->rappro) || $bankaccountnotfound) { - if (!empty($user->rights->banque->modifier)) { + if ($permissiontoadd) { if ($alreadyaccounted) { print ''; } else { diff --git a/htdocs/compta/bank/various_payment/document.php b/htdocs/compta/bank/various_payment/document.php index 43259727917..58e4d3680b9 100644 --- a/htdocs/compta/bank/various_payment/document.php +++ b/htdocs/compta/bank/various_payment/document.php @@ -100,7 +100,6 @@ if ($object->id) { // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= $langs->trans('Project').' : '; if ($user->rights->banque->modifier && 0) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; diff --git a/htdocs/compta/bank/various_payment/info.php b/htdocs/compta/bank/various_payment/info.php index ca31915d2f4..06f243a9847 100644 --- a/htdocs/compta/bank/various_payment/info.php +++ b/htdocs/compta/bank/various_payment/info.php @@ -60,7 +60,6 @@ $morehtmlref = '
'; // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= $langs->trans('Project').' : '; if ($user->rights->banque->modifier && 0) { if ($action != 'classify') { $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; From 72750c3b8d8e7d5a5348fe3be0d71fda70bdd4a9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2023 01:43:09 +0100 Subject: [PATCH 40/41] Add notice in security to show if installmodules.lock exists. --- htdocs/admin/system/security.php | 29 ++++++++++++++++++++++++++++- htdocs/langs/en_US/admin.lang | 4 ++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 90bb35320c0..751ed819e29 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -241,14 +241,41 @@ print '
'; print '
'; $installlock = DOL_DATA_ROOT.'/install.lock'; +$upgradeunlock = DOL_DATA_ROOT.'/upgrade.unlock'; +$installmoduleslock = DOL_DATA_ROOT.'/installmodules.lock'; + +// Is install (upgrade) locked print ''.$langs->trans("DolibarrSetup").': '; if (file_exists($installlock)) { - print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installlock); + if (file_exists($upgradeunlock)) { + print img_picto('', 'tick').' '.$langs->trans("InstallLockedBy", $installlock); + } else { + print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installlock); + } } else { print img_warning().' '.$langs->trans("WarningLockFileDoesNotExists", DOL_DATA_ROOT); } print '
'; +// Is upgrade unlocked +if (file_exists($installlock)) { // If install not locked, no need to show this. + if (file_exists($upgradeunlock)) { + print ''.$langs->trans("DolibarrUpgrade").': '; + print img_warning().' '.$langs->trans("UpgradeHasBeenUnlocked", $upgradeunlock); + print '
'; + } +} + +// Is addon install locked ? +print ''.$langs->trans("DolibarrAddonInstall").': '; +if (file_exists($installmoduleslock)) { + print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installmoduleslock); +} else { + print $langs->trans("InstallOfAddonIsNotBlocked", DOL_DATA_ROOT); +} +print '
'; + + // File conf.php diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 0214b73292d..484e207e347 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -51,6 +51,8 @@ ClientSortingCharset=Client collation WarningModuleNotActive=Module %s must be enabled WarningOnlyPermissionOfActivatedModules=Only permissions related to activated modules are shown here. You can activate other modules in the Home->Setup->Modules page. DolibarrSetup=Dolibarr install or upgrade +DolibarrUpgrade=Dolibarr upgrade +DolibarrAddonInstall=Installation of Addon/External modules (uploaded or generated) InternalUsers=Internal users ExternalUsers=External users UserInterface=User interface @@ -2264,6 +2266,8 @@ DatabasePasswordNotObfuscated=Database password is NOT obfuscated in conf file APIsAreNotEnabled=APIs modules are not enabled YouShouldSetThisToOff=You should set this to 0 or off InstallAndUpgradeLockedBy=Install and upgrades are locked by the file %s +InstallLockedBy=Install/Reinstall is locked by the file %s +InstallOfAddonIsNotBlocked=Installations of addons are not locked. Create a file installmodules.lock into directory %s to block installations of external addons/modules. OldImplementation=Old implementation PDF_SHOW_LINK_TO_ONLINE_PAYMENT=If some online payment modules are enabled (Paypal, Stripe, ...), add a link on the PDF to make the online payment DashboardDisableGlobal=Disable globally all the thumbs of open objects From 3821f5c27c9f397fcc06e181ab80eade0cd925c3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2023 01:50:14 +0100 Subject: [PATCH 41/41] Update security page --- htdocs/admin/system/security.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 751ed819e29..15db7d2ba0d 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -313,7 +313,7 @@ if (empty($dolibarr_main_restrict_os_commands)) { } else { print $dolibarr_main_restrict_os_commands; } -print ' ('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore').')'; +print ' ('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore, clamdscan').')'; print '
'; if (empty($conf->global->SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF)) {