Merge remote-tracking branch 'origin/new/bug_7805'
[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 booksellerid
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 C4::Suggestions;
71 use JSON;
72
73 my $input=new CGI;
74 my $booksellerid=$input->param('booksellerid');
75 my $bookseller=GetBookSellerFromId($booksellerid);
76
77 my $invoice=$input->param('invoice') || '';
78 my $freight=$input->param('freight');
79 my $input_gst = ($input->param('gst') eq '' ? undef : $input->param('gst'));
80 my $gst= $input_gst // $bookseller->{gstrate} // C4::Context->preference("gist") // 0;
81 my $datereceived =  ($input->param('op') eq 'new') ? C4::Dates->new($input->param('datereceived')) 
82                                         :  C4::Dates->new($input->param('datereceived'), 'iso')   ;
83 $datereceived = C4::Dates->new() unless $datereceived;
84 my $code            = $input->param('code');
85 my @rcv_err         = $input->param('error');
86 my @rcv_err_barcode = $input->param('error_bc');
87
88 my $startfrom=$input->param('startfrom');
89 my $resultsperpage = $input->param('resultsperpage');
90 $resultsperpage = 20 unless ($resultsperpage);
91 $startfrom=0 unless ($startfrom);
92
93 if($input->param('format') eq "json"){
94     my ($template, $loggedinuser, $cookie)
95         = get_template_and_user({template_name => "acqui/ajax.tmpl",
96                  query => $input,
97                                  type => "intranet",
98                  authnotrequired => 0,
99                  flagsrequired => {acquisition => 'order_receive'},
100                  debug => 1,
101     });
102        
103     my @datas;
104     my $search   = $input->param('search')     || '';
105     my $ean      = $input->param('ean')        || '';
106     my $supplier = $input->param('booksellerid') || '';
107     my $basketno = $input->param('basketno') || '';
108     my $orderno  = $input->param('orderno') || '';
109
110     my $orders = SearchOrder($orderno, $search, $ean, $supplier, $basketno);
111     foreach my $order (@$orders) {
112         if ( $order->{quantityreceived} < $order->{quantity} ) {
113             my $data = {};
114             
115             $data->{basketno} = $order->{basketno};
116             $data->{ordernumber} = $order->{ordernumber};
117             $data->{title} = $order->{title};
118             $data->{author} = $order->{author};
119             $data->{isbn} = $order->{isbn};
120             $data->{booksellerid} = $order->{booksellerid};
121             $data->{biblionumber} = $order->{biblionumber};
122             $data->{freight} = $order->{freight};
123             $data->{quantity} = $order->{quantity};
124             $data->{ecost} = $order->{ecost};
125             $data->{ordertotal} = sprintf("%.2f",$order->{ecost}*$order->{quantity});
126             push @datas, $data;
127         }
128     }
129     
130     my $json_text = to_json(\@datas);
131     $template->param(return => $json_text);
132     output_html_with_http_headers $input, $cookie, $template->output;
133     exit;
134 }
135
136 my ($template, $loggedinuser, $cookie)
137     = get_template_and_user({template_name => "acqui/parcel.tmpl",
138                  query => $input,
139                                  type => "intranet",
140                  authnotrequired => 0,
141                  flagsrequired => {acquisition => 'order_receive'},
142                  debug => 1,
143 });
144
145 # If receiving error, report the error (coming from finishrecieve.pl(sic)).
146 if( scalar(@rcv_err) ) {
147         my $cnt=0;
148         my $error_loop;
149         for my $err (@rcv_err) {
150                 push @$error_loop, { "error_$err" => 1 , barcode => $rcv_err_barcode[$cnt] };
151                 $cnt++;
152         }
153         $template->param( receive_error => 1 ,
154                                                 error_loop => $error_loop,
155                                         );
156 }
157
158 my $cfstr         = "%.2f";                                                           # currency format string -- could get this from currency table.
159 my @parcelitems   = GetParcel($booksellerid, $invoice, $datereceived->output('iso'));
160 my $countlines    = scalar @parcelitems;
161 my $totalprice    = 0;
162 my $totalfreight  = 0;
163 my $totalquantity = 0;
164 my $total;
165 my $tototal;
166 my @loop_received = ();
167
168 for (my $i = 0 ; $i < $countlines ; $i++) {
169
170     #$total=($parcelitems[$i]->{'unitprice'} + $parcelitems[$i]->{'freight'}) * $parcelitems[$i]->{'quantityreceived'};   #weird, are the freight fees counted by book? (pierre)
171     $total = ($parcelitems[$i]->{'unitprice'}) * $parcelitems[$i]->{'quantityreceived'};    #weird, are the freight fees counted by book? (pierre)
172     $parcelitems[$i]->{'unitprice'} += 0;
173     my %line;
174     %line          = %{ $parcelitems[$i] };
175     $line{invoice} = $invoice;
176     $line{gst}     = $gst;
177     $line{total} = sprintf($cfstr, $total);
178     $line{booksellerid} = $booksellerid;
179     push @loop_received, \%line;
180     $totalprice += $parcelitems[$i]->{'unitprice'};
181     $line{unitprice} = sprintf($cfstr, $parcelitems[$i]->{'unitprice'});
182
183     my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
184     $line{suggestionid}         = $suggestion->{suggestionid};
185     $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
186     $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
187
188     #double FIXME - totalfreight is redefined later.
189
190 # 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..
191     if ($i > 0 && $totalfreight != $parcelitems[$i]->{'freight'}) {
192         warn "FREIGHT CHARGE MISMATCH!!";
193     }
194     $totalfreight = $parcelitems[$i]->{'freight'};
195     $totalquantity += $parcelitems[$i]->{'quantityreceived'};
196     $tototal       += $total;
197 }
198
199 my $pendingorders = GetPendingOrders($booksellerid);
200 my $countpendings = scalar @$pendingorders;
201
202 # pending orders totals
203 my ($totalPunitprice, $totalPquantity, $totalPecost, $totalPqtyrcvd);
204 my $ordergrandtotal;
205 my @loop_orders = ();
206 for (my $i = 0 ; $i < $countpendings ; $i++) {
207     my %line;
208     %line = %{$pendingorders->[$i]};
209    
210     $line{quantity}+=0;
211     $line{quantityreceived}+=0;
212     $line{unitprice}+=0;
213     $totalPunitprice += $line{unitprice};
214     $totalPquantity +=$line{quantity};
215     $totalPqtyrcvd +=$line{quantityreceived};
216     $totalPecost += $line{ecost};
217     $line{ecost} = sprintf("%.2f",$line{ecost});
218     $line{ordertotal} = sprintf("%.2f",$line{ecost}*$line{quantity});
219     $line{unitprice} = sprintf("%.2f",$line{unitprice});
220     $line{invoice} = $invoice;
221     $line{gst} = $gst;
222     $line{total} = $total;
223     $line{booksellerid} = $booksellerid;
224     $ordergrandtotal += $line{ecost} * $line{quantity};
225     
226     my $biblionumber = $line{'biblionumber'};
227     my $countbiblio = CountBiblioInOrders($biblionumber);
228     my $ordernumber = $line{'ordernumber'};
229     my @subscriptions = GetSubscriptionsId ($biblionumber);
230     my $itemcount = GetItemsCount($biblionumber);
231     my $holds  = GetHolds ($biblionumber);
232     my @items = GetItemnumbersFromOrder( $ordernumber );
233     my $itemholds;
234     foreach my $item (@items){
235         my $nb = GetItemHolds($biblionumber, $item);
236         if ($nb){
237             $itemholds += $nb;
238         }
239     }
240
241     my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
242     $line{suggestionid}         = $suggestion->{suggestionid};
243     $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
244     $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
245
246     # 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
247     $line{can_del_bib}          = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
248     $line{items}                = ($itemcount) - (scalar @items);
249     $line{left_item}            = 1 if $line{items} >= 1;
250     $line{left_biblio}          = 1 if $countbiblio > 1;
251     $line{biblios}              = $countbiblio - 1;
252     $line{left_subscription}    = 1 if scalar @subscriptions >= 1;
253     $line{subscriptions}        = scalar @subscriptions;
254     $line{left_holds}           = 1 if $holds >= 1;
255     $line{left_holds_on_order}  = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
256     $line{holds}                = $holds;
257     $line{holds_on_order}       = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
258     
259     
260     push @loop_orders, \%line if ($i >= $startfrom and $i < $startfrom + $resultsperpage);
261 }
262 $freight = $totalfreight unless $freight;
263
264 my $count = $countpendings;
265
266 if ($count>$resultsperpage){
267     my $displaynext=0;
268     my $displayprev=$startfrom;
269     if(($count - ($startfrom+$resultsperpage)) > 0 ) {
270         $displaynext = 1;
271     }
272
273     my @numbers = ();
274     for (my $i=1; $i<$count/$resultsperpage+1; $i++) {
275             my $highlight=0;
276             ($startfrom/$resultsperpage==($i-1)) && ($highlight=1);
277             push @numbers, { number => $i,
278                 highlight => $highlight ,
279                 startfrom => ($i-1)*$resultsperpage};
280     }
281
282     my $from = $startfrom*$resultsperpage+1;
283     my $to;
284     if($count < (($startfrom+1)*$resultsperpage)){
285         $to = $count;
286     } else {
287         $to = (($startfrom+1)*$resultsperpage);
288     }
289     $template->param(numbers=>\@numbers,
290                      displaynext=>$displaynext,
291                      displayprev=>$displayprev,
292                      nextstartfrom=>(($startfrom+$resultsperpage<$count)?$startfrom+$resultsperpage:$count),
293                      prevstartfrom=>(($startfrom-$resultsperpage>0)?$startfrom-$resultsperpage:0)
294                     );
295 }
296
297 #$totalfreight=$freight;
298 $tototal = $tototal + $freight;
299
300 $template->param(
301     invoice               => $invoice,
302     datereceived          => $datereceived->output('iso'),
303     invoicedatereceived   => $datereceived->output('iso'),
304     formatteddatereceived => $datereceived->output(),
305     name                  => $bookseller->{'name'},
306     booksellerid            => $booksellerid,
307     gst                   => $gst,
308     freight               => $freight,
309     invoice               => $invoice,
310     countreceived         => $countlines,
311     loop_received         => \@loop_received,
312     countpending          => $countpendings,
313     loop_orders           => \@loop_orders,
314     totalprice            => sprintf($cfstr, $totalprice),
315     totalfreight          => $totalfreight,
316     totalquantity         => $totalquantity,
317     tototal               => sprintf($cfstr, $tototal),
318     ordergrandtotal       => sprintf($cfstr, $ordergrandtotal),
319     gst                   => $gst,
320     grandtot              => sprintf($cfstr, $tototal + $gst),
321     totalPunitprice       => sprintf("%.2f", $totalPunitprice),
322     totalPquantity        => $totalPquantity,
323     totalPqtyrcvd         => $totalPqtyrcvd,
324     totalPecost           => sprintf("%.2f", $totalPecost),
325     resultsperpage        => $resultsperpage,
326     (uc(C4::Context->preference("marcflavour"))) => 1
327 );
328 output_html_with_http_headers $input, $cookie, $template->output;
329