Bug 5399: remove useless eval 'use C4::Foo'
[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 #
8 # This file is part of Koha.
9 #
10 # Koha is free software; you can redistribute it and/or modify it under the
11 # terms of the GNU General Public License as published by the Free Software
12 # Foundation; either version 2 of the License, or (at your option) any later
13 # version.
14 #
15 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
16 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License along
20 # with Koha; if not, write to the Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23
24 =head1 NAME
25
26 basketgroup.pl
27
28 =head1 DESCRIPTION
29
30  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
31  have to be closed.
32
33 =head1 CGI PARAMETERS
34
35 =over 4
36
37 =item $booksellerid
38
39 The bookseller who we want to display the baskets (and basketgroups) of.
40
41 =back
42
43 =cut
44
45 use strict;
46 use warnings;
47
48 use C4::Input;
49 use C4::Auth;
50 use C4::Output;
51 use CGI;
52
53 use C4::Bookseller qw/GetBookSellerFromId/;
54 use C4::Acquisition qw/CloseBasketgroup ReOpenBasketgroup GetOrders GetBasketsByBasketgroup GetBasketsByBookseller ModBasketgroup NewBasketgroup DelBasketgroup GetBasketgroups ModBasket GetBasketgroup GetBasket/;
55 use C4::Bookseller qw/GetBookSellerFromId/;
56 use C4::Branch qw/GetBranches/;
57 use C4::Members qw/GetMember/;
58
59 my $input=new CGI;
60
61 my ($template, $loggedinuser, $cookie)
62     = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
63                              query => $input,
64                              type => "intranet",
65                              authnotrequired => 0,
66                              flagsrequired => {acquisition => 'group_manage'},
67                              debug => 1,
68                 });
69
70 sub parseinputbaskets {
71     my $booksellerid = shift;
72     my $baskets = &GetBasketsByBookseller($booksellerid);
73     for(my $i=0; $i < scalar @$baskets; ++$i) {
74         if( @$baskets[$i] && ! @$baskets[$i]->{'closedate'} ) {
75             splice(@$baskets, $i, 1);
76             --$i;
77         }
78     }
79     foreach my $basket (@$baskets){
80 #perl DBI uses value "undef" for the mysql "NULL" value, so i need to check everywhere where $basket->{'basketgroupid'} is used for undef ☹
81         $basket->{'basketgroupid'} = $input->param($basket->{'basketno'}.'-group') || undef;
82     }
83     return $baskets;
84 }
85
86
87
88 sub parseinputbasketgroups {
89     my $booksellerid = shift;
90     my $baskets = shift;
91     my $basketgroups = &GetBasketgroups($booksellerid);
92     my $newbasketgroups;
93     foreach my $basket (@$baskets){
94         my $basketgroup;
95         my $i = 0;
96         my $exists;
97         if(! $basket->{'basketgroupid'} || $basket->{'basketgroupid'} == 0){
98             $exists = "true";
99         } else {
100             foreach my $basketgroup (@$basketgroups){
101                 if($basket->{'basketgroupid'} == $basketgroup->{'id'}){
102                     $exists = "true";
103                     push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
104                     last;
105                 }
106             }
107         }
108         if (! $exists){
109 #if the basketgroup doesn't exist yet
110             $basketgroup = $newbasketgroups->{$basket->{'basketgroupid'}} || undef;
111             $basketgroup->{'booksellerid'} = $booksellerid;
112         } else {
113             while($i < scalar @$basketgroups && @$basketgroups[$i]->{'id'} != $basket->{'basketgroupid'}){
114                 ++$i;
115             }
116             $basketgroup = @$basketgroups[$i];
117         }
118         $basketgroup->{'id'}=$basket->{'basketgroupid'};
119         $basketgroup->{'name'}=$input->param('basketgroup-'.$basketgroup->{'id'}.'-name') || "";
120         $basketgroup->{'closed'}= $input->param('basketgroup-'.$basketgroup->{'id'}.'-closed');
121         push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
122         if (! $exists){
123             $newbasketgroups->{$basket->{'basketgroupid'}} = $basketgroup;
124         } else {
125             if($basketgroup->{'id'}){
126                 @$basketgroups[$i] = $basketgroup;
127             }
128         }
129     }
130     return($basketgroups, $newbasketgroups);
131 }
132
133 sub BasketTotal {
134     my $basketno = shift;
135     my $bookseller = shift;
136     my $total = 0;
137     my @orders = GetOrders($basketno);
138     for my $order (@orders){
139         $total = $total + ( $order->{ecost} * $order->{quantity} );
140         if ($bookseller->{invoiceincgst} && ! $bookseller->{listincgst} && ( $bookseller->{gstrate} || C4::Context->preference("gist") )) {
141             my $gst = $bookseller->{gstrate} || C4::Context->preference("gist");
142             $total = $total * ( $gst / 100 +1);
143         }
144     }
145     $total .= $bookseller->{invoiceprice};
146     return $total;
147 }
148
149 #displays all basketgroups and all closed baskets (in their respective groups)
150 sub displaybasketgroups {
151     my $basketgroups = shift;
152     my $bookseller = shift;
153     my $baskets = shift;
154     if (scalar @$basketgroups != 0) {
155         foreach my $basketgroup (@$basketgroups){
156             my $i = 0;
157             while($i < scalar(@$baskets)){
158                 my $basket = @$baskets[$i];
159                 if($basket->{'basketgroupid'} && $basket->{'basketgroupid'} == $basketgroup->{'id'}){
160                     $basket->{total} = BasketTotal($basket->{basketno}, $bookseller);
161                     push(@{$basketgroup->{'baskets'}}, $basket);
162                     splice(@$baskets, $i, 1);
163                     --$i;
164                 }
165                 ++$i;
166             }
167         }
168         $template->param(basketgroups => $basketgroups);
169     }
170     for(my $i=0; $i < scalar @$baskets; ++$i) {
171         if( ! @$baskets[$i]->{'closedate'} ) {
172             splice(@$baskets, $i, 1);
173             --$i;
174         }else{
175             @$baskets[$i]->{total} = BasketTotal(@$baskets[$i]->{basketno}, $bookseller);
176         }
177     }
178     $template->param(baskets => $baskets);
179     $template->param( booksellername => $bookseller ->{'name'});
180 }
181
182 sub printbasketgrouppdf{
183     my ($basketgroupid) = @_;
184     
185     my $pdfformat = C4::Context->preference("OrderPdfFormat");
186     eval "use $pdfformat";
187     # FIXME consider what would happen if $pdfformat does not
188     # contain the name of a valid Perl module.
189     
190     my $basketgroup = GetBasketgroup($basketgroupid);
191     my $bookseller = GetBookSellerFromId($basketgroup->{'booksellerid'});
192     my $baskets = GetBasketsByBasketgroup($basketgroupid);
193     
194     my %orders;
195     for my $basket (@$baskets) {
196         my @ba_orders;
197         my @ords = &GetOrders($basket->{basketno});
198         for my $ord (@ords) {
199             # ba_order is filled with : 
200             # 0      1        2        3         4            5         6       7      8        9
201             #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount gstrate
202             my @ba_order;
203             if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
204                 eval "use C4::Biblio";
205                 eval "use C4::Koha";
206                 my $bib = GetBiblioData($ord->{biblionumber});
207                 my $itemtypes = GetItemTypes();
208                 if($ord->{isbn}){
209                     push(@ba_order, $ord->{isbn});
210                 } else {
211                     push(@ba_order, undef);
212                 }
213                 if ($ord->{itemtype}){
214                     push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description}) if $bib->{itemtype};
215                 } else {
216                     push(@ba_order, undef);
217                 }
218 #             } else {
219 #                 push(@ba_order, undef, undef);
220                 for my $key (qw/author title publishercode quantity listprice ecost/) {
221                     push(@ba_order, $ord->{$key});                                                  #Order lines
222                 }
223                 push(@ba_order, $bookseller->{discount});
224                 push(@ba_order, $bookseller->{gstrate}*100 || C4::Context->preference("gist") || 0);
225                 push(@ba_orders, \@ba_order);
226                 # Editor Number
227                 my $en;
228                 if (C4::Context->preference("marcflavour") eq 'UNIMARC') {
229                     $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('345',"b");
230                 } elsif (C4::Context->preference("marcflavour") eq 'MARC21') {
231                     $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('037',"a");
232                 }
233                 if($en){
234                     push(@ba_order, $en);
235                 } else {
236                     push(@ba_order, undef);
237                 }
238             }
239         }
240         $orders{$basket->{basketno}}=\@ba_orders;
241     }
242     print $input->header(
243         -type       => 'application/pdf',
244         -attachment => ( $basketgroup->{name} || $basketgroupid ) . '.pdf'
245     );
246     my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->{gstrate} || C4::Context->preference("gist")) || die "pdf generation failed";
247     print $pdf;
248     exit; # FIXME bad form to exit out of a subroutine like this
249 }
250
251 my $op = $input->param('op');
252 my $booksellerid = $input->param('booksellerid');
253 $template->param(booksellerid => $booksellerid);
254
255 if ( $op eq "add" ) {
256     if(! $booksellerid){
257         $template->param( ungroupedlist => 1);
258         my @booksellers = GetBookSeller('');
259        for (my $i=0; $i < scalar @booksellers; $i++) {
260             my $baskets = &GetBasketsByBookseller($booksellers[$i]->{id});
261             for (my $j=0; $j < scalar @$baskets; $j++) {
262                 if(! @$baskets[$i]->{closedate} || @$baskets[$i]->{basketgroupid}) {
263                     splice(@$baskets, $j, 1);
264                     $j--;
265                 }
266             }
267             if (scalar @$baskets == 0){
268                 splice(@booksellers, $i, 1);
269                 $i--;
270             }
271         }
272     } else {
273         my $basketgroupid = $input->param('basketgroupid');
274         my $billingplace;
275         my $deliveryplace;
276         if ( $basketgroupid ) {
277             # Get the selected baskets in the basketgroup to display them
278             my $selecteds = GetBasketsByBasketgroup($basketgroupid);
279             foreach (@{$selecteds}){
280                 $_->{total} = BasketTotal($_->{basketno}, $_);
281             }
282             $template->param(basketgroupid => $basketgroupid,
283                              selectedbaskets => $selecteds);
284
285             # Get general informations about the basket group to prefill the form
286             my $basketgroup = GetBasketgroup($basketgroupid);
287             $template->param(
288                 name            => $basketgroup->{name},
289                 deliverycomment => $basketgroup->{deliverycomment},
290             );
291             $billingplace  = $basketgroup->{billingplace};
292             $deliveryplace = $basketgroup->{deliveryplace};
293         }
294
295         # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data
296         my $borrower = GetMember( ( 'borrowernumber' => $loggedinuser ) );
297         $billingplace  = $billingplace  || $borrower->{'branchcode'};
298         $deliveryplace = $deliveryplace || $borrower->{'branchcode'};
299         
300         my $branches = GetBranches;
301         
302         # Build the combobox to select the billing place
303         my @billingplaceloop;
304         for (sort keys %$branches) {
305             my $selected = 1 if $_ eq $billingplace;
306             my %row = (
307                 value      => $_,
308                 selected   => $selected,
309                 branchname => $branches->{$_}->{branchname},
310             );
311             push @billingplaceloop, \%row;
312         }
313         $template->param( billingplaceloop => \@billingplaceloop );
314         
315         # Build the combobox to select the delivery place
316         my @deliveryplaceloop;
317         for (sort keys %$branches) {
318             my $selected = 1 if $_ eq $deliveryplace;
319             my %row = (
320                 value      => $_,
321                 selected   => $selected,
322                 branchname => $branches->{$_}->{branchname},
323             );
324             push @deliveryplaceloop, \%row;
325         }
326         $template->param( deliveryplaceloop => \@deliveryplaceloop );
327
328         $template->param( booksellerid => $booksellerid );
329     }
330     $template->param(grouping => 1);
331     my $basketgroups = &GetBasketgroups($booksellerid);
332     my $bookseller = &GetBookSellerFromId($booksellerid);
333     my $baskets = &GetBasketsByBookseller($booksellerid);
334
335     displaybasketgroups($basketgroups, $bookseller, $baskets);
336 } elsif ($op eq 'mod_basket') {
337 #we want to modify an individual basket's group
338   my $basketno=$input->param('basketno');
339   my $basketgroupid=$input->param('basketgroupid');
340   ModBasket( { basketno => $basketno,
341                          basketgroupid => $basketgroupid } );
342   print $input->redirect("basket.pl?basketno=" . $basketno);
343 } elsif ($op eq 'validate') {
344     if(! $booksellerid){
345         $template->param( booksellererror => 1);
346     } else {
347         $template->param( booksellerid => $booksellerid );
348     }
349     my $baskets = parseinputbaskets($booksellerid);
350     my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
351     foreach my $nbgid (keys %$newbasketgroups){
352 #javascript just picks an ID that's higher than anything else, the ID might not be correct..chenge it and change all the basket's basketgroupid as well
353         my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
354         ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
355         ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
356     }
357     foreach my $basket (@$baskets){
358 #if the basket was added to a new basketgroup, first change the groupid to the groupid of the basket in mysql, because it contains the id from javascript otherwise.
359         if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
360             $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
361         }
362         ModBasket($basket);
363     }
364     foreach my $basketgroup (@$basketgroups){
365         if(! $basketgroup->{'id'}){
366             foreach my $basket (@{$basketgroup->{'baskets'}}){
367                 if($input->param('basket'.$basket->{'basketno'}.'changed')){
368                     ModBasket($basket);
369                 }
370             }
371         } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
372             ModBasketgroup($basketgroup);
373         }
374     }
375     $basketgroups = &GetBasketgroups($booksellerid);
376     my $bookseller = &GetBookSellerFromId($booksellerid);
377     $baskets = &GetBasketsByBookseller($booksellerid);
378
379     displaybasketgroups($basketgroups, $bookseller, $baskets);
380 } elsif ( $op eq 'closeandprint') {
381     my $basketgroupid = $input->param('basketgroupid');
382     
383     CloseBasketgroup($basketgroupid);
384     
385     printbasketgrouppdf($basketgroupid);
386 }elsif ($op eq 'print'){
387     my $basketgroupid = $input->param('basketgroupid');
388     
389     printbasketgrouppdf($basketgroupid);
390 }elsif( $op eq "delete"){
391     my $basketgroupid = $input->param('basketgroupid');
392     DelBasketgroup($basketgroupid);
393     print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
394     
395 }elsif ( $op eq 'reopen'){
396     my $basketgroupid   = $input->param('basketgroupid');
397     my $booksellerid    = $input->param('booksellerid');
398     
399     ReOpenBasketgroup($basketgroupid);
400         
401     print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
402     
403 } elsif ( $op eq 'attachbasket') {
404     
405     # Getting parameters
406     my $basketgroup = {};
407     my @baskets         = $input->param('basket');
408     my $basketgroupid   = $input->param('basketgroupid');
409     my $basketgroupname = $input->param('basketgroupname');
410     my $booksellerid    = $input->param('booksellerid');
411     my $billingplace    = $input->param('billingplace');
412     my $deliveryplace   = $input->param('deliveryplace');
413     my $deliverycomment = $input->param('deliverycomment');
414     my $close           = $input->param('close') ? 1 : 0;
415     # If we got a basketgroupname, we create a basketgroup
416     if ($basketgroupid) {
417         $basketgroup = {
418               name            => $basketgroupname,
419               id              => $basketgroupid,
420               basketlist      => \@baskets,
421               billingplace    => $billingplace,
422               deliveryplace   => $deliveryplace,
423               deliverycomment => $deliverycomment,
424               closed          => $close,
425         };
426         ModBasketgroup($basketgroup);
427         if($close){
428             
429         }
430     }else{
431         $basketgroup = {
432             name            => $basketgroupname,
433             booksellerid    => $booksellerid,
434             basketlist      => \@baskets,
435             deliveryplace   => $deliveryplace,
436             deliverycomment => $deliverycomment,
437             closed          => $close,
438         };
439         $basketgroupid = NewBasketgroup($basketgroup);
440     }
441    
442     my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
443     $url .= "&closed=1" if ($input->param("closed")); 
444     print $input->redirect($url);
445     
446 }else{
447     my $basketgroups = &GetBasketgroups($booksellerid);
448     my $bookseller = &GetBookSellerFromId($booksellerid);
449     my $baskets = &GetBasketsByBookseller($booksellerid);
450
451     displaybasketgroups($basketgroups, $bookseller, $baskets);
452 }
453 $template->param(closed => $input->param("closed"));
454 #prolly won't use all these, maybe just use print, the rest can be done inside validate
455 output_html_with_http_headers $input, $cookie, $template->output;