Bug 17600: Standardize our EXPORT_OK
[srvgit] / misc / cronjobs / gather_print_notices.pl
index fb68085..a777acb 100755 (executable)
@@ -5,26 +5,25 @@ use Modern::Perl;
 BEGIN {
     # find Koha's Perl modules
     # test carefully before changing this
-    use FindBin;
+    use FindBin ();
     eval { require "$FindBin::Bin/../kohalib.pl" };
 }
 
-use CGI qw( utf8 ); # NOT a CGI script, this is just to keep C4::Templates::gettemplate happy
+use CGI; # NOT a CGI script, this is just to keep C4::Templates::gettemplate happy
+use Koha::Script -cron;
 use C4::Context;
-use C4::Dates;
-use C4::Debug;
-use C4::Letters;
+use C4::Letters qw( GetPrintMessages );
 use C4::Templates;
 use File::Spec;
-use Pod::Usage;
-use Getopt::Long;
-use C4::Log;
+use Pod::Usage qw( pod2usage );
+use Getopt::Long qw( GetOptions );
+use C4::Log qw( cronlogaction );
 
-use File::Basename qw( dirname );
-use Koha::DateUtils;
+use Koha::DateUtils qw( dt_from_string output_pref );
+use Koha::Util::OpenDocument qw( generate_ods );
+use MIME::Lite;
 
 my (
-    $stylesheet,
     $help,
     $split,
     $html,
@@ -33,6 +32,7 @@ my (
     $delimiter,
     @letter_codes,
     $send,
+    @emails,
 );
 
 $send = 1;
@@ -45,6 +45,7 @@ GetOptions(
     'd|delimiter:s' => \$delimiter,
     'letter_code:s' => \@letter_codes,
     'send!'         => \$send,
+    'e|email:s'     => \@emails,
 ) || pod2usage(1);
 
 pod2usage(0) if $help;
@@ -79,14 +80,16 @@ $delimiter ||= q|,|;
 
 cronlogaction();
 
-my $today        = C4::Dates->new();
+my $today_iso     = output_pref( { dt => dt_from_string, dateonly => 1, dateformat => 'iso' } ) ;
+my $today_syspref = output_pref( { dt => dt_from_string, dateonly => 1 } );
+
 my @all_messages = @{ GetPrintMessages() };
 
 # Filter by letter_code
 @all_messages = map {
     my $letter_code = $_->{letter_code};
     (
-        grep { /^$letter_code$/ } @letter_codes
+        grep { $_ eq $letter_code } @letter_codes
     ) ? $_ : ()
 } @all_messages if @letter_codes;
 exit unless @all_messages;
@@ -123,6 +126,22 @@ if ( $html ) {
     });
 }
 
