From ddf98055a33f4852f42e4c24529ccf8053f924a9 Mon Sep 17 00:00:00 2001 From: Dennis Priskorn Date: Sat, 19 Jun 2021 13:45:20 +0200 Subject: [PATCH 01/78] Update README.md List missing features for the REST API --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index b7cbe471426..fdfbbb5a4a2 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,17 @@ These are features that Dolibarr does **not** yet fully support: - Payroll module - No native embedded Webmail, but you can send email to contacts in Dolibarr with e.g. offers, invoices, etc. - Dolibarr can't do coffee (yet) +- The REST API currently cannot: + - Update a supplier order + - Get tickets + - Add new ledger entry + - Output extrafields when getting orders + - Get virtual products (aka lots) + - Add special taxcodes to a line on a supplier invoice + - Get or post shipments + - Do updating or inserting of extrafields on any objects + - Add an image to a product + - Add multiprices to products ## DOCUMENTATION From f56c26a2142444022628c5fa9931b3eeb47e3670 Mon Sep 17 00:00:00 2001 From: Dennis Priskorn Date: Fri, 2 Jul 2021 13:00:29 +0200 Subject: [PATCH 02/78] Update README.md Removed a few and added issue links to the rest --- README.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index fdfbbb5a4a2..0d0e2d89d00 100644 --- a/README.md +++ b/README.md @@ -221,16 +221,13 @@ These are features that Dolibarr does **not** yet fully support: - No native embedded Webmail, but you can send email to contacts in Dolibarr with e.g. offers, invoices, etc. - Dolibarr can't do coffee (yet) - The REST API currently cannot: - - Update a supplier order - - Get tickets - - Add new ledger entry - - Output extrafields when getting orders - - Get virtual products (aka lots) - - Add special taxcodes to a line on a supplier invoice - - Get or post shipments - - Do updating or inserting of extrafields on any objects - - Add an image to a product - - Add multiprices to products + - Add new ledger entry [#14675](https://github.com/Dolibarr/dolibarr/issues/14675) + - Get virtual products (aka lots) [#14457](https://github.com/Dolibarr/dolibarr/issues/14457) + - Add special taxcodes to a line on a supplier invoice (vat_src_code) [#14404](https://github.com/Dolibarr/dolibarr/issues/14404) + - Get or post shipments on customer orders [#18074](https://github.com/Dolibarr/dolibarr/issues/18074) + - Get or post shipments on supplier orders [#14334](https://github.com/Dolibarr/dolibarr/issues/14334) + - Add an image to a product [#14262](https://github.com/Dolibarr/dolibarr/issues/14262) + - Add multiprices to products [#12812](https://github.com/Dolibarr/dolibarr/issues/12812) ## DOCUMENTATION From bd125910ab19be9b133cd015d0059a0e79c7fbb4 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Fri, 12 Nov 2021 11:18:30 +0100 Subject: [PATCH 03/78] NEW stripe element with more gateways --- htdocs/public/payment/newpayment.php | 57 +++++++++------------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index a5e24312ded..62d817ab227 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -3,7 +3,7 @@ * Copyright (C) 2006-2017 Laurent Destailleur * Copyright (C) 2009-2012 Regis Houssin * Copyright (C) 2018 Juanjo Menent - * Copyright (C) 2018-2019 Thibault FOUCART + * Copyright (C) 2018-2021 Thibault FOUCART * Copyright (C) 2021 Waƫl Almoman * Copyright (C) 2021 Dorian Vabre * @@ -2234,7 +2234,7 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme //if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION) || ! empty($paymentintent)) //{ print ' - +
'; } print ''; + print ''; print ''; print ''; $i = 0; @@ -4593,6 +4594,7 @@ abstract class CommonObject if (!empty($line->vat_src_code) && !preg_match('/\(/', $this->tpl['vat_rate'])) $this->tpl['vat_rate'] .= ' ('.$line->vat_src_code.')'; $this->tpl['price'] = price($line->subprice); + $this->tpl['total_ht'] = price($line->total_ht); $this->tpl['multicurrency_price'] = price($line->multicurrency_subprice); $this->tpl['qty'] = (($line->info_bits & 2) != 2) ? $line->qty : ' '; if ($conf->global->PRODUCT_USE_UNITS) $this->tpl['unit'] = $langs->transnoentities($line->getLabelOfUnit('long')); diff --git a/htdocs/core/tpl/originproductline.tpl.php b/htdocs/core/tpl/originproductline.tpl.php index 1b996556253..cc520039af5 100644 --- a/htdocs/core/tpl/originproductline.tpl.php +++ b/htdocs/core/tpl/originproductline.tpl.php @@ -40,6 +40,7 @@ if ($conf->global->PRODUCT_USE_UNITS) print ''; print ''; +print ''; $selected = 1; if (!empty($selectedLines) && !in_array($this->tpl['id'], $selectedLines)) $selected = 0; From 97850a6fbf56ef92402cc5f5ed9ece80081bc623 Mon Sep 17 00:00:00 2001 From: habot-it Date: Sat, 5 Feb 2022 12:22:18 +0000 Subject: [PATCH 22/78] Add options in function pdf_pagefoot of pdf.lib.php --- htdocs/core/lib/pdf.lib.php | 47 +++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 75443366037..c79cbbca645 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1130,6 +1130,11 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $pdf->SetFont('', '', 7); $pdf->SetDrawColor(224, 224, 224); + // Option for footer text color + if (!empty($conf->global->PDF_FOOTER_TEXT_COLOR)) { + list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d'); + $pdf->SetTextColor($r, $g, $b); + } // The start of the bottom of this page footer is positioned according to # of lines $freetextheight = 0; @@ -1149,6 +1154,8 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ } } + $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak + // For customize footer if (is_object($hookmanager)) { $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs'=>$outputlangs); @@ -1161,6 +1168,12 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight; $posy = $marginwithfooter + 0; + // Option for footer background color (without freetext zone) + if (!empty($conf->global->PDF_FOOTER_BACKGROUND_COLOR)) { + list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d'); + $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b)); + } + if ($line) { // Free text $pdf->SetXY($dims['lm'], -$posy); if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { // by default @@ -1172,10 +1185,18 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ } $pdf->SetY(-$posy); - $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); - $posy--; - $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $freetextheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0)); + // Hide footer line if footer background color is set + if (empty($conf->global->PDF_FOOTER_BACKGROUND_COLOR)) { + $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); + } + + // Option for set top margin height of footer after freetext + if (!empty($conf->global->PDF_FOOTER_TOP_MARGIN) || ($conf->global->PDF_FOOTER_TOP_MARGIN === '0')) { + $posy -= $conf->global->PDF_FOOTER_TOP_MARGIN; + } else { $posy--; } + + $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0)); $posy -= $mycustomfooterheight - 3; } else { @@ -1183,6 +1204,12 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0); $posy = $marginwithfooter + 0; + // Option for footer background color (without freetext zone) + if (!empty($conf->global->PDF_FOOTER_BACKGROUND_COLOR)) { + list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d'); + $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b)); + } + if ($line) { // Free text $pdf->SetXY($dims['lm'], -$posy); if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { // by default @@ -1194,8 +1221,16 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ } $pdf->SetY(-$posy); - $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); - $posy--; + + // Hide footer line if footer background color is set + if (empty($conf->global->PDF_FOOTER_BACKGROUND_COLOR)) { + $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); + } + + // Option for set top margin height of footer after freetext + if (!empty($conf->global->PDF_FOOTER_TOP_MARGIN) || ($conf->global->PDF_FOOTER_TOP_MARGIN === '0')) { + $posy -= $conf->global->PDF_FOOTER_TOP_MARGIN; + } else { $posy--; } if (!empty($line1)) { $pdf->SetFont('', 'B', 7); @@ -1232,6 +1267,8 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $pdf->MultiCell(15, 2, $pdf->PageNo().'/'.$pdf->getAliasNbPages(), 0, 'R', 0); } + $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak + return $marginwithfooter; } From 96c432566d034024c4d431b505f5d15ee7ef4044 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Fri, 1 Apr 2022 19:20:47 +0200 Subject: [PATCH 23/78] NEW 16.0 - proposal for a prefix-based consistency mechanism for trigger names --- htdocs/core/class/commonobject.class.php | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index f9bbb9ed879..ef9856a2035 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -42,6 +42,7 @@ */ abstract class CommonObject { + const TRIGGER_PREFIX = ''; // to be overriden in child class implementations, i.e. 'BILL', 'TASK', 'PROPAL', etc. /** * @var DoliDb Database handler (result of a new DoliDB) */ @@ -1987,6 +1988,10 @@ abstract class CommonObject $result = $this->fetchCommon($id); } if ($result >= 0) { + + if (!empty(self::TRIGGER_PREFIX) && strpos($trigkey, self::TRIGGER_PREFIX) !== 0) { + $trigkey = self::TRIGGER_PREFIX . '_' . $trigkey; + } $result = $this->call_trigger($trigkey, (!empty($fuser) && is_object($fuser)) ? $fuser : $user); // This may set this->errors } if ($result < 0) { @@ -4269,6 +4274,9 @@ abstract class CommonObject if ($trigkey) { // Call trigger + if (!empty(self::TRIGGER_PREFIX) && strpos($trigkey, self::TRIGGER_PREFIX) !== 0) { + $trigkey = self::TRIGGER_PREFIX . '_' . $trigkey; + } $result = $this->call_trigger($trigkey, $user); if ($result < 0) { $error++; @@ -5603,6 +5611,9 @@ abstract class CommonObject // phpcs:enable global $langs, $conf; + if (!empty(self::TRIGGER_PREFIX) && strpos($triggerName, self::TRIGGER_PREFIX) !== 0) { + $triggerName = self::TRIGGER_PREFIX . '_' . $triggerName; + } if (!is_object($langs)) { // If lang was not defined, we set it. It is required by run_triggers. include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php'; $langs = new Translate('', $conf); @@ -6190,6 +6201,9 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger $this->context = array('extrafieldaddupdate'=>1); + if (!empty(self::TRIGGER_PREFIX) && strpos($trigger, self::TRIGGER_PREFIX) !== 0) { + $trigger = self::TRIGGER_PREFIX . '_' . $trigger; + } $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -6308,6 +6322,9 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger $this->context = array('extralanguagesaddupdate'=>1); + if (!empty(self::TRIGGER_PREFIX) && strpos($trigger, self::TRIGGER_PREFIX) !== 0) { + $trigger = self::TRIGGER_PREFIX . '_' . $trigger; + } $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -6506,6 +6523,10 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger $this->context = array('extrafieldupdate'=>1); + + if (!empty(self::TRIGGER_PREFIX) && strpos($trigger, self::TRIGGER_PREFIX) !== 0) { + $trigger = self::TRIGGER_PREFIX . '_' . $trigger; + } $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -9426,6 +9447,10 @@ abstract class CommonObject if (!$error && !$notrigger) { // Call trigger + + if (!empty(self::TRIGGER_PREFIX) && strpos($triggercode, self::TRIGGER_PREFIX) !== 0) { + $triggercode = self::TRIGGER_PREFIX . '_' . $triggercode; + } $result = $this->call_trigger($triggercode, $user); if ($result < 0) { $error++; From 563716b633badb6b8db073f2abacd55063bea098 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Mon, 4 Apr 2022 10:00:10 +0200 Subject: [PATCH 24/78] 16.0 - Proposal for trigger prefix consistency: instead of adding missing prefix, check that trigger starts with declared prefix --- htdocs/core/class/commonobject.class.php | 26 ++---------------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ef9856a2035..c4d0635dde7 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1988,10 +1988,6 @@ abstract class CommonObject $result = $this->fetchCommon($id); } if ($result >= 0) { - - if (!empty(self::TRIGGER_PREFIX) && strpos($trigkey, self::TRIGGER_PREFIX) !== 0) { - $trigkey = self::TRIGGER_PREFIX . '_' . $trigkey; - } $result = $this->call_trigger($trigkey, (!empty($fuser) && is_object($fuser)) ? $fuser : $user); // This may set this->errors } if ($result < 0) { @@ -4274,9 +4270,6 @@ abstract class CommonObject if ($trigkey) { // Call trigger - if (!empty(self::TRIGGER_PREFIX) && strpos($trigkey, self::TRIGGER_PREFIX) !== 0) { - $trigkey = self::TRIGGER_PREFIX . '_' . $trigkey; - } $result = $this->call_trigger($trigkey, $user); if ($result < 0) { $error++; @@ -5610,9 +5603,8 @@ abstract class CommonObject { // phpcs:enable global $langs, $conf; - - if (!empty(self::TRIGGER_PREFIX) && strpos($triggerName, self::TRIGGER_PREFIX) !== 0) { - $triggerName = self::TRIGGER_PREFIX . '_' . $triggerName; + if (!empty(self::TRIGGER_PREFIX) && strpos($triggerName, self::TRIGGER_PREFIX . '_') !== 0) { + throw new Exception('The trigger "' . $triggerName . '" does not start with "' . self::TRIGGER_PREFIX . '_" as required.'); } if (!is_object($langs)) { // If lang was not defined, we set it. It is required by run_triggers. include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php'; @@ -6201,9 +6193,6 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger $this->context = array('extrafieldaddupdate'=>1); - if (!empty(self::TRIGGER_PREFIX) && strpos($trigger, self::TRIGGER_PREFIX) !== 0) { - $trigger = self::TRIGGER_PREFIX . '_' . $trigger; - } $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -6322,9 +6311,6 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger $this->context = array('extralanguagesaddupdate'=>1); - if (!empty(self::TRIGGER_PREFIX) && strpos($trigger, self::TRIGGER_PREFIX) !== 0) { - $trigger = self::TRIGGER_PREFIX . '_' . $trigger; - } $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -6523,10 +6509,6 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger $this->context = array('extrafieldupdate'=>1); - - if (!empty(self::TRIGGER_PREFIX) && strpos($trigger, self::TRIGGER_PREFIX) !== 0) { - $trigger = self::TRIGGER_PREFIX . '_' . $trigger; - } $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -9447,10 +9429,6 @@ abstract class CommonObject if (!$error && !$notrigger) { // Call trigger - - if (!empty(self::TRIGGER_PREFIX) && strpos($triggercode, self::TRIGGER_PREFIX) !== 0) { - $triggercode = self::TRIGGER_PREFIX . '_' . $triggercode; - } $result = $this->call_trigger($triggercode, $user); if ($result < 0) { $error++; From 2455d8fe5202fd040f9a522d6056dc3fab95a0f7 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Mon, 4 Apr 2022 14:31:48 +0200 Subject: [PATCH 25/78] avoid fetch_objectlinked for each page of the document --- htdocs/core/class/commonobject.class.php | 8 ++++++++ htdocs/core/lib/pdf.lib.php | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 232aa6b5789..f7eb6a67263 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -123,6 +123,11 @@ abstract class CommonObject */ public $linkedObjects; + /** + * @var boolean is linkedObjects full loaded. Loaded by ->fetchObjectLinked + */ + public $linkedObjectsFullLoaded = false; + /** * @var Object To store a cloned copy of object before to edit it and keep track of old properties */ @@ -3834,6 +3839,9 @@ abstract class CommonObject } else { $sql .= "(fk_source = ".((int) $sourceid)." AND sourcetype = '".$this->db->escape($sourcetype)."')"; $sql .= " ".$clause." (fk_target = ".((int) $targetid)." AND targettype = '".$this->db->escape($targettype)."')"; + if ($sourceid == $this->id && $sourcetype == $this->element && $targetid == $this->id && $targettype == $this->element && $clause == 'OR') { + $this->linkedObjectsFullLoaded = true; + } } $sql .= " ORDER BY ".$orderby; diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index ea8c6c2ce23..b273f93b69f 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -2282,7 +2282,9 @@ function pdf_getLinkedObjects(&$object, $outputlangs) $linkedobjects = array(); - $object->fetchObjectLinked(); + if (empty($object->linkedObjectsFullLoaded)) { + $object->fetchObjectLinked(); + } foreach ($object->linkedObjects as $objecttype => $objects) { if ($objecttype == 'facture') { From 04140d8dc05b4186d302f16a86e91a2ba045bcf9 Mon Sep 17 00:00:00 2001 From: jpb Date: Mon, 4 Apr 2022 15:45:16 +0200 Subject: [PATCH 26/78] add class name on tds expensereport rule card --- htdocs/admin/expensereport_rules.php | 68 ++++++++++++++-------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php index 6799ab339bd..f15b996939d 100644 --- a/htdocs/admin/expensereport_rules.php +++ b/htdocs/admin/expensereport_rules.php @@ -185,31 +185,31 @@ if ($action != 'edit') { echo '
'; if (!empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) { @@ -2242,18 +2242,14 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme } print '
'; - print ''; + //print ''; if (!empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) { - print '
'; + //print '
'; } - print '
+ print '
-
'; - - print ' -
'; print '
'; @@ -2400,9 +2396,12 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme // Create a Stripe client. var stripe = Stripe(''); - + var cardButton = document.getElementById('buttontopay'); + var clientSecret = cardButton.dataset.secret; + var options = { clientSecret: clientSecret,}; + // Create an instance of Elements - var elements = stripe.elements(); + var elements = stripe.elements(options); // Custom styling can be passed to options when creating an Element. // (Note that this demo uses a wider set of styles than the guide below.) @@ -2423,49 +2422,28 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme } }; - var cardElement = elements.create('card', {style: style}); + var paymentElement = elements.create("payment"); // Add an instance of the card Element into the `card-element`
- cardElement.mount('#card-element'); - - // Handle real-time validation errors from the card Element. - cardElement.addEventListener('change', function(event) { - var displayError = document.getElementById('card-errors'); - if (event.error) { - console.log("Show event error (like 'Incorrect card number', ...)"); - displayError.textContent = event.error.message; - } else { - console.log("Reset error message"); - displayError.textContent = ''; - } - }); + paymentElement.mount("#payment-element"); // Handle form submission - var cardholderName = document.getElementById('cardholder-name'); var cardButton = document.getElementById('buttontopay'); - var clientSecret = cardButton.dataset.secret; cardButton.addEventListener('click', function(event) { console.log("We click on buttontopay"); event.preventDefault(); - if (cardholderName.value == '') - { - console.log("Field Card holder is empty"); - var displayError = document.getElementById('card-errors'); - displayError.textContent = 'trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CardOwner"))); ?>'; - } - else - { /* Disable button to pay and show hourglass cursor */ jQuery('#hourglasstopay').show(); jQuery('#buttontopay').hide(); - stripe.handleCardPayment( - clientSecret, cardElement, { + stripe.confirmPayment({ + elements,confirmParams: { + return_url: '', payment_method_data: { billing_details: { - name: cardholderName.value + name: 'test' thirdparty) && !empty($object->thirdparty->email))) { ?>, email: 'thirdparty->email); ?>' @@ -2489,6 +2467,7 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme } else { print 'false'; } ?> /* true when a customer was provided when creating payment intent. true ask to save the card */ + }, } ).then(function(result) { console.log(result); @@ -2509,7 +2488,7 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme jQuery('#payment-form').submit(); } }); - } + }); Date: Fri, 12 Nov 2021 10:22:46 +0000 Subject: [PATCH 04/78] Fixing style errors. --- htdocs/public/payment/newpayment.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 62d817ab227..5cd9a4eefa2 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -2396,10 +2396,10 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme // Create a Stripe client. var stripe = Stripe(''); - var cardButton = document.getElementById('buttontopay'); + var cardButton = document.getElementById('buttontopay'); var clientSecret = cardButton.dataset.secret; - var options = { clientSecret: clientSecret,}; - + var options = { clientSecret: clientSecret,}; + // Create an instance of Elements var elements = stripe.elements(options); @@ -2439,8 +2439,8 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme jQuery('#buttontopay').hide(); stripe.confirmPayment({ - elements,confirmParams: { - return_url: '', + elements,confirmParams: { + return_url: '', payment_method_data: { billing_details: { name: 'test' @@ -2467,7 +2467,7 @@ if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payme } else { print 'false'; } ?> /* true when a customer was provided when creating payment intent. true ask to save the card */ - }, + }, } ).then(function(result) { console.log(result); From d601f621943173642b393ba6e32979792a553bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 21:38:29 +0100 Subject: [PATCH 05/78] can merge products but experimental --- htdocs/categories/class/categorie.class.php | 17 ++ htdocs/comm/propal/class/propal.class.php | 18 +- htdocs/commande/class/commande.class.php | 17 ++ .../facture/class/facture-rec.class.php | 17 ++ htdocs/compta/facture/class/facture.class.php | 17 ++ htdocs/contrat/class/contrat.class.php | 17 ++ htdocs/core/class/commonobject.class.php | 33 +++- htdocs/delivery/class/delivery.class.php | 17 ++ htdocs/expedition/class/expedition.class.php | 17 ++ htdocs/fichinter/class/fichinter.class.php | 17 ++ htdocs/fichinter/class/fichinterrec.class.php | 18 +- .../class/fournisseur.commande.class.php | 17 ++ htdocs/langs/en_US/products.lang | 4 + htdocs/product/card.php | 185 ++++++++++++++++++ htdocs/product/class/product.class.php | 3 +- 15 files changed, 408 insertions(+), 6 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 9a449d63700..0aee9cbfc81 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1947,6 +1947,23 @@ class Categorie extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables, 1); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'categorie_product' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Return the addtional SQL JOIN query for filtering a list by a category * diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 2f055f54a42..6b9b259fd52 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3740,8 +3740,24 @@ class Propal extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } -} + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'propaldet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } +} /** * Class to manage commercial proposal lines diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 9b315698527..0fe8d52cd1d 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3999,6 +3999,23 @@ class Commande extends CommonOrder return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'commandedet', + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Is the customer order delayed? * diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 100334e046a..c868e1e9992 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -1725,6 +1725,23 @@ class FactureRec extends CommonInvoice return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'facturedet_rec' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Update frequency and unit * diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 649b7b0c093..ffa520b1284 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4738,6 +4738,23 @@ class Facture extends CommonInvoice return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'facturedet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Is the customer invoice delayed? * diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index fe8edd30ea4..cb97e6bc895 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2459,6 +2459,23 @@ class Contrat extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'contratdet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Load an object from its id and create a new one in database * diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 5dd392ad065..601457aba71 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7990,7 +7990,7 @@ abstract class CommonObject /** * Function used to replace a thirdparty id with another one. - * This function is meant to be called from replaceThirdparty with the appropiate tables + * This function is meant to be called from replaceThirdparty with the appropriate tables * Column name fk_soc MUST be used to identify thirdparties * * @param DoliDB $db Database handler @@ -8007,7 +8007,36 @@ abstract class CommonObject if (!$db->query($sql)) { if ($ignoreerrors) { - return true; // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B. + return true; // TODO Not enough. If there is A-B on kept thirdparty and B-C on old one, we must get A-B-C after merge. Not A-B. + } + //$this->errors = $db->lasterror(); + return false; + } + } + + return true; + } + + /** + * Function used to replace a product id with another one. + * This function is meant to be called from replaceProduct with the appropriate tables + * Column name fk_product MUST be used to identify products + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id (the product to delete) + * @param int $dest_id New product id (the product that will received element of the other) + * @param string[] $tables Tables that need to be changed + * @param int $ignoreerrors Ignore errors. Return true even if errors. We need this when replacement can fails like for categories (categorie of old product may already exists on new one) + * @return bool True if success, False if error + */ + public static function commonReplaceProduct(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors = 0) + { + foreach ($tables as $table) { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$table.' SET fk_product = '.((int) $dest_id).' WHERE fk_product = '.((int) $origin_id); + + if (!$db->query($sql)) { + if ($ignoreerrors) { + return true; // TODO Not enough. If there is A-B on kept thirdparty and B-C on old one, we must get A-B-C after merge. Not A-B. } //$this->errors = $db->lasterror(); return false; diff --git a/htdocs/delivery/class/delivery.class.php b/htdocs/delivery/class/delivery.class.php index 6bfe3a33dd7..47300702baf 100644 --- a/htdocs/delivery/class/delivery.class.php +++ b/htdocs/delivery/class/delivery.class.php @@ -1082,6 +1082,23 @@ class Delivery extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'deliverydet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 8ef7be75f52..8218e1c6402 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2503,6 +2503,23 @@ class Expedition extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'expeditiondet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } } diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 297e03fa379..af5801a48fb 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -1374,6 +1374,23 @@ class Fichinter extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'fichinterdet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } } /** diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index d5690265028..9557707ad84 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -40,7 +40,7 @@ class FichinterRec extends Fichinter { public $element = 'fichinterrec'; public $table_element = 'fichinter_rec'; - public $table_element_line = 'fichinter_rec'; + public $table_element_line = 'fichinterdet_rec'; /** * @var string Fieldname with ID of parent key if this field has a parent @@ -693,6 +693,22 @@ class FichinterRec extends Fichinter return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'fichinterdet_rec' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } /** * Update frequency and unit diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 9b68ef199db..c5788197c68 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3191,6 +3191,23 @@ class CommandeFournisseur extends CommonOrder return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'commande_fournisseurdet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Is the supplier order delayed? * We suppose a purchase ordered as late if a the purchase order has been sent and the delivery date is set and before the delay. diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 205a28980a8..f4e196d0b7e 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -408,3 +408,7 @@ mandatoryHelper=Message to the user on the need to enter a start date and an end DefaultBOM=Default BOM DefaultBOMDesc=The default BOM recommended to use to manufacture this product. This field can be set only if nature of product is '%s'. Rank=Rank +MergeOriginProduct=Duplicate product (product you want to delete) +MergeProducts=Merge products +ConfirmMergeProducts=Are you sure you want to merge the chosen product with the current one? All linked objects (invoices, orders, ...) will be moved to the current product, after which the chosen product will be deleted. +ProductsMergeSuccess=Products have been merged diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 420203eedae..06a5a4102ff 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -226,6 +226,177 @@ if (empty($reshook)) { } $action = ''; } + // merge products + if ($action == 'confirm_merge' && $confirm == 'yes' && $user->rights->societe->creer) { + $error = 0; + $productOriginId = GETPOST('product_origin', 'int'); + $productOrigin = new Product($db); + + if ($productOriginId <= 0) { + $langs->load('errors'); + setEventMessages($langs->trans('ErrorProductIdIsMandatory', $langs->transnoentitiesnoconv('MergeOriginProduct')), null, 'errors'); + } else { + if (!$error && $productOrigin->fetch($productOriginId) < 1) { + setEventMessages($langs->trans('ErrorRecordNotFound'), null, 'errors'); + $error++; + } + + if (!$error) { + // TODO Move the merge function into class of object. + $db->begin(); + + // Recopy some data + //$object->client = $object->client | $productOrigin->client; + //$object->fournisseur = $object->fournisseur | $productOrigin->fournisseur; + $listofproperties = array( + 'ref', + 'ref_ext', + 'label', + 'description', + 'url', + 'barcode', + 'fk_barcode_type', + 'import_key', + 'mandatory_period', + 'accountancy_code_buy', + 'accountancy_code_buy_intra', + 'accountancy_code_buy_export', + 'accountancy_code_sell', + 'accountancy_code_sell_intra', + 'accountancy_code_sell_export' + ); + foreach ($listofproperties as $property) { + if (empty($object->$property)) { + $object->$property = $productOrigin->$property; + } + } + // Concat some data + $listofproperties = array( + 'note_public', 'note_private' + ); + foreach ($listofproperties as $property) { + $object->$property = dol_concatdesc($object->$property, $productOrigin->$property); + } + + // Merge extrafields + if (is_array($productOrigin->array_options)) { + foreach ($productOrigin->array_options as $key => $val) { + if (empty($object->array_options[$key])) { + $object->array_options[$key] = $val; + } + } + } + + // Merge categories + $static_cat = new Categorie($db); + $custcats_ori = $static_cat->containing($productOrigin->id, 'product', 'id'); + $custcats = $static_cat->containing($object->id, 'product', 'id'); + $custcats = array_merge($custcats, $custcats_ori); + $object->setCategories($custcats); + + // If product has a new code that is same than origin, we clean origin code to avoid duplicate key from database unique keys. + if ($productOrigin->barcode == $object->barcode) { + dol_syslog("We clean customer and supplier code so we will be able to make the update of target"); + $productOrigin->barcode = ''; + //$productOrigin->update($productOrigin->id, $user, 0, 'merge'); + } + + // Update + $result = $object->update($object->id, $user, 0, 'merge'); + if ($result <= 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + + // Move links + if (!$error) { + // This list is also into the api_products.class.php + // TODO Mutualise the list into object product.class.php + $objects = array( + 'Categorie' => '/categories/class/categorie.class.php', + 'Propal' => '/comm/propal/class/propal.class.php', + 'Commande' => '/commande/class/commande.class.php', + 'Facture' => '/compta/facture/class/facture.class.php', + 'FactureRec' => '/compta/facture/class/facture-rec.class.php', + // 'Mo' => '/mrp/class/mo.class.php', + 'Contrat' => '/contrat/class/contrat.class.php', + 'Expedition' => '/expedition/class/expedition.class.php', + 'Fichinter' => '/fichinter/class/fichinter.class.php', + 'FichinterRec' => '/fichinter/class/fichinter.class.php', + 'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php', + // 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php', + // 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', + // 'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php', + 'Delivery' => '/delivery/class/delivery.class.php', + // 'Project' => '/projet/class/project.class.php', + // 'Ticket' => '/ticket/class/ticket.class.php', + // 'ConferenceOrBoothAttendee' => '/eventorganization/class/conferenceorboothattendee.class.php' + ); + + //First, all core objects must update their tables + foreach ($objects as $object_name => $object_file) { + require_once DOL_DOCUMENT_ROOT.$object_file; + + if (!$error && !$object_name::replaceProduct($db, $productOrigin->id, $object->id)) { + $error++; + setEventMessages($db->lasterror(), null, 'errors'); + break; + } + } + } + + // External modules should update their ones too + if (!$error) { + $reshook = $hookmanager->executeHooks( + 'replaceProduct', + array( + 'soc_origin' => $productOrigin->id, + 'soc_dest' => $object->id, + ), + $object, + $action + ); + + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + $error++; + } + } + + + if (!$error) { + $object->context = array( + 'merge' => 1, + 'mergefromid' => $productOrigin->id, + ); + + // Call trigger + $result = $object->call_trigger('PRODUCT_MODIFY', $user); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + // End call triggers + } + + if (!$error) { + // We finally remove the old product + if ($productOrigin->delete($user) < 1) { + $error++; + } + } + + if (!$error) { + setEventMessages($langs->trans('ProductsMergeSuccess'), null, 'mesgs'); + $db->commit(); + } else { + $langs->load("errors"); + setEventMessages($langs->trans('ErrorsProductsMerge'), null, 'errors'); + $db->rollback(); + } + } + } + } // Type if ($action == 'setfk_product_type' && $usercancreate) { @@ -2502,6 +2673,17 @@ if (($action == 'delete' && (empty($conf->use_javascript_ajax) || !empty($conf-> || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) { // Always output when not jmobile nor js $formconfirm = $form->formconfirm("card.php?id=".$object->id, $langs->trans("DeleteProduct"), $langs->trans("ConfirmDeleteProduct"), "confirm_delete", '', 0, "action-delete"); } +if ($action == 'merge') { + $formquestion = array( + array( + 'name' => 'product_origin', + 'label' => $langs->trans('MergeOriginProduct'), + 'type' => 'other', + 'value' => $form->select_produits('', 'product_origin', '', 0, 0, 1, 2, '', 1, array(), 0, 1, 0, '', 0, '', null, 1), + ) + ); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("MergeProducts"), $langs->trans("ConfirmMergeProducts"), "confirm_merge", $formquestion, 'no', 1, 250); +} // Clone confirmation if (($action == 'clone' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) // Output when action = clone if jmobile or no js @@ -2569,6 +2751,9 @@ if ($action != 'create' && $action != 'edit') { } else { print ''.$langs->trans("Delete").''; } + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') > 1) { + print ''.$langs->trans('Merge').''."\n"; + } } else { print ''.$langs->trans("Delete").''; } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index a7865474014..1018f43832a 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -491,8 +491,7 @@ class Product extends CommonObject 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000), //'tosell' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'default'=>0, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')), //'tobuy' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'default'=>0, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')), - 'mandatory_period' =>array('type'=>'integer', 'label'=>'mandatory_period', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'default'=>0, 'index'=>1, 'position'=>1000), - + 'mandatory_period' => array('type'=>'integer', 'label'=>'mandatory_period', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'default'=>0, 'index'=>1, 'position'=>1000), ); /** From c56f1805153888a7a43d13ed230c9634a43c362a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 21:52:40 +0100 Subject: [PATCH 06/78] can merge products but experimental --- htdocs/bom/class/bom.class.php | 17 +++++++++++++++++ htdocs/product/card.php | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index fd8d4a19a75..ae352623d42 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1078,6 +1078,23 @@ class BOM extends CommonObject } } } + + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'bom_bomline' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } } diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 06a5a4102ff..41ecd4ff56c 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -318,7 +318,7 @@ if (empty($reshook)) { 'Commande' => '/commande/class/commande.class.php', 'Facture' => '/compta/facture/class/facture.class.php', 'FactureRec' => '/compta/facture/class/facture-rec.class.php', - // 'Mo' => '/mrp/class/mo.class.php', + 'Bom' => '/bom/class/bom.class.php', 'Contrat' => '/contrat/class/contrat.class.php', 'Expedition' => '/expedition/class/expedition.class.php', 'Fichinter' => '/fichinter/class/fichinter.class.php', @@ -2679,7 +2679,7 @@ if ($action == 'merge') { 'name' => 'product_origin', 'label' => $langs->trans('MergeOriginProduct'), 'type' => 'other', - 'value' => $form->select_produits('', 'product_origin', '', 0, 0, 1, 2, '', 1, array(), 0, 1, 0, '', 0, '', null, 1), + 'value' => $form->select_produits('', 'product_origin', '', 0, 0, 1, 2, '', 1, array(), 0, 1, 0, 'minwidth200', 0, '', null, 1), ) ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("MergeProducts"), $langs->trans("ConfirmMergeProducts"), "confirm_merge", $formquestion, 'no', 1, 250); From d9bcd277642e9c227d8c1d02a0f10aaa007ac1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 21:55:48 +0100 Subject: [PATCH 07/78] can merge products but experimental --- htdocs/core/class/commonobject.class.php | 2 +- htdocs/langs/en_US/products.lang | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 601457aba71..23d6e203bb5 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8036,7 +8036,7 @@ abstract class CommonObject if (!$db->query($sql)) { if ($ignoreerrors) { - return true; // TODO Not enough. If there is A-B on kept thirdparty and B-C on old one, we must get A-B-C after merge. Not A-B. + return true; // TODO Not enough. If there is A-B on kept product and B-C on old one, we must get A-B-C after merge. Not A-B. } //$this->errors = $db->lasterror(); return false; diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index f4e196d0b7e..097ea001c48 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -412,3 +412,4 @@ MergeOriginProduct=Duplicate product (product you want to delete) MergeProducts=Merge products ConfirmMergeProducts=Are you sure you want to merge the chosen product with the current one? All linked objects (invoices, orders, ...) will be moved to the current product, after which the chosen product will be deleted. ProductsMergeSuccess=Products have been merged +ErrorsProductsMerge=Errors in products merge From 429e5cf5171c51a29f58f12beb42226896995f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 22:02:55 +0100 Subject: [PATCH 08/78] can merge products but experimental --- .../fourn/class/fournisseur.facture.class.php | 17 +++++++++++++++++ htdocs/product/card.php | 5 +++-- htdocs/reception/class/reception.class.php | 17 +++++++++++++++++ .../class/supplier_proposal.class.php | 18 ++++++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index a1db1826684..dc5560093c0 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2929,6 +2929,23 @@ class FactureFournisseur extends CommonInvoice return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'facture_fourn_det' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Is the payment of the supplier invoice having a delay? * diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 41ecd4ff56c..c17f3290df9 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -321,11 +321,12 @@ if (empty($reshook)) { 'Bom' => '/bom/class/bom.class.php', 'Contrat' => '/contrat/class/contrat.class.php', 'Expedition' => '/expedition/class/expedition.class.php', + 'Reception' => '/reception/class/reception.class.php', 'Fichinter' => '/fichinter/class/fichinter.class.php', 'FichinterRec' => '/fichinter/class/fichinter.class.php', 'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php', - // 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php', - // 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', + 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php', + 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', // 'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php', 'Delivery' => '/delivery/class/delivery.class.php', // 'Project' => '/projet/class/project.class.php', diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 954e7f192cd..fadf013670e 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1949,4 +1949,21 @@ class Reception extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'commande_fournisseur_dispatch' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } } diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 9c84e2c2e89..f5b1b44bd85 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2681,6 +2681,24 @@ class SupplierProposal extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'supplier_proposaldet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + } From 799862362d07a6f5617b4b0c7846cbceebab2a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 22:03:46 +0100 Subject: [PATCH 09/78] can merge products but experimental --- htdocs/supplier_proposal/class/supplier_proposal.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index f5b1b44bd85..9c4818edfec 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2698,7 +2698,6 @@ class SupplierProposal extends CommonObject return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); } - } From 99cddfa235feb2d6e07410d5a8188103ad070998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 22:36:14 +0100 Subject: [PATCH 10/78] can merge products but experimental --- htdocs/compta/bank/class/account.class.php | 2 +- .../fourn/class/fournisseur.product.class.php | 17 +++++++++++++++++ htdocs/product/card.php | 10 +++------- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 685c78f5f1b..d8115e48cac 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1708,7 +1708,7 @@ class Account extends CommonObject if ($dbs->query($sql)) { return true; } else { - //if ($ignoreerrors) return true; // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B. + //if ($ignoreerrors) return true; // TODO Not enough. If there is A-B on kept thirdparty and B-C on old one, we must get A-B-C after merge. Not A-B. //$this->errors = $dbs->lasterror(); return false; } diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 5b523d8d7e8..f1487c7d8be 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -978,6 +978,23 @@ class ProductFournisseur extends Product return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'product_fournisseur_price' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * List supplier prices log of a supplier price * diff --git a/htdocs/product/card.php b/htdocs/product/card.php index c17f3290df9..25503bdbf60 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -246,8 +246,6 @@ if (empty($reshook)) { $db->begin(); // Recopy some data - //$object->client = $object->client | $productOrigin->client; - //$object->fournisseur = $object->fournisseur | $productOrigin->fournisseur; $listofproperties = array( 'ref', 'ref_ext', @@ -310,7 +308,7 @@ if (empty($reshook)) { // Move links if (!$error) { - // This list is also into the api_products.class.php + // TODO add this functionality into the api_products.class.php // TODO Mutualise the list into object product.class.php $objects = array( 'Categorie' => '/categories/class/categorie.class.php', @@ -327,11 +325,8 @@ if (empty($reshook)) { 'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php', 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php', 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', - // 'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php', + 'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php', 'Delivery' => '/delivery/class/delivery.class.php', - // 'Project' => '/projet/class/project.class.php', - // 'Ticket' => '/ticket/class/ticket.class.php', - // 'ConferenceOrBoothAttendee' => '/eventorganization/class/conferenceorboothattendee.class.php' ); //First, all core objects must update their tables @@ -382,6 +377,7 @@ if (empty($reshook)) { if (!$error) { // We finally remove the old product + // TODO merge attached files from old product into new one before delete if ($productOrigin->delete($user) < 1) { $error++; } From 6cbc3c60334587b676dac8a62148cea31c110e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 22:55:35 +0100 Subject: [PATCH 11/78] clean code --- htdocs/categories/class/categorie.class.php | 17 ----------------- htdocs/expedition/class/expedition.class.php | 17 ----------------- htdocs/product/card.php | 4 ++-- 3 files changed, 2 insertions(+), 36 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 0aee9cbfc81..9a449d63700 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1947,23 +1947,6 @@ class Categorie extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables, 1); } - /** - * Function used to replace a product id with another one. - * - * @param DoliDB $db Database handler - * @param int $origin_id Old product id - * @param int $dest_id New product id - * @return bool - */ - public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) - { - $tables = array( - 'categorie_product' - ); - - return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); - } - /** * Return the addtional SQL JOIN query for filtering a list by a category * diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 8218e1c6402..8ef7be75f52 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2503,23 +2503,6 @@ class Expedition extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } - - /** - * Function used to replace a product id with another one. - * - * @param DoliDB $db Database handler - * @param int $origin_id Old product id - * @param int $dest_id New product id - * @return bool - */ - public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) - { - $tables = array( - 'expeditiondet' - ); - - return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); - } } diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 25503bdbf60..874930d2ca9 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -311,14 +311,14 @@ if (empty($reshook)) { // TODO add this functionality into the api_products.class.php // TODO Mutualise the list into object product.class.php $objects = array( - 'Categorie' => '/categories/class/categorie.class.php', + // do not use Categorie, it cause foreign key error, merge is done before + //'Categorie' => '/categories/class/categorie.class.php', 'Propal' => '/comm/propal/class/propal.class.php', 'Commande' => '/commande/class/commande.class.php', 'Facture' => '/compta/facture/class/facture.class.php', 'FactureRec' => '/compta/facture/class/facture-rec.class.php', 'Bom' => '/bom/class/bom.class.php', 'Contrat' => '/contrat/class/contrat.class.php', - 'Expedition' => '/expedition/class/expedition.class.php', 'Reception' => '/reception/class/reception.class.php', 'Fichinter' => '/fichinter/class/fichinter.class.php', 'FichinterRec' => '/fichinter/class/fichinter.class.php', From 21a3a6cc7a145398308a10bd8de4d8e434f4b478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 23:55:01 +0100 Subject: [PATCH 12/78] clean code --- htdocs/core/class/commonobject.class.php | 2 ++ htdocs/fichinter/class/fichinter.class.php | 17 ----------------- htdocs/product/card.php | 3 +-- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 23d6e203bb5..ab988d11db2 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8038,6 +8038,8 @@ abstract class CommonObject if ($ignoreerrors) { return true; // TODO Not enough. If there is A-B on kept product and B-C on old one, we must get A-B-C after merge. Not A-B. } + print $sql; + //$this->errors = $db->lasterror(); return false; } diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index af5801a48fb..297e03fa379 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -1374,23 +1374,6 @@ class Fichinter extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } - - /** - * Function used to replace a product id with another one. - * - * @param DoliDB $db Database handler - * @param int $origin_id Old product id - * @param int $dest_id New product id - * @return bool - */ - public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) - { - $tables = array( - 'fichinterdet' - ); - - return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); - } } /** diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 874930d2ca9..ff73dff45c9 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -320,8 +320,7 @@ if (empty($reshook)) { 'Bom' => '/bom/class/bom.class.php', 'Contrat' => '/contrat/class/contrat.class.php', 'Reception' => '/reception/class/reception.class.php', - 'Fichinter' => '/fichinter/class/fichinter.class.php', - 'FichinterRec' => '/fichinter/class/fichinter.class.php', + 'FichinterRec' => '/fichinter/class/fichinterrec.class.php', 'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php', 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php', 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', From 3301790647112734ade5fdf8e38bddd3b32e8230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 23 Nov 2021 23:56:52 +0100 Subject: [PATCH 13/78] clean code --- htdocs/core/class/commonobject.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ab988d11db2..23d6e203bb5 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -8038,8 +8038,6 @@ abstract class CommonObject if ($ignoreerrors) { return true; // TODO Not enough. If there is A-B on kept product and B-C on old one, we must get A-B-C after merge. Not A-B. } - print $sql; - //$this->errors = $db->lasterror(); return false; } From ebc54f82e66710cfdeb17434d966fd1d50b4b633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 24 Nov 2021 18:16:48 +0100 Subject: [PATCH 14/78] move actioncomm --- htdocs/comm/action/class/actioncomm.class.php | 20 +++++++++++++++++++ htdocs/product/card.php | 18 +++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 3e2520f43da..bcfb15b932f 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -2203,6 +2203,26 @@ class ActionComm extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'actioncomm SET fk_element = ' . ((int) $dest_id) . ' WHERE elementtype="product" AND fk_element = '.((int) $origin_id); + + if (!$db->query($sql)) { + //$this->errors = $db->lasterror(); + return false; + } + + return true; + } + /** * Is the action delayed? * diff --git a/htdocs/product/card.php b/htdocs/product/card.php index ff73dff45c9..625d94e6566 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -311,21 +311,23 @@ if (empty($reshook)) { // TODO add this functionality into the api_products.class.php // TODO Mutualise the list into object product.class.php $objects = array( + 'ActionComm' => '/comm/action/class/actioncomm.class.php', + 'Bom' => '/bom/class/bom.class.php', // do not use Categorie, it cause foreign key error, merge is done before //'Categorie' => '/categories/class/categorie.class.php', - 'Propal' => '/comm/propal/class/propal.class.php', 'Commande' => '/commande/class/commande.class.php', - 'Facture' => '/compta/facture/class/facture.class.php', - 'FactureRec' => '/compta/facture/class/facture-rec.class.php', - 'Bom' => '/bom/class/bom.class.php', - 'Contrat' => '/contrat/class/contrat.class.php', - 'Reception' => '/reception/class/reception.class.php', - 'FichinterRec' => '/fichinter/class/fichinterrec.class.php', 'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php', + 'Contrat' => '/contrat/class/contrat.class.php', + 'Delivery' => '/delivery/class/delivery.class.php', + 'Facture' => '/compta/facture/class/facture.class.php', 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php', + 'FactureRec' => '/compta/facture/class/facture-rec.class.php', + 'FichinterRec' => '/fichinter/class/fichinterrec.class.php', 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', 'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php', - 'Delivery' => '/delivery/class/delivery.class.php', + 'Propal' => '/comm/propal/class/propal.class.php', + 'Reception' => '/reception/class/reception.class.php', + 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', ); //First, all core objects must update their tables From 38f2a2ca430ef58385233b73023497de773567b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 24 Nov 2021 18:19:59 +0100 Subject: [PATCH 15/78] move actioncomm --- htdocs/product/card.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 625d94e6566..063e6d04f09 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -323,7 +323,6 @@ if (empty($reshook)) { 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php', 'FactureRec' => '/compta/facture/class/facture-rec.class.php', 'FichinterRec' => '/fichinter/class/fichinterrec.class.php', - 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php', 'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php', 'Propal' => '/comm/propal/class/propal.class.php', 'Reception' => '/reception/class/reception.class.php', From 661e404a14500b7185a7852ec46a70f622cd57ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 24 Nov 2021 22:56:32 +0100 Subject: [PATCH 16/78] fix tests --- htdocs/comm/action/class/actioncomm.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index bcfb15b932f..e2f78e82c99 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -2206,17 +2206,17 @@ class ActionComm extends CommonObject /** * Function used to replace a product id with another one. * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param int $origin_id Old product id * @param int $dest_id New product id * @return bool */ - public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + public static function replaceProduct(DoliDB $dbs, $origin_id, $dest_id) { $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'actioncomm SET fk_element = ' . ((int) $dest_id) . ' WHERE elementtype="product" AND fk_element = '.((int) $origin_id); - - if (!$db->query($sql)) { - //$this->errors = $db->lasterror(); + // using $dbs, not $this->db because function is static + if (!$dbs->query($sql)) { + //$this->errors = $dbs->lasterror(); return false; } From efc0251a66ad35d1bcbd4511aa36ed1791277058 Mon Sep 17 00:00:00 2001 From: lvessiller Date: Mon, 6 Dec 2021 11:40:50 +0100 Subject: [PATCH 17/78] FIX can modify tag in thirdparty card if const THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER enabled --- htdocs/societe/card.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 052d681b0a0..9a6e0888b8c 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1126,13 +1126,14 @@ else document.formsoc.private.value=1; }); + var canHaveCategoryIfNotCustomerProspectSupplier = ' . (empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER) ? '0' : '1') . '; init_customer_categ(); $("#customerprospect").change(function() { init_customer_categ(); }); function init_customer_categ() { console.log("is customer or prospect = "+jQuery("#customerprospect").val()); - if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() == 0 || ' . (empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER) ? '1' : '0').')) + if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() != 0 || !canHaveCategoryIfNotCustomerProspectSupplier)) { jQuery(".visibleifcustomer").hide(); } @@ -1151,10 +1152,16 @@ else if (jQuery("#fournisseur").val() == 0) { jQuery(".visibleifsupplier").hide(); + if (jQuery("#customerprospect").val() == 0 && canHaveCategoryIfNotCustomerProspectSupplier && jQuery(".visibleifcustomer").is(":hidden")) { + jQuery(".visibleifcustomer").show(); + } } else { jQuery(".visibleifsupplier").show(); + if (jQuery("#customerprospect").val() == 0 && jQuery(".visibleifcustomer").is(":visible")) { + jQuery(".visibleifcustomer").hide(); + } } } @@ -1769,13 +1776,14 @@ else } }); + var canHaveCategoryIfNotCustomerProspectSupplier = ' . (empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER) ? '0' : '1') . '; init_customer_categ(); $("#customerprospect").change(function() { init_customer_categ(); }); function init_customer_categ() { console.log("is customer or prospect = "+jQuery("#customerprospect").val()); - if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() == 0 || '.(empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER) ? '1' : '0').')) + if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() != 0 || !canHaveCategoryIfNotCustomerProspectSupplier)) { jQuery(".visibleifcustomer").hide(); } @@ -1794,10 +1802,16 @@ else if (jQuery("#fournisseur").val() == 0) { jQuery(".visibleifsupplier").hide(); + if (jQuery("#customerprospect").val() == 0 && canHaveCategoryIfNotCustomerProspectSupplier && jQuery(".visibleifcustomer").is(":hidden")) { + jQuery(".visibleifcustomer").show(); + } } else { jQuery(".visibleifsupplier").show(); + if (jQuery("#customerprospect").val() == 0 && jQuery(".visibleifcustomer").is(":visible")) { + jQuery(".visibleifcustomer").hide(); + } } }; From 03d43173020ef87fe0fdd7696ad64d02f755e831 Mon Sep 17 00:00:00 2001 From: Christian Foellmann Date: Tue, 26 Oct 2021 18:26:36 +0200 Subject: [PATCH 18/78] add hook 'menuDropdownQuickaddItems' to manipulate dropdown menu --- htdocs/core/class/hookmanager.class.php | 1 + htdocs/main.inc.php | 319 +++++++++++------------- htdocs/theme/eldy/dropdown.inc.php | 10 +- 3 files changed, 158 insertions(+), 172 deletions(-) diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index d1b1e08710e..82772418b36 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -195,6 +195,7 @@ class HookManager 'getFormatedSupplierRef', 'getIdProfUrl', 'getInputIdProf', + 'menuDropdownQuickaddItems', 'menuLeftMenuItems', 'moveUploadedFile', 'moreHtmlStatus', diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index dec6e389156..d15abb78098 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2264,185 +2264,16 @@ function top_menu_user($hideloginname = 0, $urllogout = '') */ function top_menu_quickadd() { - global $langs, $conf, $db, $hookmanager, $user; - global $menumanager; + global $langs; $html = ''; - // Define $dropDownQuickAddHtml - $dropDownQuickAddHtml = ''; - - $dropDownQuickAddHtml .= ''; $html .= ' '; $html .= ' @@ -2477,6 +2308,152 @@ function top_menu_quickadd() return $html; } +/** + * Generate list of quickadd items + * + * @return string HTML output + */ +function printDropdownQuickadd() +{ + global $conf, $user, $langs, $hookmanager; + + $items = array( + 'items' => array( + array( + "url" => "/societe/card.php?action=create", + "title" => "MenuNewThirdParty@companies", + "name" => "ThirdParty@companies", + "picto" => "object_company", + "activation" => !empty($conf->societe->enabled) && $user->rights->societe->creer, // vs hooking + "position" => 10, + ), + array( + "url" => "/contact/card.php?action=create", + "title" => "NewContactAddress@companies", + "name" => "Contact@companies", + "picto" => "object_contact", + "activation" => !empty($conf->societe->enabled) && $user->rights->societe->contact->creer, // vs hooking + "position" => 20, + ), + array( + "url" => "/comm/propal/card.php?action=create", + "title" => "NewPropal@propal", + "name" => "Proposal@propal", + "picto" => "object_propal", + "activation" => !empty($conf->propal->enabled) && $user->rights->propale->creer, // vs hooking + "position" => 30, + ), + + array( + "url" => "/commande/card.php?action=create", + "title" => "NewOrder@orders", + "name" => "Order@orders", + "picto" => "object_order", + "activation" => !empty($conf->commande->enabled) && $user->rights->commande->creer, // vs hooking + "position" => 40, + ), + array( + "url" => "/compta/facture/card.php?action=create", + "title" => "NewBill@bills", + "name" => "Bill@bills", + "picto" => "object_bill", + "activation" => !empty($conf->facture->enabled) && $user->rights->facture->creer, // vs hooking + "position" => 50, + ), + array( + "url" => "/compta/facture/card.php?action=create", + "title" => "NewContractSubscription@contracts", + "name" => "Contract@contracts", + "picto" => "object_contract", + "activation" => !empty($conf->contrat->enabled) && $user->rights->contrat->creer, // vs hooking + "position" => 60, + ), + array( + "url" => "/supplier_proposal/card.php?action=create", + "title" => "SupplierProposalNew@supplier_proposal", + "name" => "SupplierProposal@supplier_proposal", + "picto" => "object_propal", + "activation" => !empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->creer, // vs hooking + "position" => 70, + ), + array( + "url" => "/fourn/commande/card.php?action=create", + "title" => "NewSupplierOrderShort@orders", + "name" => "SupplierOrder@orders", + "picto" => "object_order", + "activation" => (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->creer) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->creer), // vs hooking + "position" => 80, + ), + array( + "url" => "/fourn/facture/card.php?action=create", + "title" => "NewBill@bills", + "name" => "SupplierBill@bills", + "picto" => "object_bill", + "activation" => (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->creer) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->creer), // vs hooking + "position" => 90, + ), + array( + "url" => "/product/card.php?action=create&type=0", + "title" => "NewProduct@products", + "name" => "Product@products", + "picto" => "object_product", + "activation" => !empty($conf->product->enabled) && $user->rights->produit->creer, // vs hooking + "position" => 100, + ), + array( + "url" => "/product/card.php?action=create&type=1", + "title" => "NewService@products", + "name" => "Service@products", + "picto" => "object_service", + "activation" => !empty($conf->service->enabled) && $user->rights->service->creer, // vs hooking + "position" => 110, + ), + ), + ); + + $dropDownQuickAddHtml = ''; + + // Define $dropDownQuickAddHtml + $dropDownQuickAddHtml .= ''; + + return $dropDownQuickAddHtml; +} + /** * Build the tooltip on top menu bookmark * diff --git a/htdocs/theme/eldy/dropdown.inc.php b/htdocs/theme/eldy/dropdown.inc.php index dcf7ca787b7..41622afc53c 100644 --- a/htdocs/theme/eldy/dropdown.inc.php +++ b/htdocs/theme/eldy/dropdown.inc.php @@ -423,7 +423,15 @@ a.top-menu-dropdown-link { .quickadd-body.dropdown-body { padding: unset; - padding-top: 15px; +} + +.quickadd-item { + padding-top: 6px; + padding-bottom: 6px; +} + +.quickadd-item:before { + content: none; } .quickadd-header { From 9329e54fc3dcaa48bb74c32c394cc046f6632eac Mon Sep 17 00:00:00 2001 From: Christian Foellmann Date: Tue, 26 Oct 2021 18:28:08 +0200 Subject: [PATCH 19/78] fix hook 'menuDropdownQuickaddItems' --- htdocs/main.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index d15abb78098..18095df707c 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2421,9 +2421,9 @@ function printDropdownQuickadd() $parameters = array(); $hook_items = $items; $reshook = $hookmanager->executeHooks('menuDropdownQuickaddItems', $parameters, $hook_items); // Note that $action and $object may have been modified by some hooks - if (is_numeric($reshook) && !empty($hookmanager->results)) { + if (is_numeric($reshook) && is_array($hookmanager->results)) { if ($reshook == 0) { - $items['items'][] = $hookmanager->results; // add + $items['items'] = array_merge($items['items'],$hookmanager->results); // add } else { $items = $hookmanager->results; // replace } From 0f177274e01a0d83ce5d354c28f7bcfdae197722 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 26 Oct 2021 16:31:06 +0000 Subject: [PATCH 20/78] Fixing style errors. --- htdocs/main.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 18095df707c..cf0a27efd53 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2423,7 +2423,7 @@ function printDropdownQuickadd() $reshook = $hookmanager->executeHooks('menuDropdownQuickaddItems', $parameters, $hook_items); // Note that $action and $object may have been modified by some hooks if (is_numeric($reshook) && is_array($hookmanager->results)) { if ($reshook == 0) { - $items['items'] = array_merge($items['items'],$hookmanager->results); // add + $items['items'] = array_merge($items['items'], $hookmanager->results); // add } else { $items = $hookmanager->results; // replace } From 04cc0a0480459c19837abb4e0f8f88d01689301f Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Mon, 10 Jan 2022 17:02:15 +0100 Subject: [PATCH 21/78] NEW : Add column "Total HT" to products array on document creation card --- htdocs/core/class/commonobject.class.php | 2 ++ htdocs/core/tpl/originproductline.tpl.php | 1 + 2 files changed, 3 insertions(+) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index a01e2d7c209..e89990b7b5e 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4441,6 +4441,7 @@ abstract class CommonObject print '
'.$langs->trans('Unit').''.$langs->trans('ReductionShort').''.$langs->trans('TotalHT').''.$form->showCheckAddButtons('checkforselect', 1).'
'.$langs->trans($this->tpl['unit']).''.$this->tpl['remise_percent'].''.$this->tpl['total_ht'].'
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo ''; echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo '
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . '
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . ' 
'; - echo '
' . $form->selectarray('apply_to', $tab_apply, '', 0) . '
'; - echo '
' . $form->select_dolusers('', 'fk_user') . '
'; - echo '
' . $form->select_dolgroups('', 'fk_usergroup') . '
'; + echo '
' . $form->selectarray('apply_to', $tab_apply, '', 0) . '
'; + echo '
' . $form->select_dolusers('', 'fk_user') . '
'; + echo '
' . $form->select_dolgroups('', 'fk_usergroup') . '
'; echo '
' . $form->selectExpense('', 'fk_c_type_fees', 0, 1, 1) . '' . $form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0) . '' . $form->selectDate(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0) . '' . $form->selectDate(strtotime(date('Y-m-t', dol_now())), 'end', '', '', 0, '', 1, 0) . ' ' . $conf->currency . '' . $form->selectyesno('restrictive', 0, 1) . '' . $form->selectExpense('', 'fk_c_type_fees', 0, 1, 1) . '' . $form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0) . '' . $form->selectDate(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0) . ' ' . $conf->currency . '' . $form->selectyesno('restrictive', 0, 1) . '
'; @@ -227,21 +227,21 @@ if ($action == 'edit') { echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo ''; foreach ($rules as $rule) { - echo ''; + echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; foreach ($rules as $rule) { - echo ''; + echo ''; echo ''; print ''; // Overwrite some values if creation of invoice is from a predefined invoice - if (empty($origin) && empty($originid) && GETPOST('fac_rec', 'int') > 0) { - $invoice_predefined->fetch(GETPOST('fac_rec', 'int')); + if (empty($origin) && empty($originid) && $fac_recid > 0) { + $invoice_predefined->fetch($fac_recid); $dateinvoice = $invoice_predefined->date_when; // To use next gen date by default later if (empty($projectid)) { @@ -2088,15 +2088,15 @@ if ($action == 'create') { if ($num > 0) { print ''; } @@ -2432,7 +2432,7 @@ if ($action == 'create') { // Help of substitution key $htmltext = ''; - if (GETPOST('fac_rec', 'int') > 0) { + if ($fac_recid > 0) { $dateexample = $newdateinvoice ? $newdateinvoice : $dateinvoice; if (empty($dateexample)) { $dateexample = dol_now(); From 59fec7d0949cf860f01753d484242e7436f54e5f Mon Sep 17 00:00:00 2001 From: atm-greg Date: Tue, 5 Apr 2022 15:10:31 +0200 Subject: [PATCH 31/78] implement cache managed by current object --- htdocs/core/class/commonobject.class.php | 4 ++++ htdocs/core/lib/pdf.lib.php | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index a8233a3d29f..e04ac12636d 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3779,6 +3779,10 @@ abstract class CommonObject { global $conf, $hookmanager, $action; + // important for pdf generation time reduction + // this boolean is true if $this->linkedObjects has already been loaded with all objects linked without filter + if ($this->linkedObjectsFullLoaded) return 1; + $this->linkedObjectsIds = array(); $this->linkedObjects = array(); diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index b273f93b69f..ea8c6c2ce23 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -2282,9 +2282,7 @@ function pdf_getLinkedObjects(&$object, $outputlangs) $linkedobjects = array(); - if (empty($object->linkedObjectsFullLoaded)) { - $object->fetchObjectLinked(); - } + $object->fetchObjectLinked(); foreach ($object->linkedObjects as $objecttype => $objects) { if ($objecttype == 'facture') { From aa42df9961e4c0865b8f1382b870317ab521281b Mon Sep 17 00:00:00 2001 From: atm-greg Date: Tue, 5 Apr 2022 15:11:37 +0200 Subject: [PATCH 32/78] just for glory --- 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 e04ac12636d..02d016d2ce7 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -15,6 +15,7 @@ * Copyright (C) 2018-2021 FrƩdƩric France * Copyright (C) 2018 Josep Lluƭs Amador * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 GrƩgory BlƩmand * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From 046089f3716b55cfde7bcf6cce92e81b27072634 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Tue, 5 Apr 2022 15:38:54 +0200 Subject: [PATCH 33/78] FIX 16.0 - ref_client set instead of ref_supplier (maybe copy-paste error) --- htdocs/fourn/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 02e77d13f58..b1f2be177f6 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -903,7 +903,7 @@ if (empty($reshook)) { $object->date = $dateinvoice; $object->note_public = trim(GETPOST('note_public', 'restricthtml')); $object->note_private = trim(GETPOST('note_private', 'restricthtml')); - $object->ref_client = GETPOST('ref_client'); + $object->ref_supplier = GETPOST('ref_supplier', 'nohtml'); $object->model_pdf = GETPOST('model'); $object->fk_project = GETPOST('projectid', 'int'); $object->cond_reglement_id = (GETPOST('type') == 3 ? 1 : GETPOST('cond_reglement_id')); From 216b4b7309a601b4db04628a6b0ebc43f3152bf0 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Tue, 5 Apr 2022 17:30:36 +0200 Subject: [PATCH 34/78] 16.0 - deprecate `amount` field of FactureFournisseur and FactureFournisseurRec --- htdocs/fourn/class/fournisseur.facture-rec.class.php | 5 +++++ htdocs/fourn/class/fournisseur.facture.class.php | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/htdocs/fourn/class/fournisseur.facture-rec.class.php b/htdocs/fourn/class/fournisseur.facture-rec.class.php index fea334e43cf..7d90c239ba7 100644 --- a/htdocs/fourn/class/fournisseur.facture-rec.class.php +++ b/htdocs/fourn/class/fournisseur.facture-rec.class.php @@ -79,6 +79,11 @@ class FactureFournisseurRec extends CommonInvoice public $suspended; public $libelle; + + /** + * @deprecated + * @var double $amount + */ public $amount; public $remise; public $vat_src_code; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 24561e08785..b90fbbbd86a 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -181,6 +181,10 @@ class FactureFournisseur extends CommonInvoice */ public $date_echeance; + /** + * @deprecated + * @var double $amount + */ public $amount = 0; public $remise = 0; From bb30a1c8c6883033cfe6e489843a6237df324eb6 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Tue, 5 Apr 2022 17:31:04 +0200 Subject: [PATCH 35/78] FIX 16.0 SQL error on update --- htdocs/fourn/class/fournisseur.facture.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index b90fbbbd86a..b602c27af57 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1262,7 +1262,7 @@ class FactureFournisseur extends CommonInvoice } $sql .= " libelle=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; $sql .= " paye=".(isset($this->paye) ? $this->paye : "null").","; - $sql .= " amount=".(isset($this->amount) ? $this->amount : "null").","; + $sql .= " amount=".(isset($this->amount) ? doubleval($this->amount) : "null").","; $sql .= " remise=".(isset($this->remise) ? $this->remise : "null").","; $sql .= " close_code=".(isset($this->close_code) ? "'".$this->db->escape($this->close_code)."'" : "null").","; $sql .= " close_note=".(isset($this->close_note) ? "'".$this->db->escape($this->close_note)."'" : "null").","; @@ -1276,7 +1276,7 @@ class FactureFournisseur extends CommonInvoice $sql .= " fk_user_author=".(isset($this->author) ? $this->author : "null").","; $sql .= " fk_user_valid=".(isset($this->fk_user_valid) ? $this->fk_user_valid : "null").","; $sql .= " fk_facture_source=".(isset($this->fk_facture_source) ? $this->fk_facture_source : "null").","; - $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; + $sql .= " fk_projet=".(isset($this->fk_project) ? intval($this->fk_project) : "null").","; $sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : "null").","; $sql .= " date_lim_reglement=".(dol_strlen($this->date_echeance) != 0 ? "'".$this->db->idate($this->date_echeance)."'" : 'null').","; $sql .= " note_private=".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null").","; From 91909928d4ca5c73038f1146c66ce1e89ce1d608 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 Apr 2022 18:19:06 +0200 Subject: [PATCH 36/78] FIX Can't edit bank record --- htdocs/compta/bank/card.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 8430d9e7440..283258a08a0 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -65,7 +65,8 @@ $hookmanager->initHooks(array('bankcard', 'globalcard')); // Security check $id = GETPOST("id", 'int') ? GETPOST("id", 'int') : GETPOST('ref', 'alpha'); -$fieldid = GETPOSTISSET("ref") ? 'ref' : 'rowid'; +$fieldid = GETPOST("id", 'int') ? 'rowid' : 'ref'; + $result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid); From 3eabb52176e76f1180a02b9712f3e8a9fc2042ce Mon Sep 17 00:00:00 2001 From: "goup2cloud.com" Date: Tue, 5 Apr 2022 18:21:28 +0200 Subject: [PATCH 37/78] Changed --- htdocs/contrat/services_list.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 39dfe336a31..adf7a4b6ed7 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -326,25 +326,25 @@ if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue != -1 && $fil $sql .= " AND cd.date_ouverture_prevue ".$filter_opouvertureprevue." '".$db->idate($filter_dateouvertureprevue_start)."'"; } if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_dateouvertureprevue_end)."'"; + $sql .= " AND cd.date_ouverture_prevue ".$filter_opouvertureprevue." '".$db->idate($filter_dateouvertureprevue_start)."' AND '".$db->idate($filter_dateouvertureprevue_end)."'"; } if (!empty($filter_op1) && $filter_op1 != -1 && $filter_op1 != ' BETWEEN ' && $filter_date1_start != '') { $sql .= " AND cd.date_ouverture ".$filter_op1." '".$db->idate($filter_date1_start)."'"; } if (!empty($filter_op1) && $filter_op1 == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_date1_end)."'"; + $sql .= " AND cd.date_ouverture ".$filter_op1." '".$db->idate($filter_date1_start)."' AND '".$db->idate($filter_date1_end)."'"; } if (!empty($filter_op2) && $filter_op2 != -1 && $filter_op2 != ' BETWEEN ' && $filter_date2_start != '') { $sql .= " AND cd.date_fin_validite ".$filter_op2." '".$db->idate($filter_date2_start)."'"; } if (!empty($filter_op2) && $filter_op2 == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_date2_end)."'"; + $sql .= " AND cd.date_fin_validite ".$filter_op2." '".$db->idate($filter_date2_start)."' AND '".$db->idate($filter_date2_end)."'"; } if (!empty($filter_opcloture) && $filter_opcloture != ' BETWEEN ' && $filter_opcloture != -1 && $filter_datecloture_start != '') { $sql .= " AND cd.date_cloture ".$filter_opcloture." '".$db->idate($filter_datecloture_start)."'"; } if (!empty($filter_opcloture) && $filter_opcloture == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_datecloture_end)."'"; + $sql .= " AND cd.date_cloture ".$filter_opcloture." '".$db->idate($filter_datecloture_start)."' AND '".$db->idate($filter_datecloture_end)."'"; } // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; From d213be235eef7917902898f45da6e6b04e16d1c7 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Tue, 5 Apr 2022 18:32:29 +0200 Subject: [PATCH 38/78] Cleaner way of fixing the SQL error on update --- htdocs/fourn/class/fournisseur.facture.class.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index b602c27af57..176f79a51de 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1178,7 +1178,8 @@ class FactureFournisseur extends CommonInvoice $this->paye = trim($this->paye); } if (isset($this->amount)) { - $this->amount = trim($this->amount); + if (empty($this->amount)) $this->amount = 0; + else $this->amount = doubleval($this->amount); } if (isset($this->remise)) { $this->remise = trim($this->remise); @@ -1225,7 +1226,8 @@ class FactureFournisseur extends CommonInvoice $this->fk_facture_source = trim($this->fk_facture_source); } if (isset($this->fk_project)) { - $this->fk_project = trim($this->fk_project); + if (empty($this->fk_project)) $this->fk_project = null; + else $this->fk_project = intval($this->fk_project); } if (isset($this->cond_reglement_id)) { $this->cond_reglement_id = trim($this->cond_reglement_id); @@ -1262,7 +1264,7 @@ class FactureFournisseur extends CommonInvoice } $sql .= " libelle=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; $sql .= " paye=".(isset($this->paye) ? $this->paye : "null").","; - $sql .= " amount=".(isset($this->amount) ? doubleval($this->amount) : "null").","; + $sql .= " amount=".(isset($this->amount) ? $this->amount : "null").","; $sql .= " remise=".(isset($this->remise) ? $this->remise : "null").","; $sql .= " close_code=".(isset($this->close_code) ? "'".$this->db->escape($this->close_code)."'" : "null").","; $sql .= " close_note=".(isset($this->close_note) ? "'".$this->db->escape($this->close_note)."'" : "null").","; @@ -1276,7 +1278,7 @@ class FactureFournisseur extends CommonInvoice $sql .= " fk_user_author=".(isset($this->author) ? $this->author : "null").","; $sql .= " fk_user_valid=".(isset($this->fk_user_valid) ? $this->fk_user_valid : "null").","; $sql .= " fk_facture_source=".(isset($this->fk_facture_source) ? $this->fk_facture_source : "null").","; - $sql .= " fk_projet=".(isset($this->fk_project) ? intval($this->fk_project) : "null").","; + $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; $sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : "null").","; $sql .= " date_lim_reglement=".(dol_strlen($this->date_echeance) != 0 ? "'".$this->db->idate($this->date_echeance)."'" : 'null').","; $sql .= " note_private=".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null").","; From 946061af384798cdcb9df2633f70934447ca3ae2 Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:21:48 +0200 Subject: [PATCH 39/78] Update README.md --- htdocs/datapolicy/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/datapolicy/README.md b/htdocs/datapolicy/README.md index e2bde95a6d8..0d70b287a81 100644 --- a/htdocs/datapolicy/README.md +++ b/htdocs/datapolicy/README.md @@ -1,5 +1,7 @@ DataPolicy ========== + This module provides features to be compliant with data privacy rules of your country. -A schedlued job is installed to automatically clean old record in your database. You defined what to delete and when in the setup of module. \ No newline at end of file +A scheduled job is installed to automatically delete old records in your database. +In the setup of the module you define what should be deleted and when. From 32f601a48b6707afd7e6a0726da8835c57a17444 Mon Sep 17 00:00:00 2001 From: jpb Date: Wed, 6 Apr 2022 09:15:53 +0200 Subject: [PATCH 40/78] rename css class name --- htdocs/admin/expensereport_rules.php | 30 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php index 9204e72f049..1146232dca3 100644 --- a/htdocs/admin/expensereport_rules.php +++ b/htdocs/admin/expensereport_rules.php @@ -185,14 +185,14 @@ if ($action != 'edit') { echo '
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . '
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . ' 
'; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { $selected = ($object->is_for_all > 0) ? 'A' : ($object->fk_usergroup > 0 ? 'G' : 'U'); echo '
' . $form->selectarray('apply_to', $tab_apply, $selected, 0) . '
'; @@ -259,7 +259,7 @@ foreach ($rules as $rule) { echo '
'; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectExpense($object->fk_c_type_fees, 'fk_c_type_fees', 0, 1, 1); } else { @@ -278,7 +278,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectarray('code_expense_rules_type', $tab_rules_type, $object->code_expense_rules_type, 0); } else { @@ -287,7 +287,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { print $form->selectDate(strtotime(date('Y-m-d', $object->dates)), 'start', '', '', 0, '', 1, 0); } else { @@ -296,7 +296,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { print $form->selectDate(strtotime(date('Y-m-d', $object->datee)), 'end', '', '', 0, '', 1, 0); } else { @@ -305,7 +305,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo '' . $conf->currency; } else { @@ -314,7 +314,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectyesno('restrictive', $object->restrictive, 1); } else { From f4a780f3f66f149a762bab038e57eb5427b96a0d Mon Sep 17 00:00:00 2001 From: jpb Date: Mon, 4 Apr 2022 16:28:42 +0200 Subject: [PATCH 27/78] add name on tr data --- htdocs/admin/expensereport_rules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php index f15b996939d..9204e72f049 100644 --- a/htdocs/admin/expensereport_rules.php +++ b/htdocs/admin/expensereport_rules.php @@ -239,7 +239,7 @@ if ($action == 'edit') { echo '
'; if ($action == 'edit' && $object->id == $rule->id) { From ad145c94ca5a9ad2f4632e7b7621ab1ad5fd1547 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Mon, 4 Apr 2022 17:23:34 +0200 Subject: [PATCH 28/78] add comment --- 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 f7eb6a67263..a8233a3d29f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -125,6 +125,7 @@ abstract class CommonObject /** * @var boolean is linkedObjects full loaded. Loaded by ->fetchObjectLinked + * important for pdf generation time reduction */ public $linkedObjectsFullLoaded = false; From b929c2f671908619ec69a4900eb6a196e023fc3e Mon Sep 17 00:00:00 2001 From: atm-florian Date: Tue, 5 Apr 2022 11:46:06 +0200 Subject: [PATCH 29/78] FIX 16.0 - supplier invoice card creates two invoices instead of one when creating from a template --- htdocs/fourn/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index f4d628d5882..95bd9cbd136 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -929,7 +929,7 @@ if (empty($reshook)) { } // Standard invoice or Deposit invoice, not from a Predefined template invoice - if (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT && GETPOST('fac_rec') <= 0) { + elseif (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT && GETPOST('fac_rec') <= 0) { if (GETPOST('socid', 'int') < 1) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors'); $action = 'create'; From 392ba6deedb42a31f7388bff636feecb1411058e Mon Sep 17 00:00:00 2001 From: atm-florian Date: Tue, 5 Apr 2022 12:16:06 +0200 Subject: [PATCH 30/78] FIX 16.0 - my previous fix was incomplete (missing parentheses around OR-separated conditions) + replace GETPOST('fac_rec', 'int') with variable + make sure it works even if, one day, the "nothing selected" value for the template supplier invoice selector changes to -1 instead of '' --- htdocs/fourn/facture/card.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 95bd9cbd136..02e77d13f58 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -76,7 +76,7 @@ $lineid = GETPOST('lineid', 'int'); $projectid = GETPOST('projectid', 'int'); $origin = GETPOST('origin', 'alpha'); $originid = GETPOST('originid', 'int'); -$fac_rec = GETPOST('fac_rec', 'int'); +$fac_recid = GETPOST('fac_rec', 'int'); // PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -885,7 +885,7 @@ if (empty($reshook)) { } // Standard invoice or Deposit invoice, created from a Predefined template invoice - if ((GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT) && GETPOST('fac_rec', 'int') > 0) { + elseif ($fac_recid > 0 && (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)) { if (empty($dateinvoice)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); @@ -918,7 +918,7 @@ if (empty($reshook)) { $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int'); // Source facture - $object->fac_rec = GETPOST('fac_rec', 'int'); + $object->fac_rec = $fac_recid; $fac_rec = new FactureFournisseurRec($db); $fac_rec->fetch($object->fac_rec); $fac_rec->fetch_lines(); @@ -929,7 +929,7 @@ if (empty($reshook)) { } // Standard invoice or Deposit invoice, not from a Predefined template invoice - elseif (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT && GETPOST('fac_rec') <= 0) { + elseif ($fac_recid <= 0 && (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)) { if (GETPOST('socid', 'int') < 1) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors'); $action = 'create'; @@ -2024,15 +2024,15 @@ if ($action == 'create') { $exampletemplateinvoice = new FactureFournisseurRec($db); $invoice_predefined = new FactureFournisseurRec($db); - if (empty($origin) && empty($originid) && GETPOST('fac_rec', 'int') > 0) { - $invoice_predefined->fetch(GETPOST('fac_rec', 'int')); + if (empty($origin) && empty($originid) && $fac_recid > 0) { + $invoice_predefined->fetch($fac_recid); } // Third party print '
'.$langs->trans('Supplier').''; - if ($societe->id > 0 && (!GETPOST('fac_rec', 'int') || !empty($invoice_predefined->frequency))) { + if ($societe->id > 0 && ($fac_recid <= 0 || !empty($invoice_predefined->frequency))) { $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1); print $societe->getNomUrl(1, 'supplier'); print ''; @@ -2050,15 +2050,15 @@ if ($action == 'create') { }); '; } - if (!GETPOST('fac_rec', 'int')) { + if ($fac_recid <= 0) { print ' '; } } print '
'.$langs->trans('CreateFromRepeatableInvoice').''; - //print ''; + //print ''; print '
'.$langs->trans('Project').''; print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); - print ' id.($fac_rec ? '&fac_rec='.$fac_rec : '')).'">'; + print ' id.($fac_recid > 0 ? '&fac_rec='.$fac_recid : '')).'">'; print '
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo ''; @@ -227,14 +227,14 @@ if ($action == 'edit') { echo '
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . '
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . ' 
'; - echo ''; + echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo ''; From c3ae63f587f76670c113746f0d2f1e62b129548a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 Apr 2022 11:34:49 +0200 Subject: [PATCH 41/78] FIX out of memory when more than 100 000 invoices. --- htdocs/compta/facture/list.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index ccf3c2f3f0c..f2cc5943e7a 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -757,12 +757,28 @@ $sql .= ' f.rowid DESC '; $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + /* This old and fast method to get and count full list returns all record so use a high amount of memory. $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + */ + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + if ($sall || $search_product_category > 0 || $search_user > 0) { + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(DISTINCT f.rowid) as nbtotalofrecords FROM', $sql); + } else { + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(f.rowid) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture as pf ON pf.fk_facture = f.rowid/', '', $sqlforcount); + } + $sqlforcount = preg_replace('/GROUP BY.*$/', '', $sqlforcount); + + $resql = $db->query($sqlforcount); + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + + if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } $sql .= $db->plimit($limit + 1, $offset); From 091ca31b6cc661edc38ded9b1b4d0947a4740fb5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 Apr 2022 17:32:56 +0200 Subject: [PATCH 42/78] NEW Add method hintindex() in database handlers. --- htdocs/compta/facture/list.php | 31 ++++++++++++++++++++----------- htdocs/core/db/DoliDB.class.php | 11 +++++++++++ htdocs/core/db/mysqli.class.php | 13 +++++++++++++ 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 06da94e8e2b..eedc3297018 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -598,6 +598,9 @@ if (!empty($search_categ_cus) && $search_categ_cus != '-1') { } $sql .= ', '.MAIN_DB_PREFIX.'facture as f'; +if ($sortfield == "f.datef") { + $sql .= $db->hintindex('idx_facture_datef'); +} if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (f.rowid = ef.fk_object)"; } @@ -846,14 +849,6 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPrint; -$sql .= ' ORDER BY '; -$listfield = explode(',', $sortfield); -$listorder = explode(',', $sortorder); -foreach ($listfield as $key => $value) { - $sql .= $listfield[$key].' '.($listorder[$key] ? $listorder[$key] : 'DESC').','; -} -$sql .= ' f.rowid DESC '; - $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { /* This old and fast method to get and count full list returns all record so use a high amount of memory. @@ -870,8 +865,12 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $sqlforcount = preg_replace('/GROUP BY.*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); - $objforcount = $db->fetch_object($resql); - $nbtotalofrecords = $objforcount->nbtotalofrecords; + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; @@ -880,7 +879,17 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $db->free($resql); } -$sql .= $db->plimit($limit + 1, $offset); +// Complete request and execute it with limit +$sql .= ' ORDER BY '; +$listfield = explode(',', $sortfield); +$listorder = explode(',', $sortorder); +foreach ($listfield as $key => $value) { + $sql .= $listfield[$key].' '.($listorder[$key] ? $listorder[$key] : 'DESC').','; +} +$sql .= ' f.rowid DESC '; +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} $resql = $db->query($sql); diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 66e54a4fc3c..aae315ec992 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -96,6 +96,17 @@ abstract class DoliDB implements Database return '(CASE WHEN '.$test.' THEN '.$resok.' ELSE '.$resko.' END)'; } + /** + * Return SQL string to force an index + * + * @param string $nameofindex Name of index + * @return string SQL string + */ + public function hintindex($nameofindex) + { + return ''; + } + /** * Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field. * Function to use to build INSERT, UPDATE or WHERE predica diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 81a331add8a..582fd08811f 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -168,6 +168,18 @@ class DoliDBMysqli extends DoliDB } + /** + * Return SQL string to force an index + * + * @param string $nameofindex Name of index + * @return string SQL string + */ + public function hintindex($nameofindex) + { + return " FORCE INDEX(".preg_replace('/[^a-z0-9_]/', '', $nameofindex).")"; + } + + /** * Convert a SQL request in Mysql syntax to native syntax * @@ -180,6 +192,7 @@ class DoliDBMysqli extends DoliDB return $line; } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Select a database From 4f1e280355badfbb46527acbf81a56c36084e223 Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Wed, 6 Apr 2022 20:09:50 +0200 Subject: [PATCH 43/78] Update interface_80_modStripe_Stripe.class.php add D at THIR-D-PARTY if (!empty($conf->global->STRIPE_DELETE_STRIPE_ACCOUNT_WHEN_DELETING_THIRDPARTY)) --- htdocs/core/triggers/interface_80_modStripe_Stripe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php index 0e571f26c98..dfac4c5b84d 100644 --- a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php +++ b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php @@ -183,7 +183,7 @@ class InterfaceStripe extends DolibarrTriggers if ($action == 'COMPANY_DELETE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->STRIPE_DELETE_STRIPE_ACCOUNT_WHEN_DELETING_THIRPARTY)) { + if (!empty($conf->global->STRIPE_DELETE_STRIPE_ACCOUNT_WHEN_DELETING_THIRDPARTY)) { // By default, we do not delete the stripe account. We may need to reuse it with its payment_intent, for example if delete is for a merge of thirdparties. $stripeacc = $stripe->getStripeAccount($service); // No need of network access for this. May return '' if no Oauth defined. From 9db2f2c3f235f5dedd14c568e7e906955002c65c Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Wed, 6 Apr 2022 20:12:35 +0200 Subject: [PATCH 44/78] Update company.lib.php add D of THIR-D-PARTIES ($conf->global->THIRDPARTIES_DISABLE_RELATED_OBJECT_TAB) --- htdocs/core/lib/company.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index b8b6d1c728a..197a6c95687 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -180,7 +180,7 @@ function societe_prepare_head(Societe $object) // Related items if ((!empty($conf->commande->enabled) || !empty($conf->propal->enabled) || !empty($conf->facture->enabled) || !empty($conf->ficheinter->enabled) || (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) - && empty($conf->global->THIRPARTIES_DISABLE_RELATED_OBJECT_TAB)) { + && empty($conf->global->THIRDPARTIES_DISABLE_RELATED_OBJECT_TAB)) { $head[$h][0] = DOL_URL_ROOT.'/societe/consumption.php?socid='.$object->id; $head[$h][1] = $langs->trans("Referers"); $head[$h][2] = 'consumption'; From 81e68c892d292ec9633a3001b06dda69467c58ad Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Wed, 6 Apr 2022 20:43:07 +0200 Subject: [PATCH 45/78] Update currencies_iso-4217.txt --- dev/resources/iso-normes/currencies_iso-4217.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/dev/resources/iso-normes/currencies_iso-4217.txt b/dev/resources/iso-normes/currencies_iso-4217.txt index bc392b72e9c..e24faa4283e 100644 --- a/dev/resources/iso-normes/currencies_iso-4217.txt +++ b/dev/resources/iso-normes/currencies_iso-4217.txt @@ -1,8 +1,12 @@ # File of all ISO-4217 currencies codes -# http://en.wikipedia.org/wiki/ISO_4217 -# http://fx.sauder.ubc.ca/currency_table.html for symbols for 2 letter code # -# Code,Name,Nb decimals +# https://en.wikipedia.org/wiki/ISO_4217 +# https://en.wikipedia.org/wiki/Currency_symbol for symbols for 2 letter code +# + + +# Code, Currency Name, Nb decimals + AED,UAE Dirham,2 AFN,Afghanistan Afghani,2 ALL,Albanian Lek,2 From 2e890d9d283e36e27b422cd6a6ed527667dfb69e Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Wed, 6 Apr 2022 21:08:23 +0200 Subject: [PATCH 46/78] Update societe.class.php note_public => NotePublic note_private => NotePrivate see #20419 --- htdocs/societe/class/societe.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 015a8c92af6..25d2831f853 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -193,8 +193,8 @@ class Societe extends CommonObject 'tva_intra' =>array('type'=>'varchar(20)', 'label'=>'Tva intra', 'enabled'=>1, 'visible'=>-1, 'position'=>210), 'capital' =>array('type'=>'double(24,8)', 'label'=>'Capital', 'enabled'=>1, 'visible'=>-1, 'position'=>215), 'fk_stcomm' =>array('type'=>'integer', 'label'=>'CommercialStatus', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>220), - 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>225), - 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>230), + 'note_public' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>225), + 'note_private' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>230), 'prefix_comm' =>array('type'=>'varchar(5)', 'label'=>'Prefix comm', 'enabled'=>'$conf->global->SOCIETE_USEPREFIX', 'visible'=>-1, 'position'=>235), 'client' =>array('type'=>'tinyint(4)', 'label'=>'Client', 'enabled'=>1, 'visible'=>-1, 'position'=>240), 'fournisseur' =>array('type'=>'tinyint(4)', 'label'=>'Fournisseur', 'enabled'=>1, 'visible'=>-1, 'position'=>245), From 524b001f3b565e5741c75f347f3e2a73a7ad864d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 Apr 2022 21:14:35 +0200 Subject: [PATCH 47/78] Add $dolibarr_main_restrict_os_commands in security center. --- htdocs/admin/system/security.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 40656928824..8a480ea49ca 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -266,10 +266,20 @@ print '
'; print '$dolibarr_main_restrict_ip: '; if (empty($dolibarr_main_restrict_ip)) { - print ''.$langs->trans("None").''; + print $langs->trans("None"); //print ' ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("IPsOfUsers")).')'; +} else { + print $dolibarr_main_restrict_ip; } +print '
'; +print '$dolibarr_main_restrict_os_commands: '; +if (empty($dolibarr_main_restrict_os_commands)) { + print $langs->trans("None"); +} else { + print $dolibarr_main_restrict_os_commands; +} +print ' ('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore').')'; print '
'; if (empty($conf->global->SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF)) { From ed1bdd26dbbf1e3b20ba3483d212df5358ac0435 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 00:09:11 +0200 Subject: [PATCH 48/78] Rename some jobs --- htdocs/core/modules/modFacture.class.php | 4 ++-- htdocs/core/modules/modFournisseur.class.php | 4 ++-- htdocs/install/mysql/migration/15.0.0-16.0.0.sql | 3 +++ htdocs/langs/en_US/bills.lang | 2 ++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index b64ecca6cc1..817fa1b53cf 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -113,7 +113,7 @@ class modFacture extends DolibarrModules $datestart = dol_mktime(23, 0, 0, $arraydate['mon'], $arraydate['mday'], $arraydate['year']); $this->cronjobs = array( 0 => array( - 'label'=>'RecurringInvoices', + 'label'=>'RecurringInvoicesJob', 'jobtype'=>'method', 'class'=>'compta/facture/class/facture-rec.class.php', 'objectname'=>'FactureRec', @@ -122,7 +122,7 @@ class modFacture extends DolibarrModules 'comment'=>'Generate recurring invoices', 'frequency'=>1, 'unitfrequency'=>3600 * 24, - 'priority'=>50, + 'priority'=>51, 'status'=>1, 'test'=>'$conf->facture->enabled', 'datestart'=>$datestart diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 708cd1fb408..aef28514c61 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -133,7 +133,7 @@ class modFournisseur extends DolibarrModules $datestart = dol_mktime(23, 0, 0, $arraydate['mon'], $arraydate['mday'], $arraydate['year']); $this->cronjobs = array( 0 => array( - 'label'=>'RecurringSupplierInvoices', + 'label'=>'RecurringSupplierInvoicesJob', 'jobtype'=>'method', 'class'=>'fourn/class/fournisseur.facture-rec.class.php', 'objectname'=>'FactureFournisseurRec', @@ -142,7 +142,7 @@ class modFournisseur extends DolibarrModules 'comment'=>'Generate recurring supplier invoices', 'frequency'=>1, 'unitfrequency'=>3600 * 24, - 'priority'=>50, + 'priority'=>51, 'status'=>1, 'datestart'=>$datestart )); diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index fdb34f2191e..7aa4ff82e4b 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -99,6 +99,9 @@ ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_member (fk_type, fk_m -- v16 +UPDATE llx_cronjob set label = 'RecurringInvoicesJob' where label = 'RecurringInvoices'; +UPDATE llx_cronjob set label = 'RecurringSupplierInvoicesJob' where label = 'RecurringSupplierInvoices'; + ALTER TABLE llx_facture ADD INDEX idx_facture_datef (datef); ALTER TABLE llx_projet_task_time ADD COLUMN fk_product integer NULL; diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index eada0da8899..a70d2eb8f21 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -283,6 +283,8 @@ RecurringInvoices=Recurring invoices RecurringInvoice=Recurring invoice RepeatableInvoice=Template invoice RepeatableInvoices=Template invoices +RecurringInvoicesJob=Generation of recurring invoices (sales invoices) +RecurringSupplierInvoicesJob=Generation of recurring invoices (purchase invoices) Repeatable=Template Repeatables=Templates ChangeIntoRepeatableInvoice=Convert into template invoice From 35ee6096b6346a489ac9f8434f2248be72b4d52f Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 7 Apr 2022 10:38:46 +0200 Subject: [PATCH 49/78] FIX increased the size of the "note" field --- htdocs/install/mysql/migration/15.0.0-16.0.0.sql | 3 +++ htdocs/install/mysql/tables/llx_actioncomm.sql | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 7aa4ff82e4b..634e17b33b4 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -312,3 +312,6 @@ UPDATE llx_c_availability SET type_duration = 'w', qty = 4 WHERE code = 'AV_4W'; ALTER TABLE llx_boxes_def ADD COLUMN fk_user integer DEFAULT 0 NOT NULL; ALTER TABLE llx_contratdet ADD COLUMN rang integer DEFAULT 0 AFTER info_bits; + +ALTER TABLE llx_actioncomm MODIFY COLUMN note mediumtext; + diff --git a/htdocs/install/mysql/tables/llx_actioncomm.sql b/htdocs/install/mysql/tables/llx_actioncomm.sql index 2f3f7660698..d4d0b65ef25 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.sql @@ -55,7 +55,7 @@ create table llx_actioncomm durationp real, -- planed duration label varchar(255) NOT NULL, -- label/title of event or topic of email - note text, -- private note of event or content of email + note mediumtext, -- private note of event or content of email calling_duration integer, -- when event is a phone call, duration of phone call From 75b74a5fd352c94e51f17fc22fafbf0edda04533 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 7 Apr 2022 10:43:31 +0200 Subject: [PATCH 50/78] FIX : identification new td --- htdocs/core/class/commonobject.class.php | 2 +- htdocs/core/tpl/originproductline.tpl.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 59d6ab59f34..62a8038d4d4 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4948,7 +4948,7 @@ abstract class CommonObject print '
'; } print ''; - print ''; + print ''; print ''; print ''; $i = 0; diff --git a/htdocs/core/tpl/originproductline.tpl.php b/htdocs/core/tpl/originproductline.tpl.php index dfbf2ac3ea4..c19ef7bcf59 100644 --- a/htdocs/core/tpl/originproductline.tpl.php +++ b/htdocs/core/tpl/originproductline.tpl.php @@ -41,7 +41,7 @@ if (!empty($conf->global->PRODUCT_USE_UNITS)) { } print ''; -print ''; +print ''; $selected = 1; if (!empty($selectedLines) && !in_array($this->tpl['id'], $selectedLines)) { From 49a0485427cc0e126fa0eaf50612eb6f2a905e1c Mon Sep 17 00:00:00 2001 From: habot-it Date: Fri, 18 Feb 2022 08:43:36 +0000 Subject: [PATCH 51/78] Add options in function pdf_pagefoot of pdf.lib.php - Revision --- htdocs/core/lib/pdf.lib.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index c79cbbca645..278b1aeb512 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1154,8 +1154,6 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ } } - $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak - // For customize footer if (is_object($hookmanager)) { $parameters = array('line1' => $line1, 'line2' => $line2, 'line3' => $line3, 'line4' => $line4, 'outputlangs'=>$outputlangs); @@ -1171,7 +1169,9 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ // Option for footer background color (without freetext zone) if (!empty($conf->global->PDF_FOOTER_BACKGROUND_COLOR)) { list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d'); + $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b)); + $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak } if ($line) { // Free text @@ -1196,7 +1196,9 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $posy -= $conf->global->PDF_FOOTER_TOP_MARGIN; } else { $posy--; } + if ($conf->global->PDF_FOOTER_DISABLE_PAGEBREAK === '1') { $pdf->SetAutoPageBreak(0, 0); } // Option for disable auto pagebreak $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0)); + if ($conf->global->PDF_FOOTER_DISABLE_PAGEBREAK === '1') { $pdf->SetAutoPageBreak(1, 0); } // Restore pagebreak $posy -= $mycustomfooterheight - 3; } else { @@ -1207,7 +1209,9 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ // Option for footer background color (without freetext zone) if (!empty($conf->global->PDF_FOOTER_BACKGROUND_COLOR)) { list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d'); + $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b)); + $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak } if ($line) { // Free text @@ -1267,8 +1271,6 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $pdf->MultiCell(15, 2, $pdf->PageNo().'/'.$pdf->getAliasNbPages(), 0, 'R', 0); } - $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak - return $marginwithfooter; } From 4693ef42bd10a4d64df843357a20c4c35ca2d9d1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 11:18:56 +0200 Subject: [PATCH 52/78] Enhance responsive --- htdocs/comm/propal/card.php | 2 ++ htdocs/commande/card.php | 2 ++ htdocs/compta/facture/card.php | 2 ++ htdocs/fichinter/card.php | 2 ++ htdocs/fourn/commande/card.php | 2 ++ htdocs/fourn/facture/card.php | 2 ++ htdocs/supplier_proposal/card.php | 2 ++ 7 files changed, 14 insertions(+) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 10903ea3556..d73a9769d17 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1892,11 +1892,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
'; print '
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . ' 
'.$langs->trans('Unit').''.$langs->trans('ReductionShort').''.$langs->trans('TotalHT').''.$langs->trans('TotalHT').''.$form->showCheckAddButtons('checkforselect', 1).'
'.$this->tpl['remise_percent'].''.$this->tpl['total_ht'].''.$this->tpl['total_ht'].'
'; $objectsrc->printOriginLinesList(); print '
'; + print ''; } } elseif ($object->id > 0) { /* diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index e8f88800693..b54784a82b2 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1862,11 +1862,13 @@ if ($action == 'create' && $usercancreate) { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
'; print ''; $objectsrc->printOriginLinesList('', $selectedLines); print '
'; + print '
'; } print ''; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 102e0cf7f4a..2273fc27c3b 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3815,11 +3815,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
'; print ''; $objectsrc->printOriginLinesList('', $selectedLines); print '
'; + print '
'; } print "\n"; diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 80f39e17730..0d7e5278a14 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1003,11 +1003,13 @@ if ($action == 'create') { $title = $langs->trans('Services'); print load_fiche_titre($title); + print '
'; print ''; $objectsrc->printOriginLinesList(empty($conf->global->FICHINTER_PRINT_PRODUCTS) ? 'services' : ''); // Show only service, except if option FICHINTER_PRINT_PRODUCTS is on print '
'; + print '
'; } print ''; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index b71ba0de941..d895e688080 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1840,11 +1840,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
'; print ''; $objectsrc->printOriginLinesList('', $selectedLines); print '
'; + print '
'; } print "\n"; } elseif (!empty($object->id)) { diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index f4d628d5882..37bcd3199c5 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -2557,11 +2557,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
'; print ''; $objectsrc->printOriginLinesList('', $selectedLines); print '
'; + print '
'; } print "\n"; diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index f0594b90b6f..077300f9386 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1425,11 +1425,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
'; print ''; $objectsrc->printOriginLinesList(); print '
'; + print '
'; } } else { /* From 5e8f632a9ba8393f44b57a6b0cf5a986f275df12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 11:22:28 +0200 Subject: [PATCH 53/78] Close #20571 --- htdocs/install/mysql/data/llx_c_paiement.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/data/llx_c_paiement.sql b/htdocs/install/mysql/data/llx_c_paiement.sql index e29b47639f2..400e2f24276 100644 --- a/htdocs/install/mysql/data/llx_c_paiement.sql +++ b/htdocs/install/mysql/data/llx_c_paiement.sql @@ -30,6 +30,7 @@ -- Types paiement -- +-- Payment modes insert into llx_c_paiement (id,code,libelle,type,active) values ( 1, 'TIP', 'TIP', 2, 0); insert into llx_c_paiement (id,code,libelle,type,active) values ( 2, 'VIR', 'Transfer', 2, 1); insert into llx_c_paiement (id,code,libelle,type,active) values ( 3, 'PRE', 'Debit order', 2, 1); @@ -40,8 +41,10 @@ insert into llx_c_paiement (id,code,libelle,type,active) values (50, 'VAD', 'Onl insert into llx_c_paiement (id,code,libelle,type,active) values (51, 'TRA', 'Traite', 2, 0); insert into llx_c_paiement (id,code,libelle,type,active) values (52, 'LCR', 'LCR', 2, 0); insert into llx_c_paiement (id,code,libelle,type,active) values (53, 'FAC', 'Factor', 2, 0); +-- Payment services INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (100, 'KLA', 'Klarna', 1, 0); INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (101, 'SOF', 'Sofort', 1, 0); INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (102, 'BAN', 'Bancontact', 1, 0); INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (103, 'IDE', 'iDeal', 1, 0); INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (104, 'GIR', 'Giropay', 1, 0); +INSERT INTO llx_c_paiement (id,code,libelle,type,active) values (105, 'PPL', 'PayPal', 1, 0); From 93777f81f367d085c6a7a3f6edc0faab5ab72e3c Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Thu, 7 Apr 2022 11:23:27 +0200 Subject: [PATCH 54/78] NEW : identification tr by data-id --- htdocs/core/tpl/originproductline.tpl.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/tpl/originproductline.tpl.php b/htdocs/core/tpl/originproductline.tpl.php index c19ef7bcf59..55d385fcd50 100644 --- a/htdocs/core/tpl/originproductline.tpl.php +++ b/htdocs/core/tpl/originproductline.tpl.php @@ -1,6 +1,7 @@ * Copyright (C) 2017 Charlie Benke + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,7 +27,7 @@ if (empty($conf) || !is_object($conf)) { tpl['strike']) ? '' : ' strikefordisabled').'">'; +print ''; print ''.$this->tpl['label'].''; print ''.$this->tpl['description'].''; print ''.$this->tpl['vat_rate'].''; From 06f8af71effc40ba3b04a2c6ebacda1839bbb4d2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 11:24:39 +0200 Subject: [PATCH 55/78] Code comment --- htdocs/install/mysql/data/llx_c_paiement.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/install/mysql/data/llx_c_paiement.sql b/htdocs/install/mysql/data/llx_c_paiement.sql index 400e2f24276..a266070da2b 100644 --- a/htdocs/install/mysql/data/llx_c_paiement.sql +++ b/htdocs/install/mysql/data/llx_c_paiement.sql @@ -37,6 +37,7 @@ insert into llx_c_paiement (id,code,libelle,type,active) values ( 3, 'PRE', 'Deb insert into llx_c_paiement (id,code,libelle,type,active) values ( 4, 'LIQ', 'Cash', 2, 1); insert into llx_c_paiement (id,code,libelle,type,active) values ( 6, 'CB', 'Credit card', 2, 1); insert into llx_c_paiement (id,code,libelle,type,active) values ( 7, 'CHQ', 'Cheque', 2, 1); +-- Alternative not common payment modes insert into llx_c_paiement (id,code,libelle,type,active) values (50, 'VAD', 'Online payment', 2, 0); insert into llx_c_paiement (id,code,libelle,type,active) values (51, 'TRA', 'Traite', 2, 0); insert into llx_c_paiement (id,code,libelle,type,active) values (52, 'LCR', 'LCR', 2, 0); From a4b9883eac9a6dbdaf5a967be042cbbf2bd53fd9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 13:14:51 +0200 Subject: [PATCH 56/78] Use checkbox instead of combo to save clicks when adding a resource --- htdocs/core/tpl/resource_add.tpl.php | 25 ++++++++++++++++++------- htdocs/resource/element_resource.php | 17 ++++++++++++----- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php index 64d545ba583..5e605337c0c 100644 --- a/htdocs/core/tpl/resource_add.tpl.php +++ b/htdocs/core/tpl/resource_add.tpl.php @@ -13,9 +13,11 @@ require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; $form = new Form($db); $formresources = new FormResource($db); -$out = '
'; +$out = ''; -$out .= '
'; +$out .= '
'; + +$out .= ''; $out .= ''; $out .= ''; $out .= ''; @@ -23,21 +25,30 @@ $out .= ''; $out .= ''; $out .= ''; +$out .= '
'; // Place -$out .= '
'.$langs->trans("SelectResource").'
'; -$out .= '
'; +$out .= '
'.$langs->trans("SelectResource").'
'; +$out .= '
'; $events = array(); $out .= $formresources->select_resource_list('', 'fk_resource', '', 1, 1, 0, $events, '', 2, null); $out .= '
'; -$out .= '
'.$form->selectyesno('busy', (GETPOSTISSET('busy') ? GETPOST('busy') : 1), 1).'
'; -$out .= '
'.$form->selectyesno('mandatory', (GETPOSTISSET('mandatory') ? GETPOST('mandatory') : 0), 1).'
'; +$out .= '
'; +//$out .= $form->selectyesno('busy', (GETPOSTISSET('busy') ? GETPOST('busy') : 1), 1); +$out .= ''; +$out .= '
'; +$out .= '
'; +//$out .= $form->selectyesno('mandatory', (GETPOSTISSET('mandatory') ? GETPOST('mandatory') : 0), 1); +$out .= ''; +$out .= '
'; -$out .= '
'; +$out .= '
'; $out .= ''; $out .= '
'; +$out .= '
'; + $out .= ''; $out .= '
'; diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index 068dba8c50a..f4c6f3d3856 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -46,10 +46,6 @@ $sortfield = GETPOST('sortfield','alpha'); $page = GETPOST('page','int'); */ -if (!$user->rights->resource->read) { - accessforbidden(); -} - $object = new Dolresource($db); $hookmanager->initHooks(array('element_resource')); @@ -71,11 +67,22 @@ $cancel = GETPOST('cancel', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); $socid = GETPOST('socid', 'int'); +if (empty($mandatory)) { + $mandatory = 0; +} +if (empty($busy)) { + $busy = 0; +} + if ($socid > 0) { // Special for thirdparty $element_id = $socid; $element = 'societe'; } +if (!$user->rights->resource->read) { + accessforbidden(); +} + // Permission is not permission on resources. We just make link here on objects. if ($element == 'action') { $result = restrictedArea($user, 'agenda', $element_id, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id'); @@ -365,7 +372,7 @@ if (!$ret) { print '
'; - print ''; + print '
'; // Type if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) { From 485e163cf6df25570c010bd30a88ad1418bd7c17 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 13:16:51 +0200 Subject: [PATCH 57/78] default value --- htdocs/core/tpl/resource_add.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php index 5e605337c0c..02bc8ce421f 100644 --- a/htdocs/core/tpl/resource_add.tpl.php +++ b/htdocs/core/tpl/resource_add.tpl.php @@ -40,7 +40,7 @@ $out .= 'trans('Mandatory').' '; //$out .= $form->selectyesno('mandatory', (GETPOSTISSET('mandatory') ? GETPOST('mandatory') : 0), 1); -$out .= ''; +$out .= ''; $out .= ''; $out .= '
'; From 0ed7c643f88886c3820110f0a01b2df01a541f8d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 13:28:24 +0200 Subject: [PATCH 58/78] Close #20547 --- htdocs/comm/action/class/actioncomm.class.php | 32 +++++++++++++++++-- htdocs/core/actions_sendmails.inc.php | 8 ++--- ...terface_50_modAgenda_ActionsAuto.class.php | 4 ++- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index a5b4f1d8ce9..f93f5aeccb7 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -868,6 +868,16 @@ class ActionComm extends CommonObject $this->event_paid = $obj->event_paid; $this->status = $obj->status; + //email information + $this->email_msgid=$obj->email_msgid; + $this->email_from=$obj->email_from; + $this->email_sender=$obj->email_sender; + $this->email_to=$obj->email_to; + $this->email_tocc=$obj->email_tocc; + $this->email_tobcc=$obj->email_tobcc; + $this->email_subject=$obj->email_subject; + $this->errors_to=$obj->errors_to; + $this->fetch_optionals(); if ($loadresources) { @@ -1582,8 +1592,25 @@ class ActionComm extends CommonObject if (isset($this->transparency)) { $tooltip .= '
'.$langs->trans('Busy').': '.yn($this->transparency); } + if (!empty($this->email_msgid)) { + $langs->load("mails"); + $tooltip .= '
'; + //$tooltip .= '
'.img_picto('', 'email').' '.$langs->trans("Email").''; + $tooltip .= '
'.$langs->trans('MailTopic').': '.$this->email_subject; + $tooltip .= '
'.$langs->trans('MailFrom').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_from); + $tooltip .= '
'.$langs->trans('MailTo').':, '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_to); + if (!empty($this->email_tocc)) { + $tooltip .= '
'.$langs->trans('MailCC').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_tocc); + } + /* Disabled because bcc must remain by defintion not visible + if (!empty($this->email_tobcc)) { + $tooltip .= '
'.$langs->trans('MailCCC').': '.$this->email_tobcc; + } */ + } if (!empty($this->note_private)) { - $tooltip .= '
'.$langs->trans('Note').': '.(dol_textishtml($this->note_private) ? str_replace(array("\r", "\n"), "", $this->note_private) : str_replace(array("\r", "\n"), '
', $this->note_private)); + $tooltip .= '

'.$langs->trans('Description').':
'; + $texttoshow = dolGetFirstLineOfText($this->note_private, 10); + $tooltip .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '
', $texttoshow)); } $linkclose = ''; //if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color) @@ -1594,9 +1621,8 @@ class ActionComm extends CommonObject $label = $langs->trans("ShowAction"); $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1).'"'; + $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1, 0, 0, '', 1).'"'; $linkclose .= ' class="'.$classname.' classfortooltip"'; - /* $hookmanager->initHooks(array('actiondao')); $parameters=array('id'=>$this->id); diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index d31f8d60dfc..f0ef66eb78b 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -109,7 +109,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO } $subject = ''; - $actionmsg = ''; + //$actionmsg = ''; $actionmsg2 = ''; $langs->load('mails'); @@ -317,7 +317,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO if ($action == 'send' || $action == 'relance') { $actionmsg2 = $langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($from, 4, 0, 1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($sendto, 4, 0, 1); - if ($message) { + /*if ($message) { $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from); $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto)); if ($sendtocc) { @@ -326,7 +326,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); $actionmsg = dol_concatdesc($actionmsg, $message); - } + }*/ } // Create form object @@ -376,7 +376,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO $object->socid = $sendtosocid; // To link to a company $object->sendtoid = $sendtoid; // To link to contact-addresses. This is an array. $object->actiontypecode = $actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...) - $object->actionmsg = $actionmsg; // Long text (@todo Replace this with $message, we already have details of email in dedicated properties) + $object->actionmsg = $message; // Long text $object->actionmsg2 = $actionmsg2; // Short text ($langs->transnoentities('MailSentBy')...); $object->trackid = $trackid; diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index 2ff5d3f9c43..cf6a8220c29 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -958,11 +958,13 @@ class InterfaceActionsAuto extends DolibarrTriggers } } + /* Seems no more required: We have the data in dedicated field now. if (!empty($user->login)) { $object->actionmsg = dol_concatdesc($langs->transnoentities("Author").': '.$user->login, $object->actionmsg); } elseif (isset($object->origin_email)) { $object->actionmsg = dol_concatdesc($langs->transnoentities("Author").': '.$object->origin_email, $object->actionmsg); } + */ dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); @@ -1019,7 +1021,7 @@ class InterfaceActionsAuto extends DolibarrTriggers $actioncomm->type_code = $object->actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...) $actioncomm->code = 'AC_'.$action; $actioncomm->label = $object->actionmsg2; - $actioncomm->note_private = $object->actionmsg; // TODO Replace with ($actioncomm->email_msgid ? $object->email_content : $object->actionmsg) + $actioncomm->note_private = $object->actionmsg; $actioncomm->fk_project = $projectid; $actioncomm->datep = $now; $actioncomm->datef = $now; From 4cac6b7e29e36f44f0dfa37a90b86179237c25f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 14:03:14 +0200 Subject: [PATCH 59/78] css --- htdocs/compta/facture/card.php | 8 ++++---- htdocs/core/tpl/contacts.tpl.php | 2 +- htdocs/langs/en_US/companies.lang | 2 +- htdocs/theme/eldy/global.inc.php | 12 +++++++----- htdocs/theme/md/style.css.php | 17 +++++++++++------ 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 2273fc27c3b..9956fd32b97 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3522,7 +3522,7 @@ if ($action == 'create') { if ($socid > 0) { // Discounts for third party - print '
'; + print '"; - //} if (!empty($conf->global->THIRDPARTY_SUGGEST_ALSO_ADDRESS_CREATION)) { print ''; print ''; print ''; - // Parent company - if (empty($conf->global->SOCIETE_DISABLE_PARENTCOMPANY)) { - print ''; - print ''; - print ''; - } - // Prospect/Customer print ''; print ''; + print ''; + print ''; + } + // Assign a sale representative print ''; print ''; diff --git a/htdocs/theme/eldy/dropdown.inc.php b/htdocs/theme/eldy/dropdown.inc.php index 242250c8835..2bb2f61375b 100644 --- a/htdocs/theme/eldy/dropdown.inc.php +++ b/htdocs/theme/eldy/dropdown.inc.php @@ -21,8 +21,8 @@ button.dropdown-item.global-search-item { } #topmenu-bookmark-dropdown .dropdown-menu { - min-width: 300px; - max-width: 360px; + min-width: 360px; + max-width: 400px; } @@ -499,4 +499,9 @@ div.quickaddblock:focus { margin-left: 5px; right: 0; } + + #topmenu-bookmark-dropdown .dropdown-menu { + min-width: 280px; + max-width: 360px; + } } From 96c866400f5ef23e07b87e2990ecf3b9bf7d4487 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 16:05:55 +0200 Subject: [PATCH 66/78] css --- htdocs/contact/card.php | 4 ++-- htdocs/societe/card.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 229bfc0530b..ee1d10181ca 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -624,7 +624,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { */ $object->canvas = $canvas; - $object->state_id = GETPOST("state_id"); + $object->state_id = GETPOST("state_id", "int"); // We set country_id, country_code and label for the selected country $object->country_id = GETPOST("country_id") ? GETPOST("country_id", "int") : (empty($objsoc->country_id) ? $mysoc->country_id : $objsoc->country_id); @@ -697,7 +697,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; } else { print ''; } } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 37ac9805374..a8b2fb151c6 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1671,7 +1671,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; print ''; } From fc7a4dba4a3eff50248bf1abf87b146be5b6b9e1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 16:26:22 +0200 Subject: [PATCH 67/78] Removed not up to date notices --- README.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/README.md b/README.md index 0d0e2d89d00..b227b16ccba 100644 --- a/README.md +++ b/README.md @@ -220,15 +220,7 @@ These are features that Dolibarr does **not** yet fully support: - Payroll module - No native embedded Webmail, but you can send email to contacts in Dolibarr with e.g. offers, invoices, etc. - Dolibarr can't do coffee (yet) -- The REST API currently cannot: - - Add new ledger entry [#14675](https://github.com/Dolibarr/dolibarr/issues/14675) - - Get virtual products (aka lots) [#14457](https://github.com/Dolibarr/dolibarr/issues/14457) - - Add special taxcodes to a line on a supplier invoice (vat_src_code) [#14404](https://github.com/Dolibarr/dolibarr/issues/14404) - - Get or post shipments on customer orders [#18074](https://github.com/Dolibarr/dolibarr/issues/18074) - - Get or post shipments on supplier orders [#14334](https://github.com/Dolibarr/dolibarr/issues/14334) - - Add an image to a product [#14262](https://github.com/Dolibarr/dolibarr/issues/14262) - - Add multiprices to products [#12812](https://github.com/Dolibarr/dolibarr/issues/12812) - +- ## DOCUMENTATION From a120f6552125dd96fd07857b0e86f2b2252d6576 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 16:32:03 +0200 Subject: [PATCH 68/78] FIX country not visible into list of states --- htdocs/core/class/html.formcompany.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index fbaee3331c5..f976fac978d 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -406,7 +406,7 @@ class FormCompany extends Form // Show break $key = $langs->trans("Country".strtoupper($obj->country_code)); $valuetoshow = ($key != "Country".strtoupper($obj->country_code)) ? $obj->country_code." - ".$key : $obj->country; - print '\n"; + print '\n"; $country = $obj->country; } From f884137433c42a8d10ed1c0d766973be263e0e35 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 17:12:17 +0200 Subject: [PATCH 69/78] Forgot to update the COPYRIGHT 4 days ago after jqquery upgrade. --- COPYRIGHT | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index a5e1f4a4005..a2101a1db0a 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -50,8 +50,8 @@ TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes JS libraries: Ace 1.4.14 BSD Yes JS library to get code syntaxique coloration in a textarea. ChartJS 3.7.1 MIT License Yes JS library for graph -jQuery 3.5.1 MIT License Yes JS library -jQuery UI 1.12.1 GPL and MIT License Yes JS library plugin UI +jQuery 3.6.0 MIT License Yes JS library +jQuery UI 1.13.1 GPL and MIT License Yes JS library plugin UI jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect. Warning: 4.0.6+ create troubles without patching css jQuery blockUI 2.70.0 GPL and MIT License Yes JS library plugin blockUI (to use ajax popups) jQuery Colorpicker 1.1 MIT License Yes JS library for color picker for a defined list of colors From 746cec015b77341a4e80084e4a7132523bd68913 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 17:50:18 +0200 Subject: [PATCH 70/78] Fix remove warning on chartjs 3.5 --- htdocs/core/class/dolgraph.class.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index b46ca096547..488becd06b7 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -1303,11 +1303,13 @@ class DolGraph $this->stringtoshow .= $xaxis; /* For Chartjs v2.9 */ + /* if (empty($showlegend)) { $this->stringtoshow .= 'legend: { display: false }, '."\n"; } else { $this->stringtoshow .= 'legend: { maxWidth: '.round($this->width / 2).', labels: { boxWidth: 15 }, position: \'' . ($showlegend == 2 ? 'right' : 'top') . '\' }, '."\n"; } + */ /* For Chartjs v3.5 */ $this->stringtoshow .= 'plugins: { '."\n"; @@ -1318,7 +1320,9 @@ class DolGraph } $this->stringtoshow .= "}, \n"; - $this->stringtoshow .= 'scales: { xAxes: [{ '; + /* For Chartjs v2.9 */ + /* + $this->stringtoshow .= 'scales: { xAxis: [{ '; if ($this->hideXValues) { $this->stringtoshow .= ' ticks: { display: false }, display: true,'; } @@ -1328,11 +1332,12 @@ class DolGraph $this->stringtoshow .= ', stacked: true'; } $this->stringtoshow .= ' }]'; - $this->stringtoshow .= ', yAxes: [{ ticks: { beginAtZero: true }'; + $this->stringtoshow .= ', yAxis: [{ ticks: { beginAtZero: true }'; if ($type == 'bar' && count($arrayofgroupslegend) > 0) { $this->stringtoshow .= ', stacked: true'; } $this->stringtoshow .= ' }] }'; + */ // Add a callback to change label to show only positive value if (is_array($this->tooltipsLabels) || is_array($this->tooltipsTitles)) { From cbae64f9aab1b3a15dae9d2265cb64c643917e1d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 17:51:38 +0200 Subject: [PATCH 71/78] FIX Add a hack to fix a bug in jquery 3.6.0/select 2 --- htdocs/core/js/lib_head.js.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index 5d47fa5f605..3fe6dee8820 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -1198,4 +1198,22 @@ $(document).ready(function() { } }); + +/* + * Hacky fix for a bug in select2 with jQuery 3.6.0's new nested-focus "protection" + * see: https://github.com/select2/select2/issues/5993 + * see: https://github.com/jquery/jquery/issues/4382 + * + * TODO: Recheck with the select2 GH issue and remove once this is fixed on their side + */ +$(document).on('select2:open', () => { + console.log("Execute the focus (click on combo or use space when on component"); + let allFound = document.querySelectorAll('.select2-container--open .select2-search__field'); + $(this).one('mouseup keyup',()=>{ + setTimeout(()=>{ + allFound[allFound.length - 1].focus(); + },0); + }); +}); + // End of lib_head.js.php From baa4608812230ad89a6e0db5574350afa3ebb8f1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 18:16:06 +0200 Subject: [PATCH 72/78] Debug v16 --- htdocs/adherents/list.php | 14 ++++++-------- htdocs/holiday/list.php | 15 +++++++++------ htdocs/hrm/index.php | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 996f2d16c8d..e58def3f481 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -505,7 +505,7 @@ if (GETPOSTISSET("search_status")) { if ($search_type > 0) { $membertype = new AdherentType($db); - $result = $membertype->fetch(GETPOST("type", 'int')); + $result = $membertype->fetch($search_type); $titre .= " (".$membertype->label.")"; } @@ -767,7 +767,7 @@ if (!empty($arrayfields['d.email']['checked'])) { } // End of subscription date if (!empty($arrayfields['d.datefin']['checked'])) { - print ''; @@ -858,7 +858,7 @@ if (!empty($arrayfields['state.nom']['checked'])) { print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['country.code_iso']['checked'])) { - print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, '', $sortfield, $sortorder, 'center '); } if (!empty($arrayfields['d.phone']['checked'])) { print_liste_field_titre($arrayfields['d.phone']['label'], $_SERVER["PHP_SELF"], 'd.phone', '', $param, '', $sortfield, $sortorder); @@ -873,7 +873,7 @@ if (!empty($arrayfields['d.email']['checked'])) { print_liste_field_titre($arrayfields['d.email']['label'], $_SERVER["PHP_SELF"], 'd.email', '', $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['d.datefin']['checked'])) { - print_liste_field_titre($arrayfields['d.datefin']['label'], $_SERVER["PHP_SELF"], 'd.datefin', '', $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['d.datefin']['label'], $_SERVER["PHP_SELF"], 'd.datefin', '', $param, '', $sortfield, $sortorder, 'center '); } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; @@ -1110,16 +1110,14 @@ while ($i < min($num, $limit)) { // End of subscription date $datefin = $db->jdate($obj->datefin); if (!empty($arrayfields['d.datefin']['checked'])) { + print ''; } else { - print ''; } + print ''; } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index b4985100e44..bcae536f720 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -721,7 +721,7 @@ if ($resql) { if (!empty($arrayfields['cp.statut']['checked'])) { print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "cp.statut", "", $param, '', $sortfield, $sortorder, 'right '); } - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch center '); print "\n"; $listhalfday = array('morning'=>$langs->trans("Morning"), "afternoon"=>$langs->trans("Afternoon")); @@ -789,21 +789,23 @@ if ($resql) { } } if (!empty($arrayfields['cp.fk_user']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } } if (!empty($arrayfields['cp.fk_validator']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } } if (!empty($arrayfields['cp.fk_type']['checked'])) { - print ''; if (!$i) { $totalarray['nbfield']++; @@ -813,7 +815,8 @@ if ($resql) { print ''; if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index 2603d73ab81..84e336c9b97 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -235,7 +235,7 @@ if (!empty($conf->holiday->enabled) && $user->rights->holiday->read) { print ''; print ''; - print ''; + print ''; print ''; $starthalfday = ($obj->halfday == -1 || $obj->halfday == 2) ? 'afternoon' : 'morning'; From 0e36097eba04d730554d05b7ce9ef7a9053e0f1a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 19:16:50 +0200 Subject: [PATCH 73/78] Save result of some methods into cached properties. --- htdocs/core/class/commoninvoice.class.php | 37 ++++++++++++++++++----- htdocs/core/class/discount.class.php | 6 ++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index eedc1b2fa10..e49f8a6a728 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -93,6 +93,14 @@ abstract class CommonInvoice extends CommonObject const STATUS_ABANDONED = 3; + public $sumpayed; + public $sumpayed_multicurrency; + public $sumdeposit; + public $sumdeposit_multicurrency; + public $sumcreditnote; + public $sumcreditnote_multicurrency; + + /** * Return remain amount to pay. Property ->id and ->total_ttc must be set. * This does not include open direct debit requests. @@ -118,8 +126,8 @@ abstract class CommonInvoice extends CommonObject * Return amount of payments already done. This must include ONLY the record into the payment table. * Payments dones using discounts, credit notes, etc are not included. * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float Amount of payment already done, <0 if KO + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float Amount of payment already done, <0 and set ->error if KO */ public function getSommePaiement($multicurrency = 0) { @@ -138,10 +146,13 @@ abstract class CommonInvoice extends CommonObject $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); + $this->db->free($resql); if ($multicurrency) { + $this->sumpayed_multicurrency = $obj->multicurrency_amount; return $obj->multicurrency_amount; } else { + $this->sumpayed = $obj->amount; return $obj->amount; } } else { @@ -154,13 +165,13 @@ abstract class CommonInvoice extends CommonObject * Return amount (with tax) of all deposits invoices used by invoice. * Should always be empty, except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is on (not recommended). * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float <0 if KO, Sum of deposits amount otherwise + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float <0 and set ->error if KO, Sum of deposits amount otherwise */ public function getSumDepositsUsed($multicurrency = 0) { if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') { - // TODO + // FACTURE_DEPOSITS_ARE_JUST_PAYMENTS was never supported for purchase invoice, so we can return 0 with no need of SQL for this case. return 0.0; } @@ -170,6 +181,12 @@ abstract class CommonInvoice extends CommonObject $result = $discountstatic->getSumDepositsUsed($this, $multicurrency); if ($result >= 0) { + if ($multicurrency) { + $this->sumdeposit_multicurrency = $result; + } else { + $this->sumdeposit = $result; + } + return $result; } else { $this->error = $discountstatic->error; @@ -180,8 +197,8 @@ abstract class CommonInvoice extends CommonObject /** * Return amount (with tax) of all credit notes invoices + excess received used by invoice * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float <0 if KO, Sum of credit notes and deposits amount otherwise + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float <0 and set ->error if KO, Sum of credit notes and deposits amount otherwise */ public function getSumCreditNotesUsed($multicurrency = 0) { @@ -190,6 +207,12 @@ abstract class CommonInvoice extends CommonObject $discountstatic = new DiscountAbsolute($this->db); $result = $discountstatic->getSumCreditNotesUsed($this, $multicurrency); if ($result >= 0) { + if ($multicurrency) { + $this->sumcreditnote_multicurrency = $result; + } else { + $this->sumcreditnote = $result; + } + return $result; } else { $this->error = $discountstatic->error; diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index bdc5e746566..dff1383a629 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -562,7 +562,7 @@ class DiscountAbsolute * Should always be empty, except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is on (not recommended). * * @param CommonInvoice $invoice Object invoice (customer of supplier) - * @param int $multicurrency 1=Return multicurrency_amount instead of amount + * @param int $multicurrency 1=Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount * @return int <0 if KO, Sum of credit notes and deposits amount otherwise */ public function getSumDepositsUsed($invoice, $multicurrency = 0) @@ -603,7 +603,7 @@ class DiscountAbsolute * Return amount (with tax) of all credit notes invoices + excess received used by invoice as a payment * * @param CommonInvoice $invoice Object invoice - * @param int $multicurrency 1=Return multicurrency_amount instead of amount + * @param int $multicurrency 1=Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount * @return int <0 if KO, Sum of credit notes and excess received amount otherwise */ public function getSumCreditNotesUsed($invoice, $multicurrency = 0) @@ -643,7 +643,7 @@ class DiscountAbsolute * Return amount (with tax) of all converted amount for this credit note * * @param CommonInvoice $invoice Object invoice - * @param int $multicurrency Return multicurrency_amount instead of amount + * @param int $multicurrency Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount * @return int <0 if KO, Sum of credit notes and deposits amount otherwise */ public function getSumFromThisCreditNotesNotUsed($invoice, $multicurrency = 0) From e66b4a687dd3286b38b80ae3ff5cd28d0bc514b8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 19:23:45 +0200 Subject: [PATCH 74/78] Close #19414 --- htdocs/core/lib/functions.lib.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a9739989c41..50d0e8ee9e3 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7470,13 +7470,23 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__DATE_YMD__'] = is_object($object) ? (isset($object->date) ? dol_print_date($object->date, 'day', 0, $outputlangs) : null) : ''; $substitutionarray['__DATE_DUE_YMD__'] = is_object($object) ? (isset($object->date_lim_reglement) ? dol_print_date($object->date_lim_reglement, 'day', 0, $outputlangs) : null) : ''; + $already_payed_all = 0; + if (is_object($object) && ($object instanceof Facture)) { + $already_payed_all = $object->sumpayed + $object->sumdeposit + $object->sumcreditnote; + } + + $substitutionarray['__AMOUNT_EXCL_TAX__'] = is_object($object) ? $object->total_ht : ''; + $substitutionarray['__AMOUNT__'] = is_object($object) ? $object->total_ttc : ''; $substitutionarray['__AMOUNT_TEXT__'] = is_object($object) ? dol_convertToWord($object->total_ttc, $outputlangs, '', true) : ''; $substitutionarray['__AMOUNT_TEXTCURRENCY__'] = is_object($object) ? dol_convertToWord($object->total_ttc, $outputlangs, $conf->currency, true) : ''; - $substitutionarray['__AMOUNT_EXCL_TAX__'] = is_object($object) ? $object->total_ht : ''; + + $substitutionarray['__AMOUNT_REMAIN__'] = is_object($object) ? $object->total_ttc - $already_payed_all : ''; + $substitutionarray['__AMOUNT_VAT__'] = is_object($object) ? (isset($object->total_vat) ? $object->total_vat : $object->total_tva) : ''; $substitutionarray['__AMOUNT_VAT_TEXT__'] = is_object($object) ? (isset($object->total_vat) ? dol_convertToWord($object->total_vat, $outputlangs, '', true) : dol_convertToWord($object->total_tva, $outputlangs, '', true)) : ''; $substitutionarray['__AMOUNT_VAT_TEXTCURRENCY__'] = is_object($object) ? (isset($object->total_vat) ? dol_convertToWord($object->total_vat, $outputlangs, $conf->currency, true) : dol_convertToWord($object->total_tva, $outputlangs, $conf->currency, true)) : ''; + if ($onlykey != 2 || $mysoc->useLocalTax(1)) { $substitutionarray['__AMOUNT_TAX2__'] = is_object($object) ? $object->total_localtax1 : ''; } @@ -7484,8 +7494,10 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__AMOUNT_TAX3__'] = is_object($object) ? $object->total_localtax2 : ''; } - $substitutionarray['__AMOUNT_FORMATED__'] = is_object($object) ? ($object->total_ttc ? price($object->total_ttc, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; + // Amount keys formated in a currency $substitutionarray['__AMOUNT_EXCL_TAX_FORMATED__'] = is_object($object) ? ($object->total_ht ? price($object->total_ht, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; + $substitutionarray['__AMOUNT_FORMATED__'] = is_object($object) ? ($object->total_ttc ? price($object->total_ttc, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; + $substitutionarray['__AMOUNT_REMAIN_FORMATED__'] = is_object($object) ? ($object->total_ttc ? price($object->total_ttc - $already_payed_all, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; $substitutionarray['__AMOUNT_VAT_FORMATED__'] = is_object($object) ? (isset($object->total_vat) ? price($object->total_vat, 0, $outputlangs, 0, -1, -1, $conf->currency) : ($object->total_tva ? price($object->total_tva, 0, $outputlangs, 0, -1, -1, $conf->currency) : null)) : ''; if ($onlykey != 2 || $mysoc->useLocalTax(1)) { $substitutionarray['__AMOUNT_TAX2_FORMATED__'] = is_object($object) ? ($object->total_localtax1 ? price($object->total_localtax1, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; From 3a2815a9c0c4278ab00364a5b95a62bbf4d1be18 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 23:44:57 +0200 Subject: [PATCH 75/78] Debug and clean v16 --- htdocs/core/login/functions_dolibarr.php | 4 ++++ .../install/mysql/migration/15.0.0-16.0.0.sql | 9 ++++++- htdocs/install/mysql/tables/llx_user.sql | 3 +-- htdocs/install/repair.php | 24 ++++++++++++------- htdocs/user/class/user.class.php | 1 + 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/htdocs/core/login/functions_dolibarr.php b/htdocs/core/login/functions_dolibarr.php index 292ce1b44f5..610072aa35a 100644 --- a/htdocs/core/login/functions_dolibarr.php +++ b/htdocs/core/login/functions_dolibarr.php @@ -143,7 +143,11 @@ function check_user_password_dolibarr($usertotest, $passwordtotest, $entitytotes $ret = $mc->checkRight($obj->rowid, $entitytotest); if ($ret < 0) { dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentication KO entity '".$entitytotest."' not allowed for user '".$obj->rowid."'", LOG_NOTICE); + $login = ''; // force authentication failure + if ($mc->db->lasterror()) { + $_SESSION["dol_loginmesg"] = $mc->db->lasterror(); + } } } } diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 634e17b33b4..3aa5cd9c9cd 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -288,9 +288,16 @@ ALTER TABLE llx_bank_account ADD COLUMN pti_in_ctti smallint DEFAULT 0 AFTER dom -- Set default ticket type to OTHER if no default exists UPDATE llx_c_ticket_type SET use_default=1 WHERE code='OTHER' AND NOT EXISTS(SELECT * FROM (SELECT * FROM llx_c_ticket_type) AS t WHERE use_default=1); -ALTER TABLE llx_user ADD COLUMN ref_employee varchar(50) DEFAULT NULL; + +ALTER TABLE llx_user DROP COLUMN webcal_login; +ALTER TABLE llx_user DROP COLUMN module_comm; +ALTER TABLE llx_user DROP COLUMN module_compta; +ALTER TABLE llx_user DROP COLUMN ref_int; + +ALTER TABLE llx_user ADD COLUMN ref_employee varchar(50) DEFAULT NULL AFTER entity; ALTER TABLE llx_user ADD COLUMN national_registration_number varchar(50) DEFAULT NULL; + ALTER TABLE llx_propal ADD last_main_doc VARCHAR(255) NULL AFTER model_pdf; UPDATE llx_c_country SET eec=0 WHERE eec IS NULL; diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index 694ed360b21..ae3715eb028 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -22,8 +22,8 @@ create table llx_user rowid integer AUTO_INCREMENT PRIMARY KEY, entity integer DEFAULT 1 NOT NULL, -- multi company id + ref_employee varchar(50), ref_ext varchar(50), -- reference into an external system (not used by dolibarr) - ref_int varchar(50), -- reference into an internal system (deprecated) admin smallint DEFAULT 0, -- user has admin profile @@ -108,7 +108,6 @@ create table llx_user import_key varchar(14), -- import key default_range integer, default_c_exp_tax_cat integer, - employee_number varchar(50), national_registration_number varchar(50), fk_warehouse integer -- default warehouse os user )ENGINE=innodb; diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 8e4cc851d28..802711f4ff3 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -94,8 +94,8 @@ print 'Option repair_link_dispatch_lines_supplier_order_lines, (\'test\' or \'co // Init data print 'Option set_empty_time_spent_amount (\'test\' or \'confirmed\') is '.(GETPOST('set_empty_time_spent_amount', 'alpha') ?GETPOST('set_empty_time_spent_amount', 'alpha') : 'undefined').'
'."\n"; // Structure -print 'Option force_utf8_on_tables, for mysql/mariadb only (\'test\' or \'confirmed\') is '.(GETPOST('force_utf8_on_tables', 'alpha') ?GETPOST('force_utf8_on_tables', 'alpha') : 'undefined').'
'."\n"; -print "Option force_utf8mb4_on_tables (EXPERIMENTAL!), for mysql/mariadb only ('test' or 'confirmed') is ".(GETPOST('force_utf8mb4_on_tables', 'alpha') ? GETPOST('force_utf8mb4_on_tables', 'alpha') : 'undefined')."
\n"; +print 'Option force_utf8_on_tables (force utf8 + row=dynamic), for mysql/mariadb only (\'test\' or \'confirmed\') is '.(GETPOST('force_utf8_on_tables', 'alpha') ?GETPOST('force_utf8_on_tables', 'alpha') : 'undefined').'
'."\n"; +print "Option force_utf8mb4_on_tables (force utf8mb4 + row=dynamic, EXPERIMENTAL!), for mysql/mariadb only ('test' or 'confirmed') is ".(GETPOST('force_utf8mb4_on_tables', 'alpha') ? GETPOST('force_utf8mb4_on_tables', 'alpha') : 'undefined')."
\n"; // Rebuild sequence print 'Option rebuild_sequences, for postgresql only (\'test\' or \'confirmed\') is '.(GETPOST('rebuild_sequences', 'alpha') ?GETPOST('rebuild_sequences', 'alpha') : 'undefined').'
'."\n"; print '
'; @@ -176,7 +176,8 @@ $oneoptionset = 0; $oneoptionset = (GETPOST('standard', 'alpha') || GETPOST('restore_thirdparties_logos', 'alpha') || GETPOST('clean_linked_elements', 'alpha') || GETPOST('clean_menus', 'alpha') || GETPOST('clean_orphelin_dir', 'alpha') || GETPOST('clean_product_stock_batch', 'alpha') || GETPOST('set_empty_time_spent_amount', 'alpha') || GETPOST('rebuild_product_thumbs', 'alpha') || GETPOST('clean_perm_table', 'alpha') - || GETPOST('force_disable_of_modules_not_found', 'alpha') || GETPOST('force_utf8_on_tables', 'alpha') + || GETPOST('force_disable_of_modules_not_found', 'alpha') + || GETPOST('force_utf8_on_tables', 'alpha') || GETPOST('force_utf8mb4_on_tables', 'alpha') || GETPOST('rebuild_sequences', 'alpha')); if ($ok && $oneoptionset) { @@ -1218,7 +1219,7 @@ if ($ok && GETPOST('clean_perm_table', 'alpha')) { // force utf8 on tables if ($ok && GETPOST('force_utf8_on_tables', 'alpha')) { - print '
'; + print ''; if ($db->type == "mysql" || $db->type == "mysqli") { $force_utf8_on_tables = GETPOST('force_utf8_on_tables', 'alpha'); @@ -1240,11 +1241,18 @@ if ($ok && GETPOST('force_utf8_on_tables', 'alpha')) { print ''; print ''; print ''; - print ''; + + $leavecode = empty($typeleaves[$obj->fk_type]) ? 'Undefined' : $typeleaves[$obj->fk_type]['code']; + print ''; $starthalfday = ($obj->halfday == -1 || $obj->halfday == 2) ? 'afternoon' : 'morning'; $endhalfday = ($obj->halfday == 1 || $obj->halfday == 2) ? 'morning' : 'afternoon'; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index e2d36ab4695..fb04930299b 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -756,6 +756,8 @@ if (!defined('NOLOGIN')) { $login = ''; } + $dol_authmode = ''; + if ($login) { $dol_authmode = $conf->authmode; // This properties is defined only when logged, to say what mode was successfully used $dol_tz = $_POST["tz"]; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index fb9178e1ed0..dc94669d54f 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -312,8 +312,8 @@ print 'dol_hide_topmenu='.$dol_hide_topmenu."\n"; print 'dol_hide_leftmenu='.$dol_hide_leftmenu."\n"; print 'dol_optimize_smallscreen='.$dol_optimize_smallscreen."\n"; print 'dol_no_mouse_hover='.$dol_no_mouse_hover."\n"; -print 'dol_screenwidth='.$_SESSION['dol_screenwidth']."\n"; -print 'dol_screenheight='.$_SESSION['dol_screenheight']."\n"; +print 'dol_screenwidth='.(empty($_SESSION['dol_screenwidth']) ? '' : $_SESSION['dol_screenwidth'])."\n"; +print 'dol_screenheight='.(empty($_SESSION['dol_screenheight']) ? '' : $_SESSION['dol_screenheight'])."\n"; print 'fontsize='.$fontsize."\n"; print 'nbtopmenuentries='.$nbtopmenuentries."\n"; print 'fontsizesmaller='.$fontsizesmaller."\n"; From 1f73f19ff70d09d7a021133dfb82c57720cb643f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 8 Apr 2022 00:42:39 +0200 Subject: [PATCH 78/78] php8 --- htdocs/takepos/index.php | 41 ++++++++++++++++++++++---------------- htdocs/takepos/invoice.php | 7 ++++--- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 31c51a4c7b1..b23907b64f1 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -57,7 +57,7 @@ $action = GETPOST('action', 'aZ09'); $setterminal = GETPOST('setterminal', 'int'); $setcurrency = GETPOST('setcurrency', 'aZ09'); -if ($_SESSION["takeposterminal"] == "") { +if (empty($_SESSION["takeposterminal"])) { if ($conf->global->TAKEPOS_NUM_TERMINALS == "1") { $_SESSION["takeposterminal"] = 1; // Use terminal 1 if there is only 1 terminal } elseif (!empty($_COOKIE["takeposterminal"])) { @@ -114,6 +114,11 @@ $result = restrictedArea($user, 'takepos', 0, ''); $form = new Form($db); +$disablejs = 0; +$disablehead = 0; +$arrayofjs = array(); +$arrayofcss = array(); + // Title $title = 'TakePOS - Dolibarr '.DOL_VERSION; if (!empty($conf->global->MAIN_APPLICATION_TITLE)) { @@ -129,22 +134,22 @@ top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); global->TAKEPOS_COLOR_THEME == 1) { +if (getDolGlobalInt('TAKEPOS_COLOR_THEME') == 1) { print ''; } ?>
'.$langs->trans('Discounts').''; + print '
'.$langs->trans('DiscountStillRemaining').''; $thirdparty = $soc; $discount_type = 0; @@ -4355,8 +4355,8 @@ if ($action == 'create') { // Relative and absolute discounts print ''."\n"; - print '
'.$langs->trans('Discounts'); - print ''; + print '
'.$langs->trans('DiscountStillRemaining').''; $thirdparty = $soc; $discount_type = 0; $backtopage = urlencode($_SERVER["PHP_SELF"].'?facid='.$object->id); @@ -5222,7 +5222,7 @@ if ($action == 'create') { print ''; print ''; - print '

'; + print '


'; if (!empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) { $blocname = 'contacts'; diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index 2dd9751a4c6..5f463e44846 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -259,7 +259,7 @@ $arrayfields = array( 'rowid' => array('label'=>$langs->trans("Id"), 'checked'=>1), 'nature' => array('label'=>$langs->trans("NatureOfContact"), 'checked'=>1), 'thirdparty' => array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), - 'contact' => array('label'=>$langs->trans("Users").'/'.$langs->trans("Contacts"), 'checked'=>1), + 'contact' => array('label'=>$langs->trans("Users").' | '.$langs->trans("Contacts"), 'checked'=>1), 'type' => array('label'=>$langs->trans("ContactType"), 'checked'=>1), 'status' => array('label'=>$langs->trans("Status"), 'checked'=>1), 'link' => array('label'=>$langs->trans("Link"), 'checked'=>1), diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index edd6f7b7dd8..093fb47189d 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -361,7 +361,7 @@ ListOfThirdParties=List of Third Parties ShowCompany=Third Party ShowContact=Contact-Address ContactsAllShort=All (No filter) -ContactType=Contact type +ContactType=Contact role ContactForOrders=Order's contact ContactForOrdersOrShipments=Order's or shipment's contact ContactForProposals=Proposal's contact diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 0715723bf55..70b1028bca2 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -3612,6 +3612,13 @@ td.border, div.tagtable div div.border { .fichehalfright table.noborder { margin: 0px 0px 0px 0px; } +table.liste, table.noborder:not(.paymenttable):not(.margintable):not(.tableforcontact), table.formdoc, div.noborder:not(.paymenttable):not(.margintable):not(.tableforcontact) { + + border-left: 1px solid var(--colortopbordertitle1); + border-right: 1px solid var(--colortopbordertitle1); + +} table.liste, table.noborder, table.formdoc, div.noborder { width: 100%; border-collapse: separate !important; @@ -3621,11 +3628,6 @@ table.liste, table.noborder, table.formdoc, div.noborder { border-top-style: solid; margin: 0px 0px 20px 0px; - - border-left: 1px solid var(--colortopbordertitle1); - border-right: 1px solid var(--colortopbordertitle1); - /*width: calc(100% - 7px); border-collapse: separate !important; border-spacing: 0px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index f2fee83c291..9189f81856a 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3681,6 +3681,17 @@ div.colorback border-left: 1px solid #ccc; } +table.liste, table.noborder:not(.paymenttable):not(.margintable):not(.tableforcontact), table.formdoc, div.noborder:not(.paymenttable):not(.margintable):not(.tableforcontact) { + + border-left: 1px solid #BBB; + border-right: 1px solid #BBB; + +} +table.liste, table.noborder.paymenttable, table.noborder.margintable, table.noborder.tableforcontact, table.formdoc, div.noborder.paymenttable, div.noborder.margintable, div.noborder.tableforcontact { + border-left: 1px solid #f0f0f0; + border-right: 1px solid #f0f0f0; +} table.liste, table.noborder, table.formdoc, div.noborder { width: calc(100% - 2px); /* -2 to fix a bug. Without, a scroll appears due to overflow-x: auto; of div-table-responsive */ @@ -3695,12 +3706,6 @@ table.liste, table.noborder, table.formdoc, div.noborder { border-bottom-color: #BBB; border-bottom-style: solid; - - border-right: 1px solid #ccc; - border-left: 1px solid #ccc; - - margin: 0px 0px 20px 0px; -webkit-border-radius: 0.1em; From 27acaa45f515341b59a1cc15621cba54b481a29d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 14:18:24 +0200 Subject: [PATCH 60/78] Clean deprecated field --- .../class/fournisseur.facture-rec.class.php | 23 ++++++------ .../fourn/class/fournisseur.facture.class.php | 36 ++++--------------- 2 files changed, 17 insertions(+), 42 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.facture-rec.class.php b/htdocs/fourn/class/fournisseur.facture-rec.class.php index 7d90c239ba7..ab68cd3ecc6 100644 --- a/htdocs/fourn/class/fournisseur.facture-rec.class.php +++ b/htdocs/fourn/class/fournisseur.facture-rec.class.php @@ -79,13 +79,19 @@ class FactureFournisseurRec extends CommonInvoice public $suspended; public $libelle; + public $label; /** - * @deprecated * @var double $amount + * @deprecated */ public $amount; + /** + * @var double $remise + * @deprecated + */ public $remise; + public $vat_src_code; public $localtax1; public $localtax2; @@ -173,8 +179,6 @@ class FactureFournisseurRec extends CommonInvoice 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>40), 'suspended' =>array('type'=>'integer', 'label'=>'Suspended', 'enabled'=>1, 'visible'=>-1, 'position'=>225), 'libelle' =>array('type'=>'varchar(100)', 'label'=>'Libelle', 'enabled'=>1, 'showoncombobox' => 0, 'visible'=>-1, 'position'=>15), - 'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), - 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>40), 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'isameasure'=>1), 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>65, 'isameasure'=>1), @@ -278,8 +282,7 @@ class FactureFournisseurRec extends CommonInvoice $sql .= ', datec'; $sql .= ', suspended'; $sql .= ', libelle'; - $sql .= ', amount'; - $sql .= ', remise'; + $sql .= ', total_ttc'; $sql .= ', fk_user_author'; $sql .= ', fk_projet'; $sql .= ', fk_account'; @@ -310,7 +313,6 @@ class FactureFournisseurRec extends CommonInvoice $sql .= ", ".((int) $this->suspended); $sql .= ", '".$this->db->escape($this->libelle)."'"; $sql .= ", " .(!empty($facfourn_src->total_ttc) ? (float) $facfourn_src->total_ttc : '0'); // amount - $sql .= ", " .(!empty($facfourn_src->remise) ? (float) $facfourn_src->remise : '0'); $sql .= ", " .((int) $user->id); $sql .= ", " .(!empty($this->fk_project) ? ((int) $this->fk_project) : 'NULL'); $sql .= ", " .(!empty($facfourn_src->fk_account) ? ((int) $facfourn_src->fk_account) : 'NULL'); @@ -480,8 +482,6 @@ class FactureFournisseurRec extends CommonInvoice if ($this->fk_soc > 0) $sql .= " fk_soc = ". (int) $this->fk_soc. ','; $sql .= " suspended = ". (!empty($this->suspended) ? ((int) $this->suspended) : 0) . ','; $sql .= " libelle = ". (!empty($this->libelle) ? "'".$this->db->escape($this->libelle)."'" : 'NULL') . ","; - $sql .= " amount = ". (!empty($this->amount) ? ((float) $this->amount) : 0.00) . ','; - $sql .= " remise = ". (!empty($this->remise) ? ((float) $this->remise) : 'NULL') . ','; $sql .= " vat_src_code = ". (!empty($this->vat_src_code) ? "'".$this->db->escape($this->vat_src_code)."'" : 'NULL') . ','; $sql .= " localtax1 = ". (!empty($this->localtax1) ? ((float) $this->localtax1) : 0.00) . ','; $sql .= " localtax2 = ". (!empty($this->localtax2) ? ((float) $this->localtax2) : 0.00) . ','; @@ -553,7 +553,7 @@ class FactureFournisseurRec extends CommonInvoice { $sql = 'SELECT f.rowid, f.titre, f.ref_supplier, f.entity, f.fk_soc'; $sql .= ', f.datec, f.tms, f.suspended'; - $sql .= ', f.libelle, f.amount, f.remise'; + $sql .= ', f.libelle as label'; $sql .= ', f.vat_src_code, f.localtax1, f.localtax2'; $sql .= ', f.total_tva, f.total_ht, f.total_ttc'; $sql .= ', f.fk_user_author, f.fk_user_modif'; @@ -593,9 +593,8 @@ class FactureFournisseurRec extends CommonInvoice $this->date_creation = $obj->datec; $this->date_modification = $obj->tms; $this->suspended = $obj->suspended; - $this->libelle = $obj->libelle; - $this->amount = $obj->amount; - $this->remise = $obj->remise; + $this->libelle = $obj->label; + $this->label = $obj->label; $this->vat_src_code = $obj->vat_src_code; $this->total_localtax1 = $obj->localtax1; $this->total_localtax2 = $obj->localtax2; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 176f79a51de..9912f71df4b 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -182,10 +182,14 @@ class FactureFournisseur extends CommonInvoice public $date_echeance; /** - * @deprecated * @var double $amount + * @deprecated */ public $amount = 0; + /** + * @var double $remise + * @deprecated + */ public $remise = 0; /** @@ -404,11 +408,6 @@ class FactureFournisseur extends CommonInvoice $this->date = $now; } - $socid = $this->socid; - $ref_supplier = $this->ref_supplier; - $amount = $this->amount; - $remise = $this->remise; - // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate) if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) { list($this->fk_multicurrency, $this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $this->date); @@ -456,7 +455,6 @@ class FactureFournisseur extends CommonInvoice $this->total_ttc = $_facrec->total_ttc; // Fields always coming from template - $this->remise = $_facrec->remise; $this->fk_incoterms = $_facrec->fk_incoterms; $this->location_incoterms = $_facrec->location_incoterms; @@ -475,7 +473,6 @@ class FactureFournisseur extends CommonInvoice $this->array_options = $_facrec->array_options; - //if (! $this->remise) $this->remise = 0; if (! $this->mode_reglement_id) { $this->mode_reglement_id = 0; } @@ -545,10 +542,6 @@ class FactureFournisseur extends CommonInvoice $this->date_echeance = $forceduedate; } - if (!$remise) { - $remise = 0; - } - $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture_fourn ("; $sql .= "ref"; $sql .= ", ref_supplier"; @@ -882,8 +875,6 @@ class FactureFournisseur extends CommonInvoice $sql .= " t.tms,"; $sql .= " t.libelle as label,"; $sql .= " t.paye,"; - $sql .= " t.amount,"; - $sql .= " t.remise,"; $sql .= " t.close_code,"; $sql .= " t.close_note,"; $sql .= " t.tva,"; @@ -948,11 +939,8 @@ class FactureFournisseur extends CommonInvoice $this->label = $obj->label; $this->paye = $obj->paye; $this->paid = $obj->paye; - $this->amount = $obj->amount; - $this->remise = $obj->remise; $this->close_code = $obj->close_code; $this->close_note = $obj->close_note; - //$this->tva = $obj->tva; $this->total_localtax1 = $obj->localtax1; $this->total_localtax2 = $obj->localtax2; $this->total_ht = $obj->total_ht; @@ -1177,22 +1165,12 @@ class FactureFournisseur extends CommonInvoice if (isset($this->paye)) { $this->paye = trim($this->paye); } - if (isset($this->amount)) { - if (empty($this->amount)) $this->amount = 0; - else $this->amount = doubleval($this->amount); - } - if (isset($this->remise)) { - $this->remise = trim($this->remise); - } if (isset($this->close_code)) { $this->close_code = trim($this->close_code); } if (isset($this->close_note)) { $this->close_note = trim($this->close_note); } - /*if (isset($this->tva)) { - $this->tva = trim($this->tva); - }*/ if (isset($this->localtax1)) { $this->localtax1 = trim($this->localtax1); } @@ -1264,8 +1242,6 @@ class FactureFournisseur extends CommonInvoice } $sql .= " libelle=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; $sql .= " paye=".(isset($this->paye) ? $this->paye : "null").","; - $sql .= " amount=".(isset($this->amount) ? $this->amount : "null").","; - $sql .= " remise=".(isset($this->remise) ? $this->remise : "null").","; $sql .= " close_code=".(isset($this->close_code) ? "'".$this->db->escape($this->close_code)."'" : "null").","; $sql .= " close_note=".(isset($this->close_note) ? "'".$this->db->escape($this->close_note)."'" : "null").","; //$sql .= " tva=".(isset($this->tva) ? $this->tva : "null").","; @@ -2452,7 +2428,7 @@ class FactureFournisseur extends CommonInvoice $this->db->begin(); - // Libere remise liee a ligne de facture + // Free the discount linked to a line of invoice $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; $sql .= ' SET fk_invoice_supplier_line = NULL'; $sql .= ' WHERE fk_invoice_supplier_line = '.((int) $rowid); From 4ced0bac8965f4ca1cf54a4cb291d025aaa6808f Mon Sep 17 00:00:00 2001 From: atm-florian Date: Thu, 7 Apr 2022 14:39:14 +0200 Subject: [PATCH 61/78] =?UTF-8?q?replace=20throw=20new=20Exception(?= =?UTF-8?q?=E2=80=A6)=20with=20dol=5Fprint=5Ferror=20+=20exit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/core/class/commonobject.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index b1f7997b4f7..6713157c78f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5620,7 +5620,8 @@ abstract class CommonObject // phpcs:enable global $langs, $conf; if (!empty(self::TRIGGER_PREFIX) && strpos($triggerName, self::TRIGGER_PREFIX . '_') !== 0) { - throw new Exception('The trigger "' . $triggerName . '" does not start with "' . self::TRIGGER_PREFIX . '_" as required.'); + dol_print_error('', 'The trigger "' . $triggerName . '" does not start with "' . self::TRIGGER_PREFIX . '_" as required.'); + exit; } if (!is_object($langs)) { // If lang was not defined, we set it. It is required by run_triggers. include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php'; From bc7ad806e7f4185dd38fede5d4ecd1e955e19081 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 15:01:20 +0200 Subject: [PATCH 62/78] Try to fix a strange logic. --- htdocs/societe/card.php | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 2f2b1bcd89d..a591465cb23 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1180,14 +1180,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { document.formsoc.private.value=1; }); - var canHaveCategoryIfNotCustomerProspectSupplier = ' . (empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER) ? '0' : '1') . '; + var canHaveCategoryIfNotCustomerProspectSupplier = ' . (empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT) ? '0' : '1') . '; + init_customer_categ(); $("#customerprospect").change(function() { init_customer_categ(); }); function init_customer_categ() { console.log("is customer or prospect = "+jQuery("#customerprospect").val()); - if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() != 0 || !canHaveCategoryIfNotCustomerProspectSupplier)) + if (jQuery("#customerprospect").val() == 0 && !canHaveCategoryIfNotCustomerProspectSupplier) { jQuery(".visibleifcustomer").hide(); } @@ -1206,16 +1207,10 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if (jQuery("#fournisseur").val() == 0) { jQuery(".visibleifsupplier").hide(); - if (jQuery("#customerprospect").val() == 0 && canHaveCategoryIfNotCustomerProspectSupplier && jQuery(".visibleifcustomer").is(":hidden")) { - jQuery(".visibleifcustomer").show(); - } } else { jQuery(".visibleifsupplier").show(); - if (jQuery("#customerprospect").val() == 0 && jQuery(".visibleifcustomer").is(":visible")) { - jQuery(".visibleifcustomer").hide(); - } } } @@ -1646,12 +1641,10 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $langs->load('categories'); // Customer - //if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) { print '
'.$form->editfieldkey('CustomersProspectsCategoriesShort', 'custcats', '', $object, 0).''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, 'parent', null, null, 1); print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('custcats', $cate_arbo, GETPOST('custcats', 'array'), null, null, 'quatrevingtpercent widthcentpercentminusx', 0, 0); print "
'.$form->editfieldkey('ContactCategoriesShort', 'contcats', '', $object, 0).''; @@ -1921,14 +1914,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } }); - var canHaveCategoryIfNotCustomerProspectSupplier = ' . (empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER) ? '0' : '1') . '; + var canHaveCategoryIfNotCustomerProspectSupplier = ' . (empty($conf->global->THIRDPARTY_CAN_HAVE_CUSTOMER_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT) ? '0' : '1') . '; + init_customer_categ(); $("#customerprospect").change(function() { init_customer_categ(); }); function init_customer_categ() { console.log("is customer or prospect = "+jQuery("#customerprospect").val()); - if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() != 0 || !canHaveCategoryIfNotCustomerProspectSupplier)) + if (jQuery("#customerprospect").val() == 0 && !canHaveCategoryIfNotCustomerProspectSupplier) { jQuery(".visibleifcustomer").hide(); } @@ -1947,16 +1941,10 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if (jQuery("#fournisseur").val() == 0) { jQuery(".visibleifsupplier").hide(); - if (jQuery("#customerprospect").val() == 0 && canHaveCategoryIfNotCustomerProspectSupplier && jQuery(".visibleifcustomer").is(":hidden")) { - jQuery(".visibleifcustomer").show(); - } } else { jQuery(".visibleifsupplier").show(); - if (jQuery("#customerprospect").val() == 0 && jQuery(".visibleifcustomer").is(":visible")) { - jQuery(".visibleifcustomer").hide(); - } } }; @@ -2748,7 +2736,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Tags / categories if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { // Customer - if ($object->prospect || $object->client || (!$object->fournisseur && !empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) { + if ($object->prospect || $object->client || !empty($conf->global->THIRDPARTY_CAN_HAVE_CUSTOMER_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT)) { print '
'.$langs->trans("CustomersCategoriesShort").''; print $form->showCategories($object->id, Categorie::TYPE_CUSTOMER, 1); From 3e5e74c68759fe2b1b84ea4e2dd75fe286539e67 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 15:39:03 +0200 Subject: [PATCH 63/78] Close #17632 --- htdocs/contrat/list.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 55bd7071ee8..6c23cfcf720 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -338,18 +338,24 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { } } // Add where from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters); // Note that $action and $object may have been modified by hook +$parameters = array('search_dfyear' => $search_dfyear, 'search_op2df'=>$search_op2df); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -if ($search_dfyear > 0 && $search_op2df) { - if ($search_op2df == '<=') { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."'"; - } elseif ($search_op2df == '>=') { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; - } else { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; +// Add HAVING from hooks +$parameters = array('search_dfyear' => $search_dfyear, 'search_op2df'=>$search_op2df); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +if (empty($reshook)) { + if ($search_dfyear > 0 && $search_op2df) { + if ($search_op2df == '<=') { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."'"; + } elseif ($search_op2df == '>=') { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; + } else { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; + } } } +$sql .= $hookmanager->resPrint; $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { From 56bfa20d7044001723a6fe5944441132ca863b7c Mon Sep 17 00:00:00 2001 From: Christophe Battarel Date: Thu, 7 Apr 2022 15:59:42 +0200 Subject: [PATCH 64/78] FIX : dont update object price on each iteration when updating situation for all lines --- htdocs/compta/facture/card.php | 3 ++- htdocs/compta/facture/class/facture.class.php | 13 +++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 9956fd32b97..2cf5e13ff8b 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2560,9 +2560,10 @@ if (empty($reshook)) { setEventMessages($mesg, null, 'warnings'); $result = -1; } else { - $object->update_percent($line, GETPOST('all_progress')); + $object->update_percent($line, GETPOST('all_progress'), false); } } + $object->update_price(1); } } elseif ($action == 'updateline' && $usercancreate && !$cancel) { header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); // To show again edited page diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 5fe58adcd7b..2b368d7bd75 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3725,11 +3725,12 @@ class Facture extends CommonInvoice /** * Update invoice line with percentage * - * @param FactureLigne $line Invoice line - * @param int $percent Percentage + * @param FactureLigne $line Invoice line + * @param int $percent Percentage + * @param boolean $update_price Update object price * @return void */ - public function update_percent($line, $percent) + public function update_percent($line, $percent, $update_price = true) { // phpcs:enable global $mysoc, $user; @@ -3756,7 +3757,11 @@ class Facture extends CommonInvoice $line->multicurrency_total_tva = $tabprice[17]; $line->multicurrency_total_ttc = $tabprice[18]; $line->update($user); - $this->update_price(1); + + // sometimes it is better to not update price for each line, ie when updating situation on all lines + if ($update_price) { + $this->update_price(1); + } } /** From b8d19c9311c2a01de0bb5d53ed5ea2d97d97c61a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 15:59:50 +0200 Subject: [PATCH 65/78] Debug v16 --- htdocs/main.inc.php | 2 +- htdocs/societe/card.php | 20 ++++++++++---------- htdocs/theme/eldy/dropdown.inc.php | 9 +++++++-- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index dc8b49c775f..e2d36ab4695 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -2410,7 +2410,7 @@ function printDropdownQuickadd() "position" => 50, ), array( - "url" => "/compta/facture/card.php?action=create", + "url" => "/contrat/card.php?action=create", "title" => "NewContractSubscription@contracts", "name" => "Contract@contracts", "picto" => "object_contract", diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index a591465cb23..37ac9805374 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1320,16 +1320,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print '
'.$langs->trans('ParentCompany').''; - print img_picto('', 'company', 'class="paddingrightonly"'); - print $form->select_thirdparty_list('', 'parent_company_id', '', $langs->trans("ThirdParty")); - print '
'.$form->editfieldkey('ProspectCustomer', 'customerprospect', '', $object, 0, 'string', '', 1).''; @@ -1675,6 +1665,16 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $parameters = array('socid'=>$socid, 'colspan' => ' colspan="3"', 'colspanvalue' => '3'); include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; + // Parent company + if (empty($conf->global->SOCIETE_DISABLE_PARENTCOMPANY)) { + print '
'.$langs->trans('ParentCompany').''; + print img_picto('', 'company', 'class="paddingrightonly"'); + print $form->select_company(GETPOST('parent_company_id'), 'parent_company_id'); + print '
'.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).'
'; - print img_picto('', 'company').$form->select_company($socid, 'socid', '', 'SelectThirdParty'); + print img_picto('', 'company').$form->select_company($socid, 'socid', '', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx'); print '
'.$langs->trans('ParentCompany').''; print img_picto('', 'company', 'class="paddingrightonly"'); - print $form->select_company(GETPOST('parent_company_id'), 'parent_company_id'); + print $form->select_company(GETPOST('parent_company_id'), 'parent_company_id', '', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx'); print '
'; + print ''; $selectarray = array('-1'=>'', 'withoutsubscription'=>$langs->trans("WithoutSubscription"), 'uptodate'=>$langs->trans("UpToDate"), 'outofdate'=>$langs->trans("OutOfDate")); print $form->selectarray('search_filter', $selectarray, $search_filter); print ''; if ($datefin) { - print ''; print dol_print_date($datefin, 'day'); if ($memberstatic->hasDelay()) { $textlate = ' ('.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24) >= 0 ? '+' : '').ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24).' '.$langs->trans("days").')'; print " ".img_warning($langs->trans("SubscriptionLate").$textlate); } - print ''; if (!empty($obj->subscription)) { print $langs->trans("SubscriptionNotReceived"); if ($obj->statut > 0) { @@ -1128,8 +1126,8 @@ while ($i < min($num, $limit)) { } else { print ' '; } - print '
'.$userstatic->getNomUrl(-1, 'leave').''.$userstatic->getNomUrl(-1, 'leave').''.$approbatorstatic->getNomUrl(-1).''.$approbatorstatic->getNomUrl(-1).''; $labeltypeleavetoshow = ($langs->trans($typeleaves[$obj->fk_type]['code']) != $typeleaves[$obj->fk_type]['code'] ? $langs->trans($typeleaves[$obj->fk_type]['code']) : $typeleaves[$obj->fk_type]['label']); - print empty($typeleaves[$obj->fk_type]['label']) ? $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type) : $labeltypeleavetoshow; + $labeltypeleavetoshow = empty($typeleaves[$obj->fk_type]['label']) ? $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type) : $labeltypeleavetoshow; + + print ''; + print $labeltypeleavetoshow; print ''; $nbopenedday = num_open_day($db->jdate($obj->date_debut, 1), $db->jdate($obj->date_fin, 1), 0, 1, $obj->halfday); // user jdate(..., 1) because num_open_day need UTC dates $totalduration += $nbopenedday; - print $nbopenedday.' '.$langs->trans('DurationDays'); + print $nbopenedday; + //print ' '.$langs->trans('DurationDays'); print '
'.$holidaystatic->getNomUrl(1).''.$userstatic->getNomUrl(-1, 'leave').''.$userstatic->getNomUrl(-1, 'leave').''.dol_escape_htmltag($langs->trans($typeleaves[$obj->fk_type]['code'])).'

