3 # Copyright 2008 Liblime
4 # Copyright 2014 Foundations Bible College, Inc.
6 # This file is part of Koha.
8 # Koha is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # Koha is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with Koha; if not, see <http://www.gnu.org/licenses>.
23 use Koha
::Script
-cron
;
24 use C4
::Reports
::Guided
; # 0.12
31 use Getopt
::Long
qw(:config auto_help auto_version);
34 use Text
::CSV
::Encoded
;
38 use JSON
qw( to_json );
41 # find Koha's Perl modules
42 # test carefully before changing this
44 eval { require "$FindBin::Bin/../kohalib.pl" };
49 runreport.pl - Run pre-existing saved reports
53 runreport.pl [ -h | -m ] [ -v ] reportID [ reportID ... ]
56 -h --help brief help message
57 -m --man full documentation, same as --help --verbose
58 -v --verbose verbose output
60 --format=s selects format. Choice of text, html, csv or tsv
62 -e --email whether to use e-mail (implied by --to or --from)
63 -a --attachment additionally attach the report as a file. cannot be used with html format
64 --username username to pass to the SMTP server for authentication
65 --password password to pass to the SMTP server for authentication
66 --method method is the type of authentication. Ie. LOGIN, DIGEST-MD5, etc.
67 --to=s e-mail address to send report to
68 --from=s e-mail address to send report from
69 --subject=s subject for the e-mail
70 --params=s parameters for the report
71 --store-results store the result of the report
72 --csv-header add column names as first line of csv output
76 reportID report ID Number from saved_sql.id, multiple ID's may be specified
84 Print a brief help message and exits.
88 Prints the manual page and exits.
92 Verbose. Without this flag set, only fatal errors are reported.
96 Current options are text, html, csv, and tsv. At the moment, text and tsv both produce tab-separated tab-separated output.
100 Whether to use e-mail (implied by --to or --from).
104 Username to pass to the SMTP server for authentication
108 Password to pass to the SMTP server for authentication
112 Method is the type of authentication. Ie. LOGIN, DIGEST-MD5, etc.
116 E-mail address to send report to. Defaults to KohaAdminEmailAddress.
120 E-mail address to send report from. Defaults to KohaAdminEmailAddress.
124 Subject for the e-mail message. Defaults to "Koha Saved Report"
128 Repeatable, should provide one param per param requested for the report
130 =item B<--store-results>
132 Store the result of the report into the saved_reports DB table.
134 To access the results, go on Reports > Guided reports > Saved report.
140 This script is designed to run existing Saved Reports.
142 =head1 USAGE EXAMPLES
146 In the most basic form, runs the report specified by ID number from
147 saved_sql.id, in this case #16, outputting the results to STDOUT.
149 B<runreport.pl 16 17>
151 Same as above, but also runs report #17.
160 Allow Saved Results option.
167 Reports - Guided Reports
171 # These variables can be set by command line options,
172 # initially set to default values.
186 my $store_results = 0;
189 my $username = undef;
190 my $password = undef;
191 my $method = 'LOGIN';
196 'verbose' => \
$verbose,
197 'format=s' => \
$format,
200 'subject=s' => \
$subject,
201 'param=s' => \
@params,
203 'a|attachment' => \
$attachment,
204 'username:s' => \
$username,
205 'password:s' => \
$password,
206 'method:s' => \
$method,
207 'store-results' => \
$store_results,
208 'csv-header' => \
$csv_header,
211 pod2usage
( -verbose
=> 2 ) if ($man);
212 pod2usage
( -verbose
=> 2 ) if ($help and $verbose);
213 pod2usage
(1) if $help;
218 $verbose and print STDERR
"No format specified, assuming 'text'\n";
222 if ($format eq 'tsv' || $format eq 'text') {
227 if ($to or $from or $email) {
229 $from or $from = C4
::Context
->preference('KohaAdminEmailAddress');
230 $to or $to = C4
::Context
->preference('KohaAdminEmailAddress');
233 unless (scalar(@ARGV)) {
234 print STDERR
"ERROR: No reportID(s) specified\n";
237 ($verbose) and print scalar(@ARGV), " argument(s) after options: " . join(" ", @ARGV) . "\n";
239 my $today = dt_from_string
();
240 my $date = $today->ymd();
242 foreach my $report_id (@ARGV) {
243 my $report = Koha
::Reports
->find( $report_id );
245 warn "ERROR: No saved report $report_id found";
248 my $sql = $report->savedsql;
249 my $report_name = $report->report_name;
250 my $type = $report->type;
252 $verbose and print "SQL: $sql\n\n";
253 if ( $subject eq "" )
255 if ( defined($report_name) and $report_name ne "")
257 $subject = $report_name ;
261 $subject = 'Koha Saved Report';
265 # convert SQL parameters to placeholders
266 $sql =~ s/(<<.*?>>)/\?/g;
268 my ($sth) = execute_query
( $sql, undef, undef, \
@params, $report_id );
269 my $count = scalar($sth->rows);
271 print "NO OUTPUT: 0 results from execute_query\n";
274 $verbose and print "$count results from execute_query\n";
278 if ($format eq 'html') {
279 my $cgi = CGI
->new();
281 while (my $line = $sth->fetchrow_arrayref) {
282 foreach (@
$line) { defined($_) or $_ = ''; } # catch undef values, replace w/ ''
283 push @rows, $cgi->TR( join('', $cgi->td($line)) ) . "\n";
284 push @rows_to_store, [@
$line] if $store_results;
286 $message = $cgi->table(join "", @rows);
287 } elsif ($format eq 'csv') {
288 my $csv = Text
::CSV
::Encoded
->new({
289 encoding_out
=> 'utf8',
291 quote_char
=> $quote,
292 sep_char
=> $separator,
296 my @fields = map { decode
( 'utf8', $_ ) } @
{ $sth->{NAME
} };
297 $csv->combine( @fields );
298 $message .= $csv->string() . "\n";
299 push @rows_to_store, [@fields] if $store_results;
302 while (my $line = $sth->fetchrow_arrayref) {
303 $csv->combine(@
$line);
304 $message .= $csv->string() . "\n";
305 push @rows_to_store, [@
$line] if $store_results;
308 if ( $store_results ) {
309 my $json = to_json
( \
@rows_to_store );
310 C4
::Reports
::Guided
::store_results
( $report_id, $json );
313 my $args = { to
=> $to, from
=> $from, subject
=> $subject };
314 if ( $format eq 'html' ) {
315 $message = "<html><head><style>tr:nth-child(2n+1) { background-color: #ccc;}</style></head><body>$message</body></html>";
316 $args->{contenttype
} = 'text/html';
318 my $email = Koha
::Email
->new();
319 my %mail = $email->create_message_headers($args);
320 $mail{Data
} = $message;
321 $mail{Auth
} = { user
=> $username, pass
=> $password, method
=> $method } if $username;
323 my $msg = MIME
::Lite
->new(%mail);
326 Type
=> "text/$format",
327 Data
=> encode
( 'utf8', $message ),
328 Filename
=> "report$report_id-$date.$format",
329 Disposition
=> 'attachment',
333 carp
"Mail not sent" unless $msg->last_send_successful();