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
8 # This file is part of Koha.
10 # Koha is free software; you can redistribute it and/or modify it under the
11 # terms of the GNU General Public License as published by the Free Software
12 # Foundation; either version 2 of the License, or (at your option) any later
15 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
16 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License along
20 # with Koha; if not, write to the Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 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
39 The bookseller who we want to display the baskets (and basketgroups) of.
53 use C4::Bookseller qw/GetBookSellerFromId/;
54 use C4::Acquisition qw/CloseBasketgroup ReOpenBasketgroup GetOrders GetBasketsByBasketgroup GetBasketsByBookseller ModBasketgroup NewBasketgroup DelBasketgroup GetBasketgroups ModBasket GetBasketgroup GetBasket/;
55 use C4::Bookseller qw/GetBookSellerFromId/;
56 use C4::Branch qw/GetBranches/;
57 use C4::Members qw/GetMember/;
61 my ($template, $loggedinuser, $cookie)
62 = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
66 flagsrequired => {acquisition => 'group_manage'},
70 sub parseinputbaskets {
71 my $booksellerid = shift;
72 my $baskets = &GetBasketsByBookseller($booksellerid);
73 for(my $i=0; $i < scalar @$baskets; ++$i) {
74 if( @$baskets[$i] && ! @$baskets[$i]->{'closedate'} ) {
75 splice(@$baskets, $i, 1);
79 foreach my $basket (@$baskets){
80 #perl DBI uses value "undef" for the mysql "NULL" value, so i need to check everywhere where $basket->{'basketgroupid'} is used for undef ☹
81 $basket->{'basketgroupid'} = $input->param($basket->{'basketno'}.'-group') || undef;
88 sub parseinputbasketgroups {
89 my $booksellerid = shift;
91 my $basketgroups = &GetBasketgroups($booksellerid);
93 foreach my $basket (@$baskets){
97 if(! $basket->{'basketgroupid'} || $basket->{'basketgroupid'} == 0){
100 foreach my $basketgroup (@$basketgroups){
101 if($basket->{'basketgroupid'} == $basketgroup->{'id'}){
103 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
109 #if the basketgroup doesn't exist yet
110 $basketgroup = $newbasketgroups->{$basket->{'basketgroupid'}} || undef;
111 $basketgroup->{'booksellerid'} = $booksellerid;
113 while($i < scalar @$basketgroups && @$basketgroups[$i]->{'id'} != $basket->{'basketgroupid'}){
116 $basketgroup = @$basketgroups[$i];
118 $basketgroup->{'id'}=$basket->{'basketgroupid'};
119 $basketgroup->{'name'}=$input->param('basketgroup-'.$basketgroup->{'id'}.'-name') || "";
120 $basketgroup->{'closed'}= $input->param('basketgroup-'.$basketgroup->{'id'}.'-closed');
121 push(@{$basketgroup->{'basketlist'}}, $basket->{'basketno'});
123 $newbasketgroups->{$basket->{'basketgroupid'}} = $basketgroup;
125 if($basketgroup->{'id'}){
126 @$basketgroups[$i] = $basketgroup;
130 return($basketgroups, $newbasketgroups);
134 my $basketno = shift;
135 my $bookseller = shift;
137 my @orders = GetOrders($basketno);
138 for my $order (@orders){
139 $total = $total + ( $order->{ecost} * $order->{quantity} );
140 if ($bookseller->{invoiceincgst} && ! $bookseller->{listincgst} && ( $bookseller->{gstrate} || C4::Context->preference("gist") )) {
141 my $gst = $bookseller->{gstrate} || C4::Context->preference("gist");
142 $total = $total * ( $gst / 100 +1);
145 $total .= $bookseller->{invoiceprice};
149 #displays all basketgroups and all closed baskets (in their respective groups)
150 sub displaybasketgroups {
151 my $basketgroups = shift;
152 my $bookseller = shift;
154 if (scalar @$basketgroups != 0) {
155 foreach my $basketgroup (@$basketgroups){
157 while($i < scalar(@$baskets)){
158 my $basket = @$baskets[$i];
159 if($basket->{'basketgroupid'} && $basket->{'basketgroupid'} == $basketgroup->{'id'}){
160 $basket->{total} = BasketTotal($basket->{basketno}, $bookseller);
161 push(@{$basketgroup->{'baskets'}}, $basket);
162 splice(@$baskets, $i, 1);
168 $template->param(basketgroups => $basketgroups);
170 for(my $i=0; $i < scalar @$baskets; ++$i) {
171 if( ! @$baskets[$i]->{'closedate'} ) {
172 splice(@$baskets, $i, 1);
175 @$baskets[$i]->{total} = BasketTotal(@$baskets[$i]->{basketno}, $bookseller);
178 $template->param(baskets => $baskets);
179 $template->param( booksellername => $bookseller ->{'name'});
182 sub printbasketgrouppdf{
183 my ($basketgroupid) = @_;
185 my $pdfformat = C4::Context->preference("OrderPdfFormat");
186 eval "use $pdfformat" ;
187 eval "use C4::Branch";
189 my $basketgroup = GetBasketgroup($basketgroupid);
190 my $bookseller = GetBookSellerFromId($basketgroup->{'booksellerid'});
191 my $baskets = GetBasketsByBasketgroup($basketgroupid);
194 for my $basket (@$baskets) {
196 my @ords = &GetOrders($basket->{basketno});
197 for my $ord (@ords) {
198 # ba_order is filled with :
199 # 0 1 2 3 4 5 6 7 8 9
200 #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount gstrate
202 if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
203 eval "use C4::Biblio";
205 my $bib = GetBiblioData($ord->{biblionumber});
206 my $itemtypes = GetItemTypes();
208 push(@ba_order, $ord->{isbn});
210 push(@ba_order, undef);
212 if ($ord->{itemtype}){
213 push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description}) if $bib->{itemtype};
215 push(@ba_order, undef);
218 # push(@ba_order, undef, undef);
219 for my $key (qw/author title publishercode quantity listprice ecost/) {
220 push(@ba_order, $ord->{$key}); #Order lines
222 push(@ba_order, $bookseller->{discount});
223 push(@ba_order, $bookseller->{gstrate}*100 || C4::Context->preference("gist") || 0);
224 push(@ba_orders, \@ba_order);
227 if (C4::Context->preference("marcflavour") eq 'UNIMARC') {
228 $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('345',"b");
229 } elsif (C4::Context->preference("marcflavour") eq 'MARC21') {
230 $en = MARC::Record::new_from_xml($ord->{marcxml},'UTF-8')->subfield('037',"a");
233 push(@ba_order, $en);
235 push(@ba_order, undef);
239 $orders{$basket->{basketno}}=\@ba_orders;
241 print $input->header( -type => 'application/pdf', -attachment => $basketgroup->{name}.'.pdf' );
242 my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->{gstrate} || C4::Context->preference("gist")) || die "pdf generation failed";
247 my $op = $input->param('op');
248 my $booksellerid = $input->param('booksellerid');
249 $template->param(booksellerid => $booksellerid);
251 if ( $op eq "add" ) {
253 $template->param( ungroupedlist => 1);
254 my @booksellers = GetBookSeller('');
255 for (my $i=0; $i < scalar @booksellers; $i++) {
256 my $baskets = &GetBasketsByBookseller($booksellers[$i]->{id});
257 for (my $j=0; $j < scalar @$baskets; $j++) {
258 if(! @$baskets[$i]->{closedate} || @$baskets[$i]->{basketgroupid}) {
259 splice(@$baskets, $j, 1);
263 if (scalar @$baskets == 0){
264 splice(@booksellers, $i, 1);
269 my $basketgroupid = $input->param('basketgroupid');
272 if ( $basketgroupid ) {
273 # Get the selected baskets in the basketgroup to display them
274 my $selecteds = GetBasketsByBasketgroup($basketgroupid);
275 foreach (@{$selecteds}){
276 $_->{total} = BasketTotal($_->{basketno}, $_);
278 $template->param(basketgroupid => $basketgroupid,
279 selectedbaskets => $selecteds);
281 # Get general informations about the basket group to prefill the form
282 my $basketgroup = GetBasketgroup($basketgroupid);
284 name => $basketgroup->{name},
285 deliverycomment => $basketgroup->{deliverycomment},
287 $billingplace = $basketgroup->{billingplace};
288 $deliveryplace = $basketgroup->{deliveryplace};
291 # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data
292 my $borrower = GetMember( ( 'borrowernumber' => $loggedinuser ) );
293 $billingplace = $billingplace || $borrower->{'branchcode'};
294 $deliveryplace = $deliveryplace || $borrower->{'branchcode'};
296 my $branches = GetBranches;
298 # Build the combobox to select the billing place
299 my @billingplaceloop;
300 for (sort keys %$branches) {
301 my $selected = 1 if $_ eq $billingplace;
304 selected => $selected,
305 branchname => $branches->{$_}->{branchname},
307 push @billingplaceloop, \%row;
309 $template->param( billingplaceloop => \@billingplaceloop );
311 # Build the combobox to select the delivery place
312 my @deliveryplaceloop;
313 for (sort keys %$branches) {
314 my $selected = 1 if $_ eq $deliveryplace;
317 selected => $selected,
318 branchname => $branches->{$_}->{branchname},
320 push @deliveryplaceloop, \%row;
322 $template->param( deliveryplaceloop => \@deliveryplaceloop );
324 $template->param( booksellerid => $booksellerid );
326 $template->param(grouping => 1);
327 my $basketgroups = &GetBasketgroups($booksellerid);
328 my $bookseller = &GetBookSellerFromId($booksellerid);
329 my $baskets = &GetBasketsByBookseller($booksellerid);
331 displaybasketgroups($basketgroups, $bookseller, $baskets);
332 } elsif ($op eq 'mod_basket') {
333 #we want to modify an individual basket's group
334 my $basketno=$input->param('basketno');
335 my $basketgroupid=$input->param('basketgroupid');
336 ModBasket( { basketno => $basketno,
337 basketgroupid => $basketgroupid } );
338 print $input->redirect("basket.pl?basketno=" . $basketno);
339 } elsif ($op eq 'validate') {
341 $template->param( booksellererror => 1);
343 $template->param( booksellerid => $booksellerid );
345 my $baskets = parseinputbaskets($booksellerid);
346 my ($basketgroups, $newbasketgroups) = parseinputbasketgroups($booksellerid, $baskets);
347 foreach my $nbgid (keys %$newbasketgroups){
348 #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
349 my $bgid = NewBasketgroup($newbasketgroups->{$nbgid});
350 ${$newbasketgroups->{$nbgid}}->{'id'} = $bgid;
351 ${$newbasketgroups->{$nbgid}}->{'oldid'} = $nbgid;
353 foreach my $basket (@$baskets){
354 #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.
355 if ( $basket->{'basketgroupid'} && $newbasketgroups->{$basket->{'basketgroupid'}} ){
356 $basket->{'basketgroupid'} = ${$newbasketgroups->{$basket->{'basketgroupid'}}}->{'id'};
360 foreach my $basketgroup (@$basketgroups){
361 if(! $basketgroup->{'id'}){
362 foreach my $basket (@{$basketgroup->{'baskets'}}){
363 if($input->param('basket'.$basket->{'basketno'}.'changed')){
367 } elsif ($input->param('basketgroup-'.$basketgroup->{'id'}.'-changed')){
368 ModBasketgroup($basketgroup);
371 $basketgroups = &GetBasketgroups($booksellerid);
372 my $bookseller = &GetBookSellerFromId($booksellerid);
373 $baskets = &GetBasketsByBookseller($booksellerid);
375 displaybasketgroups($basketgroups, $bookseller, $baskets);
376 } elsif ( $op eq 'closeandprint') {
377 my $basketgroupid = $input->param('basketgroupid');
379 CloseBasketgroup($basketgroupid);
381 printbasketgrouppdf($basketgroupid);
382 }elsif ($op eq 'print'){
383 my $basketgroupid = $input->param('basketgroupid');
385 printbasketgrouppdf($basketgroupid);
386 }elsif( $op eq "delete"){
387 my $basketgroupid = $input->param('basketgroupid');
388 DelBasketgroup($basketgroupid);
389 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid);
391 }elsif ( $op eq 'reopen'){
392 my $basketgroupid = $input->param('basketgroupid');
393 my $booksellerid = $input->param('booksellerid');
395 ReOpenBasketgroup($basketgroupid);
397 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid . '#closed');
399 } elsif ( $op eq 'attachbasket') {
402 my $basketgroup = {};
403 my @baskets = $input->param('basket');
404 my $basketgroupid = $input->param('basketgroupid');
405 my $basketgroupname = $input->param('basketgroupname');
406 my $booksellerid = $input->param('booksellerid');
407 my $billingplace = $input->param('billingplace');
408 my $deliveryplace = $input->param('deliveryplace');
409 my $deliverycomment = $input->param('deliverycomment');
410 my $close = $input->param('close') ? 1 : 0;
411 # If we got a basketgroupname, we create a basketgroup
412 if ($basketgroupid) {
414 name => $basketgroupname,
415 id => $basketgroupid,
416 basketlist => \@baskets,
417 billingplace => $billingplace,
418 deliveryplace => $deliveryplace,
419 deliverycomment => $deliverycomment,
422 ModBasketgroup($basketgroup);
428 name => $basketgroupname,
429 booksellerid => $booksellerid,
430 basketlist => \@baskets,
431 deliveryplace => $deliveryplace,
432 deliverycomment => $deliverycomment,
435 $basketgroupid = NewBasketgroup($basketgroup);
438 my $url = '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
439 $url .= "&closed=1" if ($input->param("closed"));
440 print $input->redirect($url);
443 my $basketgroups = &GetBasketgroups($booksellerid);
444 my $bookseller = &GetBookSellerFromId($booksellerid);
445 my $baskets = &GetBasketsByBookseller($booksellerid);
447 displaybasketgroups($basketgroups, $bookseller, $baskets);
449 $template->param(closed => $input->param("closed"));
450 #prolly won't use all these, maybe just use print, the rest can be done inside validate
451 output_html_with_http_headers $input, $cookie, $template->output;