X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=misc%2Fcronjobs%2Foverdue_notices.pl;h=8c0bc12d3049493d0ad1371c959336defc1d87fe;hb=8648c21ddf975d9c8b589c8457e73e511077a05b;hp=21e7dc3dd5beb116e0837bcb955954bb9ef58b06;hpb=b9d743a9281bfd6c853ffaa639577e1801f3b71b;p=koha_fer diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl index 21e7dc3dd5..8c0bc12d30 100755 --- a/misc/cronjobs/overdue_notices.pl +++ b/misc/cronjobs/overdue_notices.pl @@ -143,6 +143,10 @@ Default items.content lists only those items that fall in the range of the currently processing notice. Choose list-all to include all overdue items in the list (limited by B<-max> setting). +=item B<-date> + +use it in order to send overdues on a specific date and not Now. + =back =head1 DESCRIPTION @@ -259,6 +263,7 @@ my $listall = 0; my $itemscontent = join( ',', qw( date_due title barcode author itemnumber ) ); my @myborcat; my @myborcatout; +my $date; GetOptions( 'help|?' => \$help, @@ -268,12 +273,13 @@ GetOptions( 'max=s' => \$MAX, 'library=s' => \@branchcodes, 'csv:s' => \$csvfilename, # this optional argument gets '' if not supplied. - 'html:s' => \$htmlfilename, # this optional argument gets '' if not supplied. + 'html:s' => \$htmlfilename, # this optional argument gets '' if not supplied. 'itemscontent=s' => \$itemscontent, - 'list-all' => \$listall, - 't|triggered' => \$triggered, - 'borcat=s' => \@myborcat, - 'borcatout=s' => \@myborcatout, + 'list-all' => \$listall, + 't|triggered' => \$triggered, + 'date' => \$date, + 'borcat=s' => \@myborcat, + 'borcatout=s' => \@myborcatout, ) or pod2usage(2); pod2usage(1) if $help; pod2usage( -verbose => 2 ) if $man; @@ -305,7 +311,7 @@ if (@branchcodes) { @branches = grep { $seen{$_} } @overduebranches; - if (@overduebranches) { + if (@branches) { my $branch_word = scalar @branches > 1 ? 'branches' : 'branch'; $verbose and warn "$branch_word @branches have overdue rules\n"; @@ -320,10 +326,17 @@ if (@branchcodes) { } } +if ($date){ + $date=$dbh->quote($date); +} +else { + $date="NOW()"; +} + # these are the fields that will be substituted into <> my @item_content_fields = split( /,/, $itemscontent ); -binmode( STDOUT, ":utf8" ); +binmode( STDOUT, ':encoding(UTF-8)' ); our $csv; # the Text::CSV_XS object @@ -350,8 +363,8 @@ if ( defined $htmlfilename ) { if ( $htmlfilename eq '' ) { $html_fh = *STDOUT; } else { - my $today = C4::Dates->new(); - open $html_fh, ">",File::Spec->catdir ($htmlfilename,"notices-".$today->output('iso').".html"); + my $today = DateTime->now(time_zone => C4::Context->tz ); + open $html_fh, ">",File::Spec->catdir ($htmlfilename,"notices-".$today->ymd().".html"); } print $html_fh "\n"; @@ -376,13 +389,13 @@ foreach my $branchcode (@branches) { $verbose and warn sprintf "branchcode : '%s' using %s\n", $branchcode, $admin_email_address; my $sth2 = $dbh->prepare( <<'END_SQL' ); -SELECT biblio.*, items.*, issues.*, biblioitems.itemtype, TO_DAYS(NOW())-TO_DAYS(date_due) AS days_overdue +SELECT biblio.*, items.*, issues.*, biblioitems.itemtype, TO_DAYS($date)-TO_DAYS(date_due) AS days_overdue FROM issues,items,biblio, biblioitems WHERE items.itemnumber=issues.itemnumber AND biblio.biblionumber = items.biblionumber AND biblio.biblionumber = biblioitems.biblionumber AND issues.borrowernumber = ? - AND TO_DAYS(NOW())-TO_DAYS(date_due) BETWEEN ? and ? + AND TO_DAYS($date)-TO_DAYS(date_due) BETWEEN ? and ? END_SQL my $query = "SELECT * FROM overduerules WHERE delay1 IS NOT NULL AND branchcode = ? "; @@ -410,7 +423,7 @@ END_SQL my $mindays = $overdue_rules->{"delay$i"}; # the notice will be sent after mindays days (grace period) my $maxdays = ( $overdue_rules->{ "delay" . ( $i + 1 ) } - ? $overdue_rules->{ "delay" . ( $i + 1 ) } + ? $overdue_rules->{ "delay" . ( $i + 1 ) } - 1 : ($MAX) ); # issues being more than maxdays late are managed somewhere else. (borrower probably suspended) @@ -426,7 +439,7 @@ END_SQL # my $borrower_sql = <<'END_SQL'; -SELECT COUNT(*), issues.borrowernumber, firstname, surname, address, address2, city, zipcode, country, email, MIN(date_due) as longest_issue +SELECT distinct(issues.borrowernumber), firstname, surname, address, address2, city, zipcode, country, email FROM issues,borrowers,categories WHERE issues.borrowernumber=borrowers.borrowernumber AND borrowers.categorycode=categories.categorycode @@ -440,13 +453,12 @@ END_SQL $borrower_sql .= ' AND borrowers.categorycode=? '; push @borrower_parameters, $overdue_rules->{categorycode}; } - $borrower_sql .= ' AND categories.overduenoticerequired=1 - GROUP BY issues.borrowernumber '; + $borrower_sql .= ' AND categories.overduenoticerequired=1 '; if($triggered) { - $borrower_sql .= ' HAVING TO_DAYS(NOW())-TO_DAYS(longest_issue) = ?'; + $borrower_sql .= ' AND TO_DAYS($date)-TO_DAYS(date_due) = ?'; push @borrower_parameters, $mindays; } else { - $borrower_sql .= ' HAVING TO_DAYS(NOW())-TO_DAYS(longest_issue) BETWEEN ? and ? ' ; + $borrower_sql .= ' AND TO_DAYS($date)-TO_DAYS(date_due) BETWEEN ? and ? ' ; push @borrower_parameters, $mindays, $maxdays; } @@ -455,21 +467,11 @@ END_SQL $sth->execute(@borrower_parameters); $verbose and warn $borrower_sql . "\n $branchcode | " . $overdue_rules->{'categorycode'} . "\n ($mindays, $maxdays)\nreturns " . $sth->rows . " rows"; - while ( my ($itemcount, $borrowernumber, $firstname, $lastname, - $address1, $address2, $city, $postcode, $country, $email, - $longest_issue ) = $sth->fetchrow ) + while ( my ( $borrowernumber, $firstname, $lastname, + $address1, $address2, $city, $postcode, $country, $email + ) = $sth->fetchrow ) { - $verbose and warn "borrower $firstname, $lastname ($borrowernumber) has $itemcount items triggering level $i."; - - my $letter = C4::Letters::getletter( 'circulation', $overdue_rules->{"letter$i"} ); - - unless ($letter) { - $verbose and warn "Message '$overdue_rules->{letter$i}' content not found"; - - # might as well skip while PERIOD, no other borrowers are going to work. - # FIXME : Does this mean a letter must be defined in order to trigger a debar ? - next PERIOD; - } + $verbose and warn "borrower $firstname, $lastname ($borrowernumber) has items triggering level $i."; if ( $overdue_rules->{"debarred$i"} ) { @@ -484,22 +486,23 @@ END_SQL my $titles = ""; my @items = (); - my $i = 0; + my $j = 0; my $exceededPrintNoticesMaxLines = 0; while ( my $item_info = $sth2->fetchrow_hashref() ) { - if ( ( !$email || $nomail ) && $PrintNoticesMaxLines && $i >= $PrintNoticesMaxLines ) { + if ( ( !$email || $nomail ) && $PrintNoticesMaxLines && $j >= $PrintNoticesMaxLines ) { $exceededPrintNoticesMaxLines = 1; last; } - $i++; + $j++; my @item_info = map { $_ =~ /^date|date$/ ? format_date( $item_info->{$_} ) : $item_info->{$_} || '' } @item_content_fields; $titles .= join("\t", @item_info) . "\n"; $itemcount++; - push @items, { itemnumber => $item_info->{'itemnumber'}, biblionumber => $item_info->{'biblionumber'} }; + push @items, $item_info; } $sth2->finish; - $letter = parse_letter( - { letter => $letter, + + my $letter = parse_letter( + { letter_code => $overdue_rules->{"letter$i"}, borrowernumber => $borrowernumber, branchcode => $branchcode, items => \@items, @@ -510,6 +513,13 @@ END_SQL } } ); + unless ($letter) { + $verbose and warn "Message '$overdue_rules->{letter$i}' content not found"; + + # might as well skip while PERIOD, no other borrowers are going to work. + # FIXME : Does this mean a letter must be defined in order to trigger a debar ? + next PERIOD; + } if ( $exceededPrintNoticesMaxLines ) { $letter->{'content'} .= "List too long for form; please check your account online for a complete list of your overdue items."; @@ -644,53 +654,56 @@ substituted keys and values. =cut -sub parse_letter { # FIXME: this code should probably be moved to C4::Letters:parseletter +sub parse_letter { my $params = shift; - foreach my $required (qw( letter borrowernumber )) { - return unless exists $params->{$required}; + foreach my $required (qw( letter_code borrowernumber )) { + return unless ( exists $params->{$required} && $params->{$required} ); } - my $todaysdate = C4::Dates->new()->output("syspref"); - $params->{'letter'}->{title} =~ s/<>/$todaysdate/g; - $params->{'letter'}->{content} =~ s/<>/$todaysdate/g; + my $substitute = $params->{'substitute'} || {}; + $substitute->{today} ||= C4::Dates->new()->output("syspref"); - if ( $params->{'substitute'} ) { - while ( my ( $key, $replacedby ) = each %{ $params->{'substitute'} } ) { - my $replacefield = "<<$key>>"; - $params->{'letter'}->{title} =~ s/$replacefield/$replacedby/g; - $params->{'letter'}->{content} =~ s/$replacefield/$replacedby/g; - } + my %tables = ( 'borrowers' => $params->{'borrowernumber'} ); + if ( my $p = $params->{'branchcode'} ) { + $tables{'branches'} = $p; } - $params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} ); - - if ( $params->{'branchcode'} ) { - $params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} ); + my $currency_format; + if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/o) { # process any fine tags... + $currency_format = $1; + $params->{'letter'}->{'content'} =~ s/.*<\/fine>/<>/o; } - if ( $params->{'items'} ) { + my @item_tables; + if ( my $i = $params->{'items'} ) { my $item_format = ''; - PROCESS_ITEMS: - while (scalar(@{$params->{'items'}}) > 0) { - my $item = shift @{$params->{'items'}}; + foreach my $item (@$i) { my $fine = GetFine($item->{'itemnumber'}, $params->{'borrowernumber'}); if (!$item_format) { $params->{'letter'}->{'content'} =~ m/(.*<\/item>)/; $item_format = $1; } - if ($params->{'letter'}->{'content'} =~ m/(.*)<\/fine>/) { # process any fine tags... - my $formatted_fine = currency_format("$1", "$fine", FMT_SYMBOL); - $params->{'letter'}->{'content'} =~ s/.*<\/fine>/$formatted_fine/; - } - $params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'biblio', $item->{'biblionumber'} ); - $params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $item->{'biblionumber'} ); - $params->{'letter'} = C4::Letters::parseletter( $params->{'letter'}, 'items', $item->{'itemnumber'} ); - $params->{'letter'}->{'content'} =~ s/(.*<\/item>)/$1\n$item_format/ if scalar(@{$params->{'items'}} > 0); + $item->{'fine'} = currency_format($currency_format, "$fine", FMT_SYMBOL) + if $currency_format; + + push @item_tables, { + 'biblio' => $item->{'biblionumber'}, + 'biblioitems' => $item->{'biblionumber'}, + 'items' => $item, + 'issues' => $item->{'itemnumber'}, + }; } } - $params->{'letter'}->{'content'} =~ s/<\/{0,1}?item>//g; # strip all remaining item tags... - return $params->{'letter'}; + + return C4::Letters::GetPreparedLetter ( + module => 'circulation', + letter_code => $params->{'letter_code'}, + branchcode => $params->{'branchcode'}, + tables => \%tables, + substitute => $substitute, + repeat => { item => \@item_tables }, + ); } =head2 prepare_letter_for_printing