Bug 5819 : No toolbar in record view when quotes present in title - fix
[koha.git] / acqui / basketgroup.pl
blob2a35f3a26474761abe088e184b0421218f2ffcba
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;
49 use C4::Input;
50 use C4::Auth;
51 use C4::Output;
52 use CGI;
54 use C4::Bookseller qw/GetBookSellerFromId/;
55 use C4::Acquisition qw/CloseBasketgroup ReOpenBasketgroup GetOrders GetBasketsByBasketgroup GetBasketsByBookseller ModBasketgroup NewBasketgroup DelBasketgroup GetBasketgroups ModBasket GetBasketgroup GetBasket/;
56 use C4::Bookseller qw/GetBookSellerFromId/;
57 use C4::Branch qw/GetBranches/;
58 use C4::Members qw/GetMember/;
60 my $input=new CGI;
62 my ($template, $loggedinuser, $cookie)
63 = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
64 query => $input,
65 type => "intranet",
66 authnotrequired => 0,
67 flagsrequired => {acquisition => 'group_manage'},
68 debug => 1,
69 });
71 sub parseinputbaskets {
72 my $booksellerid = shift;
73 my $baskets = &GetBasketsByBookseller($booksellerid);
74 for(my $i=0; $i < scalar @$baskets; ++$i) {
75 if( @$baskets[$i] && ! @$baskets[$i]->{'closedate'} ) {
76 splice(@$baskets, $i, 1);
77 --$i;
80 foreach my $basket (@$baskets){
81 #perl DBI uses value "undef" for the mysql "NULL" value, so i need to check everywhere where $basket->{'basketgroupid'} is used for undef ☹
82 $basket->{'basketgroupid'} = $input->param($basket->{'basketno'}.'-group') || undef;
84 return $baskets;
89 sub parseinputbasketgroups {
90 my $booksellerid = shift;
91 my $baskets = shift;
92 my $basketgroups = &GetBasketgroups($booksellerid);
93 my $newbasketgroups;
94 foreach my $basket (@$baskets){
95 my $basketgroup;
96 my $i = 0;
97 my $exists;
98 if(! $basket->{'basketgroupid'} || $basket->{'basketgroupid'} == 0){
99 $exists = "true";
100 } else {
101 foreach my $basketgroup (@$basketgroups){
102 if($basket->{'basketgroupid'} == $basketgroup->{'id'}){
103 $exists = "true";
104 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
105 last;
109 if (! $exists){
110 #if the basketgroup doesn't exist yet
111 $basketgroup = $newbasketgroups->{$basket->{'basketgroupid'}} || undef;
112 $basketgroup->{'booksellerid'} = $booksellerid;
113 } else {
114 while($i < scalar @$basketgroups && @$basketgroups[$i]->{'id'} != $basket->{'basketgroupid'}){
115 ++$i;
117 $basketgroup = @$basketgroups[$i];
119 $basketgroup->{'id'}=$basket->{'basketgroupid'};
120 $basketgroup->{'name'}=$input->param('basketgroup-'.$basketgroup->{'id'}.'-name') || "";
121 $basketgroup->{'closed'}= $input->param('basketgroup-'.$basketgroup->{'id'}.'-closed');
122 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
123 if (! $exists){
124 $newbasketgroups->{$basket->{'basketgroupid'}} = $basketgroup;
125 } else {
126 if($basketgroup->{'id'}){
127 @$basketgroups[$i] = $basketgroup;
131 return($basketgroups, $newbasketgroups);
134 sub BasketTotal {
135 my $basketno = shift;
136 my $bookseller = shift;
137 my $total = 0;
138 my @orders = GetOrders($basketno);
139 for my $order (@orders){
140 $total = $total + ( $order->{ecost} * $order->{quantity} );
141 if ($bookseller->{invoiceincgst} && ! $bookseller->{listincgst} && ( $bookseller->{gstrate} // C4::Context->preference("gist") )) {
142 my $gst = $bookseller->{gstrate} // C4::Context->preference("gist");
143 $total = $total * ( $gst / 100 +1);
146 $total .= $bookseller->{invoiceprice};
147 return $total;
150 #displays all basketgroups and all closed baskets (in their respective groups)
151 sub displaybasketgroups {
152 my $basketgroups = shift;
153 my $bookseller = shift;
154 my $baskets = shift;
155 if (scalar @$basketgroups != 0) {
156 foreach my $basketgroup (@$basketgroups){
157 my $i = 0;
158 while($i < scalar(@$baskets)){
159 my $basket = @$baskets[$i];
160 if($basket->{'basketgroupid'} && $basket->{'basketgroupid'} == $basketgroup->{'id'}){
161 $basket->{total} = BasketTotal($basket->{basketno}, $bookseller);
162 push(@{$basketgroup->{'baskets'}}, $basket);
163 splice(@$baskets, $i, 1);
164 --$i;
166 ++$i;
169 $template->param(basketgroups => $basketgroups);
171 for(my $i=0; $i < scalar @$baskets; ++$i) {
172 if( ! @$baskets[$i]->{'closedate'} ) {
173 splice(@$baskets, $i, 1);
174 --$i;
175 }else{
176 @$baskets[$i]->{total} = BasketTotal(@$baskets[$i]->{basketno}, $bookseller);
179 $template->param(baskets => $baskets);
180 $template->param( booksellername => $bookseller ->{'name'});
183 sub printbasketgrouppdf{
184 my ($basketgroupid) = @_;
186 my $pdfformat = C4::Context->preference("OrderPdfFormat");
187 eval "use $pdfformat";
188 # FIXME consider what would happen if $pdfformat does not
189 # contain the name of a valid Perl module.
191 my $basketgroup = GetBasketgroup($basketgroupid);
192 my $bookseller = GetBookSellerFromId($basketgroup->{'booksellerid'});
193 my $baskets = GetBasketsByBasketgroup($basketgroupid);
195 my %orders;
196 for my $basket (@$baskets) {
197 my @ba_orders;
198 my @ords = &GetOrders($basket->{basketno});
199 for my $ord (@ords) {
200 # ba_order is filled with :
201 # 0 1 2 3 4 5 6 7 8 9
202 #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount gstrate
203 my @ba_order;
204 if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
205 eval "use C4::Biblio";
206 eval "use C4::Koha";
207 my $bib = GetBiblioData($ord->{biblionumber});
208 my $itemtypes = GetItemTypes();
209 if($ord->{isbn}){
210 push(@ba_order, $ord->{isbn});
211 } else {
212 push(@ba_order, undef);
214 if ($ord->{itemtype}){
215 push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description}) if $bib->{itemtype};
216 } else {
217 push(@ba_order, undef);
219 # } else {
220 # push(@ba_order, undef, undef);
221 for my $key (qw/author title publishercode quantity listprice ecost/) {
222 push(@ba_order, $ord->{$key}); #Order lines
224 push(@ba_order, $bookseller->{discount});
225 push(@ba_order, $bookseller->{gstrate}*100 // C4::Context->preference("gist") // 0);
226 push(@ba_orders, \@ba_order);
227 # Editor Number
228 my $en;
229 if (C4::Context->preference("marcflavour") eq 'UNIMARC') {
230 $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('345',"b");
231 } elsif (C4::Context->preference("marcflavour") eq 'MARC21') {
232 $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('037',"a");
234 if($en){
235 push(@ba_order, $en);
236 } else {
237 push(@ba_order, undef);
241 $orders{$basket->{basketno}}=\@ba_orders;
243 print $input->header(
244 -type => 'application/pdf',
245 -attachment => ( $basketgroup->{name} || $basketgroupid ) . '.pdf'
247 my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->{gstrate} // C4::Context->preference("gist")) || die "pdf generation failed";
248 print $pdf;
251 my $op = $input->param('op');
252 my $booksellerid = $input->param('booksellerid');
253 $template->param(booksellerid => $booksellerid);
255 if ( $op eq "add" ) {
256 if(! $booksellerid){
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);
264 $j--;
267 if (scalar @$baskets == 0){
268 splice(@booksellers, $i, 1);
269 $i--;
272 } else {
273 my $basketgroupid = $input->param('basketgroupid');
274 my $billingplace;
275 my $deliveryplace;
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);
287 $template->param(
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;
306 my %row = (
307 value => $_,
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;
319 my %row = (
320 value => $_,
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') {
344 if(! $booksellerid){
345 $template->param( booksellererror => 1);
346 } else {
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'};
362 ModBasket($basket);
364 foreach my $basketgroup (@$basketgroups){
365 if(! $basketgroup->{'id'}){
366 foreach my $basket (@{$basketgroup->{'baskets'}}){
367 if($input->param('basket'.$basket->{'basketno'}.'changed')){
368 ModBasket($basket);
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 exit;
387 }elsif ($op eq 'print'){
388 my $basketgroupid = $input->param('basketgroupid');
390 printbasketgrouppdf($basketgroupid);
391 exit;
392 }elsif( $op eq "delete"){
393 my $basketgroupid = $input->param('basketgroupid');
394 DelBasketgroup($basketgroupid);
395 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
397 }elsif ( $op eq 'reopen'){
398 my $basketgroupid = $input->param('basketgroupid');
399 my $booksellerid = $input->param('booksellerid');
401 ReOpenBasketgroup($basketgroupid);
403 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
405 } elsif ( $op eq 'attachbasket') {
407 # Getting parameters
408 my $basketgroup = {};
409 my @baskets = $input->param('basket');
410 my $basketgroupid = $input->param('basketgroupid');
411 my $basketgroupname = $input->param('basketgroupname');
412 my $booksellerid = $input->param('booksellerid');
413 my $billingplace = $input->param('billingplace');
414 my $deliveryplace = $input->param('deliveryplace');
415 my $deliverycomment = $input->param('deliverycomment');
416 my $close = $input->param('close') ? 1 : 0;
417 # If we got a basketgroupname, we create a basketgroup
418 if ($basketgroupid) {
419 $basketgroup = {
420 name => $basketgroupname,
421 id => $basketgroupid,
422 basketlist => \@baskets,
423 billingplace => $billingplace,
424 deliveryplace => $deliveryplace,
425 deliverycomment => $deliverycomment,
426 closed => $close,
428 ModBasketgroup($basketgroup);
429 if($close){
432 }else{
433 $basketgroup = {
434 name => $basketgroupname,
435 booksellerid => $booksellerid,
436 basketlist => \@baskets,
437 deliveryplace => $deliveryplace,
438 deliverycomment => $deliverycomment,
439 closed => $close,
441 $basketgroupid = NewBasketgroup($basketgroup);
444 my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
445 $url .= "&closed=1" if ($input->param("closed"));
446 print $input->redirect($url);
448 }else{
449 my $basketgroups = &GetBasketgroups($booksellerid);
450 my $bookseller = &GetBookSellerFromId($booksellerid);
451 my $baskets = &GetBasketsByBookseller($booksellerid);
453 displaybasketgroups($basketgroups, $bookseller, $baskets);
455 $template->param(closed => $input->param("closed"));
456 #prolly won't use all these, maybe just use print, the rest can be done inside validate
457 output_html_with_http_headers $input, $cookie, $template->output;