From 8ddc4c8db61f59d48e5154ec33ec23245f47c4bb Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 1 Dec 2022 14:28:00 +0100 Subject: [PATCH 01/20] FIX: propal and order stats broken on Tag+User(retricted customer list) --- htdocs/comm/propal/class/propalestats.class.php | 15 ++++++--------- htdocs/commande/class/commandestats.class.php | 12 ++++++------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/htdocs/comm/propal/class/propalestats.class.php b/htdocs/comm/propal/class/propalestats.class.php index 181e5b545f8..af660ffd58d 100644 --- a/htdocs/comm/propal/class/propalestats.class.php +++ b/htdocs/comm/propal/class/propalestats.class.php @@ -93,9 +93,6 @@ class PropaleStats extends Stats } //$this->where.= " AND p.fk_soc = s.rowid AND p.entity = ".$conf->entity; $this->where .= ($this->where ? ' AND ' : '')."p.entity IN (".getEntity('propal').")"; - if (!$user->rights->societe->client->voir && !$this->socid) { - $this->where .= " AND p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); - } if ($this->socid) { $this->where .= " AND p.fk_soc = ".((int) $this->socid); } @@ -130,7 +127,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$user->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -155,7 +152,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->where; @@ -179,7 +176,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, SUM(p.".$this->field.")"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -204,7 +201,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, AVG(p.".$this->field.")"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -227,7 +224,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%Y') as year, COUNT(*) as nb, SUM(".$this->field.") as total, AVG(".$this->field.") as avg"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->where; @@ -253,7 +250,7 @@ class PropaleStats extends Stats $sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg"; $sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product"; if (!$user->rights->societe->client->voir && !$user->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->where; diff --git a/htdocs/commande/class/commandestats.class.php b/htdocs/commande/class/commandestats.class.php index 8ac89d5a18f..dded5f425f1 100644 --- a/htdocs/commande/class/commandestats.class.php +++ b/htdocs/commande/class/commandestats.class.php @@ -129,7 +129,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE c.date_commande BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -154,7 +154,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->where; @@ -178,7 +178,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE c.date_commande BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -203,7 +203,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, AVG(c.".$this->field.")"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE c.date_commande BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -226,7 +226,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%Y') as year, COUNT(*) as nb, SUM(c.".$this->field.") as total, AVG(".$this->field.") as avg"; $sql .= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->where; @@ -250,7 +250,7 @@ class CommandeStats extends Stats $sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg"; $sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product"; if (!$user->rights->societe->client->voir && !$user->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= $this->join; $sql .= " WHERE ".$this->where; From f405f859ca03c352b1506bdd72cf365843630c99 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 2 Dec 2022 22:49:52 +0100 Subject: [PATCH 02/20] ineer join is better than coma and where --- htdocs/commande/class/commandestats.class.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/htdocs/commande/class/commandestats.class.php b/htdocs/commande/class/commandestats.class.php index dded5f425f1..8d55f9794ee 100644 --- a/htdocs/commande/class/commandestats.class.php +++ b/htdocs/commande/class/commandestats.class.php @@ -93,9 +93,6 @@ class CommandeStats extends Stats //$this->where.= " AND c.fk_soc = s.rowid AND c.entity = ".$conf->entity; $this->where .= ($this->where ? ' AND ' : '').'c.entity IN ('.getEntity('commande').')'; - if (!$user->rights->societe->client->voir && !$this->socid) { - $this->where .= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); - } if ($this->socid) { $this->where .= " AND c.fk_soc = ".((int) $this->socid); } From 89b10b0dfbc10e814fd359e6690f6c7bedb85554 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 6 Dec 2022 04:48:04 +0100 Subject: [PATCH 03/20] Fix css --- 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 479b8b30977..29422b0a7ba 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3724,7 +3724,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ // Add CSS $arrayconvpictotomorcess = array( 'action'=>'infobox-action', 'account'=>'infobox-bank_account', 'accountline'=>'infobox-bank_account', 'accountancy'=>'infobox-bank_account', 'asset'=>'infobox-bank_account', - 'bank_account'=>'bg-infobox-bank_account', + 'bank_account'=>'infobox-bank_account', 'bill'=>'infobox-commande', 'billa'=>'infobox-commande', 'billr'=>'infobox-commande', 'billd'=>'infobox-commande', 'margin'=>'infobox-bank_account', 'conferenceorbooth'=>'infobox-project', 'cash-register'=>'infobox-bank_account', 'contract'=>'infobox-contrat', 'check'=>'font-status4', 'collab'=>'infobox-action', 'conversation'=>'infobox-contrat', From ee7e394ebf8a2b0d68fcf4785746e826822b20e3 Mon Sep 17 00:00:00 2001 From: Milen Karaganski Date: Thu, 8 Dec 2022 20:22:41 +0200 Subject: [PATCH 04/20] FIX|Fix [#23075] Wrong invoice unit price when billing Project task spent time --- htdocs/projet/tasks/time.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index cf2de5bef28..888bd4fb50b 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -462,7 +462,7 @@ if ($action == 'confirm_generateinvoice') { foreach ($arrayoftasks as $userid => $value) { $fuser->fetch($userid); - //$pu_ht = $value['timespent'] * $fuser->thm; + $pu_ht = $fuser->thm; $username = $fuser->getFullName($langs); // Define qty per hour From 381b99841372742ae1c3a285945818133d16ed4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Micard?= Date: Fri, 9 Dec 2022 11:45:09 +0100 Subject: [PATCH 05/20] Display blank td when action is confirm_valid --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 27b00377411..0e96f05539d 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7542,7 +7542,7 @@ abstract class CommonObject if ($display_type == 'card') { $out .= ''; - if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER) && ($action == 'view' || $action == 'valid' || $action == 'editline')) { + if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER) && ($action == 'view' || $action == 'valid' || $action == 'editline' || $action == 'confirm_valid')) { $out .= ''; } $out .= ''; - if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER) && ($action == 'view' || $action == 'valid' || $action == 'editline' || $action == 'confirm_valid')) { + if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER) && ($action == 'view' || $action == 'valid' || $action == 'editline' || $action == 'confirm_valid' || $action == 'confirm_cancel')) { $out .= ''; } $out .= ' 0 ? $idprod : 0)); From b8755bcf65a7282907049a3b34d48f202fcd8771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 12 Dec 2022 10:39:24 +0100 Subject: [PATCH 09/20] fix parameters order --- htdocs/reception/class/reception.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 7244fdcb60b..0f9293a18cd 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1779,7 +1779,7 @@ class Reception extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record $inventorycode = ''; - $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->cost_price, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, '', $obj->fk_origin_stock, $inventorycode); + $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->cost_price, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref), $this->db->jdate($obj->eatby), '', $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; @@ -1911,7 +1911,7 @@ class Reception extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record $inventorycode = ''; - $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->cost_price, $langs->trans("ReceptionBackToDraftInDolibarr", $this->ref), $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, '', 0, $inventorycode); + $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->cost_price, $langs->trans("ReceptionBackToDraftInDolibarr", $this->ref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, 0, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; From c134090321f8cfe64866bf0b123911f7c0e06e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 12 Dec 2022 10:44:34 +0100 Subject: [PATCH 10/20] fix parameters order --- htdocs/reception/class/reception.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 0f9293a18cd..6ced6d601da 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1779,7 +1779,7 @@ class Reception extends CommonObject // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record $inventorycode = ''; - $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->cost_price, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref), $this->db->jdate($obj->eatby), '', $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock, $inventorycode); + $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->cost_price, $langs->trans("ReceptionUnClassifyCloseddInDolibarr", $numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock, $inventorycode); if ($result < 0) { $this->error = $mouvS->error; $this->errors = $mouvS->errors; From 8a1df1df92dc453709d45706c2aea7ec2973b9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Micard?= Date: Mon, 12 Dec 2022 17:36:00 +0100 Subject: [PATCH 11/20] Give order to inventory lines --- htdocs/product/inventory/inventory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 2c8a9bd2e13..5906e83ecc5 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -640,6 +640,7 @@ if ($object->id > 0) { $sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated'; $sql .= ' FROM '.MAIN_DB_PREFIX.'inventorydet as id'; $sql .= ' WHERE id.fk_inventory = '.((int) $object->id); + $sql .= ' ORDER BY id.rowid'; $cacheOfProducts = array(); $cacheOfWarehouses = array(); From d98c998b8eb50e7a2c8716977161a768d5a3cd12 Mon Sep 17 00:00:00 2001 From: Quentin-Seekness <72733832+Quentin-Seekness@users.noreply.github.com> Date: Tue, 13 Dec 2022 11:26:53 +0100 Subject: [PATCH 12/20] Adding filter parameters Adding filter parameters in addMoreActionsButtonsList Hook --- htdocs/accountancy/bookkeeping/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 44a7906fe36..d6234b3d8ac 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -874,7 +874,7 @@ if (count($filter)) { $buttonLabel = $langs->trans("ExportList"); } -$parameters = array(); +$parameters = array('param' => $param); $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); From 1d8cf1b44ff314ea446a9f4e9335a3952417a65c Mon Sep 17 00:00:00 2001 From: Quentin-Seekness <72733832+Quentin-Seekness@users.noreply.github.com> Date: Tue, 13 Dec 2022 11:29:28 +0100 Subject: [PATCH 13/20] Add filter params --- htdocs/accountancy/bookkeeping/listbyaccount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 6cd80d7c1aa..db0b3981246 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -602,7 +602,7 @@ print ''; print ''; print ''; -$parameters = array(); +$parameters = array('param' => $param); $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); From 8c6f3719c3e4b87ce78a1c09c529242413ebdd02 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Dec 2022 15:22:59 +0100 Subject: [PATCH 14/20] Fix delay between emails --- scripts/emailings/mailing-send.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/emailings/mailing-send.php b/scripts/emailings/mailing-send.php index f427e42d8cb..4dcb9e58c97 100755 --- a/scripts/emailings/mailing-send.php +++ b/scripts/emailings/mailing-send.php @@ -80,7 +80,7 @@ if (empty($conf->global->MAILING_LIMIT_SENDBYCLI)) { print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; if (!empty($conf->global->MAILING_DELAY)) { - print 'A delay of '.((float) $conf->global->MAILING_DELAY * 1000000).' millisecond has been set between each email'."\n"; + print 'A delay of '.((float) $conf->global->MAILING_DELAY * 1000000).' seconds has been set between each email'."\n"; } if ($conf->global->MAILING_LIMIT_SENDBYCLI == '-1') { From a673bdba155c43119639036fefc3e975474f27cc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Dec 2022 20:06:56 +0100 Subject: [PATCH 15/20] Debug v17, on supplier, default vat rate is sale if no price found --- htdocs/core/boxes/box_produits.php | 4 +- .../core/boxes/box_produits_alerte_stock.php | 7 +-- htdocs/core/class/html.form.class.php | 6 +++ htdocs/core/lib/functions.lib.php | 33 ++++++++----- .../class/fournisseur.commande.class.php | 12 +++-- .../fourn/class/fournisseur.facture.class.php | 6 +-- .../fourn/class/fournisseur.product.class.php | 7 ++- htdocs/product/class/product.class.php | 47 +++++++++++++------ htdocs/product/dynamic_price/editor.php | 6 ++- htdocs/product/fournisseurs.php | 1 + htdocs/product/index.php | 4 +- htdocs/product/price.php | 3 +- .../class/supplier_proposal.class.php | 34 +++++++------- 13 files changed, 106 insertions(+), 64 deletions(-) diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index f036628db3b..f0f346b69a9 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -168,12 +168,14 @@ class box_produits extends ModeleBoxes $price = ''; $price_base_type = ''; if ($usercancreadprice) { - if (empty($conf->dynamicprices->enabled) || empty($objp->fk_price_expression)) { + if (!isModEnabled('dynamicprices') || empty($objp->fk_price_expression)) { $price_base_type = $langs->trans($objp->price_base_type); $price = ($objp->price_base_type == 'HT') ?price($objp->price) : $price = price($objp->price_ttc); } else { //Parse the dynamic price $productstatic->fetch($objp->rowid, '', '', 1); + + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProduct($productstatic); if ($price_result >= 0) { diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php index f928ebd7c6f..e7150929a89 100644 --- a/htdocs/core/boxes/box_produits_alerte_stock.php +++ b/htdocs/core/boxes/box_produits_alerte_stock.php @@ -167,12 +167,13 @@ class box_produits_alerte_stock extends ModeleBoxes 'text' => $objp->label, ); - if (empty($conf->dynamicprices->enabled) || empty($objp->fk_price_expression)) { + if (!isModEnabled('dynamicprices') || empty($objp->fk_price_expression)) { $price_base_type = $langs->trans($objp->price_base_type); $price = ($objp->price_base_type == 'HT') ?price($objp->price) : $price = price($objp->price_ttc); - } else //Parse the dynamic price - { + } else { //Parse the dynamic price $productstatic->fetch($objp->rowid, '', '', 1); + + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProduct($productstatic); if ($price_result >= 0) { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 21885b6da34..df190abc43e 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2828,6 +2828,8 @@ class Form if (isModEnabled('dynamicprices') && !empty($objp->fk_price_expression)) { $price_product = new Product($this->db); $price_product->fetch($objp->rowid, '', '', 1); + + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProduct($price_product); if ($price_result >= 0) { @@ -3463,6 +3465,8 @@ class Form $prod_supplier->fourn_qty = $objp->quantity; $prod_supplier->fourn_tva_tx = $objp->tva_tx; $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression; + + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProductSupplier($prod_supplier); if ($price_result >= 0) { @@ -3717,6 +3721,8 @@ class Form $prod_supplier->fourn_qty = $objp->quantity; $prod_supplier->fourn_tva_tx = $objp->tva_tx; $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression; + + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProductSupplier($prod_supplier); if ($price_result >= 0) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 03f13961246..27d1343747e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6316,20 +6316,25 @@ function get_product_vat_for_country($idprod, $thirdpartytouse, $idprodfournpric $product = new Product($db); $product->fetch($idprod); - if ($mysoc->country_code == $thirdpartytouse->country_code) { // If country to consider is ours + if ($mysoc->country_code == $thirdpartytouse->country_code) { + // If country to consider is ours if ($idprodfournprice > 0) { // We want vat for product for a "supplier" object - $product->get_buyprice($idprodfournprice, 0, 0, 0); - $ret = $product->vatrate_supplier; - if ($product->default_vat_code) { - $ret .= ' ('.$product->default_vat_code.')'; - } - } else { - $ret = $product->tva_tx; // Default vat of product we defined - if ($product->default_vat_code) { - $ret .= ' ('.$product->default_vat_code.')'; + $result = $product->get_buyprice($idprodfournprice, 0, 0, 0); + if ($result > 0) { + $ret = $product->vatrate_supplier; + if ($product->default_vat_code_supplier) { + $ret .= ' ('.$product->default_vat_code_supplier.')'; + } + $found = 1; } } - $found = 1; + if (!$found) { + $ret = $product->tva_tx; // Default sales vat of product + if ($product->default_vat_code) { + $ret .= ' ('.$product->default_vat_code.')'; + } + $found = 1; + } } else { // TODO Read default product vat according to product and another countrycode. // Vat for couple anothercountrycode/product is data that is not managed and store yet, so we will fallback on next rule. @@ -6341,7 +6346,7 @@ function get_product_vat_for_country($idprod, $thirdpartytouse, $idprodfournpric // If vat of product for the country not found or not defined, we return the first rate found (sorting on use_default, then on higher vat of country). $sql = "SELECT t.taux as vat_rate, t.code as default_vat_code"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; - $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code = '".$db->escape($thirdpartytouse->country_code)."'"; + $sql .= " WHERE t.active = 1 AND t.fk_pays = c.rowid AND c.code = '".$db->escape($thirdpartytouse->country_code)."'"; $sql .= " ORDER BY t.use_default DESC, t.taux DESC, t.code ASC, t.recuperableonly ASC"; $sql .= $db->plimit(1); @@ -6359,7 +6364,9 @@ function get_product_vat_for_country($idprod, $thirdpartytouse, $idprodfournpric dol_print_error($db); } } else { - // Forced value if autodetect fails. MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS can be '1.23' or '1.23 (CODE)' + // Forced value if autodetect fails. MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS can be + // '1.23' + // or '1.23 (CODE)' $defaulttx = ''; if ($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS != 'none') { $defaulttx = $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index aed73da97ba..4fc242bdbcc 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -35,11 +35,12 @@ */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonorder.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; if (isModEnabled('productbatch')) { require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; } -require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; + /** * Class to manage predefined suppliers products @@ -1820,10 +1821,10 @@ class CommandeFournisseur extends CommonOrder $label = ''; // deprecated if ($fk_product > 0) { - if (!empty($conf->global->SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY)) { + if (!empty($conf->global->SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY)) { // Not the common case // Check quantity is enough dol_syslog(get_class($this)."::addline we check supplier prices fk_product=".$fk_product." fk_prod_fourn_price=".$fk_prod_fourn_price." qty=".$qty." ref_supplier=".$ref_supplier); - $prod = new Product($this->db); + $prod = new ProductFournisseur($this->db); if ($prod->fetch($fk_product) > 0) { $product_type = $prod->type; $label = $prod->label; @@ -1882,7 +1883,7 @@ class CommandeFournisseur extends CommonOrder if (!empty($prod->packaging) && ($qty % $prod->packaging) > 0) { $coeff = intval($qty / $prod->packaging) + 1; $qty = $prod->packaging * $coeff; - setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs'); + setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs'); } } } @@ -1895,6 +1896,7 @@ class CommandeFournisseur extends CommonOrder $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $mysoc, $this->thirdparty); // Clean vat code + $reg = array(); $vat_src_code = ''; if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 456eab8b0b9..adf9fac3bde 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -38,12 +38,10 @@ include_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; if (isModEnabled('accounting')) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -} -if (isModEnabled('accounting')) { require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; } @@ -2073,7 +2071,7 @@ class FactureFournisseur extends CommonInvoice if (!empty($conf->global->SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY)) { // Check quantity is enough dol_syslog(get_class($this)."::addline we check supplier prices fk_product=".$fk_product." qty=".$qty." ref_supplier=".$ref_supplier); - $prod = new Product($this->db); + $prod = new ProductFournisseur($this->db); if ($prod->fetch($fk_product) > 0) { $product_type = $prod->type; $label = $prod->label; diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index ec923f91118..fa1706a523a 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -31,7 +31,6 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/productfournisseurprice.class.php'; @@ -638,7 +637,8 @@ class ProductFournisseur extends Product } $this->packaging = $obj->packaging; - if (empty($ignore_expression) && !empty($this->fk_supplier_price_expression)) { + if (isModEnabled('dynamicprices') && empty($ignore_expression) && !empty($this->fk_supplier_price_expression)) { + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProductSupplier($this); if ($price_result >= 0) { @@ -748,6 +748,7 @@ class ProductFournisseur extends Product } if (isModEnabled('dynamicprices') && !empty($prodfourn->fk_supplier_price_expression)) { + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProductSupplier($prodfourn); if ($price_result >= 0) { @@ -860,6 +861,8 @@ class ProductFournisseur extends Product $prod_supplier->fourn_qty = $record["quantity"]; $prod_supplier->fourn_tva_tx = $record["tva_tx"]; $prod_supplier->fk_supplier_price_expression = $record["fk_supplier_price_expression"]; + + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProductSupplier($prod_supplier); if ($price_result >= 0) { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index bebe5d5a98d..bb6d9b2a084 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -191,12 +191,28 @@ class Product extends CommonObject //! French VAT NPR (0 or 1) public $tva_npr = 0; + //! Default discount percent + public $remise_percent; + //! Other local taxes public $localtax1_tx; public $localtax2_tx; public $localtax1_type; public $localtax2_type; + // Properties set by get_buyprice() for return + + public $desc_supplier; + public $vatrate_supplier; + public $default_vat_code_supplier; + public $fourn_multicurrency_price; + public $fourn_multicurrency_unitprice; + public $fourn_multicurrency_tx; + public $fourn_multicurrency_id; + public $fourn_multicurrency_code; + public $packaging; + + public $lifetime; public $qc_frequency; @@ -415,6 +431,7 @@ class Product extends CommonObject public $fk_price_expression; /* To store supplier price found */ + public $fourn_qty; public $fourn_pu; public $fourn_price_base_type; public $fourn_socid; @@ -1955,9 +1972,8 @@ class Product extends CommonObject $result = 0; // We do a first search with a select by searching with couple prodfournprice and qty only (later we will search on triplet qty/product_id/fourn_ref) - $sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.remise_percent,"; - $sql .= " pfp.fk_product, pfp.ref_fourn, pfp.desc_fourn, pfp.fk_soc, pfp.tva_tx, pfp.fk_supplier_price_expression,"; - $sql .= " pfp.default_vat_code,"; + $sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.remise_percent, pfp.fk_soc,"; + $sql .= " pfp.fk_product, pfp.ref_fourn as ref_supplier, pfp.desc_fourn as desc_supplier, pfp.tva_tx, pfp.default_vat_code, pfp.fk_supplier_price_expression,"; $sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code,"; $sql .= " pfp.packaging"; $sql .= " FROM ".$this->db->prefix()."product_fournisseur_price as pfp"; @@ -1972,14 +1988,15 @@ class Product extends CommonObject if ($resql) { $obj = $this->db->fetch_object($resql); if ($obj && $obj->quantity > 0) { // If we found a supplier prices from the id of supplier price - if (!empty($conf->dynamicprices->enabled) && !empty($obj->fk_supplier_price_expression)) { - include_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; + if (isModEnabled('dynamicprices') && !empty($obj->fk_supplier_price_expression)) { $prod_supplier = new ProductFournisseur($this->db); $prod_supplier->product_fourn_price_id = $obj->rowid; $prod_supplier->id = $obj->fk_product; $prod_supplier->fourn_qty = $obj->quantity; $prod_supplier->fourn_tva_tx = $obj->tva_tx; $prod_supplier->fk_supplier_price_expression = $obj->fk_supplier_price_expression; + + include_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProductSupplier($prod_supplier); if ($price_result >= 0) { @@ -1991,12 +2008,12 @@ class Product extends CommonObject $this->fourn_pu = $obj->price / $obj->quantity; // Unit price of product of supplier $this->fourn_price_base_type = 'HT'; // Price base type $this->fourn_socid = $obj->fk_soc; // Company that offer this price - $this->ref_fourn = $obj->ref_fourn; // deprecated - $this->ref_supplier = $obj->ref_fourn; // Ref supplier - $this->desc_supplier = $obj->desc_fourn; // desc supplier + $this->ref_fourn = $obj->ref_supplier; // deprecated + $this->ref_supplier = $obj->ref_supplier; // Ref supplier + $this->desc_supplier = $obj->desc_supplier; // desc supplier $this->remise_percent = $obj->remise_percent; // remise percent if present and not typed $this->vatrate_supplier = $obj->tva_tx; // Vat ref supplier - $this->default_vat_code = $obj->default_vat_code; // Vat code supplier + $this->default_vat_code_supplier = $obj->default_vat_code; // Vat code supplier $this->fourn_multicurrency_price = $obj->multicurrency_price; $this->fourn_multicurrency_unitprice = $obj->multicurrency_unitprice; $this->fourn_multicurrency_tx = $obj->multicurrency_tx; @@ -2010,8 +2027,7 @@ class Product extends CommonObject } else { // If not found // We do a second search by doing a select again but searching with less reliable criteria: couple qty/id product, and if set fourn_ref or fk_soc. $sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.remise_percent, pfp.fk_soc,"; - $sql .= " pfp.fk_product, pfp.ref_fourn as ref_supplier, pfp.desc_fourn as desc_supplier, pfp.tva_tx, pfp.fk_supplier_price_expression,"; - $sql .= " pfp.default_vat_code,"; + $sql .= " pfp.fk_product, pfp.ref_fourn as ref_supplier, pfp.desc_fourn as desc_supplier, pfp.tva_tx, pfp.default_vat_code, pfp.fk_supplier_price_expression,"; $sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code,"; $sql .= " pfp.packaging"; $sql .= " FROM ".$this->db->prefix()."product_fournisseur_price as pfp"; @@ -2036,14 +2052,15 @@ class Product extends CommonObject if ($resql) { $obj = $this->db->fetch_object($resql); if ($obj && $obj->quantity > 0) { // If found - if (!empty($conf->dynamicprices->enabled) && !empty($obj->fk_supplier_price_expression)) { - include_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; + if (isModEnabled('dynamicprices') && !empty($obj->fk_supplier_price_expression)) { $prod_supplier = new ProductFournisseur($this->db); $prod_supplier->product_fourn_price_id = $obj->rowid; $prod_supplier->id = $obj->fk_product; $prod_supplier->fourn_qty = $obj->quantity; $prod_supplier->fourn_tva_tx = $obj->tva_tx; $prod_supplier->fk_supplier_price_expression = $obj->fk_supplier_price_expression; + + include_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProductSupplier($prod_supplier); if ($result >= 0) { @@ -2061,7 +2078,7 @@ class Product extends CommonObject $this->desc_supplier = $obj->desc_supplier; // desc supplier $this->remise_percent = $obj->remise_percent; // remise percent if present and not typed $this->vatrate_supplier = $obj->tva_tx; // Vat ref supplier - $this->default_vat_code = $obj->default_vat_code; // Vat code supplier + $this->default_vat_code_supplier = $obj->default_vat_code; // Vat code supplier $this->fourn_multicurrency_price = $obj->multicurrency_price; $this->fourn_multicurrency_unitprice = $obj->multicurrency_unitprice; $this->fourn_multicurrency_tx = $obj->multicurrency_tx; @@ -2696,7 +2713,7 @@ class Product extends CommonObject } } - if (!empty($conf->dynamicprices->enabled) && !empty($this->fk_price_expression) && empty($ignore_expression)) { + if (isModEnabled('dynamicprices') && !empty($this->fk_price_expression) && empty($ignore_expression)) { include_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProduct($this); diff --git a/htdocs/product/dynamic_price/editor.php b/htdocs/product/dynamic_price/editor.php index f5240d5cf61..5a95eb2bfc6 100644 --- a/htdocs/product/dynamic_price/editor.php +++ b/htdocs/product/dynamic_price/editor.php @@ -67,7 +67,8 @@ if ($action == 'add') { if ($eid == 0) { $result = $price_expression->find_title($title); if ($result == 0) { //No existing entry found with title, ok - //Check the expression validity by parsing it + // Check the expression validity by parsing it + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($db); $price_result = $priceparser->testExpression($id, $expression); if ($price_result < 0) { //Expression is not valid @@ -95,7 +96,8 @@ if ($action == 'update') { if ($eid != 0) { $result = $price_expression->find_title($title); if ($result == 0 || $result == $eid) { //No existing entry found with title or existing one is the current one, ok - //Check the expression validity by parsing it + // Check the expression validity by parsing it + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($db); $price_result = $priceparser->testExpression($id, $expression); if ($price_result < 0) { //Expression is not valid diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 95de1f53da8..c1b61913d9f 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -318,6 +318,7 @@ if (empty($reshook)) { } else { if (isModEnabled('dynamicprices') && $price_expression !== '') { //Check the expression validity by parsing it + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($db); $object->fk_supplier_price_expression = $price_expression; $price_result = $priceparser->parseProductSupplier($object); diff --git a/htdocs/product/index.php b/htdocs/product/index.php index c2704111094..a25737d5583 100644 --- a/htdocs/product/index.php +++ b/htdocs/product/index.php @@ -373,9 +373,11 @@ if ((isModEnabled("product") || isModEnabled("service")) && ($user->hasRight("pr print ""; // Sell price if (empty($conf->global->PRODUIT_MULTIPRICES)) { - if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_price_expression)) { + if (isModEnabled('dynamicprices') && !empty($objp->fk_price_expression)) { $product = new Product($db); $product->fetch($objp->rowid); + + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($db); $price_result = $priceparser->parseProduct($product); if ($price_result >= 0) { diff --git a/htdocs/product/price.php b/htdocs/product/price.php index cde676c9732..5a386792d1c 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -258,11 +258,12 @@ if (empty($reshook)) { $psq = empty($newpsq) ? 0 : $newpsq; $maxpricesupplier = $object->min_recommended_price(); - if (!empty($conf->dynamicprices->enabled)) { + if (isModEnabled('dynamicprices')) { $object->fk_price_expression = empty($eid) ? 0 : $eid; //0 discards expression if ($object->fk_price_expression != 0) { //Check the expression validity by parsing it + require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($db); if ($priceparser->parseProduct($object) < 0) { diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 15dd1924718..1f95e3de5fd 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -452,49 +452,49 @@ class SupplierProposal extends CommonObject if (!empty($conf->global->SUPPLIER_PROPOSAL_WITH_PREDEFINED_PRICES_ONLY)) { // Check quantity is enough dol_syslog(get_class($this)."::addline we check supplier prices fk_product=".$fk_product." fk_fournprice=".$fk_fournprice." qty=".$qty." ref_supplier=".$ref_supplier); - $prod = new Product($this->db); - if ($prod->fetch($fk_product) > 0) { - $product_type = $prod->type; - $label = $prod->label; + $productsupplier = new ProductFournisseur($this->db); + if ($productsupplier->fetch($fk_product) > 0) { + $product_type = $productsupplier->type; + $label = $productsupplier->label; $fk_prod_fourn_price = $fk_fournprice; // We use 'none' instead of $ref_supplier, because fourn_ref may not exists anymore. So we will take the first supplier price ok. // If we want a dedicated supplier price, we must provide $fk_prod_fourn_price. - $result = $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc ? $this->fk_soc : $this->socid)); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$ref_supplier/$this->fk_soc + $result = $productsupplier->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc ? $this->fk_soc : $this->socid)); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$ref_supplier/$this->fk_soc if ($result > 0) { - $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice - $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice + $pu = $productsupplier->fourn_pu; // Unit price supplier price set by get_buyprice + $ref_supplier = $productsupplier->ref_supplier; // Ref supplier price set by get_buyprice // is remise percent not keyed but present for the product we add it - if ($remise_percent == 0 && $prod->remise_percent != 0) { - $remise_percent = $prod->remise_percent; + if ($remise_percent == 0 && $productsupplier->remise_percent != 0) { + $remise_percent = $productsupplier->remise_percent; } } if ($result == 0) { // If result == 0, we failed to found the supplier reference price $langs->load("errors"); - $this->error = "Ref ".$prod->ref." ".$langs->trans("ErrorQtyTooLowForThisSupplier"); + $this->error = "Ref ".$productsupplier->ref." ".$langs->trans("ErrorQtyTooLowForThisSupplier"); $this->db->rollback(); dol_syslog(get_class($this)."::addline we did not found supplier price, so we can't guess unit price"); - //$pu = $prod->fourn_pu; // We do not overwrite unit price - //$ref = $prod->ref_fourn; // We do not overwrite ref supplier price + //$pu = $productsupplier->fourn_pu; // We do not overwrite unit price + //$ref = $productsupplier_fourn; // We do not overwrite ref supplier price return -1; } if ($result == -1) { $langs->load("errors"); - $this->error = "Ref ".$prod->ref." ".$langs->trans("ErrorQtyTooLowForThisSupplier"); + $this->error = "Ref ".$productsupplier->ref." ".$langs->trans("ErrorQtyTooLowForThisSupplier"); $this->db->rollback(); dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_DEBUG); return -1; } if ($result < -1) { - $this->error = $prod->error; - $this->errors = $prod->errors; + $this->error = $productsupplier->error; + $this->errors = $productsupplier->errors; $this->db->rollback(); dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_ERR); return -1; } } else { - $this->error = $prod->error; - $this->errors = $prod->errors; + $this->error = $productsupplier->error; + $this->errors = $productsupplier->errors; $this->db->rollback(); return -1; } From 7ca850830a3a2bfc0848c8ab113d8fcba220e2e2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Dec 2022 23:51:23 +0100 Subject: [PATCH 16/20] FIX #23212 --- .../class/accountancycategory.class.php | 52 +------------------ 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php index 7ae48c749c2..68662ccb610 100644 --- a/htdocs/accountancy/class/accountancycategory.class.php +++ b/htdocs/accountancy/class/accountancycategory.class.php @@ -452,56 +452,6 @@ class AccountancyCategory // extends CommonObject } } - /** - * Function to fill ->lines_cptbk with accounting account used (into bookkeeping) and not yet into a custom group - * - * @param int $id Id of custom group - * @return int <0 if KO, 0 if not found, >0 if OK - */ - /* - public function getCptBK($id) - { - global $conf; - - $sql = "SELECT DISTINCT t.numero_compte, t.label_operation, t.doc_ref"; - $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t"; - $sql .= " WHERE t.numero_compte NOT IN ("; // account not into a custom group - $sql .= " SELECT t.account_number"; - $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t"; - $sql .= " WHERE t.fk_accounting_category = ".((int) $id)." AND t.entity = ".$conf->entity.")"; - $sql .= " AND t.numero_compte IN ("; // account into current chart of account - $sql .= " SELECT DISTINCT aa.account_number"; - $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa"; - $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version"; - $sql .= " AND asy.rowid = ".((int) $conf->global->CHARTOFACCOUNTS); - $sql .= " AND aa.active = 1"; - $sql .= " AND aa.entity = ".$conf->entity.")"; - $sql .= " GROUP BY t.numero_compte, t.label_operation, t.doc_ref"; - $sql .= " ORDER BY t.numero_compte"; - - $this->lines_cptbk = array(); - - dol_syslog(__METHOD__, LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - if ($num) { - while ($obj = $this->db->fetch_object($resql)) { - $this->lines_cptbk[] = $obj; - } - } - - return $num; - } else { - $this->error = "Error ".$this->db->lasterror(); - $this->errors[] = $this->error; - dol_syslog(__METHOD__." ".implode(','.$this->errors), LOG_ERR); - - return -1; - } - } - */ - /** * Function to fill ->lines_cptbk with accounting account (defined in chart of account) and not yet into a custom group * @@ -743,7 +693,7 @@ class AccountancyCategory // extends CommonObject } $listofaccount .= "'".$cptcursor."'"; } - $sql .= " AND t.numero_compte IN (".$this->db->sanitize($listofaccount).")"; + $sql .= " AND t.numero_compte IN (".$this->db->sanitize($listofaccount, 1).")"; } else { $sql .= " AND t.numero_compte = '".$this->db->escape($cpt)."'"; } From c4dbc5e6d630421a907e4ed4ca273d52fd9ece4e Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 14 Dec 2022 10:39:15 +0800 Subject: [PATCH 17/20] Create invoice from Shipment - fix error of multicurrency code --- htdocs/compta/facture/card.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 616831ef688..cef114b7bba 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2928,6 +2928,11 @@ if ($action == 'create') { $remise_percent = (!empty($expesrc->remise_percent) ? $expesrc->remise_percent : (!empty($soc->remise_percent) ? $soc->remise_percent : 0)); $remise_absolue = (!empty($expesrc->remise_absolue) ? $expesrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 0)); + if (!empty($conf->multicurrency->enabled)) { + $currency_code = (!empty($expesrc->currency_code) ? $expesrc->currency_code : (!empty($soc->currency_code) ? $soc->currency_code : $objectsrc->multicurrency_code)); + $currency_tx = (!empty($expesrc->currency_tx) ? $expesrc->currency_tx : (!empty($soc->currency_tx) ? $soc->currency_tx : $objectsrc->currency_tx)); + } + //Replicate extrafields $expesrc->fetch_optionals(); $object->array_options = $expesrc->array_options; From 24585cf61b6fbe969f598de22b8dcdc9baa38c30 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 14 Dec 2022 02:45:20 +0000 Subject: [PATCH 18/20] Fixing style errors. --- htdocs/compta/facture/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index cef114b7bba..c0d7cf53a5d 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2930,9 +2930,9 @@ if ($action == 'create') { if (!empty($conf->multicurrency->enabled)) { $currency_code = (!empty($expesrc->currency_code) ? $expesrc->currency_code : (!empty($soc->currency_code) ? $soc->currency_code : $objectsrc->multicurrency_code)); - $currency_tx = (!empty($expesrc->currency_tx) ? $expesrc->currency_tx : (!empty($soc->currency_tx) ? $soc->currency_tx : $objectsrc->currency_tx)); + $currency_tx = (!empty($expesrc->currency_tx) ? $expesrc->currency_tx : (!empty($soc->currency_tx) ? $soc->currency_tx : $objectsrc->currency_tx)); } - + //Replicate extrafields $expesrc->fetch_optionals(); $object->array_options = $expesrc->array_options; From 19ba9f395d5afea0d9c0361c3bb872a017a6a78e Mon Sep 17 00:00:00 2001 From: daraelmin Date: Wed, 14 Dec 2022 09:26:19 +0100 Subject: [PATCH 19/20] Fix Darkmode input disabled color and bgcolor See discussion on #23207 - Fix for v14 Darkmode input disabled color and bgcolor --- htdocs/theme/eldy/global.inc.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 3f4efb7411b..6102e8584e8 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -34,6 +34,8 @@ --colortopbordertitle1: rgb(); --listetotal: #888888; --inputbackgroundcolor: #FFF; + --inputbackgroundcolordisabled: #eee; + --inputcolordisabled: rgb(80, 80, 80); --inputbordercolor: rgba(0,0,0,.15); --tooltipbgcolor: ; --tooltipfontcolor : ; @@ -85,7 +87,9 @@ if (!empty($conf->global->THEME_DARKMODEENABLED)) { --colortextbackvmenu: rgb(220,220,220); --tooltipfontcolor : rgb(220,220,220); --listetotal: rgb(245, 83, 158); - --inputbackgroundcolor: #2b2d2f; + --inputbackgroundcolor: rgb(70, 70, 70); + --inputbackgroundcolordisabled: rgb(60, 60, 60); + --inputcolordisabled: rgb(140, 140, 140); --inputbordercolor: rgb(220,220,220); --oddevencolor: rgb(220,220,220); --colorboxstatsborder: rgb(65,100,138); @@ -509,7 +513,8 @@ select:invalid, select.--error { } input:disabled, textarea:disabled, select[disabled='disabled'] { - background:#eee; + background: var(--inputbackgroundcolordisabled); + color: var(--inputcolordisabled); } input.liste_titre { From e603fdcfe5bdd55f0e6df670f11b8cc18a912d27 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 14 Dec 2022 11:34:56 +0100 Subject: [PATCH 20/20] FIX calculation of unit price for timespen invoice mode 1 line per user --- htdocs/projet/tasks/time.php | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index da2914f6e64..27ccb40b4ed 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -481,17 +481,27 @@ if ($action == 'confirm_generateinvoice') { foreach ($arrayoftasks as $userid => $data) { $fuser->fetch($userid); - - $pu_ht = $fuser->thm; // Default. However, we should later use the value calculated from timespent data per product - $username = $fuser->getFullName($langs); + foreach ($data as $fk_product => $timespent_data) { // Define qty per hour $qtyhour = $timespent_data['timespent'] / 3600; $qtyhourtext = convertSecondToTime($timespent_data['timespent'], 'all', $conf->global->MAIN_DURATION_OF_WORKDAY); - if ($timespent_data['timespent']) { - $pu_ht = price2num(($timespent_data['totalvaluetodivideby3600'] / $timespent_data['timespent']), 'MU'); + // Set the unit price we want to sell the time, for this user + if (getDolGlobalInt('PROJECT_USE_REAL_COST_FOR_TIME_INVOICING')) { + // We set unit price to 0 to force the use of the rate saved during recording + $pu_ht = 0; + } else { + // We want to sell all the time spent with the last hourly rate of user + $pu_ht = $fuser->thm; + } + + // If no unit price known for user, we use the price recorded when recording timespent. + if (empty($pu_ht)) { + if ($timespent_data['timespent']) { + $pu_ht = price2num(($timespent_data['totalvaluetodivideby3600'] / $timespent_data['timespent']), 'MU'); + } } // Add lines