Minor update to README for RM
[koha_fer] / misc / cronjobs / fines2.pl
1 #!/usr/bin/perl
2
3 #  This script loops through each overdue item, determines the fine,
4 #  and updates the total amount of fines due by each user.  It relies on
5 #  the existence of /tmp/fines, which is created by ???
6 # Doesnt really rely on it, it relys on being able to write to /tmp/
7 # It creates the fines file
8 #
9 #  This script is meant to be run nightly out of cron.
10
11 # Copyright 2000-2002 Katipo Communications
12 #
13 # This file is part of Koha.
14 #
15 # Koha is free software; you can redistribute it and/or modify it under the
16 # terms of the GNU General Public License as published by the Free Software
17 # Foundation; either version 2 of the License, or (at your option) any later
18 # version.
19 #
20 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
21 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
22 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
23 #
24 # You should have received a copy of the GNU General Public License along with
25 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
26 # Suite 330, Boston, MA  02111-1307 USA
27
28
29 use strict;
30 BEGIN {
31     # find Koha's Perl modules
32     # test carefully before changing this
33     use FindBin;
34     eval { require "$FindBin::Bin/kohalib.pl" };
35 }
36
37 use Date::Manip;        # qw( Date_DaysSince1BC ) ;
38 use Data::Dumper;
39 use Getopt::Long;
40
41 use C4::Context;
42 use C4::Circulation;
43 use C4::Overdues;       # qw( Getoverdues CalcFine );
44 use C4::Biblio;
45 use C4::Items;
46 use C4::Dates;
47 use C4::Debug;
48
49 our $verbose;
50 GetOptions('verbose+', \$verbose);
51 $debug and $verbose++;
52
53 # my $filename = "/tmp/fines";
54 # open (FILE, ">$filename") or die "Cannot write to $filename";
55
56 my ($data)=Getoverdues();
57 my $overdueItemsCounted=0;
58
59 # FIXME - There's got to be a better way to figure out what day today is.
60 my ($mday,$mon,$year) = (localtime)[3..5]; # ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
61 my $date = Date_DaysSince1BC($mon+1,$mday,$year+1900);
62 my $today_obj = C4::Dates->new();
63 my $today_iso = $today_obj->output('iso');
64
65 if ($verbose) {
66         printf "Number of overdues: %7d\nDate_DaysSince1BC : %7d\n", scalar(@$data), $date;
67         print "today: $today_iso\n";
68 }
69
70 # get the maxfine parameter
71 my $maxFine=C4::Context->preference("MaxFine") || 999999999;
72
73 our $phone_sth = C4::Context->dbh->prepare("Select * from borrowers where borrowernumber=?");
74 sub get_guarantor_phone ($) {
75         $phone_sth->execute(shift);
76         my $x = $phone_sth->fetchrow_hashref;
77         return $x->{'phone'};
78 }
79
80 our $fine_sth = C4::Context->dbh->prepare("
81         INSERT INTO accountlines
82         (borrowernumber, itemnumber, accountno, date,
83         amount, description, accounttype, amountoutstanding)
84         VALUES (?,?,?,now(),?,?,'L',?)
85         ");
86 sub insert_fine ($$$$$$) {
87         $verbose and print "inserting fine: " . join(", ",@_), "\n";
88         return $fine_sth->execute(@_);
89 }
90
91 my $circcontrol = C4::Context->preference('CircControl');
92 foreach (@$data){
93         my $date_due = $_->{date_due};
94         $verbose and print "date_due: $date_due ", ($date_due le $today_iso ? 'fine!' : 'ok'), "\n";
95     my @dates=split('-',$date_due);
96     my $date2=Date_DaysSince1BC($dates[1],$dates[2],$dates[0]);
97     my $due="$dates[2]/$dates[1]/$dates[0]";
98         my $borrowernumber = $_->{borrowernumber};
99         my $itemnumber     = $_->{itemnumber};
100     my $borrower = BorType($borrowernumber);
101     ($date_due le $today_iso) or next;          # it is valid to string compare ISO dates.
102         $overdueItemsCounted++ if $verbose;
103         my $branchcode = ($circcontrol eq 'PatronLibrary'  ) ? $borrower->{branchcode} : 
104                                          ($circcontrol eq 'ItemHomeLibrary') ?        $_->{homebranch} :
105                                                                                                                           $_->{branchcode} ; # Last option: Pickup Library.
106         my $difference=$date-$date2;
107         my (@calc_returns) = CalcFine(
108                 $_, $borrower->{categorycode}, $branchcode,undef,undef, C4::Dates->new($date_due,'iso'), $today_obj 
109         );
110         if ($verbose) {
111                 my $dump = Dumper($_);
112                 $dump =~ s/;/,/;
113                 $verbose and print "CalcFine($dump" .
114                         "\t$borrower->{categorycode}, $branchcode,undef,undef,[$date_due],[today]) returns:\n" . Dumper(\@calc_returns), "\n";
115         }
116         my ($amount,$type,$printout) = @calc_returns[0..2];
117         # ($amount,$chargename,$daycount,$daycounttotal)=&CalcFine($itemnumber,$categorycode,$branch,$days_overdue,$description, $start_date, $end_date );
118
119         ($amount > $maxFine) and $amount = $maxFine;
120         if ($amount > 0) {
121                 UpdateFine($itemnumber,$borrowernumber,$amount,$type,$due);
122                 if ($borrower->{'guarantorid'}) {
123                         $borrower->{'phone'} = get_guarantor_phone($borrower->{'guarantorid'}) || $borrower->{'phone'};
124                 }
125                 print "$printout\t$borrower->{'cardnumber'}\t$borrower->{'categorycode'}\t$borrower->{'firstname'}\t$borrower->{'surname'}\t",
126                 "$_->{'date_due'}\t$type\t$difference\t",
127                 "$borrower->{'emailaddress'}\t$borrower->{'phone'}\t$borrower->{'streetaddress'}\t$borrower->{'city'}\t$amount\n" if $verbose;
128         }
129         if ($difference >= C4::Context->preference("NoReturnSetLost")){
130                 my $borrower=BorType($borrowernumber);
131                 if ($borrower->{'cardnumber'} ne ''){
132                         my $cost = ReplacementCost($itemnumber);
133                         my $item = GetBiblioFromItemNumber($itemnumber);
134                         if ($item->{'itemlost'} ne '1' && $item->{'itemlost'} ne '2' ){
135                                 insert_fine(
136                                         $borrowernumber,
137                                         $itemnumber,
138                                         C4::Accounts::getnextacctno($borrowernumber),
139                                         $cost,
140                                         "Lost item $item->{'title'} $item->{'barcode'} $due",
141                                         $cost
142                                 );
143                                 ModItem({ itemlost => 2 }, undef, $itemnumber);
144                         }
145                 }
146         }
147 }
148
149 if ($verbose) {
150     my $numOverdueItems=scalar(@$data);
151     print <<EOM
152
153 Number of Overdue Items counted  $overdueItemsCounted
154 Number of Overdue Items reported $numOverdueItems
155
156 EOM
157 }
158
159 # close FILE;