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} and $bib->{itemtype}){
215 push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description});
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 push @billingplaceloop, {
310 selected => $_ eq $billingplace,
311 branchname => $branches->{$_}->{branchname},
314 $template->param( billingplaceloop => \@billingplaceloop );
316 # Build the combobox to select the delivery place
317 my @deliveryplaceloop;
318 for (sort keys %$branches) {
319 push @deliveryplaceloop, {
321 selected => $_ eq $deliveryplace,
322 branchname => $branches->{$_}->{branchname},
325 $template->param( deliveryplaceloop => \@deliveryplaceloop );
327 $template->param( booksellerid => $booksellerid );
329 $template->param(grouping => 1);
330 my $basketgroups = &GetBasketgroups($booksellerid);
331 my $bookseller = &GetBookSellerFromId($booksellerid);
332 my $baskets = &GetBasketsByBookseller($booksellerid);
334 displaybasketgroups($basketgroups, $bookseller, $baskets);
335 } elsif ($op eq 'mod_basket') {
336 #we want to modify an individual basket's group
337 my $basketno=$input->param('basketno');
338 my $basketgroupid=$input->param('basketgroupid');
339 ModBasket( { basketno => $basketno,
340 basketgroupid => $basketgroupid } );
341 print $input->redirect("basket.pl?basketno=" . $basketno);
342 } elsif ($op eq 'validate') {
344 $template->param( booksellererror => 1);
346 $template->param( booksellerid => $booksellerid );
348 my $baskets = parseinputbaskets($booksellerid);
349 my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
350 foreach my $nbgid (keys %$newbasketgroups){
351 #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
352 my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
353 ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
354 ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
356 foreach my $basket (@$baskets){
357 #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.
358 if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
359 $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
363 foreach my $basketgroup (@$basketgroups){
364 if(! $basketgroup->{'id'}){
365 foreach my $basket (@{$basketgroup->{'baskets'}}){
366 if($input->param('basket'.$basket->{'basketno'}.'changed')){
370 } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
371 ModBasketgroup($basketgroup);
374 $basketgroups = &GetBasketgroups($booksellerid);
375 my $bookseller = &GetBookSellerFromId($booksellerid);
376 $baskets = &GetBasketsByBookseller($booksellerid);
378 displaybasketgroups($basketgroups, $bookseller, $baskets);
379 } elsif ( $op eq 'closeandprint') {
380 my $basketgroupid = $input->param('basketgroupid');
382 CloseBasketgroup($basketgroupid);
384 printbasketgrouppdf($basketgroupid);
386 }elsif ($op eq 'print'){
387 my $basketgroupid = $input->param('basketgroupid');
389 printbasketgrouppdf($basketgroupid);
391 }elsif( $op eq "delete"){
392 my $basketgroupid = $input->param('basketgroupid');
393 DelBasketgroup($basketgroupid);
394 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
396 }elsif ( $op eq 'reopen'){
397 my $basketgroupid = $input->param('basketgroupid');
398 my $booksellerid = $input->param('booksellerid');
400 ReOpenBasketgroup($basketgroupid);
402 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
404 } elsif ( $op eq 'attachbasket') {
407 my $basketgroup = {};
408 my @baskets = $input->param('basket');
409 my $basketgroupid = $input->param('basketgroupid');
410 my $basketgroupname = $input->param('basketgroupname');
411 my $booksellerid = $input->param('booksellerid');
412 my $billingplace = $input->param('billingplace');
413 my $deliveryplace = $input->param('deliveryplace');
414 my $freedeliveryplace = $input->param('freedeliveryplace');
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) {
420 name => $basketgroupname,
421 id => $basketgroupid,
422 basketlist => \@baskets,
423 billingplace => $billingplace,
424 deliveryplace => $deliveryplace,
425 freedeliveryplace => $freedeliveryplace,
426 deliverycomment => $deliverycomment,
429 ModBasketgroup($basketgroup);
435 name => $basketgroupname,
436 booksellerid => $booksellerid,
437 basketlist => \@baskets,
438 deliveryplace => $deliveryplace,
439 freedeliveryplace => $freedeliveryplace,
440 deliverycomment => $deliverycomment,
443 $basketgroupid = NewBasketgroup($basketgroup);
446 my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
447 $url .= "&closed=1" if ($input->param("closed"));
448 print $input->redirect($url);
451 my $basketgroups = &GetBasketgroups($booksellerid);
452 my $bookseller = &GetBookSellerFromId($booksellerid);
453 my $baskets = &GetBasketsByBookseller($booksellerid);
455 displaybasketgroups($basketgroups, $bookseller, $baskets);
457 $template->param(closed => $input->param("closed"));
458 #prolly won't use all these, maybe just use print, the rest can be done inside validate
459 output_html_with_http_headers $input, $cookie, $template->output;