Bug 18073: Followup - don't use CONCAT_WS
[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 Koha::Biblios;
35 use C4::Debug;
36 use Koha::DateUtils;
37 use DateTime::Duration;
38
39 my $input = new CGI;
40 my $startdate=$input->param('from');
41 my $enddate=$input->param('to');
42 my $run_report = ( not defined $input->param('run_report') ) ? 1 : $input->param('run_report');
43
44 my $theme = $input->param('theme');    # only used if allowthemeoverride is set
45
46 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
47     {
48         template_name   => "circ/pendingreserves.tt",
49         query           => $input,
50         type            => "intranet",
51         authnotrequired => 0,
52         flagsrequired   => { circulate => "circulate_remaining_permissions" },
53         debug           => 1,
54     }
55 );
56
57 my $today = dt_from_string;
58 $startdate =~ s/^\s+//;
59 $startdate =~ s/\s+$//;
60 $enddate =~ s/^\s+//;
61 $enddate =~ s/\s+$//;
62
63 if ( $startdate ) {
64     $startdate = eval{dt_from_string( $startdate )};
65 }
66 unless ( $startdate ){
67     # changed from delivered range of 10 years-yesterday to 2 days ago-today
68     # Find two days ago for the default shelf pull start date, unless HoldsToPullStartDate sys pref is set.
69     $startdate = $today - DateTime::Duration->new( days => C4::Context->preference('HoldsToPullStartDate') || PULL_INTERVAL );
70 }
71
72 if ( $enddate ) {
73     $enddate = eval{dt_from_string( $enddate )};
74 }
75 unless ( $enddate ) {
76     #similarly: calculate end date with ConfirmFutureHolds (days)
77     $enddate = $today + DateTime::Duration->new( days => C4::Context->preference('ConfirmFutureHolds') || 0 );
78 }
79
80 my @reservedata;
81 if ( $run_report ) {
82     my $dbh    = C4::Context->dbh;
83     my $sqldatewhere = "";
84     my $startdate_iso = output_pref({ dt => $startdate, dateformat => 'iso', dateonly => 1 });
85     my $enddate_iso   = output_pref({ dt => $enddate, dateformat => 'iso', dateonly => 1 });
86     $debug and warn $startdate_iso. "\n" . $enddate_iso;
87     my @query_params = ();
88     if ($startdate_iso) {
89         $sqldatewhere .= " AND reservedate >= ?";
90         push @query_params, $startdate_iso;
91     }
92     if ($enddate_iso) {
93         $sqldatewhere .= " AND reservedate <= ?";
94         push @query_params, $enddate_iso;
95     }
96
97     my $strsth =
98     "SELECT min(reservedate) as l_reservedate,
99             reserves.borrowernumber as borrowernumber,
100             GROUP_CONCAT(DISTINCT items.holdingbranch 
101                     ORDER BY items.itemnumber SEPARATOR '|') l_holdingbranch,
102             reserves.biblionumber,
103             reserves.branchcode,
104             GROUP_CONCAT(DISTINCT reserves.branchcode 
105                     ORDER BY items.itemnumber SEPARATOR ', ') l_branch,
106             items.holdingbranch as branch,
107             GROUP_CONCAT(DISTINCT items.itype 
108                     ORDER BY items.itemnumber SEPARATOR '|') l_itype,
109             GROUP_CONCAT(DISTINCT items.location 
110                     ORDER BY items.itemnumber SEPARATOR '|') l_location,
111             GROUP_CONCAT(DISTINCT items.itemcallnumber 
112                     ORDER BY items.itemnumber SEPARATOR '<br/>') l_itemcallnumber,
113             GROUP_CONCAT(DISTINCT items.enumchron
114                     ORDER BY items.itemnumber SEPARATOR '<br/>') l_enumchron,
115             GROUP_CONCAT(DISTINCT items.copynumber
116                     ORDER BY items.itemnumber SEPARATOR '<br/>') l_copynumber,
117             items.itemnumber,
118             notificationdate,
119             reminderdate,
120             max(priority) as priority,
121             reserves.found,
122             biblio.title,
123             biblio.author,
124             count(DISTINCT items.itemnumber) as icount,
125             count(DISTINCT reserves.borrowernumber) as rcount,
126             borrowers.firstname,
127             borrowers.surname
128     FROM  reserves
129         LEFT JOIN items ON items.biblionumber=reserves.biblionumber 
130         LEFT JOIN biblio ON reserves.biblionumber=biblio.biblionumber
131         LEFT JOIN branchtransfers ON items.itemnumber=branchtransfers.itemnumber
132         LEFT JOIN issues ON items.itemnumber=issues.itemnumber
133         LEFT JOIN borrowers ON reserves.borrowernumber=borrowers.borrowernumber
134     WHERE
135     reserves.found IS NULL
136     $sqldatewhere
137     AND (reserves.itemnumber IS NULL OR reserves.itemnumber = items.itemnumber)
138     AND items.itemnumber NOT IN (SELECT itemnumber FROM branchtransfers where datearrived IS NULL)
139     AND items.itemnumber NOT IN (select itemnumber FROM reserves where found='W')
140     AND issues.itemnumber IS NULL
141     AND reserves.priority <> 0 
142     AND reserves.suspend = 0
143     AND notforloan = 0 AND damaged = 0 AND itemlost = 0 AND withdrawn = 0
144     ";
145     # GROUP BY reserves.biblionumber allows only items that are not checked out, else multiples occur when 
146     #    multiple patrons have a hold on an item
147
148
149     if (C4::Context->preference('IndependentBranches')){
150         $strsth .= " AND items.holdingbranch=? ";
151         push @query_params, C4::Context->userenv->{'branch'};
152     }
153     $strsth .= " GROUP BY reserves.biblionumber ORDER BY biblio.title ";
154
155     my $sth = $dbh->prepare($strsth);
156     $sth->execute(@query_params);
157
158     while ( my $data = $sth->fetchrow_hashref ) {
159         my $record = Koha::Biblios->find($data->{biblionumber});
160         if ($record){
161             $data->{subtitle} = [ $record->subtitles ];
162         }
163         push(
164             @reservedata,
165             {
166                 reservedate     => $data->{l_reservedate},
167                 priority        => $data->{priority},
168                 firstname       => $data->{firstname} || '',
169                 surname         => $data->{surname},
170                 title           => $data->{title},
171                 subtitle        => $data->{subtitle},
172                 author          => $data->{author},
173                 borrowernumber  => $data->{borrowernumber},
174                 itemnum         => $data->{itemnumber},
175                 phone           => $data->{phone},
176                 email           => $data->{email},
177                 biblionumber    => $data->{biblionumber},
178                 statusw         => ( $data->{found} eq "W" ),
179                 statusf         => ( $data->{found} eq "F" ),
180                 holdingbranches => [split('\|', $data->{l_holdingbranch})],,
181                 branch          => $data->{l_branch},
182                 itemcallnumber  => $data->{l_itemcallnumber},
183                 enumchron       => $data->{l_enumchron},
184                 copyno          => $data->{l_copynumber},
185                 notificationdate=> $data->{notificationdate},
186                 reminderdate    => $data->{reminderdate},
187                 count           => $data->{icount},
188                 rcount          => $data->{rcount},
189                 pullcount       => $data->{icount} <= $data->{rcount} ? $data->{icount} : $data->{rcount},
190                 itypes          => [split('\|', $data->{l_itype})],
191                 locations       => [split('\|', $data->{l_location})],
192             }
193         );
194     }
195     $sth->finish;
196 }
197
198 $template->param(
199     todaysdate          => $today,
200     from                => $startdate,
201     to                  => $enddate,
202     run_report          => $run_report,
203     reserveloop         => \@reservedata,
204     "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1,
205     HoldsToPullStartDate => C4::Context->preference('HoldsToPullStartDate') || PULL_INTERVAL,
206     HoldsToPullEndDate  => C4::Context->preference('ConfirmFutureHolds') || 0,
207 );
208
209 output_html_with_http_headers $input, $cookie, $template->output;