From d431be119054acf725095a52567b1a2c8fd35c05 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 8 Nov 2013 13:50:35 -0500 Subject: [PATCH] LP#1249398 clear negative balance (p2) Signed-off-by: Bill Erickson --- .../perlmods/lib/OpenILS/Application/Circ/Money.pm | 74 ++++++++++++++++++---- 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Money.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Money.pm index 91aec13519..a6e1148217 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Money.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Money.pm @@ -954,22 +954,22 @@ sub retrieve_credit_payable_balance { __PACKAGE__->register_method( method => 'zeroize_transaction', api_name => 'open-ils.circ.money.zeroize_transaction', - stream => 1, - authoritative => 1, signature => { desc => q/ - Given a negative-balance transaction, juggles the void - payment(s) to produce a zero-balance transaction, without - affecting any of the billings or real patron payments. + Given a list of negative-balance transactions, deletes or + modifies (as appropriate) void payment(s) on the transaction + to produce a zero-balance transaction, without affecting any + of the billings or real patron payments. + Transactions which do not have a negative balance will be + ignored. /, params => [ {desc => 'Authtoken', type => 'string'}, {desc => 'Array of transaction IDs', type => 'array'} ], - return { - desc => q/A stream of transaction summaries, one for - each transaction updated. On error, the final item - in the stream will be an Event./ + return { + desc => q/Array of IDs for each transaction updated, + Event on error./ } } ); @@ -977,11 +977,57 @@ __PACKAGE__->register_method( sub zeroize_transaction { my ($self, $client, $auth, $xact_ids) = @_; my $e = new_editor(xact => 1, authtoken => $auth); - return $e->event unless $e->checkauth; + return $e->die_event unless $e->checkauth; # in case a bare ID is passed $xact_ids = [$xact_ids] unless ref $xact_ids; + # going newest to oldest, delete void payments which cause the + # transaction to remain negative. Once we locate the void payment + # which causes the transaction to reach or exceed a $0 balance, + # delete or modify as needed, then we're done. + sub zeroize_one { + my ($e, $xact) = @_; + + my $void_payments = $e->search_money_void_payment([ + {xact => $xact->id}, + {order_by => {mvp => 'payment_ts desc'}} + ]); + + # cast to postive so we can use fpdiff(); + my $target = -$xact->balance_owed; + for my $payment (@$void_payments) { + my $remainder = $U->fpdiff($target, $payment->amount); + + if ($remainder >= 0) { + # void payment is not large enough to bring us over $0, + # we are clear to delete the whole payment. + $e->delete_money_void_payment($payment) + or return $e->die_event; + + $target = $remainder; + return if $target == 0; # all done + + } else { + # modify the payment. + # here the remainder is negative, so the new payment + # amount is the old amount plus the remainder or, IOW, + # the payment amount minus the negative remainder. + + my $new_amount = $U->fpdiff($payment->amount, -$remainder); + $logger->info("modifying void payment to $new_amount ". + "in zeroize_transaction"); + + $payment->amount($new_amount); + $e->update_money_void_payment($payment) or return $e->die_event; + + # we've reached $0, all done. + return; + } + } + } + + my @modified; for my $xact_id (@$xact_ids) { my $xact = $e->retrieve_money_billable_transaction_summary([ @@ -995,11 +1041,13 @@ sub zeroize_transaction { return $e->die_event unless $e->allowed('CREATE_PAYMENT', $xact->usr->home_ou); - # TODO: do the void payment juggling - #my $new_amount = $U->fpdiff($bill->amount(),$void->amount()); + my $evt = zeroize_one($e, $xact); + return $evt if $evt; + push(@modified, $xact->id); } - return; + $e->commit; + return \@modified; } -- 2.11.0