Merge remote-tracking branch 'origin/new/bug_8597'
[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
46 =item gst
47
48
49 =item datereceived
50
51 To filter the results list on this given date.
52
53 =back
54
55 =cut
56
57 use strict;
58 use warnings;
59
60 use C4::Auth;
61 use C4::Acquisition;
62 use C4::Budgets;
63 use C4::Bookseller qw/ GetBookSellerFromId /;
64 use C4::Biblio;
65 use C4::Items;
66 use CGI;
67 use C4::Output;
68 use C4::Dates qw/format_date format_date_in_iso/;
69 use C4::Suggestions;
70 use JSON;
71
72 my $input=new CGI;
73
74 my ($template, $loggedinuser, $cookie)
75     = get_template_and_user({template_name => "acqui/parcel.tmpl",
76                  query => $input,
77                  type => "intranet",
78                  authnotrequired => 0,
79                  flagsrequired => {acquisition => 'order_receive'},
80                  debug => 1,
81 });
82
83 my $invoiceid = $input->param('invoiceid');
84 my $op = $input->param('op') // '';
85
86 if ($op eq 'cancelreceipt') {
87     my $ordernumber = $input->param('ordernumber');
88     my $parent_ordernumber = CancelReceipt($ordernumber);
89     unless($parent_ordernumber) {
90         $template->param(error_cancelling_receipt => 1);
91     }
92 }
93
94 my $invoice = GetInvoiceDetails($invoiceid);
95 my $booksellerid = $invoice->{booksellerid};
96 my $bookseller = GetBookSellerFromId($booksellerid);
97 my $gst = $bookseller->{gstrate} // C4::Context->preference("gist") // 0;
98 my $datereceived = C4::Dates->new();
99 my $code            = $input->param('code');
100 my @rcv_err         = $input->param('error');
101 my @rcv_err_barcode = $input->param('error_bc');
102 my $startfrom=$input->param('startfrom');
103 my $resultsperpage = $input->param('resultsperpage');
104 $resultsperpage = 20 unless ($resultsperpage);
105 $startfrom=0 unless ($startfrom);
106
107
108
109 # If receiving error, report the error (coming from finishrecieve.pl(sic)).
110 if( scalar(@rcv_err) ) {
111         my $cnt=0;
112         my $error_loop;
113         for my $err (@rcv_err) {
114                 push @$error_loop, { "error_$err" => 1 , barcode => $rcv_err_barcode[$cnt] };
115                 $cnt++;
116         }
117         $template->param( receive_error => 1 ,
118                                                 error_loop => $error_loop,
119                                         );
120 }
121
122 my $cfstr         = "%.2f";                                                           # currency format string -- could get this from currency table.
123 my @parcelitems   = @{ $invoice->{orders} };
124 my $countlines    = scalar @parcelitems;
125 my $totalprice    = 0;
126 my $totalquantity = 0;
127 my $total;
128 my $tototal;
129 my @loop_received = ();
130
131 for (my $i = 0 ; $i < $countlines ; $i++) {
132
133     $total = ($parcelitems[$i]->{'unitprice'}) * $parcelitems[$i]->{'quantityreceived'};
134     $parcelitems[$i]->{'unitprice'} += 0;
135     my %line;
136     %line          = %{ $parcelitems[$i] };
137     $line{invoice} = $invoice->{invoicenumber};
138     $line{gst}     = $gst;
139     $line{total} = sprintf($cfstr, $total);
140     $line{booksellerid} = $invoice->{booksellerid};
141     $totalprice += $parcelitems[$i]->{'unitprice'};
142     $line{unitprice} = sprintf($cfstr, $parcelitems[$i]->{'unitprice'});
143
144     my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
145     $line{suggestionid}         = $suggestion->{suggestionid};
146     $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
147     $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
148
149     if ( $line{parent_ordernumber} != $line{ordernumber} ) {
150         if ( grep { $_->{ordernumber} == $line{parent_ordernumber} }
151             @parcelitems )
152         {
153             $line{cannot_cancel} = 1;
154         }
155     }
156
157     push @loop_received, \%line;
158     $totalquantity += $parcelitems[$i]->{'quantityreceived'};
159     $tototal       += $total;
160 }
161
162 if(!defined $invoice->{closedate}) {
163     my $pendingorders;
164     if($input->param('op') eq "search"){
165         my $search   = $input->param('summaryfilter') || '';
166         my $ean      = $input->param('eanfilter') || '';
167         my $basketno = $input->param('basketfilter') || '';
168         my $orderno  = $input->param('orderfilter') || '';
169         my $grouped;
170         my $owner;
171         $pendingorders = GetPendingOrders($booksellerid,$grouped,$owner,$basketno,$orderno,$search,$ean);
172     }else{
173         $pendingorders = GetPendingOrders($booksellerid);
174     }
175     my $countpendings = scalar @$pendingorders;
176
177     # pending orders totals
178     my ($totalPunitprice, $totalPquantity, $totalPecost, $totalPqtyrcvd);
179     my $ordergrandtotal;
180     my @loop_orders = ();
181     for (my $i = 0 ; $i < $countpendings ; $i++) {
182         my %line;
183         %line = %{$pendingorders->[$i]};
184
185         $line{quantity}+=0;
186         $line{quantityreceived}+=0;
187         $line{unitprice}+=0;
188         $totalPunitprice += $line{unitprice};
189         $totalPquantity +=$line{quantity};
190         $totalPqtyrcvd +=$line{quantityreceived};
191         $totalPecost += $line{ecost};
192         $line{ecost} = sprintf("%.2f",$line{ecost});
193         $line{ordertotal} = sprintf("%.2f",$line{ecost}*$line{quantity});
194         $line{unitprice} = sprintf("%.2f",$line{unitprice});
195         $line{invoice} = $invoice;
196         $line{gst} = $gst;
197         $line{total} = $total;
198         $line{booksellerid} = $booksellerid;
199         $ordergrandtotal += $line{ecost} * $line{quantity};
200
201         my $biblionumber = $line{'biblionumber'};
202         my $countbiblio = CountBiblioInOrders($biblionumber);
203         my $ordernumber = $line{'ordernumber'};
204         my @subscriptions = GetSubscriptionsId ($biblionumber);
205         my $itemcount = GetItemsCount($biblionumber);
206         my $holds  = GetHolds ($biblionumber);
207         my @items = GetItemnumbersFromOrder( $ordernumber );
208         my $itemholds;
209         foreach my $item (@items){
210             my $nb = GetItemHolds($biblionumber, $item);
211             if ($nb){
212                 $itemholds += $nb;
213             }
214         }
215
216         my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
217         $line{suggestionid}         = $suggestion->{suggestionid};
218         $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
219         $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
220
221         # 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
222         $line{can_del_bib}          = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
223         $line{items}                = ($itemcount) - (scalar @items);
224         $line{left_item}            = 1 if $line{items} >= 1;
225         $line{left_biblio}          = 1 if $countbiblio > 1;
226         $line{biblios}              = $countbiblio - 1;
227         $line{left_subscription}    = 1 if scalar @subscriptions >= 1;
228         $line{subscriptions}        = scalar @subscriptions;
229         $line{left_holds}           = ($holds >= 1) ? 1 : 0;
230         $line{left_holds_on_order}  = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
231         $line{holds}                = $holds;
232         $line{holds_on_order}       = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
233
234
235         push @loop_orders, \%line if ($i >= $startfrom and $i < $startfrom + $resultsperpage);
236     }
237
238     my $count = $countpendings;
239
240     if ($count>$resultsperpage){
241         my $displaynext=0;
242         my $displayprev=$startfrom;
243         if(($count - ($startfrom+$resultsperpage)) > 0 ) {
244             $displaynext = 1;
245         }
246
247         my @numbers = ();
248         for (my $i=1; $i<$count/$resultsperpage+1; $i++) {
249                 my $highlight=0;
250                 ($startfrom/$resultsperpage==($i-1)) && ($highlight=1);
251                 push @numbers, { number => $i,
252                     highlight => $highlight ,
253                     startfrom => ($i-1)*$resultsperpage};
254         }
255
256         my $from = $startfrom*$resultsperpage+1;
257         my $to;
258         if($count < (($startfrom+1)*$resultsperpage)){
259             $to = $count;
260         } else {
261             $to = (($startfrom+1)*$resultsperpage);
262         }
263         $template->param(numbers=>\@numbers,
264                          displaynext=>$displaynext,
265                          displayprev=>$displayprev,
266                          nextstartfrom=>(($startfrom+$resultsperpage<$count)?$startfrom+$resultsperpage:$count),
267                          prevstartfrom=>(($startfrom-$resultsperpage>0)?$startfrom-$resultsperpage:0)
268                         );
269     }
270
271     $template->param(
272         countpending => $countpendings,
273         loop_orders  => \@loop_orders,
274         ordergrandtotal => sprintf($cfstr, $ordergrandtotal),
275         totalPunitprice => sprintf("%.2f", $totalPunitprice),
276         totalPquantity  => $totalPquantity,
277         totalPqtyrcvd   => $totalPqtyrcvd,
278         totalPecost     => sprintf("%.2f", $totalPecost),
279     );
280 }
281
282
283 $template->param(
284     invoiceid             => $invoice->{invoiceid},
285     invoice               => $invoice->{invoicenumber},
286     invoiceclosedate      => $invoice->{closedate},
287     datereceived          => $datereceived->output('iso'),
288     invoicedatereceived   => $datereceived->output('iso'),
289     formatteddatereceived => $datereceived->output(),
290     name                  => $bookseller->{'name'},
291     booksellerid          => $bookseller->{id},
292     gst                   => $gst,
293     countreceived         => $countlines,
294     loop_received         => \@loop_received,
295     totalprice            => sprintf($cfstr, $totalprice),
296     totalquantity         => $totalquantity,
297     tototal               => sprintf($cfstr, $tototal),
298     gst                   => $gst,
299     grandtot              => sprintf($cfstr, $tototal + $gst),
300     resultsperpage        => $resultsperpage,
301     (uc(C4::Context->preference("marcflavour"))) => 1
302 );
303 output_html_with_http_headers $input, $cookie, $template->output;