Bug 8014 - On the patron entry form hide "restricted until" field if "Restricted...
[koha.git] / acqui / basketgroup.pl
blob3300cea9baf2ec2e2a45c689851c38e651344a14
1 #!/usr/bin/perl
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
14 # version.
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.
25 =head1 NAME
27 basketgroup.pl
29 =head1 DESCRIPTION
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.
34 =head1 CGI PARAMETERS
36 =over 4
38 =item $booksellerid
40 The bookseller who we want to display the baskets (and basketgroups) of.
42 =back
44 =cut
46 use strict;
47 use warnings;
48 use Carp;
50 use C4::Input;
51 use C4::Auth;
52 use C4::Output;
53 use CGI;
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/;
61 my $input=new CGI;
63 our ($template, $loggedinuser, $cookie)
64 = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
65 query => $input,
66 type => "intranet",
67 authnotrequired => 0,
68 flagsrequired => {acquisition => 'group_manage'},
69 debug => 1,
70 });
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);
78 --$i;
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;
85 return $baskets;
90 sub parseinputbasketgroups {
91 my $booksellerid = shift;
92 my $baskets = shift;
93 my $basketgroups = &GetBasketgroups($booksellerid);
94 my $newbasketgroups;
95 foreach my $basket (@$baskets){
96 my $basketgroup;
97 my $i = 0;
98 my $exists;
99 if(! $basket->{'basketgroupid'} || $basket->{'basketgroupid'} == 0){
100 $exists = "true";
101 } else {
102 foreach my $basketgroup (@$basketgroups){
103 if($basket->{'basketgroupid'} == $basketgroup->{'id'}){
104 $exists = "true";
105 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
106 last;
110 if (! $exists){
111 #if the basketgroup doesn't exist yet
112 $basketgroup = $newbasketgroups->{$basket->{'basketgroupid'}} || undef;
113 $basketgroup->{'booksellerid'} = $booksellerid;
114 } else {
115 while($i < scalar @$basketgroups && @$basketgroups[$i]->{'id'} != $basket->{'basketgroupid'}){
116 ++$i;
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'});
124 if (! $exists){
125 $newbasketgroups->{$basket->{'basketgroupid'}} = $basketgroup;
126 } else {
127 if($basketgroup->{'id'}){
128 @$basketgroups[$i] = $basketgroup;
132 return($basketgroups, $newbasketgroups);
135 sub BasketTotal {
136 my $basketno = shift;
137 my $bookseller = shift;
138 my $total = 0;
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};
148 return $total;
151 #displays all basketgroups and all closed baskets (in their respective groups)
152 sub displaybasketgroups {
153 my $basketgroups = shift;
154 my $bookseller = shift;
155 my $baskets = shift;
156 if (scalar @$basketgroups != 0) {
157 foreach my $basketgroup (@$basketgroups){
158 my $i = 0;
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);
165 --$i;
167 ++$i;
170 $template->param(basketgroups => $basketgroups);
172 for(my $i=0; $i < scalar @$baskets; ++$i) {
173 if( ! @$baskets[$i]->{'closedate'} ) {
174 splice(@$baskets, $i, 1);
175 --$i;
176 }else{
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'){
189 eval {
190 eval "require $pdfformat";
191 import $pdfformat;
193 if ($@){
196 else {
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";
201 exit;
204 my $basketgroup = GetBasketgroup($basketgroupid);
205 my $bookseller = GetBookSellerFromId($basketgroup->{'booksellerid'});
206 my $baskets = GetBasketsByBasketgroup($basketgroupid);
208 my %orders;
209 for my $basket (@$baskets) {
210 my @ba_orders;
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
216 my @ba_order;
217 if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
218 eval {
219 require C4::Biblio;
220 import C4::Biblio;
222 if ($@){
223 croak $@;
225 eval {
226 require C4::Koha;
227 import C4::Koha;
229 if ($@){
230 croak $@;
232 my $bib = GetBiblioData($ord->{biblionumber});
233 my $itemtypes = GetItemTypes();
234 if($ord->{isbn}){
235 push(@ba_order, $ord->{isbn});
236 } else {
237 push(@ba_order, undef);
239 if ($ord->{itemtype} and $bib->{itemtype}){
240 push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description});
241 } else {
242 push(@ba_order, undef);
244 # } else {
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);
252 # Editor Number
253 my $en;
254 my $marcrecord=eval{MARC::Record::new_from_xml( $ord->{marcxml},'UTF-8' )};
255 if ($marcrecord){
256 if ( C4::Context->preference("marcflavour") eq 'UNIMARC' ) {
257 $en = $marcrecord->subfield( '345', "b" );
258 } elsif ( C4::Context->preference("marcflavour") eq 'MARC21' ) {
259 $en = $marcrecord->subfield( '037', "a" );
262 if($en){
263 push(@ba_order, $en);
264 } else {
265 push(@ba_order, undef);
269 $orders{$basket->{basketno}}=\@ba_orders;
271 print $input->header(
272 -type => 'application/pdf',
273 -attachment => ( $basketgroup->{name} || $basketgroupid ) . '.pdf'
275 my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->{gstrate} // C4::Context->preference("gist")) || die "pdf generation failed";
276 print $pdf;
280 my $op = $input->param('op');
281 my $booksellerid = $input->param('booksellerid');
282 $template->param(booksellerid => $booksellerid);
284 if ( $op eq "add" ) {
285 if(! $booksellerid){
286 $template->param( ungroupedlist => 1);
287 my @booksellers = GetBookSeller('');
288 for (my $i=0; $i < scalar @booksellers; $i++) {
289 my $baskets = &GetBasketsByBookseller($booksellers[$i]->{id});
290 for (my $j=0; $j < scalar @$baskets; $j++) {
291 if(! @$baskets[$i]->{closedate} || @$baskets[$i]->{basketgroupid}) {
292 splice(@$baskets, $j, 1);
293 $j--;
296 if (scalar @$baskets == 0){
297 splice(@booksellers, $i, 1);
298 $i--;
301 } else {
302 my $basketgroupid = $input->param('basketgroupid');
303 my $billingplace;
304 my $deliveryplace;
305 my $freedeliveryplace;
306 if ( $basketgroupid ) {
307 # Get the selected baskets in the basketgroup to display them
308 my $selecteds = GetBasketsByBasketgroup($basketgroupid);
309 foreach (@{$selecteds}){
310 $_->{total} = BasketTotal($_->{basketno}, $_);
312 $template->param(basketgroupid => $basketgroupid,
313 selectedbaskets => $selecteds);
315 # Get general informations about the basket group to prefill the form
316 my $basketgroup = GetBasketgroup($basketgroupid);
317 $template->param(
318 name => $basketgroup->{name},
319 deliverycomment => $basketgroup->{deliverycomment},
320 freedeliveryplace => $basketgroup->{freedeliveryplace},
322 $billingplace = $basketgroup->{billingplace};
323 $deliveryplace = $basketgroup->{deliveryplace};
324 $freedeliveryplace = $basketgroup->{freedeliveryplace};
327 # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data
328 my $borrower = GetMember( ( 'borrowernumber' => $loggedinuser ) );
329 $billingplace = $billingplace || $borrower->{'branchcode'};
330 $deliveryplace = $deliveryplace || $borrower->{'branchcode'};
332 my $branches = GetBranches;
334 # Build the combobox to select the billing place
335 my @billingplaceloop;
336 for (sort keys %$branches) {
337 push @billingplaceloop, {
338 value => $_,
339 selected => $_ eq $billingplace,
340 branchname => $branches->{$_}->{branchname},
343 $template->param( billingplaceloop => \@billingplaceloop );
345 # Build the combobox to select the delivery place
346 my @deliveryplaceloop;
347 for (sort keys %$branches) {
348 push @deliveryplaceloop, {
349 value => $_,
350 selected => $_ eq $deliveryplace,
351 branchname => $branches->{$_}->{branchname},
354 $template->param( deliveryplaceloop => \@deliveryplaceloop );
356 $template->param( booksellerid => $booksellerid );
358 $template->param(grouping => 1);
359 my $basketgroups = &GetBasketgroups($booksellerid);
360 my $bookseller = &GetBookSellerFromId($booksellerid);
361 my $baskets = &GetBasketsByBookseller($booksellerid);
363 displaybasketgroups($basketgroups, $bookseller, $baskets);
364 } elsif ($op eq 'mod_basket') {
365 #we want to modify an individual basket's group
366 my $basketno=$input->param('basketno');
367 my $basketgroupid=$input->param('basketgroupid');
368 ModBasket( { basketno => $basketno,
369 basketgroupid => $basketgroupid } );
370 print $input->redirect("basket.pl?basketno=" . $basketno);
371 } elsif ($op eq 'validate') {
372 if(! $booksellerid){
373 $template->param( booksellererror => 1);
374 } else {
375 $template->param( booksellerid => $booksellerid );
377 my $baskets = parseinputbaskets($booksellerid);
378 my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
379 foreach my $nbgid (keys %$newbasketgroups){
380 #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
381 my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
382 ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
383 ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
385 foreach my $basket (@$baskets){
386 #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.
387 if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
388 $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
390 ModBasket($basket);
392 foreach my $basketgroup (@$basketgroups){
393 if(! $basketgroup->{'id'}){
394 foreach my $basket (@{$basketgroup->{'baskets'}}){
395 if($input->param('basket'.$basket->{'basketno'}.'changed')){
396 ModBasket($basket);
399 } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
400 ModBasketgroup($basketgroup);
403 $basketgroups = &GetBasketgroups($booksellerid);
404 my $bookseller = &GetBookSellerFromId($booksellerid);
405 $baskets = &GetBasketsByBookseller($booksellerid);
407 displaybasketgroups($basketgroups, $bookseller, $baskets);
408 } elsif ( $op eq 'closeandprint') {
409 my $basketgroupid = $input->param('basketgroupid');
411 CloseBasketgroup($basketgroupid);
413 printbasketgrouppdf($basketgroupid);
414 exit;
415 }elsif ($op eq 'print'){
416 my $basketgroupid = $input->param('basketgroupid');
418 printbasketgrouppdf($basketgroupid);
419 exit;
420 }elsif( $op eq "delete"){
421 my $basketgroupid = $input->param('basketgroupid');
422 DelBasketgroup($basketgroupid);
423 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
425 }elsif ( $op eq 'reopen'){
426 my $basketgroupid = $input->param('basketgroupid');
427 my $booksellerid = $input->param('booksellerid');
429 ReOpenBasketgroup($basketgroupid);
431 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
433 } elsif ( $op eq 'attachbasket') {
435 # Getting parameters
436 my $basketgroup = {};
437 my @baskets = $input->param('basket');
438 my $basketgroupid = $input->param('basketgroupid');
439 my $basketgroupname = $input->param('basketgroupname');
440 my $booksellerid = $input->param('booksellerid');
441 my $billingplace = $input->param('billingplace');
442 my $deliveryplace = $input->param('deliveryplace');
443 my $freedeliveryplace = $input->param('freedeliveryplace');
444 my $deliverycomment = $input->param('deliverycomment');
445 my $close = $input->param('close') ? 1 : 0;
446 # If we got a basketgroupname, we create a basketgroup
447 if ($basketgroupid) {
448 $basketgroup = {
449 name => $basketgroupname,
450 id => $basketgroupid,
451 basketlist => \@baskets,
452 billingplace => $billingplace,
453 deliveryplace => $deliveryplace,
454 freedeliveryplace => $freedeliveryplace,
455 deliverycomment => $deliverycomment,
456 closed => $close,
458 ModBasketgroup($basketgroup);
459 if($close){
462 }else{
463 $basketgroup = {
464 name => $basketgroupname,
465 booksellerid => $booksellerid,
466 basketlist => \@baskets,
467 deliveryplace => $deliveryplace,
468 freedeliveryplace => $freedeliveryplace,
469 deliverycomment => $deliverycomment,
470 closed => $close,
472 $basketgroupid = NewBasketgroup($basketgroup);
475 my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
476 $url .= "&closed=1" if ($input->param("closed"));
477 print $input->redirect($url);
479 }else{
480 my $basketgroups = &GetBasketgroups($booksellerid);
481 my $bookseller = &GetBookSellerFromId($booksellerid);
482 my $baskets = &GetBasketsByBookseller($booksellerid);
484 displaybasketgroups($basketgroups, $bookseller, $baskets);
486 $template->param(closed => $input->param("closed"));
487 #prolly won't use all these, maybe just use print, the rest can be done inside validate
488 output_html_with_http_headers $input, $cookie, $template->output;