*** Force page code and collation of tables into utf8/utf8_unicode_ci (for mysql/mariadb only)

*** Force page code and collation of tables into utf8/utf8_unicode_ci and row_format=dynamic (for mysql/mariadb only)
'; print $table; - $sql = "ALTER TABLE ".$table." CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci"; - print ''; + $sql1 = "ALTER TABLE ".$table." ROW_FORMAT=dynamic"; + $sql2 = "ALTER TABLE ".$table." CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci"; + print ''; + print ''; if ($force_utf8_on_tables == 'confirmed') { - $resql = $db->query($sql); - print ' - Done ('.($resql ? 'OK' : 'KO').')'; + $resql1 = $db->query($sql1); + if ($resql1) { + $resql2 = $db->query($sql2); + } else { + $resql2 = false; + } + print ' - Done ('.(($resql1 && $resql2) ? 'OK' : 'KO').')'; } else { print ' - Disabled'; } diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 84118961692..28542667dff 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -357,6 +357,7 @@ class User extends CommonObject */ public $fk_warehouse; + public $fields = array( 'rowid'=>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'), 'lastname'=>array('type'=>'varchar(50)', 'label'=>'LastName', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>20, 'searchall'=>1), From 88066d3fca6adc5fbe920eaf31d34ebcfcdb4a44 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 Apr 2022 23:53:02 +0200 Subject: [PATCH 76/78] Clean data --- htdocs/install/mysql/migration/15.0.0-16.0.0.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 3aa5cd9c9cd..5f8b1d886c3 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -322,3 +322,5 @@ ALTER TABLE llx_contratdet ADD COLUMN rang integer DEFAULT 0 AFTER info_bits; ALTER TABLE llx_actioncomm MODIFY COLUMN note mediumtext; +DELETE FROM llx_boxes WHERE box_id IN (select rowid FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php')); +DELETE FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php'); From 994b500a6820eafc5c208276187d62bf42a0241a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 8 Apr 2022 00:14:29 +0200 Subject: [PATCH 77/78] PHP 8.0 compatibility --- ChangeLog | 3 ++- htdocs/core/lib/agenda.lib.php | 6 +++--- htdocs/core/tpl/list_print_total.tpl.php | 2 +- htdocs/fourn/class/fournisseur.facture.class.php | 2 +- htdocs/hrm/index.php | 12 +++++++----- htdocs/main.inc.php | 2 ++ htdocs/theme/eldy/style.css.php | 4 ++-- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 880406bb189..31bfa1c1cff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,7 +9,8 @@ English Dolibarr ChangeLog For users: --------------- -NEW: ... +NEW: PHP 8.0 compatibility + Modules diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index d2528f45dfa..488010609f9 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -93,7 +93,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print $form->select_dolgroups($usergroupid, 'usergroup', 1, '', !$canedit, '', '', '0', false, 'minwidth100 maxwidth500 widthcentpercentminusxx'); print ''; - if ($conf->resource->enabled) { + if (!empty($conf->resource->enabled)) { include_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; $formresource = new FormResource($db); @@ -105,14 +105,14 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh } } - if (!empty($conf->societe->enabled) && $user->rights->societe->lire) { + if (!empty($conf->societe->enabled) && !empty($user->rights->societe->lire)) { print '
'; print img_picto($langs->trans("ThirdParty"), 'company', 'class="fawidth30 inline-block"'); print $form->select_company($socid, 'search_socid', '', ' ', 0, 0, null, 0, 'minwidth100 maxwidth500'); print '
'; } - if (!empty($conf->projet->enabled) && $user->rights->projet->lire) { + if (!empty($conf->projet->enabled) && !empty($user->rights->projet->lire)) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; $formproject = new FormProjets($db); diff --git a/htdocs/core/tpl/list_print_total.tpl.php b/htdocs/core/tpl/list_print_total.tpl.php index b015dc51fdc..8d84228e2ec 100644 --- a/htdocs/core/tpl/list_print_total.tpl.php +++ b/htdocs/core/tpl/list_print_total.tpl.php @@ -14,7 +14,7 @@ if (isset($totalarray['pos'])) { $i++; if (!empty($totalarray['pos'][$i])) { print '
'; - if ($totalarray['type'][$i] == 'duration') { + if (isset($totalarray['type']) && $totalarray['type'][$i] == 'duration') { print (!empty($totalarray['val'][$totalarray['pos'][$i]])?convertSecondToTime($totalarray['val'][$totalarray['pos'][$i]], 'allhourmin'):0); } else { print price(!empty($totalarray['val'][$totalarray['pos'][$i]])?$totalarray['val'][$totalarray['pos'][$i]]:0); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index da71a2a795d..0af7e083aec 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2627,7 +2627,7 @@ class FactureFournisseur extends CommonInvoice // phpcs:enable global $conf, $langs; - $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut as status'; + $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut as status, ff.total_ht, ff.total_ttc'; $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as ff'; if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ff.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index 84e336c9b97..c573b78ed51 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -34,17 +34,17 @@ require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; -if ($conf->deplacement->enabled) { +if (!empty($conf->deplacement->enabled)) { require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php'; } -if ($conf->expensereport->enabled) { +if (!empty($conf->expensereport->enabled)) { require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; } -if ($conf->recruitment->enabled) { +if (!empty($conf->recruitment->enabled)) { require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentcandidature.class.php'; require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; } -if ($conf->holiday->enabled) { +if (!empty($conf->holiday->enabled)) { require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; } @@ -236,7 +236,9 @@ if (!empty($conf->holiday->enabled) && $user->rights->holiday->read) { print '
'.$holidaystatic->getNomUrl(1).''.$userstatic->getNomUrl(-1, 'leave').''.dol_escape_htmltag($langs->trans($typeleaves[$obj->fk_type]['code'])).''.dol_escape_htmltag($langs->trans($leavecode)).'