Bug 20076: Add syspref to remove overdues notification by email to staff if user...
[srvgit] / misc / cronjobs / overdue_notices.pl
index d8fa4ee..c142bb7 100755 (executable)
 
 use Modern::Perl;
 
-BEGIN {
-
-    # find Koha's Perl modules
-    # test carefully before changing this
-    use FindBin;
-    eval { require "$FindBin::Bin/../kohalib.pl" };
-}
-
-use Getopt::Long;
-use Pod::Usage;
+use Getopt::Long qw( GetOptions );
+use Pod::Usage qw( pod2usage );
 use Text::CSV_XS;
 use DateTime;
 use DateTime::Duration;
@@ -37,10 +29,10 @@ use DateTime::Duration;
 use Koha::Script -cron;
 use C4::Context;
 use C4::Letters;
-use C4::Overdues qw(GetFine GetOverdueMessageTransportTypes parse_overdues_letter);
-use C4::Log;
-use Koha::Patron::Debarments qw(AddUniqueDebarment);
-use Koha::DateUtils;
+use C4::Overdues qw( GetOverdueMessageTransportTypes parse_overdues_letter );
+use C4::Log qw( cronlogaction );
+use Koha::Patron::Debarments qw( AddUniqueDebarment );
+use Koha::DateUtils qw( dt_from_string output_pref );
 use Koha::Calendar;
 use Koha::Libraries;
 use Koha::Acquisition::Currencies;
@@ -58,23 +50,26 @@ overdue_notices.pl
   [ -email <email_type> ... ]
 
  Options:
-   -help                          brief help message
-   -man                           full documentation
-   -v                             verbose
-   -n                             No email will be sent
-   -max          <days>           maximum days overdue to deal with
-   -library      <branchname>     only deal with overdues from this library (repeatable : several libraries can be given)
-   -csv          <filename>       populate CSV file
-   -html         <directory>      Output html to a file in the given directory
-   -text         <directory>      Output plain text to a file in the given directory
-   -itemscontent <list of fields> item information in templates
-   -borcat       <categorycode>   category code that must be included
-   -borcatout    <categorycode>   category code that must be excluded
-   -t                             only include triggered overdues
+   -help                          Brief help message.
+   -man                           Full documentation.
+   -v                             Verbose mode.
+   -n                             No email will be sent.
+   -max          <days>           Maximum days overdue to deal with.
+   -library      <branchcode>     Only deal with overdues from this library.
+                                  (repeatable : several libraries can be given)
+   -csv          <filename>       Populate CSV file.
+   -html         <directory>      Output html to a file in the given directory.
+   -text         <directory>      Output plain text to a file in the given directory.
+   -itemscontent <list of fields> Item information in templates.
+   -borcat       <categorycode>   Category code that must be included.
+   -borcatout    <categorycode>   Category code that must be excluded.
+   -t                             Only include triggered overdues.
    --test                         Run in test mode. No changes will be made on the DB.
-   -list-all                      list all overdues
-   -date         <yyyy-mm-dd>     emulate overdues run for this date
-   -email        <email_type>     type of email that will be used. Can be 'email', 'emailpro' or 'B_email'. Repeatable.
+   -list-all                      List all overdues.
+   -date         <yyyy-mm-dd>     Emulate overdues run for this date.
+   -email        <email_type>     Type of email that will be used.
+                                  Can be 'email', 'emailpro' or 'B_email'. Repeatable.
+   --frombranch                   Set the from address for the notice to one of 'item-homebranch' or 'item-issuebranch'.
 
 =head1 OPTIONS
 
@@ -183,6 +178,12 @@ use it in order to send overdues on a specific date and not Now. Format: YYYY-MM
 
 Allows to specify which type of email will be used. Can be email, emailpro or B_email. Repeatable.
 
+=item B<--frombranch>
+
+Use the address information from the item homebranch library instead of the issuing library.
+
+Defaults to 'item-issuebranch'
+
 =back
 
 =head1 DESCRIPTION
@@ -292,6 +293,7 @@ my $verbose = 0;
 my $nomail  = 0;
 my $MAX     = 90;
 my $test_mode = 0;
+my $frombranch = 'item-issuebranch';
 my @branchcodes; # Branch(es) passed as parameter
 my @emails_to_use;    # Emails to use for messaging
 my @emails;           # Emails given in command-line parameters
@@ -323,6 +325,7 @@ GetOptions(
     'borcat=s'       => \@myborcat,
     'borcatout=s'    => \@myborcatout,
     'email=s'        => \@emails,
+    'frombranch=s'   => \$frombranch,
 ) or pod2usage(2);
 pod2usage(1) if $help;
 pod2usage( -verbose => 2 ) if $man;
@@ -332,8 +335,13 @@ if ( defined $csvfilename && $csvfilename =~ /^-/ ) {
     warn qq(using "$csvfilename" as filename, that seems odd);
 }
 
