Commit 0533f794 authored by Thorsten Buss's avatar Thorsten Buss

add parseWithTax()

parent fa027149
......@@ -48,6 +48,38 @@ class Money implements \JsonSerializable, Jsonable, Arrayable {
$this->currency = $currency;
}
/**
* @param $money
* @return string
* @throws MoneyException
*/
protected static function parseStringToUnit($money) {
$matches = null;
$sign = "(?P<sign>[-\+])?";
$digits1 = "(?P<digits1>\d*?)";
$separator1 = '(?P<separator1>[.,])??';
$digits2 = "(?P<digits2>\d*)";
$separator2 = '(?P<separator2>[.,])?';
$decimals = "(?P<decimal1>\d)?(?P<decimal2>\d)?";
$pattern = '/^' . $sign . $digits1 . $separator1 . $digits2 . $separator2 . $decimals . '$/';
if (!preg_match($pattern, trim($money), $matches)) {
throw new MoneyException('The value could not be parsed as money');
}
$units = $matches['sign'] === '-' ? '-' : '';
$units .= $matches['digits1'] . $matches['digits2'];
$units .= isset($matches['decimal1']) ? $matches['decimal1'] : '0';
$units .= isset($matches['decimal2']) ? $matches['decimal2'] : '0';
if ($matches['sign'] === '-') {
$units = '-' . ltrim(substr($units, 1), '0');
} else {
$units = ltrim($units, '0');
}
if ($units === '' || $units === '-') {
$units = '0';
}
return $units;
}
public function value() {
return $this->amount();
......@@ -151,34 +183,12 @@ class Money implements \JsonSerializable, Jsonable, Arrayable {
*/
public static function parse($money, $currency=null) {
if (!is_string($money)) {
throw new MoneyException('Formatted raw money should be string, e.g. $1.00');
throw new MoneyException('Formatted raw money should be string, e.g. 1.00');
}
if (!$currency instanceof Currency)
$currency = new Currency($currency);
$sign = "(?P<sign>[-\+])?";
$digits1 = "(?P<digits1>\d*?)";
$separator1 = '(?P<separator1>[.,])??';
$digits2 = "(?P<digits2>\d*)";
$separator2 = '(?P<separator2>[.,])?';
$decimals = "(?P<decimal1>\d)?(?P<decimal2>\d)?";
$pattern = '/^' . $sign . $digits1 . $separator1 .$digits2 . $separator2 . $decimals . '$/';
if (!preg_match($pattern, trim($money), $matches)) {
throw new MoneyException('The value could not be parsed as money');
}
$units = $matches['sign'] === '-' ? '-' : '';
$units .= $matches['digits1']. $matches['digits2'];
$units .= isset($matches['decimal1']) ? $matches['decimal1'] : '0';
$units .= isset($matches['decimal2']) ? $matches['decimal2'] : '0';
if ($matches['sign'] === '-') {
$units = '-' . ltrim(substr($units, 1), '0');
} else {
$units = ltrim($units, '0');
}
if ($units === '' || $units === '-') {
$units = '0';
}
return new static((int)$units, $currency);
return new static((int)self::parseStringToUnit($money), $currency);
}
/**
......
......@@ -63,6 +63,17 @@ class TaxedMoney extends Money {
return static::fromGross($amount, $tax, $currency);
}
/**
* alias for parseFromGross
* @param int $amount
* @param float $tax tax percentage of the given amount
* @param Currency|string $currency
* @return static
*/
public static function parseFromBrutto($money, $tax, $currency=null) {
return static::parseFromGross($money, $tax, $currency);
}
/**
* create a MoneyObject with the given Amount/Tax as Gross
* @param int $amount
......@@ -74,6 +85,18 @@ class TaxedMoney extends Money {
return new static($amount, $currency, $tax, self::TYPE_GROSS);
}
/**
* create a MoneyObject with the given Amount/Tax as Gross from a string
* @param int $amount
* @param float $tax tax percentage of the given amount
* @param Currency|string $currency
* @return static
*/
public static function parseFromGross($money, $tax, $currency = null) {
return static::parseWithTax($money, $tax, $currency, self::TYPE_GROSS);
}
/**
* alias for fromNet
* @param int $amount
......@@ -85,6 +108,17 @@ class TaxedMoney extends Money {
return static::fromNet($amount, $tax, $currency);
}
/**
* alias for parseFromNet
* @param int $amount
* @param float $tax tax percentage of the given amount
* @param Currency|string $currency
* @return static
*/
public static function parseFromNetto($money, $tax, $currency = null) {
return static::parseWithTax($money, $tax, $currency, self::TYPE_GROSS);
}
/**
* create a MoneyObject with the given Amount/Tax as Net
* @param int $amount
......@@ -96,6 +130,17 @@ class TaxedMoney extends Money {
return new static($amount, $currency, $tax, self::TYPE_NET);
}
/**
* create a MoneyObject with the given Amount/Tax as Net from a string
* @param int $amount
* @param float $tax tax percentage of the given amount
* @param Currency|string $currency
* @return static
*/
public static function parseFromNet($money, $tax, $currency = null) {
return static::parseWithTax($money, $tax, $currency, self::TYPE_NET);
}
/**
* has this MoneyObj tax options
* @return bool
......@@ -218,4 +263,24 @@ class TaxedMoney extends Money {
return new static($amount, $currency ?: $this->currency(), $this->tax, $this->amount_type, $this->default_return_type);
}
/**
* parse a money string with the given tax
* @param string $money money string without currency sign
* @param int|float $tax
* @param string|Currency $currency
* @param int $input_type
* @param int $default_return_type
* @return static
* @throws MoneyException
*/
public static function parseWithTax($money, $tax, $currency = null, $input_type = self::TYPE_NET, $default_return_type = self::TYPE_GROSS) {
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);
return new static((int)self::parseStringToUnit($money), $currency, $tax, $input_type, $default_return_type);
}
}
\ No newline at end of file
......@@ -126,4 +126,23 @@ class TaxedMoneyTest extends MoneyTest {
$this->assertNotEquals($m1, $m2->divide(2));
}
/**
* test parsing of money strings
* @param $string
* @param $units
* @dataProvider provideStringsMoneyParsing
*/
public function testMoneyWithTaxParsing($string, $units) {
$tax = rand(5,19);
$m = $this->money($units);
try {
$parsed = TaxedMoney::parseWithTax($string, $tax);
$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);
} catch (\Exception $e) {
$this->fail('Exception on Value: ' . $string . ' -> ' . $e->getMessage());
}
}
}
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