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
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.
32 use C4::Bookseller qw( GetBookSellerFromId);
35 use C4::Members qw/GetMember/; #needed for permissions checking for changing basketgroup of a basket
38 use Date::Calc qw/Add_Delta_Days/;
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.
60 the supplier this script have to display the basket.
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",
78 flagsrequired => { acquisition => 'order_manage' },
83 my $basket = GetBasket($basketno);
84 $booksellerid = $basket->{booksellerid} unless $booksellerid;
85 my ($bookseller) = GetBookSellerFromId($booksellerid);
87 unless (CanUserManageBasket($loggedinuser, $basket, $userflags)) {
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;
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');
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);
129 if ($countbiblio == 0 && $itemcount == 0 && $subscriptions == 0) {
130 $error = DelBiblio($myorder->{biblionumber}) }
132 push @cannotdelbiblios, {biblionumber=> ($myorder->{biblionumber}),
133 title=> $myorder->{'title'},
134 author=> $myorder->{'author'},
135 countbiblio=> $countbiblio,
136 itemcount=>$itemcount,
137 subscriptions=>$subscriptions};
140 push @cannotdelbiblios, {biblionumber=> ($myorder->{biblionumber}),
141 title=> $myorder->{'title'},
142 author=> $myorder->{'author'},
143 othererror=> $error};
146 $template->param( cannotdelbiblios => \@cannotdelbiblios );
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");
168 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
169 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
170 my $contract = &GetContract($basket->{contractnumber});
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(
198 -attachment => 'basket' . $basket->{'basketno'} . '.csv',
200 print GetBasketAsCSV($query->param('basketno'), $query);
202 } elsif ($op eq 'close') {
203 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
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')) {
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,
221 ModBasket( { basketno => $basketno,
222 basketgroupid => $basketgroupid } );
223 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
225 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
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");
246 } elsif ( $op eq 'mod_branch' ) {
247 my $branch = $query->param('branch');
248 $branch = undef if(defined $branch and $branch eq '');
250 basketno => $basket->{basketno},
253 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
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");
270 if (!defined $basket->{branch} or $basket->{branch} eq $userenv->{branch}) {
271 push @branches_loop, {
272 branchcode => $userenv->{branch},
273 branchname => $userenv->{branchname},
279 my $branches = C4::Branch::GetBranches;
280 my @branchcodes = sort {
281 $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname}
283 foreach my $branch (@branchcodes) {
285 if (defined $basket->{branch}) {
286 $selected = 1 if $branch eq $basket->{branch};
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}){
309 my %emptygroup = ( id => undef,
311 if ( ! $basket->{basketgroupid} ) {
312 $emptygroup{default} = 1;
313 $emptygroup{nogroup} = 1;
315 unshift( @$basketgroups, \%emptygroup );
318 # if the basket is closed, calculate estimated delivery date
319 my $estimateddeliverydate;
320 if( $basket->{closedate} ) {
321 my ($year, $month, $day) = ($basket->{closedate} =~ /(\d+)-(\d+)-(\d+)/);
322 ($year, $month, $day) = Add_Delta_Days($year, $month, $day, $bookseller->{deliverytime});
323 $estimateddeliverydate = "$year-$month-$day";
326 # if new basket, pre-fill infos
327 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
328 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
331 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
332 $basket->{creationdate}, $basket->{authorisedby};
334 my @basketusers_ids = GetBasketUsers($basketno);
336 foreach my $basketuser_id (@basketusers_ids) {
337 my $basketuser = GetMember(borrowernumber => $basketuser_id);
338 push @basketusers, $basketuser if $basketuser;
341 #to get active currency
342 my $cur = GetCurrency();
345 my @results = GetOrders( $basketno );
350 my $total_quantity = 0;
353 my $total_gstvalue = 0;
354 for my $order (@results) {
355 my $line = get_order_infos( $order, $bookseller);
356 if ( $line->{uncertainprice} ) {
357 $template->param( uncertainprices => 1 );
360 push @books_loop, $line;
362 $foot{$$line{gstgsti}}{gstgsti} = $$line{gstgsti};
363 $foot{$$line{gstgsti}}{gstvalue} += $$line{gstvalue};
364 $total_gstvalue += $$line{gstvalue};
365 $foot{$$line{gstgsti}}{quantity} += $$line{quantity};
366 $total_quantity += $$line{quantity};
367 $foot{$$line{gstgsti}}{totalgste} += $$line{totalgste};
368 $total_gste += $$line{totalgste};
369 $foot{$$line{gstgsti}}{totalgsti} += $$line{totalgsti};
370 $total_gsti += $$line{totalgsti};
373 push @book_foot_loop, map {$_} values %foot;
375 # Get cancelled orders
376 @results = GetCancelledOrders($basketno);
377 my @cancelledorders_loop;
378 for my $order (@results) {
379 my $line = get_order_infos( $order, $bookseller);
380 push @cancelledorders_loop, $line;
383 my $contract = &GetContract($basket->{contractnumber});
384 my @orders = GetOrders($basketno);
386 if ($basket->{basketgroupid}){
387 $basketgroup = GetBasketgroup($basket->{basketgroupid});
388 $basketgroup->{deliveryplacename} = C4::Branch::GetBranchName( $basketgroup->{deliveryplace} );
389 $basketgroup->{billingplacename} = C4::Branch::GetBranchName( $basketgroup->{billingplace} );
391 my $borrower= GetMember('borrowernumber' => $loggedinuser);
392 my $budgets = GetBudgetHierarchy;
394 foreach my $r (@{$budgets}) {
395 if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
398 next unless (CanUserUseBudget($loggedinuser, $r, $userflags));
405 basketno => $basketno,
406 basketname => $basket->{'basketname'},
407 basketbranchname => C4::Branch::GetBranchName($basket->{branch}),
408 basketnote => $basket->{note},
409 basketbooksellernote => $basket->{booksellernote},
410 basketcontractno => $basket->{contractnumber},
411 basketcontractname => $contract->{contractname},
412 branches_loop => \@branches_loop,
413 creationdate => $basket->{creationdate},
414 authorisedby => $basket->{authorisedby},
415 authorisedbyname => $basket->{authorisedbyname},
416 basketusers_ids => join(':', @basketusers_ids),
417 basketusers => \@basketusers,
418 closedate => $basket->{closedate},
419 estimateddeliverydate=> $estimateddeliverydate,
420 deliveryplace => C4::Branch::GetBranchName( $basket->{deliveryplace} ),
421 billingplace => C4::Branch::GetBranchName( $basket->{billingplace} ),
422 active => $bookseller->{'active'},
423 booksellerid => $bookseller->{'id'},
424 name => $bookseller->{'name'},
425 books_loop => \@books_loop,
426 book_foot_loop => \@book_foot_loop,
427 cancelledorders_loop => \@cancelledorders_loop,
428 total_quantity => $total_quantity,
429 total_gste => sprintf( "%.2f", $total_gste ),
430 total_gsti => sprintf( "%.2f", $total_gsti ),
431 total_gstvalue => sprintf( "%.2f", $total_gstvalue ),
432 currency => $cur->{'currency'},
433 listincgst => $bookseller->{listincgst},
434 basketgroups => $basketgroups,
435 basketgroup => $basketgroup,
436 grouped => $basket->{basketgroupid},
437 unclosable => @orders ? 0 : 1,
438 has_budgets => $has_budgets,
442 sub get_order_infos {
444 my $bookseller = shift;
445 my $qty = $order->{'quantity'} || 0;
446 if ( !defined $order->{quantityreceived} ) {
447 $order->{quantityreceived} = 0;
449 my $budget = GetBudget( $order->{'budget_id'} );
451 my %line = %{ $order };
452 $line{order_received} = ( $qty == $order->{'quantityreceived'} );
453 $line{basketno} = $basketno;
454 $line{budget_name} = $budget->{budget_name};
455 $line{rrp} = ConvertCurrency( $order->{'currency'}, $line{rrp} ); # FIXME from comm
456 if ( $bookseller->{'listincgst'} ) {
457 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} );
458 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
459 $line{rrpgste} = sprintf( "%.2f", $line{rrp} / ( 1 + ( $line{gstgsti} / 100 ) ) );
460 $line{gstgste} = sprintf( "%.2f", $line{gstgsti} / ( 1 + ( $line{gstgsti} / 100 ) ) );
461 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} );
462 $line{ecostgste} = sprintf( "%.2f", $line{ecost} / ( 1 + ( $line{gstgsti} / 100 ) ) );
463 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
464 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
465 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
467 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} * ( 1 + ( $line{gstrate} ) ) );
468 $line{rrpgste} = sprintf( "%.2f", $line{rrp} );
469 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
470 $line{gstgste} = sprintf( "%.2f", $line{gstrate} * 100 );
471 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} * ( 1 + ( $line{gstrate} ) ) );
472 $line{ecostgste} = sprintf( "%.2f", $line{ecost} );
473 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
474 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
475 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
478 if ( $line{uncertainprice} ) {
479 $line{rrpgste} .= ' (Uncertain)';
481 if ( $line{'title'} ) {
482 my $volume = $order->{'volume'};
483 my $seriestitle = $order->{'seriestitle'};
484 $line{'title'} .= " / $seriestitle" if $seriestitle;
485 $line{'title'} .= " / $volume" if $volume;
487 $line{'title'} = "Deleted bibliographic notice, can't find title.";
490 my $biblionumber = $order->{'biblionumber'};
491 my $countbiblio = CountBiblioInOrders($biblionumber);
492 my $ordernumber = $order->{'ordernumber'};
493 my @subscriptions = GetSubscriptionsId ($biblionumber);
494 my $itemcount = GetItemsCount($biblionumber);
495 my $holds = GetHolds ($biblionumber);
496 my @items = GetItemnumbersFromOrder( $ordernumber );
498 foreach my $item (@items){
499 my $nb = GetItemHolds($biblionumber, $item);
504 # 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
505 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
506 $line{items} = ($itemcount) - (scalar @items);
507 $line{left_item} = 1 if $line{items} >= 1;
508 $line{left_biblio} = 1 if $countbiblio > 1;
509 $line{biblios} = $countbiblio - 1;
510 $line{left_subscription} = 1 if scalar @subscriptions >= 1;
511 $line{subscriptions} = scalar @subscriptions;
512 ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
513 $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
514 $line{holds} = $holds;
515 $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
518 my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber});
519 $line{suggestionid} = $$suggestion{suggestionid};
520 $line{surnamesuggestedby} = $$suggestion{surnamesuggestedby};
521 $line{firstnamesuggestedby} = $$suggestion{firstnamesuggestedby};
523 foreach my $key (qw(transferred_from transferred_to)) {
525 my $order = GetOrder($line{$key});
526 my $basket = GetBasket($order->{basketno});
527 my $bookseller = GetBookSellerFromId($basket->{booksellerid});
531 bookseller => $bookseller,
532 timestamp => $line{$key . '_timestamp'},
540 output_html_with_http_headers $query, $cookie, $template->output;