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
}){
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
} );
324 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
325 $basket->{creationdate
}, $basket->{authorisedby
};
327 my @basketusers_ids = GetBasketUsers
($basketno);
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 );
343 my $total_quantity = 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
;
387 foreach my $r (@
{$budgets}) {
388 if (!defined $r->{budget_amount
} || $r->{budget_amount
} == 0) {
391 next unless (CanUserUseBudget
($loggedinuser, $r, $userflags));
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
{
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
} );
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;
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 );
491 foreach my $item (@items){
492 my $nb = GetItemHolds
($biblionumber, $item);
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)) {
518 my $order = GetOrder
($line{$key});
519 my $basket = GetBasket
($order->{basketno
});
520 my $bookseller = GetBookSellerFromId
($basket->{booksellerid
});
524 bookseller
=> $bookseller,
525 timestamp
=> $line{$key . '_timestamp'},
533 output_html_with_http_headers
$query, $cookie, $template->output;