+if ( @emails ) {
+    my $files = {
+        html => $html_filenames,
+        csv  => $csv_filenames,
+        ods  => $ods_filenames,
+    };
+    for my $email ( @emails ) {
+        send_files({
+            directory => $output_directory,
+            files => $files,
+            to => $email,
+            from => C4::Context->preference('KohaAdminEmailAddress'), # Should be replaced if bug 8000 is pushed
+        });
+    }
+}
+
 sub print_notices {
     my ( $params ) = @_;
 
@@ -145,10 +164,10 @@ sub print_notices {
     }
 
     while ( my ( $branchcode, $branch_messages ) = each %$messages_by_branch ) {
-        my $letter_code = @letter_codes == 1 ? $letter_codes[0] : 'hold';
+        my $letter_codes = @letter_codes == 0 ? 'all' : join '_', @letter_codes;
         my $filename = $split
-            ? "notices_$letter_code-" . $today->output('iso') . "-$branchcode.$format"
-            : "notices_$letter_code-" . $today->output('iso') . ".$format";
+            ? "notices_$letter_codes-" . $today_iso . "-$branchcode.$format"
+            : "notices_$letter_codes-" . $today_iso . ".$format";
         my $filepath = File::Spec->catdir( $output_directory, $filename );
         if ( $format eq 'html' ) {
             generate_html({
@@ -161,7 +180,7 @@ sub print_notices {
                 filepath => $filepath,
             });
         } elsif ( $format eq 'ods' ) {
-            generate_ods ({
+            _generate_ods ({
                 messages => $branch_messages,
                 filepath => $filepath,
             });
@@ -189,11 +208,11 @@ sub generate_html {
 
     my $template =
       C4::Templates::gettemplate( 'batch/print-notices.tt', 'intranet',
-        new CGI );
+        CGI->new );
 
     $template->param(
         stylesheet => C4::Context->preference("NoticeCSS"),
-        today      => $today->output(),
+        today      => $today_syspref,
         messages   => $messages,
     );
 
@@ -210,7 +229,7 @@ sub generate_csv {
 
     open my $OUTPUT, '>encoding(utf-8)', $filepath
         or die "Could not open $filepath: $!";
-    my ( @csv_lines, $headers );
+    my $headers;
     foreach my $message ( @$messages ) {
         my @lines = split /\n/, $message->{content};
         chomp for @lines;
@@ -229,55 +248,78 @@ sub generate_csv {
     }
 }
 
-sub generate_ods {
+sub _generate_ods {
     my ( $params ) = @_;
     my $messages = $params->{messages};
-    my $filepath = $params->{filepath};
-
-    use OpenOffice::OODoc;
-    my $tmpdir = dirname $filepath;
-    odfWorkingDirectory( $tmpdir );
-    my $container = odfContainer( $filepath, create => 'spreadsheet' );
-    my $doc = odfDocument (
-        container => $container,
-        part      => 'content'
-    );
-    my $table = $doc->getTable(0);
+    my $ods_filepath = $params->{filepath};
 
-    my @headers;
-    my ( $nb_rows, $nb_cols, $i ) = ( scalar(@$messages), 0, 0 );
+    # Prepare sheet
+    my $ods_content;
+    my $has_headers;
     foreach my $message ( @$messages ) {
-        my @lines = split /\n/, $message->{content};
-        chomp for @lines;
-
-        # We don't have headers, get them
-        unless ( @headers ) {
-            @headers = split $delimiter, $lines[0];
-
-            $nb_cols = @headers;
-            $doc->expandTable( $table, $nb_rows + 1, $nb_cols );
-            my $row = $doc->getRow( $table, 0 );
-            my $j = 0;
-            for my $header ( @headers ) {
-                $doc->cellValue( $row, $j, Encode::encode( 'UTF8', $header ) );
-                $j++;
+        my @message_lines = split /\n/, $message->{content};
+        chomp for @message_lines;
+        # Get headers from first message
+        if ($has_headers) {
+            shift @message_lines;
+        } else {
+            $has_headers = 1;
+        }
+        foreach my $message_line ( @message_lines ) {
+            my @content_row;
+            my @message_cells = split $delimiter, $message_line;
+            foreach ( @message_cells ) {
+                push @content_row, Encode::encode( 'UTF8', $_ );
             }
-            $i = 1;
+            push @$ods_content, \@content_row;
         }
+    }
 
-        shift @lines; # remove headers
-        for my $line ( @lines ) {
-            my @row_data = split $delimiter, $line;
-            my $row = $doc->getRow( $table, $i );
-            # Note scalar(@$row_data) should be equal to $nb_cols
-            for ( my $j = 0 ; $j < scalar(@row_data) ; $j++ ) {
-                my $value = Encode::encode( 'UTF8', $row_data[$j] );
-                $doc->cellValue( $row, $j, $value );
-            }
-            $i++;
+    # Process
+    generate_ods($ods_filepath, $ods_content);
+}
+
+sub send_files {
+    my ( $params ) = @_;
+    my $directory = $params->{directory};
+    my $files = $params->{files};
+    my $to = $params->{to};
+    my $from = $params->{from};
+    return unless $to and $from;
+
+    my $mail = MIME::Lite->new(
+        From     => $from,
+        To       => $to,
+        Subject  => 'Print notices for ' . $today_syspref,
+        Type     => 'multipart/mixed',
+    );
+
+    while ( my ( $type, $filenames ) = each %$files ) {
+        for my $filename ( @$filenames ) {
+            my $mimetype = $type eq 'html'
+                ? 'text/html'
+                : $type eq 'csv'
+                    ? 'text/csv'
+                    : $type eq 'ods'
+                        ? 'application/vnd.oasis.opendocument.spreadsheet'
+                        : undef;
+
+            next unless $mimetype;
+
+            my $filepath = File::Spec->catdir( $directory, $filename );
+
+            next unless $filepath or -f $filepath;
+
+            $mail->attach(
+              Type     => $mimetype,
+              Path     => $filepath,
+              Filename => $filename,
+              Encoding => 'base64',
+            );
         }
     }
-    $doc->save();
+
+    $mail->send;
 }
 
 =head1 NAME
@@ -286,11 +328,11 @@ gather_print_notices - Print waiting print notices
 
 =head1 SYNOPSIS
 
-gather_print_notices output_directory [-s|--split] [--html] [--csv] [--ods] [--letter_code=LETTER_CODE] [-h|--help]
+gather_print_notices output_directory [-s|--split] [--html] [--csv] [--ods] [--letter_code=LETTER_CODE] [-e|--email=your_email@example.org] [-h|--help]
 
 Will print all waiting print notices to the output_directory.
 
-The generated filename will be holdnotices-TODAY.[csv|html|ods] or holdnotices-TODAY-BRANCHCODE.[csv|html|ods] if the --split parameter is given.
+The generated filename will be notices-TODAY.[csv|html|ods] or notices-TODAY-BRANCHCODE.[csv|html|ods] if the --split parameter is given.
 
 =head1 OPTIONS
 
@@ -304,15 +346,15 @@ Define the output directory where the files will be generated.
 
 After files have been generated, messages status is changed from 'pending' to
 'sent'. This is the default action, without this parameter or with --send.
-Using --nosend, mesages status aren't changed.
+Using --nosend, the message status is not changed.
 
 =item B<-s|--split>
 
-Split messages into separate file by borrower home library to OUTPUT_DIRECTORY/notices-CURRENT_DATE-BRANCHCODE.[csv|html|ods]
+Split messages into separate files by borrower home library to OUTPUT_DIRECTORY/notices-CURRENT_DATE-BRANCHCODE.[csv|html|ods]
 
 =item B<--html>
 
-Generate the print notices in a html file (default if --html, --csv and ods are not given).
+Generate the print notices in a html file (default is --html, if --csv and --ods are not given).
 
 =item B<--csv>
 
@@ -324,7 +366,7 @@ For example:
 cardnumber:patron:email:item
 <<borrowers.cardnumber>>:<<borrowers.firstname>> <<borrowers.surname>>:<<borrowers.email>>:<<items.barcode>>
 
-You have to combine this option without one (and only one) letter_code.
+You have to combine this option with one (and only one) letter_code.
 
 =item B<--ods>
 
@@ -337,6 +379,11 @@ This is the same as the csv parameter but using csv2odf to generate an ods file
 Filter print messages by letter_code.
 Several letter_code parameters can be given.
 
+=item B<-e|--email>
+
+Repeatable.
+E-mail address to send generated files to.
+
 =item B<-h|--help>
 
 Print a brief help message