Bug 18073: Holds to pull table enhancement
[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             CONCAT_WS(' ', borrowers.firstname, borrowers.surname) as l_patron
127     FROM  reserves
128         LEFT JOIN items ON items.biblionumber=reserves.biblionumber 
129         LEFT JOIN biblio ON reserves.biblionumber=biblio.biblionumber
130         LEFT JOIN branchtransfers ON items.itemnumber=branchtransfers.itemnumber
131         LEFT JOIN issues ON items.itemnumber=issues.itemnumber
132         LEFT JOIN borrowers ON reserves.borrowernumber=borrowers.borrowernumber
133     WHERE
134     reserves.found IS NULL
135     $sqldatewhere
136     AND (reserves.itemnumber IS NULL OR reserves.itemnumber = items.itemnumber)
137     AND items.itemnumber NOT IN (SELECT itemnumber FROM branchtransfers where datearrived IS NULL)
138     AND items.itemnumber NOT IN (select itemnumber FROM reserves where found='W')
139     AND issues.itemnumber IS NULL
140     AND reserves.priority <> 0 
141     AND reserves.suspend = 0
142     AND notforloan = 0 AND damaged = 0 AND itemlost = 0 AND withdrawn = 0
143     ";
144     # GROUP BY reserves.biblionumber allows only items that are not checked out, else multiples occur when 
145     #    multiple patrons have a hold on an item
146
147
148     if (C4::Context->preference('IndependentBranches')){
149         $strsth .= " AND items.holdingbranch=? ";
150         push @query_params, C4::Context->userenv->{'branch'};
151     }
152     $strsth .= " GROUP BY reserves.biblionumber ORDER BY biblio.title ";
153
154     my $sth = $dbh->prepare($strsth);
155     $sth->execute(@query_params);
156
157     while ( my $data = $sth->fetchrow_hashref ) {
158         my $record = Koha::Biblios->find($data->{biblionumber});
159         if ($record){
160             $data->{subtitle} = [ $record->subtitles ];
161         }
162         push(
163             @reservedata,
164             {
165                 reservedate     => $data->{l_reservedate},
166                 priority        => $data->{priority},
167                 name            => $data->{l_patron},
168                 title           => $data->{title},
169                 subtitle        => $data->{subtitle},
170                 author          => $data->{author},
171                 borrowernumber  => $data->{borrowernumber},
172                 itemnum         => $data->{itemnumber},
173                 phone           => $data->{phone},
174                 email           => $data->{email},
175                 biblionumber    => $data->{biblionumber},
176                 statusw         => ( $data->{found} eq "W" ),
177                 statusf         => ( $data->{found} eq "F" ),
178                 holdingbranches => [split('\|', $data->{l_holdingbranch})],,
179                 branch          => $data->{l_branch},
180                 itemcallnumber  => $data->{l_itemcallnumber},
181                 enumchron       => $data->{l_enumchron},
182                 copyno          => $data->{l_copynumber},
183                 notificationdate=> $data->{notificationdate},
184                 reminderdate    => $data->{reminderdate},
185                 count           => $data->{icount},
186                 rcount          => $data->{rcount},
187                 pullcount       => $data->{icount} <= $data->{rcount} ? $data->{icount} : $data->{rcount},
188                 itypes          => [split('\|', $data->{l_itype})],
189                 locations       => [split('\|', $data->{l_location})],
190             }
191         );
192     }
193     $sth->finish;
194 }
195
196 $template->param(
197     todaysdate          => $today,
198     from                => $startdate,
199     to                  => $enddate,
200     run_report          => $run_report,
201     reserveloop         => \@reservedata,
202     "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1,
203     HoldsToPullStartDate => C4::Context->preference('HoldsToPullStartDate') || PULL_INTERVAL,
204     HoldsToPullEndDate  => C4::Context->preference('ConfirmFutureHolds') || 0,
205 );
206
207 output_html_with_http_headers $input, $cookie, $template->output;