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,
234 interface => $interface
238 $update_type can be any of:
241 Authors Note: The intention here is that this method is only used
242 to adjust accountlines where the final amount is not yet known/fixed.
243 Incrementing fines are the only existing case at the time of writing,
244 all other forms of 'adjustment' should be recorded as distinct credits
245 or debits and applied, via an offset, to the corresponding debit or credit.
250 my ( $self, $params ) = @_;
252 my $amount = $params->{amount
};
253 my $update_type = $params->{type
};
254 my $interface = $params->{interface
};
256 unless ( exists($Koha::Account
::Line
::allowed_update
->{$update_type}) ) {
257 Koha
::Exceptions
::Account
::UnrecognisedType
->throw(
258 error
=> 'Update type not recognised'
262 my $account_type = $self->accounttype;
263 unless ( $Koha::Account
::Line
::allowed_update
->{$update_type} eq $account_type ) {
264 Koha
::Exceptions
::Account
::UnrecognisedType
->throw(
265 error
=> 'Update type not allowed on this accounttype'
269 my $schema = Koha
::Database
->new->schema;
274 my $amount_before = $self->amount;
275 my $amount_outstanding_before = $self->amountoutstanding;
276 my $difference = $amount - $amount_before;
277 my $new_outstanding = $amount_outstanding_before + $difference;
279 my $offset_type = substr( $update_type, 0, index( $update_type, '_' ) );
280 $offset_type .= ( $difference > 0 ) ?
"_increase" : "_decrease";
282 # Catch cases that require patron refunds
283 if ( $new_outstanding < 0 ) {
285 Koha
::Patrons
->find( $self->borrowernumber )->account;
286 my $credit = $account->add_credit(
288 amount
=> $new_outstanding * -1,
289 description
=> 'Overpayment refund',
291 interface
=> $interface,
292 ( $update_type eq 'fine_update' ?
( item_id
=> $self->itemnumber ) : ()),
295 $new_outstanding = 0;
298 # Update the account line
303 amountoutstanding => $new_outstanding
307 # Record the account offset
308 my $account_offset = Koha::Account::Offset->new(
310 debit_id => $self->id,
311 type => $offset_type,
312 amount => $difference
316 if ( C4::Context->preference("FinesLog") ) {
318 "FINES", 'UPDATE
', #undef becomes UPDATE in UpdateFine
319 $self->borrowernumber,
321 { action => $update_type,
322 borrowernumber => $self->borrowernumber,
324 description => undef,
325 amountoutstanding => $new_outstanding,
326 accounttype => $self->accounttype,
328 itemnumber => $self->itemnumber,
332 ) if ( $update_type eq 'fine_update
' );
342 my $bool = $line->is_credit;
349 return ( $self->amount < 0 );
354 my $bool = $line->is_debit;
361 return !$self->is_credit;
364 =head2 Internal methods
373 return 'Accountline
';
380 =head3 $allowed_update
384 our $allowed_update = { 'fine_update
' => 'FU
', };
388 Kyle M Hall <kyle@bywatersolutions.com >
389 Tomás Cohen Arazi <tomascohen@theke.io>
390 Martin Renvoize <martin.renvoize@ptfs-europe.com>