X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=Koha%2FAccount.pm;h=304d0e2743cbfd49ade62ebe9550b2038d740173;hb=d3ff671f215398ad51a6ce550c33c0c6ca3aa30a;hp=6fe1a84d0206d93166df0ae96ec83a8c664755c3;hpb=a66542d67ba2cd6edb582055d38b1d577dd1be32;p=srvgit diff --git a/Koha/Account.pm b/Koha/Account.pm index 6fe1a84d02..304d0e2743 100644 --- a/Koha/Account.pm +++ b/Koha/Account.pm @@ -23,9 +23,12 @@ use Carp; use Data::Dumper; use List::MoreUtils qw( uniq ); +use C4::Circulation qw( ReturnLostItem ); +use C4::Letters; use C4::Log qw( logaction ); use C4::Stats qw( UpdateStats ); +use Koha::Patrons; use Koha::Account::Lines; use Koha::Account::Offsets; use Koha::DateUtils qw( dt_from_string ); @@ -79,15 +82,12 @@ sub pay { my $userenv = C4::Context->userenv; + 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; @@ -151,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; @@ -260,6 +259,34 @@ sub pay { ); } + if ( C4::Context->preference('UseEmailReceipts') ) { + if ( + my $letter = C4::Letters::GetPreparedLetter( + module => 'circulation', + letter_code => uc("ACCOUNT_$type"), + message_transport_type => 'email', + lang => $patron->lang, + tables => { + borrowers => $self->{patron_id}, + branches => $self->{library_id}, + }, + substitute => { + credit => $payment, + offsets => \@account_offsets, + }, + ) + ) + { + C4::Letters::EnqueueLetter( + { + letter => $letter, + borrowernumber => $self->{patron_id}, + message_transport_type => 'email', + } + ) or warn "can't enqueue letter $letter"; + } + } + return $payment->id; } @@ -281,7 +308,12 @@ my $credit_line = Koha::Account->new({ patron_id => $patron_id })->add_credit( } ); -$credit_type can be any of 'credit', 'payment', 'forgiven' or 'writeoff' +$credit_type can be any of: + - 'credit' + - 'payment' + - 'forgiven' + - 'lost_item_return' + - 'writeoff' =cut @@ -312,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; @@ -346,7 +379,7 @@ sub add_credit { borrowernumber => $self->{patron_id}, accountno => $accountno, } - ); + ) if grep { $type eq $_ } ('payment', 'writeoff') ; if ( C4::Context->preference("FinesLog") ) { logaction( @@ -383,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 @@ -407,14 +428,29 @@ 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 + +my $lines = Koha::Account->new({ patron_id => $patron_id })->outstanding_credits; + +=cut + +sub outstanding_credits { + my ($self) = @_; + + return $self->lines->search( + { + amount => { '<' => 0 }, + amountoutstanding => { '<' => 0 } + } + ); } =head3 non_issues_charges @@ -452,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; @@ -476,10 +551,11 @@ sub non_issues_charges { =cut our $offset_type = { - 'credit' => 'Payment', - 'forgiven' => 'Writeoff', - 'payment' => 'Payment', - 'writeoff' => 'Writeoff' + 'credit' => 'Manual Credit', + 'forgiven' => 'Writeoff', + 'lost_item_return' => 'Lost Item', + 'payment' => 'Payment', + 'writeoff' => 'Writeoff' }; =head3 $account_type @@ -487,10 +563,11 @@ our $offset_type = { =cut our $account_type = { - 'credit' => 'C', - 'forgiven' => 'FOR', - 'payment' => 'Pay', - 'writeoff' => 'W' + 'credit' => 'C', + 'forgiven' => 'FOR', + 'lost_item_return' => 'CR', + 'payment' => 'Pay', + 'writeoff' => 'W' }; =head1 AUTHOR