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