-my @overduebranches    = C4::Overdues::GetBranchcodesWithOverdueRules();       # Branches with overdue rules
-my @branches;                                                                  # Branches passed as parameter with overdue rules
+die "--frombranch takes item-homebranch or item-issuebranch only"
+    unless ( $frombranch eq 'item-issuebranch'
+        || $frombranch eq 'item-homebranch' );
+my $owning_library = ( $frombranch eq 'item-homebranch' ) ? 1 : 0;
+
+my @overduebranches    = C4::Overdues::GetBranchcodesWithOverdueRules();    # Branches with overdue rules
+my @branches;                                    # Branches passed as parameter with overdue rules
 my $branchcount = scalar(@overduebranches);
 
 my $overduebranch_word = scalar @overduebranches > 1 ? 'branches' : 'branch';
@@ -357,8 +365,9 @@ if (@branchcodes) {
     
     if (@branches) {
 
-       my $branch_word = scalar @branches > 1 ? 'branches' : 'branch';
-       $verbose and warn "$branch_word @branches have overdue rules\n";
+        my $branch_word = scalar @branches > 1 ? 'branches' : 'branch';
+    $verbose and warn "$branch_word @branches have overdue rules\n";
+
 
     } else {
     
@@ -396,7 +405,7 @@ binmode( STDOUT, ':encoding(UTF-8)' );
 our $csv;       # the Text::CSV_XS object
 our $csv_fh;    # the filehandle to the CSV file.
 if ( defined $csvfilename ) {
-    my $sep_char = C4::Context->preference('delimiter') || ';';
+    my $sep_char = C4::Context->preference('CSVDelimiter') || ';';
     $sep_char = "\t" if ($sep_char eq 'tabulation');
     $csv = Text::CSV_XS->new( { binary => 1 , sep_char => $sep_char } );
     if ( $csvfilename eq '' ) {
@@ -439,7 +448,7 @@ elsif ( defined $text_filename ) {
     $fh = *STDOUT;
   } else {
     my $today = dt_from_string();
-    open $fh, ">",File::Spec->catdir ($text_filename,"notices-".$today->ymd().".txt");
+    open $fh, ">:encoding(UTF-8)",File::Spec->catdir ($text_filename,"notices-".$today->ymd().".txt");
   }
 }
 
@@ -453,14 +462,14 @@ foreach my $branchcode (@branches) {
     }
 
     my $library             = Koha::Libraries->find($branchcode);
-    my $admin_email_address = $library->branchemail
-      || C4::Context->preference('KohaAdminEmailAddress');
-    my $branch_email_address = $library->inbound_email_address;
+    my $admin_email_address = $library->from_email_address;
+    my $branch_email_address = C4::Context->preference('AddressForFailedOverdueNotices')
+      || $library->inbound_email_address;
     my @output_chunks;    # may be sent to mail or stdout or csv file.
 
     $verbose and warn sprintf "branchcode : '%s' using %s\n", $branchcode, $branch_email_address;
 
-    my $sth2 = $dbh->prepare( <<"END_SQL" );
+    my $sql2 = <<"END_SQL";
 SELECT biblio.*, items.*, issues.*, biblioitems.itemtype, branchname
   FROM issues,items,biblio, biblioitems, branches b
   WHERE items.itemnumber=issues.itemnumber
@@ -468,11 +477,17 @@ SELECT biblio.*, items.*, issues.*, biblioitems.itemtype, branchname
     AND b.branchcode = items.homebranch
     AND biblio.biblionumber   = biblioitems.biblionumber
     AND issues.borrowernumber = ?
-    AND issues.branchcode = ?
     AND items.itemlost = 0
     AND TO_DAYS($date)-TO_DAYS(issues.date_due) >= 0
 END_SQL
 
+    if($owning_library) {
+      $sql2 .= ' AND items.homebranch = ? ';
+    } else {
+      $sql2 .= ' AND issues.branchcode = ? ';
+    }
+    my $sth2 = $dbh->prepare($sql2);
+
     my $query = "SELECT * FROM overduerules WHERE delay1 IS NOT NULL AND branchcode = ? ";
     $query .= " AND categorycode IN (".join( ',' , ('?') x @myborcat ).") " if (@myborcat);
     $query .= " AND categorycode NOT IN (".join( ',' , ('?') x @myborcatout ).") " if (@myborcatout);
@@ -513,7 +528,7 @@ END_SQL
             # $letter->{'content'} is the text of the mail that is sent.
             # this text contains fields that are replaced by their value. Those fields must be written between brackets
             # The following fields are available :
-           # itemcount is interpreted here as the number of items in the overdue range defined by the current notice or all overdues < max if(-list-all).
+        # itemcount is interpreted here as the number of items in the overdue range defined by the current notice or all overdues < max if(-list-all).
             # <date> <itemcount> <firstname> <lastname> <address1> <address2> <address3> <city> <postcode> <country>
 
             my $borrower_sql = <<"END_SQL";
@@ -527,7 +542,11 @@ AND    TO_DAYS($date)-TO_DAYS(issues.date_due) >= 0
 END_SQL
             my @borrower_parameters;
             if ($branchcode) {
-                $borrower_sql .= ' AND issues.branchcode=? ';
+        if($owning_library) {
+            $borrower_sql .= ' AND items.homebranch=? ';
+        } else {
+            $borrower_sql .= ' AND issues.branchcode=? ';
+        }
                 push @borrower_parameters, $branchcode;
             }
             if ( $overdue_rules->{categorycode} ) {
@@ -537,7 +556,7 @@ END_SQL
             $borrower_sql .= '  AND categories.overduenoticerequired=1 ORDER BY issues.borrowernumber';
 
             # $sth gets borrower info iff at least one overdue item has triggered the overdue action.
-               my $sth = $dbh->prepare($borrower_sql);
+            my $sth = $dbh->prepare($borrower_sql);
             $sth->execute(@borrower_parameters);
 
             $verbose and warn $borrower_sql . "\n $branchcode | " . $overdue_rules->{'categorycode'} . "\n ($mindays, $maxdays, ".  $date_to_run->datetime() .")\nreturns " . $sth->rows . " rows";
@@ -597,7 +616,14 @@ END_SQL
                     }
                 }
 
-                my $letter = C4::Letters::getletter( 'circulation', $overdue_rules->{"letter$i"}, $branchcode );
+                my $letter = Koha::Notice::Templates->find_effective_template(
+                    {
+                        module     => 'circulation',
+                        code       => $overdue_rules->{"letter$i"},
+                        branchcode => $branchcode,
+                        lang       => $patron->lang
+                    }
+                );
 
                 unless ($letter) {
                     $verbose and warn qq|Message '$overdue_rules->{"letter$i"}' content not found|;
@@ -688,7 +714,16 @@ END_SQL
                     splice @items, $PrintNoticesMaxLines if $effective_mtt eq 'print' && $PrintNoticesMaxLines && scalar @items > $PrintNoticesMaxLines;
                     #catch the case where we are sending a print to someone with an email
 
-                    my $letter_exists = C4::Letters::getletter( 'circulation', $overdue_rules->{"letter$i"}, $branchcode, $effective_mtt ) ? 1 : 0;
+                    my $letter_exists = Koha::Notice::Templates->find_effective_template(
+                        {
+                            module     => 'circulation',
+                            code       => $overdue_rules->{"letter$i"},
+                            message_transport_type => $effective_mtt,
+                            branchcode => $branchcode,
+                            lang       => $patron->lang
+                        }
+                    );
+
                     my $letter = parse_overdues_letter(
                         {   letter_code     => $overdue_rules->{"letter$i"},
                             borrowernumber  => $borrowernumber,
@@ -704,7 +739,7 @@ END_SQL
                             message_transport_type => $letter_exists ? $effective_mtt : $mtt,
                         }
                     );
-                    unless ($letter) {
+                    unless ($letter && $letter->{content}) {
                         $verbose and warn qq|Message '$overdue_rules->{"letter$i"}' content not found|;
                         # this transport doesn't have a configured notice, so try another
                         next;
@@ -799,7 +834,7 @@ END_SQL
         # Generate the content of the csv with headers
         my $content;
         if ( defined $csvfilename ) {
-            my $delimiter = C4::Context->preference('delimiter') || ';';
+            my $delimiter = C4::Context->preference('CSVDelimiter') || ';';
             $content = join($delimiter, qw(title name surname address1 address2 zipcode city country email itemcount itemsinfo due_date issue_date)) . "\n";
         }
         else {
@@ -807,24 +842,28 @@ END_SQL
         }
         $content .= join( "\n", @output_chunks );
 
-        my $attachment = {
-            filename => defined $csvfilename ? 'attachment.csv' : 'attachment.txt',
-            type => 'text/plain',
-            content => $content, 
-        };
-
-        my $letter = {
-            title   => 'Overdue Notices',
-            content => 'These messages were not sent directly to the patrons.',
-        };
-        C4::Letters::EnqueueLetter(
-            {   letter                 => $letter,
-                borrowernumber         => undef,
-                message_transport_type => 'email',
-                attachments            => [$attachment],
-                to_address             => $branch_email_address,
-            }
-        ) unless $test_mode;
+        my $EmailOverduesNoEmail = C4::Context->preference('EmailOverduesNoEmail');
+        if ( $EmailOverduesNoEmail == 0) {
+            my $attachment = {
+                filename => defined $csvfilename ? 'attachment.csv' : 'attachment.txt',
+                type => 'text/plain',
+                content => $content,
+            };
+
+            my $letter = {
+                title   => 'Overdue Notices',
+                content => 'These messages were not sent directly to the patrons.',
+            };
+
+            C4::Letters::EnqueueLetter(
+                {   letter                 => $letter,
+                    borrowernumber         => undef,
+                    message_transport_type => 'email',
+                    attachments            => [$attachment],
+                    to_address             => $branch_email_address,
+                }
+            ) unless $test_mode;
+        }
     }
 
 }