[3.2.x](bug #3623) PDF printing enhancements
[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 with
20 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
21 # Suite 330, Boston, MA  02111-1307 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     warn @_;
188     eval "use C4::Branch";
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( -type => 'application/pdf', -attachment => 'basketgroup.pdf' );
243     my $branch = GetBranchInfo(GetBranch($input, GetBranches()));
244     $branch = @$branch[0];
245     my $pdf = printpdf($basketgroup, $bookseller, $baskets, $branch, \%orders, $bookseller->{gstrate} || C4::Context->preference("gist")) || die "pdf generation failed";
246     print $pdf;
247     exit;
248 }
249
250 my $op = $input->param('op');
251 my $booksellerid = $input->param('booksellerid');
252 $template->param(booksellerid => $booksellerid);
253
254 if ( $op eq "add" ) {
255     if(! $booksellerid){
256         $template->param( ungroupedlist => 1);
257         my @booksellers = GetBookSeller('');
258        for (my $i=0; $i < scalar @booksellers; $i++) {
259             my $baskets = &GetBasketsByBookseller($booksellers[$i]->{id});
260             for (my $j=0; $j < scalar @$baskets; $j++) {
261                 if(! @$baskets[$i]->{closedate} || @$baskets[$i]->{basketgroupid}) {
262                     splice(@$baskets, $j, 1);
263                     $j--;
264                 }
265             }
266             if (scalar @$baskets == 0){
267                 splice(@booksellers, $i, 1);
268                 $i--;
269             }
270         }
271     } else {
272         my $basketgroupid = $input->param('basketgroupid');
273         my $branchcode;
274         if ( $basketgroupid ) {
275             # Get the selected baskets in the basketgroup to display them
276             my $selecteds = GetBasketsByBasketgroup($basketgroupid);
277             foreach (@{$selecteds}){
278                 $_->{total} = BasketTotal($_->{basketno}, $_);
279             }
280             $template->param(basketgroupid => $basketgroupid,
281                              selectedbaskets => $selecteds);
282
283             # Get general informations about the basket group to prefill the form
284             my $basketgroup = GetBasketgroup($basketgroupid);
285             $template->param(
286                 name            => $basketgroup->{name},
287                 deliverycomment => $basketgroup->{deliverycomment},
288             );
289             $branchcode = $basketgroup->{deliveryplace};
290         }
291
292         # Build the combobox to select the delivery place
293         my $borrower = GetMember( ( 'borrowernumber' => $loggedinuser ) );
294         my $branch   = $branchcode || $borrower->{'branchcode'};
295         my $branches = GetBranches;
296         my @branchloop;
297         foreach my $thisbranch (sort keys %$branches) {
298             my $selected = 1 if $thisbranch eq $branch;
299             my %row = (
300                 value      => $thisbranch,
301                 selected   => $selected,
302                 branchname => $branches->{$thisbranch}->{branchname},
303             );
304             push @branchloop, \%row;
305         }
306         $template->param( branchloop => \@branchloop );
307
308         $template->param( booksellerid => $booksellerid );
309     }
310     $template->param(grouping => 1);
311     my $basketgroups = &GetBasketgroups($booksellerid);
312     my $bookseller = &GetBookSellerFromId($booksellerid);
313     my $baskets = &GetBasketsByBookseller($booksellerid);
314
315     displaybasketgroups($basketgroups, $bookseller, $baskets);
316 } elsif ($op eq 'mod_basket') {
317 #we want to modify an individual basket's group
318   my $basketno=$input->param('basketno');
319   my $basketgroupid=$input->param('basketgroupid');
320   ModBasket( { basketno => $basketno,
321                          basketgroupid => $basketgroupid } );
322   print $input->redirect("basket.pl?basketno=" . $basketno);
323 } elsif ($op eq 'validate') {
324     if(! $booksellerid){
325         $template->param( booksellererror => 1);
326     } else {
327         $template->param( booksellerid => $booksellerid );
328     }
329     my $baskets = parseinputbaskets($booksellerid);
330     my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
331     foreach my $nbgid (keys %$newbasketgroups){
332 #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
333         my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
334         ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
335         ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
336     }
337     foreach my $basket (@$baskets){
338 #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.
339         if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
340             $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
341         }
342         ModBasket($basket);
343     }
344     foreach my $basketgroup (@$basketgroups){
345         if(! $basketgroup->{'id'}){
346             foreach my $basket (@{$basketgroup->{'baskets'}}){
347                 if($input->param('basket'.$basket->{'basketno'}.'changed')){
348                     ModBasket($basket);
349                 }
350             }
351         } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
352             ModBasketgroup($basketgroup);
353         }
354     }
355     $basketgroups = &GetBasketgroups($booksellerid);
356     my $bookseller = &GetBookSellerFromId($booksellerid);
357     $baskets = &GetBasketsByBookseller($booksellerid);
358
359     displaybasketgroups($basketgroups, $bookseller, $baskets);
360 } elsif ( $op eq 'closeandprint') {
361     my $basketgroupid = $input->param('basketgroupid');
362     
363     CloseBasketgroup($basketgroupid);
364     
365     printbasketgrouppdf($basketgroupid);
366 }elsif ($op eq 'print'){
367     my $basketgroupid = $input->param('basketgroupid');
368     
369     printbasketgrouppdf($basketgroupid);
370 }elsif( $op eq "delete"){
371     my $basketgroupid = $input->param('basketgroupid');
372     warn $basketgroupid;
373     DelBasketgroup($basketgroupid);
374     warn "---------------";
375     print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
376     
377 }elsif ( $op eq 'reopen'){
378     my $basketgroupid   = $input->param('basketgroupid');
379     my $booksellerid    = $input->param('booksellerid');
380     
381     ReOpenBasketgroup($basketgroupid);
382         
383     print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
384     
385 } elsif ( $op eq 'attachbasket') {
386     
387     # Getting parameters
388     my $basketgroup = {};
389     
390     my @baskets         = $input->param('basket');
391     my $basketgroupid   = $input->param('basketgroupid');
392     my $basketgroupname = $input->param('basketgroupname');
393     my $booksellerid    = $input->param('booksellerid');
394     my $deliveryplace   = $input->param('deliveryplace');
395     my $deliverycomment = $input->param('deliverycomment');
396     my $close           = $input->param('close') ? 1 : 0;
397     # If we got a basketgroupname, we create a basketgroup
398     if ($basketgroupid) {
399         $basketgroup = {
400               name            => $basketgroupname,
401               id              => $basketgroupid,
402               basketlist      => \@baskets,
403               deliveryplace   => $deliveryplace,
404               deliverycomment => $deliverycomment,
405               closed          => $close,
406         };
407         ModBasketgroup($basketgroup);
408         if($close){
409             
410         }
411     }else{
412         $basketgroup = {
413             name            => $basketgroupname,
414             booksellerid    => $booksellerid,
415             basketlist      => \@baskets,
416             deliveryplace   => $deliveryplace,
417             deliverycomment => $deliverycomment,
418             closed          => $close,
419         };
420         $basketgroupid = NewBasketgroup($basketgroup);
421     }
422     
423     print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
424     
425 }else{
426     my $basketgroups = &GetBasketgroups($booksellerid);
427     my $bookseller = &GetBookSellerFromId($booksellerid);
428     my $baskets = &GetBasketsByBookseller($booksellerid);
429
430     displaybasketgroups($basketgroups, $bookseller, $baskets);
431 }
432 #prolly won't use all these, maybe just use print, the rest can be done inside validate
433 output_html_with_http_headers $input, $cookie, $template->output;