Use of . as thousand separator. Can use it for decimal if not 3 digits.

This commit is contained in:
Laurent Destailleur 2020-11-24 10:56:05 +01:00
parent 5822fcfbed
commit 53208e620e
2 changed files with 33 additions and 21 deletions

View File

@ -4691,19 +4691,19 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $
* Function to use on each input amount before any numeric test or database insert. A better name for this function
* should be roundtext2num().
*
* @param float $amount Amount to convert/clean or round
* @param string $rounding ''=No rounding
* 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT)
* 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT)
* '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
* @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..
* @param string|float $amount Amount to convert/clean or round
* @param string $rounding ''=No rounding
* 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT)
* 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT)
* '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
* @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
* @see price() Opposite function of price2num
*/
function price2num($amount, $rounding = '', $alreadysqlnb = 0)
{
@ -4720,15 +4720,15 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0)
//print "amount=".$amount." html=".$form." trunc=".$trunc." nbdecimal=".$nbdecimal." dec='".$dec."' thousand='".$thousand."'<br>";
// 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 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'<br>';
if ($alreadysqlnb != 1) { // If not a PHP number or unknown, we change or clean format
print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'<br>';
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
print 'TTTT'.$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.
if ($thousand == '.') {
$amount = str_replace($thousand, '', $amount); // Replace of thousand before test of is_numeric to avoid pb if thousand is .
}
if (is_numeric($amount))
{
// We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10
@ -4738,7 +4738,7 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0)
$amount = number_format($amount, $nbofdec, $dec, $thousand);
}
//print "QQ".$amount.'<br>';
// Now make replace (the main goal of function)
if ($thousand != ',' && $thousand != '.') {
$amount = str_replace(',', '.', $amount); // To accept 2 notations for french users

View File

@ -1260,10 +1260,18 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase
$newlangs2->load("main");
$langs = $newlangs2;
$this->assertEquals(1000, price2num('1.000'), 'Test 1.000 give 1000 with spanish language');
$this->assertEquals(1000, price2num('1 000'), 'Test 1 000 give 1000 with spanish language');
// 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'), '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(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');
// For french language
$newlangs3 = new Translate('', $conf);
@ -1275,6 +1283,10 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase
$this->assertEquals(1000, price2num('1 000'), 'Test 1.000 give 1 with french language');
$this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with french language');
$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');
$this->assertEquals(21500, price2num('21500.00'), 'Test 21500.00 give 21500 with french language');
$this->assertEquals(21500, price2num('21500,00'), 'Test 21500,00 give 21500 with french language');
$langs = $oldlangs;