Bug 21832: add is_expired to ILS-DI example
[koha.git] / acqui / basketgroup.pl
1 #!/usr/bin/perl
2
3 #script to group (closed) baskets into basket groups for easier order management
4 #written by john.soros@biblibre.com 01/10/2008
5
6 # Copyright 2008 - 2009 BibLibre SARL
7 # Parts Copyright Catalyst 2010
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
25 =head1 NAME
26
27 basketgroup.pl
28
29 =head1 DESCRIPTION
30
31  This script lets the user group (closed) baskets into basket groups for easier order management. Note that the grouped baskets have to be from the same bookseller and
32  have to be closed to be printed or exported.
33
34 =head1 CGI PARAMETERS
35
36 =over 4
37
38 =item $booksellerid
39
40 The bookseller who we want to display the baskets (and basketgroups) of.
41
42 =back
43
44 =cut
45
46 use strict;
47 use warnings;
48 use Carp;
49
50 use C4::Auth;
51 use C4::Output;
52 use CGI qw ( -utf8 );
53 use File::Spec;
54
55 use C4::Acquisition qw/CloseBasketgroup ReOpenBasketgroup GetOrders GetBasketsByBasketgroup GetBasketsByBookseller ModBasketgroup NewBasketgroup DelBasketgroup GetBasketgroups ModBasket GetBasketgroup GetBasket GetBasketGroupAsCSV/;
56 use Koha::EDI qw/create_edi_order get_edifact_ean/;
57
58 use Koha::Biblioitems;
59 use Koha::Acquisition::Booksellers;
60 use Koha::ItemTypes;
61 use Koha::Patrons;
62
63 our $input=new CGI;
64
65 our ($template, $loggedinuser, $cookie)
66     = get_template_and_user({template_name => "acqui/basketgroup.tt",
67                              query => $input,
68                              type => "intranet",
69                              authnotrequired => 0,
70                              flagsrequired => {acquisition => 'group_manage'},
71                              debug => 1,
72                 });
73
74 sub BasketTotal {
75     my $basketno = shift;
76     my $bookseller = shift;
77     my $total = 0;
78     my @orders = GetOrders($basketno);
79     for my $order (@orders){
80         # FIXME The following is wrong
81         if ( $bookseller->listincgst ) {
82             $total = $total + ( $order->{ecost_tax_included} * $order->{quantity} );
83         } else {
84             $total = $total + ( $order->{ecost_tax_excluded} * $order->{quantity} );
85         }
86     }
87     $total .= " " . ($bookseller->invoiceprice // 0);
88     return $total;
89 }
90
91 #displays all basketgroups and all closed baskets (in their respective groups)
92 sub displaybasketgroups {
93     my $basketgroups = shift;
94     my $bookseller = shift;
95     my $baskets = shift;
96     if (scalar @$basketgroups != 0) {
97         foreach my $basketgroup (@$basketgroups){
98             my $i = 0;
99             my $basketsqty = 0;
100             while($i < scalar(@$baskets)){
101                 my $basket = @$baskets[$i];
102                 if($basket->{'basketgroupid'} && $basket->{'basketgroupid'} == $basketgroup->{'id'}){
103                     $basket->{total} = BasketTotal($basket->{basketno}, $bookseller);
104                     push(@{$basketgroup->{'baskets'}}, $basket);
105                     splice(@$baskets, $i, 1);
106                     ++$basketsqty;
107                     --$i;
108                 }
109                 ++$i;
110             }
111             $basketgroup -> {'basketsqty'} = $basketsqty;
112         }
113         $template->param(basketgroups => $basketgroups);
114     }
115     for(my $i=0; $i < scalar @$baskets; ++$i) {
116         if( ! @$baskets[$i]->{'closedate'} ) {
117             splice(@$baskets, $i, 1);
118             --$i;
119         }else{
120             @$baskets[$i]->{total} = BasketTotal(@$baskets[$i]->{basketno}, $bookseller);
121         }
122     }
123     $template->param(baskets => $baskets);
124     $template->param( booksellername => $bookseller->name);
125 }
126
127 sub printbasketgrouppdf{
128     my ($basketgroupid) = @_;
129
130     my $pdfformat = C4::Context->preference("OrderPdfFormat");
131     my @valid_pdfformats = qw(pdfformat::layout3pages pdfformat::layout2pages pdfformat::layout3pagesfr pdfformat::layout2pagesde);
132     if (grep {$_ eq $pdfformat} @valid_pdfformats) {
133         $pdfformat = "Koha::$pdfformat";
134         my $pdfformat_filepath = File::Spec->catfile(split /::/, $pdfformat) . '.pm';
135         require $pdfformat_filepath;
136         import $pdfformat qw(printpdf);
137     }
138     else {
139         print $input->header;
140         print $input->start_html;  # FIXME Should do a nicer page
141         print "<h1>Invalid PDF Format set</h1>";
142         print "Please go to the systempreferences and set a valid pdfformat";
143         exit;
144     }
145
146     my $basketgroup = GetBasketgroup($basketgroupid);
147     my $bookseller = Koha::Acquisition::Booksellers->find( $basketgroup->{booksellerid} );
148     my $baskets = GetBasketsByBasketgroup($basketgroupid);
149
150     my %orders;
151     for my $basket (@$baskets) {
152         my @ba_orders;
153         my @ords = &GetOrders($basket->{basketno});
154         for my $ord (@ords) {
155
156             next unless ( $ord->{biblionumber} or $ord->{quantity}> 0 );
157             eval {
158                 require C4::Biblio;
159                 import C4::Biblio;
160             };
161             if ($@){
162                 croak $@;
163             }
164             eval {
165                 require C4::Koha;
166                 import C4::Koha;
167             };
168             if ($@){
169                 croak $@;
170             }
171
172             $ord->{tax_value} = $ord->{tax_value_on_ordering};
173             $ord->{tax_rate} = $ord->{tax_rate_on_ordering};
174             $ord->{total_tax_included} = $ord->{ecost_tax_included} * $ord->{quantity};
175             $ord->{total_tax_excluded} = $ord->{ecost_tax_excluded} * $ord->{quantity};
176
177             my $biblioitem = Koha::Biblioitems->search({ biblionumber => $ord->{biblionumber} })->next;
178
179             #FIXME DELETE ME
180             # 0      1        2        3         4            5         6       7      8        9
181             #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount tax_rate
182
183             # Editor Number
184             my $en;
185             my $edition;
186             $ord->{marcxml} = C4::Biblio::GetXmlBiblio( $ord->{biblionumber} );
187             my $marcrecord=eval{MARC::Record::new_from_xml( $ord->{marcxml},'UTF-8' )};
188             if ($marcrecord){
189                 if ( C4::Context->preference("marcflavour") eq 'UNIMARC' ) {
190                     $en = $marcrecord->subfield( '345', "b" );
191                     $edition = $marcrecord->subfield( '205', 'a' );
192                 } elsif ( C4::Context->preference("marcflavour") eq 'MARC21' ) {
193                     $en = $marcrecord->subfield( '037', "a" );
194                     $edition = $marcrecord->subfield( '250', 'a' );
195                 }
196             }
197
198             my $itemtype = ( $ord->{itemtype} and $biblioitem->itemtype )
199                 ? Koha::ItemTypes->find( $biblioitem->itemtype )
200                 : undef;
201             $ord->{itemtype} = $itemtype ? $itemtype->description : undef;
202
203             $ord->{en} = $en ? $en : undef;
204             $ord->{edition} = $edition ? $edition : undef;
205
206             push(@ba_orders, $ord);
207         }
208         $orders{$basket->{basketno}} = \@ba_orders;
209     }
210     print $input->header(
211         -type       => 'application/pdf',
212         -attachment => ( $basketgroup->{name} || $basketgroupid ) . '.pdf'
213     );
214     my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->tax_rate // C4::Context->preference("gist")) || die "pdf generation failed";
215     print $pdf;
216
217 }
218
219 sub generate_edifact_orders {
220     my $basketgroupid = shift;
221     my $baskets       = GetBasketsByBasketgroup($basketgroupid);
222     my $ean           = get_edifact_ean();
223
224     if($ean) {
225         for my $basket ( @{$baskets} ) {
226             create_edi_order( { ean => $ean, basketno => $basket->{basketno}, } );
227         }
228     } else {
229         my $booksellerid = $input->param('booksellerid') || 0;
230         print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' .
231                                $booksellerid .
232                                '&message=No%20EDIFACT%20Setup');
233     }
234     return;
235 }
236
237 my $op = $input->param('op') || 'display';
238 # possible values of $op :
239 # - add : adds a new basketgroup, or edit an open basketgroup, or display a closed basketgroup
240 # - mod_basket : modify an individual basket of the basketgroup
241 # - closeandprint : close and print an closed basketgroup in pdf. called by clicking on "Close and print" button in closed basketgroups list
242 # - print : print a closed basketgroup. called by clicking on "Print" button in closed basketgroups list
243 # - ediprint : generate edi order messages for the baskets in the group
244 # - export : export in CSV a closed basketgroup. called by clicking on "Export" button in closed basketgroups list
245 # - delete : delete an open basketgroup. called by clicking on "Delete" button in open basketgroups list
246 # - reopen : reopen a closed basketgroup. called by clicking on "Reopen" button in closed basketgroup list
247 # - attachbasket : save a modified basketgroup, or creates a new basketgroup when a basket is closed. called from basket page
248 # - display : display the list of all basketgroups for a vendor
249 my $booksellerid = $input->param('booksellerid');
250 $template->param(booksellerid => $booksellerid);
251 my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
252
253 my $schema = Koha::Database->new()->schema();
254 my $rs = $schema->resultset('VendorEdiAccount')->search(
255     { vendor_id => $booksellerid, } );
256 $template->param( ediaccount => ($rs->count > 0));
257
258 if ( $op eq "add" ) {
259 #
260 # if no param('basketgroupid') is not defined, adds a new basketgroup
261 # else, edit (if it is open) or display (if it is close) the basketgroup basketgroupid
262 # the template will know if basketgroup must be displayed or edited, depending on the value of closed key
263 #
264     my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
265     my $basketgroupid = $input->param('basketgroupid');
266     my $billingplace;
267     my $deliveryplace;
268     my $freedeliveryplace;
269     if ( $basketgroupid ) {
270         # Get the selected baskets in the basketgroup to display them
271         my $selecteds = GetBasketsByBasketgroup($basketgroupid);
272         foreach my $basket(@{$selecteds}){
273             $basket->{total} = BasketTotal($basket->{basketno}, $bookseller);
274         }
275         $template->param(basketgroupid => $basketgroupid,
276                          selectedbaskets => $selecteds);
277
278         # Get general informations about the basket group to prefill the form
279         my $basketgroup = GetBasketgroup($basketgroupid);
280         $template->param(
281             name            => $basketgroup->{name},
282             deliverycomment => $basketgroup->{deliverycomment},
283             freedeliveryplace => $basketgroup->{freedeliveryplace},
284         );
285         $billingplace  = $basketgroup->{billingplace};
286         $deliveryplace = $basketgroup->{deliveryplace};
287         $freedeliveryplace = $basketgroup->{freedeliveryplace};
288         $template->param( closedbg => ($basketgroup ->{'closed'}) ? 1 : 0);
289     } else {
290         $template->param( closedbg => 0);
291     }
292     # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data
293     my $patron = Koha::Patrons->find( $loggedinuser ); # FIXME Not needed if billingplace and deliveryplace are set
294     $billingplace  = $billingplace  || $patron->branchcode;
295     $deliveryplace = $deliveryplace || $patron->branchcode;
296
297     $template->param( billingplace => $billingplace );
298     $template->param( deliveryplace => $deliveryplace );
299     $template->param( booksellerid => $booksellerid );
300
301     # the template will display a unique basketgroup
302     $template->param(grouping => 1);
303     my $basketgroups = &GetBasketgroups($booksellerid);
304     my $baskets = &GetBasketsByBookseller($booksellerid);
305     displaybasketgroups($basketgroups, $bookseller, $baskets);
306 } elsif ($op eq 'mod_basket') {
307 #
308 # edit an individual basket contained in this basketgroup
309 #
310   my $basketno=$input->param('basketno');
311   my $basketgroupid=$input->param('basketgroupid');
312   ModBasket( { basketno => $basketno,
313                          basketgroupid => $basketgroupid } );
314   print $input->redirect("basket.pl?basketno=" . $basketno);
315 } elsif ( $op eq 'closeandprint') {
316 #
317 # close an open basketgroup and generates a pdf
318 #
319     my $basketgroupid = $input->param('basketgroupid');
320     CloseBasketgroup($basketgroupid);
321     printbasketgrouppdf($basketgroupid);
322     exit;
323 }elsif ($op eq 'print'){
324 #
325 # print a closed basketgroup
326 #
327     my $basketgroupid = $input->param('basketgroupid');
328     printbasketgrouppdf($basketgroupid);
329     exit;
330 }elsif ( $op eq "export" ) {
331 #
332 # export a closed basketgroup in csv
333 #
334     my $basketgroupid = $input->param('basketgroupid');
335     print $input->header(
336         -type       => 'text/csv',
337         -attachment => 'basketgroup' . $basketgroupid . '.csv',
338     );
339     print GetBasketGroupAsCSV( $basketgroupid, $input );
340     exit;
341 }elsif( $op eq "delete"){
342 #
343 # delete an closed basketgroup
344 #
345     my $basketgroupid = $input->param('basketgroupid');
346     DelBasketgroup($basketgroupid);
347     print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid.'&amp;listclosed=1');
348 }elsif ( $op eq 'reopen'){
349 #
350 # reopen a closed basketgroup
351 #
352     my $basketgroupid   = $input->param('basketgroupid');
353     my $booksellerid    = $input->param('booksellerid');
354     ReOpenBasketgroup($basketgroupid);
355     my $redirectpath = ((defined $input->param('mode'))&& ($input->param('mode') eq 'singlebg')) ?'/cgi-bin/koha/acqui/basketgroup.pl?op=add&amp;basketgroupid='.$basketgroupid.'&amp;booksellerid='.$booksellerid : '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' .$booksellerid.'&amp;listclosed=1';
356     print $input->redirect($redirectpath);
357 } elsif ( $op eq 'attachbasket') {
358 #
359 # save a modified basketgroup, or creates a new basketgroup when a basket is closed. called from basket page
360 #
361     # Getting parameters
362     my $basketgroup       = {};
363     my @baskets           = $input->multi_param('basket');
364     my $basketgroupid     = $input->param('basketgroupid');
365     my $basketgroupname   = $input->param('basketgroupname');
366     my $booksellerid      = $input->param('booksellerid');
367     my $billingplace      = $input->param('billingplace');
368     my $deliveryplace     = $input->param('deliveryplace');
369     my $freedeliveryplace = $input->param('freedeliveryplace');
370     my $deliverycomment   = $input->param('deliverycomment');
371     my $closedbg          = $input->param('closedbg') ? 1 : 0;
372     if ($basketgroupid) {
373     # If we have a basketgroupid we edit the basketgroup
374         $basketgroup = {
375               name              => $basketgroupname,
376               id                => $basketgroupid,
377               basketlist        => \@baskets,
378               billingplace      => $billingplace,
379               deliveryplace     => $deliveryplace,
380               freedeliveryplace => $freedeliveryplace,
381               deliverycomment   => $deliverycomment,
382               closed            => $closedbg,
383         };
384         ModBasketgroup($basketgroup);
385         if($closedbg){
386 # FIXME
387         }
388     }else{
389     # we create a new basketgroup (with a closed basket)
390         $basketgroup = {
391             name              => $basketgroupname,
392             booksellerid      => $booksellerid,
393             basketlist        => \@baskets,
394             billingplace      => $billingplace,
395             deliveryplace     => $deliveryplace,
396             freedeliveryplace => $freedeliveryplace,
397             deliverycomment   => $deliverycomment,
398             closed            => $closedbg,
399         };
400         $basketgroupid = NewBasketgroup($basketgroup);
401     }
402     my $redirectpath = ((defined $input->param('mode')) && ($input->param('mode') eq 'singlebg')) ?'/cgi-bin/koha/acqui/basketgroup.pl?op=add&amp;basketgroupid='.$basketgroupid.'&amp;booksellerid='.$booksellerid : '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
403     $redirectpath .=  "&amp;listclosed=1" if $closedbg ;
404     print $input->redirect($redirectpath );
405     
406 } elsif ( $op eq 'ediprint') {
407     my $basketgroupid = $input->param('basketgroupid');
408     if ($template->param( 'ediaccount' )) {
409         generate_edifact_orders( $basketgroupid );
410         exit;
411     } else {
412         $template->param('NoEDIMessage' => 1);
413         my $basketgroups = &GetBasketgroups($booksellerid);
414         my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
415         my $baskets = &GetBasketsByBookseller($booksellerid);
416
417         displaybasketgroups($basketgroups, $bookseller, $baskets);
418     }
419 }else{
420 # no param : display the list of all basketgroups for a given vendor
421     my $basketgroups = &GetBasketgroups($booksellerid);
422     my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
423     my $baskets = &GetBasketsByBookseller($booksellerid);
424
425     displaybasketgroups($basketgroups, $bookseller, $baskets);
426 }
427 $template->param(listclosed => ((defined $input->param('listclosed')) && ($input->param('listclosed') eq '1'))? 1:0 );
428 #prolly won't use all these, maybe just use print, the rest can be done inside validate
429 output_html_with_http_headers $input, $cookie, $template->output;