Bug 7843: Followup - fix broken url
[koha.git] / acqui / basket.pl
blob04ab8bc792a0223275d0c4cb4236f76eb256d27e
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
11 # under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or
13 # (at your option) any later version.
15 # Koha is distributed in the hope that it will be useful, but
16 # WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with Koha; if not, see <http://www.gnu.org/licenses>.
23 use strict;
24 use warnings;
25 use C4::Auth;
26 use C4::Koha;
27 use C4::Output;
28 use CGI qw ( -utf8 );
29 use C4::Acquisition;
30 use C4::Budgets;
31 use C4::Branch;
32 use C4::Contract;
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.tt",
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 = Koha::Acquisition::Bookseller->fetch({ id => $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({
171 contractnumber => $basket->{contractnumber}
173 $template->param(
174 basketno => $basketno,
175 basketname => $basket->{'basketname'},
176 basketnote => $basket->{note},
177 basketbooksellernote => $basket->{booksellernote},
178 basketcontractno => $basket->{contractnumber},
179 basketcontractname => $contract->{contractname},
180 creationdate => $basket->{creationdate},
181 authorisedby => $basket->{authorisedby},
182 authorisedbyname => $basket->{authorisedbyname},
183 closedate => $basket->{closedate},
184 deliveryplace => $basket->{deliveryplace},
185 billingplace => $basket->{billingplace},
186 active => $bookseller->{'active'},
187 booksellerid => $bookseller->{'id'},
188 name => $bookseller->{'name'},
189 address1 => $bookseller->{'address1'},
190 address2 => $bookseller->{'address2'},
191 address3 => $bookseller->{'address3'},
192 address4 => $bookseller->{'address4'},
194 } elsif ($op eq 'export') {
195 print $query->header(
196 -type => 'text/csv',
197 -attachment => 'basket' . $basket->{'basketno'} . '.csv',
199 print GetBasketAsCSV($query->param('basketno'), $query);
200 exit;
201 } elsif ($op eq 'close') {
202 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
203 if ($confirm) {
204 my $basketno = $query->param('basketno');
205 my $booksellerid = $query->param('booksellerid');
206 $basketno =~ /^\d+$/ and CloseBasket($basketno);
207 # if requested, create basket group, close it and attach the basket
208 if ($query->param('createbasketgroup')) {
209 my $branchcode;
210 if(C4::Context->userenv and C4::Context->userenv->{'branch'}
211 and C4::Context->userenv->{'branch'} ne "NO_LIBRARY_SET") {
212 $branchcode = C4::Context->userenv->{'branch'};
214 my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
215 booksellerid => $booksellerid,
216 deliveryplace => $branchcode,
217 billingplace => $branchcode,
218 closed => 1,
220 ModBasket( { basketno => $basketno,
221 basketgroupid => $basketgroupid } );
222 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
223 } else {
224 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
226 exit;
227 } else {
228 $template->param(
229 confirm_close => "1",
230 booksellerid => $booksellerid,
231 basketno => $basket->{'basketno'},
232 basketname => $basket->{'basketname'},
233 basketgroupname => $basket->{'basketname'},
236 } elsif ($op eq 'reopen') {
237 ReopenBasket($query->param('basketno'));
238 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
239 } elsif ( $op eq 'mod_users' ) {
240 my $basketusers_ids = $query->param('users_ids');
241 my @basketusers = split( /:/, $basketusers_ids );
242 ModBasketUsers($basketno, @basketusers);
243 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
244 exit;
245 } elsif ( $op eq 'mod_branch' ) {
246 my $branch = $query->param('branch');
247 $branch = undef if(defined $branch and $branch eq '');
248 ModBasket({
249 basketno => $basket->{basketno},
250 branch => $branch
252 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
253 exit;
254 } else {
255 my @branches_loop;
256 # get librarian branch...
257 if ( C4::Context->preference("IndependentBranches") ) {
258 my $userenv = C4::Context->userenv;
259 unless ( C4::Context->IsSuperLibrarian() ) {
260 my $validtest = ( $basket->{creationdate} eq '' )
261 || ( $userenv->{branch} eq $basket->{branch} )
262 || ( $userenv->{branch} eq '' )
263 || ( $basket->{branch} eq '' );
264 unless ($validtest) {
265 print $query->redirect("../mainpage.pl");
266 exit 1;
269 if (!defined $basket->{branch} or $basket->{branch} eq $userenv->{branch}) {
270 push @branches_loop, {
271 branchcode => $userenv->{branch},
272 branchname => $userenv->{branchname},
273 selected => 1,
276 } else {
277 # get branches
278 my $branches = C4::Branch::GetBranches;
279 my @branchcodes = sort {
280 $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname}
281 } keys %$branches;
282 foreach my $branch (@branchcodes) {
283 my $selected = 0;
284 if (defined $basket->{branch}) {
285 $selected = 1 if $branch eq $basket->{branch};
286 } else {
287 $selected = 1 if $branch eq C4::Context->userenv->{branch};
289 push @branches_loop, {
290 branchcode => $branch,
291 branchname => $branches->{$branch}->{branchname},
292 selected => $selected
297 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
298 my ($basketgroup, $basketgroups);
299 my $staffuser = GetMember(borrowernumber => $loggedinuser);
300 if ($basket->{closedate} && haspermission($staffuser->{userid}, { acquisition => 'group_manage'} )) {
301 $basketgroups = GetBasketgroups($basket->{booksellerid});
302 for my $bg ( @{$basketgroups} ) {
303 if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
304 $bg->{default} = 1;
305 $basketgroup = $bg;
310 # if the basket is closed, calculate estimated delivery date
311 my $estimateddeliverydate;
312 if( $basket->{closedate} ) {
313 my ($year, $month, $day) = ($basket->{closedate} =~ /(\d+)-(\d+)-(\d+)/);
314 ($year, $month, $day) = Add_Delta_Days($year, $month, $day, $bookseller->{deliverytime});
315 $estimateddeliverydate = sprintf( "%04d-%02d-%02d", $year, $month, $day );
318 # if new basket, pre-fill infos
319 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
320 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
321 $debug
322 and warn sprintf
323 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
324 $basket->{creationdate}, $basket->{authorisedby};
326 my @basketusers_ids = GetBasketUsers($basketno);
327 my @basketusers;
328 foreach my $basketuser_id (@basketusers_ids) {
329 my $basketuser = GetMember(borrowernumber => $basketuser_id);
330 push @basketusers, $basketuser if $basketuser;
333 #to get active currency
334 my $cur = GetCurrency();
337 my @orders = GetOrders( $basketno );
338 my @books_loop;
340 my @book_foot_loop;
341 my %foot;
342 my $total_quantity = 0;
343 my $total_gste = 0;
344 my $total_gsti = 0;
345 my $total_gstvalue = 0;
346 for my $order (@orders) {
347 $order = C4::Acquisition::populate_order_with_prices({ order => $order, booksellerid => $booksellerid, ordering => 1 });
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{gstrate}}{gstrate} = $$line{gstrate};
356 $foot{$$line{gstrate}}{gstvalue} += $$line{gstvalue};
357 $total_gstvalue += $$line{gstvalue};
358 $foot{$$line{gstrate}}{quantity} += $$line{quantity};
359 $total_quantity += $$line{quantity};
360 $foot{$$line{gstrate}}{totalgste} += $$line{totalgste};
361 $total_gste += $$line{totalgste};
362 $foot{$$line{gstrate}}{totalgsti} += $$line{totalgsti};
363 $total_gsti += $$line{totalgsti};
366 push @book_foot_loop, map {$_} values %foot;
368 # Get cancelled orders
369 my @cancelledorders = GetOrders($basketno, { cancelled => 1 });
370 my @cancelledorders_loop;
371 for my $order (@cancelledorders) {
372 $order = C4::Acquisition::populate_order_with_prices({ order => $order, booksellerid => $booksellerid, ordering => 1 });
373 my $line = get_order_infos( $order, $bookseller);
374 push @cancelledorders_loop, $line;
377 my $contract = GetContract({
378 contractnumber => $basket->{contractnumber}
381 if ($basket->{basketgroupid}){
382 $basketgroup = GetBasketgroup($basket->{basketgroupid});
383 $basketgroup->{deliveryplacename} = C4::Branch::GetBranchName( $basketgroup->{deliveryplace} );
384 $basketgroup->{billingplacename} = C4::Branch::GetBranchName( $basketgroup->{billingplace} );
386 my $borrower= GetMember('borrowernumber' => $loggedinuser);
387 my $budgets = GetBudgetHierarchy;
388 my $has_budgets = 0;
389 foreach my $r (@{$budgets}) {
390 if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
391 next;
393 next unless (CanUserUseBudget($loggedinuser, $r, $userflags));
395 $has_budgets = 1;
396 last;
399 $template->param(
400 basketno => $basketno,
401 basketname => $basket->{'basketname'},
402 basketbranchname => C4::Branch::GetBranchName($basket->{branch}),
403 basketnote => $basket->{note},
404 basketbooksellernote => $basket->{booksellernote},
405 basketcontractno => $basket->{contractnumber},
406 basketcontractname => $contract->{contractname},
407 branches_loop => \@branches_loop,
408 creationdate => $basket->{creationdate},
409 authorisedby => $basket->{authorisedby},
410 authorisedbyname => $basket->{authorisedbyname},
411 users_ids => join(':', @basketusers_ids),
412 users => \@basketusers,
413 closedate => $basket->{closedate},
414 estimateddeliverydate=> $estimateddeliverydate,
415 deliveryplace => C4::Branch::GetBranchName( $basket->{deliveryplace} ),
416 billingplace => C4::Branch::GetBranchName( $basket->{billingplace} ),
417 active => $bookseller->{'active'},
418 booksellerid => $bookseller->{'id'},
419 name => $bookseller->{'name'},
420 books_loop => \@books_loop,
421 book_foot_loop => \@book_foot_loop,
422 cancelledorders_loop => \@cancelledorders_loop,
423 total_quantity => $total_quantity,
424 total_gste => sprintf( "%.2f", $total_gste ),
425 total_gsti => sprintf( "%.2f", $total_gsti ),
426 total_gstvalue => sprintf( "%.2f", $total_gstvalue ),
427 currency => $cur->{'currency'},
428 listincgst => $bookseller->{listincgst},
429 basketgroups => $basketgroups,
430 basketgroup => $basketgroup,
431 grouped => $basket->{basketgroupid},
432 unclosable => @orders ? 0 : 1,
433 has_budgets => $has_budgets,
437 sub get_order_infos {
438 my $order = shift;
439 my $bookseller = shift;
440 my $qty = $order->{'quantity'} || 0;
441 if ( !defined $order->{quantityreceived} ) {
442 $order->{quantityreceived} = 0;
444 my $budget = GetBudget( $order->{'budget_id'} );
446 my %line = %{ $order };
447 $line{order_received} = ( $qty == $order->{'quantityreceived'} );
448 $line{basketno} = $basketno;
449 $line{budget_name} = $budget->{budget_name};
451 if ( $line{uncertainprice} ) {
452 $line{rrpgste} .= ' (Uncertain)';
454 if ( $line{'title'} ) {
455 my $volume = $order->{'volume'};
456 my $seriestitle = $order->{'seriestitle'};
457 $line{'title'} .= " / $seriestitle" if $seriestitle;
458 $line{'title'} .= " / $volume" if $volume;
459 } else {
460 $line{'title'} = "Deleted bibliographic notice, can't find title.";
463 my $biblionumber = $order->{'biblionumber'};
464 my $countbiblio = CountBiblioInOrders($biblionumber);
465 my $ordernumber = $order->{'ordernumber'};
466 my @subscriptions = GetSubscriptionsId ($biblionumber);
467 my $itemcount = GetItemsCount($biblionumber);
468 my $holds = GetHolds ($biblionumber);
469 my @items = GetItemnumbersFromOrder( $ordernumber );
470 my $itemholds;
471 foreach my $item (@items){
472 my $nb = GetItemHolds($biblionumber, $item);
473 if ($nb){
474 $itemholds += $nb;
477 # 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
478 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
479 $line{items} = ($itemcount) - (scalar @items);
480 $line{left_item} = 1 if $line{items} >= 1;
481 $line{left_biblio} = 1 if $countbiblio > 1;
482 $line{biblios} = $countbiblio - 1;
483 $line{left_subscription} = 1 if scalar @subscriptions >= 1;
484 $line{subscriptions} = scalar @subscriptions;
485 ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
486 $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
487 $line{holds} = $holds;
488 $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
491 my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber});
492 $line{suggestionid} = $$suggestion{suggestionid};
493 $line{surnamesuggestedby} = $$suggestion{surnamesuggestedby};
494 $line{firstnamesuggestedby} = $$suggestion{firstnamesuggestedby};
496 foreach my $key (qw(transferred_from transferred_to)) {
497 if ($line{$key}) {
498 my $order = GetOrder($line{$key});
499 my $basket = GetBasket($order->{basketno});
500 my $bookseller = Koha::Acquisition::Bookseller->fetch({ id => $basket->{booksellerid} });
501 $line{$key} = {
502 order => $order,
503 basket => $basket,
504 bookseller => $bookseller,
505 timestamp => $line{$key . '_timestamp'},
510 return \%line;
513 output_html_with_http_headers $query, $cookie, $template->output;