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
7 # Parts Copyright Catalyst 2010
9 # This file is part of Koha.
11 # Koha is free software; you can redistribute it and/or modify it under the
12 # terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
16 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License along
21 # with Koha; if not, write to the Free Software Foundation, Inc.,
22 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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
40 The bookseller who we want to display the baskets (and basketgroups) of.
55 use C4::Bookseller qw/GetBookSellerFromId/;
56 use C4::Acquisition qw/CloseBasketgroup ReOpenBasketgroup GetOrders GetBasketsByBasketgroup GetBasketsByBookseller ModBasketgroup NewBasketgroup DelBasketgroup GetBasketgroups ModBasket GetBasketgroup GetBasket/;
57 use C4::Bookseller qw/GetBookSellerFromId/;
58 use C4::Branch qw/GetBranches/;
59 use C4::Members qw/GetMember/;
63 my ($template, $loggedinuser, $cookie)
64 = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
68 flagsrequired => {acquisition => 'group_manage'},
72 sub parseinputbaskets {
73 my $booksellerid = shift;
74 my $baskets = &GetBasketsByBookseller($booksellerid);
75 for(my $i=0; $i < scalar @$baskets; ++$i) {
76 if( @$baskets[$i] && ! @$baskets[$i]->{'closedate'} ) {
77 splice(@$baskets, $i, 1);
81 foreach my $basket (@$baskets){
82 #perl DBI uses value "undef" for the mysql "NULL" value, so i need to check everywhere where $basket->{'basketgroupid'} is used for undef ☹
83 $basket->{'basketgroupid'} = $input->param($basket->{'basketno'}.'-group') || undef;
90 sub parseinputbasketgroups {
91 my $booksellerid = shift;
93 my $basketgroups = &GetBasketgroups($booksellerid);
95 foreach my $basket (@$baskets){
99 if(! $basket->{'basketgroupid'} || $basket->{'basketgroupid'} == 0){
102 foreach my $basketgroup (@$basketgroups){
103 if($basket->{'basketgroupid'} == $basketgroup->{'id'}){
105 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
111 #if the basketgroup doesn't exist yet
112 $basketgroup = $newbasketgroups->{$basket->{'basketgroupid'}} || undef;
113 $basketgroup->{'booksellerid'} = $booksellerid;
115 while($i < scalar @$basketgroups && @$basketgroups[$i]->{'id'} != $basket->{'basketgroupid'}){
118 $basketgroup = @$basketgroups[$i];
120 $basketgroup->{'id'}=$basket->{'basketgroupid'};
121 $basketgroup->{'name'}=$input->param('basketgroup-'.$basketgroup->{'id'}.'-name') || "";
122 $basketgroup->{'closed'}= $input->param('basketgroup-'.$basketgroup->{'id'}.'-closed');
123 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
125 $newbasketgroups->{$basket->{'basketgroupid'}} = $basketgroup;
127 if($basketgroup->{'id'}){
128 @$basketgroups[$i] = $basketgroup;
132 return($basketgroups, $newbasketgroups);
136 my $basketno = shift;
137 my $bookseller = shift;
139 my @orders = GetOrders($basketno);
140 for my $order (@orders){
141 $total = $total + ( $order->{ecost} * $order->{quantity} );
142 if ($bookseller->{invoiceincgst} && ! $bookseller->{listincgst} && ( $bookseller->{gstrate} // C4::Context->preference("gist") )) {
143 my $gst = $bookseller->{gstrate} // C4::Context->preference("gist");
144 $total = $total * ( $gst / 100 +1);
147 $total .= $bookseller->{invoiceprice};
151 #displays all basketgroups and all closed baskets (in their respective groups)
152 sub displaybasketgroups {
153 my $basketgroups = shift;
154 my $bookseller = shift;
156 if (scalar @$basketgroups != 0) {
157 foreach my $basketgroup (@$basketgroups){
159 while($i < scalar(@$baskets)){
160 my $basket = @$baskets[$i];
161 if($basket->{'basketgroupid'} && $basket->{'basketgroupid'} == $basketgroup->{'id'}){
162 $basket->{total} = BasketTotal($basket->{basketno}, $bookseller);
163 push(@{$basketgroup->{'baskets'}}, $basket);
164 splice(@$baskets, $i, 1);
170 $template->param(basketgroups => $basketgroups);
172 for(my $i=0; $i < scalar @$baskets; ++$i) {
173 if( ! @$baskets[$i]->{'closedate'} ) {
174 splice(@$baskets, $i, 1);
177 @$baskets[$i]->{total} = BasketTotal(@$baskets[$i]->{basketno}, $bookseller);
180 $template->param(baskets => $baskets);
181 $template->param( booksellername => $bookseller ->{'name'});
184 sub printbasketgrouppdf{
185 my ($basketgroupid) = @_;
187 my $pdfformat = C4::Context->preference("OrderPdfFormat");
188 if ($pdfformat eq 'pdfformat::layout3pages' || $pdfformat eq 'pdfformat::layout2pages'){
197 print $input->header;
198 print $input->start_html; # FIXME Should do a nicer page
199 print "<h1>Invalid PDF Format set</h1>";
200 print "Please go to the systempreferences and set a valid pdfformat";
204 my $basketgroup = GetBasketgroup($basketgroupid);
205 my $bookseller = GetBookSellerFromId($basketgroup->{'booksellerid'});
206 my $baskets = GetBasketsByBasketgroup($basketgroupid);
209 for my $basket (@$baskets) {
211 my @ords = &GetOrders($basket->{basketno});
212 for my $ord (@ords) {
213 # ba_order is filled with :
214 # 0 1 2 3 4 5 6 7 8 9
215 #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount gstrate
217 if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
232 my $bib = GetBiblioData($ord->{biblionumber});
233 my $itemtypes = GetItemTypes();
235 push(@ba_order, $ord->{isbn});
237 push(@ba_order, undef);
239 if ($ord->{itemtype} and $bib->{itemtype}){
240 push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description});
242 push(@ba_order, undef);
245 # push(@ba_order, undef, undef);
246 for my $key (qw/author title publishercode quantity listprice ecost/) {
247 push(@ba_order, $ord->{$key}); #Order lines
249 push(@ba_order, $bookseller->{discount});
250 push(@ba_order, $bookseller->{gstrate}*100 // C4::Context->preference("gist") // 0);
251 push(@ba_orders, \@ba_order);
254 if (C4::Context->preference("marcflavour") eq 'UNIMARC') {
255 $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('345',"b");
256 } elsif (C4::Context->preference("marcflavour") eq 'MARC21') {
257 $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('037',"a");
260 push(@ba_order, $en);
262 push(@ba_order, undef);
266 $orders{$basket->{basketno}}=\@ba_orders;
268 print $input->header(
269 -type => 'application/pdf',
270 -attachment => ( $basketgroup->{name} || $basketgroupid ) . '.pdf'
272 my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->{gstrate} // C4::Context->preference("gist")) || die "pdf generation failed";
277 my $op = $input->param('op');
278 my $booksellerid = $input->param('booksellerid');
279 $template->param(booksellerid => $booksellerid);
281 if ( $op eq "add" ) {
283 $template->param( ungroupedlist => 1);
284 my @booksellers = GetBookSeller('');
285 for (my $i=0; $i < scalar @booksellers; $i++) {
286 my $baskets = &GetBasketsByBookseller($booksellers[$i]->{id});
287 for (my $j=0; $j < scalar @$baskets; $j++) {
288 if(! @$baskets[$i]->{closedate} || @$baskets[$i]->{basketgroupid}) {
289 splice(@$baskets, $j, 1);
293 if (scalar @$baskets == 0){
294 splice(@booksellers, $i, 1);
299 my $basketgroupid = $input->param('basketgroupid');
302 my $freedeliveryplace;
303 if ( $basketgroupid ) {
304 # Get the selected baskets in the basketgroup to display them
305 my $selecteds = GetBasketsByBasketgroup($basketgroupid);
306 foreach (@{$selecteds}){
307 $_->{total} = BasketTotal($_->{basketno}, $_);
309 $template->param(basketgroupid => $basketgroupid,
310 selectedbaskets => $selecteds);
312 # Get general informations about the basket group to prefill the form
313 my $basketgroup = GetBasketgroup($basketgroupid);
315 name => $basketgroup->{name},
316 deliverycomment => $basketgroup->{deliverycomment},
317 freedeliveryplace => $basketgroup->{freedeliveryplace},
319 $billingplace = $basketgroup->{billingplace};
320 $deliveryplace = $basketgroup->{deliveryplace};
321 $freedeliveryplace = $basketgroup->{freedeliveryplace};
324 # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data
325 my $borrower = GetMember( ( 'borrowernumber' => $loggedinuser ) );
326 $billingplace = $billingplace || $borrower->{'branchcode'};
327 $deliveryplace = $deliveryplace || $borrower->{'branchcode'};
329 my $branches = GetBranches;
331 # Build the combobox to select the billing place
332 my @billingplaceloop;
333 for (sort keys %$branches) {
334 push @billingplaceloop, {
336 selected => $_ eq $billingplace,
337 branchname => $branches->{$_}->{branchname},
340 $template->param( billingplaceloop => \@billingplaceloop );
342 # Build the combobox to select the delivery place
343 my @deliveryplaceloop;
344 for (sort keys %$branches) {
345 push @deliveryplaceloop, {
347 selected => $_ eq $deliveryplace,
348 branchname => $branches->{$_}->{branchname},
351 $template->param( deliveryplaceloop => \@deliveryplaceloop );
353 $template->param( booksellerid => $booksellerid );
355 $template->param(grouping => 1);
356 my $basketgroups = &GetBasketgroups($booksellerid);
357 my $bookseller = &GetBookSellerFromId($booksellerid);
358 my $baskets = &GetBasketsByBookseller($booksellerid);
360 displaybasketgroups($basketgroups, $bookseller, $baskets);
361 } elsif ($op eq 'mod_basket') {
362 #we want to modify an individual basket's group
363 my $basketno=$input->param('basketno');
364 my $basketgroupid=$input->param('basketgroupid');
365 ModBasket( { basketno => $basketno,
366 basketgroupid => $basketgroupid } );
367 print $input->redirect("basket.pl?basketno=" . $basketno);
368 } elsif ($op eq 'validate') {
370 $template->param( booksellererror => 1);
372 $template->param( booksellerid => $booksellerid );
374 my $baskets = parseinputbaskets($booksellerid);
375 my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
376 foreach my $nbgid (keys %$newbasketgroups){
377 #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
378 my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
379 ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
380 ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
382 foreach my $basket (@$baskets){
383 #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.
384 if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
385 $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
389 foreach my $basketgroup (@$basketgroups){
390 if(! $basketgroup->{'id'}){
391 foreach my $basket (@{$basketgroup->{'baskets'}}){
392 if($input->param('basket'.$basket->{'basketno'}.'changed')){
396 } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
397 ModBasketgroup($basketgroup);
400 $basketgroups = &GetBasketgroups($booksellerid);
401 my $bookseller = &GetBookSellerFromId($booksellerid);
402 $baskets = &GetBasketsByBookseller($booksellerid);
404 displaybasketgroups($basketgroups, $bookseller, $baskets);
405 } elsif ( $op eq 'closeandprint') {
406 my $basketgroupid = $input->param('basketgroupid');
408 CloseBasketgroup($basketgroupid);
410 printbasketgrouppdf($basketgroupid);
412 }elsif ($op eq 'print'){
413 my $basketgroupid = $input->param('basketgroupid');
415 printbasketgrouppdf($basketgroupid);
417 }elsif( $op eq "delete"){
418 my $basketgroupid = $input->param('basketgroupid');
419 DelBasketgroup($basketgroupid);
420 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
422 }elsif ( $op eq 'reopen'){
423 my $basketgroupid = $input->param('basketgroupid');
424 my $booksellerid = $input->param('booksellerid');
426 ReOpenBasketgroup($basketgroupid);
428 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
430 } elsif ( $op eq 'attachbasket') {
433 my $basketgroup = {};
434 my @baskets = $input->param('basket');
435 my $basketgroupid = $input->param('basketgroupid');
436 my $basketgroupname = $input->param('basketgroupname');
437 my $booksellerid = $input->param('booksellerid');
438 my $billingplace = $input->param('billingplace');
439 my $deliveryplace = $input->param('deliveryplace');
440 my $freedeliveryplace = $input->param('freedeliveryplace');
441 my $deliverycomment = $input->param('deliverycomment');
442 my $close = $input->param('close') ? 1 : 0;
443 # If we got a basketgroupname, we create a basketgroup
444 if ($basketgroupid) {
446 name => $basketgroupname,
447 id => $basketgroupid,
448 basketlist => \@baskets,
449 billingplace => $billingplace,
450 deliveryplace => $deliveryplace,
451 freedeliveryplace => $freedeliveryplace,
452 deliverycomment => $deliverycomment,
455 ModBasketgroup($basketgroup);
461 name => $basketgroupname,
462 booksellerid => $booksellerid,
463 basketlist => \@baskets,
464 deliveryplace => $deliveryplace,
465 freedeliveryplace => $freedeliveryplace,
466 deliverycomment => $deliverycomment,
469 $basketgroupid = NewBasketgroup($basketgroup);
472 my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
473 $url .= "&closed=1" if ($input->param("closed"));
474 print $input->redirect($url);
477 my $basketgroups = &GetBasketgroups($booksellerid);
478 my $bookseller = &GetBookSellerFromId($booksellerid);
479 my $baskets = &GetBasketsByBookseller($booksellerid);
481 displaybasketgroups($basketgroups, $bookseller, $baskets);
483 $template->param(closed => $input->param("closed"));
484 #prolly won't use all these, maybe just use print, the rest can be done inside validate
485 output_html_with_http_headers $input, $cookie, $template->output;