remove extraneous warns
[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     eval "use C4::Branch";
188     
189     my $basketgroup = GetBasketgroup($basketgroupid);
190     my $bookseller = GetBookSellerFromId($basketgroup->{'booksellerid'});
191     my $baskets = GetBasketsByBasketgroup($basketgroupid);
192     
193     my %orders;
194     for my $basket (@$baskets) {
195         my @ba_orders;
196         my @ords = &GetOrders($basket->{basketno});
197         for my $ord (@ords) {
198             # ba_order is filled with : 
199             # 0      1        2        3         4            5         6       7      8        9
200             #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount gstrate
201             my @ba_order;
202             if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
203                 eval "use C4::Biblio";
204                 eval "use C4::Koha";
205                 my $bib = GetBiblioData($ord->{biblionumber});
206                 my $itemtypes = GetItemTypes();
207                 if($ord->{isbn}){
208                     push(@ba_order, $ord->{isbn});
209                 } else {
210                     push(@ba_order, undef);
211                 }
212                 if ($ord->{itemtype}){
213                     push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description}) if $bib->{itemtype};
214                 } else {
215                     push(@ba_order, undef);
216                 }
217 #             } else {
218 #                 push(@ba_order, undef, undef);
219                 for my $key (qw/author title publishercode quantity listprice ecost/) {
220                     push(@ba_order, $ord->{$key});                                                  #Order lines
221                 }
222                 push(@ba_order, $bookseller->{discount});
223                 push(@ba_order, $bookseller->{gstrate}*100 || C4::Context->preference("gist") || 0);
224                 push(@ba_orders, \@ba_order);
225                 # Editor Number
226                 my $en;
227                 if (C4::Context->preference("marcflavour") eq 'UNIMARC') {
228                     $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('345',"b");
229                 } elsif (C4::Context->preference("marcflavour") eq 'MARC21') {
230                     $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('037',"a");
231                 }
232                 if($en){
233                     push(@ba_order, $en);
234                 } else {
235                     push(@ba_order, undef);
236                 }
237             }
238         }
239         $orders{$basket->{basketno}}=\@ba_orders;
240     }
241     print $input->header( -type => 'application/pdf', -attachment => $basketgroup->{name}.'.pdf' );
242     my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->{gstrate} || C4::Context->preference("gist")) || die "pdf generation failed";
243     print $pdf;
244     exit;
245 }
246
247 my $op = $input->param('op');
248 my $booksellerid = $input->param('booksellerid');
249 $template->param(booksellerid => $booksellerid);
250
251 if ( $op eq "add" ) {
252     if(! $booksellerid){
253         $template->param( ungroupedlist => 1);
254         my @booksellers = GetBookSeller('');
255        for (my $i=0; $i < scalar @booksellers; $i++) {
256             my $baskets = &GetBasketsByBookseller($booksellers[$i]->{id});
257             for (my $j=0; $j < scalar @$baskets; $j++) {
258                 if(! @$baskets[$i]->{closedate} || @$baskets[$i]->{basketgroupid}) {
259                     splice(@$baskets, $j, 1);
260                     $j--;
261                 }
262             }
263             if (scalar @$baskets == 0){
264                 splice(@booksellers, $i, 1);
265                 $i--;
266             }
267         }
268     } else {
269         my $basketgroupid = $input->param('basketgroupid');
270         my $billingplace;
271         my $deliveryplace;
272         if ( $basketgroupid ) {
273             # Get the selected baskets in the basketgroup to display them
274             my $selecteds = GetBasketsByBasketgroup($basketgroupid);
275             foreach (@{$selecteds}){
276                 $_->{total} = BasketTotal($_->{basketno}, $_);
277             }
278             $template->param(basketgroupid => $basketgroupid,
279                              selectedbaskets => $selecteds);
280
281             # Get general informations about the basket group to prefill the form
282             my $basketgroup = GetBasketgroup($basketgroupid);
283             $template->param(
284                 name            => $basketgroup->{name},
285                 deliverycomment => $basketgroup->{deliverycomment},
286             );
287             $billingplace  = $basketgroup->{billingplace};
288             $deliveryplace = $basketgroup->{deliveryplace};
289         }
290
291         # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data
292         my $borrower = GetMember( ( 'borrowernumber' => $loggedinuser ) );
293         $billingplace  = $billingplace  || $borrower->{'branchcode'};
294         $deliveryplace = $deliveryplace || $borrower->{'branchcode'};
295         
296         my $branches = GetBranches;
297         
298         # Build the combobox to select the billing place
299         my @billingplaceloop;
300         for (sort keys %$branches) {
301             my $selected = 1 if $_ eq $billingplace;
302             my %row = (
303                 value      => $_,
304                 selected   => $selected,
305                 branchname => $branches->{$_}->{branchname},
306             );
307             push @billingplaceloop, \%row;
308         }
309         $template->param( billingplaceloop => \@billingplaceloop );
310         
311         # Build the combobox to select the delivery place
312         my @deliveryplaceloop;
313         for (sort keys %$branches) {
314             my $selected = 1 if $_ eq $deliveryplace;
315             my %row = (
316                 value      => $_,
317                 selected   => $selected,
318                 branchname => $branches->{$_}->{branchname},
319             );
320             push @deliveryplaceloop, \%row;
321         }
322         $template->param( deliveryplaceloop => \@deliveryplaceloop );
323
324         $template->param( booksellerid => $booksellerid );
325     }
326     $template->param(grouping => 1);
327     my $basketgroups = &GetBasketgroups($booksellerid);
328     my $bookseller = &GetBookSellerFromId($booksellerid);
329     my $baskets = &GetBasketsByBookseller($booksellerid);
330
331     displaybasketgroups($basketgroups, $bookseller, $baskets);
332 } elsif ($op eq 'mod_basket') {
333 #we want to modify an individual basket's group
334   my $basketno=$input->param('basketno');
335   my $basketgroupid=$input->param('basketgroupid');
336   ModBasket( { basketno => $basketno,
337                          basketgroupid => $basketgroupid } );
338   print $input->redirect("basket.pl?basketno=" . $basketno);
339 } elsif ($op eq 'validate') {
340     if(! $booksellerid){
341         $template->param( booksellererror => 1);
342     } else {
343         $template->param( booksellerid => $booksellerid );
344     }
345     my $baskets = parseinputbaskets($booksellerid);
346     my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
347     foreach my $nbgid (keys %$newbasketgroups){
348 #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
349         my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
350         ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
351         ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
352     }
353     foreach my $basket (@$baskets){
354 #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.
355         if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
356             $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
357         }
358         ModBasket($basket);
359     }
360     foreach my $basketgroup (@$basketgroups){
361         if(! $basketgroup->{'id'}){
362             foreach my $basket (@{$basketgroup->{'baskets'}}){
363                 if($input->param('basket'.$basket->{'basketno'}.'changed')){
364                     ModBasket($basket);
365                 }
366             }
367         } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
368             ModBasketgroup($basketgroup);
369         }
370     }
371     $basketgroups = &GetBasketgroups($booksellerid);
372     my $bookseller = &GetBookSellerFromId($booksellerid);
373     $baskets = &GetBasketsByBookseller($booksellerid);
374
375     displaybasketgroups($basketgroups, $bookseller, $baskets);
376 } elsif ( $op eq 'closeandprint') {
377     my $basketgroupid = $input->param('basketgroupid');
378     
379     CloseBasketgroup($basketgroupid);
380     
381     printbasketgrouppdf($basketgroupid);
382 }elsif ($op eq 'print'){
383     my $basketgroupid = $input->param('basketgroupid');
384     
385     printbasketgrouppdf($basketgroupid);
386 }elsif( $op eq "delete"){
387     my $basketgroupid = $input->param('basketgroupid');
388     DelBasketgroup($basketgroupid);
389     print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
390     
391 }elsif ( $op eq 'reopen'){
392     my $basketgroupid   = $input->param('basketgroupid');
393     my $booksellerid    = $input->param('booksellerid');
394     
395     ReOpenBasketgroup($basketgroupid);
396         
397     print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
398     
399 } elsif ( $op eq 'attachbasket') {
400     
401     # Getting parameters
402     my $basketgroup = {};
403     my @baskets         = $input->param('basket');
404     my $basketgroupid   = $input->param('basketgroupid');
405     my $basketgroupname = $input->param('basketgroupname');
406     my $booksellerid    = $input->param('booksellerid');
407     my $billingplace    = $input->param('billingplace');
408     my $deliveryplace   = $input->param('deliveryplace');
409     my $deliverycomment = $input->param('deliverycomment');
410     my $close           = $input->param('close') ? 1 : 0;
411     # If we got a basketgroupname, we create a basketgroup
412     if ($basketgroupid) {
413         $basketgroup = {
414               name            => $basketgroupname,
415               id              => $basketgroupid,
416               basketlist      => \@baskets,
417               billingplace    => $billingplace,
418               deliveryplace   => $deliveryplace,
419               deliverycomment => $deliverycomment,
420               closed          => $close,
421         };
422         ModBasketgroup($basketgroup);
423         if($close){
424             
425         }
426     }else{
427         $basketgroup = {
428             name            => $basketgroupname,
429             booksellerid    => $booksellerid,
430             basketlist      => \@baskets,
431             deliveryplace   => $deliveryplace,
432             deliverycomment => $deliverycomment,
433             closed          => $close,
434         };
435         $basketgroupid = NewBasketgroup($basketgroup);
436     }
437    
438     my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
439     $url .= "&closed=1" if ($input->param("closed")); 
440     print $input->redirect($url);
441     
442 }else{
443     my $basketgroups = &GetBasketgroups($booksellerid);
444     my $bookseller = &GetBookSellerFromId($booksellerid);
445     my $baskets = &GetBasketsByBookseller($booksellerid);
446
447     displaybasketgroups($basketgroups, $bookseller, $baskets);
448 }
449 $template->param(closed => $input->param("closed"));
450 #prolly won't use all these, maybe just use print, the rest can be done inside validate
451 output_html_with_http_headers $input, $cookie, $template->output;