Merge branch 'master' of git://git.koha-community.org/koha into MSWin32
[wip/koha-chris_n.git] / misc / cronjobs / smsoverdues.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
25 # with Koha; if not, write to the Free Software Foundation, Inc.,
26 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27
28 # $Id: sendoverdues.pl,v 1.1.2.1 2007/03/26 22:38:09 tgarip1957 Exp $
29
30 #use strict;
31 #use warnings; FIXME - Bug 2505
32
33 BEGIN {
34     # find Koha's Perl modules
35     # test carefully before changing this
36     use FindBin;
37     eval { require "$FindBin::Bin/../kohalib.pl" };
38 }
39
40 use C4::Context;
41 use C4::Search;
42 use C4::Circulation;
43 use C4::Members;
44 use C4::Dates qw/format_date/;
45 use HTML::Template::Pro;
46 use Mail::Sendmail;
47 use Mail::RFC822::Address;
48 use C4::SMS;
49 use Carp;
50 use utf8;
51 my ($res,$ua);##variables for SMS
52
53 my $date=get_today();
54                 my $dbh = C4::Context->dbh;
55  
56
57
58 notifyOverdues();
59
60 sub     notifyOverdues {
61         # Look up the overdues for today. 
62         # Capture overdues which fall on our dates of interest.
63
64 ####################################################################################################
65 # Creating a big hash of available templates
66 my %email;
67 %email->{'template'}='email-2.txt';
68 my %sms; 
69 %sms->{'template'}='sms-2.txt';
70
71
72 my %firstReminder->{'email'} = \%email;
73 %firstReminder->{'sms'} = \%sms;
74
75 my %email2;
76 %email2->{'template'}='email-7.txt';
77 my %secondReminder->{'email'} = \%email2;
78 my %sms2;  
79 %sms2->{'template'}='sms-7.txt';
80 %secondReminder->{'sms'} = \%sms2;
81 my %letter2;
82 %letter2->{'template'}='letter-7.html';
83 %secondReminder->{'letter'} = \%letter2;    
84
85
86 my %email3;
87 %email3->{'template'}='email-29.txt';
88 my %sms3;
89 %sms3->{'template'}='sms-29.txt';
90 my %letter3;
91 %letter3->{'template'}='letter-29.html';
92
93 my %finalReminder->{'email'} = \%email3;
94 %finalReminder->{'letter'} = \%letter3;
95 %finalReminder->{'sms'} = \%sms3;
96
97 my %actions;
98 %actions->{'1'}=\%firstReminder;
99 %actions->{'3'}=\%secondReminder;###This was 7 days changed to 3 days
100 %actions->{'20'}=\%finalReminder;###This was 29 days changed to 20 days
101
102 ##################################################################################################################
103 my @overdues2;#an array for each actiondate
104 my @overdues7;
105 my @overdues29;
106 my $filename;
107        
108    
109
110         # Retrieve an array of overdues.
111         my ($count, $overduesReference) = Getoverdues();
112         my @overdues=@$overduesReference;
113
114
115         # We're going to build a hash of arrays, containing the items requiring action.
116         # ->borrowernumber, date, @overdues
117         my %actionItems;
118         
119
120         foreach my $overdue (@overdues) {
121                  my $due_day=$overdue->{'date_due'};
122
123                 my $difference=DATE_subtract($date,$due_day);
124                 # If does this item fall on a day of interest?
125                                 $overdue->{'difference'}=$difference;
126                 foreach my $actiondate (keys(%actions)) {
127                         if ($actiondate == $difference) {
128                         $filename='overdues'.$actiondate;
129                                 push @$$filename,$overdue;              
130 #print "$actiondate,-,$overdue->{borrowernumber}\n";            
131                         }
132                         $actionItems{$actiondate} = \@$$filename;
133                 }
134         }
135
136         # We now have a hash containing overdues which need actioning,  we can step through each set. 
137         # Work from earilest to latest. We only wish to send the most urgent message.
138         my %messages; 
139         my %borritem;
140
141     foreach my $actiondate (keys %actions) {
142 #               print "\n\nThe following items are $actiondate days overdue.\n";
143                 my $items = $actionItems{$actiondate};
144                 $filename='overdues'.$actiondate;
145         foreach my $overdue (@$$filename) {
146                                 # Detemine which borrower is responsible for this overdue;
147                                 # if the offender is a child, then the guarantor is the person to notify
148                                 my $borrowernumber=$overdue->{borrowernumber};
149
150                                 my $borrower=responsibleBorrower($borrowernumber);
151                                 my ($method, $address) = preferedContactMethod($borrower);
152                   if ($method && $address) {    
153                                 
154                                         # Do we have to send something, using this method on this day?
155                     if (%actions->{$actiondate}->{$method}->{'template'}) {
156                                                 my $intranetdir=C4::Context->config('intranetdir');
157                                                 # Template the message
158                                                 my $template = HTML::Template::Pro->new(filename => $intranetdir.'/scripts/misc/notifys/templates/'.%actions->{$actiondate}->{$method}->{'template'}, die_on_bad_params => 0);
159                                                 my @bookdetails;
160                                                                 my %row_data;
161                                          my $item = getiteminformation("", $overdue->{'itemnumber'});
162                                                         $row_data{'BARCODE'}=$item->{'barcode'};
163                                 
164                                                        my $title=substr($item->{'title'},0,25)."...";
165
166                                 $title=changecharacter($title);
167                                   $row_data{'TITLE'}=$title;
168                                                         $row_data{'DATE_DUE'}=format_date($overdue->{'date_due'});
169                                 $row_data{'cardnumber'}=$borrower->{'cardnumber'};
170                                         push(@bookdetails, \%row_data);
171                                                 $template->param(BOOKDETAILS => \@bookdetails);                                                         
172                                 my $name= "$borrower->{'firstname'} $borrower->{'surname'}"; 
173                                 $template->param(NAME=> $name);
174                       %messages->{$borrower->{'borrowernumber'}} = $template->output();
175                         if ($method eq 'email') {
176                         $result = sendEmail($address, 'library@library.neu.edu.tr', 'Overdue Library Items', %messages->{$borrowernumber});
177                         logContact($borrowernumber, $method, $address, $result, %messages->{$borrowernumber});
178                         }
179                         elsif ($method eq 'sms') {
180                         $result = sendSMS($address, %messages->{$borrowernumber});
181                         logContact($borrowernumber, $method, $address, $result, %messages->{$borrowernumber});
182                         }
183                         elsif ($method eq 'letter') {
184                         $result = printLetter($address, %messages->{$borrowernumber});
185                         }                                                       
186                        }##template exists
187                 }else{
188                 print "$borrowernumber has an overdue item, but no means of contact\n";
189                 }##$method              
190
191
192         } #end of 'foreach overdue'
193
194      } # end of foreach actiondate
195 }
196
197 sub     responsibleBorrower {   
198         # Given an overdue item, return the details of the borrower responible as a hash of database columns.
199         my $borrowernumber=shift;
200
201         if ($borrowernumber) {
202                 my $borrower=BorType($borrowernumber);
203                 # Overdue books assigned to children have notices sent to the guarantor.        
204                 if ($borrower->{'categorycode'} eq 'C') {
205                         my $guarantor=BorType($borrower->{'guarantor'});
206                         $borrower = $guarantor;
207                         }
208         
209                 return $borrower;
210         }
211
212 }
213
214
215
216
217
218
219
220
221
222 sub     preferedContactMethod {
223         # Given a reference to borrower details, in the format
224         # returned by BorType(), determine the prefered contact method, and address to use.
225         my $borrower=$_[0];
226         my $borrcat = getborrowercategoryinfo($borrower->{'categorycode'});
227 if(  !$borrcat->{'overduenoticerequired'}){
228 return (undef,undef);
229 }
230         my $method='';  
231         my $address=''; 
232 ## if borrower has a phone set that as our preferrred contact
233         if ($borrower->{'phoneday'}) {
234                 if (parse_phone($borrower->{phoneday})){
235                                 $address = parse_phone($borrower->{phoneday});
236                                 $method="sms";
237                                 return ($method, $address);
238                 }
239         }
240         
241         if (($borrower->{'emailaddress'}) and (Mail::RFC822::Address::valid($borrower->{'emailaddress'}))) {
242                                 $address = $borrower->{'emailaddress'};
243                 $method="email";
244                                 return ($method, $address);
245         }
246                         
247         if ($borrower->{'streetaddress'}) {
248                                 $address =  mailingAddress($borrower);
249                         $method = 'letter';     
250         }
251 #print "$method, $address\n";
252         return ($method, $address);
253 }
254
255
256
257
258
259
260
261
262 sub     logContact {
263         # Given the details of an attempt to contact a borrower, 
264         # log them in the attempted_contacts table of the koha database.
265         my ($borrowernumber, $method, $address, $result, $message) = @_;
266
267         my $querystring = "     insert into     attempted_contacts 
268                                                 (borrowernumber, method, address, result, message, date) 
269                                                 values (?, ?, ?, ?, ?, now())";
270         my $sth= $dbh->prepare($querystring);
271         $sth->execute($borrowernumber, $method, $address, $result, $message);
272         $sth->finish();
273 }
274
275
276
277
278
279
280
281
282 sub     mailingAddress {
283         # Given a hash of borrower information, such as that returned by BorType, 
284         # return a mailing address. 
285         my $borrower=$_[0];
286
287         my $address =   $borrower->{'firstname'}."\n". 
288                         $borrower->{'streetaddress'}."\n".
289                         $borrower->{'streetcity'};
290
291         return $address;
292 }
293
294
295
296 sub     sendEmail {
297         # Given an email address, and a subject and message, attempt to send email.
298
299         my $to=$_[0];
300         my $from=$_[1];
301         my $subject=$_[2];
302         my $message=$_[3];
303 #    print "in email area";
304
305 #       print "\nSending Email To: $to\n$message\n";
306
307         my      %mail = (               To      => $to,
308                                         CC => 'library@library.neu.edu.tr', 
309                                         From    => $from,
310                                         Subject => $subject,
311                                         Message => $message);
312
313                 
314         if (not(sendmail %mail)) {       
315 carp  "sendEmail to $to failed: " . $Mail::Sendmail::error;
316                 return 0;       
317         }
318         
319         return 1;
320 }
321
322
323 sub     sendSMS {
324 my ($phone, $message)=@_;
325 ($res,$ua)=get_sms_auth() unless $res;
326         # Given a cell number and a message, attempt to send an SMS message.
327 my  $sendresult=send_sms($ua,$phone,$message,$res->{pSessionId});
328         my $error=error_codes($sendresult->{pErrCode});
329         return 1 unless $error;
330         return $error;
331 }
332
333
334 sub     printLetter {
335 print "letter\n";
336         # Print a letter
337         # FIXME - decide where to print
338         return 1;
339 }
340 sub changecharacter {
341 my ($string)=@_;
342 $_=$string;
343
344 s/ş/s/g;
345 s/Ş/S/g;
346 s/ü/u/g;
347 s/Ü/U/g;
348 s/ç/c/g;
349 s/Ç/C/g;
350 s/ö/o/g;
351 s/Ö/O/g;
352 s/ı/i/g;
353 s/İ/I/g;
354 s/ğ/g/g;
355 s/Ğ/G/g;
356 $string=$_;
357 return $string;
358 }
359 $dbh->disconnect();
360