From 22dddb8e8784e68308b73b71ca400b519e02273e Mon Sep 17 00:00:00 2001 From: Florian Mortgat <50440633+atm-florianm@users.noreply.github.com> Date: Wed, 15 May 2024 15:07:29 +0200 Subject: [PATCH 01/39] FIX: Backport page inventory.php from v18 to fix pagination bugs causing data loss (#29688) --- htdocs/product/inventory/inventory.php | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 4b2ea3e93c0f3..b924b9c442c92 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -97,11 +97,10 @@ //$result = restrictedArea($user, 'mymodule', $id); //Parameters Page -$param = '&id='.$object->id; +$paramwithsearch = ''; if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $paramwithsearch .= '&limit='.((int) $limit); } -$paramwithsearch = $param; if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { @@ -265,6 +264,7 @@ $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 .= $db->order('id.rowid', 'ASC'); $sql .= $db->plimit($limit, $offset); $db->begin(); @@ -297,7 +297,7 @@ $inventoryline->pmp_expected = price2num(GETPOST('expectedpmp_'.$lineid, 'alpha'), 'MS'); $resultupdate = $inventoryline->update($user); } - } else { + } elseif (GETPOSTISSET('id_' . $lineid)) { // Delete record $result = $inventoryline->fetch($lineid); if ($result > 0) { @@ -415,7 +415,6 @@ - /* * View */ @@ -459,7 +458,7 @@ // Confirmation to close if ($action == 'record') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $langs->trans('ConfirmFinish'), 'update', '', 0, 1); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&page='.$page.$paramwithsearch, $langs->trans('Close'), $langs->trans('ConfirmFinish'), 'update', '', 0, 1); $action = 'view'; } @@ -494,7 +493,7 @@ // Thirdparty $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1); // Project -if (!empty($conf->project->enabled)) +if (isModEnabled('project')) { $langs->load("projects"); $morehtmlref.='
'.$langs->trans('Project') . ' '; @@ -583,13 +582,13 @@ // Save if ($object->status == $object::STATUS_VALIDATED) { if ($permissiontoadd) { - print ''.$langs->trans("MakeMovementsAndClose").''."\n"; + print ''.$langs->trans("MakeMovementsAndClose").''."\n"; } else { print ''.$langs->trans('MakeMovementsAndClose').''."\n"; } if ($permissiontoadd) { - print ''.$langs->trans("Cancel").''."\n"; + print ''.$langs->trans("Cancel").''."\n"; } } } @@ -990,7 +989,7 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,sele $num = $db->num_rows($resql); if (!empty($limit != 0) || $num > $limit || $page) { - print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num >= $limit), '', '', $limit); + print_fleche_navigation($page, $_SERVER["PHP_SELF"], '&id='.$object->id.$paramwithsearch, ($num >= $limit), '', '', $limit); } $i = 0; @@ -1046,8 +1045,9 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,sele // Expected quantity = Quantity in stock when we start inventory print ''; $valuetoshow = $obj->qty_stock; + // For inventory not yet close, we overwrite with the real value in stock now - if ($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) { + if (($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) && !getDolGlobalString('DISABLE_QTY_OVERWRITE')) { if (isModEnabled('productbatch') && $product_static->hasbatch()) { $valuetoshow = $product_static->stock_warehouse[$obj->fk_warehouse]->detail_batch[$obj->batch]->qty; } else { @@ -1206,38 +1206,38 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,sele $(".paginationnext:last").click(function(e){ var form = $("#formrecord"); - var actionURL = "'.$_SERVER['PHP_SELF']."?page=".($page).$paramwithsearch.'"; + var actionURL = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page).$paramwithsearch.'"; $.ajax({ url: actionURL, data: form.serialize(), cache: false, success: function(result){ - window.location.href = "'.$_SERVER['PHP_SELF']."?page=".($page + 1).$paramwithsearch.'"; + window.location.href = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page + 1).$paramwithsearch.'"; }}); }); $(".paginationprevious:last").click(function(e){ var form = $("#formrecord"); - var actionURL = "'.$_SERVER['PHP_SELF']."?page=".($page).$paramwithsearch.'"; + var actionURL = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page).$paramwithsearch.'"; $.ajax({ url: actionURL, data: form.serialize(), cache: false, success: function(result){ - window.location.href = "'.$_SERVER['PHP_SELF']."?page=".($page - 1).$paramwithsearch.'"; + window.location.href = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page - 1).$paramwithsearch.'"; }}); }); $("#idbuttonmakemovementandclose").click(function(e){ var form = $("#formrecord"); - var actionURL = "'.$_SERVER['PHP_SELF']."?page=".($page).$paramwithsearch.'"; + var actionURL = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page).$paramwithsearch.'"; $.ajax({ url: actionURL, data: form.serialize(), cache: false, success: function(result){ - window.location.href = "'.$_SERVER['PHP_SELF']."?page=".($page - 1).$paramwithsearch.'&action=record"; + window.location.href = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page - 1).$paramwithsearch.'&action=record"; }}); }); }); From f3460eae482ca6c8a382b85704463336fd52fc3e Mon Sep 17 00:00:00 2001 From: IC-Mathieu <95343351+IC-Mathieu@users.noreply.github.com> Date: Tue, 21 May 2024 20:01:36 +0200 Subject: [PATCH 02/39] FIX REPLENISH MANY FOURN WHEN ORDER ALREADY CREATE (#29710) --- htdocs/product/stock/replenish.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 66ad0889b31b0..e3f274764888a 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -273,6 +273,7 @@ } else { $id = $result; } + $i++; } else { $order->socid = $suppliersid[$i]; $order->fetch_thirdparty(); From 26e09f85d2c0ac57ec4a6344a040ab43e1ca0d32 Mon Sep 17 00:00:00 2001 From: Yannis Hoareau <93135242+YannisHoareau@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:52:29 +0200 Subject: [PATCH 03/39] FIX: Unsigned propal having signing date (#29825) * FIX propal dates: setting sign date only if signed * FIX propal dates: clearing sign date when reopenning a propal * FIX propal dates: reworked + not clearing sign date Not clearing the sign date anymore because of 17.0 configuration that allow the user to choose if he wants to keep the previous sign date or the current date. * FIX propal dates: move comma to fix sql syntax error * FIX propal dates: add SQL request to update database This SQL request is meant to set the sign date and the signing user to null to match the fix * Update 15.0.0-16.0.0.sql --------- Co-authored-by: Laurent Destailleur --- htdocs/comm/propal/class/propal.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 2998753192595..a33d0864a6c6d 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2629,7 +2629,10 @@ public function closeProposal($user, $status, $note = '', $notrigger = 0) $newprivatenote = dol_concatdesc($this->note_private, $note); $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql .= " SET fk_statut = ".((int) $status).", note_private = '".$this->db->escape($newprivatenote)."', date_signature='".$this->db->idate($now)."', fk_user_signature=".$user->id; + $sql .= " SET fk_statut = ".((int) $status).", note_private = '".$this->db->escape($newprivatenote)."'"; + if ($status == self::STATUS_SIGNED) { + $sql .= ", date_signature='".$this->db->idate($now)."', fk_user_signature=".$user->id; + } $sql .= " WHERE rowid = ".((int) $this->id); $resql = $this->db->query($sql); From a3e7151633a0d098e0263b4b68cb25cff8647daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Champlon?= <85104766+Kazimir42@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:20:25 +0200 Subject: [PATCH 04/39] fix restrictedArea on selectobject (#29882) --- htdocs/core/ajax/selectobject.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/core/ajax/selectobject.php b/htdocs/core/ajax/selectobject.php index c8c3e13ea3d2b..c4010731ccba4 100644 --- a/htdocs/core/ajax/selectobject.php +++ b/htdocs/core/ajax/selectobject.php @@ -84,7 +84,11 @@ $searchkey = (($id && GETPOST($id, 'alpha')) ? GETPOST($id, 'alpha') : (($htmlname && GETPOST($htmlname, 'alpha')) ? GETPOST($htmlname, 'alpha') : '')); // Add a security test to avoid to get content of all tables -restrictedArea($user, $objecttmp->element, $id); +if (!empty($objecttmp->module)) { + restrictedArea($user, $objecttmp->module, $id, $objecttmp->table_element, $objecttmp->element); +}else { + restrictedArea($user, $objecttmp->element, $id); +} $arrayresult = $form->selectForFormsList($objecttmp, $htmlname, '', 0, $searchkey, '', '', '', 0, 1); From 72a2a96063dae6a50e2ee56516f6716d43e341fd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Jun 2024 23:46:21 +0200 Subject: [PATCH 05/39] Fix travis --- htdocs/core/ajax/selectobject.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/ajax/selectobject.php b/htdocs/core/ajax/selectobject.php index c4010731ccba4..37a0e6e32e368 100644 --- a/htdocs/core/ajax/selectobject.php +++ b/htdocs/core/ajax/selectobject.php @@ -85,9 +85,9 @@ // Add a security test to avoid to get content of all tables if (!empty($objecttmp->module)) { - restrictedArea($user, $objecttmp->module, $id, $objecttmp->table_element, $objecttmp->element); -}else { - restrictedArea($user, $objecttmp->element, $id); + restrictedArea($user, $objecttmp->module, $id, $objecttmp->table_element, $objecttmp->element); +} else { + restrictedArea($user, $objecttmp->element, $id); } $arrayresult = $form->selectForFormsList($objecttmp, $htmlname, '', 0, $searchkey, '', '', '', 0, 1); From 040e9083da39a03bcbb0eddbc74ae78ebbf64866 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Fri, 7 Jun 2024 23:56:14 +0200 Subject: [PATCH 06/39] Fix : expense report reapproval email, wrong date format + missing parameter (#29874) --- htdocs/expensereport/card.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 0201dfdd7f668..44cd66ff0c553 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -502,8 +502,7 @@ // CONTENT $link = $urlwithroot.'/expensereport/card.php?id='.$object->id; $link = ''.$link.''; - $dateRefusEx = explode(" ", $object->date_refuse); - $message = $langs->transnoentities("ExpenseReportWaitingForReApprovalMessage", $dateRefusEx[0], $object->detail_refuse, $expediteur->getFullName($langs), $link); + $message = $langs->transnoentities("ExpenseReportWaitingForReApprovalMessage", dol_print_date($object->date_refuse, 'day'), $object->detail_refuse, $expediteur->getFullName($langs), get_date_range($object->date_debut, $object->date_fin, '', $langs), $link); // Rebuild pdf /* From b0e825c1230827e8462c89cc4c408c73d9324f2e Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com> Date: Sat, 8 Jun 2024 12:01:22 +0200 Subject: [PATCH 07/39] FIX: PHP 8 warning on output of successful cronjob (#29922) --- htdocs/cron/class/cronjob.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index b89d7ea3cb7e3..569364a4dfd6e 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1275,7 +1275,7 @@ public function run_jobs($userlogin) $error++; } else { dol_syslog(get_class($this)."::run_jobs END"); - $this->lastoutput = dol_substr((empty($object->output) ? "" : $object->output."\n").$errmsg, 0, $this::MAXIMUM_LENGTH_FOR_LASTOUTPUT_FIELD, 'UTF-8', 1); + $this->lastoutput = dol_substr((empty($object->output) ? "" : $object->output."\n"), 0, $this::MAXIMUM_LENGTH_FOR_LASTOUTPUT_FIELD, 'UTF-8', 1); $this->lastresult = var_export($result, true); $retval = $this->lastresult; } From 956d1b025a4a4096e143ba226c7f943058d5b749 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 8 Jun 2024 23:35:01 +0200 Subject: [PATCH 08/39] Fix : product price by quantity was removing default price (#29899) --- htdocs/product/price.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index d93fdbe9b1701..8ef9398cefe1e 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -503,7 +503,9 @@ if ($action == 'activate_price_by_qty') { // Activating product price by quantity add a new price line with price_by_qty set to 1 $level = GETPOST('level', 'int'); - $ret = $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 1); + $basePrice = ($object->price_base_type == 'HT') ? $object->price : $object->price_ttc; + $basePriceMin = ($object->price_base_type == 'HT') ? $object->price_min : $object->price_min_ttc; + $ret = $object->updatePrice($basePrice, $object->price_base_type, $user, $object->tva_tx, $basePriceMin, $level, $object->tva_npr, 1); if ($ret < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -513,7 +515,9 @@ if ($action == 'disable_price_by_qty') { // Disabling product price by quantity add a new price line with price_by_qty set to 0 $level = GETPOST('level', 'int'); - $ret = $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 0); + $basePrice = ($object->price_base_type == 'HT') ? $object->price : $object->price_ttc; + $basePriceMin = ($object->price_base_type == 'HT') ? $object->price_min : $object->price_min_ttc; + $ret = $object->updatePrice($basePrice, $object->price_base_type, $user, $object->tva_tx, $basePriceMin, $level, $object->tva_npr, 0); if ($ret < 0) { setEventMessages($object->error, $object->errors, 'errors'); From c5bb1856c2f0806d7da4a9f7ea44a71e29a3b831 Mon Sep 17 00:00:00 2001 From: lvessiller-opendsi Date: Sat, 15 Jun 2024 15:02:19 +0200 Subject: [PATCH 09/39] FIX modification date from label in accounting bookkeeping list (#30038) --- 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 0ec53018a215d..56a9a0916cf24 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -919,7 +919,7 @@ print $form->selectDate($search_date_modification_start, 'search_date_modification_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); print ''; print '
'; - print $form->selectDate($search_date_modification_end, 'search_date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print $form->selectDate($search_date_modification_end, 'search_date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); print '
'; print ''; } From 6031f8437bbb97b9f3547afdba4ce3c6f3781696 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com> Date: Sun, 30 Jun 2024 12:36:59 +0200 Subject: [PATCH 10/39] FIX: pos: invoice date incorrectly set beacause of timezome mismatches (reverts #36e91da) (#30184) --- htdocs/takepos/invoice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 64688ef537a89..6b98c197df72c 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -473,7 +473,7 @@ function fail($message) // If we add a line and no invoice yet, we create the invoice if (($action == "addline" || $action == "freezone") && $placeid == 0) { $invoice->socid = getDolGlobalString($constforcompanyid); - $invoice->date = dol_now('tzuserrel'); // We use the local date, only the day will be saved. + $invoice->date = dol_now(); // Invoice::create() needs a GMT timestamp $invoice->module_source = 'takepos'; $invoice->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ; $invoice->entity = !empty($_SESSION["takeposinvoiceentity"]) ? $_SESSION["takeposinvoiceentity"] : $conf->entity; From 75f853f2db63edcc6e1cf21d84536f77f2b13eac Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 1 Jul 2024 02:46:48 +0200 Subject: [PATCH 11/39] Fix date of invoice. We want the date of the user. --- htdocs/takepos/invoice.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 6b98c197df72c..5257e2ab7a2d8 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -473,7 +473,10 @@ function fail($message) // If we add a line and no invoice yet, we create the invoice if (($action == "addline" || $action == "freezone") && $placeid == 0) { $invoice->socid = getDolGlobalString($constforcompanyid); - $invoice->date = dol_now(); // Invoice::create() needs a GMT timestamp + + include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + $invoice->date = dol_get_first_hour(dol_now('tzuserrel')); // Invoice::create() needs a date with no hours + $invoice->module_source = 'takepos'; $invoice->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ; $invoice->entity = !empty($_SESSION["takeposinvoiceentity"]) ? $_SESSION["takeposinvoiceentity"] : $conf->entity; From ca39809658f116d974b76436761e38060c68f731 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 4 Jul 2024 20:46:29 +0200 Subject: [PATCH 12/39] Fix #30256 --- htdocs/accountancy/journal/bankjournal.php | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 9ca0c188fa2e0..1ddfd22832811 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -215,6 +215,7 @@ // one line tabpay = line into bank // one line for bank record = tabbq // one line for thirdparty record = tabtp + // Note: tabcompany is used to store the subledger account $i = 0; while ($i < $num) { $obj = $db->fetch_object($result); @@ -262,7 +263,8 @@ ); // Set accountancy code for user - // $obj->accountancy_code is the accountancy_code of table u=user but it is defined only if a link with type 'user' exists) + // $obj->accountancy_code is the accountancy_code of table u=user (but it is defined only if + // a link with type 'user' exists and user as a subledger account) $compta_user = (!empty($obj->accountancy_code) ? $obj->accountancy_code : ''); $tabuser[$obj->rowid] = array( @@ -359,13 +361,25 @@ $userstatic->lastname = $tabuser[$obj->rowid]['lastname']; $userstatic->statut = $tabuser[$obj->rowid]['status']; $userstatic->accountancy_code = $tabuser[$obj->rowid]['accountancy_code']; + // For a payment of social contribution, we have a link sc + user. + // but we already fill the $tabpay[$obj->rowid]["soclib"] in the line 'sc'. + // If we fill it here to, we must concat if ($userstatic->id > 0) { - $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0); + if ($is_sc) { + $tabpay[$obj->rowid]["soclib"] .= ' '.$userstatic->getNomUrl(1, 'accountancy', 0); + } else { + $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0); + } } else { $tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen, but happens with old data when id of user was not saved on expense report payment. } + if ($compta_user) { - $tabtp[$obj->rowid][$compta_user] += $amounttouse; + if ($is_sc) { + //$tabcompany[$obj->rowid][$compta_user] += $amounttouse; + } else { + $tabtp[$obj->rowid][$compta_user] += $amounttouse; + } } } elseif ($links[$key]['type'] == 'sc') { $chargestatic->id = $links[$key]['url_id']; From 05cfd3dc529989771b0274dc784e4cf4872f4481 Mon Sep 17 00:00:00 2001 From: ksar <35605507+ksar-ksar@users.noreply.github.com> Date: Wed, 10 Jul 2024 23:36:53 +0200 Subject: [PATCH 13/39] FIX #30274 : Add the include before executing dolibarr_set_const (#30320) --- htdocs/main.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index b7e0c93ffcd5c..a5a353ff7192a 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1582,6 +1582,7 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr } // Refresh value of MAIN_IHM_PARAMS_REV before forging the parameter line. if (GETPOST('dol_resetcache')) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", ((int) $conf->global->MAIN_IHM_PARAMS_REV) + 1, 'chaine', 0, '', $conf->entity); } From eca8735e2216e8378cf1cbea5991946c409de0a1 Mon Sep 17 00:00:00 2001 From: MaximilienR-easya <122890855+MaximilienR-easya@users.noreply.github.com> Date: Sat, 13 Jul 2024 18:13:32 +0200 Subject: [PATCH 14/39] =?UTF-8?q?Fix=20les=20lien=20de=20t=C3=A9l=C3=A9cha?= =?UTF-8?q?rgement=20de=20facture=20fournisseur=20sur=20la=20page=20vue=20?= =?UTF-8?q?d'ensemble=20des=20projets=20(#30349)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/projet/element.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 537215896a1bc..d86076b2633e8 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -1207,8 +1207,8 @@ $filedir = $conf->fournisseur->commande->multidir_output[$element->entity].'/'.dol_sanitizeFileName($element->ref); } elseif ($element_doc === 'invoice_supplier') { $element_doc = 'facture_fournisseur'; - $filename = get_exdir($element->id, 2, 0, 0, $element, 'product').dol_sanitizeFileName($element->ref); - $filedir = $conf->fournisseur->facture->multidir_output[$element->entity].'/'.get_exdir($element->id, 2, 0, 0, $element, 'invoice_supplier').dol_sanitizeFileName($element->ref); + $filename = get_exdir($element->id, 2, 0, 0, $element, 'invoice_supplier').dol_sanitizeFileName($element->ref); + $filedir = $conf->fournisseur->facture->multidir_output[$element->entity].'/'.$filename; } print '
'.$formfile->getDocumentsLink($element_doc, $filename, $filedir).'
'; From 30f1d4f18b05e84df76a0e8c23e6022555d1da61 Mon Sep 17 00:00:00 2001 From: MaximilienR-easya <122890855+MaximilienR-easya@users.noreply.github.com> Date: Sat, 20 Jul 2024 18:24:01 +0200 Subject: [PATCH 15/39] Backport fix from develop (#30421) --- 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 72603fdca9523..ad1fef236cd37 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2985,7 +2985,7 @@ public function getChildrenOfLine($id, $includealltree = 0) while ($row = $this->db->fetch_row($resql)) { $rows[] = $row[0]; if (!empty($includealltree)) { - $rows = array_merge($rows, $this->getChildrenOfLine($row[0]), $includealltree); + $rows = array_merge($rows, $this->getChildrenOfLine($row[0], $includealltree)); } } } From 09822203979872acf9a866b773164867d2ecd243 Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Wed, 24 Jul 2024 18:12:53 +0200 Subject: [PATCH 16/39] FIX: Supplier Order search on date valid (#30448) * FIX: Supplier Order search on date valid * FIX: Supplier Order search on date valid --- htdocs/fourn/commande/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 9144a61a982cf..7bff6c12eb819 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -856,10 +856,10 @@ $sql .= " AND cf.date_livraison <= '".$db->idate($search_date_delivery_end)."'"; } if ($search_date_valid_start) { - $sql .= " AND cf.date_commande >= '".$db->idate($search_date_valid_start)."'"; + $sql .= " AND cf.date_valid >= '".$db->idate($search_date_valid_start)."'"; } if ($search_date_valid_end) { - $sql .= " AND cf.date_commande <= '".$db->idate($search_date_valid_end)."'"; + $sql .= " AND cf.date_valid <= '".$db->idate($search_date_valid_end)."'"; } if ($search_date_approve_start) { $sql .= " AND cf.date_livraison >= '".$db->idate($search_date_approve_start)."'"; From 2c92e57fe7b81a814f67ad8064dce67f37f8118a Mon Sep 17 00:00:00 2001 From: atm-adrien <67913809+atm-adrien@users.noreply.github.com> Date: Thu, 1 Aug 2024 12:52:53 +0200 Subject: [PATCH 17/39] FIX : Display the real_PMP on inventory when its value is equal to 0 (#22291) * FIX : Display the real_PMP on inventory when its value is equal to 0 * FIX : PR Returns * FIX : PR returns --- htdocs/product/inventory/inventory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 4719fe00ce8c8..0d65a78baddb9 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -1087,7 +1087,7 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,sele print ''; - if (! empty($obj->pmp_real)) $pmp_real = $obj->pmp_real; + if (! empty($obj->pmp_real) || (string) $obj->pmp_real === '0') $pmp_real = $obj->pmp_real; else $pmp_real = $product_static->pmp; $pmp_valuation_real = $pmp_real * $qty_view; print ''; From 163e6239649dc6e03d6409f5971ac0f3017448c6 Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Wed, 7 Aug 2024 03:08:04 +0200 Subject: [PATCH 18/39] FIX: on change ref for bank account attachement are lost (#30529) * FIX: on change ref for bank account attachement are lost * FIX: on change ref for bank account attachement are lost * FIX: on change ref for bank account attachement are lost * Update card.php --------- Co-authored-by: Laurent Destailleur --- htdocs/compta/bank/card.php | 2 +- htdocs/compta/bank/class/account.class.php | 27 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index a923f3a082913..102e6c5f69770 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -80,7 +80,6 @@ $result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid); - /* * Actions */ @@ -222,6 +221,7 @@ $object = new Account($db); $object->fetch(GETPOST("id", 'int')); + $object->oldref = $object->ref; $object->ref = dol_string_nospecial(trim(GETPOST('ref', 'alpha'))); $object->label = trim(GETPOST("label", 'alphanohtml')); $object->courant = GETPOST("type"); diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index dcf13e72e3b6a..bea28d9775bc0 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -266,6 +266,11 @@ class Account extends CommonObject */ public $ics_transfer; + /** + * @var string The previous ref in case of rename on update to rename attachment folders + */ + public $oldref; + /** @@ -897,6 +902,28 @@ public function update(User $user, $notrigger = 0) } } + if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) { + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'"; + $sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type='bank_account' and entity = ".((int) $conf->entity); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->error = $this->db->lasterror(); + } + + // We rename directory in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->oldref); + $newref = dol_sanitizeFileName($this->ref); + $dirsource = $conf->bank->dir_output.'/'.$oldref; + $dirdest = $conf->bank->dir_output.'/'.$newref; + if (file_exists($dirsource)) { + dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG); + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok", LOG_DEBUG); + } + } + } + if (!$error && !$notrigger) { // Call trigger $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user); From e7e96f650aadb40ed0f32cb2442fd44f2a5d7d01 Mon Sep 17 00:00:00 2001 From: Shanty <111346550+evarisk-micka@users.noreply.github.com> Date: Tue, 27 Aug 2024 03:02:43 +0200 Subject: [PATCH 19/39] FIX #30768 allocate the correct invoice_line_id to the element timespent (#30769) --- 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 c35cd9e83cb24..87764277b6586 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -658,7 +658,7 @@ // Update lineid into line of timespent $sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id); - $sql .= ' WHERE rowid IN ('.$db->sanitize(join(',', $toselect)).') AND fk_user = '.((int) $userid); + $sql .= ' WHERE rowid = '.((int) $timespent_id).' AND fk_user = '.((int) $userid); $result = $db->query($sql); if (!$result) { $error++; From 9f5ef68123ad6336f99a36a7c791afaa7f4547e3 Mon Sep 17 00:00:00 2001 From: thomas-Ngr Date: Thu, 5 Sep 2024 16:01:31 +0200 Subject: [PATCH 20/39] fix replenish with multicurrency (#30832) * fix replenish * Use multicurrency supplier price instead of recomputing from EUR supplier price --- htdocs/product/stock/replenish.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index e3f274764888a..a1a99523d919c 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -194,6 +194,13 @@ // TODO Get desc in language of thirdparty } + // If we use multicurrency + if (isModEnabled('multicurrency') && !empty($productsupplier->fourn_multicurrency_code) && $productsupplier->fourn_multicurrency_code != $conf->currency) { + $line->multicurrency_code = $productsupplier->fourn_multicurrency_code; + $line->fk_multicurrency = $productsupplier->fourn_multicurrency_id; + $line->multicurrency_subprice = $productsupplier->fourn_multicurrency_unitprice; + } + $line->tva_tx = $productsupplier->vatrate_supplier; $line->subprice = $productsupplier->fourn_pu; $line->total_ht = $productsupplier->fourn_pu * $qty; @@ -262,7 +269,8 @@ null, null, 0, - $line->fk_unit + $line->fk_unit, + $line->multicurrency_subprice ?? 0 ); } if ($result < 0) { @@ -277,6 +285,7 @@ } else { $order->socid = $suppliersid[$i]; $order->fetch_thirdparty(); + $order->multicurrency_code = $order->thirdparty->multicurrency_code; // Trick to know which orders have been generated using the replenishment feature $order->source = $order::SOURCE_ID_REPLENISHMENT; From d17890f05b15d6d442fc333d1bc47738148a50a9 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com> Date: Thu, 12 Sep 2024 21:57:41 +0200 Subject: [PATCH 21/39] FIX: purge files cron: php warnings when rest module enabled (#30919) --- htdocs/core/class/conf.class.php | 1 + htdocs/core/class/utils.class.php | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 44a510ef15719..f92b1397f617b 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -161,6 +161,7 @@ public function __construct() $this->mailing = new stdClass(); $this->expensereport = new stdClass(); $this->productbatch = new stdClass(); + $this->api = new stdClass(); } /** diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index d983d06120335..5e2ecdf055e9d 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -133,7 +133,13 @@ public function purgeFiles($choices = 'tempfilesold+logfiles', $nbsecondsold = 8 $result = dol_delete_dir_recursive($filesarray[$key]['fullname'], $startcount, 1, 0, $tmpcountdeleted); - if (!in_array($filesarray[$key]['fullname'], array($conf->api->dir_temp, $conf->user->dir_temp))) { // The 2 directories $conf->api->dir_temp and $conf->user->dir_temp are recreated at end, so we do not count them + $recreatedDirs = array($conf->user->dir_temp); + + if (isModEnabled('api')) { + $recreatedDirs[] = $conf->api->dir_temp; + } + + if (!in_array($filesarray[$key]['fullname'], $recreatedDirs)) { // The 2 directories $conf->api->dir_temp and $conf->user->dir_temp are recreated at end, so we do not count them $count += $result; $countdeleted += $tmpcountdeleted; } From 61c5a61623125af2297bceffd1ad470b46173a66 Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Fri, 20 Sep 2024 17:46:52 +0200 Subject: [PATCH 22/39] fix: better error reporting in CMailFile (#31058) --- htdocs/core/class/CMailFile.class.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index da861fbfb0d2e..4110c7ee731b5 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -875,7 +875,7 @@ public function sendfile() } } elseif ($this->sendmode == 'smtps') { if (!is_object($this->smtps)) { - $this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."
Constructor of object CMailFile was not initialized without errors."; + $this->error = "Failed to send mail with smtps lib to HOST=".ini_get('SMTP').", PORT=".$conf->global->$keyforsmtpport."
Constructor of object CMailFile was not initialized without errors."; dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); return false; } @@ -1165,9 +1165,10 @@ public function sendfile() $res = true; if (!empty($this->error) || !empty($this->errors) || !$result) { if (!empty($failedRecipients)) { - $this->errors[] = 'Transport failed for the following addresses: "' . join('", "', $failedRecipients) . '".'; + $this->error = 'Transport failed for the following addresses: "' . join('", "', $failedRecipients) . '".'; + $this->errors[] = $this->error; } - dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); + dol_syslog("CMailFile::sendfile: mail end error=". join(' ', $this->errors), LOG_ERR); $res = false; if (!empty($conf->global->MAIN_MAIL_DEBUG)) { From bb40a43c5fa4c70ff158a9ba75686bb228700fb4 Mon Sep 17 00:00:00 2001 From: thomas-Ngr Date: Thu, 26 Sep 2024 03:13:34 +0200 Subject: [PATCH 23/39] FIX Add same security test whe nuploading files from API than from GUI (#31114) Co-authored-by: Laurent Destailleur --- htdocs/api/class/api_documents.class.php | 45 +++++++++++++++++++++++- htdocs/core/lib/files.lib.php | 2 +- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 197ca42469dca..f80b9f69666d9 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -693,7 +693,50 @@ public function post($filename, $modulepart, $ref = '', $subdir = '', $fileconte throw new RestException(500, "Failed to open file '".$destfiletmp."' for write"); } - $result = dol_move($destfiletmp, $destfile, 0, $overwriteifexists, 1); + $disablevirusscan = 0; + $src_file = $destfiletmp; + $dest_file = $destfile; + + // Security: + // If we need to make a virus scan + if (empty($disablevirusscan) && file_exists($src_file)) { + $checkvirusarray = dolCheckVirus($src_file); + if (count($checkvirusarray)) { + dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: errors='.join(',', $checkvirusarray), LOG_WARNING); + throw new RestException(500, 'ErrorFileIsInfectedWithAVirus: '.join(',', $checkvirusarray)); + } + } + + // Security: + // Disallow file with some extensions. We rename them. + // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. + if (isAFileWithExecutableContent($dest_file) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) { + // $upload_dir ends with a slash, so be must be sure the medias dir to compare to ends with slash too. + $publicmediasdirwithslash = $conf->medias->multidir_output[$conf->entity]; + if (!preg_match('/\/$/', $publicmediasdirwithslash)) { + $publicmediasdirwithslash .= '/'; + } + + if (strpos($upload_dir, $publicmediasdirwithslash) !== 0 || !getDolGlobalInt("MAIN_DOCUMENT_DISABLE_NOEXE_IN_MEDIAS_DIR")) { // We never add .noexe on files into media directory + $dest_file .= '.noexe'; + } + } + + // Security: + // We refuse cache files/dirs, upload using .. and pipes into filenames. + if (preg_match('/^\./', basename($src_file)) || preg_match('/\.\./', $src_file) || preg_match('/[<>|]/', $src_file)) { + dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING); + throw new RestException(500, "Refused to deliver file ".$src_file); + } + + // Security: + // We refuse cache files/dirs, upload using .. and pipes into filenames. + if (preg_match('/^\./', basename($dest_file)) || preg_match('/\.\./', $dest_file) || preg_match('/[<>|]/', $dest_file)) { + dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING); + throw new RestException(500, "Refused to deliver file ".$dest_file); + } + + $result = dol_move($destfiletmp, $dest_file, 0, $overwriteifexists, 1, 1); if (!$result) { throw new RestException(500, "Failed to move file into '".$destfile."'"); } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 2fab41a2a03c7..36be91901bbcf 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1081,7 +1081,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable $publicmediasdirwithslash .= '/'; } - if (strpos($upload_dir, $publicmediasdirwithslash) !== 0) { // We never add .noexe on files into media directory + if (strpos($upload_dir, $publicmediasdirwithslash) !== 0 || !getDolGlobalInt("MAIN_DOCUMENT_DISABLE_NOEXE_IN_MEDIAS_DIR")) { // We never add .noexe on files into media directory $file_name .= '.noexe'; $successcode = 2; } From a8cb076bbda27284ed68d82b14b6913070250556 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Sep 2024 03:34:32 +0200 Subject: [PATCH 24/39] Fix move --- htdocs/api/class/api_documents.class.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 4bd54f158af78..0c79e261f3853 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -805,10 +805,9 @@ public function post($filename, $modulepart, $ref = '', $subdir = '', $fileconte throw new RestException(500, "Refused to deliver file ".$dest_file); } - $result = dol_move($destfiletmp, $destfile, 0, $overwriteifexists, 1, 1); - + $result = dol_move($destfiletmp, $dest_file, 0, $overwriteifexists, 1, 1); if (!$result) { - throw new RestException(500, "Failed to move file into '".$destfile."'"); + throw new RestException(500, "Failed to move file into '".$dest_file."'"); } return dol_basename($destfile); From c0f5e314e1f497fd45a3f800523685feeba66774 Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Thu, 26 Sep 2024 03:51:06 +0200 Subject: [PATCH 25/39] fix: DOL_DATA_ROOT do not have last / by defaut, and last_main_doc not have first / (#31090) --- htdocs/compta/facture/class/facture.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 9d96dce5088b4..2379bc5e2c549 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -5602,9 +5602,9 @@ public function sendEmailsRemindersOnInvoiceDueDate($nbdays = 0, $paymentmode = $joinFileName = []; $joinFileMime = []; if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) { - $joinFile[] = DOL_DATA_ROOT.$tmpinvoice->last_main_doc; + $joinFile[] = DOL_DATA_ROOT.'/'.$tmpinvoice->last_main_doc; $joinFileName[] = basename($tmpinvoice->last_main_doc); - $joinFileMime[] = dol_mimetype(DOL_DATA_ROOT.$tmpinvoice->last_main_doc); + $joinFileMime[] = dol_mimetype(DOL_DATA_ROOT.'/'.$tmpinvoice->last_main_doc); } // Mail Creation From c727bbb530b5d3a884fbfbf25609d7ad383631a3 Mon Sep 17 00:00:00 2001 From: Florian Mortgat <50440633+atm-florianm@users.noreply.github.com> Date: Thu, 26 Sep 2024 18:41:41 +0200 Subject: [PATCH 26/39] FIX: when qty is not an integer, apply price() (#31138) * FIX: when qty is not an integer, apply price() to avoid displaying precision errors if php.ini's precision settings are too high * Apply eldy's suggestion to use price's parameters rather than a test --- htdocs/compta/stats/cabyprodserv.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php index 0a30390e215ac..3d1f12ce8b6a7 100644 --- a/htdocs/compta/stats/cabyprodserv.php +++ b/htdocs/compta/stats/cabyprodserv.php @@ -425,7 +425,7 @@ // Quantity print ''; - print $qty[$key]; + print price($qty[$key], 1, $langs, 0, 0); print ''; // Percent; From 231fc6ce707925f9ea5c9156b65287b98b44131d Mon Sep 17 00:00:00 2001 From: Florian Mortgat <50440633+atm-florianm@users.noreply.github.com> Date: Sun, 29 Sep 2024 15:27:24 +0200 Subject: [PATCH 27/39] FIX: if you call fetchLines several times, your $object->lines contains duplicates (#31167) --- htdocs/core/class/commonobject.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 547a6029e4030..4182c05dde727 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -9297,6 +9297,7 @@ public function fetchLinesCommon($morewhere = '') if ($resql) { $num_rows = $this->db->num_rows($resql); $i = 0; + $this->lines = array(); while ($i < $num_rows) { $obj = $this->db->fetch_object($resql); if ($obj) { From 74b67eb6c6c1274d6e0a8385b3b3a3a375da4875 Mon Sep 17 00:00:00 2001 From: Florian Mortgat <50440633+atm-florianm@users.noreply.github.com> Date: Sun, 29 Sep 2024 15:57:05 +0200 Subject: [PATCH 28/39] FIX - use price() to display qty on a product's stats tab to avoid showing too many decimals when rounding errors are possible (#31165) --- htdocs/core/lib/product.lib.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index f54f39b20f31c..003ab66ad2fcc 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -363,7 +363,7 @@ function show_stats_for_company($product, $socid) print ''; print $product->stats_propale['nb']; print ''; - print $product->stats_propale['qty']; + print price($product->stats_propale['qty'], 1, $langs, 0, 0); print ''; print ''; } @@ -381,7 +381,7 @@ function show_stats_for_company($product, $socid) print ''; print $product->stats_proposal_supplier['nb']; print ''; - print $product->stats_proposal_supplier['qty']; + print price($product->stats_proposal_supplier['qty'], 1, $langs, 0, 0); print ''; print ''; } @@ -399,7 +399,7 @@ function show_stats_for_company($product, $socid) print ''; print $product->stats_commande['nb']; print ''; - print $product->stats_commande['qty']; + print price($product->stats_commande['qty'], 1, $langs, 0, 0); print ''; print ''; } @@ -417,7 +417,7 @@ function show_stats_for_company($product, $socid) print ''; print $product->stats_commande_fournisseur['nb']; print ''; - print $product->stats_commande_fournisseur['qty']; + print price($product->stats_commande_fournisseur['qty'], 1, $langs, 0, 0); print ''; print ''; } @@ -435,7 +435,7 @@ function show_stats_for_company($product, $socid) print ''; print $product->stats_facture['nb']; print ''; - print $product->stats_facture['qty']; + print price($product->stats_facture['qty'], 1, $langs, 0, 0); print ''; print ''; } @@ -453,7 +453,7 @@ function show_stats_for_company($product, $socid) print ''; print $product->stats_facture_fournisseur['nb']; print ''; - print $product->stats_facture_fournisseur['qty']; + print price($product->stats_facture_fournisseur['qty'], 1, $langs, 0, 0); print ''; print ''; } @@ -472,7 +472,7 @@ function show_stats_for_company($product, $socid) print ''; print $product->stats_contrat['nb']; print ''; - print $product->stats_contrat['qty']; + print price($product->stats_contrat['qty'], 1, $langs, 0, 0); print ''; print ''; } From 385927fe069eace69544fef6fa0d8cb3b2395123 Mon Sep 17 00:00:00 2001 From: Florian Mortgat <50440633+atm-florianm@users.noreply.github.com> Date: Sun, 29 Sep 2024 22:18:18 +0200 Subject: [PATCH 29/39] FIX: box_actions.php still uses fk_user_done which no longer exists (#31190) Co-authored-by: FlorianMortgat <5845502+FlorianMortgat@users.noreply.github.com> --- htdocs/core/boxes/box_actions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/boxes/box_actions.php b/htdocs/core/boxes/box_actions.php index 64a2314560c37..1d2f03b11b546 100644 --- a/htdocs/core/boxes/box_actions.php +++ b/htdocs/core/boxes/box_actions.php @@ -106,7 +106,7 @@ public function loadBox($max = 5) $sql .= " AND s.rowid = ".((int) $user->socid); } if (!$user->rights->agenda->allactions->read) { - $sql .= " AND (a.fk_user_author = ".((int) $user->id)." OR a.fk_user_action = ".((int) $user->id)." OR a.fk_user_done = ".((int) $user->id).")"; + $sql .= " AND (a.fk_user_author = ".((int) $user->id)." OR a.fk_user_action = ".((int) $user->id).")"; } $sql .= " ORDER BY a.datec DESC"; $sql .= $this->db->plimit($max, 0); From 25ea797aed961cd1bbc2df647a7ab532e18922e6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 30 Sep 2024 18:26:24 +0200 Subject: [PATCH 30/39] Fix not default template for BOM --- htdocs/bom/class/bom.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 68cd44dcf46eb..0ad0cddf96dbf 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -986,7 +986,7 @@ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hided $outputlangs->load("products"); if (!dol_strlen($modele)) { - $modele = 'standard'; + $modele = ''; if ($this->model_pdf) { $modele = $this->model_pdf; From e71631abe0b64037fa3e749186aa326c53319f4e Mon Sep 17 00:00:00 2001 From: thomas-Ngr Date: Thu, 3 Oct 2024 19:33:33 +0200 Subject: [PATCH 31/39] fix : missing update for extrafields on holidays (#31256) --- htdocs/holiday/class/holiday.class.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 6271f1d43e8a5..ab1efaa7f9047 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -987,6 +987,13 @@ public function update($user = null, $notrigger = 0) $error++; $this->errors[] = "Error ".$this->db->lasterror(); } + if (!$error) { + $result = $this->insertExtraFields(); + if ($result < 0) { + $error++; + } + } + if (!$error) { if (!$notrigger) { // Call trigger From 336d3ad8e584bdbbf35f7f60c8f452783de2e692 Mon Sep 17 00:00:00 2001 From: thomas-Ngr Date: Thu, 3 Oct 2024 21:03:13 +0200 Subject: [PATCH 32/39] finish fix (#31203) --- htdocs/product/stock/replenish.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index a1a99523d919c..29b02cb0796ea 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -194,17 +194,20 @@ // TODO Get desc in language of thirdparty } + $line->tva_tx = $productsupplier->vatrate_supplier; + $tva = $line->tva_tx / 100; + // If we use multicurrency if (isModEnabled('multicurrency') && !empty($productsupplier->fourn_multicurrency_code) && $productsupplier->fourn_multicurrency_code != $conf->currency) { - $line->multicurrency_code = $productsupplier->fourn_multicurrency_code; - $line->fk_multicurrency = $productsupplier->fourn_multicurrency_id; - $line->multicurrency_subprice = $productsupplier->fourn_multicurrency_unitprice; + $line->multicurrency_code = $productsupplier->fourn_multicurrency_code; + $line->fk_multicurrency = $productsupplier->fourn_multicurrency_id; + $line->multicurrency_subprice = $productsupplier->fourn_multicurrency_unitprice; + $line->multicurrency_total_ht = $line->multicurrency_subprice * $qty; + $line->multicurrency_total_tva = $line->multicurrency_total_ht * $tva; + $line->multicurrency_total_ttc = $line->multicurrency_total_ht + $line->multicurrency_total_tva; } - - $line->tva_tx = $productsupplier->vatrate_supplier; $line->subprice = $productsupplier->fourn_pu; $line->total_ht = $productsupplier->fourn_pu * $qty; - $tva = $line->tva_tx / 100; $line->total_tva = $line->total_ht * $tva; $line->total_ttc = $line->total_ht + $line->total_tva; $line->remise_percent = $productsupplier->remise_percent; From f287d100a367a84c262a0f35b86c45e4cfa4cc5a Mon Sep 17 00:00:00 2001 From: atm-irvine <165771178+atm-irvine@users.noreply.github.com> Date: Fri, 4 Oct 2024 11:49:44 +0200 Subject: [PATCH 33/39] Use <= 0 instead of ! because delete method returns -1 or 1 (#31268) * Use <= 0 instead of ! because delete method returns -1 or 1 * Added contact * Removed user from parameters --- htdocs/categories/class/api_categories.class.php | 4 ++-- htdocs/societe/class/api_contacts.class.php | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php index e10371f87b666..77356ba2a87fc 100644 --- a/htdocs/categories/class/api_categories.class.php +++ b/htdocs/categories/class/api_categories.class.php @@ -267,8 +267,8 @@ public function delete($id) throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - if (!$this->category->delete(DolibarrApiAccess::$user)) { - throw new RestException(401, 'error when delete category'); + if ($this->category->delete(DolibarrApiAccess::$user) <= 0) { + throw new RestException(500, 'Error when delete category : ' . $this->category->error); } return array( diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index afd6c5807a550..d8839c9a12227 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -348,7 +348,7 @@ public function put($id, $request_data = null) * Delete contact * * @param int $id Contact ID - * @return integer + * @return array[] */ public function delete($id) { @@ -364,7 +364,17 @@ public function delete($id) throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->contact->oldcopy = clone $this->contact; - return $this->contact->delete(); + + if ($this->contact->delete() <= 0) { + throw new RestException(500, 'Error when delete contact ' . $this->contact->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Contact deleted' + ) + ); } /** From 1e64870a9ec465f090f94e907a4dd3c1a1257305 Mon Sep 17 00:00:00 2001 From: atm-lucas <121817516+atm-lucasmantegari@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:53:43 +0200 Subject: [PATCH 34/39] NEW - Add a new hook on order list (#31315) * Add a new hook on order list * pr correction --- htdocs/commande/list.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index bf39beba029f8..2d80c7afec500 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -2566,6 +2566,21 @@ } } } + + // Call Hook modifyTextInfo + $parameters = array('textinfo' => $text_info); + $reshook = $hookmanager->executeHooks('modifyTextInfo', $parameters, $object, $action); + if ($reshook == 1) { + // for add information + $text_info .= $hookmanager->resPrint; + } elseif ($reshook == 0) { + // for replace information + $text_info = $hookmanager->resPrint; + } elseif ($reshook == -1) { + // for errors + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + if ($notshippable == 0) { $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'green paddingleft'); $text_info = $text_icon.' '.$langs->trans('Shippable').'
'.$text_info; From 70a453a5c2a2ae7dfae7e11b6780947f086bf2d2 Mon Sep 17 00:00:00 2001 From: thomas-Ngr Date: Mon, 14 Oct 2024 11:57:55 +0200 Subject: [PATCH 35/39] FIX: substitutions THIRDPARTY_XXX are not available for actioncomm reminders (#31385) --- htdocs/comm/action/class/actioncomm.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index f5e1fe40b1fdc..9b006c83ab66d 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -2341,6 +2341,7 @@ public function sendEmailsReminder() // Load event $res = $this->fetch($actionCommReminder->fk_actioncomm); + if ($res > 0) $res = $this->fetch_thirdparty(); if ($res > 0) { // PREPARE EMAIL $errormesg = ''; From 111e3fcd32b956bc6d86b3e67618d3c2c7ca766c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 17 Oct 2024 00:52:42 +0200 Subject: [PATCH 36/39] Revert "NEW - Add a new hook on order list (#31315)" This reverts commit 1e64870a9ec465f090f94e907a4dd3c1a1257305. --- htdocs/commande/list.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 2d80c7afec500..bf39beba029f8 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -2566,21 +2566,6 @@ } } } - - // Call Hook modifyTextInfo - $parameters = array('textinfo' => $text_info); - $reshook = $hookmanager->executeHooks('modifyTextInfo', $parameters, $object, $action); - if ($reshook == 1) { - // for add information - $text_info .= $hookmanager->resPrint; - } elseif ($reshook == 0) { - // for replace information - $text_info = $hookmanager->resPrint; - } elseif ($reshook == -1) { - // for errors - setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - } - if ($notshippable == 0) { $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'green paddingleft'); $text_info = $text_icon.' '.$langs->trans('Shippable').'
'.$text_info; From 352bdaf9c45e808366978dca42fc936048b5a91d Mon Sep 17 00:00:00 2001 From: atm-irvine <165771178+atm-irvine@users.noreply.github.com> Date: Sat, 19 Oct 2024 01:33:31 +0200 Subject: [PATCH 37/39] FIX : Extrafield following between rec invoice and classic invoice (#31445) --- htdocs/compta/facture/class/facture-rec.class.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 22ea97feb6d57..5b377edaee413 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -1338,6 +1338,14 @@ public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidat $facture->multicurrency_tx = $facturerec->multicurrency_tx; } + if (isset($facture->array_options) && isset($facturerec->array_options)) { + foreach ($facturerec->array_options as $key => $value) { + if (isset($facture->array_options[$key])) { + $facture->array_options[$key] = $value; + } + } + } + $invoiceidgenerated = $facture->create($user); if ($invoiceidgenerated <= 0) { $this->errors = $facture->errors; From abefce7ae2215ed7230a0b48e0ef35b7a724223f Mon Sep 17 00:00:00 2001 From: Florian Mortgat <50440633+atm-florianm@users.noreply.github.com> Date: Sat, 19 Oct 2024 01:55:58 +0200 Subject: [PATCH 38/39] FIX 17.0: supplier invoice template card: buyer and seller swapped in VAT-related function calls (probably a copy-paste from customer invoice templates) (#31446) --- htdocs/core/class/commonobject.class.php | 4 ++-- htdocs/fourn/facture/card-rec.php | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index dfaba07f66311..8a0b73e8b2f9a 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4917,8 +4917,8 @@ public function formAddObjectLine($dateSelector, $seller, $buyer, $defaulttpldir * But for the moment we don't know if it's possible as we keep a method available on overloaded objects. * * @param string $action Action code - * @param string $seller Object of seller third party - * @param string $buyer Object of buyer third party + * @param Societe $seller Object of seller third party + * @param Societe $buyer Object of buyer third party * @param int $selected Object line selected * @param int $dateSelector 1=Show also date range input fields * @param string $defaulttpldir Directory where to find the template diff --git a/htdocs/fourn/facture/card-rec.php b/htdocs/fourn/facture/card-rec.php index 525b5e9123ad9..8ba6c8be50e3f 100644 --- a/htdocs/fourn/facture/card-rec.php +++ b/htdocs/fourn/facture/card-rec.php @@ -535,8 +535,8 @@ $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : ''); // Update if prices fields are defined - $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); - $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); + $tva_tx = get_default_tva($object->thirdparty, $mysoc, $prod->id); + $tva_npr = get_default_npr($object->thirdparty, $mysoc, $prod->id); if (empty($tva_tx)) { $tva_npr = 0; } @@ -544,7 +544,7 @@ // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp']. $pqp = (GETPOST('pbq', 'int') ? GETPOST('pbq', 'int') : 0); - $datapriceofproduct = $prod->getSellPrice($mysoc, $object->thirdparty, $pqp); + $datapriceofproduct = $prod->getSellPrice($object->thirdparty, $mysoc, $pqp); $pu_ht = $datapriceofproduct['pu_ht']; $pu_ttc = $datapriceofproduct['pu_ttc']; @@ -659,8 +659,8 @@ $buyingprice = price2num(GETPOST('buying_price' . $predef) != '' ? GETPOST('buying_price' . $predef) : ''); // If buying_price is '0', we must keep this value // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr); - $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr); + $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr); + $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr); $info_bits = 0; if ($tva_npr) { $info_bits |= 0x01; @@ -1080,7 +1080,7 @@ $disableedit = 1; $disablemove = 1; $disableremove = 1; - $object->printObjectLines('', $mysoc, $object->thirdparty, $lineid, 0); // No date selector for template invoice + $object->printObjectLines('', $object->thirdparty, $mysoc, $lineid, 0); // No date selector for template invoice } print "\n"; @@ -1569,7 +1569,7 @@ $canchangeproduct = 0; $object->statut = $object->suspended; - $object->printObjectLines($action, $mysoc, $object->thirdparty, $lineid, 0); // No date selector for template invoice + $object->printObjectLines($action, $object->thirdparty, $mysoc, $lineid, 0); // No date selector for template invoice } // Form to add new line From 1d197e42bbe2ab6c5fecce36ca6181c4156d3e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 20 Oct 2024 00:11:04 +0200 Subject: [PATCH 39/39] fix shippable tooltip value overwritten (#31468) --- htdocs/commande/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index bf39beba029f8..ef7f802c61bf4 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -2508,7 +2508,7 @@ $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; } else { $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; - $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; + $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel']; } if ($reliquat > $generic_product->stock_reel) {