Bug 15560: Fix display of multiple item types in pending reserves report
[koha.git] / circ / pendingreserves.pl
1 #!/usr/bin/perl
2
3 # Copyright 2000-2002 Katipo Communications
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 # Modification by D.Ulm, actually works (as long as indep. branches not turned on)
21 #               Someone let me know what indep. branches is supposed to do and I'll make that part work too
22 #
23 #               The reserve pull lists *works* as long as not for indepencdant branches, I can fix!
24
25 use strict;
26 #use warnings; FIXME - Bug 2505
27
28 use constant PULL_INTERVAL => 2;
29
30 use C4::Context;
31 use C4::Output;
32 use CGI qw ( -utf8 );
33 use C4::Auth;
34 use C4::Debug;
35 use Koha::DateUtils;
36 use DateTime::Duration;
37
38 my $input = new CGI;
39 my $startdate=$input->param('from');
40 my $enddate=$input->param('to');
41 my $run_report = ( not defined $input->param('run_report') ) ? 1 : $input->param('run_report');
42
43 my $theme = $input->param('theme');    # only used if allowthemeoverride is set
44
45 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
46     {
47         template_name   => "circ/pendingreserves.tt",
48         query           => $input,
49         type            => "intranet",
50         authnotrequired => 0,
51         flagsrequired   => { circulate => "circulate_remaining_permissions" },
52         debug           => 1,
53     }
54 );
55
56 my $today = dt_from_string;
57 $startdate =~ s/^\s+//;
58 $startdate =~ s/\s+$//;
59 $enddate =~ s/^\s+//;
60 $enddate =~ s/\s+$//;
61
62 if ( $startdate ) {
63     $startdate = eval{dt_from_string( $startdate )};
64 }
65 unless ( $startdate ){
66     # changed from delivered range of 10 years-yesterday to 2 days ago-today
67     # Find two days ago for the default shelf pull start date, unless HoldsToPullStartDate sys pref is set.
68     $startdate = $today - DateTime::Duration->new( days => C4::Context->preference('HoldsToPullStartDate') || PULL_INTERVAL );
69 }
70
71 if ( $enddate ) {
72     $enddate = eval{dt_from_string( $enddate )};
73 }
74 unless ( $enddate ) {
75     #similarly: calculate end date with ConfirmFutureHolds (days)
76     $enddate = $today + DateTime::Duration->new( days => C4::Context->preference('ConfirmFutureHolds') || 0 );
77 }
78
79 my @reservedata;
80 if ( $run_report ) {
81     my $dbh    = C4::Context->dbh;
82     my $sqldatewhere = "";
83     my $startdate_iso = output_pref({ dt => $startdate, dateformat => 'iso', dateonly => 1 });
84     my $enddate_iso   = output_pref({ dt => $enddate, dateformat => 'iso', dateonly => 1 });
85     $debug and warn $startdate_iso. "\n" . $enddate_iso;
86     my @query_params = ();
87     if ($startdate_iso) {
88         $sqldatewhere .= " AND reservedate >= ?";
89         push @query_params, $startdate_iso;
90     }
91     if ($enddate_iso) {
92         $sqldatewhere .= " AND reservedate <= ?";
93         push @query_params, $enddate_iso;
94     }
95
96     my $strsth =
97     "SELECT min(reservedate) as l_reservedate,
98             reserves.borrowernumber as borrowernumber,
99             GROUP_CONCAT(DISTINCT items.holdingbranch 
100                     ORDER BY items.itemnumber SEPARATOR '|') l_holdingbranch,
101             reserves.biblionumber,
102             reserves.branchcode,
103             GROUP_CONCAT(DISTINCT reserves.branchcode 
104                     ORDER BY items.itemnumber SEPARATOR ', ') l_branch,
105             items.holdingbranch as branch,
106             GROUP_CONCAT(DISTINCT items.itype 
107                     ORDER BY items.itemnumber SEPARATOR '|') l_itype,
108             GROUP_CONCAT(DISTINCT items.location 
109                     ORDER BY items.itemnumber SEPARATOR '|') l_location,
110             GROUP_CONCAT(DISTINCT items.itemcallnumber 
111                     ORDER BY items.itemnumber SEPARATOR '<br/>') l_itemcallnumber,
112             GROUP_CONCAT(DISTINCT items.enumchron
113                     ORDER BY items.itemnumber SEPARATOR '<br/>') l_enumchron,
114             GROUP_CONCAT(DISTINCT items.copynumber
115                     ORDER BY items.itemnumber SEPARATOR '<br/>') l_copynumber,
116             items.itemnumber,
117             notificationdate,
118             reminderdate,
119             max(priority) as priority,
120             reserves.found,
121             biblio.title,
122             biblio.author,
123             count(DISTINCT items.itemnumber) as icount,
124             count(DISTINCT reserves.borrowernumber) as rcount
125     FROM  reserves
126         LEFT JOIN items ON items.biblionumber=reserves.biblionumber 
127         LEFT JOIN biblio ON reserves.biblionumber=biblio.biblionumber
128         LEFT JOIN branchtransfers ON items.itemnumber=branchtransfers.itemnumber
129         LEFT JOIN issues ON items.itemnumber=issues.itemnumber
130     WHERE
131     reserves.found IS NULL
132     $sqldatewhere
133     AND (reserves.itemnumber IS NULL OR reserves.itemnumber = items.itemnumber)
134     AND items.itemnumber NOT IN (SELECT itemnumber FROM branchtransfers where datearrived IS NULL)
135     AND items.itemnumber NOT IN (select itemnumber FROM reserves where found='W')
136     AND issues.itemnumber IS NULL
137     AND reserves.priority <> 0 
138     AND reserves.suspend = 0
139     AND notforloan = 0 AND damaged = 0 AND itemlost = 0 AND withdrawn = 0
140     ";
141     # GROUP BY reserves.biblionumber allows only items that are not checked out, else multiples occur when 
142     #    multiple patrons have a hold on an item
143
144
145     if (C4::Context->preference('IndependentBranches')){
146         $strsth .= " AND items.holdingbranch=? ";
147         push @query_params, C4::Context->userenv->{'branch'};
148     }
149     $strsth .= " GROUP BY reserves.biblionumber ORDER BY biblio.title ";
150
151     my $sth = $dbh->prepare($strsth);
152     $sth->execute(@query_params);
153
154     while ( my $data = $sth->fetchrow_hashref ) {
155         push(
156             @reservedata,
157             {
158                 reservedate     => $data->{l_reservedate},
159                 priority        => $data->{priority},
160                 name            => $data->{l_patron},
161                 title           => $data->{title},
162                 author          => $data->{author},
163                 borrowernumber  => $data->{borrowernumber},
164                 itemnum         => $data->{itemnumber},
165                 phone           => $data->{phone},
166                 email           => $data->{email},
167                 biblionumber    => $data->{biblionumber},
168                 statusw         => ( $data->{found} eq "W" ),
169                 statusf         => ( $data->{found} eq "F" ),
170                 holdingbranches => [split('\|', $data->{l_holdingbranch})],,
171                 branch          => $data->{l_branch},
172                 itemcallnumber  => $data->{l_itemcallnumber},
173                 enumchron       => $data->{l_enumchron},
174                 copyno          => $data->{l_copynumber},
175                 notificationdate=> $data->{notificationdate},
176                 reminderdate    => $data->{reminderdate},
177                 count           => $data->{icount},
178                 rcount          => $data->{rcount},
179                 pullcount       => $data->{icount} <= $data->{rcount} ? $data->{icount} : $data->{rcount},
180                 itypes          => [split('\|', $data->{l_itype})],
181                 locations       => [split('\|', $data->{l_location})],
182             }
183         );
184     }
185     $sth->finish;
186 }
187
188 $template->param(
189     todaysdate          => $today,
190     from                => $startdate,
191     to                  => $enddate,
192     run_report          => $run_report,
193     reserveloop         => \@reservedata,
194     "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1,
195     HoldsToPullStartDate => C4::Context->preference('HoldsToPullStartDate') || PULL_INTERVAL,
196     HoldsToPullEndDate  => C4::Context->preference('ConfirmFutureHolds') || 0,
197 );
198
199 output_html_with_http_headers $input, $cookie, $template->output;