3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
25 use C4
::Log
qw(logaction);
27 use Koha
::Account
::Lines
;
28 use Koha
::Account
::Offsets
;
31 use Mojo
::Util
qw(deprecated);
32 use Data
::Dumper
qw(Dumper);
34 use vars
qw(@ISA @EXPORT);
41 &purge_zero_balance_fees
47 C4::Accounts - Functions for dealing with Koha accounts
55 The functions in this module deal with the monetary aspect of Koha,
56 including looking up and modifying the amount of money owed by a
63 In a default install of Koha the following lost values are set
68 FIXME: itemlost should be set to 3 after payment is made, should be a warning to the interface that a charge has been added
69 FIXME : if no replacement price, borrower just doesn't get charged?
74 my $dbh = C4
::Context
->dbh();
75 my ($borrowernumber, $itemnumber, $amount, $description) = @_;
76 my $itype = Koha
::ItemTypes
->find({ itemtype
=> Koha
::Items
->find($itemnumber)->effective_itemtype() });
77 my $replacementprice = $amount;
78 my $defaultreplacecost = $itype->defaultreplacecost;
79 my $processfee = $itype->processfee;
80 my $usedefaultreplacementcost = C4
::Context
->preference("useDefaultReplacementCost");
81 my $processingfeenote = C4
::Context
->preference("ProcessingFeeNote");
82 if ($usedefaultreplacementcost && $amount == 0 && $defaultreplacecost){
83 $replacementprice = $defaultreplacecost;
85 my $checkout = Koha
::Checkouts
->find({ itemnumber
=> $itemnumber });
86 my $issue_id = $checkout ?
$checkout->issue_id : undef;
88 my $account = Koha
::Account
->new({ patron_id
=> $borrowernumber });
89 # first make sure the borrower hasn't already been charged for this item (for this issuance)
90 my $existing_charges = $account->lines->search(
92 itemnumber
=> $itemnumber,
93 debit_type_code
=> 'LOST',
99 unless ($existing_charges) {
101 if ($processfee && $processfee > 0){
102 my $accountline = $account->add_debit(
104 amount
=> $processfee,
105 description
=> $description,
106 note
=> $processingfeenote,
107 user_id
=> C4
::Context
->userenv ? C4
::Context
->userenv->{'number'} : undef,
108 interface
=> C4
::Context
->interface,
109 library_id
=> C4
::Context
->userenv ? C4
::Context
->userenv->{'branch'} : undef,
110 type
=> 'PROCESSING',
111 item_id
=> $itemnumber,
112 issue_id
=> $issue_id,
117 if ($replacementprice > 0){
118 my $accountline = $account->add_debit(
120 amount
=> $replacementprice,
121 description
=> $description,
123 user_id
=> C4
::Context
->userenv ? C4
::Context
->userenv->{'number'} : undef,
124 interface
=> C4
::Context
->interface,
125 library_id
=> C4
::Context
->userenv ? C4
::Context
->userenv->{'branch'} : undef,
127 item_id
=> $itemnumber,
128 issue_id
=> $issue_id,
137 &manualinvoice($borrowernumber, $itemnumber, $description, $type,
140 This function is now deprecated and not used anywhere within koha. It is due for complete removal in 19.11
145 my ( $borrowernumber, $itemnum, $desc, $type, $amount, $note ) = @_;
147 deprecated
"C4::Accounts::manualinvoice is deprecated in favor of Koha::Account->add_debit";
149 my $manager_id = C4
::Context
->userenv ? C4
::Context
->userenv->{'number'} : undef;
150 my $dbh = C4
::Context
->dbh;
152 my $amountleft = $amount;
154 my $branchcode = C4
::Context
->userenv ? C4
::Context
->userenv->{'branch'} : undef;
157 if ( $type eq 'LOST' && $itemnum ) {
158 my $checkouts = Koha
::Checkouts
->search(
159 { itemnumber
=> $itemnum, borrowernumber
=> $borrowernumber } );
163 : Koha
::Old
::Checkouts
->search(
164 { itemnumber
=> $itemnum, borrowernumber
=> $borrowernumber },
165 { order_by
=> { -desc
=> 'returndate' }, rows
=> 1 }
167 $issue_id = $checkout ?
$checkout->issue_id : undef;
170 my $accountline = Koha
::Account
::Line
->new(
172 borrowernumber
=> $borrowernumber,
175 description => $desc,
176 debit_type_code => $type,
177 amountoutstanding => $amountleft,
178 itemnumber => $itemnum || undef,
179 issue_id => $issue_id,
181 manager_id => $manager_id,
182 interface => C4::Context->interface,
183 branchcode => $branchcode,
187 my $account_offset = Koha::Account::Offset->new(
189 debit_id => $accountline->id,
190 type => 'Manual Debit
',
195 if ( C4::Context->preference("FinesLog") ) {
196 logaction("FINES", 'CREATE
',$borrowernumber,Dumper({
197 action => 'create_fee
',
198 borrowernumber => $borrowernumber,
200 description => $desc,
201 debit_type_code => $type,
202 amountoutstanding => $amountleft,
204 itemnumber => $itemnum,
205 manager_id => $manager_id,
212 =head2 purge_zero_balance_fees
214 purge_zero_balance_fees( $days );
216 Delete accountlines entries where amountoutstanding is 0 or NULL which are more than a given number of days old.
218 B<$days> -- Zero balance fees older than B<$days> days old will be deleted.
220 B<Warning:> Because fines and payments are not linked in accountlines, it is
221 possible for a fine to be deleted without the accompanying payment,
222 or vise versa. This won't affect the account balance
, but might be
227 sub purge_zero_balance_fees
{
231 my $dbh = C4
::Context
->dbh;
232 my $sth = $dbh->prepare(
234 DELETE a1 FROM accountlines a1
236 LEFT JOIN account_offsets credit_offset ON ( a1.accountlines_id = credit_offset.credit_id )
237 LEFT JOIN accountlines a2 ON ( credit_offset.debit_id = a2.accountlines_id )
239 LEFT JOIN account_offsets debit_offset ON ( a1.accountlines_id = debit_offset.debit_id )
240 LEFT JOIN accountlines a3 ON ( debit_offset.credit_id = a3.accountlines_id )
242 WHERE a1.date < date_sub(curdate(), INTERVAL ? DAY)
243 AND ( a1.amountoutstanding = 0 OR a1.amountoutstanding IS NULL )
244 AND ( a2.amountoutstanding = 0 OR a2.amountoutstanding IS NULL )
245 AND ( a3.amountoutstanding = 0 OR a3.amountoutstanding IS NULL )
248 $sth->execute($days) or die $dbh->errstr;
251 END { } # module clean-up code here (global destructor)