Bug 10379 - Followup: add koha-rebuild-zebra -q to the man page
[koha.git] / acqui / basket.pl
blob7eff6e465ef746663a190b69e7787974efb95a8e
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::Debug;
33 use C4::Biblio;
34 use C4::Members qw/GetMember/; #needed for permissions checking for changing basketgroup of a basket
35 use C4::Items;
36 use C4::Suggestions;
37 use Date::Calc qw/Add_Delta_Days/;
39 =head1 NAME
41 basket.pl
43 =head1 DESCRIPTION
45 This script display all informations about basket for the supplier given
46 on input arg. Moreover, it allows us to add a new order for this supplier from
47 an existing record, a suggestion or a new record.
49 =head1 CGI PARAMETERS
51 =over 4
53 =item $basketno
55 The basket number.
57 =item booksellerid
59 the supplier this script have to display the basket.
61 =item order
63 =back
65 =cut
67 my $query = new CGI;
68 our $basketno = $query->param('basketno');
69 my $booksellerid = $query->param('booksellerid');
71 my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user(
73 template_name => "acqui/basket.tmpl",
74 query => $query,
75 type => "intranet",
76 authnotrequired => 0,
77 flagsrequired => { acquisition => 'order_manage' },
78 debug => 1,
82 my $basket = GetBasket($basketno);
84 # FIXME : what about the "discount" percentage?
85 # FIXME : the query->param('booksellerid') below is probably useless. The bookseller is always known from the basket
86 # if no booksellerid in parameter, get it from basket
87 # warn "=>".$basket->{booksellerid};
88 $booksellerid = $basket->{booksellerid} unless $booksellerid;
89 my ($bookseller) = GetBookSellerFromId($booksellerid);
90 my $op = $query->param('op');
91 if (!defined $op) {
92 $op = q{};
95 my $confirm_pref= C4::Context->preference("BasketConfirmations") || '1';
96 $template->param( skip_confirm_reopen => 1) if $confirm_pref eq '2';
98 if ( $op eq 'delete_confirm' ) {
99 my $basketno = $query->param('basketno');
100 DelBasket($basketno);
101 $template->param( delete_confirmed => 1 );
102 } elsif ( !$bookseller ) {
103 $template->param( NO_BOOKSELLER => 1 );
104 } elsif ( $op eq 'del_basket') {
105 $template->param( delete_confirm => 1 );
106 if ( C4::Context->preference("IndependentBranches") ) {
107 my $userenv = C4::Context->userenv;
108 unless ( $userenv->{flags} == 1 ) {
109 my $validtest = ( $basket->{creationdate} eq '' )
110 || ( $userenv->{branch} eq $basket->{branch} )
111 || ( $userenv->{branch} eq '' )
112 || ( $basket->{branch} eq '' );
113 unless ($validtest) {
114 print $query->redirect("../mainpage.pl");
115 exit 1;
119 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
120 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
121 my $contract = &GetContract($basket->{contractnumber});
122 $template->param(
123 basketno => $basketno,
124 basketname => $basket->{'basketname'},
125 basketnote => $basket->{note},
126 basketbooksellernote => $basket->{booksellernote},
127 basketcontractno => $basket->{contractnumber},
128 basketcontractname => $contract->{contractname},
129 creationdate => $basket->{creationdate},
130 authorisedby => $basket->{authorisedby},
131 authorisedbyname => $basket->{authorisedbyname},
132 closedate => $basket->{closedate},
133 deliveryplace => $basket->{deliveryplace},
134 billingplace => $basket->{billingplace},
135 active => $bookseller->{'active'},
136 booksellerid => $bookseller->{'id'},
137 name => $bookseller->{'name'},
138 address1 => $bookseller->{'address1'},
139 address2 => $bookseller->{'address2'},
140 address3 => $bookseller->{'address3'},
141 address4 => $bookseller->{'address4'},
143 } elsif ($op eq 'attachbasket' && $template->{'VARS'}->{'CAN_user_acquisition_group_manage'} == 1) {
144 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?basketno=' . $basket->{'basketno'} . '&op=attachbasket&booksellerid=' . $booksellerid);
145 # check if we have to "close" a basket before building page
146 } elsif ($op eq 'export') {
147 print $query->header(
148 -type => 'text/csv',
149 -attachment => 'basket' . $basket->{'basketno'} . '.csv',
151 print GetBasketAsCSV($query->param('basketno'), $query);
152 exit;
153 } elsif ($op eq 'close') {
154 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
155 if ($confirm) {
156 my $basketno = $query->param('basketno');
157 my $booksellerid = $query->param('booksellerid');
158 $basketno =~ /^\d+$/ and CloseBasket($basketno);
159 # if requested, create basket group, close it and attach the basket
160 if ($query->param('createbasketgroup')) {
161 my $branchcode;
162 if(C4::Context->userenv and C4::Context->userenv->{'branch'}
163 and C4::Context->userenv->{'branch'} ne "NO_LIBRARY_SET") {
164 $branchcode = C4::Context->userenv->{'branch'};
166 my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
167 booksellerid => $booksellerid,
168 deliveryplace => $branchcode,
169 billingplace => $branchcode,
170 closed => 1,
172 ModBasket( { basketno => $basketno,
173 basketgroupid => $basketgroupid } );
174 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
175 } else {
176 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
178 exit;
179 } else {
180 $template->param(confirm_close => "1",
181 booksellerid => $booksellerid,
182 basketno => $basket->{'basketno'},
183 basketname => $basket->{'basketname'},
184 basketgroupname => $basket->{'basketname'});
187 } elsif ($op eq 'reopen') {
188 my $basket;
189 $basket->{basketno} = $query->param('basketno');
190 $basket->{closedate} = undef;
191 ModBasket($basket);
192 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
193 } else {
194 # get librarian branch...
195 if ( C4::Context->preference("IndependentBranches") ) {
196 my $userenv = C4::Context->userenv;
197 unless ( $userenv->{flags} == 1 ) {
198 my $validtest = ( $basket->{creationdate} eq '' )
199 || ( $userenv->{branch} eq $basket->{branch} )
200 || ( $userenv->{branch} eq '' )
201 || ( $basket->{branch} eq '' );
202 unless ($validtest) {
203 print $query->redirect("../mainpage.pl");
204 exit 1;
208 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
209 my ($basketgroup, $basketgroups);
210 my $member = GetMember(borrowernumber => $loggedinuser);
211 if ($basket->{closedate} && haspermission({ acquisition => 'group_manage'} )) {
212 $basketgroups = GetBasketgroups($basket->{booksellerid});
213 for my $bg ( @{$basketgroups} ) {
214 if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
215 $bg->{default} = 1;
216 $basketgroup = $bg;
219 my %emptygroup = ( id => undef,
220 name => "No group");
221 if ( ! $basket->{basketgroupid} ) {
222 $emptygroup{default} = 1;
223 $emptygroup{nogroup} = 1;
225 unshift( @$basketgroups, \%emptygroup );
228 # if the basket is closed, calculate estimated delivery date
229 my $estimateddeliverydate;
230 if( $basket->{closedate} ) {
231 my ($year, $month, $day) = ($basket->{closedate} =~ /(\d+)-(\d+)-(\d+)/);
232 ($year, $month, $day) = Add_Delta_Days($year, $month, $day, $bookseller->{deliverytime});
233 $estimateddeliverydate = "$year-$month-$day";
236 # if new basket, pre-fill infos
237 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
238 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
239 $debug
240 and warn sprintf
241 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
242 $basket->{creationdate}, $basket->{authorisedby};
244 #to get active currency
245 my $cur = GetCurrency();
248 my @results = GetOrders( $basketno );
249 my @books_loop;
251 my @book_foot_loop;
252 my %foot;
253 my $total_quantity = 0;
254 my $total_gste = 0;
255 my $total_gsti = 0;
256 my $total_gstvalue = 0;
257 for my $order (@results) {
258 my $line = get_order_infos( $order, $bookseller);
259 if ( $line->{uncertainprice} ) {
260 $template->param( uncertainprices => 1 );
263 push @books_loop, $line;
265 $foot{$$line{gstgsti}}{gstgsti} = $$line{gstgsti};
266 $foot{$$line{gstgsti}}{gstvalue} += $$line{gstvalue};
267 $total_gstvalue += $$line{gstvalue};
268 $foot{$$line{gstgsti}}{quantity} += $$line{quantity};
269 $total_quantity += $$line{quantity};
270 $foot{$$line{gstgsti}}{totalgste} += $$line{totalgste};
271 $total_gste += $$line{totalgste};
272 $foot{$$line{gstgsti}}{totalgsti} += $$line{totalgsti};
273 $total_gsti += $$line{totalgsti};
276 push @book_foot_loop, map {$_} values %foot;
278 # Get cancelled orders
279 @results = GetCancelledOrders($basketno);
280 my @cancelledorders_loop;
281 for my $order (@results) {
282 my $line = get_order_infos( $order, $bookseller);
283 push @cancelledorders_loop, $line;
286 my $contract = &GetContract($basket->{contractnumber});
287 my @orders = GetOrders($basketno);
289 if ($basket->{basketgroupid}){
290 my $basketgroup = GetBasketgroup($basket->{basketgroupid});
291 for my $key (keys %$basketgroup ){
292 $basketgroup->{"basketgroup$key"} = delete $basketgroup->{$key};
294 $basketgroup->{basketgroupdeliveryplace} = C4::Branch::GetBranchName( $basketgroup->{basketgroupdeliveryplace} );
295 $basketgroup->{basketgroupbillingplace} = C4::Branch::GetBranchName( $basketgroup->{basketgroupbillingplace} );
296 $template->param(%$basketgroup);
298 my $borrower= GetMember('borrowernumber' => $loggedinuser);
299 my $budgets = GetBudgetHierarchy;
300 my $has_budgets = 0;
301 foreach my $r (@{$budgets}) {
302 if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
303 next;
305 next unless (CanUserUseBudget($loggedinuser, $r, $userflags));
307 $has_budgets = 1;
308 last;
311 my @cancelledorders = GetCancelledOrders($basketno);
312 foreach (@cancelledorders) {
313 $_->{'line_total'} = sprintf("%.2f", $_->{'ecost'} * $_->{'quantity'});
316 $template->param(
317 basketno => $basketno,
318 basketname => $basket->{'basketname'},
319 basketnote => $basket->{note},
320 basketbooksellernote => $basket->{booksellernote},
321 basketcontractno => $basket->{contractnumber},
322 basketcontractname => $contract->{contractname},
323 creationdate => $basket->{creationdate},
324 authorisedby => $basket->{authorisedby},
325 authorisedbyname => $basket->{authorisedbyname},
326 closedate => $basket->{closedate},
327 estimateddeliverydate=> $estimateddeliverydate,
328 deliveryplace => C4::Branch::GetBranchName( $basket->{deliveryplace} ),
329 billingplace => C4::Branch::GetBranchName( $basket->{billingplace} ),
330 active => $bookseller->{'active'},
331 booksellerid => $bookseller->{'id'},
332 name => $bookseller->{'name'},
333 books_loop => \@books_loop,
334 book_foot_loop => \@book_foot_loop,
335 cancelledorders_loop => \@cancelledorders,
336 total_quantity => $total_quantity,
337 total_gste => sprintf( "%.2f", $total_gste ),
338 total_gsti => sprintf( "%.2f", $total_gsti ),
339 total_gstvalue => sprintf( "%.2f", $total_gstvalue ),
340 currency => $cur->{'currency'},
341 listincgst => $bookseller->{listincgst},
342 basketgroups => $basketgroups,
343 basketgroup => $basketgroup,
344 grouped => $basket->{basketgroupid},
345 unclosable => @orders ? 0 : 1,
346 has_budgets => $has_budgets,
350 sub get_order_infos {
351 my $order = shift;
352 my $bookseller = shift;
353 my $qty = $order->{'quantity'} || 0;
354 if ( !defined $order->{quantityreceived} ) {
355 $order->{quantityreceived} = 0;
357 my $budget = GetBudget( $order->{'budget_id'} );
359 my %line = %{ $order };
360 $line{order_received} = ( $qty == $order->{'quantityreceived'} );
361 $line{basketno} = $basketno;
362 $line{budget_name} = $budget->{budget_name};
363 $line{rrp} = ConvertCurrency( $order->{'currency'}, $line{rrp} ); # FIXME from comm
364 if ( $bookseller->{'listincgst'} ) {
365 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} );
366 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
367 $line{rrpgste} = sprintf( "%.2f", $line{rrp} / ( 1 + ( $line{gstgsti} / 100 ) ) );
368 $line{gstgste} = sprintf( "%.2f", $line{gstgsti} / ( 1 + ( $line{gstgsti} / 100 ) ) );
369 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} );
370 $line{ecostgste} = sprintf( "%.2f", $line{ecost} / ( 1 + ( $line{gstgsti} / 100 ) ) );
371 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
372 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
373 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
374 } else {
375 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} * ( 1 + ( $line{gstrate} ) ) );
376 $line{rrpgste} = sprintf( "%.2f", $line{rrp} );
377 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
378 $line{gstgste} = sprintf( "%.2f", $line{gstrate} * 100 );
379 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} * ( 1 + ( $line{gstrate} ) ) );
380 $line{ecostgste} = sprintf( "%.2f", $line{ecost} );
381 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
382 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
383 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
386 if ( $line{uncertainprice} ) {
387 $line{rrpgste} .= ' (Uncertain)';
389 if ( $line{'title'} ) {
390 my $volume = $order->{'volume'};
391 my $seriestitle = $order->{'seriestitle'};
392 $line{'title'} .= " / $seriestitle" if $seriestitle;
393 $line{'title'} .= " / $volume" if $volume;
394 } else {
395 $line{'title'} = "Deleted bibliographic notice, can't find title.";
398 my $biblionumber = $order->{'biblionumber'};
399 my $countbiblio = CountBiblioInOrders($biblionumber);
400 my $ordernumber = $order->{'ordernumber'};
401 my @subscriptions = GetSubscriptionsId ($biblionumber);
402 my $itemcount = GetItemsCount($biblionumber);
403 my $holds = GetHolds ($biblionumber);
404 my @items = GetItemnumbersFromOrder( $ordernumber );
405 my $itemholds;
406 foreach my $item (@items){
407 my $nb = GetItemHolds($biblionumber, $item);
408 if ($nb){
409 $itemholds += $nb;
412 # 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
413 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
414 $line{items} = ($itemcount) - (scalar @items);
415 $line{left_item} = 1 if $line{items} >= 1;
416 $line{left_biblio} = 1 if $countbiblio > 1;
417 $line{biblios} = $countbiblio - 1;
418 $line{left_subscription} = 1 if scalar @subscriptions >= 1;
419 $line{subscriptions} = scalar @subscriptions;
420 ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
421 $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
422 $line{holds} = $holds;
423 $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
426 my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber});
427 $line{suggestionid} = $$suggestion{suggestionid};
428 $line{surnamesuggestedby} = $$suggestion{surnamesuggestedby};
429 $line{firstnamesuggestedby} = $$suggestion{firstnamesuggestedby};
431 return \%line;
434 output_html_with_http_headers $query, $cookie, $template->output;