support simple arithmetic (only + and -) for monetary amounts
This commit is contained in:
parent
3470ebeb1c
commit
3dab71fdbf
3 changed files with 77 additions and 2 deletions
|
@ -29,7 +29,26 @@ sub import {
|
|||
defined $amount or return undef;
|
||||
length $amount or return undef;
|
||||
|
||||
$amount = RevBank::Amount->parse_string($amount) // return undef;
|
||||
my @split = grep /\S/, split /([+-])/, $amount;
|
||||
|
||||
my $posneg = 1;
|
||||
$amount = RevBank::Amount->new(0);
|
||||
for my $token (@split) {
|
||||
if ($token eq '-') {
|
||||
$posneg = $posneg == -1 ? 1 : -1;
|
||||
} elsif ($token eq '+') {
|
||||
next if $posneg == -1; # -+
|
||||
$posneg ||= 1;
|
||||
next;
|
||||
} else {
|
||||
$posneg or return undef; # two terms in a row
|
||||
my $term = RevBank::Amount->parse_string($token) // return undef;
|
||||
$amount += $posneg * $term;
|
||||
$posneg = 0;
|
||||
}
|
||||
}
|
||||
$posneg and return undef; # last token must be term
|
||||
|
||||
if ($amount->cents < 0) {
|
||||
die "For our sanity, no negative amounts, please :).\n";
|
||||
}
|
||||
|
|
2
revbank
2
revbank
|
@ -17,7 +17,7 @@ use RevBank::Global;
|
|||
use RevBank::Messages;
|
||||
use RevBank::Cart;
|
||||
|
||||
our $VERSION = "4.2.4";
|
||||
our $VERSION = "4.3.0";
|
||||
our %HELP1 = (
|
||||
"abort" => "Abort the current transaction",
|
||||
);
|
||||
|
|
56
t/calc.t
Normal file
56
t/calc.t
Normal file
|
@ -0,0 +1,56 @@
|
|||
use v5.32;
|
||||
|
||||
use Test::More;
|
||||
use Test::Exception;
|
||||
use Test::Warnings ":all";
|
||||
|
||||
BEGIN { use_ok('RevBank::Global'); }
|
||||
|
||||
dies_ok sub { parse_amount("-1") };
|
||||
dies_ok sub { parse_amount("0-42") };
|
||||
dies_ok sub { parse_amount("999999") };
|
||||
|
||||
is parse_amount("0.123"), undef;
|
||||
is parse_amount("42.000"), undef;
|
||||
is parse_amount("a"), undef;
|
||||
is parse_amount("(1+1)"), undef;
|
||||
|
||||
is parse_amount("42")->cents, 4200;
|
||||
is parse_amount("42.0")->cents, 4200;
|
||||
is parse_amount("42.00")->cents, 4200;
|
||||
is parse_amount("1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1")->cents, 4200;
|
||||
|
||||
is parse_amount("-42+42")->cents, 0;
|
||||
is parse_amount("+42")->cents, 4200;
|
||||
is parse_amount("--42")->cents, 4200;
|
||||
is parse_amount("+42-42")->cents, 0;
|
||||
is parse_amount("0--42")->cents, 4200;
|
||||
is parse_amount("0++42")->cents, 4200;
|
||||
is parse_amount("42+-42")->cents, 0;
|
||||
is parse_amount("42-+42")->cents, 0;
|
||||
is parse_amount("0+42")->cents, 4200;
|
||||
is parse_amount("42-42")->cents, 0;
|
||||
|
||||
is parse_amount(" - 42 + 42")->cents, 0;
|
||||
is parse_amount(" + 42 ")->cents, 4200;
|
||||
is parse_amount(" - - 42 ")->cents, 4200;
|
||||
is parse_amount(" + 42 - 42 ")->cents, 0;
|
||||
is parse_amount(" 0 - - 42 ")->cents, 4200;
|
||||
is parse_amount(" 0 + + 42 ")->cents, 4200;
|
||||
is parse_amount(" 42 + - 42 ")->cents, 0;
|
||||
is parse_amount(" 42 - + 42 ")->cents, 0;
|
||||
is parse_amount(" 0 + 42 ")->cents, 4200;
|
||||
is parse_amount(" 42 - 42 ")->cents, 0;
|
||||
|
||||
is parse_amount("-4.20+4.20")->cents, 0;
|
||||
is parse_amount("+4.20")->cents, 420;
|
||||
is parse_amount("--4.20")->cents, 420;
|
||||
is parse_amount("+4.20-4.20")->cents, 0;
|
||||
is parse_amount("0--4.20")->cents, 420;
|
||||
is parse_amount("0++4.20")->cents, 420;
|
||||
is parse_amount("4.20+-4.20")->cents, 0;
|
||||
is parse_amount("4.20-+4.20")->cents, 0;
|
||||
is parse_amount("0+4.20")->cents, 420;
|
||||
is parse_amount("4.20-4.20")->cents, 0;
|
||||
|
||||
done_testing;
|
Loading…
Add table
Reference in a new issue