Lines 105-110
defaults to due date,title,author,barcode
Link Here
|
105 |
Other possible values come from fields in the biblios, items and |
105 |
Other possible values come from fields in the biblios, items and |
106 |
issues tables. |
106 |
issues tables. |
107 |
|
107 |
|
|
|
108 |
=item B<--date_in_history> |
109 |
|
110 |
YYYY-MM-DD of the date from which to generate advance notices. |
111 |
Used to fix failed advance_notices.pl-cronjob runs, or for debugging purposes. |
112 |
So if today is 2014-09-15 and you want to run advance_notices.pl for two days |
113 |
ago, you can run "advance_notices.pl -c --date_in_history 2014-09-13 -n" |
114 |
to generate those notifications. |
115 |
Be aware not to send advance notices after users have received overdue |
116 |
notifications! |
117 |
|
118 |
To fix a crashed advance_notices.pl-run two days ago, run the following command: |
119 |
advance_notices.pl -c --date_in_history 2014-09-13 \ |
120 |
--exclude_days_until_due 2,0 -n |
121 |
Be aware that you have already sent the advance notices for users requesting the |
122 |
notice 2 days in advance, and also the overdue notification is sent. |
123 |
Remove -n -flag if you get the desired result. |
124 |
|
125 |
=item B<--exclude_days_until_due> |
126 |
|
127 |
An array of integers, each a duration in days in advance to NOT send advance notices. |
128 |
You can skip processing of some advance notices which have days_until_due of the |
129 |
given values. See --date_in_history for a useful usage scenario. |
130 |
|
131 |
ex. --exclude_days_until_due 0,2,3 |
132 |
|
108 |
=back |
133 |
=back |
109 |
|
134 |
|
110 |
=head1 DESCRIPTION |
135 |
=head1 DESCRIPTION |
Lines 170-175
my $mindays = 0; # -m: Maximu
Link Here
|
170 |
my $maxdays = 30; # -e: the End of the time period |
195 |
my $maxdays = 30; # -e: the End of the time period |
171 |
my $verbose = 0; # -v: verbose |
196 |
my $verbose = 0; # -v: verbose |
172 |
my $itemscontent = join(',',qw( date_due title author barcode )); |
197 |
my $itemscontent = join(',',qw( date_due title author barcode )); |
|
|
198 |
my $exclude_days_until_due; |
199 |
|
200 |
#Defaulting $date_in_history to NOW() |
201 |
#Getting the ISO 8601 Date in the most efficient way for the computer :) |
202 |
my @t = localtime; $t[5] += 1900; $t[4]++; |
203 |
my $date_in_history = sprintf "%04d-%02d-%02d", @t[5,4,3]; |
204 |
undef @t; #Don't pollute package namespace! |
173 |
|
205 |
|
174 |
my $help = 0; |
206 |
my $help = 0; |
175 |
my $man = 0; |
207 |
my $man = 0; |
Lines 182-187
GetOptions(
Link Here
|
182 |
'm:i' => \$maxdays, |
214 |
'm:i' => \$maxdays, |
183 |
'v' => \$verbose, |
215 |
'v' => \$verbose, |
184 |
'itemscontent=s' => \$itemscontent, |
216 |
'itemscontent=s' => \$itemscontent, |
|
|
217 |
'date_in_history=s' => \$date_in_history, |
218 |
'exclude_days_until_due=s' => \$exclude_days_until_due, |
185 |
)or pod2usage(2); |
219 |
)or pod2usage(2); |
186 |
pod2usage(1) if $help; |
220 |
pod2usage(1) if $help; |
187 |
pod2usage( -verbose => 2 ) if $man;; |
221 |
pod2usage( -verbose => 2 ) if $man;; |
Lines 205-211
unless ($confirm) {
Link Here
|
205 |
my @item_content_fields = split(/,/,$itemscontent); |
239 |
my @item_content_fields = split(/,/,$itemscontent); |
206 |
|
240 |
|
207 |
warn 'getting upcoming due issues' if $verbose; |
241 |
warn 'getting upcoming due issues' if $verbose; |
208 |
my $upcoming_dues = C4::Circulation::GetUpcomingDueIssues( { days_in_advance => $maxdays } ); |
242 |
my $upcoming_dues = C4::Circulation::GetUpcomingDueIssues( { days_in_advance => $maxdays, date_in_history => $date_in_history } ); |
209 |
warn 'found ' . scalar( @$upcoming_dues ) . ' issues' if $verbose; |
243 |
warn 'found ' . scalar( @$upcoming_dues ) . ' issues' if $verbose; |
210 |
|
244 |
|
211 |
# hash of borrowernumber to number of items upcoming |
245 |
# hash of borrowernumber to number of items upcoming |
Lines 221-227
SELECT biblio.*, items.*, issues.*
Link Here
|
221 |
AND biblio.biblionumber=items.biblionumber |
255 |
AND biblio.biblionumber=items.biblionumber |
222 |
AND issues.borrowernumber = ? |
256 |
AND issues.borrowernumber = ? |
223 |
AND issues.itemnumber = ? |
257 |
AND issues.itemnumber = ? |
224 |
AND (TO_DAYS(date_due)-TO_DAYS(NOW()) = ?) |
258 |
AND (TO_DAYS(date_due)-TO_DAYS(?) = ?) |
225 |
END_SQL |
259 |
END_SQL |
226 |
|
260 |
|
227 |
my $admin_adress = C4::Context->preference('KohaAdminEmailAddress'); |
261 |
my $admin_adress = C4::Context->preference('KohaAdminEmailAddress'); |
Lines 232-237
UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
Link Here
|
232 |
warn 'examining ' . $upcoming->{'itemnumber'} . ' upcoming due items' if $verbose; |
266 |
warn 'examining ' . $upcoming->{'itemnumber'} . ' upcoming due items' if $verbose; |
233 |
# warn( Data::Dumper->Dump( [ $upcoming ], [ 'overdue' ] ) ); |
267 |
# warn( Data::Dumper->Dump( [ $upcoming ], [ 'overdue' ] ) ); |
234 |
|
268 |
|
|
|
269 |
#Skip some days for --exclude_days_until_due |
270 |
my $days_until_due = $upcoming->{'days_until_due'}; |
271 |
if (defined $exclude_days_until_due && $exclude_days_until_due =~ /(^|,)$days_until_due(,|$)/) { |
272 |
next UPCOMINGITEM; |
273 |
} |
274 |
|
235 |
my $from_address = $upcoming->{branchemail} || $admin_adress; |
275 |
my $from_address = $upcoming->{branchemail} || $admin_adress; |
236 |
|
276 |
|
237 |
my $borrower_preferences; |
277 |
my $borrower_preferences; |
Lines 250-256
UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
Link Here
|
250 |
} else { |
290 |
} else { |
251 |
my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} ); |
291 |
my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} ); |
252 |
my $letter_type = 'DUE'; |
292 |
my $letter_type = 'DUE'; |
253 |
$sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},'0'); |
293 |
$sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},$date_in_history,'0'); |
254 |
my $titles = ""; |
294 |
my $titles = ""; |
255 |
while ( my $item_info = $sth->fetchrow_hashref()) { |
295 |
while ( my $item_info = $sth->fetchrow_hashref()) { |
256 |
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields; |
296 |
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields; |
Lines 286-292
UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
Link Here
|
286 |
} else { |
326 |
} else { |
287 |
my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} ); |
327 |
my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} ); |
288 |
my $letter_type = 'PREDUE'; |
328 |
my $letter_type = 'PREDUE'; |
289 |
$sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},$borrower_preferences->{'days_in_advance'}); |
329 |
$sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},$date_in_history,$borrower_preferences->{'days_in_advance'}); |
290 |
my $titles = ""; |
330 |
my $titles = ""; |
291 |
while ( my $item_info = $sth->fetchrow_hashref()) { |
331 |
while ( my $item_info = $sth->fetchrow_hashref()) { |
292 |
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields; |
332 |
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields; |
Lines 339-345
SELECT biblio.*, items.*, issues.*
Link Here
|
339 |
WHERE items.itemnumber=issues.itemnumber |
379 |
WHERE items.itemnumber=issues.itemnumber |
340 |
AND biblio.biblionumber=items.biblionumber |
380 |
AND biblio.biblionumber=items.biblionumber |
341 |
AND issues.borrowernumber = ? |
381 |
AND issues.borrowernumber = ? |
342 |
AND (TO_DAYS(date_due)-TO_DAYS(NOW()) = ?) |
382 |
AND (TO_DAYS(date_due)-TO_DAYS(?) = ?) |
343 |
END_SQL |
383 |
END_SQL |
344 |
PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) { |
384 |
PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) { |
345 |
@letters = (); |
385 |
@letters = (); |
Lines 354-360
PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) {
Link Here
|
354 |
|
394 |
|
355 |
my $letter_type = 'PREDUEDGST'; |
395 |
my $letter_type = 'PREDUEDGST'; |
356 |
|
396 |
|
357 |
$sth->execute($borrowernumber,$borrower_preferences->{'days_in_advance'}); |
397 |
$sth->execute($borrowernumber,$date_in_history,$borrower_preferences->{'days_in_advance'}); |
358 |
my $titles = ""; |
398 |
my $titles = ""; |
359 |
while ( my $item_info = $sth->fetchrow_hashref()) { |
399 |
while ( my $item_info = $sth->fetchrow_hashref()) { |
360 |
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields; |
400 |
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields; |
Lines 412-418
PATRON: while ( my ( $borrowernumber, $digest ) = each %$due_digest ) {
Link Here
|
412 |
next PATRON unless $borrower_preferences; # how could this happen? |
452 |
next PATRON unless $borrower_preferences; # how could this happen? |
413 |
|
453 |
|
414 |
my $letter_type = 'DUEDGST'; |
454 |
my $letter_type = 'DUEDGST'; |
415 |
$sth->execute($borrowernumber,'0'); |
455 |
$sth->execute($borrowernumber,$date_in_history,'0'); |
416 |
my $titles = ""; |
456 |
my $titles = ""; |
417 |
while ( my $item_info = $sth->fetchrow_hashref()) { |
457 |
while ( my $item_info = $sth->fetchrow_hashref()) { |
418 |
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields; |
458 |
my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields; |
419 |
- |
|
|