From 6de24e0c2e8b7ba734e288a0d8f4d8e1314cc657 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 00:19:45 +0100 Subject: [PATCH 1/3] Reduce travis load for v12 --- .travis.yml | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a89572148b..edd7582b1e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ # We use dist: xenial to have php 5.6+ available os: linux dist: xenial -sudo: required +#dist: bionic language: php @@ -115,6 +115,9 @@ install: - | echo "Adding path of binaries tools installed by composer to the PATH" export PATH="$TRAVIS_BUILD_DIR/htdocs/includes/bin:$PATH" + echo $PATH + ls $TRAVIS_BUILD_DIR/vendor + ls $TRAVIS_BUILD_DIR/htdocs/includes/bin echo @@ -141,15 +144,20 @@ before_script: - | echo "Versions information" + echo # Check PHP echo "PHP version" php -i | head - - # Check PHP CodeSniffer installation + # Check Parallel-lint version + echo "Parallel-lint version" + which parallel-lint + parallel-lint -V + # Check PHP CodeSniffer version echo "PHPCS version" which phpcs phpcs --version | head - phpcs -i | head - - # Check PHPUnit installation + # Check PHPUnit version echo "PHPUnit version" which phpunit phpunit --version | head - @@ -254,17 +262,18 @@ script: # Ensure we catch errors set -e #parallel-lint --exclude htdocs/includes --blame . - parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/ --exclude htdocs/includes/composer/autoload_static.php --blame . + parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/ --exclude htdocs/includes/composer/autoload_static.php --blame . set +e echo - | - echo "Checking coding style (excluding Pull Requests builds)" + echo "Checking coding style (excluding Pull Requests builds to not overload travis, excluding also some jobs to avoid duplicate tests)" # Ensure we catch errors set -e # Exclusions are defined in the ruleset.xml file - #phpcs -s -n -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 . - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; fi + if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4" ] && [ "$DB" = "mysql" ]; then + phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; + fi set +e echo @@ -376,6 +385,7 @@ script: php upgrade.php 11.0.0 12.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade11001200.log php upgrade2.php 11.0.0 12.0.0 > $TRAVIS_BUILD_DIR/upgrade11001200-2.log php step5.php 11.0.0 12.0.0 > $TRAVIS_BUILD_DIR/upgrade11001200-3.log + # Enable modules not enabled into original dump php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_API,MAIN_MODULE_SUPPLIERPROPOSAL,MAIN_MODULE_WEBSITE,MAIN_MODULE_TICKETSUP,MAIN_MODULE_ACCOUNTING > $TRAVIS_BUILD_DIR/enablemodule.log echo $? @@ -396,7 +406,7 @@ script: after_script: - | - echo "After script - Output lines of dolibarr.log" + echo "After script - Output last lines of dolibarr.log" ls $TRAVIS_BUILD_DIR/documents #cat $TRAVIS_BUILD_DIR/documents/dolibarr.log sudo tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log From ac3c12973559b3c3cb5f5e356dd9fa00ce50f1c8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 14:24:15 +0100 Subject: [PATCH 2/3] Clean code --- htdocs/accountancy/bookkeeping/balance.php | 4 +-- htdocs/adherents/class/subscription.class.php | 7 ++++- htdocs/categories/edit.php | 4 +-- htdocs/commande/class/commande.class.php | 1 + htdocs/compta/bank/card.php | 2 +- htdocs/compta/bank/categ.php | 2 +- htdocs/compta/facture/class/facture.class.php | 1 + htdocs/contrat/class/contrat.class.php | 2 +- htdocs/core/boxes/box_task.php | 2 +- .../core/class/commondocgenerator.class.php | 2 +- htdocs/core/lib/functions.lib.php | 27 ++++++++++--------- htdocs/core/lib/price.lib.php | 8 ++++-- htdocs/core/lib/project.lib.php | 10 +++---- .../class/expensereport.class.php | 6 ++--- htdocs/fichinter/class/fichinterrec.class.php | 1 - .../class/fournisseur.commande.class.php | 11 +++----- .../fourn/class/fournisseur.facture.class.php | 6 ++--- htdocs/main.inc.php | 2 +- htdocs/product/price.php | 9 ++++--- htdocs/projet/tasks/time.php | 8 +++--- htdocs/reception/card.php | 2 +- htdocs/societe/class/societe.class.php | 2 +- test/phpunit/FunctionsLibTest.php | 19 ++++++++++--- 23 files changed, 78 insertions(+), 60 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index ef19a6ae330..29e56cd4233 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -336,11 +336,11 @@ if ($action != 'export_csv') $sous_total_opening_balance += $opening_balance; } - print ''.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit)).''; + print ''.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit, 'MT')).''; print " \n"; print ''; - print ''.$langs->trans("AccountBalance").':'.price($total_opening_balance).''.price($total_debit).''.price($total_credit).''.price(price2num($total_opening_balance + $total_debit - $total_credit)).''; + print ''.$langs->trans("AccountBalance").':'.price($total_opening_balance).''.price($total_debit).''.price($total_credit).''.price(price2num($total_opening_balance + $total_debit - $total_credit, 'MT')).''; print " \n"; print ''; diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index e512e1152bb..6e96ac64d2c 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -257,13 +257,18 @@ class Subscription extends CommonObject { $error = 0; + if (!is_numeric($this->amount)) { + $this->error = 'BadValueForParameterAmount'; + return -1; + } + $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET "; $sql .= " fk_type = ".$this->fk_type.","; $sql .= " fk_adherent = ".$this->fk_adherent.","; $sql .= " note=".($this->note ? "'".$this->db->escape($this->note)."'" : 'null').","; - $sql .= " subscription = '".price2num($this->amount)."',"; + $sql .= " subscription = ".price2num($this->amount).","; $sql .= " dateadh='".$this->db->idate($this->dateh)."',"; $sql .= " datef='".$this->db->idate($this->datef)."',"; $sql .= " datec='".$this->db->idate($this->datec)."',"; diff --git a/htdocs/categories/edit.php b/htdocs/categories/edit.php index 48bd82b9326..cd8a718279e 100644 --- a/htdocs/categories/edit.php +++ b/htdocs/categories/edit.php @@ -157,7 +157,7 @@ print ''; // Description print ''; print ''.$langs->trans("Description").''; -print ''; +print ''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor = new DolEditor('description', $object->description, '', 200, 'dolibarr_notes', '', false, true, $conf->fckeditor->enabled, ROWS_6, '90%'); $doleditor->Create(); @@ -166,7 +166,7 @@ print ''; // Color print ''; print ''.$langs->trans("Color").''; -print ''; +print ''; print $formother->selectColor($object->color, 'color'); print ''; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index fbbd40265a1..5402d31ba7d 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3135,6 +3135,7 @@ class Commande extends CommonOrder // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 593893878e0..1403ecc66b8 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -907,7 +907,7 @@ else print 'min_allowed).'">'; print ''.$langs->trans("BalanceMinimalDesired").''; - print 'min_desired).'">'; + print 'min_desired).'">'; // Web print ''.$langs->trans("Web").''; diff --git a/htdocs/compta/bank/categ.php b/htdocs/compta/bank/categ.php index 308dad5dbca..d24b49ce426 100644 --- a/htdocs/compta/bank/categ.php +++ b/htdocs/compta/bank/categ.php @@ -135,7 +135,7 @@ if ($result) } else { - print "".$objp->label.""; + print "".$objp->label.""; print ''; print ''.img_edit().''; print ''.img_delete().''; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 8a2c75037ba..4bfc36a3e78 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3326,6 +3326,7 @@ class Facture extends CommonInvoice // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 31730353ea1..e38c24565dd 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -1504,9 +1504,9 @@ class Contrat extends CommonObject } $txtva = price2num($txtva); - $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); + $remise_percent = price2num($remise_percent); $qty = price2num($qty); if (empty($qty)) $qty = 1; diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php index 4239e6f1b28..b9c40a9098c 100644 --- a/htdocs/core/boxes/box_task.php +++ b/htdocs/core/boxes/box_task.php @@ -139,7 +139,7 @@ class box_task extends ModeleBoxes $boxcontent .= ''; } $this->info_box_contents[0][] = array( - 'tr'=>'class="nohover showiffilter'.$this->boxcode.' hideobject"', + 'tr' => 'class="nohover showiffilter'.$this->boxcode.' hideobject"', 'td' => 'class="nohover"', 'textnoformat' => $boxcontent, ); diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 2900a4cd173..90cfd84cf69 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1347,7 +1347,7 @@ abstract class CommonDocGenerator if ($itemsInRow > 0) { // close table row and empty cols for ($i = $itemsInRow; $i <= $maxItemsInRow; $i++) { - $html .= ""; + $html .= ""; } $html .= ""; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 155b1d74a5f..24ec5645ffd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4698,14 +4698,15 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $ * 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK) * 'CR'=Currency rate * Numeric = Nb of digits for rounding - * @param int $alreadysqlnb Put 1 if you know that content is already universal format number + * @param int $option Put 1 if you know that content is already universal format number (so no correction on decimal will be done) + * Put 2 if you know that number is a user input (so we know we don't have to fix decimal separator). * @return string Amount with universal numeric format (Example: '99.99999'). * If conversion fails, it return text unchanged if $rounding = '' or '0' if $rounding is defined. * If amount is null or '', it returns '' if $rounding = '' or '0' if $rounding is defined.. * * @see price() Opposite function of price2num */ -function price2num($amount, $rounding = '', $alreadysqlnb = 0) +function price2num($amount, $rounding = '', $option = 0) { global $langs, $conf; @@ -4720,14 +4721,16 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) //print "amount=".$amount." html=".$form." trunc=".$trunc." nbdecimal=".$nbdecimal." dec='".$dec."' thousand='".$thousand."'
"; // Convert value to universal number format (no thousand separator, '.' as decimal separator) - if ($alreadysqlnb != 1) { // If not a PHP number or unknown, we change or clean format + if ($option != 1) { // If not a PHP number or unknown, we change or clean format //print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; - if ($thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator, not as a decimal separator - $amount = str_replace($thousand, '', $amount); // Replace of thousand before test of is_numeric to avoid pb if thousand is . and there is 3 numbers after + if ($option == 2 && $thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator and string come frominput data, so 1.123 is 1123 + $amount = str_replace($thousand, '', $amount); } + // Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number // to format defined by LC_NUMERIC after a calculation and we want source format to be like defined by Dolibarr setup. + // So if number was already a good number, it is converted into local Dolibarr setup. if (is_numeric($amount)) { // We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10 @@ -4736,7 +4739,7 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) $nbofdec = max(0, dol_strlen($temps) - 2); // -2 to remove "0." $amount = number_format($amount, $nbofdec, $dec, $thousand); } - //print "QQ".$amount.'
'; + //print "QQ".$amount."
\n"; // Now make replace (the main goal of function) if ($thousand != ',' && $thousand != '.') { @@ -4960,10 +4963,10 @@ function get_localtax($vatrate, $local, $thirdparty_buyer = "", $thirdparty_sell // By default, search value of local tax on line of common tax $sql = "SELECT t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; - $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$thirdparty_seller->country_code."'"; + $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($thirdparty_seller->country_code)."'"; $sql .= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1"; - if ($vatratecode) $sql .= " AND t.code ='".$vatratecode."'"; // If we have the code, we use it in priority - else $sql .= " AND t.recuperableonly ='".$vatnpr."'"; + if ($vatratecode) $sql .= " AND t.code ='".$db->escape($vatratecode)."'"; // If we have the code, we use it in priority + else $sql .= " AND t.recuperableonly ='".$db->escape($vatnpr)."'"; dol_syslog("get_localtax", LOG_DEBUG); $resql = $db->query($sql); @@ -5119,10 +5122,10 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi } $sql .= ", ".MAIN_DB_PREFIX."c_country as c"; - if ($mysoc->country_code == 'ES') $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$buyer->country_code."'"; // local tax in spain use the buyer country ?? - else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$seller->country_code."'"; + if ($mysoc->country_code == 'ES') $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($buyer->country_code)."'"; // local tax in spain use the buyer country ?? + else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($seller->country_code)."'"; $sql .= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1"; - if ($vatratecode) $sql .= " AND t.code = '".$vatratecode."'"; + if ($vatratecode) $sql .= " AND t.code = '".$db->escape($vatratecode)."'"; } $resql = $db->query($sql); diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index 2cb8d8e30f6..dfb5f4ffaf1 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -103,10 +103,14 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt $seller = $mysoc; // If sell is done to a customer, $seller is not provided, we use $mysoc //var_dump($seller->country_id);exit; } - if (empty($localtaxes_array) || !is_array($localtaxes_array)) - { + if (empty($localtaxes_array) || !is_array($localtaxes_array)) { dol_syslog("Price.lib::calcul_price_total Warning: function is called with parameter localtaxes_array that is missing", LOG_WARNING); } + if (!is_numeric($txtva)) { + dol_syslog("Price.lib::calcul_price_total Warning: function was called with a parameter vat rate that is not a real numeric value. There is surely a bug.", LOG_ERR); + } elseif ($txtva >= 1000) { + dol_syslog("Price.lib::calcul_price_total Warning: function was called with a bad value for vat rate (should be often < 100, always < 1000). There is surely a bug.", LOG_ERR); + } // Too verbose. Enable for debug only //dol_syslog("Price.lib::calcul_price_total qty=".$qty." pu=".$pu." remiserpercent_ligne=".$remise_percent_ligne." txtva=".$txtva." uselocaltax1_rate=".$uselocaltax1_rate." uselocaltax2_rate=".$uselocaltax2_rate.' remise_percent_global='.$remise_percent_global.' price_base_type='.$ice_base_type.' type='.$type.' progress='.$progress); diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index ac8530b4aa5..284ebb3ad37 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -2397,24 +2397,24 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide // this conf is actually hidden, by default we use 10% for "be carefull or warning" $warningRatio = !empty($conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT) ? (1 + $conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT / 100) : 1.10; - $diffTitle = '
'.$langs->trans('ProgressDeclared').' : '.$task->progress.($task->progress ? '%' : ''); - $diffTitle .= '
'.$langs->trans('ProgressCalculated').' : '.$progressCalculated.($progressCalculated ? '%' : ''); + $diffTitle = '
'.$langs->trans('ProgressDeclared').' : '.$task->progress.($task->progress ? '%' : ''); + $diffTitle .= '
'.$langs->trans('ProgressCalculated').' : '.$progressCalculated.($progressCalculated ? '%' : ''); //var_dump($progressCalculated.' '.$warningRatio.' '.$task->progress.' '.doubleval($task->progress * $warningRatio)); if (doubleval($progressCalculated) > doubleval($task->progress * $warningRatio)) { $progressBarClass = 'progress-bar-danger'; $title = $langs->trans('TheReportedProgressIsLessThanTheCalculatedProgressionByX', abs($task->progress - $progressCalculated).' '.$langs->trans("point")); - $diff = ' '.($task->progress - $progressCalculated).'%'; + $diff = ' '.($task->progress - $progressCalculated).'%'; } elseif (doubleval($progressCalculated) > doubleval($task->progress)) { // warning if close at 10% $progressBarClass = 'progress-bar-warning'; $title = $langs->trans('TheReportedProgressIsLessThanTheCalculatedProgressionByX', abs($task->progress - $progressCalculated).' '.$langs->trans("point")); - $diff = ' '.($task->progress - $progressCalculated).'%'; + $diff = ' '.($task->progress - $progressCalculated).'%'; } else { $progressBarClass = 'progress-bar-success'; $title = $langs->trans('TheReportedProgressIsMoreThanTheCalculatedProgressionByX', ($task->progress - $progressCalculated).' '.$langs->trans("point")); - $diff = ' '.($task->progress - $progressCalculated).'%'; + $diff = ' '.($task->progress - $progressCalculated).'%'; } } diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index c56a0ecae64..3c18805362f 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1801,6 +1801,7 @@ class ExpenseReport extends CommonObject $localtaxes_type = getLocalTaxesFromRate($vatrate, 0, $mysoc, $this->thirdparty); $vat_src_code = ''; + $reg = array(); if (preg_match('/\s*\((.*)\)/', $vatrate, $reg)) { $vat_src_code = $reg[1]; @@ -2046,6 +2047,7 @@ class ExpenseReport extends CommonObject // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $vatrate, $reg)) { $vat_src_code = $reg[1]; @@ -2060,10 +2062,6 @@ class ExpenseReport extends CommonObject $tx_tva = $vatrate / 100; $tx_tva = $tx_tva + 1; - $total_ht = price2num($total_ttc / $tx_tva, 'MT'); - - $total_tva = price2num($total_ttc - $total_ht, 'MT'); - // fin calculs $this->line = new ExpenseReportLine($this->db); $this->line->comments = $comments; diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index a09547b3164..5b3dfb3a2fc 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -481,7 +481,6 @@ class FichinterRec extends Fichinter $pu = $pu_ttc; } - // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index a95ef1bc7c7..dc3113f2554 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1776,8 +1776,6 @@ class CommandeFournisseur extends CommonOrder $localtax1_type = $localtaxes_type[0]; $localtax2_type = $localtaxes_type[2]; - $subprice = price2num($pu, 'MU'); - $rangmax = $this->line_max(); $rang = $rangmax + 1; @@ -2635,9 +2633,9 @@ class CommandeFournisseur extends CommonOrder if (!$qty) $qty = 1; $pu = price2num($pu); $pu_ht_devise = price2num($pu_ht_devise); - $txtva = price2num($txtva); - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); + $txtva = price2num($txtva); + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); // Check parameters if ($type < 0) return -1; @@ -2658,6 +2656,7 @@ class CommandeFournisseur extends CommonOrder // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; @@ -2683,8 +2682,6 @@ class CommandeFournisseur extends CommonOrder $localtax1_type = $localtaxes_type[0]; $localtax2_type = $localtaxes_type[2]; - $subprice = price2num($pu_ht, 'MU'); - //Fetch current line from the database and then clone the object and set it in $oldline property $this->line = new CommandeFournisseurLigne($this->db); $this->line->fetch($rowid); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 952e609555d..72d040583b2 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1679,11 +1679,11 @@ class FactureFournisseur extends CommonInvoice $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); if (!preg_match('/\((.*)\)/', $txtva)) { $txtva = price2num($txtva); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1' } + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); if ($date_start && $date_end && $date_start > $date_end) { $langs->load("errors"); @@ -1939,8 +1939,6 @@ class FactureFournisseur extends CommonInvoice $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); - $localtaxes_type = array($txlocaltax1, $txlocaltax2); - // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 9b85e62880a..84c695d9978 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1705,7 +1705,7 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead } if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $text = ''.DOL_VERSION.''; + $text = ''.DOL_VERSION.''; $toprightmenu .= @Form::textwithtooltip('', $appli, 2, 1, $text, 'login_block_elem', 2); } diff --git a/htdocs/product/price.php b/htdocs/product/price.php index f93545ee19e..12029ea7cdc 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -110,6 +110,7 @@ if (empty($reshook)) // We must define tva_tx, npr and local taxes $tva_tx = $tva_tx_txt; $vatratecode = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; @@ -262,8 +263,8 @@ if (empty($reshook)) } $pricestoupdate[$i] = array( - 'price' => price2num($newprice[$i]), - 'price_min' => price2num($newprice_min[$i]), + 'price' => price2num($newprice[$i], '', 2), + 'price_min' => price2num($newprice_min[$i], '', 2), 'price_base_type' => $newpricebase[$i], 'default_vat_code' => $vatratecode, 'vat_tx' => $tva_tx, // default_vat_code should be used in priority in a future @@ -279,8 +280,8 @@ if (empty($reshook)) } elseif (!$error) { - $newprice = price2num(GETPOST('price', 'alpha')); - $newprice_min = price2num(GETPOST('price_min', 'alpha')); + $newprice = price2num(GETPOST('price', 'alpha'), '', 2); + $newprice_min = price2num(GETPOST('price_min', 'alpha'), '', 2); $newpricebase = GETPOST('price_base_type', 'alpha'); $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 4a5d484abf8..b95f285c628 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1463,7 +1463,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) if (!empty($arrayfields['value']['checked'])) { print ''; - $value = price2num($task_time->thm * $task_time->task_duration / 3600); + $value = price2num($task_time->thm * $task_time->task_duration / 3600, 'MT', 1); print price($value, 1, $langs, 1, -1, -1, $conf->currency); print ''; if (!$i) $totalarray['nbfield']++; @@ -1680,7 +1680,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) if (!empty($arrayfields['value']['checked'])) { print ''; - $value = price2num($task_time->thm * $task_time->task_duration / 3600); + $value = price2num($task_time->thm * $task_time->task_duration / 3600, 'MT', 1); print price($value, 1, $langs, 1, -1, -1, $conf->currency); print ''; } @@ -1689,7 +1689,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) if (!empty($arrayfields['valuebilled']['checked'])) { print ''; - $valuebilled = price2num($task_time->total_ht); + $valuebilled = price2num($task_time->total_ht, '', 1); if (isset($task_time->total_ht)) print price($valuebilled, 1, $langs, 1, -1, -1, $conf->currency); print ''; } @@ -1837,7 +1837,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) if (!empty($arrayfields['valuebilled']['checked'])) { print ''; - $valuebilled = price2num($task_time->total_ht); + $valuebilled = price2num($task_time->total_ht, '', 1); if (isset($task_time->total_ht)) print price($valuebilled, 1, $langs, 1, -1, -1, $conf->currency); print ''; } diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 3d8547f9322..47a7af62bb0 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -1804,7 +1804,7 @@ elseif ($id || $ref) if ($action == 'editline' && $lines[$i]->id == $line_id) { - print ''; + print ''; } else { diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 30a90a884bd..ee91363dba1 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2077,7 +2077,7 @@ class Societe extends CommonObject $discount->amount_tva = $discount->multicurrency_amount_tva = price2num($remise * $vatrate / 100, 'MT'); $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num($discount->amount_ht + $discount->amount_tva, 'MT'); - $discount->tva_tx = price2num($vatrate, 'MT'); + $discount->tva_tx = price2num($vatrate); $discount->vat_src_code = $vat_src_code; $discount->description = $desc; diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 85937147cff..a987f28c7ed 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1262,16 +1262,24 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase // Test with 3 chars after . or , // If a . is used and there is 3 digits after, it is a thousand separator - $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); + $this->assertEquals(1234, price2num('1.234', '', 2), 'Test 1.234 give 1234 with spanish language if user input'); + $this->assertEquals(1.234, price2num('1,234', '', 2), 'Test 1,234 give 1234 with spanish language if user input'); + $this->assertEquals(1234, price2num('1 234', '', 2), 'Test 1 234 give 1234 with spanish language if user input'); + $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with spanish language'); + $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1234 with spanish language'); $this->assertEquals(1234, price2num('1 234'), 'Test 1 234 give 1234 with spanish language'); - $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); - $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with spanish language'); $this->assertEquals(21500123, price2num('21.500.123'), 'Test 21.500.123 give 21500123 with spanish language'); - $this->assertEquals(21500123, price2num('21500.123'), 'Test 21500.123 give 21500123 with spanish language'); + $this->assertEquals(21500123, price2num('21500.123', 0, 2), 'Test 21500.123 give 21500123 with spanish language if user input'); + $this->assertEquals(21500.123, price2num('21500.123'), 'Test 21500.123 give 21500123 with spanish language'); $this->assertEquals(21500.123, price2num('21500,123'), 'Test 21500,123 give 21500.123 with spanish language'); // Test with 2 digits $this->assertEquals(21500.12, price2num('21500.12'), 'Test 21500.12 give 21500.12 with spanish language'); $this->assertEquals(21500.12, price2num('21500,12'), 'Test 21500,12 give 21500.12 with spanish language'); + // Test with 3 digits + $this->assertEquals(12123, price2num('12.123', '', 2), 'Test 12.123 give 12123 with spanish language if user input'); + $this->assertEquals(12.123, price2num('12,123', '', 2), 'Test 12,123 give 12.123 with spanish language if user input'); + $this->assertEquals(12.123, price2num('12.123'), 'Test 12.123 give 12.123 with spanish language'); + $this->assertEquals(12.123, price2num('12,123'), 'Test 12,123 give 12.123 with spanish language'); // For french language $newlangs3 = new Translate('', $conf); @@ -1279,9 +1287,12 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $newlangs3->load("main"); $langs = $newlangs3; + $this->assertEquals(1, price2num('1.000', '', 2), 'Test 1.000 give 1 with french language if user input'); $this->assertEquals(1, price2num('1.000'), 'Test 1.000 give 1 with french language'); $this->assertEquals(1000, price2num('1 000'), 'Test 1.000 give 1 with french language'); + $this->assertEquals(1.234, price2num('1.234', '', 2), 'Test 1.234 give 1.234 with french language if user input'); $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with french language'); + $this->assertEquals(1.234, price2num('1,234', '', 2), 'Test 1,234 give 1.234 with french language if user input'); $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with french language'); $this->assertEquals(21500000, price2num('21500 000'), 'Test 21500 000 give 21500000 with french language'); $this->assertEquals(21500000, price2num('21 500 000'), 'Test 21 500 000 give 21500000 with french language'); From 4a5cdd00921b19b32945332aede507c31d479c01 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 15:27:35 +0100 Subject: [PATCH 3/3] Several fixes in export and repair tool --- htdocs/core/class/interfaces.class.php | 2 +- htdocs/core/modules/modBom.class.php | 1 + htdocs/core/modules/modCategorie.class.php | 50 +++------------------- htdocs/exports/class/export.class.php | 1 + htdocs/install/repair.php | 3 +- 5 files changed, 12 insertions(+), 45 deletions(-) diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php index 4199e51cb68..3f542f845b9 100644 --- a/htdocs/core/class/interfaces.class.php +++ b/htdocs/core/class/interfaces.class.php @@ -212,7 +212,7 @@ class Interfaces if ($result < 0) { // Action KO - //dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($objMod->errors), LOG_ERR); + //dol_syslog("Error in trigger ".$action." - result = ".$result." - Nb of error strings returned = ".count($objMod->errors), LOG_ERR); $nbtotal++; $nbko++; if (!empty($objMod->errors)) $this->errors = array_merge($this->errors, $objMod->errors); diff --git a/htdocs/core/modules/modBom.class.php b/htdocs/core/modules/modBom.class.php index 7258541a7da..062b89d218d 100644 --- a/htdocs/core/modules/modBom.class.php +++ b/htdocs/core/modules/modBom.class.php @@ -300,6 +300,7 @@ class modBom extends DolibarrModules $this->export_dependencies_array[$r] = array('bomline'=>'tl.rowid'); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields) $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'bom_bom as t'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bom_bom_extrafields as extra on (t.rowid = extra.fk_object)'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bom_bomline as tl ON tl.fk_bom = t.rowid'; $this->export_sql_end[$r] .= ' WHERE 1 = 1'; $this->export_sql_end[$r] .= ' AND t.entity IN ('.getEntity('bom').')'; diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index 4f0c1e04307..0ea473ed95b 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -176,56 +176,20 @@ class modCategorie extends DolibarrModules 's.idprof4'=>"company", 's.tva_intra'=>"company", 's.capital'=>"company", 's.note_public'=>"company", 's.fk_prospectlevel'=>'company', 's.fk_stcomm'=>'company' ); // We define here only fields that use another picto + + $keyforselect = 'societe'; $keyforelement = 'company'; $keyforaliasextra = 'extrasoc'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '; $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'categorie_societe as cf, '; - $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object '; + $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extrasoc ON s.rowid = extrasoc.fk_object '; $this->export_sql_end[$r] .= ' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid'; $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')'; $this->export_sql_end[$r] .= ' AND u.type = 2'; // Customer/Prospect categories - // Add extra fields - $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) // This can fail when class is used on old database (during migration for example) - { - while ($obj = $this->db->fetch_object($resql)) - { - $fieldname = 'extra.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $typeFilter = "Text"; - switch ($obj->type) - { - case 'int': - case 'double': - case 'price': - $typeFilter = "Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter = "Date"; - break; - case 'boolean': - $typeFilter = "Boolean"; - break; - case 'sellist': - $typeFilter = "List:".$obj->param; - break; - case 'select': - $typeFilter = "Select:".$obj->param; - break; - } - $this->export_fields_array[$r][$fieldname] = $fieldlabel; - $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; - $this->export_entities_array[$r][$fieldname] = 'company'; - } - } - // End add axtra fields - - - - - $r++; $this->export_code[$r] = 'category_'.$r; $this->export_label[$r] = 'CatProdList'; diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php index 978a3059ace..6b939dca247 100644 --- a/htdocs/exports/class/export.class.php +++ b/htdocs/exports/class/export.class.php @@ -102,6 +102,7 @@ class Export // Search module files while (($file = readdir($handle)) !== false) { + $reg = array(); if (is_readable($dir.$file) && preg_match("/^(mod.*)\.class\.php$/i", $file, $reg)) { $modulename = $reg[1]; diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 034741c7c7e..e0402bb88a1 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -231,7 +231,7 @@ if ($ok && GETPOST('standard', 'alpha')) $listofmodulesextra = array('societe'=>'societe', 'adherent'=>'adherent', 'product'=>'product', 'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture', 'supplier_proposal'=>'supplier_proposal', 'commande_fournisseur'=>'commande_fournisseur', 'facture_fourn'=>'facture_fourn', - 'actioncomm'=>'actioncomm', + 'actioncomm'=>'actioncomm', 'bom_bom'=>'bom_bom', 'mrp_mo'=>'mrp_mo', 'adherent_type'=>'adherent_type', 'user'=>'user', 'projet'=>'projet', 'projet_task'=>'projet_task'); print '
*** Check fields into extra table structure match table of definition. If not add column into table'; foreach ($listofmodulesextra as $tablename => $elementtype) @@ -268,6 +268,7 @@ if ($ok && GETPOST('standard', 'alpha')) $arrayoffieldsfound[$fieldname] = array('type'=>$fieldtype); } + // If it does not match, we create fields foreach ($arrayoffieldsdesc as $code => $label) {