Lines 19-25
Link Here
|
19 |
|
19 |
|
20 |
use strict; |
20 |
use strict; |
21 |
use warnings; |
21 |
use warnings; |
|
|
22 |
|
22 |
BEGIN { |
23 |
BEGIN { |
|
|
24 |
|
23 |
# find Koha's Perl modules |
25 |
# find Koha's Perl modules |
24 |
# test carefully before changing this |
26 |
# test carefully before changing this |
25 |
use FindBin; |
27 |
use FindBin; |
Lines 42-48
sub usage {
Link Here
|
42 |
exit; |
44 |
exit; |
43 |
} |
45 |
} |
44 |
|
46 |
|
45 |
die "TalkingTechItivaPhoneNotification system preference not activated... dying\n" unless (C4::Context->preference("TalkingTechItivaPhoneNotification")); |
47 |
die |
|
|
48 |
"TalkingTechItivaPhoneNotification system preference not activated... dying\n" |
49 |
unless ( C4::Context->preference("TalkingTechItivaPhoneNotification") ); |
46 |
|
50 |
|
47 |
# Database handle |
51 |
# Database handle |
48 |
my $dbh = C4::Context->dbh; |
52 |
my $dbh = C4::Context->dbh; |
Lines 57-80
my $help;
Link Here
|
57 |
my $outfile; |
61 |
my $outfile; |
58 |
|
62 |
|
59 |
# maps to convert I-tiva terms to Koha terms |
63 |
# maps to convert I-tiva terms to Koha terms |
60 |
my $type_module_map = { 'PREOVERDUE' => 'circulation', |
64 |
my $type_module_map = { |
61 |
'OVERDUE' => 'circulation', |
65 |
'PREOVERDUE' => 'circulation', |
62 |
'RESERVE' => 'reserves', |
66 |
'OVERDUE' => 'circulation', |
63 |
}; |
67 |
'RESERVE' => 'reserves', |
64 |
|
68 |
}; |
65 |
my $type_notice_map = { 'PREOVERDUE' => 'PREDUE_PHONE', |
69 |
|
66 |
'OVERDUE' => 'OVERDUE_PHONE', |
70 |
my $type_notice_map = { |
67 |
'RESERVE' => 'HOLD_PHONE', |
71 |
'PREOVERDUE' => 'PREDUE_PHONE', |
68 |
}; |
72 |
'OVERDUE' => 'OVERDUE_PHONE', |
|
|
73 |
'RESERVE' => 'HOLD_PHONE', |
74 |
}; |
69 |
|
75 |
|
70 |
GetOptions( |
76 |
GetOptions( |
71 |
'o|output:s' => \$outfile, |
77 |
'o|output:s' => \$outfile, |
72 |
'v' => \$verbose, |
78 |
'v' => \$verbose, |
73 |
'lang:s' => \$language, |
79 |
'lang:s' => \$language, |
74 |
'type:s' => \@types, |
80 |
'type:s' => \@types, |
75 |
'w|waiting-hold-day:s' => \@holds_waiting_days_to_call, |
81 |
'w|waiting-hold-day:s' => \@holds_waiting_days_to_call, |
76 |
'c|code|library-code:s' => \$library_code, |
82 |
'c|code|library-code:s' => \$library_code, |
77 |
'help|h' => \$help, |
83 |
'help|h' => \$help, |
78 |
); |
84 |
); |
79 |
|
85 |
|
80 |
$language = uc($language); |
86 |
$language = uc($language); |
Lines 83-141
$library_code ||= '';
Link Here
|
83 |
pod2usage( -verbose => 1 ) if $help; |
89 |
pod2usage( -verbose => 1 ) if $help; |
84 |
|
90 |
|
85 |
# output log or STDOUT |
91 |
# output log or STDOUT |
86 |
if (defined $outfile) { |
92 |
my $OUT; |
87 |
open (OUT, ">$outfile") || die ("Cannot open output file"); |
93 |
if ( defined $outfile ) { |
88 |
} else { |
94 |
open( $OUT, '>', "$outfile" ) || die("Cannot open output file"); |
89 |
print "No output file defined; printing to STDOUT\n" if (defined $verbose); |
95 |
} |
90 |
open(OUT, ">&STDOUT") || die ("Couldn't duplicate STDOUT: $!"); |
96 |
else { |
|
|
97 |
print "No output file defined; printing to STDOUT\n" |
98 |
if ( defined $verbose ); |
99 |
open( $OUT, '>', "&STDOUT" ) || die("Couldn't duplicate STDOUT: $!"); |
91 |
} |
100 |
} |
92 |
|
101 |
|
93 |
my $format = 'V'; # format for phone notifications |
102 |
my $format = 'V'; # format for phone notifications |
94 |
|
103 |
|
95 |
foreach my $type (@types) { |
104 |
foreach my $type (@types) { |
96 |
$type = uc($type); #just in case lower or mixed-case was supplied |
105 |
$type = uc($type); #just in case lower or mixed-case was supplied |
97 |
my $module = $type_module_map->{$type}; #since the module is required to get the letter |
106 |
my $module = |
98 |
my $code = $type_notice_map->{$type}; #to get the Koha name of the notice |
107 |
$type_module_map->{$type}; #since the module is required to get the letter |
99 |
|
108 |
my $code = $type_notice_map->{$type}; #to get the Koha name of the notice |
100 |
my @loop; |
109 |
|
101 |
if ($type eq 'OVERDUE') { |
110 |
my @loop; |
102 |
@loop = GetOverdueIssues(); |
111 |
if ( $type eq 'OVERDUE' ) { |
103 |
} elsif ($type eq 'PREOVERDUE') { |
112 |
@loop = GetOverdueIssues(); |
104 |
@loop = GetPredueIssues(); |
113 |
} |
105 |
} elsif ($type eq 'RESERVE') { |
114 |
elsif ( $type eq 'PREOVERDUE' ) { |
106 |
@loop = GetWaitingHolds(); |
115 |
@loop = GetPredueIssues(); |
107 |
} else { |
116 |
} |
108 |
print "Unknown or unsupported message type $type; skipping...\n" if (defined $verbose); |
117 |
elsif ( $type eq 'RESERVE' ) { |
109 |
next; |
118 |
@loop = GetWaitingHolds(); |
110 |
} |
119 |
} |
111 |
|
120 |
else { |
112 |
foreach my $issues (@loop) { |
121 |
print "Unknown or unsupported message type $type; skipping...\n" |
113 |
my $date = C4::Dates->new($issues->{'date_due'}, 'iso'); |
122 |
if ( defined $verbose ); |
114 |
my $due_date = $date->output('metric'); |
123 |
next; |
115 |
|
124 |
} |
116 |
# gets the placeholder message, and enqueues the letter |
125 |
|
117 |
my $letter = getletter($module, $code); |
126 |
foreach my $issues (@loop) { |
118 |
die "No letter found for type $type!... dying\n" unless $letter; |
127 |
my $date = C4::Dates->new( $issues->{'date_due'}, 'iso' ); |
119 |
# covers basic variable parsing in letter |
128 |
my $due_date = $date->output('metric'); |
120 |
$letter = C4::Letters::parseletter($letter, 'borrowers', $issues->{'borrowernumber'}); |
129 |
|
121 |
$letter = C4::Letters::parseletter($letter, 'biblio', $issues->{'biblionumber'}); |
130 |
# gets the placeholder message, and enqueues the letter |
122 |
$letter = C4::Letters::parseletter($letter, 'biblioitems', $issues->{'biblionumber'}); |
131 |
my $letter = getletter( $module, $code ); |
123 |
|
132 |
die "No letter found for type $type!... dying\n" unless $letter; |
124 |
my $message_id = 0; |
133 |
|
125 |
if ($outfile) { |
134 |
# covers basic variable parsing in letter |
126 |
$message_id = C4::Letters::EnqueueLetter( { letter => $letter, |
135 |
$letter = |
127 |
borrowernumber => $issues->{'borrowernumber'}, |
136 |
C4::Letters::parseletter( $letter, 'borrowers', |
128 |
message_transport_type => 'phone', |
137 |
$issues->{'borrowernumber'} ); |
129 |
}); |
138 |
$letter = |
130 |
} |
139 |
C4::Letters::parseletter( $letter, 'biblio', |
131 |
|
140 |
$issues->{'biblionumber'} ); |
132 |
print OUT "\"$format\",\"$language\",\"$type\",\"$issues->{level}\",\"$issues->{cardnumber}\",\"$issues->{patron_title}\",\"$issues->{firstname}\","; |
141 |
$letter = |
133 |
print OUT "\"$issues->{surname}\",\"$issues->{phone}\",\"$issues->{email}\",\"$library_code\","; |
142 |
C4::Letters::parseletter( $letter, 'biblioitems', |
134 |
print OUT "\"$issues->{site}\",\"$issues->{site_name}\",\"$issues->{barcode}\",\"$due_date\",\"$issues->{title}\",\"$message_id\"\n"; |
143 |
$issues->{'biblionumber'} ); |
135 |
} |
144 |
|
|
|
145 |
my $message_id = 0; |
146 |
if ($outfile) { |
147 |
$message_id = C4::Letters::EnqueueLetter( |
148 |
{ |
149 |
letter => $letter, |
150 |
borrowernumber => $issues->{'borrowernumber'}, |
151 |
message_transport_type => 'phone', |
152 |
} |
153 |
); |
154 |
} |
155 |
|
156 |
print $OUT |
157 |
"\"$format\",\"$language\",\"$type\",\"$issues->{level}\",\"$issues->{cardnumber}\",\"$issues->{patron_title}\",\"$issues->{firstname}\","; |
158 |
print $OUT |
159 |
"\"$issues->{surname}\",\"$issues->{phone}\",\"$issues->{email}\",\"$library_code\","; |
160 |
print $OUT |
161 |
"\"$issues->{site}\",\"$issues->{site_name}\",\"$issues->{barcode}\",\"$due_date\",\"$issues->{title}\",\"$message_id\"\n"; |
162 |
} |
136 |
} |
163 |
} |
137 |
|
164 |
|
138 |
|
|
|
139 |
=head1 NAME |
165 |
=head1 NAME |
140 |
|
166 |
|
141 |
TalkingTech_itiva_outbound.pl |
167 |
TalkingTech_itiva_outbound.pl |
Lines 194-200
This field can be blank if all messages are from a single library.
Link Here
|
194 |
=cut |
220 |
=cut |
195 |
|
221 |
|
196 |
sub GetOverdueIssues { |
222 |
sub GetOverdueIssues { |
197 |
my $query = "SELECT borrowers.borrowernumber, borrowers.cardnumber, borrowers.title as patron_title, borrowers.firstname, borrowers.surname, |
223 |
my $query = |
|
|
224 |
"SELECT borrowers.borrowernumber, borrowers.cardnumber, borrowers.title as patron_title, borrowers.firstname, borrowers.surname, |
198 |
borrowers.phone, borrowers.email, borrowers.branchcode, biblio.biblionumber, biblio.title, items.barcode, issues.date_due, |
225 |
borrowers.phone, borrowers.email, borrowers.branchcode, biblio.biblionumber, biblio.title, items.barcode, issues.date_due, |
199 |
max(overduerules.branchcode) as rulebranch, TO_DAYS(NOW())-TO_DAYS(date_due) as daysoverdue, delay1, delay2, delay3, |
226 |
max(overduerules.branchcode) as rulebranch, TO_DAYS(NOW())-TO_DAYS(date_due) as daysoverdue, delay1, delay2, delay3, |
200 |
issues.branchcode as site, branches.branchname as site_name |
227 |
issues.branchcode as site, branches.branchname as site_name |
Lines 209-234
sub GetOverdueIssues {
Link Here
|
209 |
OR (TO_DAYS(NOW())-TO_DAYS(date_due) ) = delay3 ) |
236 |
OR (TO_DAYS(NOW())-TO_DAYS(date_due) ) = delay3 ) |
210 |
GROUP BY items.itemnumber |
237 |
GROUP BY items.itemnumber |
211 |
"; |
238 |
"; |
212 |
my $sth = $dbh->prepare($query); |
239 |
my $sth = $dbh->prepare($query); |
213 |
$sth->execute(); |
240 |
$sth->execute(); |
214 |
my @results; |
241 |
my @results; |
215 |
while( my $issue = $sth->fetchrow_hashref() ) { |
242 |
while ( my $issue = $sth->fetchrow_hashref() ) { |
216 |
if ( $issue->{'daysoverdue'} == $issue->{'delay1'} ) { |
243 |
if ( $issue->{'daysoverdue'} == $issue->{'delay1'} ) { |
217 |
$issue->{'level'} = 1; |
244 |
$issue->{'level'} = 1; |
218 |
} elsif ( $issue->{'daysoverdue'} == $issue->{'delay2'} ) { |
245 |
} |
219 |
$issue->{'level'} = 2; |
246 |
elsif ( $issue->{'daysoverdue'} == $issue->{'delay2'} ) { |
220 |
} elsif ( $issue->{'daysoverdue'} == $issue->{'delay3'} ) { |
247 |
$issue->{'level'} = 2; |
221 |
$issue->{'level'} = 3; |
248 |
} |
222 |
} else { |
249 |
elsif ( $issue->{'daysoverdue'} == $issue->{'delay3'} ) { |
223 |
# this shouldn't ever happen, based our SQL criteria |
250 |
$issue->{'level'} = 3; |
224 |
} |
251 |
} |
225 |
push @results, $issue; |
252 |
else { |
226 |
} |
253 |
|
227 |
return @results; |
254 |
# this shouldn't ever happen, based our SQL criteria |
|
|
255 |
} |
256 |
push @results, $issue; |
257 |
} |
258 |
return @results; |
228 |
} |
259 |
} |
229 |
|
260 |
|
230 |
sub GetPredueIssues { |
261 |
sub GetPredueIssues { |
231 |
my $query = "SELECT borrowers.borrowernumber, borrowers.cardnumber, borrowers.title as patron_title, borrowers.firstname, borrowers.surname, |
262 |
my $query = |
|
|
263 |
"SELECT borrowers.borrowernumber, borrowers.cardnumber, borrowers.title as patron_title, borrowers.firstname, borrowers.surname, |
232 |
borrowers.phone, borrowers.email, borrowers.branchcode, biblio.biblionumber, biblio.title, items.barcode, issues.date_due, |
264 |
borrowers.phone, borrowers.email, borrowers.branchcode, biblio.biblionumber, biblio.title, items.barcode, issues.date_due, |
233 |
issues.branchcode as site, branches.branchname as site_name |
265 |
issues.branchcode as site, branches.branchname as site_name |
234 |
FROM borrowers JOIN issues USING (borrowernumber) |
266 |
FROM borrowers JOIN issues USING (borrowernumber) |
Lines 242-259
sub GetPredueIssues {
Link Here
|
242 |
AND message_transport_type = 'phone' |
274 |
AND message_transport_type = 'phone' |
243 |
AND message_name = 'Advance_Notice' |
275 |
AND message_name = 'Advance_Notice' |
244 |
"; |
276 |
"; |
245 |
my $sth = $dbh->prepare($query); |
277 |
my $sth = $dbh->prepare($query); |
246 |
$sth->execute(); |
278 |
$sth->execute(); |
247 |
my @results; |
279 |
my @results; |
248 |
while( my $issue = $sth->fetchrow_hashref() ) { |
280 |
while ( my $issue = $sth->fetchrow_hashref() ) { |
249 |
$issue->{'level'} = 1; # only one level for Predue notifications |
281 |
$issue->{'level'} = 1; # only one level for Predue notifications |
250 |
push @results, $issue; |
282 |
push @results, $issue; |
251 |
} |
283 |
} |
252 |
return @results; |
284 |
return @results; |
253 |
} |
285 |
} |
254 |
|
286 |
|
255 |
sub GetWaitingHolds { |
287 |
sub GetWaitingHolds { |
256 |
my $query = "SELECT borrowers.borrowernumber, borrowers.cardnumber, borrowers.title as patron_title, borrowers.firstname, borrowers.surname, |
288 |
my $query = |
|
|
289 |
"SELECT borrowers.borrowernumber, borrowers.cardnumber, borrowers.title as patron_title, borrowers.firstname, borrowers.surname, |
257 |
borrowers.phone, borrowers.email, borrowers.branchcode, biblio.biblionumber, biblio.title, items.barcode, reserves.waitingdate, |
290 |
borrowers.phone, borrowers.email, borrowers.branchcode, biblio.biblionumber, biblio.title, items.barcode, reserves.waitingdate, |
258 |
reserves.branchcode AS site, branches.branchname AS site_name, |
291 |
reserves.branchcode AS site, branches.branchname AS site_name, |
259 |
TO_DAYS(NOW())-TO_DAYS(reserves.waitingdate) AS days_since_waiting |
292 |
TO_DAYS(NOW())-TO_DAYS(reserves.waitingdate) AS days_since_waiting |
Lines 268-295
sub GetWaitingHolds {
Link Here
|
268 |
AND message_transport_type = 'phone' |
301 |
AND message_transport_type = 'phone' |
269 |
AND message_name = 'Hold_Filled' |
302 |
AND message_name = 'Hold_Filled' |
270 |
"; |
303 |
"; |
271 |
my $pickupdelay = C4::Context->preference("ReservesMaxPickUpDelay"); |
304 |
my $pickupdelay = C4::Context->preference("ReservesMaxPickUpDelay"); |
272 |
my $sth = $dbh->prepare($query); |
305 |
my $sth = $dbh->prepare($query); |
273 |
$sth->execute(); |
306 |
$sth->execute(); |
274 |
my @results; |
307 |
my @results; |
275 |
while( my $issue = $sth->fetchrow_hashref() ) { |
308 |
while ( my $issue = $sth->fetchrow_hashref() ) { |
276 |
my @waitingdate = split( /-/, $issue->{'waitingdate'} ); |
309 |
my @waitingdate = split( /-/, $issue->{'waitingdate'} ); |
277 |
my @date_due = Add_Delta_Days( $waitingdate[0], $waitingdate[1], $waitingdate[2], $pickupdelay ); |
310 |
my @date_due = |
278 |
$issue->{'date_due'} = sprintf( "%04d-%02d-%02d", $date_due[0], $date_due[1], $date_due[2] ); |
311 |
Add_Delta_Days( $waitingdate[0], $waitingdate[1], $waitingdate[2], |
279 |
$issue->{'level'} = 1; # only one level for Hold Waiting notifications |
312 |
$pickupdelay ); |
280 |
|
313 |
$issue->{'date_due'} = |
281 |
my $days_to_subtract = 0; |
314 |
sprintf( "%04d-%02d-%02d", $date_due[0], $date_due[1], $date_due[2] ); |
282 |
my $calendar = C4::Calendar->new( branchcode => $issue->{'site'} ); |
315 |
$issue->{'level'} = 1; # only one level for Hold Waiting notifications |
283 |
while( $calendar->isHoliday( reverse( Add_Delta_Days( $waitingdate[0], $waitingdate[1], $waitingdate[2], $days_to_subtract ) ) ) ) { |
316 |
|
284 |
$days_to_subtract++; |
317 |
my $days_to_subtract = 0; |
285 |
} |
318 |
my $calendar = C4::Calendar->new( branchcode => $issue->{'site'} ); |
286 |
$issue->{'days_since_waiting'} = $issue->{'days_since_waiting'} - $days_to_subtract; |
319 |
while ( |
287 |
|
320 |
$calendar->isHoliday( |
288 |
if ( ( grep $_ eq $issue->{'days_since_waiting'}, @holds_waiting_days_to_call ) || !scalar( @holds_waiting_days_to_call ) ) { |
321 |
reverse( |
289 |
push @results, $issue; |
322 |
Add_Delta_Days( |
290 |
} |
323 |
$waitingdate[0], $waitingdate[1], |
291 |
} |
324 |
$waitingdate[2], $days_to_subtract |
292 |
return @results; |
325 |
) |
293 |
|
326 |
) |
|
|
327 |
) |
328 |
) |
329 |
{ |
330 |
$days_to_subtract++; |
331 |
} |
332 |
$issue->{'days_since_waiting'} = |
333 |
$issue->{'days_since_waiting'} - $days_to_subtract; |
334 |
|
335 |
if ( |
336 |
( |
337 |
grep $_ eq $issue->{'days_since_waiting'}, |
338 |
@holds_waiting_days_to_call |
339 |
) |
340 |
|| !scalar(@holds_waiting_days_to_call) |
341 |
) |
342 |
{ |
343 |
push @results, $issue; |
344 |
} |
345 |
} |
346 |
return @results; |
294 |
|
347 |
|
295 |
} |
348 |
} |
296 |
- |
|
|