3 #script to group (closed) baskets into basket groups for easier order management
4 #written by john.soros@biblibre.com 01/10/2008
6 # Copyright 2008 - 2009 BibLibre SARL
8 # This file is part of Koha.
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
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.
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.
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
39 The bookseller who we want to display the baskets (and basketgroups) of.
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/;
61 my ($template, $loggedinuser, $cookie)
62 = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
66 flagsrequired => {acquisition => 'group_manage'},
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);
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;
88 sub parseinputbasketgroups {
89 my $booksellerid = shift;
91 my $basketgroups = &GetBasketgroups($booksellerid);
93 foreach my $basket (@$baskets){
97 if(! $basket->{'basketgroupid'} || $basket->{'basketgroupid'} == 0){
100 foreach my $basketgroup (@$basketgroups){
101 if($basket->{'basketgroupid'} == $basketgroup->{'id'}){
103 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
109 #if the basketgroup doesn't exist yet
110 $basketgroup = $newbasketgroups->{$basket->{'basketgroupid'}} || undef;
111 $basketgroup->{'booksellerid'} = $booksellerid;
113 while($i < scalar @$basketgroups && @$basketgroups[$i]->{'id'} != $basket->{'basketgroupid'}){
116 $basketgroup = @$basketgroups[$i];
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'});
123 $newbasketgroups->{$basket->{'basketgroupid'}} = $basketgroup;
125 if($basketgroup->{'id'}){
126 @$basketgroups[$i] = $basketgroup;
130 return($basketgroups, $newbasketgroups);
134 my $basketno = shift;
135 my $bookseller = shift;
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);
145 $total .= $bookseller->{invoiceprice};
149 #displays all basketgroups and all closed baskets (in their respective groups)
150 sub displaybasketgroups {
151 my $basketgroups = shift;
152 my $bookseller = shift;
154 if (scalar @$basketgroups != 0) {
155 foreach my $basketgroup (@$basketgroups){
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);
168 $template->param(basketgroups => $basketgroups);
170 for(my $i=0; $i < scalar @$baskets; ++$i) {
171 if( ! @$baskets[$i]->{'closedate'} ) {
172 splice(@$baskets, $i, 1);
175 @$baskets[$i]->{total} = BasketTotal(@$baskets[$i]->{basketno}, $bookseller);
178 $template->param(baskets => $baskets);
179 $template->param( booksellername => $bookseller ->{'name'});
182 sub printbasketgrouppdf{
183 my ($basketgroupid) = @_;
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.
190 my $basketgroup = GetBasketgroup($basketgroupid);
191 my $bookseller = GetBookSellerFromId($basketgroup->{'booksellerid'});
192 my $baskets = GetBasketsByBasketgroup($basketgroupid);
195 for my $basket (@$baskets) {
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
203 if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
204 eval "use C4::Biblio";
206 my $bib = GetBiblioData($ord->{biblionumber});
207 my $itemtypes = GetItemTypes();
209 push(@ba_order, $ord->{isbn});
211 push(@ba_order, undef);
213 if ($ord->{itemtype}){
214 push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description}) if $bib->{itemtype};
216 push(@ba_order, undef);
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
223 push(@ba_order, $bookseller->{discount});
224 push(@ba_order, $bookseller->{gstrate}*100 || C4::Context->preference("gist") || 0);
225 push(@ba_orders, \@ba_order);
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");
234 push(@ba_order, $en);
236 push(@ba_order, undef);
240 $orders{$basket->{basketno}}=\@ba_orders;
242 print $input->header(
243 -type => 'application/pdf',
244 -attachment => ( $basketgroup->{name} || $basketgroupid ) . '.pdf'
246 my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->{gstrate} || C4::Context->preference("gist")) || die "pdf generation failed";
248 exit; # FIXME bad form to exit out of a subroutine like this
251 my $op = $input->param('op');
252 my $booksellerid = $input->param('booksellerid');
253 $template->param(booksellerid => $booksellerid);
255 if ( $op eq "add" ) {
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);
267 if (scalar @$baskets == 0){
268 splice(@booksellers, $i, 1);
273 my $basketgroupid = $input->param('basketgroupid');
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}, $_);
282 $template->param(basketgroupid => $basketgroupid,
283 selectedbaskets => $selecteds);
285 # Get general informations about the basket group to prefill the form
286 my $basketgroup = GetBasketgroup($basketgroupid);
288 name => $basketgroup->{name},
289 deliverycomment => $basketgroup->{deliverycomment},
291 $billingplace = $basketgroup->{billingplace};
292 $deliveryplace = $basketgroup->{deliveryplace};
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'};
300 my $branches = GetBranches;
302 # Build the combobox to select the billing place
303 my @billingplaceloop;
304 for (sort keys %$branches) {
305 my $selected = 1 if $_ eq $billingplace;
308 selected => $selected,
309 branchname => $branches->{$_}->{branchname},
311 push @billingplaceloop, \%row;
313 $template->param( billingplaceloop => \@billingplaceloop );
315 # Build the combobox to select the delivery place
316 my @deliveryplaceloop;
317 for (sort keys %$branches) {
318 my $selected = 1 if $_ eq $deliveryplace;
321 selected => $selected,
322 branchname => $branches->{$_}->{branchname},
324 push @deliveryplaceloop, \%row;
326 $template->param( deliveryplaceloop => \@deliveryplaceloop );
328 $template->param( booksellerid => $booksellerid );
330 $template->param(grouping => 1);
331 my $basketgroups = &GetBasketgroups($booksellerid);
332 my $bookseller = &GetBookSellerFromId($booksellerid);
333 my $baskets = &GetBasketsByBookseller($booksellerid);
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') {
345 $template->param( booksellererror => 1);
347 $template->param( booksellerid => $booksellerid );
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;
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'};
364 foreach my $basketgroup (@$basketgroups){
365 if(! $basketgroup->{'id'}){
366 foreach my $basket (@{$basketgroup->{'baskets'}}){
367 if($input->param('basket'.$basket->{'basketno'}.'changed')){
371 } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
372 ModBasketgroup($basketgroup);
375 $basketgroups = &GetBasketgroups($booksellerid);
376 my $bookseller = &GetBookSellerFromId($booksellerid);
377 $baskets = &GetBasketsByBookseller($booksellerid);
379 displaybasketgroups($basketgroups, $bookseller, $baskets);
380 } elsif ( $op eq 'closeandprint') {
381 my $basketgroupid = $input->param('basketgroupid');
383 CloseBasketgroup($basketgroupid);
385 printbasketgrouppdf($basketgroupid);
386 }elsif ($op eq 'print'){
387 my $basketgroupid = $input->param('basketgroupid');
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);
395 }elsif ( $op eq 'reopen'){
396 my $basketgroupid = $input->param('basketgroupid');
397 my $booksellerid = $input->param('booksellerid');
399 ReOpenBasketgroup($basketgroupid);
401 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
403 } elsif ( $op eq 'attachbasket') {
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) {
418 name => $basketgroupname,
419 id => $basketgroupid,
420 basketlist => \@baskets,
421 billingplace => $billingplace,
422 deliveryplace => $deliveryplace,
423 deliverycomment => $deliverycomment,
426 ModBasketgroup($basketgroup);
432 name => $basketgroupname,
433 booksellerid => $booksellerid,
434 basketlist => \@baskets,
435 deliveryplace => $deliveryplace,
436 deliverycomment => $deliverycomment,
439 $basketgroupid = NewBasketgroup($basketgroup);
442 my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
443 $url .= "&closed=1" if ($input->param("closed"));
444 print $input->redirect($url);
447 my $basketgroups = &GetBasketgroups($booksellerid);
448 my $bookseller = &GetBookSellerFromId($booksellerid);
449 my $baskets = &GetBasketsByBookseller($booksellerid);
451 displaybasketgroups($basketgroups, $bookseller, $baskets);
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;