3 #script to show display basket of orders
5 # Copyright 2000 - 2004 Katipo
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
11 # under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or
13 # (at your option) any later version.
15 # Koha is distributed in the hope that it will be useful, but
16 # WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with Koha; if not, see <http://www.gnu.org/licenses>.
33 use C4
::Members qw
/GetMember/; #needed for permissions checking for changing basketgroup of a basket
37 use C4
::Letters qw
/SendAlerts/;
38 use Date
::Calc qw
/Add_Delta_Days/;
40 use Koha
::EDI
qw( create_edi_order get_edifact_ean );
48 This script display all informations about basket for the supplier given
49 on input arg. Moreover, it allows us to add a new order for this supplier from
50 an existing record, a suggestion or a new record.
62 the supplier this script have to display the basket.
71 our $basketno = $query->param('basketno');
72 my $ean = $query->param('ean');
73 my $booksellerid = $query->param('booksellerid');
74 my $duplinbatch = $query->param('duplinbatch');
76 my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user
(
78 template_name
=> "acqui/basket.tt",
82 flagsrequired
=> { acquisition
=> 'order_manage' },
87 my $basket = GetBasket
($basketno);
88 $booksellerid = $basket->{booksellerid
} unless $booksellerid;
89 my $bookseller = Koha
::Acquisition
::Bookseller
->fetch({ id
=> $booksellerid });
90 my $schema = Koha
::Database
->new()->schema();
91 my $rs = $schema->resultset('VendorEdiAccount')->search(
92 { vendor_id
=> $booksellerid, } );
93 $template->param( ediaccount
=> ($rs->count > 0));
95 unless (CanUserManageBasket
($loggedinuser, $basket, $userflags)) {
97 cannot_manage_basket
=> 1,
98 basketno
=> $basketno,
99 basketname
=> $basket->{basketname
},
100 booksellerid
=> $booksellerid,
101 name
=> $bookseller->{name
}
103 output_html_with_http_headers
$query, $cookie, $template->output;
107 # FIXME : what about the "discount" percentage?
108 # FIXME : the query->param('booksellerid') below is probably useless. The bookseller is always known from the basket
109 # if no booksellerid in parameter, get it from basket
110 # warn "=>".$basket->{booksellerid};
111 my $op = $query->param('op') // 'list';
113 my $confirm_pref= C4
::Context
->preference("BasketConfirmations") || '1';
114 $template->param( skip_confirm_reopen
=> 1) if $confirm_pref eq '2';
118 if ( $op eq 'delete_confirm' ) {
119 my $basketno = $query->param('basketno');
120 my $delbiblio = $query->param('delbiblio');
121 my @orders = GetOrders
($basketno);
122 #Delete all orders included in that basket, and all items received.
123 foreach my $myorder (@orders){
124 DelOrder
($myorder->{biblionumber
},$myorder->{ordernumber
});
126 # if $delbiblio = 1, delete the records if possible
127 if ((defined $delbiblio)and ($delbiblio ==1)){
128 my @cannotdelbiblios ;
129 foreach my $myorder (@orders){
130 my $biblionumber = $myorder->{'biblionumber'};
131 my $countbiblio = CountBiblioInOrders
($biblionumber);
132 my $ordernumber = $myorder->{'ordernumber'};
133 my $subscriptions = scalar GetSubscriptionsId
($biblionumber);
134 my $itemcount = GetItemsCount
($biblionumber);
136 if ($countbiblio == 0 && $itemcount == 0 && $subscriptions == 0) {
137 $error = DelBiblio
($myorder->{biblionumber
}) }
139 push @cannotdelbiblios, {biblionumber
=> ($myorder->{biblionumber
}),
140 title
=> $myorder->{'title'},
141 author
=> $myorder->{'author'},
142 countbiblio
=> $countbiblio,
143 itemcount
=>$itemcount,
144 subscriptions
=>$subscriptions};
147 push @cannotdelbiblios, {biblionumber
=> ($myorder->{biblionumber
}),
148 title
=> $myorder->{'title'},
149 author
=> $myorder->{'author'},
150 othererror
=> $error};
153 $template->param( cannotdelbiblios
=> \
@cannotdelbiblios );
156 DelBasket
($basketno,);
157 $template->param( delete_confirmed
=> 1 );
158 } elsif ( !$bookseller ) {
159 $template->param( NO_BOOKSELLER
=> 1 );
160 } elsif ($op eq 'export') {
161 print $query->header(
163 -attachment
=> 'basket' . $basket->{'basketno'} . '.csv',
165 print GetBasketAsCSV
($query->param('basketno'), $query);
167 } elsif ($op eq 'email') {
169 SendAlerts
( 'orderacquisition', $query->param('basketno'), 'ACQORDER' );
172 push @messages, { type
=> 'error', code
=> $@
};
173 } elsif ( ref $err and exists $err->{error
} ) {
174 push @messages, { type
=> 'error', code
=> $err->{error
} };
176 push @messages, { type
=> 'message', code
=> 'email_sent' };
180 } elsif ($op eq 'close') {
181 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
183 my $basketno = $query->param('basketno');
184 my $booksellerid = $query->param('booksellerid');
185 $basketno =~ /^\d+$/ and CloseBasket
($basketno);
186 # if requested, create basket group, close it and attach the basket
187 if ($query->param('createbasketgroup')) {
189 if(C4
::Context
->userenv and C4
::Context
->userenv->{'branch'}
190 and C4
::Context
->userenv->{'branch'} ne "NO_LIBRARY_SET") {
191 $branchcode = C4
::Context
->userenv->{'branch'};
193 my $basketgroupid = NewBasketgroup
( { name
=> $basket->{basketname
},
194 booksellerid
=> $booksellerid,
195 deliveryplace
=> $branchcode,
196 billingplace
=> $branchcode,
199 ModBasket
( { basketno
=> $basketno,
200 basketgroupid
=> $basketgroupid } );
201 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
203 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
208 confirm_close
=> "1",
209 booksellerid
=> $booksellerid,
210 basketno
=> $basket->{'basketno'},
211 basketname
=> $basket->{'basketname'},
212 basketgroupname
=> $basket->{'basketname'},
215 } elsif ($op eq 'reopen') {
216 ReopenBasket
($query->param('basketno'));
217 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
219 elsif ( $op eq 'ediorder' ) {
220 edi_close_and_order
()
221 } elsif ( $op eq 'mod_users' ) {
222 my $basketusers_ids = $query->param('users_ids');
223 my @basketusers = split( /:/, $basketusers_ids );
224 ModBasketUsers
($basketno, @basketusers);
225 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
227 } elsif ( $op eq 'mod_branch' ) {
228 my $branch = $query->param('branch');
229 $branch = undef if(defined $branch and $branch eq '');
231 basketno
=> $basket->{basketno
},
234 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
238 if ( $op eq 'list' ) {
240 # get librarian branch...
241 if ( C4
::Context
->preference("IndependentBranches") ) {
242 my $userenv = C4
::Context
->userenv;
243 unless ( C4
::Context
->IsSuperLibrarian() ) {
244 my $validtest = ( $basket->{creationdate
} eq '' )
245 || ( $userenv->{branch
} eq $basket->{branch
} )
246 || ( $userenv->{branch
} eq '' )
247 || ( $basket->{branch
} eq '' );
248 unless ($validtest) {
249 print $query->redirect("../mainpage.pl");
254 if (!defined $basket->{branch
} or $basket->{branch
} eq $userenv->{branch
}) {
255 push @branches_loop, {
256 branchcode
=> $userenv->{branch
},
257 branchname
=> $userenv->{branchname
},
263 my $branches = Koha
::Libraries
->search( {}, { order_by
=> ['branchname'] } )->unblessed;
264 foreach my $branch (@
$branches) {
266 if (defined $basket->{branch
}) {
267 $selected = 1 if $branch->{branchcode
} eq $basket->{branch
};
269 $selected = 1 if $branch->{branchcode
} eq C4
::Context
->userenv->{branch
};
271 push @branches_loop, {
272 branchcode
=> $branch->{branchcode
},
273 branchname
=> $branch->{branchname
},
274 selected
=> $selected
279 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
280 my ($basketgroup, $basketgroups);
281 my $staffuser = GetMember
(borrowernumber
=> $loggedinuser);
282 if ($basket->{closedate
} && haspermission
($staffuser->{userid
}, { acquisition
=> 'group_manage'} )) {
283 $basketgroups = GetBasketgroups
($basket->{booksellerid
});
284 for my $bg ( @
{$basketgroups} ) {
285 if ($basket->{basketgroupid
} && $basket->{basketgroupid
} == $bg->{id
}){
292 # if the basket is closed, calculate estimated delivery date
293 my $estimateddeliverydate;
294 if( $basket->{closedate
} ) {
295 my ($year, $month, $day) = ($basket->{closedate
} =~ /(\d+)-(\d+)-(\d+)/);
296 ($year, $month, $day) = Add_Delta_Days
($year, $month, $day, $bookseller->{deliverytime
});
297 $estimateddeliverydate = sprintf( "%04d-%02d-%02d", $year, $month, $day );
300 # if new basket, pre-fill infos
301 $basket->{creationdate
} = "" unless ( $basket->{creationdate
} );
302 $basket->{authorisedby
} = $loggedinuser unless ( $basket->{authorisedby
} );
305 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
306 $basket->{creationdate
}, $basket->{authorisedby
};
308 my @basketusers_ids = GetBasketUsers
($basketno);
310 foreach my $basketuser_id (@basketusers_ids) {
311 my $basketuser = GetMember
(borrowernumber
=> $basketuser_id);
312 push @basketusers, $basketuser if $basketuser;
315 my $active_currency = Koha
::Acquisition
::Currencies
->get_active;
317 my @orders = GetOrders
( $basketno );
322 my $total_quantity = 0;
323 my $total_tax_excluded = 0;
324 my $total_tax_included = 0;
325 my $total_tax_value = 0;
326 for my $order (@orders) {
327 my $line = get_order_infos
( $order, $bookseller);
328 if ( $line->{uncertainprice
} ) {
329 $template->param( uncertainprices
=> 1 );
332 $line->{tax_rate
} = $line->{tax_rate_on_ordering
};
333 $line->{tax_value
} = $line->{tax_value_on_ordering
};
335 push @books_loop, $line;
337 $foot{$$line{tax_rate
}}{tax_rate
} = $$line{tax_rate
};
338 $foot{$$line{tax_rate
}}{tax_value
} += $$line{tax_value
};
339 $total_tax_value += $$line{tax_value
};
340 $foot{$$line{tax_rate
}}{quantity
} += $$line{quantity
};
341 $total_quantity += $$line{quantity
};
342 $foot{$$line{tax_rate
}}{total_tax_excluded
} += $$line{total_tax_excluded
};
343 $total_tax_excluded += $$line{total_tax_excluded
};
344 $foot{$$line{tax_rate
}}{total_tax_included
} += $$line{total_tax_included
};
345 $total_tax_included += $$line{total_tax_included
};
348 push @book_foot_loop, map {$_} values %foot;
350 # Get cancelled orders
351 my @cancelledorders = GetOrders
($basketno, { cancelled
=> 1 });
352 my @cancelledorders_loop;
353 for my $order (@cancelledorders) {
354 my $line = get_order_infos
( $order, $bookseller);
355 push @cancelledorders_loop, $line;
358 my $contract = GetContract
({
359 contractnumber
=> $basket->{contractnumber
}
362 if ($basket->{basketgroupid
}){
363 $basketgroup = GetBasketgroup
($basket->{basketgroupid
});
365 my $borrower= GetMember
('borrowernumber' => $loggedinuser);
366 my $budgets = GetBudgetHierarchy
;
368 foreach my $r (@
{$budgets}) {
369 if (!defined $r->{budget_amount
} || $r->{budget_amount
} == 0) {
372 next unless (CanUserUseBudget
($loggedinuser, $r, $userflags));
379 basketno
=> $basketno,
381 basketname
=> $basket->{'basketname'},
382 basketbranchcode
=> $basket->{branch
},
383 basketnote
=> $basket->{note
},
384 basketbooksellernote
=> $basket->{booksellernote
},
385 basketcontractno
=> $basket->{contractnumber
},
386 basketcontractname
=> $contract->{contractname
},
387 branches_loop
=> \
@branches_loop,
388 creationdate
=> $basket->{creationdate
},
389 authorisedby
=> $basket->{authorisedby
},
390 authorisedbyname
=> $basket->{authorisedbyname
},
391 users_ids
=> join(':', @basketusers_ids),
392 users
=> \
@basketusers,
393 closedate
=> $basket->{closedate
},
394 estimateddeliverydate
=> $estimateddeliverydate,
395 is_standing
=> $basket->{is_standing
},
396 deliveryplace
=> $basket->{deliveryplace
},
397 billingplace
=> $basket->{billingplace
},
398 active
=> $bookseller->{'active'},
399 booksellerid
=> $bookseller->{'id'},
400 name
=> $bookseller->{'name'},
401 books_loop
=> \
@books_loop,
402 book_foot_loop
=> \
@book_foot_loop,
403 cancelledorders_loop
=> \
@cancelledorders_loop,
404 total_quantity
=> $total_quantity,
405 total_tax_excluded
=> $total_tax_excluded,
406 total_tax_included
=> $total_tax_included,
407 total_tax_value
=> $total_tax_value,
408 currency
=> $active_currency->currency,
409 listincgst
=> $bookseller->{listincgst
},
410 basketgroups
=> $basketgroups,
411 basketgroup
=> $basketgroup,
412 grouped
=> $basket->{basketgroupid
},
413 # The double negatives and booleans here mean:
414 # "A basket cannot be closed if there are no orders in it or it's a standing order basket."
416 # (The template has another implicit restriction that the order cannot be closed if there
417 # are any orders with uncertain prices.)
418 unclosable
=> @orders ?
$basket->{is_standing
} : 1,
419 has_budgets
=> $has_budgets,
420 duplinbatch
=> $duplinbatch,
424 $template->param( messages
=> \
@messages );
425 output_html_with_http_headers
$query, $cookie, $template->output;
427 sub get_order_infos
{
429 my $bookseller = shift;
430 my $qty = $order->{'quantity'} || 0;
431 if ( !defined $order->{quantityreceived
} ) {
432 $order->{quantityreceived
} = 0;
434 my $budget = GetBudget
($order->{budget_id
});
435 my $basket = GetBasket
($order->{basketno
});
437 my %line = %{ $order };
438 # Don't show unreceived standing orders as received
439 $line{order_received
} = ( $qty == $order->{'quantityreceived'} && ( $basket->{is_standing
} ?
$qty : 1 ) );
440 $line{basketno
} = $basketno;
441 $line{budget_name
} = $budget->{budget_name
};
443 $line{total_tax_included
} = $line{ecost_tax_included
} * $line{quantity
};
444 $line{total_tax_excluded
} = $line{ecost_tax_excluded
} * $line{quantity
};
445 $line{tax_value
} = $line{tax_value_on_ordering
};
446 $line{tax_rate
} = $line{tax_rate_on_ordering
};
448 if ( $line{uncertainprice
} ) {
449 $line{rrp_tax_excluded
} .= ' (Uncertain)';
451 if ( $line{'title'} ) {
452 my $volume = $order->{'volume'};
453 my $seriestitle = $order->{'seriestitle'};
454 $line{'title'} .= " / $seriestitle" if $seriestitle;
455 $line{'title'} .= " / $volume" if $volume;
458 my $biblionumber = $order->{'biblionumber'};
459 my $countbiblio = CountBiblioInOrders
($biblionumber);
460 my $ordernumber = $order->{'ordernumber'};
461 my @subscriptions = GetSubscriptionsId
($biblionumber);
462 my $itemcount = GetItemsCount
($biblionumber);
463 my $holds = GetHolds
($biblionumber);
464 my @items = GetItemnumbersFromOrder
( $ordernumber );
466 foreach my $item (@items){
467 my $nb = GetItemHolds
($biblionumber, $item);
472 # if the biblio is not in other orders and if there is no items elsewhere and no subscriptions and no holds we can then show the link "Delete order and Biblio" see bug 5680
473 $line{can_del_bib
} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds);
474 $line{items
} = ($itemcount) - (scalar @items);
475 $line{left_item
} = 1 if $line{items
} >= 1;
476 $line{left_biblio
} = 1 if $countbiblio > 1;
477 $line{biblios
} = $countbiblio - 1;
478 $line{left_subscription
} = 1 if scalar @subscriptions >= 1;
479 $line{subscriptions
} = scalar @subscriptions;
480 ($holds >= 1) ?
$line{left_holds
} = 1 : $line{left_holds
} = 0;
481 $line{left_holds_on_order
} = 1 if $line{left_holds
}==1 && ($line{items
} == 0 || $itemholds );
482 $line{holds
} = $holds;
483 $line{holds_on_order
} = $itemholds?
$itemholds:$holds if $line{left_holds_on_order
};
486 my $suggestion = GetSuggestionInfoFromBiblionumber
($line{biblionumber
});
487 $line{suggestionid
} = $$suggestion{suggestionid
};
488 $line{surnamesuggestedby
} = $$suggestion{surnamesuggestedby
};
489 $line{firstnamesuggestedby
} = $$suggestion{firstnamesuggestedby
};
491 foreach my $key (qw(transferred_from transferred_to)) {
493 my $order = GetOrder
($line{$key});
494 my $bookseller = Koha
::Acquisition
::Bookseller
->fetch({ id
=> $basket->{booksellerid
} });
498 bookseller
=> $bookseller,
499 timestamp
=> $line{$key . '_timestamp'},
507 sub edi_close_and_order
{
508 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
511 basketno
=> $basketno,
514 if ( $basket->{branch
} ) {
515 $edi_params->{branchcode
} = $basket->{branch
};
517 if ( create_edi_order
($edi_params) ) {
518 #$template->param( edifile => 1 );
520 CloseBasket
($basketno);
522 # if requested, create basket group, close it and attach the basket
523 if ( $query->param('createbasketgroup') ) {
525 if ( C4
::Context
->userenv
526 and C4
::Context
->userenv->{'branch'}
527 and C4
::Context
->userenv->{'branch'} ne "NO_LIBRARY_SET" )
529 $branchcode = C4
::Context
->userenv->{'branch'};
531 my $basketgroupid = NewBasketgroup
(
533 name
=> $basket->{basketname
},
534 booksellerid
=> $booksellerid,
535 deliveryplace
=> $branchcode,
536 billingplace
=> $branchcode,
542 basketno
=> $basketno,
543 basketgroupid
=> $basketgroupid
546 print $query->redirect(
547 "/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=$booksellerid&closed=1"
551 print $query->redirect(
552 "/cgi-bin/koha/acqui/booksellers.pl?booksellerid=$booksellerid"
560 booksellerid
=> $booksellerid,
561 basketno
=> $basket->{basketno
},
562 basketname
=> $basket->{basketname
},
563 basketgroupname
=> $basket->{basketname
},
566 $template->param( ean
=> $ean );