Merge branch 'bug_9134' into 3.12-master
[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 sub get_value_with_gst_params {
75     my $value = shift;
76     my $gstrate = shift;
77     my $bookseller = shift;
78     if ( $bookseller->{listincgst} ) {
79         if ( $bookseller->{invoiceincgst} ) {
80             return $value;
81         } else {
82             return $value / ( 1 + $gstrate );
83         }
84     } else {
85         if ( $bookseller->{invoiceincgst} ) {
86             return $value * ( 1 + $gstrate );
87         } else {
88             return $value;
89         }
90     }
91 }
92
93 sub get_gste {
94     my $value = shift;
95     my $gstrate = shift;
96     my $bookseller = shift;
97     return $bookseller->{invoiceincgst}
98         ? $value / ( 1 + $gstrate )
99         : $value;
100 }
101
102 sub get_gst {
103     my $value = shift;
104     my $gstrate = shift;
105     my $bookseller = shift;
106     return $bookseller->{invoiceincgst}
107         ? $value / ( 1 + $gstrate ) * $gstrate
108         : $value * ( 1 + $gstrate ) - $value;
109 }
110
111 my ($template, $loggedinuser, $cookie)
112     = get_template_and_user({template_name => "acqui/parcel.tmpl",
113                  query => $input,
114                  type => "intranet",
115                  authnotrequired => 0,
116                  flagsrequired => {acquisition => 'order_receive'},
117                  debug => 1,
118 });
119
120 my $invoiceid = $input->param('invoiceid');
121 my $op = $input->param('op') // '';
122
123 if ($op eq 'cancelreceipt') {
124     my $ordernumber = $input->param('ordernumber');
125     my $parent_ordernumber = CancelReceipt($ordernumber);
126     unless($parent_ordernumber) {
127         $template->param(error_cancelling_receipt => 1);
128     }
129 }
130
131 my $invoice = GetInvoiceDetails($invoiceid);
132 my $booksellerid = $invoice->{booksellerid};
133 my $bookseller = GetBookSellerFromId($booksellerid);
134 my $gst = $bookseller->{gstrate} // C4::Context->preference("gist") // 0;
135 my $datereceived = C4::Dates->new();
136 my $code            = $input->param('code');
137 my @rcv_err         = $input->param('error');
138 my @rcv_err_barcode = $input->param('error_bc');
139 my $startfrom=$input->param('startfrom');
140 my $resultsperpage = $input->param('resultsperpage');
141 $resultsperpage = 20 unless ($resultsperpage);
142 $startfrom=0 unless ($startfrom);
143
144
145
146 # If receiving error, report the error (coming from finishrecieve.pl(sic)).
147 if( scalar(@rcv_err) ) {
148         my $cnt=0;
149         my $error_loop;
150         for my $err (@rcv_err) {
151                 push @$error_loop, { "error_$err" => 1 , barcode => $rcv_err_barcode[$cnt] };
152                 $cnt++;
153         }
154         $template->param( receive_error => 1 ,
155                                                 error_loop => $error_loop,
156                                         );
157 }
158
159 my $cfstr         = "%.2f";                                                           # currency format string -- could get this from currency table.
160 my @parcelitems   = @{ $invoice->{orders} };
161 my $countlines    = scalar @parcelitems;
162 my $totalprice    = 0;
163 my $totalquantity = 0;
164 my $total;
165 my @loop_received = ();
166 my @book_foot_loop;
167 my %foot;
168 my $total_quantity = 0;
169 my $total_gste = 0;
170 my $total_gsti = 0;
171
172 for my $item ( @parcelitems ) {
173     $item->{unitprice} = get_value_with_gst_params( $item->{unitprice}, $item->{gstrate}, $bookseller );
174     $total = ( $item->{'unitprice'} ) * $item->{'quantityreceived'};
175     $item->{'unitprice'} += 0;
176     my %line;
177     %line          = %{ $item };
178     my $ecost = get_value_with_gst_params( $line{ecost}, $line{gstrate}, $bookseller );
179     $line{ecost} = sprintf( "%.2f", $ecost );
180     $line{invoice} = $invoice->{invoicenumber};
181     $line{total} = sprintf($cfstr, $total);
182     $line{booksellerid} = $invoice->{booksellerid};
183     $totalprice += $item->{'unitprice'};
184     $line{unitprice} = sprintf( $cfstr, $item->{'unitprice'} );
185     my $gste = get_gste( $line{total}, $line{gstrate}, $bookseller );
186     my $gst = get_gst( $line{total}, $line{gstrate}, $bookseller );
187     $foot{$line{gstrate}}{gstrate} = $line{gstrate};
188     $foot{$line{gstrate}}{value} += sprintf( "%.2f", $gst );
189     $total_quantity += $line{quantity};
190     $total_gste += $gste;
191     $total_gsti += $gste + $gst;
192
193     my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
194     $line{suggestionid}         = $suggestion->{suggestionid};
195     $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
196     $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
197
198     if ( $line{parent_ordernumber} != $line{ordernumber} ) {
199         if ( grep { $_->{ordernumber} == $line{parent_ordernumber} }
200             @parcelitems )
201         {
202             $line{cannot_cancel} = 1;
203         }
204     }
205
206     my $budget = GetBudget( $line{budget_id} );
207     $line{budget_name} = $budget->{'budget_name'};
208
209     push @loop_received, \%line;
210     $totalquantity += $item->{'quantityreceived'};
211
212 }
213 push @book_foot_loop, map { $_ } values %foot;
214
215 my @loop_orders = ();
216 if(!defined $invoice->{closedate}) {
217     my $pendingorders;
218     if($input->param('op') eq "search"){
219         my $search   = $input->param('summaryfilter') || '';
220         my $ean      = $input->param('eanfilter') || '';
221         my $basketno = $input->param('basketfilter') || '';
222         my $orderno  = $input->param('orderfilter') || '';
223         my $grouped;
224         my $owner;
225         $pendingorders = GetPendingOrders($booksellerid,$grouped,$owner,$basketno,$orderno,$search,$ean);
226     }else{
227         $pendingorders = GetPendingOrders($booksellerid);
228     }
229     my $countpendings = scalar @$pendingorders;
230
231     for (my $i = 0 ; $i < $countpendings ; $i++) {
232         my %line;
233         %line = %{$pendingorders->[$i]};
234
235         my $ecost = get_value_with_gst_params( $line{ecost}, $line{gstrate}, $bookseller );
236         $line{unitprice} = get_value_with_gst_params( $line{unitprice}, $line{gstrate}, $bookseller );
237         $line{quantity} += 0;
238         $line{quantityreceived} += 0;
239         $line{unitprice}+=0;
240         $line{ecost} = sprintf( "%.2f", $ecost );
241         $line{ordertotal} = sprintf( "%.2f", $ecost * $line{quantity} );
242         $line{unitprice} = sprintf("%.2f",$line{unitprice});
243         $line{invoice} = $invoice;
244         $line{booksellerid} = $booksellerid;
245
246
247
248         my $biblionumber = $line{'biblionumber'};
249         my $countbiblio = CountBiblioInOrders($biblionumber);
250         my $ordernumber = $line{'ordernumber'};
251         my @subscriptions = GetSubscriptionsId ($biblionumber);
252         my $itemcount = GetItemsCount($biblionumber);
253         my $holds  = GetHolds ($biblionumber);
254         my @items = GetItemnumbersFromOrder( $ordernumber );
255         my $itemholds;
256         foreach my $item (@items){
257             my $nb = GetItemHolds($biblionumber, $item);
258             if ($nb){
259                 $itemholds += $nb;
260             }
261         }
262
263         my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
264         $line{suggestionid}         = $suggestion->{suggestionid};
265         $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
266         $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
267
268         # 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
269         $line{can_del_bib}          = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
270         $line{items}                = ($itemcount) - (scalar @items);
271         $line{left_item}            = 1 if $line{items} >= 1;
272         $line{left_biblio}          = 1 if $countbiblio > 1;
273         $line{biblios}              = $countbiblio - 1;
274         $line{left_subscription}    = 1 if scalar @subscriptions >= 1;
275         $line{subscriptions}        = scalar @subscriptions;
276         $line{left_holds}           = ($holds >= 1) ? 1 : 0;
277         $line{left_holds_on_order}  = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
278         $line{holds}                = $holds;
279         $line{holds_on_order}       = $itemholds?$itemholds:$holds if $line{left_holds_on_order};
280
281         my $budget = GetBudget( $line{budget_id} );
282         $line{budget_name} = $budget->{'budget_name'};
283
284         push @loop_orders, \%line if ($i >= $startfrom and $i < $startfrom + $resultsperpage);
285     }
286
287     my $count = $countpendings;
288
289     if ($count>$resultsperpage){
290         my $displaynext=0;
291         my $displayprev=$startfrom;
292         if(($count - ($startfrom+$resultsperpage)) > 0 ) {
293             $displaynext = 1;
294         }
295
296         my @numbers = ();
297         for (my $i=1; $i<$count/$resultsperpage+1; $i++) {
298                 my $highlight=0;
299                 ($startfrom/$resultsperpage==($i-1)) && ($highlight=1);
300                 push @numbers, { number => $i,
301                     highlight => $highlight ,
302                     startfrom => ($i-1)*$resultsperpage};
303         }
304
305         my $from = $startfrom*$resultsperpage+1;
306         my $to;
307         if($count < (($startfrom+1)*$resultsperpage)){
308             $to = $count;
309         } else {
310             $to = (($startfrom+1)*$resultsperpage);
311         }
312         $template->param(numbers=>\@numbers,
313                          displaynext=>$displaynext,
314                          displayprev=>$displayprev,
315                          nextstartfrom=>(($startfrom+$resultsperpage<$count)?$startfrom+$resultsperpage:$count),
316                          prevstartfrom=>(($startfrom-$resultsperpage>0)?$startfrom-$resultsperpage:0)
317                         );
318     }
319
320     $template->param(
321         loop_orders  => \@loop_orders,
322     );
323 }
324
325 $template->param(
326     invoiceid             => $invoice->{invoiceid},
327     invoice               => $invoice->{invoicenumber},
328     invoiceclosedate      => $invoice->{closedate},
329     datereceived          => $datereceived->output('iso'),
330     invoicedatereceived   => $datereceived->output('iso'),
331     formatteddatereceived => $datereceived->output(),
332     name                  => $bookseller->{'name'},
333     booksellerid          => $bookseller->{id},
334     countreceived         => $countlines,
335     loop_received         => \@loop_received,
336     loop_orders           => \@loop_orders,
337     book_foot_loop        => \@book_foot_loop,
338     totalprice            => sprintf($cfstr, $totalprice),
339     totalquantity         => $totalquantity,
340     resultsperpage        => $resultsperpage,
341     (uc(C4::Context->preference("marcflavour"))) => 1,
342     total_quantity       => $total_quantity,
343     total_gste           => sprintf( "%.2f", $total_gste ),
344     total_gsti           => sprintf( "%.2f", $total_gsti ),
345 );
346 output_html_with_http_headers $input, $cookie, $template->output;