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