Fines fixes: apparent problems with fines prevent processing.
[koha.git] / misc / cronjobs / fines.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 # FIXME: use FinesMode as described or change syspref description
30 use strict;
31
32 BEGIN {
33     # find Koha's Perl modules
34     # test carefully before changing this
35     use FindBin;
36     eval { require "$FindBin::Bin/kohalib.pl" };
37 }
38
39 use Date::Calc qw/Date_to_Days/;
40
41 use C4::Context;
42 use C4::Circulation;
43 use C4::Overdues;
44 use C4::Calendar qw();  # don't need any exports from Calendar
45 use C4::Biblio;
46 use C4::Debug;  # supplying $debug and $cgi_debug
47
48 use vars qw(@borrower_fields @item_fields @other_fields);
49 use vars qw($fldir $libname $control $mode $delim $dbname $today $today_iso $today_days);
50 use vars qw($filename $summary);
51
52 CHECK {
53     @borrower_fields = qw(cardnumber categorycode surname firstname email phone address citystate);
54         @item_fields = qw(itemnumber barcode date_due);
55        @other_fields = qw(type days_overdue fine);
56     $libname = C4::Context->preference('LibraryName');
57     $control = C4::Context->preference('CircControl');
58     $mode    = C4::Context->preference('finesMode');
59     $dbname  = C4::Context->config('database');
60     $delim   = "\t"; # ?  C4::Context->preference('delimiter') || "\t";
61
62     $today = C4::Dates->new();
63     $today_iso = $today->output('iso');
64     $today_days = Date_to_Days(split(/-/,$today_iso));
65     $fldir = $ENV{TMPDIR} || "/tmp"; # TODO: use GetOpt
66     $filename = $dbname;
67     $filename =~ s/\W//;
68     $filename = $fldir . '/'. $filename . '_' .  $today_iso . ".log";
69     $summary = 1;  # TODO: use GetOpt
70 }
71
72 INIT {
73     $debug and print "Each line will contain the following fields:\n",
74         "From borrowers : ", join(', ', @borrower_fields), "\n",
75         "From items : ", join(', ', @item_fields), "\n",
76         "Per overdue: ", join(', ', @other_fields), "\n",
77         "Delimiter: '$delim'\n";
78 }
79
80 open (FILE, ">$filename") or die "Cannot write file $filename: $!";
81 print FILE join $delim, (@borrower_fields, @item_fields, @other_fields);
82 print FILE "\n";
83
84 my $data = Getoverdues();
85 my $overdueItemsCounted = 0;
86 my %calendars = ();
87
88 for (my $i=0; $i<scalar(@$data); $i++) {
89     my $datedue = C4::Dates->new($data->[$i]->{'date_due'},'iso');
90     my $datedue_days = Date_to_Days(split(/-/,$datedue->output('iso')));
91     my $due_str = $datedue->output();
92     my $borrower = BorType($data->[$i]->{'borrowernumber'});
93     my $branchcode = ($control eq 'ItemHomeLibrary') ? $data->[$i]->{homebranch} :
94                      ($control eq 'PatronLibrary'  ) ?   $borrower->{branchcode} :
95                                                        $data->[$i]->{branchcode} ;
96     # In final case, CircControl must be PickupLibrary. (branchcode comes from issues table here).
97     my $calendar;
98     unless (defined ($calendars{$branchcode})) {
99         $calendars{$branchcode} = C4::Calendar->new(branchcode => $branchcode);
100     }
101     $calendar = $calendars{$branchcode};
102     my $isHoliday = $calendar->isHoliday(split '/', $today->output('metric'));
103       
104     ($datedue_days <= $today_days) or next; # or it's not overdue, right?
105
106     $overdueItemsCounted++;
107     my ($amount,$type,$daycounttotal,$daycount)=
108                 CalcFine($data->[$i], $borrower->{'categorycode'}, $branchcode,undef,undef, $datedue, $today);
109         # FIXME: $type NEVER gets populated by anything.
110     (defined $type) or $type = '';
111         # Don't update the fine if today is a holiday.  
112         # This ensures that dropbox mode will remove the correct amount of fine.
113         if ($mode eq 'production' and  ! $isHoliday) {
114                 UpdateFine($data->[$i]->{'itemnumber'},$data->[$i]->{'borrowernumber'},$amount,$type,$due_str) if( $amount > 0 ) ;
115         }
116     my @cells = ();
117     push @cells, map {$borrower->{$_}} @borrower_fields;
118     push @cells, map {$data->[$i]->{$_}} @item_fields;
119     push @cells, $type, $daycounttotal, $amount;
120     print FILE join($delim, @cells), "\n";
121 }
122
123 my $numOverdueItems = scalar(@$data);
124 if ($summary) {
125    print <<EOM;
126 Fines assessment -- $today_iso -- Saved to $filename
127 Number of Overdue Items:
128      counted $overdueItemsCounted
129     reported $numOverdueItems
130
131 EOM
132 }
133
134 close FILE;