Bug 11603: Gather print notices - add a csv parameter
authorJonathan Druart <jonathan.druart@biblibre.com>
Wed, 22 Jan 2014 12:56:10 +0000 (13:56 +0100)
committerTomas Cohen Arazi <tomascohen@gmail.com>
Mon, 1 Jun 2015 17:25:02 +0000 (14:25 -0300)
This patch adds:
- the ability to generate a csv file instead of a html file.
- a letter_code parameter.

From now you are able to generate a csv file for print notices.

Imagine a template notice defined as:
cardnumber:patron:email:item
<<borrowers.cardnumber>>:<<borrowers.firstname>> <borrowers.surname>>:<<borrowers.email>>:<<items.barcode>>

You would like to generate a csv file and not a html file.

Test plan:
- define your ODUE notice for the print template as:

cardnumber:patron:email:item
<<borrowers.cardnumber>>:<<borrowers.firstname>> <<borrowers.surname>>:<<borrowers.email>>:<item><<items.barcode>></item>

- define overdues rules for a patron category
- check 2 items out using a due date in order to generate the overdue
  notices
- check these 2 items in
- launch the overdue_notices script
- the message_queue table should now contain 2 new entries
- launch the gather_print_notices cronjob with the following parameters:
 perl misc/cronjobs/gather_print_notices.pl /tmp/test --csv
 --letter_code=OVERDUE --letter_code=CHECKIN
you should get an error

 perl misc/cronjobs/gather_print_notices.pl /tmp/test --csv
you should get an error

 perl misc/cronjobs/gather_print_notices.pl /tmp/test --csv
 --letter_code=OVERDUE -d=:
 will produce 1 csv file in your /tmp/test directory
- verify the csv file is correct and contain only 1 csv header column.

Signed-off-by: Frederic Demians <f.demians@tamil.fr>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
QA note: Keep in mind that you can use all placeholders for the
csv that you can use for the normal templates. If you normally
get the item information from <item></item> you need to use that.
If you can use <<item.barcode>> directly, you can also do so
in the csv.
Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>
misc/cronjobs/gather_print_notices.pl

index 66ef214..ad2aed2 100755 (executable)
@@ -23,11 +23,14 @@ use C4::Log;
 
 use Koha::DateUtils;
 
-my ( $stylesheet, $help, $split );
+my ( $stylesheet, $help, $split, $html, $csv, @letter_codes );
 
 GetOptions(
     'h|help'  => \$help,
     's|split' => \$split,
+    'html'    => \$html,
+    'csv'     => \$csv,
+    'letter_code:s' => \@letter_codes,
 ) || pod2usage(1);
 
 pod2usage(0) if $help;
@@ -41,11 +44,29 @@ if ( !$output_directory || !-d $output_directory || !-w $output_directory ) {
     });
 }
 
+# Default value is html
+$html = 1 unless $html or $csv;
+
+if ( $csv and @letter_codes != 1 ) {
+    pod2usage({
+        -exitval => 1,
+        -msg => qq{\nIt is not consistent to use --csv without one (and only one) letter_code\n},
+    });
+}
+
 cronlogaction();
 
 my $today        = C4::Dates->new();
 my @all_messages = @{ GetPrintMessages() };
-exit unless (@all_messages);
+
+# Filter by letter_code
+@all_messages = map {
+    my $letter_code = $_->{letter_code};
+    (
+        grep { /^$letter_code$/ } @letter_codes
+    ) ? $_ : ()
+} @all_messages;
+exit unless @all_messages;
 
 ## carriage return replaced by <br/> as output is html
 foreach my $message (@all_messages) {
@@ -55,9 +76,11 @@ foreach my $message (@all_messages) {
     $message->{'content'} = $_;
 }
 
-my $OUTPUT;
+print_notices_html({ messages => \@all_messages, split => $split })
+    if $html;
 
-print_notices_html({ messages => \@all_messages, split => $split });
+print_notices_csv({ messages => \@all_messages, split => $split })
+    if $csv;
 
 sub print_notices_html {
     my ( $params ) = @_;
@@ -102,7 +125,58 @@ sub print_notices_html {
                     status => 'sent'
                 }
             );
+            $message->{status} = 'sent';
+        }
+    }
+}
+
+sub print_notices_csv {
+    my ( $params ) = @_;
+
+    my $messages = $params->{messages};
+    my $split = $params->{split};
+
+    my $messages_by_branch;
+    if ( $split ) {
+        foreach my $message (@$messages) {
+            push( @{ $messages_by_branch->{ $message->{'branchcode'} } }, $message );
+        }
+    } else {
+        $messages_by_branch->{all_branches} = $messages;
+    }
+
+    while ( my ( $branchcode, $branch_messages ) = each %$messages_by_branch ) {
+        my $filename = $split
+            ? 'holdnotices-' . $today->output('iso') . "-$branchcode.csv"
+            : 'holdnotices-' . $today->output('iso') . ".csv";
+
+        open my $OUTPUT, '>', File::Spec->catdir( $output_directory, $filename );
+        my ( @csv_lines, $headers );
+        foreach my $message ( @$branch_messages ) {
+            my @lines = split /\n/, $message->{content};
+
+            # We don't have headers, get them
+            unless ( $headers ) {
+                $headers = $lines[0];
+                chomp $headers;
+                say $OUTPUT $headers;
+            }
+
+            shift @lines;
+            for my $line ( @lines ) {
+                chomp $line;
+                next if $line =~ /^\s$/;
+                say $OUTPUT $line;
+            }
+
+            C4::Letters::_set_message_status(
+                {
+                    message_id => $message->{'message_id'},
+                    status => 'sent'
+                }
+            ) if $message->{status} ne 'sent';
         }
+        close $OUTPUT;
     }
 }
 
@@ -112,11 +186,11 @@ gather_print_notices - Print waiting print notices
 
 =head1 SYNOPSIS
 
-gather_print_notices output_directory [-s|--split] [-h|--help]
+gather_print_notices output_directory [-s|--split] [--html] [--csv] [--letter_code=LETTER_CODE] [-h|--help]
 
 Will print all waiting print notices to the output_directory.
 
-The generated filename will be holdnotices-TODAY.html or holdnotices-TODAY-BRANCHCODE.html if the --split parameter is given.
+The generated filename will be holdnotices-TODAY.[csv|html] or holdnotices-TODAY-BRANCHCODE.[csv|html] if the --split parameter is given.
 
 =head1 OPTIONS
 
@@ -128,7 +202,28 @@ Define the output directory where the files will be generated.
 
 =item B<-s|--split>
 
-Split messages into separate file by borrower home library to OUTPUT_DIRECTORY/notices-CURRENT_DATE-BRANCHCODE.html
+Split messages into separate file by borrower home library to OUTPUT_DIRECTORY/notices-CURRENT_DATE-BRANCHCODE.[csv|html]
+
+=item B<--html>
+
+Generate the print notices in a html file (default if --html and --csv are not given).
+
+=item B<--csv>
+
+Generate the print notices in a csv file.
+If you use this parameter, the template should contain 2 lines.
+The first one the the csv headers and the second one the value list.
+
+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.
+
+=item B<--letter_code>
+
+Filter print messages by letter_code.
+Several letter_code parameters can be given.
 
 =item B<-h|--help>