Bug 18731: (QA follow-up) Spelling and POD corrections
[koha.git] / misc / cronjobs / runreport.pl
blob6732afae9c6e9cb69726bec87c4cf75ec8907289
1 #!/usr/bin/perl
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>.
21 use Modern::Perl;
23 use Koha::Script -cron;
24 use C4::Reports::Guided; # 0.12
25 use Koha::Reports;
26 use C4::Context;
27 use C4::Log;
28 use Koha::Email;
29 use Koha::DateUtils;
31 use Getopt::Long qw(:config auto_help auto_version);
32 use Pod::Usage;
33 use MIME::Lite;
34 use Text::CSV::Encoded;
35 use CGI qw ( -utf8 );
36 use Carp;
37 use Encode;
38 use JSON qw( to_json );
40 BEGIN {
41 # find Koha's Perl modules
42 # test carefully before changing this
43 use FindBin;
44 eval { require "$FindBin::Bin/../kohalib.pl" };
47 =head1 NAME
49 runreport.pl - Run pre-existing saved reports
51 =head1 SYNOPSIS
53 runreport.pl [ -h | -m ] [ -v ] reportID [ reportID ... ]
55 Options:
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 --param=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
75 Arguments:
76 reportID report ID Number from saved_sql.id, multiple ID's may be specified
78 =head1 OPTIONS
80 =over
82 =item B<--help>
84 Print a brief help message and exits.
86 =item B<--man>
88 Prints the manual page and exits.
90 =item B<-v>
92 Verbose. Without this flag set, only fatal errors are reported.
94 =item B<--format>
96 Current options are text, html, csv, and tsv. At the moment, text and tsv both produce tab-separated tab-separated output.
98 =item B<--email>
100 Whether to use e-mail (implied by --to or --from).
102 =item B<--username>
104 Username to pass to the SMTP server for authentication
106 =item B<--password>
108 Password to pass to the SMTP server for authentication
110 =item B<--method>
112 Method is the type of authentication. Ie. LOGIN, DIGEST-MD5, etc.
114 =item B<--to>
116 E-mail address to send report to. Defaults to KohaAdminEmailAddress.
118 =item B<--from>
120 E-mail address to send report from. Defaults to KohaAdminEmailAddress.
122 =item B<--subject>
124 Subject for the e-mail message. Defaults to "Koha Saved Report"
126 =item B<--param>
128 Repeatable, should provide one param per param requested for the report.
129 Report params are not combined as on the staff side, so you may need to repeat
130 params.
132 =item B<--store-results>
134 Store the result of the report into the saved_reports DB table.
136 To access the results, go on Reports > Guided reports > Saved report.
138 =back
140 =head1 DESCRIPTION
142 This script is designed to run existing Saved Reports.
144 =head1 USAGE EXAMPLES
146 B<runreport.pl 16>
148 In the most basic form, runs the report specified by ID number from
149 saved_sql.id, in this case #16, outputting the results to STDOUT.
151 B<runreport.pl 16 17>
153 Same as above, but also runs report #17.
155 =head1 TO DO
157 =over
160 =item *
162 Allow Saved Results option.
165 =back
167 =head1 SEE ALSO
169 Reports - Guided Reports
171 =cut
173 # These variables can be set by command line options,
174 # initially set to default values.
176 my $help = 0;
177 my $man = 0;
178 my $verbose = 0;
179 my $email = 0;
180 my $attachment = 0;
181 my $format = "text";
182 my $to = "";
183 my $from = "";
184 my $subject = "";
185 my @params = ();
186 my $separator = ',';
187 my $quote = '"';
188 my $store_results = 0;
189 my $csv_header = 0;
191 my $username = undef;
192 my $password = undef;
193 my $method = 'LOGIN';
195 GetOptions(
196 'help|?' => \$help,
197 'man' => \$man,
198 'verbose' => \$verbose,
199 'format=s' => \$format,
200 'to=s' => \$to,
201 'from=s' => \$from,
202 'subject=s' => \$subject,
203 'param=s' => \@params,
204 'email' => \$email,
205 'a|attachment' => \$attachment,
206 'username:s' => \$username,
207 'password:s' => \$password,
208 'method:s' => \$method,
209 'store-results' => \$store_results,
210 'csv-header' => \$csv_header,
212 ) or pod2usage(2);
213 pod2usage( -verbose => 2 ) if ($man);
214 pod2usage( -verbose => 2 ) if ($help and $verbose);
215 pod2usage(1) if $help;
217 cronlogaction();
219 unless ($format) {
220 $verbose and print STDERR "No format specified, assuming 'text'\n";
221 $format = 'text';
224 if ($format eq 'tsv' || $format eq 'text') {
225 $format = 'csv';
226 $separator = "\t";
229 if ($to or $from or $email) {
230 $email = 1;
231 $from or $from = C4::Context->preference('KohaAdminEmailAddress');
232 $to or $to = C4::Context->preference('KohaAdminEmailAddress');
235 unless (scalar(@ARGV)) {
236 print STDERR "ERROR: No reportID(s) specified\n";
237 pod2usage(1);
239 ($verbose) and print scalar(@ARGV), " argument(s) after options: " . join(" ", @ARGV) . "\n";
241 my $today = dt_from_string();
242 my $date = $today->ymd();
244 foreach my $report_id (@ARGV) {
245 my $report = Koha::Reports->find( $report_id );
246 unless ($report) {
247 warn "ERROR: No saved report $report_id found";
248 next;
250 my $sql = $report->savedsql;
251 my $report_name = $report->report_name;
252 my $type = $report->type;
254 $verbose and print "SQL: $sql\n\n";
255 if ( $subject eq "" )
257 if ( defined($report_name) and $report_name ne "")
259 $subject = $report_name ;
261 else
263 $subject = 'Koha Saved Report';
267 # convert SQL parameters to placeholders
268 my $params_needed = ( $sql =~ s/(<<[^>]+>>)/\?/g );
269 die("You supplied ". scalar @params . " parameter(s) and $params_needed are required by the report") if scalar @params != $params_needed;
271 my ($sth) = execute_query( $sql, undef, undef, \@params, $report_id );
272 my $count = scalar($sth->rows);
273 unless ($count) {
274 print "NO OUTPUT: 0 results from execute_query\n";
275 next;
277 $verbose and print "$count results from execute_query\n";
279 my $message;
280 my @rows_to_store;
281 if ($format eq 'html') {
282 my $cgi = CGI->new();
283 my @rows;
284 while (my $line = $sth->fetchrow_arrayref) {
285 foreach (@$line) { defined($_) or $_ = ''; } # catch undef values, replace w/ ''
286 push @rows, $cgi->TR( join('', $cgi->td($line)) ) . "\n";
287 push @rows_to_store, [@$line] if $store_results;
289 $message = $cgi->table(join "", @rows);
290 } elsif ($format eq 'csv') {
291 my $csv = Text::CSV::Encoded->new({
292 encoding_out => 'utf8',
293 binary => 1,
294 quote_char => $quote,
295 sep_char => $separator,
298 if ( $csv_header ) {
299 my @fields = map { decode( 'utf8', $_ ) } @{ $sth->{NAME} };
300 $csv->combine( @fields );
301 $message .= $csv->string() . "\n";
302 push @rows_to_store, [@fields] if $store_results;
305 while (my $line = $sth->fetchrow_arrayref) {
306 $csv->combine(@$line);
307 $message .= $csv->string() . "\n";
308 push @rows_to_store, [@$line] if $store_results;
311 if ( $store_results ) {
312 my $json = to_json( \@rows_to_store );
313 C4::Reports::Guided::store_results( $report_id, $json );
315 if ($email) {
316 my $args = { to => $to, from => $from, subject => $subject };
317 if ( $format eq 'html' ) {
318 $message = "<html><head><style>tr:nth-child(2n+1) { background-color: #ccc;}</style></head><body>$message</body></html>";
319 $args->{contenttype} = 'text/html';
321 my $email = Koha::Email->new();
322 my %mail = $email->create_message_headers($args);
323 $mail{Data} = $message;
324 $mail{Auth} = { user => $username, pass => $password, method => $method } if $username;
326 my $msg = MIME::Lite->new(%mail);
328 $msg->attach(
329 Type => "text/$format",
330 Data => encode( 'utf8', $message ),
331 Filename => "report$report_id-$date.$format",
332 Disposition => 'attachment',
333 ) if $attachment;
335 $msg->send();
336 carp "Mail not sent" unless $msg->last_send_successful();
338 else {
339 print $message;