Bug 21909: Make Koha::Account::outstanding_* preserve context
[srvgit] / Koha / Account.pm
index 2db8d0d..304d0e2 100644 (file)
@@ -85,14 +85,9 @@ sub pay {
     my $patron = Koha::Patrons->find( $self->{patron_id} );
 
     # We should remove accountno, it is no longer needed
-    my $last = Koha::Account::Lines->search(
-        {
-            borrowernumber => $self->{patron_id}
-        },
-        {
-            order_by => 'accountno'
-        }
-    )->next();
+    my $last = $self->lines->search(
+        {},
+        { order_by => 'accountno' } )->next();
     my $accountno = $last ? $last->accountno + 1 : 1;
 
     my $manager_id = $userenv ? $userenv->{number} : 0;
@@ -156,9 +151,8 @@ sub pay {
     # than the what was owed on the given line. In that case pay down other
     # lines with remaining balance.
     my @outstanding_fines;
-    @outstanding_fines = Koha::Account::Lines->search(
+    @outstanding_fines = $self->lines->search(
         {
-            borrowernumber    => $self->{patron_id},
             amountoutstanding => { '>' => 0 },
         }
     ) if $balance_remaining > 0;
@@ -350,7 +344,8 @@ sub add_credit {
     $schema->txn_do(
         sub {
             # We should remove accountno, it is no longer needed
-            my $last = Koha::Account::Lines->search( { borrowernumber => $self->{patron_id} },
+            my $last = $self->lines->search(
+                {},
                 { order_by => 'accountno' } )->next();
             my $accountno = $last ? $last->accountno + 1 : 1;
 
@@ -421,19 +416,7 @@ Return the balance (sum of amountoutstanding columns)
 
 sub balance {
     my ($self) = @_;
-    my $fines = Koha::Account::Lines->search(
-        {
-            borrowernumber => $self->{patron_id},
-        },
-        {
-            select => [ { sum => 'amountoutstanding' } ],
-            as => ['total_amountoutstanding'],
-        }
-    );
-
-    return ( $fines->count )
-      ? $fines->next->get_column('total_amountoutstanding') + 0
-      : 0;
+    return $self->lines->total_outstanding;
 }
 
 =head3 outstanding_debits
@@ -445,14 +428,12 @@ my $lines = Koha::Account->new({ patron_id => $patron_id })->outstanding_debits;
 sub outstanding_debits {
     my ($self) = @_;
 
-    my $lines = Koha::Account::Lines->search(
+    return $self->lines->search(
         {
-            borrowernumber    => $self->{patron_id},
+            amount            => { '>' => 0 },
             amountoutstanding => { '>' => 0 }
         }
     );
-
-    return $lines;
 }
 
 =head3 outstanding_credits
@@ -464,14 +445,12 @@ my $lines = Koha::Account->new({ patron_id => $patron_id })->outstanding_credits
 sub outstanding_credits {
     my ($self) = @_;
 
-    my $lines = Koha::Account::Lines->search(
+    return $self->lines->search(
         {
-            borrowernumber    => $self->{patron_id},
+            amount            => { '<' => 0 },
             amountoutstanding => { '<' => 0 }
         }
     );
-
-    return $lines;
 }
 
 =head3 non_issues_charges
@@ -509,19 +488,58 @@ sub non_issues_charges {
     }
     @not_fines = map { substr( $_, 0, $ACCOUNT_TYPE_LENGTH ) } uniq(@not_fines);
 
-    my $non_issues_charges = Koha::Account::Lines->search(
+    return $self->lines->search(
         {
-            borrowernumber => $self->{patron_id},
             accounttype    => { -not_in => \@not_fines }
         },
+    )->total_outstanding;
+}
+
+=head3 lines
+
+my $lines = $self->lines;
+
+Return all credits and debits for the user, outstanding or otherwise
+
+=cut
+
+sub lines {
+    my ($self) = @_;
+
+    return Koha::Account::Lines->search(
         {
-            select => [ { sum => 'amountoutstanding' } ],
-            as     => ['non_issues_charges'],
+            borrowernumber => $self->{patron_id},
         }
     );
-    return $non_issues_charges->count
-      ? $non_issues_charges->next->get_column('non_issues_charges') + 0
-      : 0;
+}
+
+=head3 reconcile_balance
+
+$account->reconcile_balance();
+
+Find outstanding credits and use them to pay outstanding debits.
+Currently, this implicitly uses the 'First In First Out' rule for
+applying credits against debits.
+
+=cut
+
+sub reconcile_balance {
+    my ($self) = @_;
+
+    my $outstanding_debits  = $self->outstanding_debits;
+    my $outstanding_credits = $self->outstanding_credits;
+
+    while (     $outstanding_debits->total_outstanding > 0
+            and my $credit = $outstanding_credits->next )
+    {
+        # there's both outstanding debits and credits
+        $credit->apply( { debits => $outstanding_debits } );    # applying credit, no special offset
+
+        $outstanding_debits = $self->outstanding_debits;
+
+    }
+
+    return $self;
 }
 
 1;
@@ -535,7 +553,7 @@ sub non_issues_charges {
 our $offset_type = {
     'credit'           => 'Manual Credit',
     'forgiven'         => 'Writeoff',
-    'lost_item_return' => 'Lost Item Return',
+    'lost_item_return' => 'Lost Item',
     'payment'          => 'Payment',
     'writeoff'         => 'Writeoff'
 };