Fix for bug #496
[koha.git] / opac / opac-reserve.pl
1 #!/usr/bin/perl
2 # NOTE: This file uses standard 8-character tabs
3
4 use strict;
5 require Exporter;
6 use CGI;
7
8 use C4::Search;
9 use C4::Auth;         # checkauth, getborrowernumber.
10 use C4::Koha;
11 use C4::Circulation::Circ2;
12 use C4::Reserves2;
13 use C4::Interface::CGI::Output;
14 use HTML::Template;
15 use C4::Date;
16 use C4::Context;
17
18 my $MAXIMUM_NUMBER_OF_RESERVES = C4::Context->preference("maxreserves");
19
20 my $query = new CGI;
21 my ($template, $borrowernumber, $cookie)
22     = get_template_and_user({template_name => "opac-reserve.tmpl",
23                              query => $query,
24                              type => "opac",
25                              authnotrequired => 0,
26                              flagsrequired => {borrow => 1},
27                              debug => 1,
28                              });
29
30 # get borrower information ....
31 my ($borr, $flags) = getpatroninformation(undef, $borrowernumber);
32 my @bordat;
33 $bordat[0] = $borr;
34
35 # get biblionumber.....
36 my $biblionumber = $query->param('bib');
37
38 my $bibdata = bibdata($biblionumber);
39  $template->param($bibdata);
40  $template->param(BORROWER_INFO => \@bordat, biblionumber => $biblionumber);
41
42 # get the rank number....
43 my ($rank,$reserves) = FindReserves($biblionumber,'');
44 $template->param(reservecount => $rank);
45
46 foreach my $res (@$reserves) {
47     if ($res->{'found'} eq 'W') {
48         $rank--;
49     }
50 }
51
52
53
54 $rank++;
55 $template->param(rank => $rank);
56
57 # pass the pickup branch along....
58 my $branch = $query->param('branch');
59 $template->param(branch => $branch);
60
61 my $branches = getbranches();
62 $template->param(branchname => $branches->{$branch}->{'branchname'});
63
64
65 # make branch selection options...
66 #my $branchoptions = '';
67 my @branches;
68 my @select_branch;
69 my %select_branches;
70
71 foreach my $branch (keys %$branches) {
72         push @select_branch, $branch;
73         $select_branches{$branch} = $branches->{$branch}->{'branchname'};
74 }
75 my $CGIbranch=CGI::scrolling_list( -name     => 'branch',
76                         -values   => \@select_branch,
77                         -labels   => \%select_branches,
78                         -size     => 1,
79                         -multiple => 0 );
80 $template->param( CGIbranch => $CGIbranch);
81
82 #### THIS IS A BIT OF A HACK BECAUSE THE BIBLIOITEMS DATA IS A LITTLE MESSED UP!
83 # get the itemtype data....
84 my @items = ItemInfo(undef, $biblionumber, 'opac');
85
86 #######################################################
87 # old version, add so that old templates still work
88 my %types_old;
89 foreach my $itm (@items) {
90     my $ity = $itm->{'itemtype'};
91     unless ($types_old {$ity}) {
92         $types_old{$ity}->{'itemtype'} = $ity;
93         $types_old{$ity}->{'branchinfo'}->{$itm->{'branchcode'}} = 1;
94         $types_old{$ity}->{'description'} = $itm->{'description'};
95     } else {
96         $types_old{$ity}->{'branchinfo'}->{$itm->{'branchcode'}} ++;
97     }
98 }
99
100 foreach my $type (values %types_old) {
101     my $copies = "";
102     foreach my $bc (keys %{$type->{'branchinfo'}}) {
103         $copies .= $branches->{$bc}->{'branchname'}."(".$type->{'branchinfo'}->{$bc}.")";
104     }
105     $type->{'copies'} = $copies;
106 }
107
108 my @types_old = values %types_old;
109
110 # end old version
111 ################################
112
113 my @temp;
114 foreach my $itm (@items) {
115     push @temp, $itm if $itm->{'itemtype'};
116 }
117 @items = @temp;
118 my $itemcount = @items;
119 $template->param(itemcount => $itemcount);
120
121 my %types;
122 my %itemtypes;
123 my @duedates;
124 foreach my $itm (@items) {
125     push @duedates, {date_due => format_date($itm->{'date_due'})} if defined $itm->{'date_due'};
126     $itm->{$itm->{'publictype'}} = 1;
127     # FIXME CalcReserveFee is supposed to be internal-use-only
128     my $fee  = CalcReserveFee(undef, $borrowernumber, $itm->{'biblionumber'},'a',($itm->{'biblioitemnumber'}));
129     $fee = sprintf "%.02f", $fee;
130     $itm->{'reservefee'} = $fee;
131     my $pty = $itm->{'publictype'};
132     $itemtypes{$itm->{'itemtype'}} = $itm;
133     unless ($types {$pty}) {
134         $types{$pty}->{'count'} = 1;
135         $types{$pty}->{$itm->{'itemtype'}} = 1;
136         push @{$types{$pty}->{'items'}}, $itm;
137     } else {
138         unless ($types{$pty}->{$itm->{'itemtype'}}) {
139             $types{$pty}->{'count'}++;
140             $types{$pty}->{$itm->{'itemtype'}} = 1;
141             push @{$types{$pty}->{'items'}}, $itm;
142         }
143     }
144 }
145
146
147 $template->param(ITEMS => \@duedates);
148
149 my $width = keys %types;
150 my @publictypes = sort {$b->{'count'} <=> $a->{'count'}} values %types;
151 my $typecount;
152 foreach my $pt (@publictypes) {
153     $typecount += $pt->{'count'};
154 }
155 $template->param(onlyone => 1) if $typecount == 1;
156
157 my @typerows;
158 for (my $rownum=0;$rownum<$publictypes[0]->{'count'} ;$rownum++) {
159     my @row;
160     foreach my $pty (@publictypes) {
161         my @items = @{$pty->{'items'}};
162         push @row, $items[$rownum] if defined $items[$rownum];
163     }
164     my $last = @row; 
165     $row[$last-1]->{'last'} =1 if $last == $width;
166     my $fill = ($width - $last)*2;
167     $fill-- if $fill;
168     push @typerows, {ROW => \@row, fill => $fill};
169 }
170 $template->param(TYPE_ROWS => \@typerows);
171 $width = 2*$width -1;
172 $template->param(totalwidth => 2*$width-1);
173
174 if ($query->param('item_types_selected')) {
175         # this is what happens after the itemtypes have been selected. Stage 2
176         my @itemtypes = $query->param('itemtype');
177         my $fee = 0;
178         my $proceed = 0;
179         if (@itemtypes) {
180                 my %newtypes;
181                 foreach my $itmtype (@itemtypes) {
182                 $newtypes{$itmtype} = $itemtypes{$itmtype};
183                 }
184                 my @types = values %newtypes;
185                 $template->param(TYPES => \@types);
186                 foreach my $type (@itemtypes) {
187                 my @reqbibs;
188                 foreach my $item (@items) {
189                         if ($item->{'itemtype'} eq $type) {
190                         push @reqbibs, $item->{'biblioitemnumber'};
191                         }
192                 }
193                 $fee += CalcReserveFee(undef,$borrowernumber,$biblionumber,'o',\@reqbibs);
194                 }
195                 $proceed = 1;
196         } elsif ($query->param('all')) {
197                 $template->param(all => 1);
198                 $fee = 1;
199                 $proceed = 1;
200         }
201         warn "branch :$branch:";
202         if ($proceed && $branch) {
203                 $fee = sprintf "%.02f", $fee;
204                 $template->param(fee => $fee);
205                 $template->param(item_types_selected => 1);
206         } else {
207                 $template->param(message => 1);
208                 $template->param(no_items_selected => 1) unless ($proceed);
209                 $template->param(no_branch_selected =>1) unless ($branch);
210         }
211 } elsif ($query->param('place_reserve')) {
212         # here we actually do the reserveration. Stage 3.
213         my $title = $bibdata->{'title'};
214         my @itemtypes = $query->param('itemtype');
215         foreach my $type (@itemtypes) {
216                 my @reqbibs;
217                 foreach my $item (@items) {
218                 if ($item->{'itemtype'} eq $type) {
219                         push @reqbibs, $item->{'biblioitemnumber'};
220                 }
221                 }
222                 CreateReserve(undef,$branch,$borrowernumber,$biblionumber,'o',\@reqbibs,$rank,'',$title);
223         }
224         if ($query->param('all')) {
225                 CreateReserve(undef,$branch,$borrowernumber,$biblionumber,'a', undef, $rank,'',$title);
226         }
227         print $query->redirect("/cgi-bin/koha/opac-user.pl");
228 } else {
229         # Here we check that the borrower can actually make reserves Stage 1.
230         my $noreserves = 0;
231         my $maxoutstanding = C4::Context->preference("maxoustanding");
232         if ($borr->{'amountoutstanding'} > $maxoutstanding) {
233                 my $amount = sprintf "\$%.02f", $borr->{'amountoutstanding'};
234                 $template->param(message => 1);
235                 $noreserves = 1;
236                 $template->param(too_much_oweing => $amount);
237         }
238         my ($resnum, $reserves) = FindReserves('', $borrowernumber);
239         $template->param(RESERVES => $reserves);
240         if ($resnum >= $MAXIMUM_NUMBER_OF_RESERVES) {
241                 $template->param(message => 1);
242                 $noreserves = 1;
243                 $template->param(too_many_reserves => $resnum);
244         }
245         foreach my $res (@$reserves) {
246                 if ($res->{'biblionumber'} == $biblionumber) {
247                 $template->param(message => 1);
248                 $noreserves = 1;
249                 $template->param(already_reserved => 1);
250                 }
251         }
252         unless ($noreserves) {
253                 $template->param(TYPES => \@types_old);
254                 $template->param(select_item_types => 1);
255         }
256 }
257
258 # check that you can actually make the reserve.
259
260 output_html_with_http_headers $query, $cookie, $template->output;
261
262 # Local Variables:
263 # tab-width: 8
264 # End: