1 package Koha
::Account
::Line
;
3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 use C4
::Log
qw(logaction);
25 use Koha
::Account
::DebitType
;
26 use Koha
::Account
::Offsets
;
28 use Koha
::Exceptions
::Account
;
31 use base
qw(Koha::Object);
37 Koha::Account::Line - Koha accountline Object class
47 Return the patron linked to this account line
53 my $rs = $self->_result->borrowernumber;
55 return Koha
::Patron
->_new_from_dbic( $rs );
60 Return the item linked to this account line if exists
66 my $rs = $self->_result->itemnumber;
68 return Koha
::Item
->_new_from_dbic( $rs );
73 Return the checkout linked to this account line if exists
79 return unless $self->issue_id ;
81 $self->{_checkout
} ||= Koha
::Checkouts
->find( $self->issue_id );
82 $self->{_checkout
} ||= Koha
::Old
::Checkouts
->find( $self->issue_id );
83 return $self->{_checkout
};
88 Return the debit_type linked to this account line
94 my $rs = $self->_result->debit_type_code;
96 return Koha
::Account
::DebitType
->_new_from_dbic( $rs );
101 $payment_accountline->void();
103 Used to 'void' (or reverse) a payment/credit. It will roll back any offsets
104 created by the application of this credit upon any debits and mark the credit
105 as 'void' by updating it's status to "VOID".
112 # Make sure it is a payment we are voiding
113 return unless $self->amount < 0;
115 my @account_offsets =
116 Koha
::Account
::Offsets
->search(
117 { credit_id
=> $self->id, amount
=> { '<' => 0 } } );
119 $self->_result->result_source->schema->txn_do(
121 foreach my $account_offset (@account_offsets) {
123 Koha
::Account
::Lines
->find( $account_offset->debit_id );
125 next unless $fee_paid;
127 my $amount_paid = $account_offset->amount * -1; # amount paid is stored as a negative amount
128 my $new_amount = $fee_paid->amountoutstanding + $amount_paid;
129 $fee_paid->amountoutstanding($new_amount);
132 Koha
::Account
::Offset
->new(
134 credit_id
=> $self->id,
135 debit_id
=> $fee_paid->id,
136 amount
=> $amount_paid,
137 type
=> 'Void Payment',
142 if ( C4
::Context
->preference("FinesLog") ) {
145 $self->borrowernumber,
148 action
=> 'void_payment',
149 borrowernumber
=> $self->borrowernumber,
150 amount
=> $self->amount,
151 amountoutstanding
=> $self->amountoutstanding,
152 description
=> $self->description,
153 credit_type_code
=> $self->credit_type_code,
154 payment_type
=> $self->payment_type,
156 itemnumber
=> $self->itemnumber,
157 manager_id
=> $self->manager_id,
159 [ map { $_->unblessed } @account_offsets ],
168 amountoutstanding
=> 0,
180 my $debits = $account->outstanding_debits;
181 my $outstanding_amount = $credit->apply( { debits => $debits, [ offset_type => $offset_type ] } );
183 Applies the credit to a given debits array reference.
185 =head4 arguments hashref
189 =item debits - Koha::Account::Lines object set of debits
191 =item offset_type (optional) - a string indicating the offset type (valid values are those from
192 the 'account_offset_types' table)
199 my ( $self, $params ) = @_;
201 my $debits = $params->{debits
};
202 my $offset_type = $params->{offset_type
} // 'Credit Applied';
204 unless ( $self->is_credit ) {
205 Koha
::Exceptions
::Account
::IsNotCredit
->throw(
206 error
=> 'Account line ' . $self->id . ' is not a credit'
210 my $available_credit = $self->amountoutstanding * -1;
212 unless ( $available_credit > 0 ) {
213 Koha
::Exceptions
::Account
::NoAvailableCredit
->throw(
214 error
=> 'Outstanding credit is ' . $available_credit . ' and cannot be applied'
218 my $schema = Koha
::Database
->new->schema;
220 $schema->txn_do( sub {
221 for my $debit ( @
{$debits} ) {
223 unless ( $debit->is_debit ) {
224 Koha
::Exceptions
::Account
::IsNotDebit
->throw(
225 error
=> 'Account line ' . $debit->id . 'is not a debit'
228 my $amount_to_cancel;
229 my $owed = $debit->amountoutstanding;
231 if ( $available_credit >= $owed ) {
232 $amount_to_cancel = $owed;
234 else { # $available_credit < $debit->amountoutstanding
235 $amount_to_cancel = $available_credit;
238 # record the account offset
239 Koha
::Account
::Offset
->new(
240 { credit_id
=> $self->id,
241 debit_id
=> $debit->id,
242 amount
=> $amount_to_cancel * -1,
243 type
=> $offset_type,
247 $available_credit -= $amount_to_cancel;
249 $self->amountoutstanding( $available_credit * -1 )->store;
250 $debit->amountoutstanding( $owed - $amount_to_cancel )->store;
252 # Same logic exists in Koha::Account::pay
253 if ( $debit->amountoutstanding == 0
254 && $debit->itemnumber
255 && $debit->debit_type_code
256 && $debit->debit_type_code eq 'LOST' )
258 C4
::Circulation
::ReturnLostItem
( $self->borrowernumber, $debit->itemnumber );
264 return $available_credit;
269 This method allows updating a debit or credit on a patron's account
271 $account_line->adjust(
274 type => $update_type,
275 interface => $interface
279 $update_type can be any of:
282 Authors Note: The intention here is that this method is only used
283 to adjust accountlines where the final amount is not yet known/fixed.
284 Incrementing fines are the only existing case at the time of writing,
285 all other forms of 'adjustment' should be recorded as distinct credits
286 or debits and applied, via an offset, to the corresponding debit or credit.
291 my ( $self, $params ) = @_;
293 my $amount = $params->{amount
};
294 my $update_type = $params->{type
};
295 my $interface = $params->{interface
};
297 unless ( exists($Koha::Account
::Line
::allowed_update
->{$update_type}) ) {
298 Koha
::Exceptions
::Account
::UnrecognisedType
->throw(
299 error
=> 'Update type not recognised'
303 my $debit_type_code = $self->debit_type_code;
304 my $account_status = $self->status;
308 $Koha::Account
::Line
::allowed_update
->{$update_type}
311 && ( $Koha::Account
::Line
::allowed_update
->{$update_type}
312 ->{$debit_type_code} eq $account_status )
316 Koha
::Exceptions
::Account
::UnrecognisedType
->throw(
317 error
=> 'Update type not allowed on this debit_type' );
320 my $schema = Koha
::Database
->new->schema;
325 my $amount_before = $self->amount;
326 my $amount_outstanding_before = $self->amountoutstanding;
327 my $difference = $amount - $amount_before;
328 my $new_outstanding = $amount_outstanding_before + $difference;
330 my $offset_type = $debit_type_code;
331 $offset_type .= ( $difference > 0 ) ?
"_INCREASE" : "_DECREASE";
333 # Catch cases that require patron refunds
334 if ( $new_outstanding < 0 ) {
336 Koha
::Patrons
->find( $self->borrowernumber )->account;
337 my $credit = $account->add_credit(
339 amount
=> $new_outstanding * -1,
340 description
=> 'Overpayment refund',
342 interface
=> $interface,
343 ( $update_type eq 'overdue_update' ?
( item_id
=> $self->itemnumber ) : ()),
346 $new_outstanding = 0;
349 # Update the account line
354 amountoutstanding => $new_outstanding,
358 # Record the account offset
359 my $account_offset = Koha::Account::Offset->new(
361 debit_id => $self->id,
362 type => $offset_type,
363 amount => $difference
367 if ( C4::Context->preference("FinesLog") ) {
369 "FINES", 'UPDATE
', #undef becomes UPDATE in UpdateFine
370 $self->borrowernumber,
372 { action => $update_type,
373 borrowernumber => $self->borrowernumber,
375 description => undef,
376 amountoutstanding => $new_outstanding,
377 debit_type_code => $self->debit_type_code,
379 itemnumber => $self->itemnumber,
383 ) if ( $update_type eq 'overdue_update
' );
393 my $bool = $line->is_credit;
400 return ( $self->amount < 0 );
405 my $bool = $line->is_debit;
412 return !$self->is_credit;
415 =head3 to_api_mapping
417 This method returns the mapping for representing a Koha::Account::Line object
424 accountlines_id => 'account_line_id
',
425 credit_type_code => 'credit_type
',
426 debit_type_code => 'debit_type
',
427 amountoutstanding => 'amount_outstanding
',
428 borrowernumber => 'patron_id
',
429 branchcode => 'library_id
',
430 issue_id => 'checkout_id
',
431 itemnumber => 'item_id
',
432 manager_id => 'user_id
',
433 note => 'internal_note
',
437 =head2 Internal methods
446 return 'Accountline
';
453 =head3 $allowed_update
457 our $allowed_update = { 'overdue_update
' => { 'OVERDUE
' => 'UNRETURNED
' } };
461 Kyle M Hall <kyle@bywatersolutions.com >
462 Tomás Cohen Arazi <tomascohen@theke.io>
463 Martin Renvoize <martin.renvoize@ptfs-europe.com>