Bug 13914 : Fix UNION in SQL request for reserves statistics
[koha.git] / reports / reserves_stats.pl
index 4254d5a..a444bc5 100755 (executable)
 
 
 use strict;
+use warnings;
 
-use CGI;
+use CGI qw ( -utf8 );
 
 use C4::Auth;
 use C4::Debug;
 use C4::Context;
-use C4::Branch; # GetBranches
 use C4::Koha;
 use C4::Output;
 use C4::Reports;
 use C4::Members;
-use C4::Dates qw/format_date format_date_in_iso/;
-use C4::Category;
+use Koha::DateUtils;
+use Koha::Libraries;
+use Koha::Patron::Categories;
 use List::MoreUtils qw/any/;
 use YAML;
 
 =head1 NAME
 
-plugin that shows circulation stats
+    reports/reserve_stats.pl
 
 =head1 DESCRIPTION
 
-=over 2
+    Plugin that shows circulation stats
 
 =cut
 
 # my $debug = 1;       # override for now.
 my $input = new CGI;
-my $fullreportname = "reports/reserves_stats.tmpl";
+my $fullreportname = "reports/reserves_stats.tt";
 my $do_it    = $input->param('do_it');
 my $line     = $input->param("Line");
 my $column   = $input->param("Column");
@@ -74,14 +75,13 @@ my ($template, $borrowernumber, $cookie) = get_template_and_user({
        flagsrequired => {reports => '*'},
        debug => 0,
 });
-our $sep     = $input->param("sep");
+our $sep     = $input->param("sep") || '';
 $sep = "\t" if ($sep eq 'tabulation');
 $template->param(do_it => $do_it,
-       DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),
 );
 
 my $itemtypes = GetItemTypes();
-my $categoryloop = GetBorrowercategoryList;
+my @patron_categories = Koha::Patron::Categories->search_limited({}, {order_by => ['description']});
 
 my $ccodes    = GetKohaAuthorisedValues("items.ccode");
 my $locations = GetKohaAuthorisedValues("items.location");
@@ -129,7 +129,7 @@ if ($do_it) {
                print map {$sep.$_->{totalcol}} @$cols;
         print $sep.@$results[0]->{total};
        }
-       exit(1); # exit either way after $do_it
+       exit; # exit either way after $do_it
 }
 
 my $dbh = C4::Context->dbh;
@@ -139,8 +139,8 @@ my %select;
 
 # create itemtype arrayref for <select>.
 my @itemtypeloop;
