basketgrouping management
[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/GetOrders GetBasketsByBasketgroup GetBasketsByBookseller ModBasketgroup NewBasketgroup DelBasketgroup GetBasketgroups ModBasket GetBasketgroup/;
55 use C4::Bookseller qw/GetBookSellerFromId/;
56
57 my $input=new CGI;
58
59 my ($template, $loggedinuser, $cookie)
60     = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
61                              query => $input,
62                              type => "intranet",
63                              authnotrequired => 0,
64                              flagsrequired => {acquisition => 'group_manage'},
65                              debug => 1,
66                 });
67
68 sub parseinputbaskets {
69     my $booksellerid = shift;
70     my $baskets = &GetBasketsByBookseller($booksellerid);
71     for(my $i=0; $i < scalar @$baskets; ++$i) {
72         if( @$baskets[$i] && ! @$baskets[$i]->{'closedate'} ) {
73             splice(@$baskets, $i, 1);
74             --$i;
75         }
76     }
77     foreach my $basket (@$baskets){
78 #perl DBI uses value "undef" for the mysql "NULL" value, so i need to check everywhere where $basket->{'basketgroupid'} is used for undef ☹
79         $basket->{'basketgroupid'} = $input->param($basket->{'basketno'}.'-group') || undef;
80     }
81     return $baskets;
82 }
83
84
85
86 sub parseinputbasketgroups {
87     my $booksellerid = shift;
88     my $baskets = shift;
89     my $basketgroups = &GetBasketgroups($booksellerid);
90     my $newbasketgroups;
91     foreach my $basket (@$baskets){
92         my $basketgroup;
93         my $i = 0;
94         my $exists;
95         if(! $basket->{'basketgroupid'} || $basket->{'basketgroupid'} == 0){
96             $exists = "true";
97         } else {
98             foreach my $basketgroup (@$basketgroups){
99                 if($basket->{'basketgroupid'} == $basketgroup->{'id'}){
100                     $exists = "true";
101                     push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
102                     last;
103                 }
104             }
105         }
106         if (! $exists){
107 #if the basketgroup doesn't exist yet
108             $basketgroup = $newbasketgroups->{$basket->{'basketgroupid'}} || undef;
109             $basketgroup->{'booksellerid'} = $booksellerid;
110         } else {
111             while($i < scalar @$basketgroups && @$basketgroups[$i]->{'id'} != $basket->{'basketgroupid'}){
112                 ++$i;
113             }
114             $basketgroup = @$basketgroups[$i];
115         }
116         $basketgroup->{'id'}=$basket->{'basketgroupid'};
117         $basketgroup->{'name'}=$input->param('basketgroup-'.$basketgroup->{'id'}.'-name') || "";
118         $basketgroup->{'closed'}= $input->param('basketgroup-'.$basketgroup->{'id'}.'-closed');
119         push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
120         if (! $exists){
121             $newbasketgroups->{$basket->{'basketgroupid'}} = $basketgroup;
122         } else {
123             if($basketgroup->{'id'}){
124                 @$basketgroups[$i] = $basketgroup;
125             }
126         }
127     }
128     return($basketgroups, $newbasketgroups);
129 }
130
131 sub BasketTotal {
132     my $basketno = shift;
133     my $bookseller = shift;
134     my $total = 0;
135     my @orders = GetOrders($basketno);
136     for my $order (@orders){
137         $total = $total + ( $order->{ecost} * $order->{quantity} );
138         if ($bookseller->{invoiceincgst} && ! $bookseller->{listincgst} && ( $bookseller->{gstrate} || C4::Context->preference("gist") )) {
139             my $gst = $bookseller->{gstrate} || C4::Context->preference("gist");
140             $total = $total * ( $gst / 100 +1);
141         }
142     }
143     $total .= $bookseller->{invoiceprice};
144     return $total;
145 }
146
147 #displays all basketgroups and all closed baskets (in their respective groups)
148 sub displaybasketgroups {
149     my $basketgroups = shift;
150     my $bookseller = shift;
151     my $baskets = shift;
152     if (scalar @$basketgroups != 0) {
153         foreach my $basketgroup (@$basketgroups){
154             my $i = 0;
155             while($i < scalar(@$baskets)){
156                 my $basket = @$baskets[$i];
157                 if($basket->{'basketgroupid'} && $basket->{'basketgroupid'} == $basketgroup->{'id'}){
158                     $basket->{total} = BasketTotal($basket->{basketno}, $bookseller);
159                     push(@{$basketgroup->{'baskets'}}, $basket);
160                     splice(@$baskets, $i, 1);
161                     --$i;
162                 }
163                 ++$i;
164             }
165         }
166         $template->param(basketgroups => $basketgroups);
167     }
168     for(my $i=0; $i < scalar @$baskets; ++$i) {
169         if( ! @$baskets[$i]->{'closedate'} ) {
170             splice(@$baskets, $i, 1);
171             --$i;
172         }
173     }
174     $template->param(baskets => $baskets);
175     $template->param( booksellername => $bookseller ->{'name'});
176 }
177
178
179 my $op = $input->param('op');
180 my $booksellerid = $input->param('booksellerid');
181
182 if (! $op ) {
183     if(! $booksellerid){
184         $template->param( ungroupedlist => 1);
185         my @booksellers = GetBookSeller('');
186        for (my $i=0; $i < scalar @booksellers; $i++) {
187             my $baskets = &GetBasketsByBookseller($booksellers[$i]->{id});
188             for (my $j=0; $j < scalar @$baskets; $j++) {
189                 if(! @$baskets[$i]->{closedate} || @$baskets[$i]->{basketgroupid}) {
190                     splice(@$baskets, $j, 1);
191                     $j--;
192                 }
193             }
194             if (scalar @$baskets == 0){
195                 splice(@booksellers, $i, 1);
196                 $i--;
197             }
198         }
199     } else {
200         $template->param( booksellerid => $booksellerid );
201     }
202     my $basketgroups = &GetBasketgroups($booksellerid);
203     my $bookseller = &GetBookSellerFromId($booksellerid);
204     my $baskets = &GetBasketsByBookseller($booksellerid);
205
206     displaybasketgroups($basketgroups, $bookseller, $baskets);
207 } elsif ($op eq 'mod_basket') {
208 #we want to modify an individual basket's group
209   my $basketno=$input->param('basketno');
210   my $basketgroupid=$input->param('basketgroupid');
211   ModBasket( { basketno => $basketno,
212                          basketgroupid => $basketgroupid } );
213   print $input->redirect("basket.pl?basketno=" . $basketno);
214 } elsif ($op eq 'validate') {
215     if(! $booksellerid){
216         $template->param( booksellererror => 1);
217     } else {
218         $template->param( booksellerid => $booksellerid );
219     }
220     my $baskets = parseinputbaskets($booksellerid);
221     my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
222     foreach my $nbgid (keys %$newbasketgroups){
223 #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
224         my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
225         ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
226         ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
227     }
228     foreach my $basket (@$baskets){
229 #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.
230         if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
231             $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
232         }
233         ModBasket($basket);
234     }
235     foreach my $basketgroup (@$basketgroups){
236         if(! $basketgroup->{'id'}){
237             foreach my $basket (@{$basketgroup->{'baskets'}}){
238                 if($input->param('basket'.$basket->{'basketno'}.'changed')){
239                     ModBasket($basket);
240                 }
241             }
242         } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
243             ModBasketgroup($basketgroup);
244         }
245     }
246     $basketgroups = &GetBasketgroups($booksellerid);
247     my $bookseller = &GetBookSellerFromId($booksellerid);
248     $baskets = &GetBasketsByBookseller($booksellerid);
249
250     displaybasketgroups($basketgroups, $bookseller, $baskets);
251 } elsif ( $op eq 'printbgroup') {
252     my $pdfformat = C4::Context->preference("pdfformat");
253     eval "use $pdfformat" ;
254     eval "use C4::Branch";
255     my $basketgroupid = $input->param('bgroupid');
256     my $basketgroup = GetBasketgroup($basketgroupid);
257     my $bookseller = GetBookSellerFromId($basketgroup->{'booksellerid'});
258     my $baskets = GetBasketsByBasketgroup($basketgroupid);
259     my %orders;
260     for my $basket (@$baskets) {
261         my @ba_orders;
262         my @ords = &GetOrders($basket->{basketno});
263         for my $ord (@ords) {
264             # ba_order is filled with : 
265             # 0      1        2        3         4            5         6       7      8        9
266             #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount gstrate
267             my @ba_order;
268             if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
269                 eval "use C4::Biblio";
270                 eval "use C4::Koha";
271                 my $bib = GetBiblioData($ord->{biblionumber});
272                 my $itemtypes = GetItemTypes();
273                 if($ord->{isbn}){
274                     push(@ba_order, $ord->{isbn});
275                 } else {
276                     push(@ba_order, undef);
277                 }
278                 if ($ord->{itemtype}){
279                     push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description});
280                 } else {
281                     push(@ba_order, undef);
282                 }
283 #             } else {
284 #                 push(@ba_order, undef, undef);
285                 for my $key (qw/author title publishercode quantity listprice ecost/) {
286                     push(@ba_order, $ord->{$key});                                                  #Order lines
287                 }
288                 push(@ba_order, $bookseller->{discount});
289                 push(@ba_order, $bookseller->{gstrate}*100 || C4::Context->preference("gist"));
290                 push(@ba_orders, \@ba_order);
291             }
292         }
293         %orders->{$basket->{basketno}}=\@ba_orders;
294     }
295     print $input->header( -type => 'application/pdf', -attachment => 'basketgroup.pdf' );
296     my $branch = GetBranchInfo(GetBranch($input, GetBranches()));
297     $branch = @$branch[0];
298     my $pdf = printpdf($basketgroup, $bookseller, $baskets, $branch, \%orders, $bookseller->{gstrate} || C4::Context->preference("gist")) || die "pdf generation failed";
299     print $pdf;
300     exit;
301 }
302 #prolly won't use all these, maybe just use print, the rest can be done inside validate
303 output_html_with_http_headers $input, $cookie, $template->output;