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