Bug 21205: (follow-up) Fix column name - itemnumbers -> itemnumber
[koha.git] / acqui / parcel.pl
1 #!/usr/bin/perl
2
3 #script to receive 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
12 # under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 3 of the License, or
14 # (at your option) any later version.
15 #
16 # Koha is distributed in the hope that it will be useful, but
17 # WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License
22 # along with Koha; if not, see <http://www.gnu.org/licenses>.
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 it 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 Modern::Perl;
58
59 use C4::Auth;
60 use C4::Acquisition;
61 use C4::Budgets;
62 use C4::Biblio;
63 use C4::Items;
64 use CGI qw ( -utf8 );
65 use C4::Output;
66 use C4::Suggestions;
67
68 use Koha::Acquisition::Baskets;
69 use Koha::Acquisition::Bookseller;
70 use Koha::Acquisition::Orders;
71 use Koha::Biblios;
72 use Koha::DateUtils;
73 use Koha::Biblios;
74
75 use JSON;
76
77 my $input=new CGI;
78 my $sticky_filters = $input->param('sticky_filters') || 0;
79
80 my ($template, $loggedinuser, $cookie)
81     = get_template_and_user({template_name => "acqui/parcel.tt",
82                  query => $input,
83                  type => "intranet",
84                  authnotrequired => 0,
85                  flagsrequired => {acquisition => 'order_receive'},
86                  debug => 1,
87 });
88
89 my $op = $input->param('op') // '';
90
91 # process cancellation first so that list of
92 # orders to display is calculated after
93 if ($op eq 'cancelreceipt') {
94     my $ordernumber = $input->param('ordernumber');
95     my $parent_ordernumber = CancelReceipt($ordernumber);
96     unless($parent_ordernumber) {
97         $template->param(error_cancelling_receipt => 1);
98     }
99 }
100
101 my $invoiceid = $input->param('invoiceid');
102 my $invoice;
103 $invoice = GetInvoiceDetails($invoiceid) if $invoiceid;
104
105 unless( $invoiceid and $invoice->{invoiceid} ) {
106     $template->param(
107         error_invoice_not_known => 1,
108         no_orders_to_display    => 1
109     );
110     output_html_with_http_headers $input, $cookie, $template->output;
111     exit;
112 }
113
114 my $booksellerid = $invoice->{booksellerid};
115 my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
116
117 my @orders        = @{ $invoice->{orders} };
118 my $countlines    = scalar @orders;
119 my @loop_received = ();
120 my @book_foot_loop;
121 my %foot;
122 my $total_tax_excluded = 0;
123 my $total_tax_included = 0;
124
125 my $subtotal_for_funds;
126 for my $order ( @orders ) {
127     $order->{'unitprice'} += 0;
128
129     my $order_object = Koha::Acquisition::Orders->find($order->{ordernumber});
130     if ( $bookseller->invoiceincgst ) {
131         $order->{ecost}     = $order->{ecost_tax_included};
132         $order->{unitprice} = $order->{unitprice_tax_included};
133     }
134     else {
135         $order->{ecost}     = $order->{ecost_tax_excluded};
136         $order->{unitprice} = $order->{unitprice_tax_excluded};
137     }
138
139     $order->{total} = $order->{unitprice} * $order->{quantity};
140
141     my %line = %{ $order };
142     $line{invoice} = $invoice->{invoicenumber};
143     my @itemnumbers = $order_object->items->get_column('itemnumber');
144     my $biblio = Koha::Biblios->find( $line{biblionumber} );
145     $line{total_holds} = $biblio ? $biblio->holds->count : 0;
146     $line{item_holds} = $biblio ? $biblio->current_holds->search(
147         {
148             itemnumber => { -in => \@itemnumbers },
149         }
150     )->count : 0;
151     $line{budget} = GetBudgetByOrderNumber( $line{ordernumber} );
152
153     $line{tax_value} = $line{tax_value_on_receiving};
154     $line{tax_rate} = $line{tax_rate_on_receiving};
155     $foot{$line{tax_rate}}{tax_rate} = $line{tax_rate};
156     $foot{$line{tax_rate}}{tax_value} += $line{tax_value};
157     $total_tax_excluded += $line{unitprice_tax_excluded} * $line{quantity};
158     $total_tax_included += $line{unitprice_tax_included} * $line{quantity};
159
160     my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
161     $line{suggestionid}         = $suggestion->{suggestionid};
162     $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
163     $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
164
165     if ( $line{parent_ordernumber} != $line{ordernumber} ) {
166         if ( grep { $_->{ordernumber} == $line{parent_ordernumber} }
167             @orders
168             )
169         {
170             $line{cannot_cancel} = 1;
171         }
172     }
173
174     my $budget_name = GetBudgetName( $line{budget_id} );
175     $line{budget_name} = $budget_name;
176
177     $subtotal_for_funds->{ $line{budget_name} }{ecost} += $order->{ecost} * $order->{quantity};
178     $subtotal_for_funds->{ $line{budget_name} }{unitprice} += $order->{total};
179
180     push @loop_received, \%line;
181 }
182 push @book_foot_loop, map { $_ } values %foot;
183
184 my @loop_orders = ();
185 unless( defined $invoice->{closedate} ) {
186     my $pendingorders;
187     if ( $op eq "search" or $sticky_filters ) {
188         my ( $search, $ean, $basketname, $orderno, $basketgroupname );
189         if ( $sticky_filters ) {
190             $search = $input->cookie("filter_parcel_summary");
191             $ean = $input->cookie("filter_parcel_ean");
192             $basketname = $input->cookie("filter_parcel_basketname");
193             $orderno = $input->cookie("filter_parcel_orderno");
194             $basketgroupname = $input->cookie("filter_parcel_basketgroupname");
195         } else {
196             $search   = $input->param('summaryfilter') || '';
197             $ean      = $input->param('eanfilter') || '';
198             $basketname = $input->param('basketfilter') || '';
199             $orderno  = $input->param('orderfilter') || '';
200             $basketgroupname = $input->param('basketgroupnamefilter') || '';
201         }
202         $pendingorders = SearchOrders({
203             booksellerid => $booksellerid,
204             basketname => $basketname,
205             ordernumber => $orderno,
206             search => $search,
207             ean => $ean,
208             basketgroupname => $basketgroupname,
209             pending => 1,
210             ordered => 1,
211         });
212         $template->param(
213             summaryfilter => $search,
214             eanfilter => $ean,
215             basketfilter => $basketname,
216             orderfilter => $orderno,
217             basketgroupnamefilter => $basketgroupname,
218         );
219     }else{
220         $pendingorders = SearchOrders({
221             booksellerid => $booksellerid,
222             ordered => 1
223         });
224     }
225     my $countpendings = scalar @$pendingorders;
226
227     for (my $i = 0 ; $i < $countpendings ; $i++) {
228         my $order = $pendingorders->[$i];
229
230         if ( $bookseller->invoiceincgst ) {
231             $order->{ecost} = $order->{ecost_tax_included};
232         } else {
233             $order->{ecost} = $order->{ecost_tax_excluded};
234         }
235         $order->{total} = $order->{ecost} * $order->{quantity};
236
237         my %line = %$order;
238
239         $line{invoice} = $invoice;
240         $line{booksellerid} = $booksellerid;
241
242         my $biblionumber = $line{'biblionumber'};
243         my $biblio = Koha::Biblios->find( $biblionumber );
244         my $countbiblio = CountBiblioInOrders($biblionumber);
245         my $ordernumber = $line{'ordernumber'};
246         my $order_object = Koha::Acquisition::Orders->find($ordernumber);
247         my $cnt_subscriptions = $biblio ? $biblio->subscriptions->count: 0;
248         my $itemcount   = $biblio ? $biblio->items->count : 0;
249         my $holds_count = $biblio ? $biblio->holds->count : 0;
250         my @itemnumbers = $order_object->items->get_column('itemnumber');
251         my $itemholds = $biblio ? $biblio->holds->search({ itemnumber => { -in => \@itemnumbers } })->count : 0;
252
253         my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
254         $line{suggestionid}         = $suggestion->{suggestionid};
255         $line{surnamesuggestedby}   = $suggestion->{surnamesuggestedby};
256         $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby};
257
258         # 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
259         $line{can_del_bib}          = 1 if $countbiblio <= 1 && $itemcount == scalar @itemnumbers && !($cnt_subscriptions) && !($holds_count);
260         $line{items}                = ($itemcount) - (scalar @itemnumbers);
261         $line{left_item}            = 1 if $line{items} >= 1;
262         $line{left_biblio}          = 1 if $countbiblio > 1;
263         $line{biblios}              = $countbiblio - 1;
264         $line{left_subscription}    = 1 if $cnt_subscriptions;
265         $line{subscriptions}        = $cnt_subscriptions;
266         $line{left_holds}           = ($holds_count >= 1) ? 1 : 0;
267         $line{left_holds_on_order}  = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds );
268         $line{holds}                = $holds_count;
269         $line{holds_on_order}       = $itemholds?$itemholds:$holds_count if $line{left_holds_on_order};
270         $line{basket}               = Koha::Acquisition::Baskets->find( $line{basketno} );
271
272         my $budget_name = GetBudgetName( $line{budget_id} );
273         $line{budget_name} = $budget_name;
274
275         push @loop_orders, \%line;
276     }
277
278     $template->param(
279         loop_orders  => \@loop_orders,
280     );
281 }
282
283 $template->param(
284     invoiceid             => $invoice->{invoiceid},
285     invoice               => $invoice->{invoicenumber},
286     invoiceclosedate      => $invoice->{closedate},
287     datereceived          => dt_from_string,
288     name                  => $bookseller->name,
289     booksellerid          => $bookseller->id,
290     loop_received         => \@loop_received,
291     loop_orders           => \@loop_orders,
292     book_foot_loop        => \@book_foot_loop,
293     (uc(C4::Context->preference("marcflavour"))) => 1,
294     total_tax_excluded    => $total_tax_excluded,
295     total_tax_included    => $total_tax_included,
296     subtotal_for_funds    => $subtotal_for_funds,
297     sticky_filters       => $sticky_filters,
298 );
299 output_html_with_http_headers $input, $cookie, $template->output;