Bug 17600: Standardize our EXPORT_OK
[koha.git] / C4 / Accounts.pm
1 package C4::Accounts;
2
3 # Copyright 2000-2002 Katipo Communications
4 #
5 # This file is part of Koha.
6 #
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.
11 #
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.
16 #
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>.
19
20
21 use Modern::Perl;
22 use C4::Context;
23 use C4::Stats;
24 use C4::Members;
25 use Koha::Account;
26 use Koha::Account::Lines;
27 use Koha::Account::Offsets;
28 use Koha::Items;
29
30
31 use vars qw(@ISA @EXPORT);
32
33 BEGIN {
34     require Exporter;
35     @ISA    = qw(Exporter);
36     @EXPORT = qw(
37       chargelostitem
38       purge_zero_balance_fees
39     );
40 }
41
42 =head1 NAME
43
44 C4::Accounts - Functions for dealing with Koha accounts
45
46 =head1 SYNOPSIS
47
48 use C4::Accounts;
49
50 =head1 DESCRIPTION
51
52 The functions in this module deal with the monetary aspect of Koha,
53 including looking up and modifying the amount of money owed by a
54 patron.
55
56 =head1 FUNCTIONS
57
58 =head2 chargelostitem
59
60 In a default install of Koha the following lost values are set
61 1 = Lost
62 2 = Long overdue
63 3 = Lost and paid for
64
65 FIXME: itemlost should be set to 3 after payment is made, should be a warning to the interface that a charge has been added
66 FIXME : if no replacement price, borrower just doesn't get charged?
67
68 =cut
69
70 sub chargelostitem {
71     my $dbh = C4::Context->dbh();
72     my ($borrowernumber, $itemnumber, $amount, $description) = @_;
73     my $itype = Koha::ItemTypes->find({ itemtype => Koha::Items->find($itemnumber)->effective_itemtype() });
74     my $replacementprice = $amount;
75     my $defaultreplacecost = $itype->defaultreplacecost;
76     my $processfee = $itype->processfee;
77     my $usedefaultreplacementcost = C4::Context->preference("useDefaultReplacementCost");
78     my $processingfeenote = C4::Context->preference("ProcessingFeeNote");
79     if ($usedefaultreplacementcost && $amount == 0 && $defaultreplacecost){
80         $replacementprice = $defaultreplacecost;
81     }
82     my $checkout = Koha::Checkouts->find({ itemnumber => $itemnumber });
83     my $issue_id = $checkout ? $checkout->issue_id : undef;
84
85     my $account = Koha::Account->new({ patron_id => $borrowernumber });
86     # first make sure the borrower hasn't already been charged for this item (for this issuance)
87     my $existing_charges = $account->lines->search(
88         {
89             itemnumber      => $itemnumber,
90             debit_type_code => 'LOST',
91             issue_id        => $issue_id
92         }
93     )->count();
94
95     # OK, they haven't
96     unless ($existing_charges) {
97         #add processing fee
98         if ($processfee && $processfee > 0){
99             my $accountline = $account->add_debit(
100                 {
101                     amount      => $processfee,
102                     description => $description,
103                     note        => $processingfeenote,
104                     user_id     => C4::Context->userenv ? C4::Context->userenv->{'number'} : undef,
105                     interface   => C4::Context->interface,
106                     library_id  => C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef,
107                     type        => 'PROCESSING',
108                     item_id     => $itemnumber,
109                     issue_id    => $issue_id,
110                 }
111             );
112         }
113         #add replace cost
114         if ($replacementprice > 0){
115             my $accountline = $account->add_debit(
116                 {
117                     amount      => $replacementprice,
118                     description => $description,
119                     note        => undef,
120                     user_id     => C4::Context->userenv ? C4::Context->userenv->{'number'} : undef,
121                     interface   => C4::Context->interface,
122                     library_id  => C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef,
123                     type        => 'LOST',
124                     item_id     => $itemnumber,
125                     issue_id    => $issue_id,
126                 }
127             );
128         }
129     }
130 }
131
132 =head2 purge_zero_balance_fees
133
134   purge_zero_balance_fees( $days );
135
136 Delete accountlines entries where amountoutstanding is 0 or NULL which are more than a given number of days old.
137
138 B<$days> -- Zero balance fees older than B<$days> days old will be deleted.
139
140 B<Warning:> Because fines and payments are not linked in accountlines, it is
141 possible for a fine to be deleted without the accompanying payment,
142 or vise versa. This won't affect the account balance, but might be
143 confusing to staff.
144
145 =cut
146
147 sub purge_zero_balance_fees {
148     my $days  = shift;
149     my $count = 0;
150
151     my $dbh = C4::Context->dbh;
152     my $sth = $dbh->prepare(
153         q{
154             DELETE a1 FROM accountlines a1
155
156             LEFT JOIN account_offsets credit_offset ON ( a1.accountlines_id = credit_offset.credit_id )
157             LEFT JOIN accountlines a2 ON ( credit_offset.debit_id = a2.accountlines_id )
158
159             LEFT JOIN account_offsets debit_offset ON ( a1.accountlines_id = debit_offset.debit_id )
160             LEFT JOIN accountlines a3 ON ( debit_offset.credit_id = a3.accountlines_id )
161
162             WHERE a1.date < date_sub(curdate(), INTERVAL ? DAY)
163               AND ( a1.amountoutstanding = 0 OR a1.amountoutstanding IS NULL )
164               AND ( a2.amountoutstanding = 0 OR a2.amountoutstanding IS NULL )
165               AND ( a3.amountoutstanding = 0 OR a3.amountoutstanding IS NULL )
166         }
167     );
168     $sth->execute($days) or die $dbh->errstr;
169 }
170
171 END { }    # module clean-up code here (global destructor)
172
173 1;
174 __END__
175
176 =head1 SEE ALSO
177
178 DBI(3)
179
180 =cut
181