-for my $itype ( sort {$itemtypes->{$a}->{description} cmp $itemtypes->{$b}->{description}} keys(%$itemtypes)) {
-       push @itemtypeloop, { code => $itype , description => $itemtypes->{$itype}->{description} } ;
+for my $itype ( sort {$itemtypes->{$a}->{translated_description} cmp $itemtypes->{$b}->{translated_description}} keys(%$itemtypes)) {
+       push @itemtypeloop, { code => $itype , description => $itemtypes->{$itype}->{translated_description} } ;
 }
 
     # location list
@@ -155,22 +155,14 @@ foreach (sort {$ccodes->{$a} cmp $ccodes->{$b}} keys %$ccodes) {
 }
 
 # various
-my @mime = (C4::Context->preference("MIME"));
-
-my $CGIextChoice=CGI::scrolling_list(
-       -name     => 'MIME',
-       -id       => 'MIME',
-       -values   => \@mime,
-       -size     => 1,
-       -multiple => 0 );
-    
+my $CGIextChoice = ( 'CSV' ); # FIXME translation
 my $CGIsepChoice=GetDelimiterChoices;
  
 $template->param(
-       categoryloop => $categoryloop,
+    categoryloop => \@patron_categories,
        itemtypeloop => \@itemtypeloop,
+       locationloop => \@locations,
           ccodeloop => \@ccodes,
-         branchloop => GetBranchesLoop(C4::Context->userenv->{'branch'}),
        hassort1=> $hassort1,
        hassort2=> $hassort2,
        Bsort1 => $Bsort1,
@@ -194,18 +186,26 @@ sub calculate {
 # Filters
 # Checking filters
 #
-       my @loopfilter;
-       foreach my $filter (keys %$filters_hashref){
-               $$filters_hashref{$filter} =~s/\*/%/;
-               $$filters_hashref{$filter} = format_date_in_iso($$filters_hashref{$_}) if ($_=~/date/);
-       }
-       #display
-       @loopfilter= map{{ crit=>$_ ,filter=>($_=~/date/?
-                                                                                       format_date($$filters_hashref{$_})
-                                                                                       :$$filters_hashref{$_}
-                                                                                 )
-                                         }
-                                       } sort keys %$filters_hashref;
+    my @loopfilter;
+    foreach my $filter ( keys %$filters_hashref ) {
+        $filters_hashref->{$filter} =~ s/\*/%/;
+        if ( $filter =~ /date/ ) {
+            $filters_hashref->{$filter} =
+                eval { output_pref( { dt => dt_from_string( $filters_hashref->{$filter} ), dateonly => 1, dateformat => 'iso' }); };
+        }
+    }
+
+    #display
+    @loopfilter = map {
+        {
+            crit   => $_,
+            filter => (
+                $_ =~ /date/
+                ? eval { output_pref( { dt => dt_from_string( $filters_hashref->{$_} ), dateonly => 1 }); }
+                : $filters_hashref->{$_}
+            )
+        }
+    } sort keys %$filters_hashref;
 
 
 
@@ -221,14 +221,14 @@ sub calculate {
                                ($process == 3) ? "(COUNT(DISTINCT reserves.itemnumber)) calculation"      : 
                                ($process == 4) ? "(COUNT(DISTINCT reserves.biblionumber)) calculation"    : '*';
        $strcalc .= "
-        FROM reserves
+        FROM (select * from reserves union select * from old_reserves) reserves
         LEFT JOIN borrowers USING (borrowernumber)
        ";
        $strcalc .= "LEFT JOIN biblio ON reserves.biblionumber=biblio.biblionumber "
         if ($linefield =~ /^biblio\./ or $colfield =~ /^biblio\./ or any {$_=~/biblio/}keys %$filters_hashref);
        $strcalc .= "LEFT JOIN items ON reserves.itemnumber=items.itemnumber "
         if ($linefield =~ /^items\./ or $colfield =~ /^items\./ or any {$_=~/items/}keys %$filters_hashref);
-        
+
        my @sqlparams;
        my @sqlorparams;
        my @sqlor;
@@ -238,7 +238,6 @@ sub calculate {
                my $string;
                my $stringfield=$filter;
                $stringfield=~s/\_[a-z_]+$//;
-               warn $stringfield;
                if ($filter=~/ /){
                        $string=$stringfield;
                }
@@ -246,6 +245,9 @@ sub calculate {
                         push @sqlor, qq{( }.changeifreservestatus($filter)." = ? ) ";
                         push @sqlorparams, $$filters_hashref{$filter};
                }
+               elsif ($filter=~/_endex$/){
+                       $string = " $stringfield < ? ";
+               }
                elsif ($filter=~/_end$/){
                        $string = " $stringfield <= ? ";
                }
@@ -264,17 +266,13 @@ sub calculate {
        $strcalc .= " WHERE ".join(" AND ",@sqlwhere) if (@sqlwhere);
        $strcalc .= " AND (".join(" OR ",@sqlor).")" if (@sqlor);
        $strcalc .= " GROUP BY line, col )";
-       my $strcalc_old=$strcalc;
-       $strcalc_old=~s/reserves/old_reserves/g;
-       $strcalc.=qq{ UNION $strcalc_old ORDER BY line, col};
        ($debug) and print STDERR $strcalc;
        my $dbcalc = $dbh->prepare($strcalc);
        push @loopfilter, {crit=>'SQL =', sql=>1, filter=>$strcalc};
        @sqlparams=(@sqlparams,@sqlorparams);
-       $dbcalc->execute(@sqlparams,@sqlparams);
+       $dbcalc->execute(@sqlparams);
        my ($emptycol,$emptyrow); 
        my $data = $dbcalc->fetchall_hashref([qw(line col)]);
-       my @loopline;
        my %cols_hash;
        foreach my $row (keys %$data){
                push @loopline, $row;
@@ -304,14 +302,13 @@ sub calculate {
        for my $col ( sort keys %cols_hash ) {
                my $total = 0;
                foreach my $row (@loopline) {
-                       $total += $$data{$row}{$col}{calculation};
+                       $total += $data->{$row}{$col}{calculation} if $data->{$row}{$col}{calculation};
                        $debug and warn "value added ".$$data{$row}{$col}{calculation}. "for line ".$row;
                }
                push @loopfooter, {'totalcol' => $total};
                push @loopcol, {'coltitle' => $col,
                                                coltitle_display=>display_value($colfield,$col)};
        }
-
        # the header of the table
        $globalline{loopfilter}=\@loopfilter;
        # the core of the table
@@ -331,22 +328,34 @@ sub null_to_zzempty ($) {
        ($string eq "NULL") and return 'zzEMPTY';
        return $string;         # else return the valid value
 }
-sub display_value{
-       my ($crit,$value)=@_;
-       my $display_value =
-               ($crit =~ /ccode/   ) ? $ccodes->{$value}    :
-               ($crit =~ /location/) ? $locations->{$value} :
-               ($crit =~ /itemtype/) ? $itemtypes->{$value}->{description} :
-               ($crit =~ /branch/) ? GetBranchName($value):
-               ($crit =~ /reservestatus/) ? reservestatushuman($value):
-               $value; # default fallback
-       if ($crit =~ /(sort1|sort2)/) {
-               $display_value=GetAuthorisedValues("B$_",$value);
-       } elsif ($crit =~ /category/) {
-               my $element=any{$value eq $_->{categorycode}} @$categoryloop;
-               $display_value=$$element{description};
-       }
-       return $display_value;
+sub display_value {
+    my ( $crit, $value ) = @_;
+    my $display_value =
+        ( $crit =~ /ccode/ )         ? $ccodes->{$value}
+      : ( $crit =~ /location/ )      ? $locations->{$value}
+      : ( $crit =~ /itemtype/ )      ? $itemtypes->{$value}->{description}
+      : ( $crit =~ /branch/ )        ? Koha::Libraries->find($value)->branchname
+      : ( $crit =~ /reservestatus/ ) ? reservestatushuman($value)
+      :                                $value;    # default fallback
+    if ($crit =~ /sort1/) {
+        foreach (@$Bsort1) {
+            ($value eq $_->{authorised_value}) or next;
+            $display_value = $_->{lib} and last;
+        }
+    }
+    elsif ($crit =~ /sort2/) {
+        foreach (@$Bsort2) {
+            ($value eq $_->{authorised_value}) or next;
+            $display_value = $_->{lib} and last;
+        }
+    }
+    elsif ( $crit =~ /category/ ) {
+        foreach my $patron_category ( @patron_categories ) {
+            ( $value eq $patron_category->categorycode ) or next;
+            $display_value = $patron_category->description and last;
+        }
+    }
+    return $display_value;
 }
 sub reservestatushuman{
        my ($val)=@_;