Bug 11369 - Updating the jquery.cookie.js-plugin
[koha.git] / acqui / basket.pl
blob047ae84a1d3114766acf88b8e6162bc2ddcef7e6
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::Branch;
32 use C4::Bookseller qw( GetBookSellerFromId);
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 use C4::Suggestions;
38 use Date::Calc qw/Add_Delta_Days/;
40 =head1 NAME
42 basket.pl
44 =head1 DESCRIPTION
46 This script display all informations about basket for the supplier given
47 on input arg. Moreover, it allows us to add a new order for this supplier from
48 an existing record, a suggestion or a new record.
50 =head1 CGI PARAMETERS
52 =over 4
54 =item $basketno
56 The basket number.
58 =item booksellerid
60 the supplier this script have to display the basket.
62 =item order
64 =back
66 =cut
68 my $query = new CGI;
69 our $basketno = $query->param('basketno');
70 my $booksellerid = $query->param('booksellerid');
72 my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user(
74 template_name => "acqui/basket.tmpl",
75 query => $query,
76 type => "intranet",
77 authnotrequired => 0,
78 flagsrequired => { acquisition => 'order_manage' },
79 debug => 1,
83 my $basket = GetBasket($basketno);
84 $booksellerid = $basket->{booksellerid} unless $booksellerid;
85 my ($bookseller) = GetBookSellerFromId($booksellerid);
87 unless (CanUserManageBasket($loggedinuser, $basket, $userflags)) {
88 $template->param(
89 cannot_manage_basket => 1,
90 basketno => $basketno,
91 basketname => $basket->{basketname},
92 booksellerid => $booksellerid,
93 name => $bookseller->{name}
95 output_html_with_http_headers $query, $cookie, $template->output;
96 exit;
99 # FIXME : what about the "discount" percentage?
100 # FIXME : the query->param('booksellerid') below is probably useless. The bookseller is always known from the basket
101 # if no booksellerid in parameter, get it from basket
102 # warn "=>".$basket->{booksellerid};
103 my $op = $query->param('op');
104 if (!defined $op) {
105 $op = q{};
108 my $confirm_pref= C4::Context->preference("BasketConfirmations") || '1';
109 $template->param( skip_confirm_reopen => 1) if $confirm_pref eq '2';
111 if ( $op eq 'delete_confirm' ) {
112 my $basketno = $query->param('basketno');
113 my $delbiblio = $query->param('delbiblio');
114 my @orders = GetOrders($basketno);
115 #Delete all orders included in that basket, and all items received.
116 foreach my $myorder (@orders){
117 DelOrder($myorder->{biblionumber},$myorder->{ordernumber});
119 # if $delbiblio = 1, delete the records if possible
120 if ((defined $delbiblio)and ($delbiblio ==1)){
121 my @cannotdelbiblios ;
122 foreach my $myorder (@orders){
123 my $biblionumber = $myorder->{'biblionumber'};
124 my $countbiblio = CountBiblioInOrders($biblionumber);
125 my $ordernumber = $myorder->{'ordernumber'};
126 my $subscriptions = scalar GetSubscriptionsId ($biblionumber);
127 my $itemcount = GetItemsCount($biblionumber);
128 my $error;
129 if ($countbiblio == 0 && $itemcount == 0 && $subscriptions == 0) {
130 $error = DelBiblio($myorder->{biblionumber}) }
131 else {
132 push @cannotdelbiblios, {biblionumber=> ($myorder->{biblionumber}),
133 title=> $myorder->{'title'},
134 author=> $myorder->{'author'},
135 countbiblio=> $countbiblio,
136 itemcount=>$itemcount,
137 subscriptions=>$subscriptions};
139 if ($error) {
140 push @cannotdelbiblios, {biblionumber=> ($myorder->{biblionumber}),
141 title=> $myorder->{'title'},
142 author=> $myorder->{'author'},
143 othererror=> $error};
146 $template->param( cannotdelbiblios => \@cannotdelbiblios );
148 # delete the basket
149 DelBasket($basketno,);
150 $template->param( delete_confirmed => 1 );
151 } elsif ( !$bookseller ) {
152 $template->param( NO_BOOKSELLER => 1 );
153 } elsif ( $op eq 'del_basket') {
154 $template->param( delete_confirm => 1 );
155 if ( C4::Context->preference("IndependentBranches") ) {
156 my $userenv = C4::Context->userenv;
157 unless ( C4::Context->IsSuperLibrarian() ) {
158 my $validtest = ( $basket->{creationdate} eq '' )
159 || ( $userenv->{branch} eq $basket->{branch} )
160 || ( $userenv->{branch} eq '' )
161 || ( $basket->{branch} eq '' );
162 unless ($validtest) {
163 print $query->redirect("../mainpage.pl");
164 exit 1;
168 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
169 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
170 my $contract = &GetContract($basket->{contractnumber});
171 $template->param(
172 basketno => $basketno,
173 basketname => $basket->{'basketname'},
174 basketnote => $basket->{note},
175 basketbooksellernote => $basket->{booksellernote},
176 basketcontractno => $basket->{contractnumber},
177 basketcontractname => $contract->{contractname},
178 creationdate => $basket->{creationdate},
179 authorisedby => $basket->{authorisedby},
180 authorisedbyname => $basket->{authorisedbyname},
181 closedate => $basket->{closedate},
182 deliveryplace => $basket->{deliveryplace},
183 billingplace => $basket->{billingplace},
184 active => $bookseller->{'active'},
185 booksellerid => $bookseller->{'id'},
186 name => $bookseller->{'name'},
187 address1 => $bookseller->{'address1'},
188 address2 => $bookseller->{'address2'},
189 address3 => $bookseller->{'address3'},
190 address4 => $bookseller->{'address4'},
192 } elsif ($op eq 'attachbasket' && $template->{'VARS'}->{'CAN_user_acquisition_group_manage'} == 1) {
193 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?basketno=' . $basket->{'basketno'} . '&op=attachbasket&booksellerid=' . $booksellerid);
194 # check if we have to "close" a basket before building page
195 } elsif ($op eq 'export') {
196 print $query->header(
197 -type => 'text/csv',
198 -attachment => 'basket' . $basket->{'basketno'} . '.csv',
200 print GetBasketAsCSV($query->param('basketno'), $query);
201 exit;
202 } elsif ($op eq 'close') {
203 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
204 if ($confirm) {
205 my $basketno = $query->param('basketno');
206 my $booksellerid = $query->param('booksellerid');
207 $basketno =~ /^\d+$/ and CloseBasket($basketno);
208 # if requested, create basket group, close it and attach the basket
209 if ($query->param('createbasketgroup')) {
210 my $branchcode;
211 if(C4::Context->userenv and C4::Context->userenv->{'branch'}
212 and C4::Context->userenv->{'branch'} ne "NO_LIBRARY_SET") {
213 $branchcode = C4::Context->userenv->{'branch'};
215 my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
216 booksellerid => $booksellerid,
217 deliveryplace => $branchcode,
218 billingplace => $branchcode,
219 closed => 1,
221 ModBasket( { basketno => $basketno,
222 basketgroupid => $basketgroupid } );
223 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
224 } else {
225 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
227 exit;
228 } else {
229 $template->param(
230 confirm_close => "1",
231 booksellerid => $booksellerid,
232 basketno => $basket->{'basketno'},
233 basketname => $basket->{'basketname'},
234 basketgroupname => $basket->{'basketname'},
237 } elsif ($op eq 'reopen') {
238 ReopenBasket($query->param('basketno'));
239 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
240 } elsif ( $op eq 'mod_users' ) {
241 my $basketusers_ids = $query->param('basketusers_ids');
242 my @basketusers = split( /:/, $basketusers_ids );
243 ModBasketUsers($basketno, @basketusers);
244 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
245 exit;
246 } elsif ( $op eq 'mod_branch' ) {
247 my $branch = $query->param('branch');
248 $branch = undef if(defined $branch and $branch eq '');
249 ModBasket({
250 basketno => $basket->{basketno},
251 branch => $branch
253 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
254 exit;
255 } else {
256 my @branches_loop;
257 # get librarian branch...
258 if ( C4::Context->preference("IndependentBranches") ) {
259 my $userenv = C4::Context->userenv;
260 unless ( C4::Context->IsSuperLibrarian() ) {
261 my $validtest = ( $basket->{creationdate} eq '' )
262 || ( $userenv->{branch} eq $basket->{branch} )
263 || ( $userenv->{branch} eq '' )
264 || ( $basket->{branch} eq '' );
265 unless ($validtest) {
266 print $query->redirect("../mainpage.pl");
267 exit 1;
270 if (!defined $basket->{branch} or $basket->{branch} eq $userenv->{branch}) {
271 push @branches_loop, {
272 branchcode => $userenv->{branch},
273 branchname => $userenv->{branchname},
274 selected => 1,
277 } else {
278 # get branches
279 my $branches = C4::Branch::GetBranches;
280 my @branchcodes = sort {
281 $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname}
282 } keys %$branches;
283 foreach my $branch (@branchcodes) {
284 my $selected = 0;
285 if (defined $basket->{branch}) {
286 $selected = 1 if $branch eq $basket->{branch};
287 } else {
288 $selected = 1 if $branch eq C4::Context->userenv->{branch};
290 push @branches_loop, {
291 branchcode => $branch,
292 branchname => $branches->{$branch}->{branchname},
293 selected => $selected
298 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
299 my ($basketgroup, $basketgroups);
300 my $staffuser = GetMember(borrowernumber => $loggedinuser);
301 if ($basket->{closedate} && haspermission($staffuser->{userid}, { acquisition => 'group_manage'} )) {
302 $basketgroups = GetBasketgroups($basket->{booksellerid});
303 for my $bg ( @{$basketgroups} ) {
304 if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
305 $bg->{default} = 1;
306 $basketgroup = $bg;
311 # if the basket is closed, calculate estimated delivery date
312 my $estimateddeliverydate;
313 if( $basket->{closedate} ) {
314 my ($year, $month, $day) = ($basket->{closedate} =~ /(\d+)-(\d+)-(\d+)/);
315 ($year, $month, $day) = Add_Delta_Days($year, $month, $day, $bookseller->{deliverytime});
316 $estimateddeliverydate = "$year-$month-$day";
319 # if new basket, pre-fill infos
320 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
321 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
322 $debug
323 and warn sprintf
324 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
325 $basket->{creationdate}, $basket->{authorisedby};
327 my @basketusers_ids = GetBasketUsers($basketno);
328 my @basketusers;
329 foreach my $basketuser_id (@basketusers_ids) {
330 my $basketuser = GetMember(borrowernumber => $basketuser_id);
331 push @basketusers, $basketuser if $basketuser;
334 #to get active currency
335 my $cur = GetCurrency();
338 my @results = GetOrders( $basketno );
339 my @books_loop;
341 my @book_foot_loop;
342 my %foot;
343 my $total_quantity = 0;
344 my $total_gste = 0;
345 my $total_gsti = 0;
346 my $total_gstvalue = 0;
347 for my $order (@results) {
348 my $line = get_order_infos( $order, $bookseller);
349 if ( $line->{uncertainprice} ) {
350 $template->param( uncertainprices => 1 );
353 push @books_loop, $line;
355 $foot{$$line{gstgsti}}{gstgsti} = $$line{gstgsti};
356 $foot{$$line{gstgsti}}{gstvalue} += $$line{gstvalue};
357 $total_gstvalue += $$line{gstvalue};
358 $foot{$$line{gstgsti}}{quantity} += $$line{quantity};
359 $total_quantity += $$line{quantity};
360 $foot{$$line{gstgsti}}{totalgste} += $$line{totalgste};
361 $total_gste += $$line{totalgste};
362 $foot{$$line{gstgsti}}{totalgsti} += $$line{totalgsti};
363 $total_gsti += $$line{totalgsti};
366 push @book_foot_loop, map {$_} values %foot;
368 # Get cancelled orders
369 @results = GetCancelledOrders($basketno);
370 my @cancelledorders_loop;
371 for my $order (@results) {
372 my $line = get_order_infos( $order, $bookseller);
373 push @cancelledorders_loop, $line;
376 my $contract = &GetContract($basket->{contractnumber});
377 my @orders = GetOrders($basketno);
379 if ($basket->{basketgroupid}){
380 $basketgroup = GetBasketgroup($basket->{basketgroupid});
381 $basketgroup->{deliveryplacename} = C4::Branch::GetBranchName( $basketgroup->{deliveryplace} );
382 $basketgroup->{billingplacename} = C4::Branch::GetBranchName( $basketgroup->{billingplace} );
384 my $borrower= GetMember('borrowernumber' => $loggedinuser);
385 my $budgets = GetBudgetHierarchy;
386 my $has_budgets = 0;
387 foreach my $r (@{$budgets}) {
388 if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
389 next;
391 next unless (CanUserUseBudget($loggedinuser, $r, $userflags));
393 $has_budgets = 1;
394 last;
397 $template->param(
398 basketno => $basketno,
399 basketname => $basket->{'basketname'},
400 basketbranchname => C4::Branch::GetBranchName($basket->{branch}),
401 basketnote => $basket->{note},
402 basketbooksellernote => $basket->{booksellernote},
403 basketcontractno => $basket->{contractnumber},
404 basketcontractname => $contract->{contractname},
405 branches_loop => \@branches_loop,
406 creationdate => $basket->{creationdate},
407 authorisedby => $basket->{authorisedby},
408 authorisedbyname => $basket->{authorisedbyname},
409 basketusers_ids => join(':', @basketusers_ids),
410 basketusers => \@basketusers,
411 closedate => $basket->{closedate},
412 estimateddeliverydate=> $estimateddeliverydate,
413 deliveryplace => C4::Branch::GetBranchName( $basket->{deliveryplace} ),
414 billingplace => C4::Branch::GetBranchName( $basket->{billingplace} ),
415 active => $bookseller->{'active'},
416 booksellerid => $bookseller->{'id'},
417 name => $bookseller->{'name'},
418 books_loop => \@books_loop,
419 book_foot_loop => \@book_foot_loop,
420 cancelledorders_loop => \@cancelledorders_loop,
421 total_quantity => $total_quantity,
422 total_gste => sprintf( "%.2f", $total_gste ),
423 total_gsti => sprintf( "%.2f", $total_gsti ),
424 total_gstvalue => sprintf( "%.2f", $total_gstvalue ),
425 currency => $cur->{'currency'},
426 listincgst => $bookseller->{listincgst},
427 basketgroups => $basketgroups,
428 basketgroup => $basketgroup,
429 grouped => $basket->{basketgroupid},
430 unclosable => @orders ? 0 : 1,
431 has_budgets => $has_budgets,
435 sub get_order_infos {
436 my $order = shift;
437 my $bookseller = shift;
438 my $qty = $order->{'quantity'} || 0;
439 if ( !defined $order->{quantityreceived} ) {
440 $order->{quantityreceived} = 0;
442 my $budget = GetBudget( $order->{'budget_id'} );
444 my %line = %{ $order };
445 $line{order_received} = ( $qty == $order->{'quantityreceived'} );
446 $line{basketno} = $basketno;
447 $line{budget_name} = $budget->{budget_name};
448 $line{rrp} = ConvertCurrency( $order->{'currency'}, $line{rrp} ); # FIXME from comm
449 if ( $bookseller->{'listincgst'} ) {
450 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} );
451 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
452 $line{rrpgste} = sprintf( "%.2f", $line{rrp} / ( 1 + ( $line{gstgsti} / 100 ) ) );
453 $line{gstgste} = sprintf( "%.2f", $line{gstgsti} / ( 1 + ( $line{gstgsti} / 100 ) ) );
454 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} );
455 $line{ecostgste} = sprintf( "%.2f", $line{ecost} / ( 1 + ( $line{gstgsti} / 100 ) ) );
456 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
457 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
458 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
459 } else {
460 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} * ( 1 + ( $line{gstrate} ) ) );
461 $line{rrpgste} = sprintf( "%.2f", $line{rrp} );
462 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
463 $line{gstgste} = sprintf( "%.2f", $line{gstrate} * 100 );
464 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} * ( 1 + ( $line{gstrate} ) ) );
465 $line{ecostgste} = sprintf( "%.2f", $line{ecost} );
466 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
467 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
468 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
471 if ( $line{uncertainprice} ) {
472 $line{rrpgste} .= ' (Uncertain)';
474 if ( $line{'title'} ) {
475 my $volume = $order->{'volume'};
476 my $seriestitle = $order->{'seriestitle'};
477 $line{'title'} .= " / $seriestitle" if $seriestitle;
478 $line{'title'} .= " / $volume" if $volume;
479 } else {
480 $line{'title'} = "Deleted bibliographic notice, can't find title.";
483 my $biblionumber = $order->{'biblionumber'};
484 my $countbiblio = CountBiblioInOrders($biblionumber);
485 my $ordernumber = $order->{'ordernumber'};
486 my @subscriptions = GetSubscriptionsId ($biblionumber);
487 my $itemcount = GetItemsCount($biblionumber);
488 my $holds = GetHolds ($biblionumber);
489 my @items = GetItemnumbersFromOrder( $ordernumber );
490 my $itemholds;
491 foreach my $item (@items){
492 my $nb = GetItemHolds($biblionumber, $item);
493 if ($nb){
494 $itemholds += $nb;
497 # 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
498 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
499 $line{items} = ($itemcount) - (scalar @items);
500 $line{left_item} = 1 if $line{items} >= 1;
501 $line{left_biblio} = 1 if $countbiblio > 1;
502 $line{biblios} = $countbiblio - 1;
503 $line{left_subscription} = 1 if scalar @subscriptions >= 1;
504 $line{subscriptions} = scalar @subscriptions;
505 ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
506 $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
507 $line{holds} = $holds;
508 $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
511 my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber});
512 $line{suggestionid} = $$suggestion{suggestionid};
513 $line{surnamesuggestedby} = $$suggestion{surnamesuggestedby};
514 $line{firstnamesuggestedby} = $$suggestion{firstnamesuggestedby};
516 foreach my $key (qw(transferred_from transferred_to)) {
517 if ($line{$key}) {
518 my $order = GetOrder($line{$key});
519 my $basket = GetBasket($order->{basketno});
520 my $bookseller = GetBookSellerFromId($basket->{booksellerid});
521 $line{$key} = {
522 order => $order,
523 basket => $basket,
524 bookseller => $bookseller,
525 timestamp => $line{$key . '_timestamp'},
530 return \%line;
533 output_html_with_http_headers $query, $cookie, $template->output;