Bug 5346: Linking suggestions and orders.
[koha.git] / acqui / basket.pl
blobbd7d45da413fb25ce61a2a5ef236ddc534d7b204
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 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
13 # version.
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.
23 use strict;
24 use warnings;
25 use C4::Auth;
26 use C4::Koha;
27 use C4::Output;
28 use CGI;
29 use C4::Acquisition;
30 use C4::Budgets;
31 use C4::Bookseller qw( GetBookSellerFromId);
32 use C4::Dates qw/format_date/;
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;
39 =head1 NAME
41 basket.pl
43 =head1 DESCRIPTION
45 This script display all informations about basket for the supplier given
46 on input arg. Moreover, it allows us to add a new order for this supplier from
47 an existing record, a suggestion or a new record.
49 =head1 CGI PARAMETERS
51 =over 4
53 =item $basketno
55 The basket number.
57 =item supplierid
59 the supplier this script have to display the basket.
61 =item order
63 =back
65 =cut
67 my $query = new CGI;
68 my $basketno = $query->param('basketno');
69 my $booksellerid = $query->param('supplierid');
71 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
73 template_name => "acqui/basket.tmpl",
74 query => $query,
75 type => "intranet",
76 authnotrequired => 0,
77 flagsrequired => { acquisition => 'order_manage' },
78 debug => 1,
82 my $basket = GetBasket($basketno);
84 # FIXME : what about the "discount" percentage?
85 # FIXME : the query->param('supplierid') below is probably useless. The bookseller is always known from the basket
86 # if no booksellerid in parameter, get it from basket
87 # warn "=>".$basket->{booksellerid};
88 $booksellerid = $basket->{booksellerid} unless $booksellerid;
89 my ($bookseller) = GetBookSellerFromId($booksellerid);
90 my $op = $query->param('op');
91 if (!defined $op) {
92 $op = q{};
95 my $confirm_pref= C4::Context->preference("BasketConfirmations") || '1';
96 $template->param( skip_confirm_reopen => 1) if $confirm_pref eq '2';
98 if ( $op eq 'delete_confirm' ) {
99 my $basketno = $query->param('basketno');
100 DelBasket($basketno);
101 $template->param( delete_confirmed => 1 );
102 } elsif ( !$bookseller ) {
103 $template->param( NO_BOOKSELLER => 1 );
104 } elsif ( $op eq 'del_basket') {
105 $template->param( delete_confirm => 1 );
106 if ( C4::Context->preference("IndependantBranches") ) {
107 my $userenv = C4::Context->userenv;
108 unless ( $userenv->{flags} == 1 ) {
109 my $validtest = ( $basket->{creationdate} eq '' )
110 || ( $userenv->{branch} eq $basket->{branch} )
111 || ( $userenv->{branch} eq '' )
112 || ( $basket->{branch} eq '' );
113 unless ($validtest) {
114 print $query->redirect("../mainpage.pl");
115 exit 1;
119 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
120 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
121 my $contract = &GetContract($basket->{contractnumber});
122 $template->param(
123 basketno => $basketno,
124 basketname => $basket->{'basketname'},
125 basketnote => $basket->{note},
126 basketbooksellernote => $basket->{booksellernote},
127 basketcontractno => $basket->{contractnumber},
128 basketcontractname => $contract->{contractname},
129 creationdate => format_date( $basket->{creationdate} ),
130 authorisedby => $basket->{authorisedby},
131 authorisedbyname => $basket->{authorisedbyname},
132 closedate => format_date( $basket->{closedate} ),
133 active => $bookseller->{'active'},
134 booksellerid => $bookseller->{'id'},
135 name => $bookseller->{'name'},
136 address1 => $bookseller->{'address1'},
137 address2 => $bookseller->{'address2'},
138 address3 => $bookseller->{'address3'},
139 address4 => $bookseller->{'address4'},
141 } elsif ($op eq 'attachbasket' && $template->{'VARS'}->{'CAN_user_acquisition_group_manage'} == 1) {
142 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?basketno=' . $basket->{'basketno'} . '&op=attachbasket&booksellerid=' . $booksellerid);
143 # check if we have to "close" a basket before building page
144 } elsif ($op eq 'export') {
145 print $query->header(
146 -type => 'text/csv',
147 -attachment => 'basket' . $basket->{'basketno'} . '.csv',
149 print GetBasketAsCSV($query->param('basketno'));
150 exit;
151 } elsif ($op eq 'close') {
152 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
153 if ($confirm) {
154 my $basketno = $query->param('basketno');
155 my $booksellerid = $query->param('booksellerid');
156 $basketno =~ /^\d+$/ and CloseBasket($basketno);
157 # if requested, create basket group, close it and attach the basket
158 if ($query->param('createbasketgroup')) {
159 my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
160 booksellerid => $booksellerid,
161 closed => 1,
163 ModBasket( { basketno => $basketno,
164 basketgroupid => $basketgroupid } );
165 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
166 } else {
167 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?supplierid=' . $booksellerid);
169 exit;
170 } else {
171 $template->param(confirm_close => "1",
172 booksellerid => $booksellerid,
173 basketno => $basket->{'basketno'},
174 basketname => $basket->{'basketname'},
175 basketgroupname => $basket->{'basketname'});
178 } elsif ($op eq 'reopen') {
179 my $basket;
180 $basket->{basketno} = $query->param('basketno');
181 $basket->{closedate} = undef;
182 ModBasket($basket);
183 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
184 } else {
185 # get librarian branch...
186 if ( C4::Context->preference("IndependantBranches") ) {
187 my $userenv = C4::Context->userenv;
188 unless ( $userenv->{flags} == 1 ) {
189 my $validtest = ( $basket->{creationdate} eq '' )
190 || ( $userenv->{branch} eq $basket->{branch} )
191 || ( $userenv->{branch} eq '' )
192 || ( $basket->{branch} eq '' );
193 unless ($validtest) {
194 print $query->redirect("../mainpage.pl");
195 exit 1;
199 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
200 my $basketgroups;
201 my $member = GetMember(borrowernumber => $loggedinuser);
202 if ($basket->{closedate} && haspermission({ acquisition => 'group_manage'} )) {
203 $basketgroups = GetBasketgroups($basket->{booksellerid});
204 for my $bg ( @{$basketgroups} ) {
205 if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
206 $bg->{default} = 1;
209 my %emptygroup = ( id => undef,
210 name => "No group");
211 if ( ! $basket->{basketgroupid} ) {
212 $emptygroup{default} = 1;
213 $emptygroup{nogroup} = 1;
215 unshift( @$basketgroups, \%emptygroup );
217 # if new basket, pre-fill infos
218 $basket->{creationdate} = "" unless ( $basket->{creationdate} );
219 $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
220 $debug
221 and warn sprintf
222 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
223 $basket->{creationdate}, $basket->{authorisedby};
225 #to get active currency
226 my $cur = GetCurrency();
229 my @results = GetOrders( $basketno );
231 my $gist = $bookseller->{gstrate} // C4::Context->preference("gist") // 0;
232 $gist = 0 if $gist == 0.0000;
233 my $discount = $bookseller->{'discount'} / 100;
234 my $total_rrp = 0; # RRP Total, its value will be assigned to $total_rrp_gsti or $total_rrp_gste depending of $bookseller->{'listincgst'}
235 my $total_rrp_gsti = 0; # RRP Total, GST included
236 my $total_rrp_gste = 0; # RRP Total, GST excluded
237 my $gist_rrp = 0;
238 my $total_rrp_est = 0;
240 my $qty_total;
241 my @books_loop;
242 my $suggestion;
244 for my $order ( @results ) {
245 my $rrp = $order->{'listprice'} || 0;
246 my $qty = $order->{'quantity'} || 0;
247 if (!defined $order->{quantityreceived}) {
248 $order->{quantityreceived} = 0;
250 for ( qw(rrp ecost quantityreceived)) {
251 if (!defined $order->{$_}) {
252 $order->{$_} = 0;
256 my $budget = GetBudget( $order->{'budget_id'} );
257 $rrp = ConvertCurrency( $order->{'currency'}, $rrp );
259 $total_rrp += $qty * $order->{'rrp'};
260 my $line_total = $qty * $order->{'ecost'};
261 $total_rrp_est += $qty * $order->{'ecost'};
262 # FIXME: what about the "actual cost" field?
263 $qty_total += $qty;
264 my %line = %{ $order };
265 my $biblionumber = $order->{'biblionumber'};
266 my $countbiblio = CountBiblioInOrders($biblionumber);
267 my $ordernumber = $order->{'ordernumber'};
268 my @subscriptions = GetSubscriptionsId ($biblionumber);
269 my $itemcount = GetItemsCount($biblionumber);
270 my $holds = GetHolds ($biblionumber);
271 my @items = GetItemnumbersFromOrder( $ordernumber );
272 my $itemholds;
273 foreach my $item (@items){
274 my $nb = GetItemHolds($biblionumber, $item);
275 if ($nb){
276 $itemholds += $nb;
279 # 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
280 $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
281 $line{items} = ($itemcount) - (scalar @items);
282 $line{left_item} = 1 if $line{items} >= 1;
283 $line{left_biblio} = 1 if $countbiblio > 1;
284 $line{biblios} = $countbiblio - 1;
285 $line{left_subscription} = 1 if scalar @subscriptions >= 1;
286 $line{subscriptions} = scalar @subscriptions;
287 ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
288 $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
289 $line{holds} = $holds;
290 $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
291 $line{order_received} = ( $qty == $order->{'quantityreceived'} );
292 $line{basketno} = $basketno;
293 $line{budget_name} = $budget->{budget_name};
294 $line{rrp} = sprintf( "%.2f", $line{'rrp'} );
295 $line{ecost} = sprintf( "%.2f", $line{'ecost'} );
296 $line{line_total} = sprintf( "%.2f", $line_total );
297 if ($line{uncertainprice}) {
298 $template->param( uncertainprices => 1 );
299 $line{rrp} .= ' (Uncertain)';
301 if ($line{'title'}){
302 my $volume = $order->{'volume'};
303 my $seriestitle = $order->{'seriestitle'};
304 $line{'title'} .= " / $seriestitle" if $seriestitle;
305 $line{'title'} .= " / $volume" if $volume;
306 } else {
307 $line{'title'} = "Deleted bibliographic notice, can't find title.";
310 $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber});
311 $line{suggestionid} = $suggestion->{suggestionid};
312 $line{surnamesuggestedby} = $suggestion->{surnamesuggestedby};
313 $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
315 push @books_loop, \%line;
318 my $total_est_gste;
319 my $total_est_gsti;
320 my $gist_est;
321 if ($gist){ # if we have GST
322 if ( $bookseller->{'listincgst'} ) { # if prices already includes GST
323 $total_rrp_gsti = $total_rrp; # we know $total_rrp_gsti
324 $total_rrp_gste = $total_rrp_gsti / ( $gist + 1 ); # and can reverse compute other values
325 $gist_rrp = $total_rrp_gsti - $total_rrp_gste; #
326 $total_est_gste = $total_rrp_gste - ( $total_rrp_gste * $discount );
327 $total_est_gsti = $total_rrp_est;
328 } else { # if prices does not include GST
329 $total_rrp_gste = $total_rrp; # then we use the common way to compute other values
330 $gist_rrp = $total_rrp_gste * $gist; #
331 $total_rrp_gsti = $total_rrp_gste + $gist_rrp; #
332 $total_est_gste = $total_rrp_est;
333 $total_est_gsti = $total_rrp_gsti - ( $total_rrp_gsti * $discount );
335 $gist_est = $gist_rrp - ( $gist_rrp * $discount );
336 } else {
337 $total_rrp_gsti = $total_rrp;
338 $total_est_gsti = $total_rrp_est;
341 my $contract = &GetContract($basket->{contractnumber});
342 my @orders = GetOrders($basketno);
344 my $borrower= GetMember('borrowernumber' => $loggedinuser);
345 my $budgets = GetBudgetHierarchy(q{},$borrower->{branchcode},$borrower->{borrowernumber});
346 my $has_budgets = 0;
347 foreach my $r (@{$budgets}) {
348 if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
349 next;
351 $has_budgets = 1;
352 last;
355 my @cancelledorders = GetCancelledOrders($basketno);
356 foreach (@cancelledorders) {
357 $_->{'line_total'} = sprintf("%.2f", $_->{'ecost'} * $_->{'quantity'});
360 $template->param(
361 basketno => $basketno,
362 basketname => $basket->{'basketname'},
363 basketnote => $basket->{note},
364 basketbooksellernote => $basket->{booksellernote},
365 basketcontractno => $basket->{contractnumber},
366 basketcontractname => $contract->{contractname},
367 creationdate => C4::Dates->new($basket->{creationdate},'iso')->output,
368 authorisedby => $basket->{authorisedby},
369 authorisedbyname => $basket->{authorisedbyname},
370 closedate => C4::Dates->new($basket->{closedate},'iso')->output,
371 active => $bookseller->{'active'},
372 booksellerid => $bookseller->{'id'},
373 name => $bookseller->{'name'},
374 entrydate => C4::Dates->new($results[0]->{'entrydate'},'iso')->output,
375 books_loop => \@books_loop,
376 cancelledorders_loop => \@cancelledorders,
377 gist_rate => sprintf( "%.2f", $gist * 100 ) . '%',
378 total_rrp_gste => sprintf( "%.2f", $total_rrp_gste ),
379 total_est_gste => sprintf( "%.2f", $total_est_gste ),
380 gist_est => sprintf( "%.2f", $gist_est ),
381 gist_rrp => sprintf( "%.2f", $gist_rrp ),
382 total_rrp_gsti => sprintf( "%.2f", $total_rrp_gsti ),
383 total_est_gsti => sprintf( "%.2f", $total_est_gsti ),
384 # currency => $bookseller->{'listprice'},
385 currency => $cur->{'currency'},
386 qty_total => $qty_total,
387 GST => $gist,
388 basketgroups => $basketgroups,
389 grouped => $basket->{basketgroupid},
390 unclosable => @orders ? 0 : 1,
391 has_budgets => $has_budgets,
395 output_html_with_http_headers $query, $cookie, $template->output;