Commit c05f5b9a authored by Thorsten Buss's avatar Thorsten Buss

add parsing method for Money, depending on the currency (decimal and thousand...

add parsing method for Money, depending on the currency (decimal and thousand separator from currency if given)
parent 6b62b3b0
......@@ -10,7 +10,7 @@
}
],
"require": {
"illuminate/support": "5.*",
"illuminate/support": "5.4.*",
"ext-bcmath": "*",
"ext-json": "*",
"ext-ctype": "*"
......
......@@ -88,6 +88,40 @@ class Money implements \JsonSerializable, Jsonable, Arrayable {
return $units;
}
/**
* Parse a Moneystring
* @param string $money
* @param string|Currency $currency
* @return static
* @throws MoneyException
* @see https://github.com/gerardojbaez/money/blob/master/src/Money.php#L127
*/
protected static function parseStringToUnitWithCurrency($str, $currency) {
// get currency object
$currency = (is_string($currency) ? new Currency($currency) : $currency);
// remove HTML encoded characters: http://stackoverflow.com/a/657670
// special characters that arrive like &0234;
$str = preg_replace("/&#?[a-z0-9]{2,8};/i", '', $str);
// remove all leading non numbers
$str = preg_replace('/^[^0-9\-\+]*/', '', $str);
// remove all thousands separators
if (strlen($currency->thousands_separator)) {
$str = str_replace($currency->thousands_separator, '', $str);
}
if (strlen($currency->decimal_mark)) {
// make decimal separator regex safe
$char = preg_quote($currency->decimal_mark);
// remove all other characters
$str = preg_replace('/[^' . $char . '\-\+\d]/', "", $str);
// convert all decimal seperators to PHP/bcmath safe decimal '.'
$str = preg_replace('/' . $char . '/', ".", $str);
} else {
// for currencies that do not have decimal points
// remove all other characters
$str = preg_replace('/[^\d]/', "", $str);
}
return bcmul($str, $currency->unit_factor);
}
public function value() {
return $this->amount();
......@@ -193,9 +227,16 @@ class Money implements \JsonSerializable, Jsonable, Arrayable {
if (!is_string($money)) {
throw new MoneyException('Formatted raw money should be string, e.g. 1.00');
}
if (!$currency instanceof Currency)
$currency = new Currency($currency);
// parsing with the format from the currency
if (!empty($currency)) {
if (!$currency instanceof Currency)
$currency = new Currency($currency);
return new static((int)self::parseStringToUnitWithCurrency($money, $currency), $currency);
}
// parsing with guessing separators
$currency = new Currency($currency);
return new static((int)self::parseStringToUnit($money), $currency);
}
......
......@@ -296,9 +296,16 @@ class TaxedMoney extends Money {
if (!is_string($money)) {
throw new MoneyException('Formatted raw money should be string, e.g. 1.00');
}
if (!$currency instanceof Currency)
$currency = new Currency($currency);
// parsing with the format from the currency
if (!empty($currency)) {
if (!$currency instanceof Currency)
$currency = new Currency($currency);
return new static((int)self::parseStringToUnitWithCurrency($money, $currency), $currency, $tax, $input_type, $default_return_type);
}
// parsing with guessing separators
$currency = new Currency($currency);
return new static((int)self::parseStringToUnit($money), $currency, $tax, $input_type, $default_return_type);
}
......
......@@ -123,55 +123,109 @@ class MoneyTest extends \PHPUnit_Framework_TestCase {
$this->money('11.1', $this->currency());
$this->fail('No Exception on float-string');
} catch (MoneyException $e) { }
$this->assertTrue(true);
}
public static function provideStringsMoneyParsing() {
return array(
array("1000", 100000),
array("1000.0", 100000),
array("1000.00", 100000),
array("1000.1", 100010),
array("1000.11", 100011),
array("1000,0", 100000),
array("1000,00", 100000),
array("1000,1", 100010),
array("1000,11", 100011),
array("1.000,11", 100011),
array("1.000.11", 100011),
array("1,000,11", 100011),
array("1,000.11", 100011),
array("0.01", 1),
array("0,01", 1),
array("1", 100),
array("-1000", -100000),
array("-1000.0", -100000),
array("-1000.00", -100000),
array("-0.01", -1),
array("-1000,0", -100000),
array("-1000,00", -100000),
array("-0,01", -1),
array("-1", -100),
array("+1000", 100000),
array("+1000.0", 100000),
array("+1000.00", 100000),
array("+0.01", 1),
array("+1000,0", 100000),
array("+1000,00", 100000),
array("+0,01", 1),
array("+1", 100)
);
$usd = Currency::USD();
$eur = Currency::EUR();
return [
[$usd, "1000", 100000],
[$usd, "1000.0", 100000],
[$usd, "1000.00", 100000],
[$usd, "1000.1", 100010],
[$usd, "1000.11", 100011],
[$eur, "1000,0", 100000],
[$eur, "1000,00", 100000],
[$eur, "1000,1", 100010],
[$eur, "1000,11", 100011],
[$eur, "1.000,11", 100011],
[$usd, "1,000.11", 100011],
[$usd, "0.01", 1],
[$eur, "0,01", 1],
[$eur, "1", 100],
[$usd, "1", 100],
[$eur, "-1000", -100000],
[$usd, "-1000", -100000],
[$usd, "-1000.0", -100000],
[$usd, "-1000.00", -100000],
[$usd, "-0.01", -1],
[$eur, "-1000,0", -100000],
[$eur, "-1000,00", -100000],
[$eur, "-0,01", -1],
[$eur, "-1", -100],
[$usd, "-1", -100],
[$eur, "+1000", 100000],
[$usd, "+1000", 100000],
[$usd, "+1000.0", 100000],
[$usd, "+1000.00", 100000],
[$usd, "+0.01", 1],
[$eur, "+1000,0", 100000],
[$eur, "+1000,00", 100000],
[$eur, "+0,01", 1],
[$eur, "+1", 100],
[$usd, "+1", 100],
[$eur, "4.321.000,11", 432100011],
[$usd, "4,321,000.11", 432100011],
[$eur, "7.654.321.000,11", 765432100011],
[$usd, "7,654,321,000.11", 765432100011],
[$eur, "7654.321.000,11", 765432100011],
[$usd, "7654,321,000.11", 765432100011],
// parsing without currency
[null, "1000", 100000],
[null, "1000.0", 100000],
[null, "1000.00", 100000],
[null, "1000.1", 100010],
[null, "1000.11", 100011],
[null, "1000,0", 100000],
[null, "1000,00", 100000],
[null, "1000,1", 100010],
[null, "1000,11", 100011],
[null, "1.000,11", 100011],
[null, "1.000.11", 100011],
[null, "1,000,11", 100011],
[null, "1,000.11", 100011],
[null, "0.01", 1],
[null, "0,01", 1],
[null, "1", 100],
[null, "1", 100],
[null, "-1000", -100000],
[null, "-1000", -100000],
[null, "-1000.0", -100000],
[null, "-1000.00", -100000],
[null, "-0.01", -1],
[null, "-1000,0", -100000],
[null, "-1000,00", -100000],
[null, "-0,01", -1],
[null, "-1", -100],
[null, "-1", -100],
[null, "+1000", 100000],
[null, "+1000", 100000],
[null, "+1000.0", 100000],
[null, "+1000.00", 100000],
[null, "+0.01", 1],
[null, "+1000,0", 100000],
[null, "+1000,00", 100000],
[null, "+0,01", 1],
[null, "+1", 100],
[null, "+1", 100],
];
}
/**
* test parsing of money strings
* @param Currency|null $currency
* @param $string
* @param $units
* @dataProvider provideStringsMoneyParsing
*/
public function testMoneyParsing($string, $units) {
public function testMoneyParsing($currency, $string, $units) {
$m = $this->money($units);
try {
$this->assertEquals($m->value(), Money::parse($string)->value(), 'Value: ' . $string);
$this->assertEquals($m->value(), Money::parse($string, $currency)->value(), 'Value: ' . $string);
} catch (\Exception $e) {
$this->fail('Exception on Value: ' . $string . ' -> ' . $e->getMessage());
}
......@@ -324,6 +378,6 @@ class MoneyTest extends \PHPUnit_Framework_TestCase {
$this->money('');
$this->money(null);
$this->money(0.00);
$this->isTrue();
$this->assertTrue(true);
}
}
......@@ -135,15 +135,16 @@ class TaxedMoneyTest extends MoneyTest {
/**
* test parsing of money strings
* @param Currency|null $currency
* @param $string
* @param $units
* @dataProvider provideStringsMoneyParsing
*/
public function testMoneyWithTaxParsing($string, $units) {
public function testMoneyWithTaxParsing($currency, $string, $units) {
$tax = rand(5,19);
$m = $this->money($units);
try {
$parsed = TaxedMoney::parseWithTax($string, $tax);
$parsed = TaxedMoney::parseWithTax($string, $tax, $currency);
$this->assertEquals($m->value(), $parsed->amountWithoutTax(), 'Value without Tax: ' . $string);
$this->assertEquals(round($m->value() * (($tax / 100) + 1)), $parsed->value(), 'Value with Tax: ' . $string);
$this->assertEquals($tax, $parsed->tax, 'Tax: ' . $string);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment