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 Koha
::Acquisition
::Booksellers
;
39 use C4
::Letters qw
/SendAlerts/;
40 use Date
::Calc qw
/Add_Delta_Days/;
42 use Koha
::EDI
qw( create_edi_order get_edifact_ean );
50 This script display all informations about basket for the supplier given
51 on input arg. Moreover, it allows us to add a new order for this supplier from
52 an existing record, a suggestion or a new record.
64 the supplier this script have to display the basket.
73 our $basketno = $query->param('basketno');
74 my $ean = $query->param('ean');
75 my $booksellerid = $query->param('booksellerid');
76 my $duplinbatch = $query->param('duplinbatch');
78 my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user
(
80 template_name
=> "acqui/basket.tt",
84 flagsrequired
=> { acquisition
=> 'order_manage' },
89 my $basket = GetBasket
($basketno);
90 $booksellerid = $basket->{booksellerid
} unless $booksellerid;
91 my $bookseller = Koha
::Acquisition
::Booksellers
->find( $booksellerid );
92 my $schema = Koha
::Database
->new()->schema();
93 my $rs = $schema->resultset('VendorEdiAccount')->search(
94 { vendor_id
=> $booksellerid, } );
95 $template->param( ediaccount
=> ($rs->count > 0));
97 unless (CanUserManageBasket
($loggedinuser, $basket, $userflags)) {
99 cannot_manage_basket
=> 1,
100 basketno
=> $basketno,
101 basketname
=> $basket->{basketname
},
102 booksellerid
=> $booksellerid,
103 name
=> $bookseller->name,
105 output_html_with_http_headers
$query, $cookie, $template->output;
109 # FIXME : what about the "discount" percentage?
110 # FIXME : the query->param('booksellerid') below is probably useless. The bookseller is always known from the basket
111 # if no booksellerid in parameter, get it from basket
112 # warn "=>".$basket->{booksellerid};
113 my $op = $query->param('op') // 'list';
115 my $confirm_pref= C4
::Context
->preference("BasketConfirmations") || '1';
116 $template->param( skip_confirm_reopen
=> 1) if $confirm_pref eq '2';
120 if ( $op eq 'delete_confirm' ) {
121 my $basketno = $query->param('basketno');
122 my $delbiblio = $query->param('delbiblio');
123 my @orders = GetOrders
($basketno);
124 #Delete all orders included in that basket, and all items received.
125 foreach my $myorder (@orders){
126 DelOrder
($myorder->{biblionumber
},$myorder->{ordernumber
});
128 # if $delbiblio = 1, delete the records if possible
129 if ((defined $delbiblio)and ($delbiblio ==1)){
130 my @cannotdelbiblios ;
131 foreach my $myorder (@orders){
132 my $biblionumber = $myorder->{'biblionumber'};
133 my $countbiblio = CountBiblioInOrders
($biblionumber);
134 my $ordernumber = $myorder->{'ordernumber'};
135 my $subscriptions = scalar GetSubscriptionsId
($biblionumber);
136 my $itemcount = GetItemsCount
($biblionumber);
138 if ($countbiblio == 0 && $itemcount == 0 && $subscriptions == 0) {
139 $error = DelBiblio
($myorder->{biblionumber
}) }
141 push @cannotdelbiblios, {biblionumber
=> ($myorder->{biblionumber
}),
142 title
=> $myorder->{'title'},
143 author
=> $myorder->{'author'},
144 countbiblio
=> $countbiblio,
145 itemcount
=>$itemcount,
146 subscriptions
=>$subscriptions};
149 push @cannotdelbiblios, {biblionumber
=> ($myorder->{biblionumber
}),
150 title
=> $myorder->{'title'},
151 author
=> $myorder->{'author'},
152 othererror
=> $error};
155 $template->param( cannotdelbiblios
=> \
@cannotdelbiblios );
158 DelBasket
($basketno,);
159 $template->param( delete_confirmed
=> 1 );
160 } elsif ( !$bookseller ) {
161 $template->param( NO_BOOKSELLER
=> 1 );
162 } elsif ($op eq 'export') {
163 print $query->header(
165 -attachment
=> 'basket' . $basket->{'basketno'} . '.csv',
167 print GetBasketAsCSV
($query->param('basketno'), $query);
169 } elsif ($op eq 'email') {
171 SendAlerts
( 'orderacquisition', $query->param('basketno'), 'ACQORDER' );
174 push @messages, { type
=> 'error', code
=> $@
};
175 } elsif ( ref $err and exists $err->{error
} ) {
176 push @messages, { type
=> 'error', code
=> $err->{error
} };
178 push @messages, { type
=> 'message', code
=> 'email_sent' };
182 } elsif ($op eq 'close') {
183 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
185 my $basketno = $query->param('basketno');
186 my $booksellerid = $query->param('booksellerid');
187 $basketno =~ /^\d+$/ and CloseBasket
($basketno);
188 # if requested, create basket group, close it and attach the basket
189 if ($query->param('createbasketgroup')) {
191 if(C4
::Context
->userenv and C4
::Context
->userenv->{'branch'}
192 and C4
::Context
->userenv->{'branch'} ne "NO_LIBRARY_SET") {
193 $branchcode = C4
::Context
->userenv->{'branch'};
195 my $basketgroupid = NewBasketgroup
( { name
=> $basket->{basketname
},
196 booksellerid
=> $booksellerid,
197 deliveryplace
=> $branchcode,
198 billingplace
=> $branchcode,
201 ModBasket
( { basketno
=> $basketno,
202 basketgroupid
=> $basketgroupid } );
203 print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
205 print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
210 confirm_close
=> "1",
211 booksellerid
=> $booksellerid,
212 basketno
=> $basket->{'basketno'},
213 basketname
=> $basket->{'basketname'},
214 basketgroupname
=> $basket->{'basketname'},
217 } elsif ($op eq 'reopen') {
218 ReopenBasket
($query->param('basketno'));
219 print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
221 elsif ( $op eq 'ediorder' ) {
222 edi_close_and_order
()
223 } elsif ( $op eq 'mod_users' ) {
224 my $basketusers_ids = $query->param('users_ids');
225 my @basketusers = split( /:/, $basketusers_ids );
226 ModBasketUsers
($basketno, @basketusers);
227 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
229 } elsif ( $op eq 'mod_branch' ) {
230 my $branch = $query->param('branch');
231 $branch = undef if(defined $branch and $branch eq '');
233 basketno
=> $basket->{basketno
},
236 print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
240 if ( $op eq 'list' ) {
242 # get librarian branch...
243 if ( C4
::Context
->preference("IndependentBranches") ) {
244 my $userenv = C4
::Context
->userenv;
245 unless ( C4
::Context
->IsSuperLibrarian() ) {
246 my $validtest = ( $basket->{creationdate
} eq '' )
247 || ( $userenv->{branch
} eq $basket->{branch
} )
248 || ( $userenv->{branch
} eq '' )
249 || ( $basket->{branch
} eq '' );
250 unless ($validtest) {
251 print $query->redirect("../mainpage.pl");
256 if (!defined $basket->{branch
} or $basket->{branch
} eq $userenv->{branch
}) {
257 push @branches_loop, {
258 branchcode
=> $userenv->{branch
},
259 branchname
=> $userenv->{branchname
},
265 my $branches = Koha
::Libraries
->search( {}, { order_by
=> ['branchname'] } )->unblessed;
266 foreach my $branch (@
$branches) {
268 if (defined $basket->{branch
}) {
269 $selected = 1 if $branch->{branchcode
} eq $basket->{branch
};
271 $selected = 1 if $branch->{branchcode
} eq C4
::Context
->userenv->{branch
};
273 push @branches_loop, {
274 branchcode
=> $branch->{branchcode
},
275 branchname
=> $branch->{branchname
},
276 selected
=> $selected
281 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
282 my ($basketgroup, $basketgroups);
283 my $staffuser = GetMember
(borrowernumber
=> $loggedinuser);
284 if ($basket->{closedate
} && haspermission
($staffuser->{userid
}, { acquisition
=> 'group_manage'} )) {
285 $basketgroups = GetBasketgroups
($basket->{booksellerid
});
286 for my $bg ( @
{$basketgroups} ) {
287 if ($basket->{basketgroupid
} && $basket->{basketgroupid
} == $bg->{id
}){
294 # if the basket is closed, calculate estimated delivery date
295 my $estimateddeliverydate;
296 if( $basket->{closedate
} ) {
297 my ($year, $month, $day) = ($basket->{closedate
} =~ /(\d+)-(\d+)-(\d+)/);
298 ($year, $month, $day) = Add_Delta_Days
($year, $month, $day, $bookseller->deliverytime);
299 $estimateddeliverydate = sprintf( "%04d-%02d-%02d", $year, $month, $day );
302 # if new basket, pre-fill infos
303 $basket->{creationdate
} = "" unless ( $basket->{creationdate
} );
304 $basket->{authorisedby
} = $loggedinuser unless ( $basket->{authorisedby
} );
307 "loggedinuser: $loggedinuser; creationdate: %s; authorisedby: %s",
308 $basket->{creationdate
}, $basket->{authorisedby
};
310 my @basketusers_ids = GetBasketUsers
($basketno);
312 foreach my $basketuser_id (@basketusers_ids) {
313 my $basketuser = GetMember
(borrowernumber
=> $basketuser_id);
314 push @basketusers, $basketuser if $basketuser;
317 my $active_currency = Koha
::Acquisition
::Currencies
->get_active;
319 my @orders = GetOrders
( $basketno );
324 my $total_quantity = 0;
325 my $total_tax_excluded = 0;
326 my $total_tax_included = 0;
327 my $total_tax_value = 0;
328 for my $order (@orders) {
329 my $line = get_order_infos
( $order, $bookseller);
330 if ( $line->{uncertainprice
} ) {
331 $template->param( uncertainprices
=> 1 );
334 $line->{tax_rate
} = $line->{tax_rate_on_ordering
};
335 $line->{tax_value
} = $line->{tax_value_on_ordering
};
337 push @books_loop, $line;
339 $foot{$$line{tax_rate
}}{tax_rate
} = $$line{tax_rate
};
340 $foot{$$line{tax_rate
}}{tax_value
} += $$line{tax_value
};
341 $total_tax_value += $$line{tax_value
};
342 $foot{$$line{tax_rate
}}{quantity
} += $$line{quantity
};
343 $total_quantity += $$line{quantity
};
344 $foot{$$line{tax_rate
}}{total_tax_excluded
} += $$line{total_tax_excluded
};
345 $total_tax_excluded += $$line{total_tax_excluded
};
346 $foot{$$line{tax_rate
}}{total_tax_included
} += $$line{total_tax_included
};
347 $total_tax_included += $$line{total_tax_included
};
350 push @book_foot_loop, map {$_} values %foot;
352 # Get cancelled orders
353 my @cancelledorders = GetOrders
($basketno, { cancelled
=> 1 });
354 my @cancelledorders_loop;
355 for my $order (@cancelledorders) {
356 my $line = get_order_infos
( $order, $bookseller);
357 push @cancelledorders_loop, $line;
360 my $contract = GetContract
({
361 contractnumber
=> $basket->{contractnumber
}
364 if ($basket->{basketgroupid
}){
365 $basketgroup = GetBasketgroup
($basket->{basketgroupid
});
367 my $borrower= GetMember
('borrowernumber' => $loggedinuser);
368 my $budgets = GetBudgetHierarchy
;
370 foreach my $r (@
{$budgets}) {
371 if (!defined $r->{budget_amount
} || $r->{budget_amount
} == 0) {
374 next unless (CanUserUseBudget
($loggedinuser, $r, $userflags));
381 basketno
=> $basketno,
383 basketname
=> $basket->{'basketname'},
384 basketbranchcode
=> $basket->{branch
},
385 basketnote
=> $basket->{note
},
386 basketbooksellernote
=> $basket->{booksellernote
},
387 basketcontractno
=> $basket->{contractnumber
},
388 basketcontractname
=> $contract->{contractname
},
389 branches_loop
=> \
@branches_loop,
390 creationdate
=> $basket->{creationdate
},
391 authorisedby
=> $basket->{authorisedby
},
392 authorisedbyname
=> $basket->{authorisedbyname
},
393 users_ids
=> join(':', @basketusers_ids),
394 users
=> \
@basketusers,
395 closedate
=> $basket->{closedate
},
396 estimateddeliverydate
=> $estimateddeliverydate,
397 is_standing
=> $basket->{is_standing
},
398 deliveryplace
=> $basket->{deliveryplace
},
399 billingplace
=> $basket->{billingplace
},
400 active
=> $bookseller->active,
401 booksellerid
=> $bookseller->id,
402 name
=> $bookseller->name,
403 books_loop
=> \
@books_loop,
404 book_foot_loop
=> \
@book_foot_loop,
405 cancelledorders_loop
=> \
@cancelledorders_loop,
406 total_quantity
=> $total_quantity,
407 total_tax_excluded
=> $total_tax_excluded,
408 total_tax_included
=> $total_tax_included,
409 total_tax_value
=> $total_tax_value,
410 currency
=> $active_currency->currency,
411 listincgst
=> $bookseller->listincgst,
412 basketgroups
=> $basketgroups,
413 basketgroup
=> $basketgroup,
414 grouped
=> $basket->{basketgroupid
},
415 # The double negatives and booleans here mean:
416 # "A basket cannot be closed if there are no orders in it or it's a standing order basket."
418 # (The template has another implicit restriction that the order cannot be closed if there
419 # are any orders with uncertain prices.)
420 unclosable
=> @orders ?
$basket->{is_standing
} : 1,
421 has_budgets
=> $has_budgets,
422 duplinbatch
=> $duplinbatch,
426 $template->param( messages
=> \
@messages );
427 output_html_with_http_headers
$query, $cookie, $template->output;
429 sub get_order_infos
{
431 my $bookseller = shift;
432 my $qty = $order->{'quantity'} || 0;
433 if ( !defined $order->{quantityreceived
} ) {
434 $order->{quantityreceived
} = 0;
436 my $budget = GetBudget
($order->{budget_id
});
437 my $basket = GetBasket
($order->{basketno
});
439 my %line = %{ $order };
440 # Don't show unreceived standing orders as received
441 $line{order_received
} = ( $qty == $order->{'quantityreceived'} && ( $basket->{is_standing
} ?
$qty : 1 ) );
442 $line{basketno
} = $basketno;
443 $line{budget_name
} = $budget->{budget_name
};
445 $line{total_tax_included
} = $line{ecost_tax_included
} * $line{quantity
};
446 $line{total_tax_excluded
} = $line{ecost_tax_excluded
} * $line{quantity
};
447 $line{tax_value
} = $line{tax_value_on_ordering
};
448 $line{tax_rate
} = $line{tax_rate_on_ordering
};
450 if ( $line{uncertainprice
} ) {
451 $line{rrp_tax_excluded
} .= ' (Uncertain)';
453 if ( $line{'title'} ) {
454 my $volume = $order->{'volume'};
455 my $seriestitle = $order->{'seriestitle'};
456 $line{'title'} .= " / $seriestitle" if $seriestitle;
457 $line{'title'} .= " / $volume" if $volume;
460 my $biblionumber = $order->{'biblionumber'};
461 my $biblio = Koha
::Biblios
->find( $biblionumber );
462 my $countbiblio = CountBiblioInOrders
($biblionumber);
463 my $ordernumber = $order->{'ordernumber'};
464 my @subscriptions = GetSubscriptionsId
($biblionumber);
465 my $itemcount = GetItemsCount
($biblionumber);
466 my $holds_count = $biblio->holds->count;
467 my @items = GetItemnumbersFromOrder
( $ordernumber );
469 foreach my $item (@items){
470 my $nb = GetItemHolds
($biblionumber, $item);
475 # 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
476 $line{can_del_bib
} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds_count);
477 $line{items
} = ($itemcount) - (scalar @items);
478 $line{left_item
} = 1 if $line{items
} >= 1;
479 $line{left_biblio
} = 1 if $countbiblio > 1;
480 $line{biblios
} = $countbiblio - 1;
481 $line{left_subscription
} = 1 if scalar @subscriptions >= 1;
482 $line{subscriptions
} = scalar @subscriptions;
483 ($holds_count >= 1) ?
$line{left_holds
} = 1 : $line{left_holds
} = 0;
484 $line{left_holds_on_order
} = 1 if $line{left_holds
}==1 && ($line{items
} == 0 || $itemholds );
485 $line{holds
} = $holds_count;
486 $line{holds_on_order
} = $itemholds?
$itemholds:$holds_count if $line{left_holds_on_order
};
489 my $suggestion = GetSuggestionInfoFromBiblionumber
($line{biblionumber
});
490 $line{suggestionid
} = $$suggestion{suggestionid
};
491 $line{surnamesuggestedby
} = $$suggestion{surnamesuggestedby
};
492 $line{firstnamesuggestedby
} = $$suggestion{firstnamesuggestedby
};
494 foreach my $key (qw(transferred_from transferred_to)) {
496 my $order = GetOrder
($line{$key});
497 my $bookseller = Koha
::Acquisition
::Booksellers
->find( $basket->{booksellerid
} );
501 bookseller
=> $bookseller,
502 timestamp
=> $line{$key . '_timestamp'},
510 sub edi_close_and_order
{
511 my $confirm = $query->param('confirm') || $confirm_pref eq '2';
514 basketno
=> $basketno,
517 if ( $basket->{branch
} ) {
518 $edi_params->{branchcode
} = $basket->{branch
};
520 if ( create_edi_order
($edi_params) ) {
521 #$template->param( edifile => 1 );
523 CloseBasket
($basketno);
525 # if requested, create basket group, close it and attach the basket
526 if ( $query->param('createbasketgroup') ) {
528 if ( C4
::Context
->userenv
529 and C4
::Context
->userenv->{'branch'}
530 and C4
::Context
->userenv->{'branch'} ne "NO_LIBRARY_SET" )
532 $branchcode = C4
::Context
->userenv->{'branch'};
534 my $basketgroupid = NewBasketgroup
(
536 name
=> $basket->{basketname
},
537 booksellerid
=> $booksellerid,
538 deliveryplace
=> $branchcode,
539 billingplace
=> $branchcode,
545 basketno
=> $basketno,
546 basketgroupid
=> $basketgroupid
549 print $query->redirect(
550 "/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=$booksellerid&closed=1"
554 print $query->redirect(
555 "/cgi-bin/koha/acqui/booksellers.pl?booksellerid=$booksellerid"
563 booksellerid
=> $booksellerid,
564 basketno
=> $basket->{basketno
},
565 basketname
=> $basket->{basketname
},
566 basketgroupname
=> $basket->{basketname
},
569 $template->param( ean
=> $ean );