From 4efe500ae5129aa6870bca722146bc94d9f9bfd1 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Thu, 15 Sep 2016 15:13:47 -0400 Subject: [PATCH] LP#1282751 Credit card payment balance owed rounding fix Avoid using Perl's int() when summing owed/paid totals for display in the TPAC credit card payment form, since this can lead to rounding errors. A simple example of why we should not use int() when summing floating point numbers: perl -e 'print "no match\n" unless ((8.29 * 100) == int(8.29 * 100))'; Furthermore, use the relatively new fpsum() utility function for summing floating point numbers so we can avoid having multiple versions of the summing logic floating (*cough*) around (*cough cough*). Signed-off-by: Bill Erickson Signed-off-by: Mike Rylander --- .../lib/OpenILS/WWW/EGCatLoader/Account.pm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm index d2be12d789..9896ff23a4 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm @@ -1947,8 +1947,8 @@ sub prepare_fines { } ); - my @total_keys = qw/total_paid total_owed balance_owed/; - $self->ctx->{"fines"}->{@total_keys} = (0, 0, 0); + # Collect $$ amounts from each transaction for summing below. + my (@paid_amounts, @owed_amounts, @balance_amounts); while(my $resp = $req->recv) { my $mobts = $resp->content; @@ -1960,10 +1960,9 @@ sub prepare_fines { $last_billing = pop(@billings); } - # XXX TODO confirm that the following, and the later division by 100.0 - # to get a floating point representation once again, is sufficiently - # "money-safe" math. - $self->ctx->{"fines"}->{$_} += int($mobts->$_ * 100) for (@total_keys); + push(@paid_amounts, $mobts->total_paid); + push(@owed_amounts, $mobts->total_owed); + push(@balance_amounts, $mobts->balance_owed); my $marc_xml = undef; if ($mobts->xact_type eq 'reservation' and @@ -1990,7 +1989,10 @@ sub prepare_fines { $cstore->kill_me; - $self->ctx->{"fines"}->{$_} /= 100.0 for (@total_keys); + $self->ctx->{"fines"}->{total_paid} = $U->fpsum(@paid_amounts); + $self->ctx->{"fines"}->{total_owed} = $U->fpsum(@owed_amounts); + $self->ctx->{"fines"}->{balance_owed} = $U->fpsum(@balance_amounts); + return; } -- 2.43.2