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 foreach my $myorder (@orders){
122 my $biblionumber = $myorder->{'biblionumber'};
123 my $countbiblio = CountBiblioInOrders($biblionumber);
124 my $ordernumber = $myorder->{'ordernumber'};
125 my @subscriptions = GetSubscriptionsId ($biblionumber);
126 my $itemcount = GetItemsCount($biblionumber);
127 DelBiblio($myorder->{biblionumber}) if ($countbiblio == 0 && $itemcount == 0 && !(@subscriptions));
131 DelBasket($basketno,);
132 $template->param( delete_confirmed => 1 );
133 } elsif ( !$bookseller ) {
134 $template->param( NO_BOOKSELLER => 1 );
135 } elsif ( $op eq 'del_basket') {
136 $template->param( delete_confirm => 1 );
137 if ( C4::Context->preference("IndependentBranches") ) {
138 my $userenv = C4::Context->userenv;
139 unless ( $userenv->{flags} == 1 ) {
140 my $validtest = ( $basket->{creationdate} eq '' )
141 || ( $userenv->{branch} eq $basket->{branch} )
142 || ( $userenv->{branch} eq '' )
143 || ( $basket->{branch} eq '' );
144 unless ($validtest) {
145 print $query->redirect("../mainpage.pl");
150 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
151 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
152 my $contract = &GetContract($basket->{contractnumber});
154 basketno => $basketno,
155 basketname => $basket->{'basketname'},
156 basketnote => $basket->{note},
157 basketbooksellernote => $basket->{booksellernote},
158 basketcontractno => $basket->{contractnumber},
159 basketcontractname => $contract->{contractname},
160 creationdate => $basket->{creationdate},
161 authorisedby => $basket->{authorisedby},
162 authorisedbyname => $basket->{authorisedbyname},
163 closedate => $basket->{closedate},
164 deliveryplace => $basket->{deliveryplace},
165 billingplace => $basket->{billingplace},
166 active => $bookseller->{'active'},
167 booksellerid => $bookseller->{'id'},
168 name => $bookseller->{'name'},
169 address1 => $bookseller->{'address1'},
170 address2 => $bookseller->{'address2'},
171 address3 => $bookseller->{'address3'},
172 address4 => $bookseller->{'address4'},
174 } elsif ($op eq 'attachbasket' && $template->{'VARS'}->{'CAN_user_acquisition_group_manage'} == 1) {
175 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?basketno=' . $basket->{'basketno'} . '&op=attachbasket&booksellerid=' . $booksellerid);
176 # check if we have to "close" a basket before building page
177 } elsif ($op eq 'export') {
178 print $query->header(
180 -attachment => 'basket' . $basket->{'basketno'} . '.csv',
182 print GetBasketAsCSV($query->param('basketno'), $query);
184 } elsif ($op eq 'close') {
185 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
187 my $basketno = $query->param('basketno');
188 my $booksellerid = $query->param('booksellerid');
189 $basketno =~ /^\d+$/ and CloseBasket($basketno);
190 # if requested, create basket group, close it and attach the basket
191 if ($query->param('createbasketgroup')) {
193 if(C4::Context->userenv and C4::Context->userenv->{'branch'}
194 and C4::Context->userenv->{'branch'} ne "NO_LIBRARY_SET") {
195 $branchcode = C4::Context->userenv->{'branch'};
197 my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
198 booksellerid => $booksellerid,
199 deliveryplace => $branchcode,
200 billingplace => $branchcode,
203 ModBasket( { basketno => $basketno,
204 basketgroupid => $basketgroupid } );
205 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
207 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
212 confirm_close => "1",
213 booksellerid => $booksellerid,
214 basketno => $basket->{'basketno'},
215 basketname => $basket->{'basketname'},
216 basketgroupname => $basket->{'basketname'},
219 } elsif ($op eq 'reopen') {
220 ReopenBasket($query->param('basketno'));
221 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
222 } elsif ( $op eq 'mod_users' ) {
223 my $basketusers_ids = $query->param('basketusers_ids');
224 my @basketusers = split( /:/, $basketusers_ids );
225 ModBasketUsers($basketno, @basketusers);
226 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
228 } elsif ( $op eq 'mod_branch' ) {
229 my $branch = $query->param('branch');
230 $branch = undef if(defined $branch and $branch eq '');
232 basketno => $basket->{basketno},
235 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
239 # get librarian branch...
240 if ( C4::Context->preference("IndependentBranches") ) {
241 my $userenv = C4::Context->userenv;
242 unless ( $userenv->{flags} == 1 ) {
243 my $validtest = ( $basket->{creationdate} eq '' )
244 || ( $userenv->{branch} eq $basket->{branch} )
245 || ( $userenv->{branch} eq '' )
246 || ( $basket->{branch} eq '' );
247 unless ($validtest) {
248 print $query->redirect("../mainpage.pl");
252 if (!defined $basket->{branch} or $basket->{branch} eq $userenv->{branch}) {
253 push @branches_loop, {
254 branchcode => $userenv->{branch},
255 branchname => $userenv->{branchname},
261 my $branches = C4::Branch::GetBranches;
262 my @branchcodes = sort {
263 $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname}
265 foreach my $branch (@branchcodes) {
267 if (defined $basket->{branch}) {
268 $selected = 1 if $branch eq $basket->{branch};
270 $selected = 1 if $branch eq C4::Context->userenv->{branch};
272 push @branches_loop, {
273 branchcode => $branch,
274 branchname => $branches->{$branch}->{branchname},
275 selected => $selected
280 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
281 my ($basketgroup, $basketgroups);
282 my $staffuser = GetMember(borrowernumber => $loggedinuser);
283 if ($basket->{closedate} && haspermission($staffuser->{userid}, { acquisition => 'group_manage'} )) {
284 $basketgroups = GetBasketgroups($basket->{booksellerid});
285 for my $bg ( @{$basketgroups} ) {
286 if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
291 my %emptygroup = ( id => undef,
293 if ( ! $basket->{basketgroupid} ) {
294 $emptygroup{default} = 1;
295 $emptygroup{nogroup} = 1;
297 unshift( @$basketgroups, \%emptygroup );
300 # if the basket is closed, calculate estimated delivery date
301 my $estimateddeliverydate;
302 if( $basket->{closedate} ) {
303 my ($year, $month, $day) = ($basket->{closedate} =~ /(\d+)-(\d+)-(\d+)/);
304 ($year, $month, $day) = Add_Delta_Days($year, $month, $day, $bookseller->{deliverytime});
305 $estimateddeliverydate = "$year-$month-$day";
308 # if new basket, pre-fill infos
309 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
310 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
313 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
314 $basket->{creationdate}, $basket->{authorisedby};
316 my @basketusers_ids = GetBasketUsers($basketno);
318 foreach my $basketuser_id (@basketusers_ids) {
319 my $basketuser = GetMember(borrowernumber => $basketuser_id);
320 push @basketusers, $basketuser if $basketuser;
323 #to get active currency
324 my $cur = GetCurrency();
327 my @results = GetOrders( $basketno );
332 my $total_quantity = 0;
335 my $total_gstvalue = 0;
336 for my $order (@results) {
337 my $line = get_order_infos( $order, $bookseller);
338 if ( $line->{uncertainprice} ) {
339 $template->param( uncertainprices => 1 );
342 push @books_loop, $line;
344 $foot{$$line{gstgsti}}{gstgsti} = $$line{gstgsti};
345 $foot{$$line{gstgsti}}{gstvalue} += $$line{gstvalue};
346 $total_gstvalue += $$line{gstvalue};
347 $foot{$$line{gstgsti}}{quantity} += $$line{quantity};
348 $total_quantity += $$line{quantity};
349 $foot{$$line{gstgsti}}{totalgste} += $$line{totalgste};
350 $total_gste += $$line{totalgste};
351 $foot{$$line{gstgsti}}{totalgsti} += $$line{totalgsti};
352 $total_gsti += $$line{totalgsti};
355 push @book_foot_loop, map {$_} values %foot;
357 # Get cancelled orders
358 @results = GetCancelledOrders($basketno);
359 my @cancelledorders_loop;
360 for my $order (@results) {
361 my $line = get_order_infos( $order, $bookseller);
362 push @cancelledorders_loop, $line;
365 my $contract = &GetContract($basket->{contractnumber});
366 my @orders = GetOrders($basketno);
368 if ($basket->{basketgroupid}){
369 $basketgroup = GetBasketgroup($basket->{basketgroupid});
370 $basketgroup->{deliveryplacename} = C4::Branch::GetBranchName( $basketgroup->{deliveryplace} );
371 $basketgroup->{billingplacename} = C4::Branch::GetBranchName( $basketgroup->{billingplace} );
373 my $borrower= GetMember('borrowernumber' => $loggedinuser);
374 my $budgets = GetBudgetHierarchy;
376 foreach my $r (@{$budgets}) {
377 if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
380 next unless (CanUserUseBudget($loggedinuser, $r, $userflags));
387 basketno => $basketno,
388 basketname => $basket->{'basketname'},
389 basketbranchname => C4::Branch::GetBranchName($basket->{branch}),
390 basketnote => $basket->{note},
391 basketbooksellernote => $basket->{booksellernote},
392 basketcontractno => $basket->{contractnumber},
393 basketcontractname => $contract->{contractname},
394 branches_loop => \@branches_loop,
395 creationdate => $basket->{creationdate},
396 authorisedby => $basket->{authorisedby},
397 authorisedbyname => $basket->{authorisedbyname},
398 basketusers_ids => join(':', @basketusers_ids),
399 basketusers => \@basketusers,
400 closedate => $basket->{closedate},
401 estimateddeliverydate=> $estimateddeliverydate,
402 deliveryplace => C4::Branch::GetBranchName( $basket->{deliveryplace} ),
403 billingplace => C4::Branch::GetBranchName( $basket->{billingplace} ),
404 active => $bookseller->{'active'},
405 booksellerid => $bookseller->{'id'},
406 name => $bookseller->{'name'},
407 books_loop => \@books_loop,
408 book_foot_loop => \@book_foot_loop,
409 cancelledorders_loop => \@cancelledorders_loop,
410 total_quantity => $total_quantity,
411 total_gste => sprintf( "%.2f", $total_gste ),
412 total_gsti => sprintf( "%.2f", $total_gsti ),
413 total_gstvalue => sprintf( "%.2f", $total_gstvalue ),
414 currency => $cur->{'currency'},
415 listincgst => $bookseller->{listincgst},
416 basketgroups => $basketgroups,
417 basketgroup => $basketgroup,
418 grouped => $basket->{basketgroupid},
419 unclosable => @orders ? 0 : 1,
420 has_budgets => $has_budgets,
424 sub get_order_infos {
426 my $bookseller = shift;
427 my $qty = $order->{'quantity'} || 0;
428 if ( !defined $order->{quantityreceived} ) {
429 $order->{quantityreceived} = 0;
431 my $budget = GetBudget( $order->{'budget_id'} );
433 my %line = %{ $order };
434 $line{order_received} = ( $qty == $order->{'quantityreceived'} );
435 $line{basketno} = $basketno;
436 $line{budget_name} = $budget->{budget_name};
437 $line{rrp} = ConvertCurrency( $order->{'currency'}, $line{rrp} ); # FIXME from comm
438 if ( $bookseller->{'listincgst'} ) {
439 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} );
440 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
441 $line{rrpgste} = sprintf( "%.2f", $line{rrp} / ( 1 + ( $line{gstgsti} / 100 ) ) );
442 $line{gstgste} = sprintf( "%.2f", $line{gstgsti} / ( 1 + ( $line{gstgsti} / 100 ) ) );
443 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} );
444 $line{ecostgste} = sprintf( "%.2f", $line{ecost} / ( 1 + ( $line{gstgsti} / 100 ) ) );
445 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
446 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
447 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
449 $line{rrpgsti} = sprintf( "%.2f", $line{rrp} * ( 1 + ( $line{gstrate} ) ) );
450 $line{rrpgste} = sprintf( "%.2f", $line{rrp} );
451 $line{gstgsti} = sprintf( "%.2f", $line{gstrate} * 100 );
452 $line{gstgste} = sprintf( "%.2f", $line{gstrate} * 100 );
453 $line{ecostgsti} = sprintf( "%.2f", $line{ecost} * ( 1 + ( $line{gstrate} ) ) );
454 $line{ecostgste} = sprintf( "%.2f", $line{ecost} );
455 $line{gstvalue} = sprintf( "%.2f", ( $line{ecostgsti} - $line{ecostgste} ) * $line{quantity});
456 $line{totalgste} = sprintf( "%.2f", $order->{quantity} * $line{ecostgste} );
457 $line{totalgsti} = sprintf( "%.2f", $order->{quantity} * $line{ecostgsti} );
460 if ( $line{uncertainprice} ) {
461 $line{rrpgste} .= ' (Uncertain)';
463 if ( $line{'title'} ) {
464 my $volume = $order->{'volume'};
465 my $seriestitle = $order->{'seriestitle'};
466 $line{'title'} .= " / $seriestitle" if $seriestitle;
467 $line{'title'} .= " / $volume" if $volume;
469 $line{'title'} = "Deleted bibliographic notice, can't find title.";
472 my $biblionumber = $order->{'biblionumber'};
473 my $countbiblio = CountBiblioInOrders($biblionumber);
474 my $ordernumber = $order->{'ordernumber'};
475 my @subscriptions = GetSubscriptionsId ($biblionumber);
476 my $itemcount = GetItemsCount($biblionumber);
477 my $holds = GetHolds ($biblionumber);
478 my @items = GetItemnumbersFromOrder( $ordernumber );
480 foreach my $item (@items){
481 my $nb = GetItemHolds($biblionumber, $item);
486 # 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
487 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
488 $line{items} = ($itemcount) - (scalar @items);
489 $line{left_item} = 1 if $line{items} >= 1;
490 $line{left_biblio} = 1 if $countbiblio > 1;
491 $line{biblios} = $countbiblio - 1;
492 $line{left_subscription} = 1 if scalar @subscriptions >= 1;
493 $line{subscriptions} = scalar @subscriptions;
494 ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
495 $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
496 $line{holds} = $holds;
497 $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
500 my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber});
501 $line{suggestionid} = $$suggestion{suggestionid};
502 $line{surnamesuggestedby} = $$suggestion{surnamesuggestedby};
503 $line{firstnamesuggestedby} = $$suggestion{firstnamesuggestedby};
505 foreach my $key (qw(transferred_from transferred_to)) {
507 my $order = GetOrder($line{$key});
508 my $basket = GetBasket($order->{basketno});
509 my $bookseller = GetBookSellerFromId($basket->{booksellerid});
513 bookseller => $bookseller,
514 timestamp => $line{$key . '_timestamp'},
522 output_html_with_http_headers $query, $cookie, $template->output;