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
::Offsets
;
27 use Koha
::Exceptions
::Account
;
30 use base
qw(Koha::Object);
36 Koha::Account::Line - Koha accountline Object class
46 Return the item linked to this account line if exists
52 my $rs = $self->_result->itemnumber;
54 return Koha
::Item
->_new_from_dbic( $rs );
59 Return the checkout linked to this account line if exists
65 return unless $self->issue_id ;
67 $self->{_checkout
} ||= Koha
::Checkouts
->find( $self->issue_id );
68 $self->{_checkout
} ||= Koha
::Old
::Checkouts
->find( $self->issue_id );
69 return $self->{_checkout
};
74 $payment_accountline->void();
81 # Make sure it is a payment we are voiding
82 return unless $self->amount < 0;
85 Koha
::Account
::Offsets
->search(
86 { credit_id
=> $self->id, amount
=> { '<' => 0 } } );
88 $self->_result->result_source->schema->txn_do(
90 foreach my $account_offset (@account_offsets) {
92 Koha
::Account
::Lines
->find( $account_offset->debit_id );
94 next unless $fee_paid;
96 my $amount_paid = $account_offset->amount * -1; # amount paid is stored as a negative amount
97 my $new_amount = $fee_paid->amountoutstanding + $amount_paid;
98 $fee_paid->amountoutstanding($new_amount);
101 Koha
::Account
::Offset
->new(
103 credit_id
=> $self->id,
104 debit_id
=> $fee_paid->id,
105 amount
=> $amount_paid,
106 type
=> 'Void Payment',
111 if ( C4
::Context
->preference("FinesLog") ) {
114 $self->borrowernumber,
117 action
=> 'void_payment',
118 borrowernumber
=> $self->borrowernumber,
119 amount
=> $self->amount,
120 amountoutstanding
=> $self->amountoutstanding,
121 description
=> $self->description,
122 accounttype
=> $self->accounttype,
123 payment_type
=> $self->payment_type,
125 itemnumber
=> $self->itemnumber,
126 manager_id
=> $self->manager_id,
128 [ map { $_->unblessed } @account_offsets ],
136 accounttype
=> 'VOID',
137 amountoutstanding
=> 0,
149 my $debits = $account->outstanding_debits;
150 my $outstanding_amount = $credit->apply( { debits => $debits, [ offset_type => $offset_type ] } );
152 Applies the credit to a given debits set.
154 =head4 arguments hashref
158 =item debits - Koha::Account::Lines object set of debits
160 =item offset_type (optional) - a string indicating the offset type (valid values are those from
161 the 'account_offset_types' table)
168 my ( $self, $params ) = @_;
170 my $debits = $params->{debits
};
171 my $offset_type = $params->{offset_type
} // 'Credit Applied';
173 unless ( $self->is_credit ) {
174 Koha
::Exceptions
::Account
::IsNotCredit
->throw(
175 error
=> 'Account line ' . $self->id . ' is not a credit'
179 my $available_credit = $self->amountoutstanding * -1;
181 unless ( $available_credit > 0 ) {
182 Koha
::Exceptions
::Account
::NoAvailableCredit
->throw(
183 error
=> 'Outstanding credit is ' . $available_credit . ' and cannot be applied'
187 my $schema = Koha
::Database
->new->schema;
189 $schema->txn_do( sub {
190 while ( my $debit = $debits->next ) {
192 unless ( $debit->is_debit ) {
193 Koha
::Exceptions
::Account
::IsNotDebit
->throw(
194 error
=> 'Account line ' . $debit->id . 'is not a debit'
197 my $amount_to_cancel;
198 my $owed = $debit->amountoutstanding;
200 if ( $available_credit >= $owed ) {
201 $amount_to_cancel = $owed;
203 else { # $available_credit < $debit->amountoutstanding
204 $amount_to_cancel = $available_credit;
207 # record the account offset
208 Koha
::Account
::Offset
->new(
209 { credit_id
=> $self->id,
210 debit_id
=> $debit->id,
211 amount
=> $amount_to_cancel * -1,
212 type
=> $offset_type,
216 $available_credit -= $amount_to_cancel;
218 $self->amountoutstanding( $available_credit * -1 )->store;
219 $debit->amountoutstanding( $owed - $amount_to_cancel )->store;
223 return $available_credit;
228 This method allows updating a debit or credit on a patron's account
230 $account_line->adjust(
233 type => $update_type,
237 $update_type can be any of:
240 Authors Note: The intention here is that this method is only used
241 to adjust accountlines where the final amount is not yet known/fixed.
242 Incrementing fines are the only existing case at the time of writing,
243 all other forms of 'adjustment' should be recorded as distinct credits
244 or debits and applied, via an offset, to the corresponding debit or credit.
249 my ( $self, $params ) = @_;
251 my $amount = $params->{amount
};
252 my $update_type = $params->{type
};
254 unless ( exists($Koha::Account
::Line
::allowed_update
->{$update_type}) ) {
255 Koha
::Exceptions
::Account
::UnrecognisedType
->throw(
256 error
=> 'Update type not recognised'
260 my $account_type = $self->accounttype;
261 unless ( $Koha::Account
::Line
::allowed_update
->{$update_type} eq $account_type ) {
262 Koha
::Exceptions
::Account
::UnrecognisedType
->throw(
263 error
=> 'Update type not allowed on this accounttype'
267 my $schema = Koha
::Database
->new->schema;
272 my $amount_before = $self->amount;
273 my $amount_outstanding_before = $self->amountoutstanding;
274 my $difference = $amount - $amount_before;
275 my $new_outstanding = $amount_outstanding_before + $difference;
277 my $offset_type = substr( $update_type, 0, index( $update_type, '_' ) );
278 $offset_type .= ( $difference > 0 ) ?
"_increase" : "_decrease";
280 # Catch cases that require patron refunds
281 if ( $new_outstanding < 0 ) {
283 Koha
::Patrons
->find( $self->borrowernumber )->account;
284 my $credit = $account->add_credit(
286 amount
=> $new_outstanding * -1,
287 description
=> 'Overpayment refund',
289 ( $update_type eq 'fine_update' ?
( item_id
=> $self->itemnumber ) : ()),
292 $new_outstanding = 0;
295 # Update the account line
300 amountoutstanding => $new_outstanding,
301 ( $update_type eq 'fine_update
' ? ( lastincrement => $difference ) : ()),
305 # Record the account offset
306 my $account_offset = Koha::Account::Offset->new(
308 debit_id => $self->id,
309 type => $offset_type,
310 amount => $difference
314 if ( C4::Context->preference("FinesLog") ) {
316 "FINES", 'UPDATE
', #undef becomes UPDATE in UpdateFine
317 $self->borrowernumber,
319 { action => $update_type,
320 borrowernumber => $self->borrowernumber,
321 accountno => $self->accountno,
323 description => undef,
324 amountoutstanding => $new_outstanding,
325 accounttype => $self->accounttype,
327 itemnumber => $self->itemnumber,
331 ) if ( $update_type eq 'fine_update
' );
341 my $bool = $line->is_credit;
348 return ( $self->amount < 0 );
353 my $bool = $line->is_debit;
360 return !$self->is_credit;
363 =head2 Internal methods
372 return 'Accountline
';
379 =head3 $allowed_update
383 our $allowed_update = { 'fine_update
' => 'FU
', };
387 Kyle M Hall <kyle@bywatersolutions.com >
388 Tomás Cohen Arazi <tomascohen@theke.io>
389 Martin Renvoize <martin.renvoize@ptfs-europe.com>