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