LP#1249398 clear negative balance (p3)
authorBill Erickson <berick@esilibrary.com>
Fri, 8 Nov 2013 20:49:35 +0000 (15:49 -0500)
committerBill Erickson <berick@esilibrary.com>
Fri, 8 Nov 2013 20:49:35 +0000 (15:49 -0500)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Money.pm

index a6e1148..ab3c7c4 100644 (file)
@@ -967,7 +967,7 @@ __PACKAGE__->register_method(
             {desc => 'Authtoken', type => 'string'},
             {desc => 'Array of transaction IDs', type => 'array'}
         ],
-        return { 
+        return => 
             desc => q/Array of IDs for each transaction updated, 
             Event on error./ 
         }
@@ -976,6 +976,7 @@ __PACKAGE__->register_method(
 
 sub zeroize_transaction {
     my ($self, $client, $auth, $xact_ids) = @_;
+
     my $e = new_editor(xact => 1, authtoken => $auth);
     return $e->die_event unless $e->checkauth;
 
@@ -994,31 +995,36 @@ sub zeroize_transaction {
             {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);
+
+            # cast balance_owed to postive so we can use fpdiff();
+            my $remainder = $U->fpdiff(-$xact->balance_owed, $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;
+                # delete the whole payment.
+
+                $logger->info("deleting void payment ".$payment->id.
+                    " in zeroize_transaction");
+
+                $e->delete_money_void_payment($payment) or return $e->die_event;
                 
-                $target = $remainder;
-                return if $target == 0; # all done
+                return if $remainder == 0; # all done
+
+                # instead of doing math, fetch the updated transaction
+                # to get the latest value for balance_owed from the DB.
+                $xact = $e->retrieve_money_billable_transaction_summary($xact->id);
 
             } 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.
+                # update the void payment to use the difference between
+                # the amount voided and the amount owed.
+                $remainder = -$remainder; 
+                $payment->amount($remainder);
+                $payment->amount_collected($remainder);
                 
-                my $new_amount = $U->fpdiff($payment->amount, -$remainder);
-                $logger->info("modifying void payment to $new_amount ".
-                    "in zeroize_transaction");
+                $logger->info("modifying void payment ".
+                    $payment->id."; setting amount to $remainder in zeroize");
 
-                $payment->amount($new_amount);
                 $e->update_money_void_payment($payment) or return $e->die_event;
 
                 # we've reached $0, all done.
@@ -1029,6 +1035,7 @@ sub zeroize_transaction {
 
     my @modified;
     for my $xact_id (@$xact_ids) {
+
         my $xact = 
             $e->retrieve_money_billable_transaction_summary([
                 $xact_id, 
@@ -1044,6 +1051,19 @@ sub zeroize_transaction {
         my $evt = zeroize_one($e, $xact);
         return $evt if $evt;
         push(@modified, $xact->id);
+
+        # now we see if we can close the transaction
+        # same logic as make_payments();
+        my $circ = $e->retrieve_action_circulation($xact_id);
+        next if $circ and !$CC->can_close_circ($e, $circ);
+
+        # we don't check to see if the xact is already closed.  since the
+        # xact had a negative balance, it should not have been closed, so
+        # assume 'now' is the real close time regardless.
+        
+        my $trans = $e->retrieve_money_billable_transaction($xact_id);
+        $trans->xact_finish("now");
+        $e->update_money_billable_transaction($trans) or return $e->die_event;
     }
 
     $e->commit;