Bug 8172: Followup: Removes useless empty params
[koha.git] / acqui / basket.pl
1 #!/usr/bin/perl
2
3 #script to show display basket of orders
4
5 # Copyright 2000 - 2004 Katipo
6 # Copyright 2008 - 2009 BibLibre SARL
7 #
8 # This file is part of Koha.
9 #
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.
14 #
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.
18 #
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.
22
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::Debug;
33 use C4::Biblio;
34 use C4::Members qw/GetMember/;  #needed for permissions checking for changing basketgroup of a basket
35 use C4::Items;
36 use C4::Suggestions;
37 use Date::Calc qw/Add_Delta_Days/;
38
39 =head1 NAME
40
41 basket.pl
42
43 =head1 DESCRIPTION
44
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.
48
49 =head1 CGI PARAMETERS
50
51 =over 4
52
53 =item $basketno
54
55 The basket number.
56
57 =item booksellerid
58
59 the supplier this script have to display the basket.
60
61 =item order
62
63 =back
64
65 =cut
66
67 my $query        = new CGI;
68 my $basketno     = $query->param('basketno');
69 my $booksellerid = $query->param('booksellerid');
70
71 my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user(
72     {
73         template_name   => "acqui/basket.tmpl",
74         query           => $query,
75         type            => "intranet",
76         authnotrequired => 0,
77         flagsrequired   => { acquisition => 'order_manage' },
78         debug           => 1,
79     }
80 );
81
82 my $basket = GetBasket($basketno);
83
84 # FIXME : what about the "discount" percentage?
85 # FIXME : the query->param('booksellerid') 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{};
93 }
94
95 my $confirm_pref= C4::Context->preference("BasketConfirmations") || '1';
96 $template->param( skip_confirm_reopen => 1) if $confirm_pref eq '2';
97
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;
116             }
117         }
118     }
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         => $basket->{creationdate},
130         authorisedby         => $basket->{authorisedby},
131         authorisedbyname     => $basket->{authorisedbyname},
132         closedate            => $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'},
140       );
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',
148     );
149     print GetBasketAsCSV($query->param('basketno'), $query);
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 $branchcode;
160             if(C4::Context->userenv and C4::Context->userenv->{'branch'}
161               and C4::Context->userenv->{'branch'} ne "NO_LIBRARY_SET") {
162                 $branchcode = C4::Context->userenv->{'branch'};
163             }
164             my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
165                             booksellerid => $booksellerid,
166                             deliveryplace => $branchcode,
167                             billingplace => $branchcode,
168                             closed => 1,
169                             });
170             ModBasket( { basketno => $basketno,
171                          basketgroupid => $basketgroupid } );
172             print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
173         } else {
174             print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
175         }
176         exit;
177     } else {
178     $template->param(confirm_close => "1",
179             booksellerid    => $booksellerid,
180             basketno        => $basket->{'basketno'},
181                 basketname      => $basket->{'basketname'},
182             basketgroupname => $basket->{'basketname'});
183         
184     }
185 } elsif ($op eq 'reopen') {
186     my $basket;
187     $basket->{basketno} = $query->param('basketno');
188     $basket->{closedate} = undef;
189     ModBasket($basket);
190     print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
191 } else {
192     # get librarian branch...
193     if ( C4::Context->preference("IndependantBranches") ) {
194         my $userenv = C4::Context->userenv;
195         unless ( $userenv->{flags} == 1 ) {
196             my $validtest = ( $basket->{creationdate} eq '' )
197               || ( $userenv->{branch} eq $basket->{branch} )
198               || ( $userenv->{branch} eq '' )
199               || ( $basket->{branch}  eq '' );
200             unless ($validtest) {
201                 print $query->redirect("../mainpage.pl");
202                 exit 1;
203             }
204         }
205     }
206 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
207     my $basketgroups;
208     my $member = GetMember(borrowernumber => $loggedinuser);
209     if ($basket->{closedate} && haspermission({ acquisition => 'group_manage'} )) {
210         $basketgroups = GetBasketgroups($basket->{booksellerid});
211         for my $bg ( @{$basketgroups} ) {
212             if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
213                 $bg->{default} = 1;
214             }
215         }
216         my %emptygroup = ( id   =>   undef,
217                            name =>   "No group");
218         if ( ! $basket->{basketgroupid} ) {
219             $emptygroup{default} = 1;
220             $emptygroup{nogroup} = 1;
221         }
222         unshift( @$basketgroups, \%emptygroup );
223     }
224
225     # if the basket is closed, calculate estimated delivery date
226     my $estimateddeliverydate;
227     if( $basket->{closedate} ) {
228         my ($year, $month, $day) = ($basket->{closedate} =~ /(\d+)-(\d+)-(\d+)/);
229         ($year, $month, $day) = Add_Delta_Days($year, $month, $day, $bookseller->{deliverytime});
230         $estimateddeliverydate = "$year-$month-$day";
231     }
232
233     # if new basket, pre-fill infos
234     $basket->{creationdate} = ""            unless ( $basket->{creationdate} );
235     $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
236     $debug
237       and warn sprintf
238       "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
239       $basket->{creationdate}, $basket->{authorisedby};
240
241         #to get active currency
242         my $cur = GetCurrency();
243
244
245     my @results = GetOrders( $basketno );
246     
247         my $gist = $bookseller->{gstrate} // C4::Context->preference("gist") // 0;
248         $gist = 0 if $gist == 0.0000;
249         my $discount = $bookseller->{'discount'} / 100;
250     my $total_rrp = 0;      # RRP Total, its value will be assigned to $total_rrp_gsti or $total_rrp_gste depending of $bookseller->{'listincgst'}
251     my $total_rrp_gsti = 0; # RRP Total, GST included
252     my $total_rrp_gste = 0; # RRP Total, GST excluded
253     my $gist_rrp = 0;
254     my $total_rrp_est = 0;
255
256     my $qty_total;
257     my @books_loop;
258     my $suggestion;
259
260     for my $order ( @results ) {
261         my $rrp = $order->{'listprice'} || 0;
262                 my $qty = $order->{'quantity'} || 0;
263         if (!defined $order->{quantityreceived}) {
264             $order->{quantityreceived} = 0;
265         }
266         for ( qw(rrp ecost quantityreceived)) {
267             if (!defined $order->{$_}) {
268                 $order->{$_} = 0;
269             }
270         }
271
272         my $budget = GetBudget(  $order->{'budget_id'} );
273         $rrp = ConvertCurrency( $order->{'currency'}, $rrp );
274
275         $total_rrp += $qty * $order->{'rrp'};
276         my $line_total = $qty * $order->{'ecost'};
277         $total_rrp_est += $qty * $order->{'ecost'};
278                 # FIXME: what about the "actual cost" field?
279         $qty_total += $qty;
280         my %line = %{ $order };
281         my $biblionumber = $order->{'biblionumber'};
282         my $countbiblio = CountBiblioInOrders($biblionumber);
283         my $ordernumber = $order->{'ordernumber'};
284         my @subscriptions = GetSubscriptionsId ($biblionumber);
285         my $itemcount = GetItemsCount($biblionumber);
286         my $holds  = GetHolds ($biblionumber);
287         my @items = GetItemnumbersFromOrder( $ordernumber );
288         my $itemholds;
289         foreach my $item (@items){
290             my $nb = GetItemHolds($biblionumber, $item);
291             if ($nb){
292                 $itemholds += $nb;
293             }
294         }
295         # 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
296         $line{can_del_bib}          = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
297         $line{items}                = ($itemcount) - (scalar @items);
298         $line{left_item}            = 1 if $line{items} >= 1;
299         $line{left_biblio}          = 1 if $countbiblio > 1;
300         $line{biblios}              = $countbiblio - 1;
301         $line{left_subscription}    = 1 if scalar @subscriptions >= 1;
302         $line{subscriptions}        = scalar @subscriptions;
303         ($holds >= 1) ? $line{left_holds} = 1 : $line{left_holds} = 0;
304         $line{left_holds_on_order}  = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
305         $line{holds}                = $holds;
306         $line{holds_on_order}       = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
307         $line{order_received}       = ( $qty == $order->{'quantityreceived'} );
308         $line{basketno}             = $basketno;
309         $line{budget_name}          = $budget->{budget_name};
310         $line{rrp}                  = sprintf( "%.2f", $line{'rrp'} );
311         $line{ecost}                = sprintf( "%.2f", $line{'ecost'} );
312         $line{line_total}           = sprintf( "%.2f", $line_total );
313         if ($line{uncertainprice}) {
314             $template->param( uncertainprices => 1 );
315             $line{rrp} .= ' (Uncertain)';
316         }
317         if ($line{'title'}){
318             my $volume = $order->{'volume'};
319             my $seriestitle = $order->{'seriestitle'};
320             $line{'title'} .= " / $seriestitle" if $seriestitle;
321             $line{'title'} .= " / $volume" if $volume;
322         } else {
323             $line{'title'} = "Deleted bibliographic notice, can't find title.";
324         }
325
326         $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber});
327         $line{suggestionid}         = $suggestion->{suggestionid};
328         $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
329         $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
330
331         push @books_loop, \%line;
332     }
333
334 my $total_est_gste;
335     my $total_est_gsti;
336     my $gist_est;
337     if ($gist){                                                    # if we have GST
338        if ( $bookseller->{'listincgst'} ) {                        # if prices already includes GST
339            $total_rrp_gsti = $total_rrp;                           # we know $total_rrp_gsti
340            $total_rrp_gste = $total_rrp_gsti / ( $gist + 1 );      # and can reverse compute other values
341            $gist_rrp       = $total_rrp_gsti - $total_rrp_gste;    #
342            $total_est_gste = $total_rrp_gste - ( $total_rrp_gste * $discount );
343            $total_est_gsti = $total_rrp_est;
344         } else {                                                    # if prices does not include GST
345            $total_rrp_gste = $total_rrp;                           # then we use the common way to compute other values
346            $gist_rrp       = $total_rrp_gste * $gist;              #
347            $total_rrp_gsti = $total_rrp_gste + $gist_rrp;          #
348            $total_est_gste = $total_rrp_est;
349            $total_est_gsti = $total_rrp_gsti - ( $total_rrp_gsti * $discount );
350        }
351        $gist_est = $gist_rrp - ( $gist_rrp * $discount );
352     } else {
353     $total_rrp_gsti = $total_rrp;
354     $total_est_gsti = $total_rrp_est;
355 }
356
357     my $contract = &GetContract($basket->{contractnumber});
358     my @orders = GetOrders($basketno);
359
360     my $borrower= GetMember('borrowernumber' => $loggedinuser);
361     my $budgets = GetBudgetHierarchy;
362     my $has_budgets = 0;
363     foreach my $r (@{$budgets}) {
364         if (!defined $r->{budget_amount} || $r->{budget_amount} == 0) {
365             next;
366         }
367         next unless (CanUserUseBudget($loggedinuser, $r, $userflags));
368
369         $has_budgets = 1;
370         last;
371     }
372
373     my @cancelledorders = GetCancelledOrders($basketno);
374     foreach (@cancelledorders) {
375         $_->{'line_total'} = sprintf("%.2f", $_->{'ecost'} * $_->{'quantity'});
376     }
377
378     $template->param(
379         basketno             => $basketno,
380         basketname           => $basket->{'basketname'},
381         basketnote           => $basket->{note},
382         basketbooksellernote => $basket->{booksellernote},
383         basketcontractno     => $basket->{contractnumber},
384         basketcontractname   => $contract->{contractname},
385         creationdate         => $basket->{creationdate},
386         authorisedby         => $basket->{authorisedby},
387         authorisedbyname     => $basket->{authorisedbyname},
388         closedate            => $basket->{closedate},
389         estimateddeliverydate=> $estimateddeliverydate,
390         active               => $bookseller->{'active'},
391         booksellerid         => $bookseller->{'id'},
392         name                 => $bookseller->{'name'},
393         books_loop           => \@books_loop,
394         cancelledorders_loop => \@cancelledorders,
395         gist_rate            => sprintf( "%.2f", $gist * 100 ) . '%',
396         total_rrp_gste       => sprintf( "%.2f", $total_rrp_gste ),
397         total_est_gste       => sprintf( "%.2f", $total_est_gste ),
398         gist_est             => sprintf( "%.2f", $gist_est ),
399         gist_rrp             => sprintf( "%.2f", $gist_rrp ),        
400         total_rrp_gsti       => sprintf( "%.2f", $total_rrp_gsti ),
401         total_est_gsti       => sprintf( "%.2f", $total_est_gsti ),
402 #        currency             => $bookseller->{'listprice'},
403         currency                => $cur->{'currency'},
404         qty_total            => $qty_total,
405         GST                  => $gist,
406         basketgroups         => $basketgroups,
407         grouped              => $basket->{basketgroupid},
408         unclosable           => @orders ? 0 : 1, 
409         has_budgets          => $has_budgets,
410     );
411 }
412
413 output_html_with_http_headers $query, $cookie, $template->output;