From 09a304f78143e53ef68ac00fe7a8bf3cd4066846 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 16 Nov 2009 00:19:30 +0000 Subject: [PATCH] Fix: Unit prices of products must use the unit precision and not the total precision. --- htdocs/lib/functions.lib.php | 28 ++++++++++++++++++---------- htdocs/product.class.php | 5 +++-- htdocs/product/price.php | 16 ++++++++-------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/htdocs/lib/functions.lib.php b/htdocs/lib/functions.lib.php index 3de6be90138..4d48d7a8631 100644 --- a/htdocs/lib/functions.lib.php +++ b/htdocs/lib/functions.lib.php @@ -2313,14 +2313,15 @@ function vatrate($rate,$addpercent=false,$info_bits=0) * \param html Type de formatage, html ou pas (par defaut) * \param outlangs Objet langs pour formatage text * \param trunc 1=Tronque affichage si trop de decimales,0=Force le non troncage - * \param rounding Nbre decimals minimum. + * \param rounding Minimum number of decimal. If not defined we use min($conf->global->MAIN_MAX_DECIMALS_UNIT,$conf->global->MAIN_MAX_DECIMALS_TOTAL) * \return string Chaine avec montant formate * \seealso price2num Revert function of price */ -function price($amount, $html=0, $outlangs='', $trunc=1, $rounding=2) +function price($amount, $html=0, $outlangs='', $trunc=1, $rounding=-1) { global $langs,$conf; + if ($rounding < 0) $rounding=min($conf->global->MAIN_MAX_DECIMALS_UNIT,$conf->global->MAIN_MAX_DECIMALS_TOT); $nbdecimal=$rounding; // Output separators by default (french) @@ -2396,13 +2397,16 @@ function price2num($amount,$rounding='',$alreadysqlnb=0) // Convert value to universal number format (no thousand separator, '.' as decimal separator) if ($alreadysqlnb != 1) // If not a PHP number or unknown, we change format { - //print 'ZZ'.$nbofdec.'=>'.$amount.'
'; + //print 'PP'.$amount.' - '.$dec.' - '.$thousand.'
'; // 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. if (is_numeric($amount)) { - $nbofdec=max(0,strlen($amount-intval($amount))-2); + // We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10 + $temps=sprintf("%0.10F",$amount-intval($amount)); // temps=0.0000000000 or 0.0000200000 or 9999.1000000000 + $temps=preg_replace('/([\.1-9])0+$/','\\1',$temps); // temps=0. or 0.00002 or 9999.1 + $nbofdec=max(0,strlen($temps)-2); // -2 to remove "0." $amount=number_format($amount,$nbofdec,$dec,$thousand); } //print "QQ".$amount.'
'; @@ -2422,18 +2426,22 @@ function price2num($amount,$rounding='',$alreadysqlnb=0) elseif ($rounding == 'MT') $nbofdectoround=$conf->global->MAIN_MAX_DECIMALS_TOT; elseif ($rounding == 'MS') $nbofdectoround=$conf->global->MAIN_MAX_DECIMALS_SHOWN; elseif ($rounding == '2') $nbofdectoround=2; // For admin info page + //print "RR".$amount.' - '.$nbofdectoround.'
'; if (strlen($nbofdectoround)) $amount = round($amount,$nbofdectoround); // $nbofdectoround can be 0. else return 'ErrorBadParameterProvidedToFunction'; - //print 'ZZ'.$nbofdec.'-'.$nbofdectoround.'=>'.$amount.'
'; + //print 'SS'.$amount.' - '.$nbofdec.' - '.$dec.' - '.$thousand.' - '.$nbofdectoround.'
'; // 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 defined by Dolibarr setup. if (is_numeric($amount)) { - $nbofdec=max(0,strlen($amount-intval($amount))-2); + // We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10 + $temps=sprintf("%0.10F",$amount-intval($amount)); // temps=0.0000000000 or 0.0000200000 or 9999.1000000000 + $temps=preg_replace('/([\.1-9])0+$/','\\1',$temps); // temps=0. or 0.00002 or 9999.1 + $nbofdec=max(0,strlen($temps)-2); // -2 to remove "0." $amount=number_format($amount,min($nbofdec,$nbofdectoround),$dec,$thousand); // Convert amount to format with dolibarr dec and thousand } - //print "RR".$amount.'
'; + //print "TT".$amount.'
'; // Always make replace because each math function (like round) replace // with local values and we want a number that has a SQL string format x.y @@ -3145,16 +3153,16 @@ function dol_getIdFromCode($db,$key,$tablename,$fieldkey='code',$fieldid='id') function addHelpMessage($inputId,$message) { global $conf; - + $helpMessage = ''; - + if ($conf->use_javascript_ajax) { $helpMessage.= 'style="color: grey;" '; $helpMessage.= 'onFocus="hideMessage(\''.$inputId.'\',\''.$message.'\');" '; $helpMessage.= 'onBlur="displayMessage(\''.$inputId.'\',\''.$message.'\');"'; } - + return $helpMessage; } diff --git a/htdocs/product.class.php b/htdocs/product.class.php index b6e4491ee5c..9de626ec3e2 100644 --- a/htdocs/product.class.php +++ b/htdocs/product.class.php @@ -824,7 +824,7 @@ class Product extends CommonObject { global $conf,$langs; - dol_syslog("Product::update_price id=".$id." newprice=".$newprice." newpricebase=".$newpricebase." newminprice=".$newminprice." level=".$level, LOG_DEBUG); + dol_syslog("Product::update_price id=".$id." newprice=".$newprice." newpricebase=".$newpricebase." newminprice=".$newminprice." level=".$level); // Clean parameters if (empty($this->tva_tx)) $this->tva_tx=0; @@ -863,6 +863,7 @@ class Product extends CommonObject $price_min = price2num($newminprice,'MU'); $price_min_ttc = price2num($newminprice) * (1 + ($newvat / 100)); $price_min_ttc = price2num($price_min_ttc,'MU'); + //print 'X'.$newminprice.'-'.$price_min; } else { @@ -883,7 +884,7 @@ class Product extends CommonObject $sql.= " tva_tx='".price2num($newvat)."'"; $sql.= " WHERE rowid = " . $id; - dol_syslog("Product::update_price sql=".$sql); + dol_syslog("Product::update_price sql=".$sql, LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { diff --git a/htdocs/product/price.php b/htdocs/product/price.php index be558c515d4..30352e05a12 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -86,7 +86,7 @@ if ($_POST["action"] == 'update_price' && ! $_POST["cancel"] && ($user->rights-> $newvat=str_replace('*','',$_POST["tva_tx"]); } - if ($product->update_price($product->id, $newprice, $newpricebase, $user, $newvat,$newprice_min, $level) > 0) + if ($product->update_price($product->id, $newprice, $newpricebase, $user, $newvat, $newprice_min, $level) > 0) { $_GET["action"] = ''; $mesg = '
'.$langs->trans("RecordSaved").'
'; @@ -146,9 +146,9 @@ if($conf->global->PRODUIT_MULTIPRICES) $soc = new Societe($db); $soc->id = $socid; $soc->fetch($socid); - + print ''.$langs->trans("SellingPrice").''; - + if ($product->multiprices_base_type["$soc->price_level"] == 'TTC') { print ''.price($product->multiprices_ttc["$soc->price_level"]); @@ -157,7 +157,7 @@ if($conf->global->PRODUIT_MULTIPRICES) { print ''.price($product->multiprices["$soc->price_level"]); } - + if ($product->multiprices_base_type["$soc->price_level"]) { print ' '.$langs->trans($product->multiprices_base_type["$soc->price_level"]); @@ -167,7 +167,7 @@ if($conf->global->PRODUIT_MULTIPRICES) print ' '.$langs->trans($product->price_base_type); } print ''; - + // Prix mini print ''.$langs->trans("MinPrice").''; if ($product->multiprices_base_type["$soc->price_level"] == 'TTC') @@ -185,7 +185,7 @@ if($conf->global->PRODUIT_MULTIPRICES) for ($i=1; $i<=$conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { print ''.$langs->trans("SellingPrice").' '.$i.''; - + if ($product->multiprices_base_type["$i"] == 'TTC') { print ''.price($product->multiprices_ttc["$i"]); @@ -194,7 +194,7 @@ if($conf->global->PRODUIT_MULTIPRICES) { print ''.price($product->multiprices["$i"]); } - + if ($product->multiprices_base_type["$i"]) { print ' '.$langs->trans($product->multiprices_base_type["$i"]); @@ -204,7 +204,7 @@ if($conf->global->PRODUIT_MULTIPRICES) print ' '.$langs->trans($product->price_base_type); } print ''; - + // Prix mini print ''.$langs->trans("MinPrice").' '.$i.''; if ($product->multiprices_base_type["$i"] == 'TTC')