Bug 7147 - Style Z39.50 search errors according to style patterns
[koha.git] / acqui / basket.pl
blobb55973283e6f79550dec5da859bcbddcafbd4374
1 #!/usr/bin/perl
3 #script to show display basket of orders
5 # Copyright 2000 - 2004 Katipo
6 # Copyright 2008 - 2009 BibLibre SARL
8 # This file is part of Koha.
10 # Koha is free software; you can redistribute it and/or modify it under the
11 # terms of the GNU General Public License as published by the Free Software
12 # Foundation; either version 2 of the License, or (at your option) any later
13 # version.
15 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
16 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License along
20 # with Koha; if not, write to the Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 use strict;
24 use warnings;
25 use C4::Auth;
26 use C4::Koha;
27 use C4::Output;
28 use CGI;
29 use C4::Acquisition;
30 use C4::Budgets;
31 use C4::Bookseller qw( GetBookSellerFromId);
32 use C4::Dates qw/format_date/;
33 use C4::Debug;
34 use C4::Biblio;
35 use C4::Members qw/GetMember/; #needed for permissions checking for changing basketgroup of a basket
36 use C4::Items;
37 =head1 NAME
39 basket.pl
41 =head1 DESCRIPTION
43 This script display all informations about basket for the supplier given
44 on input arg. Moreover, it allows us to add a new order for this supplier from
45 an existing record, a suggestion or a new record.
47 =head1 CGI PARAMETERS
49 =over 4
51 =item $basketno
53 The basket number.
55 =item supplierid
57 the supplier this script have to display the basket.
59 =item order
61 =back
63 =cut
65 my $query = new CGI;
66 my $basketno = $query->param('basketno');
67 my $booksellerid = $query->param('supplierid');
69 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
71 template_name => "acqui/basket.tmpl",
72 query => $query,
73 type => "intranet",
74 authnotrequired => 0,
75 flagsrequired => { acquisition => 'order_manage' },
76 debug => 1,
80 my $basket = GetBasket($basketno);
82 # FIXME : what about the "discount" percentage?
83 # FIXME : the query->param('supplierid') below is probably useless. The bookseller is always known from the basket
84 # if no booksellerid in parameter, get it from basket
85 # warn "=>".$basket->{booksellerid};
86 $booksellerid = $basket->{booksellerid} unless $booksellerid;
87 my ($bookseller) = GetBookSellerFromId($booksellerid);
88 my $op = $query->param('op');
89 if (!defined $op) {
90 $op = q{};
93 my $confirm_pref= C4::Context->preference("BasketConfirmations") || '1';
94 $template->param( skip_confirm_reopen => 1) if $confirm_pref eq '2';
96 if ( $op eq 'delete_confirm' ) {
97 my $basketno = $query->param('basketno');
98 DelBasket($basketno);
99 $template->param( delete_confirmed => 1 );
100 } elsif ( !$bookseller ) {
101 $template->param( NO_BOOKSELLER => 1 );
102 } elsif ( $op eq 'del_basket') {
103 $template->param( delete_confirm => 1 );
104 if ( C4::Context->preference("IndependantBranches") ) {
105 my $userenv = C4::Context->userenv;
106 unless ( $userenv->{flags} == 1 ) {
107 my $validtest = ( $basket->{creationdate} eq '' )
108 || ( $userenv->{branch} eq $basket->{branch} )
109 || ( $userenv->{branch} eq '' )
110 || ( $basket->{branch} eq '' );
111 unless ($validtest) {
112 print $query->redirect("../mainpage.pl");
113 exit 1;
117 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
118 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
119 my $contract = &GetContract($basket->{contractnumber});
120 $template->param(
121 basketno => $basketno,
122 basketname => $basket->{'basketname'},
123 basketnote => $basket->{note},
124 basketbooksellernote => $basket->{booksellernote},
125 basketcontractno => $basket->{contractnumber},
126 basketcontractname => $contract->{contractname},
127 creationdate => format_date( $basket->{creationdate} ),
128 authorisedby => $basket->{authorisedby},
129 authorisedbyname => $basket->{authorisedbyname},
130 closedate => format_date( $basket->{closedate} ),
131 active => $bookseller->{'active'},
132 booksellerid => $bookseller->{'id'},
133 name => $bookseller->{'name'},
134 address1 => $bookseller->{'address1'},
135 address2 => $bookseller->{'address2'},
136 address3 => $bookseller->{'address3'},
137 address4 => $bookseller->{'address4'},
139 } elsif ($op eq 'attachbasket' && $template->{'VARS'}->{'CAN_user_acquisition_group_manage'} == 1) {
140 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?basketno=' . $basket->{'basketno'} . '&op=attachbasket&booksellerid=' . $booksellerid);
141 # check if we have to "close" a basket before building page
142 } elsif ($op eq 'export') {
143 print $query->header(
144 -type => 'text/csv',
145 -attachment => 'basket' . $basket->{'basketno'} . '.csv',
147 print GetBasketAsCSV($query->param('basketno'));
148 exit;
149 } elsif ($op eq 'close') {
150 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
151 if ($confirm) {
152 my $basketno = $query->param('basketno');
153 my $booksellerid = $query->param('booksellerid');
154 $basketno =~ /^\d+$/ and CloseBasket($basketno);
155 # if requested, create basket group, close it and attach the basket
156 if ($query->param('createbasketgroup')) {
157 my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
158 booksellerid => $booksellerid,
159 closed => 1,
161 ModBasket( { basketno => $basketno,
162 basketgroupid => $basketgroupid } );
163 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
164 } else {
165 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?supplierid=' . $booksellerid);
167 exit;
168 } else {
169 $template->param(confirm_close => "1",
170 booksellerid => $booksellerid,
171 basketno => $basket->{'basketno'},
172 basketname => $basket->{'basketname'},
173 basketgroupname => $basket->{'basketname'});
176 } elsif ($op eq 'reopen') {
177 my $basket;
178 $basket->{basketno} = $query->param('basketno');
179 $basket->{closedate} = undef;
180 ModBasket($basket);
181 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
182 } else {
183 # get librarian branch...
184 if ( C4::Context->preference("IndependantBranches") ) {
185 my $userenv = C4::Context->userenv;
186 unless ( $userenv->{flags} == 1 ) {
187 my $validtest = ( $basket->{creationdate} eq '' )
188 || ( $userenv->{branch} eq $basket->{branch} )
189 || ( $userenv->{branch} eq '' )
190 || ( $basket->{branch} eq '' );
191 unless ($validtest) {
192 print $query->redirect("../mainpage.pl");
193 exit 1;
197 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
198 my $basketgroups;
199 my $member = GetMember(borrowernumber => $loggedinuser);
200 if ($basket->{closedate} && haspermission({ acquisition => 'group_manage'} )) {
201 $basketgroups = GetBasketgroups($basket->{booksellerid});
202 for my $bg ( @{$basketgroups} ) {
203 if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
204 $bg->{default} = 1;
207 my %emptygroup = ( id => undef,
208 name => "No group");
209 if ( ! $basket->{basketgroupid} ) {
210 $emptygroup{default} = 1;
211 $emptygroup{nogroup} = 1;
213 unshift( @$basketgroups, \%emptygroup );
215 # if new basket, pre-fill infos
216 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
217 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
218 $debug
219 and warn sprintf
220 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
221 $basket->{creationdate}, $basket->{authorisedby};
223 #to get active currency
224 my $cur = GetCurrency();
227 my @results = GetOrders( $basketno );
229 my $gist = $bookseller->{gstrate} // C4::Context->preference("gist") // 0;
230 $gist = 0 if $gist == 0.0000;
231 my $discount = $bookseller->{'discount'} / 100;
232 my $total_rrp = 0; # RRP Total, its value will be assigned to $total_rrp_gsti or $total_rrp_gste depending of $bookseller->{'listincgst'}
233 my $total_rrp_gsti = 0; # RRP Total, GST included
234 my $total_rrp_gste = 0; # RRP Total, GST excluded
235 my $gist_rrp = 0;
236 my $total_rrp_est = 0;
238 my $qty_total;
239 my @books_loop;
241 for my $order ( @results ) {
242 my $rrp = $order->{'listprice'} || 0;
243 my $qty = $order->{'quantity'} || 0;
244 if (!defined $order->{quantityreceived}) {
245 $order->{quantityreceived} = 0;
247 for ( qw(rrp ecost quantityreceived)) {
248 if (!defined $order->{$_}) {
249 $order->{$_} = 0;
253 my $budget = GetBudget( $order->{'budget_id'} );
254 $rrp = ConvertCurrency( $order->{'currency'}, $rrp );
256 $total_rrp += $qty * $order->{'rrp'};
257 my $line_total = $qty * $order->{'ecost'};
258 $total_rrp_est += $qty * $order->{'ecost'};
259 # FIXME: what about the "actual cost" field?
260 $qty_total += $qty;
261 my %line = %{ $order };
262 my $biblionumber = $order->{'biblionumber'};
263 my $countbiblio = CountBiblioInOrders($biblionumber);
264 my $ordernumber = $order->{'ordernumber'};
265 my @subscriptions = GetSubscriptionsId ($biblionumber);
266 my $itemcount = GetItemsCount($biblionumber);
267 my $holds = GetHolds ($biblionumber);
268 my @items = GetItemnumbersFromOrder( $ordernumber );
269 my $itemholds;
270 foreach my $item (@items){
271 my $nb = GetItemHolds($biblionumber, $item);
272 if ($nb){
273 $itemholds += $nb;
276 # if the biblio is not in other orders and if there is no items elsewhere and no subscriptions and no holds we can then show the link "Delete order and Biblio" see bug 5680
277 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
278 $line{items} = ($itemcount) - (scalar @items);
279 $line{left_item} = 1 if $line{items} >= 1;
280 $line{left_biblio} = 1 if $countbiblio > 1;
281 $line{biblios} = $countbiblio - 1;
282 $line{left_subscription} = 1 if scalar @subscriptions >= 1;
283 $line{subscriptions} = scalar @subscriptions;
284 ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
285 $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
286 $line{holds} = $holds;
287 $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
288 $line{order_received} = ( $qty == $order->{'quantityreceived'} );
289 $line{basketno} = $basketno;
290 $line{budget_name} = $budget->{budget_name};
291 $line{rrp} = sprintf( "%.2f", $line{'rrp'} );
292 $line{ecost} = sprintf( "%.2f", $line{'ecost'} );
293 $line{line_total} = sprintf( "%.2f", $line_total );
294 if ($line{uncertainprice}) {
295 $template->param( uncertainprices => 1 );
296 $line{rrp} .= ' (Uncertain)';
298 if ($line{'title'}){
299 my $volume = $order->{'volume'};
300 my $seriestitle = $order->{'seriestitle'};
301 $line{'title'} .= " / $seriestitle" if $seriestitle;
302 $line{'title'} .= " / $volume" if $volume;
303 } else {
304 $line{'title'} = "Deleted bibliographic notice, can't find title.";
306 push @books_loop, \%line;
309 my $total_est_gste;
310 my $total_est_gsti;
311 my $gist_est;
312 if ($gist){ # if we have GST
313 if ( $bookseller->{'listincgst'} ) { # if prices already includes GST
314 $total_rrp_gsti = $total_rrp; # we know $total_rrp_gsti
315 $total_rrp_gste = $total_rrp_gsti / ( $gist + 1 ); # and can reverse compute other values
316 $gist_rrp = $total_rrp_gsti - $total_rrp_gste; #
317 $total_est_gste = $total_rrp_gste - ( $total_rrp_gste * $discount );
318 $total_est_gsti = $total_rrp_est;
319 } else { # if prices does not include GST
320 $total_rrp_gste = $total_rrp; # then we use the common way to compute other values
321 $gist_rrp = $total_rrp_gste * $gist; #
322 $total_rrp_gsti = $total_rrp_gste + $gist_rrp; #
323 $total_est_gste = $total_rrp_est;
324 $total_est_gsti = $total_rrp_gsti - ( $total_rrp_gsti * $discount );
326 $gist_est = $gist_rrp - ( $gist_rrp * $discount );
327 } else {
328 $total_rrp_gsti = $total_rrp;
329 $total_est_gsti = $total_rrp_est;
332 my $contract = &GetContract($basket->{contractnumber});
333 my @orders = GetOrders($basketno);
335 my $borrower= GetMember('borrowernumber' => $loggedinuser);
336 my $budgets = GetBudgetHierarchy(q{},$borrower->{branchcode},$borrower->{borrowernumber});
337 my $has_budgets = 0;
338 foreach my $r (@{$budgets}) {
339 if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
340 next;
342 $has_budgets = 1;
343 last;
346 my @cancelledorders = GetCancelledOrders($basketno);
347 foreach (@cancelledorders) {
348 $_->{'line_total'} = sprintf("%.2f", $_->{'ecost'} * $_->{'quantity'});
351 $template->param(
352 basketno => $basketno,
353 basketname => $basket->{'basketname'},
354 basketnote => $basket->{note},
355 basketbooksellernote => $basket->{booksellernote},
356 basketcontractno => $basket->{contractnumber},
357 basketcontractname => $contract->{contractname},
358 creationdate => C4::Dates->new($basket->{creationdate},'iso')->output,
359 authorisedby => $basket->{authorisedby},
360 authorisedbyname => $basket->{authorisedbyname},
361 closedate => C4::Dates->new($basket->{closedate},'iso')->output,
362 active => $bookseller->{'active'},
363 booksellerid => $bookseller->{'id'},
364 name => $bookseller->{'name'},
365 entrydate => C4::Dates->new($results[0]->{'entrydate'},'iso')->output,
366 books_loop => \@books_loop,
367 cancelledorders_loop => \@cancelledorders,
368 gist_rate => sprintf( "%.2f", $gist * 100 ) . '%',
369 total_rrp_gste => sprintf( "%.2f", $total_rrp_gste ),
370 total_est_gste => sprintf( "%.2f", $total_est_gste ),
371 gist_est => sprintf( "%.2f", $gist_est ),
372 gist_rrp => sprintf( "%.2f", $gist_rrp ),
373 total_rrp_gsti => sprintf( "%.2f", $total_rrp_gsti ),
374 total_est_gsti => sprintf( "%.2f", $total_est_gsti ),
375 # currency => $bookseller->{'listprice'},
376 currency => $cur->{'currency'},
377 qty_total => $qty_total,
378 GST => $gist,
379 basketgroups => $basketgroups,
380 grouped => $basket->{basketgroupid},
381 unclosable => @orders ? 0 : 1,
382 has_budgets => $has_budgets,
386 output_html_with_http_headers $query, $cookie, $template->output;