[Koha-patches] [PATCH] Custom Reports

Kyle Hall kyle.m.hall at gmail.com
Tue Jan 26 15:00:20 CET 2010


Also, the report_dir should be named in a fashion to guarantee uniquness.
I have used a java style naming system, so each report is named
org.ccfls.REPORT_NAME. If Biblibre created custom reports, they
would be named com.biblibre.REPORT_NAME and so on.

I should note this patch does not represent the finished product, it
is still a work in progress.

I'm hoping to get suggestions to further improve on it.

Kyle

http://www.kylehall.info
Information Technology
Crawford County Federated Library System ( http://www.ccfls.org )




On Tue, Jan 26, 2010 at 8:42 AM, Kyle Hall <kyle.m.hall at gmail.com> wrote:
> Hello All,
>  I've written a new "Custom Reports" addition for Koha to allow Koha
> users to trade more complicated reports that cannot be represented in
> pure SQL. Here's how it works:
>
> Each report is downloaded as a .krz file. This filetype is just a zip
> file with a specific structure ( sort of like .deb is ).
>
> The structure is like so:
> report_dir /
>   report.ini
>   ( other report files )
>
> Pretty simple, I should say.
>
> The report.ini file looks something like this:
> name=Access PA
> author=Kyle M Hall
> description=A Report of the data necessary to fill out the Access PA
> report form.
> start=access_pa/step1.pl
>
> When a report.krz file is uploaded into Koha, it is extracted to
> KOHA_ROOT/reports/custom_reports/
>
> The custom_reports.pl script reads all the report.ini files it fines
> and generates the list of available reports dynamically.
>
> Please let me know what you think. I'm in the process of rewriting all
> my php-based reports in perl using this system. I've sent patches for
> the three I've done so far. The Access PA report is the only one too
> complicated to represent in pure SQL, but I like being able to have
> one query and to be able to select the library.
>
> I would suggest making all report forms use GET methods. That way, the
> reports can be cronned using a simple wget command.
>
> Please let me know what you think.
>
> Thanks,
> Kyle
>
> http://www.kylehall.info
> Information Technology
> Crawford County Federated Library System ( http://www.ccfls.org )
>
>
>
>
> On Tue, Jan 26, 2010 at 8:32 AM, Kyle M Hall <kyle.m.hall at gmail.com> wrote:
>> ---
>>  C4/Reports/Custom.pm                               |  138 ++++++++++++++++++++
>>  .../prog/en/modules/reports/custom_reports.tmpl    |   58 ++++++++
>>  .../en/modules/reports/custom_reports_upload.tmpl  |   66 ++++++++++
>>  .../prog/en/modules/reports/reports-home.tmpl      |    5 +
>>  reports/custom_reports.pl                          |   52 ++++++++
>>  reports/custom_reports_upload.pl                   |   89 +++++++++++++
>>  6 files changed, 408 insertions(+), 0 deletions(-)
>>  create mode 100644 C4/Reports/Custom.pm
>>  create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/reports/custom_reports.tmpl
>>  create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/reports/custom_reports_upload.tmpl
>>  create mode 100755 reports/custom_reports.pl
>>  create mode 100644 reports/custom_reports/empty
>>  create mode 100755 reports/custom_reports_upload.pl
>>
>> diff --git a/C4/Reports/Custom.pm b/C4/Reports/Custom.pm
>> new file mode 100644
>> index 0000000..add811c
>> --- /dev/null
>> +++ b/C4/Reports/Custom.pm
>> @@ -0,0 +1,138 @@
>> +package C4::Reports::Custom;
>> +
>> +# Copyright 2010 Kyle Hall
>> +#
>> +# This file is part of Koha.
>> +#
>> +# Koha is free software; you can redistribute it and/or modify it under the
>> +# terms of the GNU General Public License as published by the Free Software
>> +# Foundation; either version 2 of the License, or (at your option) any later
>> +# version.
>> +#
>> +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
>> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
>> +# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License along with
>> +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
>> +# Suite 330, Boston, MA  02111-1307 USA
>> +
>> +use strict;
>> +use warnings;
>> +
>> +use CGI;
>> +use Config::Simple;
>> +
>> +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
>> +
>> +use C4::Context;
>> +use C4::Output;
>> +use C4::Dates;
>> +use C4::Debug;
>> +
>> +BEGIN {
>> +       # set the version for version checking
>> +       $VERSION = 0.01;
>> +       require Exporter;
>> +       @ISA = qw(Exporter);
>> +       @EXPORT = qw(
>> +               GetReports
>> +       );
>> +}
>> +
>> +=head1 NAME
>> +
>> +C4::Reports::Custom - Module for loading and managing custom reports.
>> +
>> +=head1 SYNOPSIS
>> +
>> +  use C4::Reports::Custom;
>> +
>> +=over 2
>> +
>> +=cut
>> +
>> +=item GetReports()
>> +
>> +This will return a list of all the available reports
>> +
>> +Usage: my ( $reports_hasref, $reports_count ) = C4::Reports::Custom::GetReports();
>> +
>> +=cut
>> +
>> +sub GetReports {
>> +       my @reports_ini = _GetReportsIniFiles();
>> +
>> +       my @reports;
>> +       foreach my $report_ini ( @reports_ini ) {
>> +               my $ini_hashref = _ParseReportIni( $report_ini );
>> +               push( @reports, $ini_hashref );
>> +       }
>> +
>> +       my $count = @reports;
>> +
>> +       return ( \@reports, $count );
>> +}
>> +
>> +=item _GetReportsIniFiles()
>> +
>> +This will return an array of all the ini files for the custom reports.
>> +
>> +=cut
>> +
>> +sub _GetReportsIniFiles {
>> +       my $reports_dir = '/home/koha/kohaclone/reports/custom_reports/';
>> +       opendir(DIRHANDLE, $reports_dir);
>> +       my @reports_dirs = readdir(DIRHANDLE);
>> +       closedir(DIRHANDLE);
>> +
>> +       my @reports;
>> +       foreach my $report_dir ( @reports_dirs ) {
>> +
>> +               my $report_path = $reports_dir . $report_dir;
>> +
>> +               if ( -d $report_path ) {
>> +                       my $ini_path = $report_path . '/report.ini';
>> +
>> +                       if ( -f $ini_path ) {
>> +                               push( @reports, $ini_path );
>> +                       }
>> +
>> +               }
>> +
>> +       }
>> +
>> +       return ( @reports );
>> +}
>> +
>> +=item _ParseReportIni( $ini_path )
>> +
>> +This will return a hasref of key/value pairs found in the ini file
>> +
>> +=cut
>> +
>> +sub _ParseReportIni {
>> +       my ( $ini_path ) = @_;
>> +
>> +       my $ini;
>> +
>> +       open( INIFILE, '<', $ini_path ) or die("Could not open file $ini_path");
>> +       foreach my $line ( <INIFILE> ) {
>> +               my ( $key, $value );
>> +               ( $key, $value ) = split(/=/, $line );
>> +               $ini->{$key} = $value;
>> +       }
>> +
>> +       return $ini;
>> +}
>> +
>> +1;
>> +__END__
>> +
>> +=back
>> +
>> +=head1 AUTHOR
>> +
>> +Kyle M Hall <kyle.m.hall at gmail.com>
>> +
>> +=cut
>> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/custom_reports.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/custom_reports.tmpl
>> new file mode 100644
>> index 0000000..a5db511
>> --- /dev/null
>> +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/custom_reports.tmpl
>> @@ -0,0 +1,58 @@
>> +<!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
>> +<title>Koha &rsaquo; Reports &rsaquo; Custom Reports </title>
>> +<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
>> +<!-- TMPL_INCLUDE NAME="calendar.inc" -->
>> +</head>
>> +
>> +<body>
>> +<!-- TMPL_INCLUDE NAME="header.inc" -->
>> +<!-- TMPL_INCLUDE NAME="circ-search.inc" -->
>> +
>> +<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a>
>> +&rsaquo; <a href="/cgi-bin/koha/reports/reports-home.pl">Reports</a>
>> +&rsaquo; <a href="/cgi-bin/koha/reports/custom_reports.pl">Custom Reports</a>
>> +</div>
>> +
>> +<div id="doc3" class="yui-t1">
>> +       <div id="bd">
>> +               <div id="yui-main">
>> +                       <div class="yui-b">
>> +                               <div class="details">
>> +                                       <h1>Custom Reports</h1>
>> +
>> +                                       <!-- TMPL_IF NAME="ERROR_NO_REPORTS" -->
>> +                                               <h2>No Custom Reports Exist.</h2>
>> +                                               <p>Please upload one or more Koha Custom Reports files (.krz) before using.</p>
>> +                                       <!-- TMPL_ELSE -->
>> +                                               <table>
>> +                                                       <tr>
>> +                                                               <th>Name</th>
>> +                                                               <th>Description</th>
>> +                                                               <th>Run</th>
>> +                                                       </tr>
>> +
>> +                                                       <!-- TMPL_LOOP NAME="REPORTS_LOOP" -->
>> +                                                               <tr>
>> +                                                                       <td><!-- TMPL_VAR NAME="name" --></td>
>> +                                                                       <td><!-- TMPL_VAR NAME="description" --></td>
>> +                                                                       <td><a href="custom_reports/<!-- TMPL_VAR NAME="start" -->">Run Report</a></td>
>> +                                                               </tr>
>> +                                                       <!-- /TMPL_LOOP -->
>> +                                               </table>
>> +                                       <!-- /TMPL_IF -->
>> +                               </div>
>> +                       </div>
>> +               </div>
>> +
>> +               <div class="yui-b noprint">
>> +                       <div id="navmenu">
>> +                               <ul id="navmenulist">
>> +                                       <li><a href="custom_reports_upload.pl">Upload A Custom Report</a></li>
>> +                               </ul>
>> +                       </div>
>> +               </div>
>> +       </div>
>> +</div>
>> +
>> +
>> +<!-- TMPL_INCLUDE NAME="intranet-bottom.inc" -->
>> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/custom_reports_upload.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/custom_reports_upload.tmpl
>> new file mode 100644
>> index 0000000..30ff908
>> --- /dev/null
>> +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/custom_reports_upload.tmpl
>> @@ -0,0 +1,66 @@
>> +<!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
>> +<title>Koha &rsaquo; Reports &rsaquo; Custom Reports &rsaquo; Upload Custom Report
>> + </title>
>> +<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
>> +<!-- TMPL_INCLUDE NAME="calendar.inc" -->
>> +</head>
>> +
>> +<body>
>> +<!-- TMPL_INCLUDE NAME="header.inc" -->
>> +<!-- TMPL_INCLUDE NAME="circ-search.inc" -->
>> +
>> +<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a>
>> +&rsaquo; <a href="/cgi-bin/koha/reports/reports-home.pl">Reports</a>
>> +&rsaquo; <a href="/cgi-bin/koha/reports/custom_reports.pl">Custom Reports</a>
>> +&rsaquo; Upload Custom Report
>> +</div>
>> +
>> +<div id="doc3" class="yui-t2">
>> +    <div id="bd">
>> +        <div id="yui-main">
>> +    <div class="yui-b">
>> +        <div class="yui-g">
>> +            <div class="yui-u first">
>> +                <h1>Upload Custom Report</h1>
>> +                <!-- TMPL_IF name="ERRORS" -->
>> +                <div class="dialog alert">
>> +                    <!-- TMPL_LOOP name="ERRORS" -->
>> +                        <!-- TMPL_IF name="NOTKRZ" --><li><b>The upload file does not appear to be a krz file.  The extention is not '.krz'.</b></li>
>> +                        <!-- TMPL_ELSIF name="NOWRITETEMP" --><li><b>This script is not able to create/write to the necessary temporary directory.</b></li>
>> +                        <!-- TMPL_ELSIF name="EMPTYUPLOAD" --><li><b>The upload file appears to be empty.</b></li>
>> +                        <!-- TMPL_ELSIF name="UZIPFAIL" --><li><b><!-- TMPL_VAR name="UZIPFAIL" --> failed to unpack.<br />Please verify the integrity of the zip file and retry.</b></li>
>> +                        <!-- TMPL_ELSIF name="NOWRITEREPORTS" --><li><b>Cannot unpack file to the custom reports directory.<br />Please verify that the Apache user can write to the custom reports directory.</b></li>
>> +                        <!-- TMPL_ELSE --><li><b><!-- TMPL_VAR name ="CORERR" --> An unknown error has occurred.<br />Please review the error log for more details.</b></li><!-- /TMPL_IF -->
>> +                    <!-- /TMPL_LOOP -->
>> +                </div>
>> +                <!-- /TMPL_IF -->
>> +               <form method="post" action="/cgi-bin/koha/reports/custom_reports_upload.pl" enctype="multipart/form-data">
>> +                   <fieldset class="brief">
>> +                        <div class="hint"><b>NOTE:</b> Only KRZ file format is supported.</div>
>> +                       <ol>
>> +                            <li>
>> +                                <label for="uploadfile">Select the file to upload: </label><input type="file" id="uploadfile" name="uploadfile" />
>> +                            </li>
>> +                       </ol>
>> +                                       </li></ol>
>> +                   </fieldset>
>> +                    <fieldset class="action">
>> +                        <input type="hidden" name="op" value="Upload" />
>> +                        <input type="submit" value="Upload" class="submit" />
>> +                    </fieldset>
>> +                </form>
>> +
>> +            </div>
>> +        </div>
>> +    </div>
>> +</div>
>> +<div class="yui-b noprint">
>> +<div id="navmenu">
>> +       <ul id="navmenulist">
>> +               <li><a href="/cgi-bin/koha/reports/custom_reports.pl">Custom Reports Home</a></li>
>> +       </ul>
>> +</div>
>> +
>> +</div>
>> +</div>
>> +<!-- TMPL_INCLUDE NAME="intranet-bottom.inc" -->
>> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl
>> index b2d8487..d97c8ef 100644
>> --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl
>> +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tmpl
>> @@ -27,6 +27,11 @@
>>                <li><a href="/cgi-bin/koha/reports/dictionary.pl?phase=View%20Dictionary">View Dictionary</a></li>
>>        </ul>
>>
>> +       <h2>Custom Reports</h2>
>> +       <ul>
>> +               <li><a href="/cgi-bin/koha/reports/custom_reports.pl">Custom Reports</a></li>
>> +       </ul>
>> +
>>        <h2>Statistics wizards</h2>
>>        <ul>
>>                <li><a href="/cgi-bin/koha/reports/acquisitions_stats.pl">Acquisitions</a></li>
>> diff --git a/reports/custom_reports.pl b/reports/custom_reports.pl
>> new file mode 100755
>> index 0000000..29e23a9
>> --- /dev/null
>> +++ b/reports/custom_reports.pl
>> @@ -0,0 +1,52 @@
>> +#!/usr/bin/perl
>> +
>> +# Copyright 2010 Kyle M Hall <kyle.m.hall at gmail.com>
>> +#
>> +# This file is part of Koha.
>> +#
>> +# Koha is free software; you can redistribute it and/or modify it under the
>> +# terms of the GNU General Public License as published by the Free Software
>> +# Foundation; either version 2 of the License, or (at your option) any later
>> +# version.
>> +#
>> +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
>> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
>> +# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License along with
>> +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
>> +# Suite 330, Boston, MA  02111-1307 USA
>> +
>> +use strict;
>> +use warnings;
>> +
>> +use CGI;
>> +
>> +use C4::Reports::Custom;
>> +use C4::Auth;
>> +use C4::Output;
>> +use C4::Dates;
>> +use C4::Debug;
>> +
>> +my $input = new CGI;
>> +
>> +my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
>> +    {
>> +        template_name   => "reports/custom_reports.tmpl",
>> +        query           => $input,
>> +        type            => "intranet",
>> +        authnotrequired => 0,
>> +        flagsrequired   => { reports => "execute_reports" },
>> +        debug           => 1,
>> +    }
>> +);
>> +
>> +my ( $reports_loop, $reports_count ) = GetReports();
>> +
>> +$template->param( REPORTS_LOOP => $reports_loop );
>> +
>> +unless ( $reports_count ) {
>> +  $template->param( ERROR_NO_REPORTS => 1 );
>> +}
>> +
>> +output_html_with_http_headers $input, $cookie, $template->output;
>> diff --git a/reports/custom_reports/empty b/reports/custom_reports/empty
>> new file mode 100644
>> index 0000000..e69de29
>> diff --git a/reports/custom_reports_upload.pl b/reports/custom_reports_upload.pl
>> new file mode 100755
>> index 0000000..5bf98bf
>> --- /dev/null
>> +++ b/reports/custom_reports_upload.pl
>> @@ -0,0 +1,89 @@
>> +#!/usr/bin/perl
>> +#
>> +# This file is part of Koha.
>> +#
>> +# Koha is free software; you can redistribute it and/or modify it under the
>> +# terms of the GNU General Public License as published by the Free Software
>> +# Foundation; either version 2 of the License, or (at your option) any later
>> +# version.
>> +#
>> +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
>> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
>> +# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License along with
>> +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
>> +# Suite 330, Boston, MA  02111-1307 USA
>> +
>> +use strict;
>> +use warnings;
>> +
>> +use File::Temp;
>> +use File::Copy;
>> +use CGI;
>> +use GD;
>> +
>> +use C4::Context;
>> +use C4::Auth;
>> +use C4::Output;
>> +use C4::Members;
>> +use C4::Debug;
>> +
>> +my $input = new CGI;
>> +
>> +my ($template, $loggedinuser, $cookie)
>> +       = get_template_and_user({template_name => "reports/custom_reports_upload.tmpl",
>> +                                       query => $input,
>> +                                       type => "intranet",
>> +                                       authnotrequired => 0,
>> +                                       flagsrequired => { reports => 'create_report'},
>> +                                       debug => 1,
>> +                                       });
>> +
>> +my $uploadfilename      = $input->param('uploadfile');
>> +my $uploadfile          = $input->upload('uploadfile');
>> +my $op                  = $input->param('op');
>> +
>> +my ( $total, $handled, @counts, $tempfile, $tfh );
>> +
>> +my %errors;
>> +
>> +if ( ($op eq 'Upload') && $uploadfile ) {
>> +    my $custom_reports_dir = "/home/koha/kohaclone/reports/custom_reports/";
>> +
>> +    my $dirname = File::Temp::tempdir( CLEANUP => 1);
>> +    $debug and warn "dirname = $dirname";
>> +
>> +    my $filesuffix = $1 if $uploadfilename =~ m/(\..+)$/i;
>> +    ( $tfh, $tempfile ) = File::Temp::tempfile( SUFFIX => $filesuffix, UNLINK => 1 );
>> +
>> +    $debug and warn "tempfile = $tempfile";
>> +
>> +    $errors{'NOTKRZ'} = 1 if ( $uploadfilename !~ /\.krz$/i );
>> +    $errors{'NOWRITETEMP'} = 1 unless ( -w $dirname );
>> +    $errors{'NOWRITEREPORTS'} = 1 unless ( -w $custom_reports_dir );
>> +    $errors{'EMPTYUPLOAD'} = 1 unless ( length( $uploadfile ) > 0 );
>> +
>> +    if ( %errors ) {
>> +       $template->param( ERRORS => [ \%errors ] );
>> +    } else {
>> +       while ( <$uploadfile> ) {
>> +           print $tfh $_;
>> +        }
>> +        close $tfh;
>> +        unless (system("unzip $tempfile -d $custom_reports_dir") == 0) {
>> +            $errors{'UZIPFAIL'} = $uploadfilename;
>> +            $template->param( ERRORS => [ \%errors ] );
>> +            output_html_with_http_headers $input, $cookie, $template->output;
>> +            exit;
>> +        }
>> +    }
>> +} elsif ( ($op eq 'Upload') && !$uploadfile ) {
>> +    warn "Problem uploading file or no file uploaded.";
>> +}
>> +
>> +if ( $uploadfile && !%errors && !$template->param('ERRORS') ) {
>> +    print $input->redirect ("/cgi-bin/koha/reports/custom_reports.pl");
>> +} else {
>> +    output_html_with_http_headers $input, $cookie, $template->output;
>> +}
>> --
>> 1.5.6.5
>>
>>
>



More information about the Koha-patches mailing list