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.
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/;
62 my ($template, $loggedinuser, $cookie)
63 = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
67 flagsrequired => {acquisition => 'group_manage'},
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);
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;
89 sub parseinputbasketgroups {
90 my $booksellerid = shift;
92 my $basketgroups = &GetBasketgroups($booksellerid);
94 foreach my $basket (@$baskets){
98 if(! $basket->{'basketgroupid'} || $basket->{'basketgroupid'} == 0){
101 foreach my $basketgroup (@$basketgroups){
102 if($basket->{'basketgroupid'} == $basketgroup->{'id'}){
104 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
110 #if the basketgroup doesn't exist yet
111 $basketgroup = $newbasketgroups->{$basket->{'basketgroupid'}} || undef;
112 $basketgroup->{'booksellerid'} = $booksellerid;
114 while($i < scalar @$basketgroups && @$basketgroups[$i]->{'id'} != $basket->{'basketgroupid'}){
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'});
124 $newbasketgroups->{$basket->{'basketgroupid'}} = $basketgroup;
126 if($basketgroup->{'id'}){
127 @$basketgroups[$i] = $basketgroup;
131 return($basketgroups, $newbasketgroups);
135 my $basketno = shift;
136 my $bookseller = shift;
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};
150 #displays all basketgroups and all closed baskets (in their respective groups)
151 sub displaybasketgroups {
152 my $basketgroups = shift;
153 my $bookseller = shift;
155 if (scalar @$basketgroups != 0) {
156 foreach my $basketgroup (@$basketgroups){
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);
169 $template->param(basketgroups => $basketgroups);
171 for(my $i=0; $i < scalar @$baskets; ++$i) {
172 if( ! @$baskets[$i]->{'closedate'} ) {
173 splice(@$baskets, $i, 1);
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);
196 for my $basket (@$baskets) {
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
204 if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
205 eval "use C4::Biblio";
207 my $bib = GetBiblioData($ord->{biblionumber});
208 my $itemtypes = GetItemTypes();
210 push(@ba_order, $ord->{isbn});
212 push(@ba_order, undef);
214 if ($ord->{itemtype}){
215 push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description}) if $bib->{itemtype};
217 push(@ba_order, undef);
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);
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");
235 push(@ba_order, $en);
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";
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 my $freedeliveryplace;
277 if ( $basketgroupid ) {
278 # Get the selected baskets in the basketgroup to display them
279 my $selecteds = GetBasketsByBasketgroup($basketgroupid);
280 foreach (@{$selecteds}){
281 $_->{total} = BasketTotal($_->{basketno}, $_);
283 $template->param(basketgroupid => $basketgroupid,
284 selectedbaskets => $selecteds);
286 # Get general informations about the basket group to prefill the form
287 my $basketgroup = GetBasketgroup($basketgroupid);
289 name => $basketgroup->{name},
290 deliverycomment => $basketgroup->{deliverycomment},
291 freedeliveryplace => $basketgroup->{freedeliveryplace},
293 $billingplace = $basketgroup->{billingplace};
294 $deliveryplace = $basketgroup->{deliveryplace};
295 $freedeliveryplace = $basketgroup->{freedeliveryplace};
298 # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data
299 my $borrower = GetMember( ( 'borrowernumber' => $loggedinuser ) );
300 $billingplace = $billingplace || $borrower->{'branchcode'};
301 $deliveryplace = $deliveryplace || $borrower->{'branchcode'};
303 my $branches = GetBranches;
305 # Build the combobox to select the billing place
306 my @billingplaceloop;
307 for (sort keys %$branches) {
308 my $selected = 1 if $_ eq $billingplace;
311 selected => $selected,
312 branchname => $branches->{$_}->{branchname},
314 push @billingplaceloop, \%row;
316 $template->param( billingplaceloop => \@billingplaceloop );
318 # Build the combobox to select the delivery place
319 my @deliveryplaceloop;
320 for (sort keys %$branches) {
321 my $selected = 1 if $_ eq $deliveryplace;
324 selected => $selected,
325 branchname => $branches->{$_}->{branchname},
327 push @deliveryplaceloop, \%row;
329 $template->param( deliveryplaceloop => \@deliveryplaceloop );
331 $template->param( booksellerid => $booksellerid );
333 $template->param(grouping => 1);
334 my $basketgroups = &GetBasketgroups($booksellerid);
335 my $bookseller = &GetBookSellerFromId($booksellerid);
336 my $baskets = &GetBasketsByBookseller($booksellerid);
338 displaybasketgroups($basketgroups, $bookseller, $baskets);
339 } elsif ($op eq 'mod_basket') {
340 #we want to modify an individual basket's group
341 my $basketno=$input->param('basketno');
342 my $basketgroupid=$input->param('basketgroupid');
343 ModBasket( { basketno => $basketno,
344 basketgroupid => $basketgroupid } );
345 print $input->redirect("basket.pl?basketno=" . $basketno);
346 } elsif ($op eq 'validate') {
348 $template->param( booksellererror => 1);
350 $template->param( booksellerid => $booksellerid );
352 my $baskets = parseinputbaskets($booksellerid);
353 my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
354 foreach my $nbgid (keys %$newbasketgroups){
355 #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
356 my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
357 ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
358 ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
360 foreach my $basket (@$baskets){
361 #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.
362 if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
363 $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
367 foreach my $basketgroup (@$basketgroups){
368 if(! $basketgroup->{'id'}){
369 foreach my $basket (@{$basketgroup->{'baskets'}}){
370 if($input->param('basket'.$basket->{'basketno'}.'changed')){
374 } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
375 ModBasketgroup($basketgroup);
378 $basketgroups = &GetBasketgroups($booksellerid);
379 my $bookseller = &GetBookSellerFromId($booksellerid);
380 $baskets = &GetBasketsByBookseller($booksellerid);
382 displaybasketgroups($basketgroups, $bookseller, $baskets);
383 } elsif ( $op eq 'closeandprint') {
384 my $basketgroupid = $input->param('basketgroupid');
386 CloseBasketgroup($basketgroupid);
388 printbasketgrouppdf($basketgroupid);
390 }elsif ($op eq 'print'){
391 my $basketgroupid = $input->param('basketgroupid');
393 printbasketgrouppdf($basketgroupid);
395 }elsif( $op eq "delete"){
396 my $basketgroupid = $input->param('basketgroupid');
397 DelBasketgroup($basketgroupid);
398 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
400 }elsif ( $op eq 'reopen'){
401 my $basketgroupid = $input->param('basketgroupid');
402 my $booksellerid = $input->param('booksellerid');
404 ReOpenBasketgroup($basketgroupid);
406 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
408 } elsif ( $op eq 'attachbasket') {
411 my $basketgroup = {};
412 my @baskets = $input->param('basket');
413 my $basketgroupid = $input->param('basketgroupid');
414 my $basketgroupname = $input->param('basketgroupname');
415 my $booksellerid = $input->param('booksellerid');
416 my $billingplace = $input->param('billingplace');
417 my $deliveryplace = $input->param('deliveryplace');
418 my $freedeliveryplace = $input->param('freedeliveryplace');
419 my $deliverycomment = $input->param('deliverycomment');
420 my $close = $input->param('close') ? 1 : 0;
421 # If we got a basketgroupname, we create a basketgroup
422 if ($basketgroupid) {
424 name => $basketgroupname,
425 id => $basketgroupid,
426 basketlist => \@baskets,
427 billingplace => $billingplace,
428 deliveryplace => $deliveryplace,
429 freedeliveryplace => $freedeliveryplace,
430 deliverycomment => $deliverycomment,
433 ModBasketgroup($basketgroup);
439 name => $basketgroupname,
440 booksellerid => $booksellerid,
441 basketlist => \@baskets,
442 deliveryplace => $deliveryplace,
443 freedeliveryplace => $freedeliveryplace,
444 deliverycomment => $deliverycomment,
447 $basketgroupid = NewBasketgroup($basketgroup);
450 my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
451 $url .= "&closed=1" if ($input->param("closed"));
452 print $input->redirect($url);
455 my $basketgroups = &GetBasketgroups($booksellerid);
456 my $bookseller = &GetBookSellerFromId($booksellerid);
457 my $baskets = &GetBasketsByBookseller($booksellerid);
459 displaybasketgroups($basketgroups, $bookseller, $baskets);
461 $template->param(closed => $input->param("closed"));
462 #prolly won't use all these, maybe just use print, the rest can be done inside validate
463 output_html_with_http_headers $input, $cookie, $template->output;