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});
118 warn "suppression de ".$myorder->{biblionumber}.' '.$myorder->{ordernumber};
120 # if $delbiblio = 1, delete the records if possible
121 if ((defined $delbiblio)and ($delbiblio ==1)){
122 foreach my $myorder (@orders){
123 my $biblionumber = $myorder->{'biblionumber'};
124 my $countbiblio = CountBiblioInOrders($biblionumber);
125 my $ordernumber = $myorder->{'ordernumber'};
126 my @subscriptions = GetSubscriptionsId ($biblionumber);
127 my $itemcount = GetItemsCount($biblionumber);
128 DelBiblio($myorder->{biblionumber}) if ($countbiblio == 0 && $itemcount == 0 && !(@subscriptions));
129 warn "suppression de la notice ".$myorder->{biblionumber}};
133 DelBasket($basketno,);
134 $template->param( delete_confirmed => 1 );
135 } elsif ( !$bookseller ) {
136 $template->param( NO_BOOKSELLER => 1 );
137 } elsif ( $op eq 'del_basket') {
138 $template->param( delete_confirm => 1 );
139 if ( C4::Context->preference("IndependentBranches") ) {
140 my $userenv = C4::Context->userenv;
141 unless ( $userenv->{flags} == 1 ) {
142 my $validtest = ( $basket->{creationdate} eq '' )
143 || ( $userenv->{branch} eq $basket->{branch} )
144 || ( $userenv->{branch} eq '' )
145 || ( $basket->{branch} eq '' );
146 unless ($validtest) {
147 print $query->redirect("../mainpage.pl");
152 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
153 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
154 my $contract = &GetContract($basket->{contractnumber});
156 basketno => $basketno,
157 basketname => $basket->{'basketname'},
158 basketnote => $basket->{note},
159 basketbooksellernote => $basket->{booksellernote},
160 basketcontractno => $basket->{contractnumber},
161 basketcontractname => $contract->{contractname},
162 creationdate => $basket->{creationdate},
163 authorisedby => $basket->{authorisedby},
164 authorisedbyname => $basket->{authorisedbyname},
165 closedate => $basket->{closedate},
166 deliveryplace => $basket->{deliveryplace},
167 billingplace => $basket->{billingplace},
168 active => $bookseller->{'active'},
169 booksellerid => $bookseller->{'id'},
170 name => $bookseller->{'name'},
171 address1 => $bookseller->{'address1'},
172 address2 => $bookseller->{'address2'},
173 address3 => $bookseller->{'address3'},
174 address4 => $bookseller->{'address4'},
176 } elsif ($op eq 'attachbasket' && $template->{'VARS'}->{'CAN_user_acquisition_group_manage'} == 1) {
177 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?basketno=' . $basket->{'basketno'} . '&op=attachbasket&booksellerid=' . $booksellerid);
178 # check if we have to "close" a basket before building page
179 } elsif ($op eq 'export') {
180 print $query->header(
182 -attachment => 'basket' . $basket->{'basketno'} . '.csv',
184 print GetBasketAsCSV($query->param('basketno'), $query);
186 } elsif ($op eq 'close') {
187 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
189 my $basketno = $query->param('basketno');
190 my $booksellerid = $query->param('booksellerid');
191 $basketno =~ /^\d+$/ and CloseBasket($basketno);
192 # if requested, create basket group, close it and attach the basket
193 if ($query->param('createbasketgroup')) {
195 if(C4::Context->userenv and C4::Context->userenv->{'branch'}
196 and C4::Context->userenv->{'branch'} ne "NO_LIBRARY_SET") {
197 $branchcode = C4::Context->userenv->{'branch'};
199 my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
200 booksellerid => $booksellerid,
201 deliveryplace => $branchcode,
202 billingplace => $branchcode,
205 ModBasket( { basketno => $basketno,
206 basketgroupid => $basketgroupid } );
207 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
209 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
214 confirm_close => "1",
215 booksellerid => $booksellerid,
216 basketno => $basket->{'basketno'},
217 basketname => $basket->{'basketname'},
218 basketgroupname => $basket->{'basketname'},
221 } elsif ($op eq 'reopen') {
222 ReopenBasket($query->param('basketno'));
223 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
224 } elsif ( $op eq 'mod_users' ) {
225 my $basketusers_ids = $query->param('basketusers_ids');
226 my @basketusers = split( /:/, $basketusers_ids );
227 ModBasketUsers($basketno, @basketusers);
228 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
230 } elsif ( $op eq 'mod_branch' ) {
231 my $branch = $query->param('branch');
232 $branch = undef if(defined $branch and $branch eq '');
234 basketno => $basket->{basketno},
237 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
241 # get librarian branch...
242 if ( C4::Context->preference("IndependentBranches") ) {
243 my $userenv = C4::Context->userenv;
244 unless ( $userenv->{flags} == 1 ) {
245 my $validtest = ( $basket->{creationdate} eq '' )
246 || ( $userenv->{branch} eq $basket->{branch} )
247 || ( $userenv->{branch} eq '' )
248 || ( $basket->{branch} eq '' );
249 unless ($validtest) {
250 print $query->redirect("../mainpage.pl");
254 if (!defined $basket->{branch} or $basket->{branch} eq $userenv->{branch}) {
255 push @branches_loop, {
256 branchcode => $userenv->{branch},
257 branchname => $userenv->{branchname},
263 my $branches = C4::Branch::GetBranches;
264 my @branchcodes = sort {
265 $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname}
267 foreach my $branch (@branchcodes) {
269 if (defined $basket->{branch}) {
270 $selected = 1 if $branch eq $basket->{branch};
272 $selected = 1 if $branch eq C4::Context->userenv->{branch};
274 push @branches_loop, {
275 branchcode => $branch,
276 branchname => $branches->{$branch}->{branchname},
277 selected => $selected
282 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
283 my ($basketgroup, $basketgroups);
284 my $staffuser = GetMember(borrowernumber => $loggedinuser);
285 if ($basket->{closedate} && haspermission($staffuser->{userid}, { acquisition => 'group_manage'} )) {
286 $basketgroups = GetBasketgroups($basket->{booksellerid});
287 for my $bg ( @{$basketgroups} ) {
288 if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
293 my %emptygroup = ( id => undef,
295 if ( ! $basket->{basketgroupid} ) {
296 $emptygroup{default} = 1;
297 $emptygroup{nogroup} = 1;
299 unshift( @$basketgroups, \%emptygroup );
302 # if the basket is closed, calculate estimated delivery date
303 my $estimateddeliverydate;
304 if( $basket->{closedate} ) {
305 my ($year, $month, $day) = ($basket->{closedate} =~ /(\d+)-(\d+)-(\d+)/);
306 ($year, $month, $day) = Add_Delta_Days($year, $month, $day, $bookseller->{deliverytime});
307 $estimateddeliverydate = "$year-$month-$day";
310 # if new basket, pre-fill infos
311 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
312 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
315 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
316 $basket->{creationdate}, $basket->{authorisedby};
318 my @basketusers_ids = GetBasketUsers($basketno);
320 foreach my $basketuser_id (@basketusers_ids) {
321 my $basketuser = GetMember(borrowernumber => $basketuser_id);
322 push @basketusers, $basketuser if $basketuser;
325 #to get active currency
326 my $cur = GetCurrency();
329 my @results = GetOrders( $basketno );
334 my $total_quantity = 0;
337 my $total_gstvalue = 0;
338 for my $order (@results) {
339 my $line = get_order_infos( $order, $bookseller);
340 if ( $line->{uncertainprice} ) {
341 $template->param( uncertainprices => 1 );
344 push @books_loop, $line;
346 $foot{$$line{gstgsti}}{gstgsti} = $$line{gstgsti};
347 $foot{$$line{gstgsti}}{gstvalue} += $$line{gstvalue};
348 $total_gstvalue += $$line{gstvalue};
349 $foot{$$line{gstgsti}}{quantity} += $$line{quantity};
350 $total_quantity += $$line{quantity};
351 $foot{$$line{gstgsti}}{totalgste} += $$line{totalgste};
352 $total_gste += $$line{totalgste};
353 $foot{$$line{gstgsti}}{totalgsti} += $$line{totalgsti};
354 $total_gsti += $$line{totalgsti};
357 push @book_foot_loop, map {$_} values %foot;
359 # Get cancelled orders
360 @results = GetCancelledOrders($basketno);
361 my @cancelledorders_loop;
362 for my $order (@results) {
363 my $line = get_order_infos( $order, $bookseller);
364 push @cancelledorders_loop, $line;
367 my $contract = &GetContract($basket->{contractnumber});
368 my @orders = GetOrders($basketno);
370 if ($basket->{basketgroupid}){
371 $basketgroup = GetBasketgroup($basket->{basketgroupid});
372 $basketgroup->{deliveryplacename} = C4::Branch::GetBranchName( $basketgroup->{deliveryplace} );
373 $basketgroup->{billingplacename} = C4::Branch::GetBranchName( $basketgroup->{billingplace} );
375 my $borrower= GetMember('borrowernumber' => $loggedinuser);
376 my $budgets = GetBudgetHierarchy;
378 foreach my $r (@{$budgets}) {
379 if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
382 next unless (CanUserUseBudget($loggedinuser, $r, $userflags));
389 basketno => $basketno,
390 basketname => $basket->{'basketname'},
391 basketbranchname => C4::Branch::GetBranchName($basket->{branch}),
392 basketnote => $basket->{note},
393 basketbooksellernote => $basket->{booksellernote},
394 basketcontractno => $basket->{contractnumber},
395 basketcontractname => $contract->{contractname},
396 branches_loop => \@branches_loop,
397 creationdate => $basket->{creationdate},
398 authorisedby => $basket->{authorisedby},
399 authorisedbyname => $basket->{authorisedbyname},
400 basketusers_ids => join(':', @basketusers_ids),
401 basketusers => \@basketusers,
402 closedate => $basket->{closedate},
403 estimateddeliverydate=> $estimateddeliverydate,
404 deliveryplace => C4::Branch::GetBranchName( $basket->{deliveryplace} ),
405 billingplace => C4::Branch::GetBranchName( $basket->{billingplace} ),
406 active => $bookseller->{'active'},
407 booksellerid => $bookseller->{'id'},
408 name => $bookseller->{'name'},
409 books_loop => \@books_loop,
410 book_foot_loop => \@book_foot_loop,
411 cancelledorders_loop => \@cancelledorders_loop,
412 total_quantity => $total_quantity,
413 total_gste => sprintf( "%.2f", $total_gste ),
414 total_gsti => sprintf( "%.2f", $total_gsti ),
415 total_gstvalue => sprintf( "%.2f", $total_gstvalue ),
416 currency => $cur->{'currency'},
417 listincgst => $bookseller->{listincgst},
418 basketgroups => $basketgroups,
419 basketgroup => $basketgroup,
420 grouped => $basket->{basketgroupid},
421 unclosable => @orders ? 0 : 1,
422 has_budgets => $has_budgets,
426 sub get_order_infos {
428 my $bookseller = shift;
429 my $qty = $order->{'quantity'} || 0;
430 if ( !defined $order->{quantityreceived} ) {
431 $order->{quantityreceived} = 0;
433 my $budget = GetBudget( $order->{'budget_id'} );
435 my %line = %{ $order };
436 $line{order_received} = ( $qty == $order->{'quantityreceived'} );
437 $line{basketno} = $basketno;
438 $line{budget_name} = $budget->{budget_name};
439 $line{rrp} = ConvertCurrency( $order->{'currency'}, $line{rrp} ); # FIXME from comm
440 if ( $bookseller->{'listincgst'} ) {
441 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} );
442 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
443 $line{rrpgste} = sprintf( "%.2f", $line{rrp} / ( 1 + ( $line{gstgsti} / 100 ) ) );
444 $line{gstgste} = sprintf( "%.2f", $line{gstgsti} / ( 1 + ( $line{gstgsti} / 100 ) ) );
445 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} );
446 $line{ecostgste} = sprintf( "%.2f", $line{ecost} / ( 1 + ( $line{gstgsti} / 100 ) ) );
447 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
448 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
449 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
451 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} * ( 1 + ( $line{gstrate} ) ) );
452 $line{rrpgste} = sprintf( "%.2f", $line{rrp} );
453 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
454 $line{gstgste} = sprintf( "%.2f", $line{gstrate} * 100 );
455 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} * ( 1 + ( $line{gstrate} ) ) );
456 $line{ecostgste} = sprintf( "%.2f", $line{ecost} );
457 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
458 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
459 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
462 if ( $line{uncertainprice} ) {
463 $line{rrpgste} .= ' (Uncertain)';
465 if ( $line{'title'} ) {
466 my $volume = $order->{'volume'};
467 my $seriestitle = $order->{'seriestitle'};
468 $line{'title'} .= " / $seriestitle" if $seriestitle;
469 $line{'title'} .= " / $volume" if $volume;
471 $line{'title'} = "Deleted bibliographic notice, can't find title.";
474 my $biblionumber = $order->{'biblionumber'};
475 my $countbiblio = CountBiblioInOrders($biblionumber);
476 my $ordernumber = $order->{'ordernumber'};
477 my @subscriptions = GetSubscriptionsId ($biblionumber);
478 my $itemcount = GetItemsCount($biblionumber);
479 my $holds = GetHolds ($biblionumber);
480 my @items = GetItemnumbersFromOrder( $ordernumber );
482 foreach my $item (@items){
483 my $nb = GetItemHolds($biblionumber, $item);
488 # 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
489 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
490 $line{items} = ($itemcount) - (scalar @items);
491 $line{left_item} = 1 if $line{items} >= 1;
492 $line{left_biblio} = 1 if $countbiblio > 1;
493 $line{biblios} = $countbiblio - 1;
494 $line{left_subscription} = 1 if scalar @subscriptions >= 1;
495 $line{subscriptions} = scalar @subscriptions;
496 ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
497 $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
498 $line{holds} = $holds;
499 $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
502 my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber});
503 $line{suggestionid} = $$suggestion{suggestionid};
504 $line{surnamesuggestedby} = $$suggestion{surnamesuggestedby};
505 $line{firstnamesuggestedby} = $$suggestion{firstnamesuggestedby};
507 foreach my $key (qw(transferred_from transferred_to)) {
509 my $order = GetOrder($line{$key});
510 my $basket = GetBasket($order->{basketno});
511 my $bookseller = GetBookSellerFromId($basket->{booksellerid});
515 bookseller => $bookseller,
516 timestamp => $line{$key . '_timestamp'},
524 output_html_with_http_headers $query, $cookie, $template->output;