Bug 6994: Wrong 'no budget defined' alert
[koha.git] / acqui / parcel.pl
1 #!/usr/bin/perl
2
3 #script to recieve orders
4
5
6 # Copyright 2000-2002 Katipo Communications
7 # Copyright 2008-2009 BibLibre SARL
8 #
9 # This file is part of Koha.
10 #
11 # Koha is free software; you can redistribute it and/or modify it under the
12 # terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
14 # version.
15 #
16 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License along
21 # with Koha; if not, write to the Free Software Foundation, Inc.,
22 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
24 =head1 NAME
25
26 parcel.pl
27
28 =head1 DESCRIPTION
29
30 This script shows all orders receipt or pending for a given supplier.
31 It allows to write an order as 'received' when he arrives.
32
33 =head1 CGI PARAMETERS
34
35 =over 4
36
37 =item supplierid
38
39 To know the supplier this script has to show orders.
40
41 =item code
42
43 is the bookseller invoice number.
44
45 =item freight
46
47
48 =item gst
49
50
51 =item datereceived
52
53 To filter the results list on this given date.
54
55 =back
56
57 =cut
58
59 use strict;
60 #use warnings; FIXME - Bug 2505
61 use C4::Auth;
62 use C4::Acquisition;
63 use C4::Budgets;
64 use C4::Bookseller qw/ GetBookSellerFromId /;
65 use C4::Biblio;
66 use C4::Items;
67 use CGI;
68 use C4::Output;
69 use C4::Dates qw/format_date format_date_in_iso/;
70 use JSON;
71
72 my $input=new CGI;
73 my $supplierid=$input->param('supplierid');
74 my $bookseller=GetBookSellerFromId($supplierid);
75
76 my $invoice=$input->param('invoice') || '';
77 my $freight=$input->param('freight');
78 my $input_gst = ($input->param('gst') eq '' ? undef : $input->param('gst'));
79 my $gst= $input_gst // $bookseller->{gstrate} // C4::Context->preference("gist") // 0;
80 my $datereceived =  ($input->param('op') eq 'new') ? C4::Dates->new($input->param('datereceived')) 
81                                         :  C4::Dates->new($input->param('datereceived'), 'iso')   ;
82 $datereceived = C4::Dates->new() unless $datereceived;
83 my $code            = $input->param('code');
84 my @rcv_err         = $input->param('error');
85 my @rcv_err_barcode = $input->param('error_bc');
86
87 my $startfrom=$input->param('startfrom');
88 my $resultsperpage = $input->param('resultsperpage');
89 $resultsperpage = 20 unless ($resultsperpage);
90 $startfrom=0 unless ($startfrom);
91
92 if($input->param('format') eq "json"){
93     my ($template, $loggedinuser, $cookie)
94         = get_template_and_user({template_name => "acqui/ajax.tmpl",
95                  query => $input,
96                                  type => "intranet",
97                  authnotrequired => 0,
98                  flagsrequired => {acquisition => 'order_receive'},
99                  debug => 1,
100     });
101        
102     my @datas;
103     my $search   = $input->param('search') || '';
104     my $supplier = $input->param('supplierid') || '';
105     my $basketno = $input->param('basketno') || '';
106     my $orderno  = $input->param('orderno') || '';
107
108     my $orders = SearchOrder($orderno, $search, $supplier, $basketno);
109     foreach my $order (@$orders){
110         if($order->{quantityreceived} < $order->{quantity}){
111             my $data = {};
112             
113             $data->{basketno} = $order->{basketno};
114             $data->{ordernumber} = $order->{ordernumber};
115             $data->{title} = $order->{title};
116             $data->{author} = $order->{author};
117             $data->{isbn} = $order->{isbn};
118             $data->{booksellerid} = $order->{booksellerid};
119             $data->{biblionumber} = $order->{biblionumber};
120             $data->{freight} = $order->{freight};
121             $data->{quantity} = $order->{quantity};
122             $data->{ecost} = $order->{ecost};
123             $data->{ordertotal} = sprintf("%.2f",$order->{ecost}*$order->{quantity});
124             push @datas, $data;
125         }
126     }
127     
128     my $json_text = to_json(\@datas);
129     $template->param(return => $json_text);
130     output_html_with_http_headers $input, $cookie, $template->output;
131     exit;
132 }
133
134 my ($template, $loggedinuser, $cookie)
135     = get_template_and_user({template_name => "acqui/parcel.tmpl",
136                  query => $input,
137                                  type => "intranet",
138                  authnotrequired => 0,
139                  flagsrequired => {acquisition => 'order_receive'},
140                  debug => 1,
141 });
142
143 # If receiving error, report the error (coming from finishrecieve.pl(sic)).
144 if( scalar(@rcv_err) ) {
145         my $cnt=0;
146         my $error_loop;
147         for my $err (@rcv_err) {
148                 push @$error_loop, { "error_$err" => 1 , barcode => $rcv_err_barcode[$cnt] };
149                 $cnt++;
150         }
151         $template->param( receive_error => 1 ,
152                                                 error_loop => $error_loop,
153                                         );
154 }
155
156 my $cfstr         = "%.2f";                                                           # currency format string -- could get this from currency table.
157 my @parcelitems   = GetParcel($supplierid, $invoice, $datereceived->output('iso'));
158 my $countlines    = scalar @parcelitems;
159 my $totalprice    = 0;
160 my $totalfreight  = 0;
161 my $totalquantity = 0;
162 my $total;
163 my $tototal;
164 my @loop_received = ();
165
166 for (my $i = 0 ; $i < $countlines ; $i++) {
167
168     #$total=($parcelitems[$i]->{'unitprice'} + $parcelitems[$i]->{'freight'}) * $parcelitems[$i]->{'quantityreceived'};   #weird, are the freight fees counted by book? (pierre)
169     $total = ($parcelitems[$i]->{'unitprice'}) * $parcelitems[$i]->{'quantityreceived'};    #weird, are the freight fees counted by book? (pierre)
170     $parcelitems[$i]->{'unitprice'} += 0;
171     my %line;
172     %line          = %{ $parcelitems[$i] };
173     $line{invoice} = $invoice;
174     $line{gst}     = $gst;
175     $line{total} = sprintf($cfstr, $total);
176     $line{supplierid} = $supplierid;
177     push @loop_received, \%line;
178     $totalprice += $parcelitems[$i]->{'unitprice'};
179     $line{unitprice} = sprintf($cfstr, $parcelitems[$i]->{'unitprice'});
180
181     #double FIXME - totalfreight is redefined later.
182
183 # FIXME - each order in a  parcel holds the freight for the whole parcel. This means if you receive a parcel with items from multiple budgets, you'll see the freight charge in each budget..
184     if ($i > 0 && $totalfreight != $parcelitems[$i]->{'freight'}) {
185         warn "FREIGHT CHARGE MISMATCH!!";
186     }
187     $totalfreight = $parcelitems[$i]->{'freight'};
188     $totalquantity += $parcelitems[$i]->{'quantityreceived'};
189     $tototal       += $total;
190 }
191
192 my $pendingorders = GetPendingOrders($supplierid);
193 my $countpendings = scalar @$pendingorders;
194
195 # pending orders totals
196 my ($totalPunitprice, $totalPquantity, $totalPecost, $totalPqtyrcvd);
197 my $ordergrandtotal;
198 my @loop_orders = ();
199 for (my $i = 0 ; $i < $countpendings ; $i++) {
200     my %line;
201     %line = %{$pendingorders->[$i]};
202    
203     $line{quantity}+=0;
204     $line{quantityreceived}+=0;
205     $line{unitprice}+=0;
206     $totalPunitprice += $line{unitprice};
207     $totalPquantity +=$line{quantity};
208     $totalPqtyrcvd +=$line{quantityreceived};
209     $totalPecost += $line{ecost};
210     $line{ecost} = sprintf("%.2f",$line{ecost});
211     $line{ordertotal} = sprintf("%.2f",$line{ecost}*$line{quantity});
212     $line{unitprice} = sprintf("%.2f",$line{unitprice});
213     $line{invoice} = $invoice;
214     $line{gst} = $gst;
215     $line{total} = $total;
216     $line{supplierid} = $supplierid;
217     $ordergrandtotal += $line{ecost} * $line{quantity};
218     
219     my $biblionumber = $line{'biblionumber'};
220     my $countbiblio = CountBiblioInOrders($biblionumber);
221     my $ordernumber = $line{'ordernumber'};
222     my @subscriptions = GetSubscriptionsId ($biblionumber);
223     my $itemcount = GetItemsCount($biblionumber);
224     my $holds  = GetHolds ($biblionumber);
225     my @items = GetItemnumbersFromOrder( $ordernumber );
226     my $itemholds;
227     foreach my $item (@items){
228         my $nb = GetItemHolds($biblionumber, $item);
229         if ($nb){
230             $itemholds += $nb;
231         }
232     }
233     
234     # 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
235     $line{can_del_bib}          = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
236     $line{items}                = ($itemcount) - (scalar @items);
237     $line{left_item}            = 1 if $line{items} >= 1;
238     $line{left_biblio}          = 1 if $countbiblio > 1;
239     $line{biblios}              = $countbiblio - 1;
240     $line{left_subscription}    = 1 if scalar @subscriptions >= 1;
241     $line{subscriptions}        = scalar @subscriptions;
242     $line{left_holds}           = 1 if $holds >= 1;
243     $line{left_holds_on_order}  = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
244     $line{holds}                = $holds;
245     $line{holds_on_order}       = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
246     
247     
248     push @loop_orders, \%line if ($i >= $startfrom and $i < $startfrom + $resultsperpage);
249 }
250 $freight = $totalfreight unless $freight;
251
252 my $count = $countpendings;
253
254 if ($count>$resultsperpage){
255     my $displaynext=0;
256     my $displayprev=$startfrom;
257     if(($count - ($startfrom+$resultsperpage)) > 0 ) {
258         $displaynext = 1;
259     }
260
261     my @numbers = ();
262     for (my $i=1; $i<$count/$resultsperpage+1; $i++) {
263             my $highlight=0;
264             ($startfrom/$resultsperpage==($i-1)) && ($highlight=1);
265             push @numbers, { number => $i,
266                 highlight => $highlight ,
267                 startfrom => ($i-1)*$resultsperpage};
268     }
269
270     my $from = $startfrom*$resultsperpage+1;
271     my $to;
272     if($count < (($startfrom+1)*$resultsperpage)){
273         $to = $count;
274     } else {
275         $to = (($startfrom+1)*$resultsperpage);
276     }
277     $template->param(numbers=>\@numbers,
278                      displaynext=>$displaynext,
279                      displayprev=>$displayprev,
280                      nextstartfrom=>(($startfrom+$resultsperpage<$count)?$startfrom+$resultsperpage:$count),
281                      prevstartfrom=>(($startfrom-$resultsperpage>0)?$startfrom-$resultsperpage:0)
282                     );
283 }
284
285 #$totalfreight=$freight;
286 $tototal = $tototal + $freight;
287
288 $template->param(
289     invoice               => $invoice,
290     datereceived          => $datereceived->output('iso'),
291     invoicedatereceived   => $datereceived->output('iso'),
292     formatteddatereceived => $datereceived->output(),
293     name                  => $bookseller->{'name'},
294     supplierid            => $supplierid,
295     gst                   => $gst,
296     freight               => $freight,
297     invoice               => $invoice,
298     countreceived         => $countlines,
299     loop_received         => \@loop_received,
300     countpending          => $countpendings,
301     loop_orders           => \@loop_orders,
302     totalprice            => sprintf($cfstr, $totalprice),
303     totalfreight          => $totalfreight,
304     totalquantity         => $totalquantity,
305     tototal               => sprintf($cfstr, $tototal),
306     ordergrandtotal       => sprintf($cfstr, $ordergrandtotal),
307     gst                   => $gst,
308     grandtot              => sprintf($cfstr, $tototal + $gst),
309     totalPunitprice       => sprintf("%.2f", $totalPunitprice),
310     totalPquantity        => $totalPquantity,
311     totalPqtyrcvd         => $totalPqtyrcvd,
312     totalPecost           => sprintf("%.2f", $totalPecost),
313     resultsperpage        => $resultsperpage,
314 );
315 output_html_with_http_headers $input, $cookie, $template->output;
316