DBRev 24.06.00.000: Start of a new release cycle
[koha.git] / acqui / basket.pl
1 #!/usr/bin/perl
2
3 #script to show display basket of orders
4
5 # Copyright 2000 - 2004 Katipo
6 # Copyright 2008 - 2009 BibLibre SARL
7 #
8 # This file is part of Koha.
9 #
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.
14 #
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.
19 #
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>.
22
23 use Modern::Perl;
24 use C4::Auth qw( get_template_and_user haspermission );
25 use C4::Output qw( output_html_with_http_headers output_and_exit );
26 use CGI qw ( -utf8 );
27 use C4::Acquisition qw( GetBasket CanUserManageBasket GetBasketAsCSV NewBasket NewBasketgroup ModBasket ReopenBasket ModBasketUsers GetBasketgroup GetBasketgroups GetBasketUsers GetOrders GetOrder get_rounded_price );
28 use C4::Budgets qw( GetBudgetHierarchy GetBudget CanUserUseBudget );
29 use C4::Contract qw( GetContract );
30 use C4::Suggestions qw( GetSuggestion GetSuggestionInfoFromBiblionumber GetSuggestionInfo );
31 use Koha::Biblios;
32 use Koha::Acquisition::Baskets;
33 use Koha::Acquisition::Booksellers;
34 use Koha::Acquisition::Orders;
35 use Koha::Libraries;
36 use C4::Letters qw( SendAlerts );
37 use Date::Calc qw( Add_Delta_Days );
38 use Koha::Database;
39 use Koha::EDI qw( create_edi_order );
40 use Koha::CsvProfiles;
41 use Koha::Patrons;
42
43 use Koha::AdditionalFields;
44 use Koha::Old::Biblios;
45
46 =head1 NAME
47
48 basket.pl
49
50 =head1 DESCRIPTION
51
52  This script display all informations about basket for the supplier given
53  on input arg.  Moreover, it allows us to add a new order for this supplier from
54  an existing record, a suggestion or a new record.
55
56 =head1 CGI PARAMETERS
57
58 =over 4
59
60 =item $basketno
61
62 The basket number.
63
64 =item booksellerid
65
66 the supplier this script have to display the basket.
67
68 =item order
69
70 =back
71
72 =cut
73
74 our $query        = CGI->new;
75 our $basketno     = $query->param('basketno');
76 our $ean          = $query->param('ean');
77 our $booksellerid = $query->param('booksellerid');
78 my $duplinbatch =  $query->param('duplinbatch');
79
80 our ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user(
81     {
82         template_name   => "acqui/basket.tt",
83         query           => $query,
84         type            => "intranet",
85         flagsrequired   => { acquisition => 'order_manage' },
86     }
87 );
88
89 my $logged_in_patron = Koha::Patrons->find( $loggedinuser );
90
91 our $basket = GetBasket($basketno);
92 $booksellerid = $basket->{booksellerid} unless $booksellerid;
93 my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
94 my $schema = Koha::Database->new()->schema();
95 my $rs = $schema->resultset('VendorEdiAccount')->search(
96     { vendor_id => $booksellerid, } );
97 $template->param( ediaccount => ($rs->count > 0));
98
99 unless (CanUserManageBasket($loggedinuser, $basket, $userflags)) {
100     $template->param(
101         cannot_manage_basket => 1,
102         basketno => $basketno,
103         basketname => $basket->{basketname},
104         booksellerid => $booksellerid,
105         booksellername => $bookseller->name,
106     );
107     output_html_with_http_headers $query, $cookie, $template->output;
108     exit;
109 }
110
111 # FIXME : what about the "discount" percentage?
112 # FIXME : the query->param('booksellerid') below is probably useless. The bookseller is always known from the basket
113 # if no booksellerid in parameter, get it from basket
114 # warn "=>".$basket->{booksellerid};
115 my $op = $query->param('op') // 'list';
116
117 our $confirm_pref= C4::Context->preference("BasketConfirmations") || '1';
118 $template->param( skip_confirm_reopen => 1) if $confirm_pref eq '2';
119
120 my @messages;
121
122 if ( $op eq 'cud-delete-order' ) {
123     output_and_exit( $query, $cookie, $template, 'insufficient_permission' )
124         unless $logged_in_patron->has_permission( { acquisition => 'order_manage' } );
125
126     # We only allow deleting cancelled line without biblionumber for now
127     my $ordernumber = $query->param('ordernumber');
128     my $order       = Koha::Acquisition::Orders->search(
129         {
130             biblionumber => undef,
131             ordernumber  => $ordernumber, orderstatus => 'cancelled'
132         }
133     );
134     $order->delete if $order;
135     $op = 'list';
136
137 } elsif ( $op eq 'cud-delete_confirm' ) {
138
139     output_and_exit( $query, $cookie, $template, 'insufficient_permission' )
140       unless $logged_in_patron->has_permission( { acquisition => 'delete_baskets' } );
141
142     my $basketno   = $query->param('basketno');
143     my $delbiblio  = $query->param('delbiblio');
144     my $basket_obj = Koha::Acquisition::Baskets->find($basketno);
145
146     my $orders = $basket_obj->orders->filter_by_current;
147
148     my @cannotdelbiblios;
149
150     while ( my $order = $orders->next ) {
151         # cancel the order
152         $order->cancel({ delete_biblio => $delbiblio });
153         my @messages = @{ $order->object_messages };
154
155         if ( scalar @messages > 0 ) {
156
157             my $biblio = $order->biblio;
158
159             push @cannotdelbiblios, {
160                 biblionumber  => $biblio->id,
161                 title         => $biblio->title // '',
162                 author        => $biblio->author // '',
163                 countbiblio   => $biblio->active_orders->count,
164                 itemcount     => $biblio->items->count,
165                 subscriptions => $biblio->subscriptions->count,
166             };
167         }
168     }
169
170     $template->param( cannotdelbiblios => \@cannotdelbiblios );
171
172     # delete the basket
173     $basket_obj->delete;
174     $template->param(
175         delete_confirmed => 1,
176         booksellername => $bookseller->name,
177         booksellerid => $booksellerid,
178     );
179 } elsif ( !$bookseller ) {
180     $template->param( NO_BOOKSELLER => 1 );
181 } elsif ($op eq 'export') {
182     print $query->header(
183         -type       => 'text/csv',
184         -attachment => 'basket' . $basket->{'basketno'} . '.csv',
185     );
186     my $csv_profile_id = $query->param('csv_profile');
187     print GetBasketAsCSV( scalar $query->param('basketno'), $query, $csv_profile_id ); # if no csv_profile_id passed, using default rows
188     exit;
189 } elsif ($op eq 'cud-email') {
190     my $err = eval {
191         SendAlerts( 'orderacquisition', scalar $query->param('basketno'), 'ACQORDER' );
192     };
193     if ( $@ ) {
194         push @messages, { type => 'error', code => $@ };
195     } elsif ( ref $err and exists $err->{error} ) {
196         push @messages, { type => 'error', code => $err->{error} };
197     } else {
198         push @messages, { type => 'message', code => 'email_sent' };
199     }
200
201     $op = 'list';
202 } elsif ($op eq 'cud-close') {
203     my $confirm = $query->param('confirm') || $confirm_pref eq '2';
204     if ($confirm) {
205
206         # close the basket
207         # FIXME: we should fetch the object at the beginning of this script
208         #        and get rid of the hash that is passed around
209         Koha::Acquisition::Baskets->find($basketno)->close;
210
211         # if requested, create basket group, close it and attach the basket
212         if ($query->param('createbasketgroup')) {
213             my $branchcode;
214             if(C4::Context->userenv and C4::Context->userenv->{'branch'}) {
215                 $branchcode = C4::Context->userenv->{'branch'};
216             }
217             my $basketgroupid = NewBasketgroup( { name => $basket->{basketname},
218                             booksellerid => $booksellerid,
219                             deliveryplace => $branchcode,
220                             billingplace => $branchcode,
221                             closed => 1,
222                             });
223             ModBasket( { basketno => $basketno,
224                          basketgroupid => $basketgroupid } );
225             print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1');
226         } else {
227             print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid);
228         }
229         exit;
230     } else {
231     $template->param(
232         confirm_close   => "1",
233         booksellerid    => $booksellerid,
234         booksellername  => $bookseller->name,
235         basketno        => $basket->{'basketno'},
236         basketname      => $basket->{'basketname'},
237         basketgroupname => $basket->{'basketname'},
238     );
239     }
240 } elsif ($op eq 'cud-reopen') {
241     ReopenBasket(scalar $query->param('basketno'));
242     print $query->redirect('/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'})
243 }
244 elsif ( $op eq 'cud-ediorder' ) {
245     edi_close_and_order()
246 } elsif ( $op eq 'cud-mod_users' ) {
247     my $basketusers_ids = $query->param('users_ids');
248     my @basketusers = split( /:/, $basketusers_ids );
249     ModBasketUsers($basketno, @basketusers);
250     print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
251     exit;
252 } elsif ( $op eq 'cud-mod_branch' ) {
253     my $branch = $query->param('branch');
254     $branch = undef if(defined $branch and $branch eq '');
255     ModBasket({
256         basketno => $basket->{basketno},
257         branch   => $branch
258     });
259     print $query->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");
260     exit;
261 }
262
263 if ( $op eq 'list' ) {
264     my @branches_loop;
265     # get librarian branch...
266     if ( C4::Context->preference("IndependentBranches") ) {
267         my $userenv = C4::Context->userenv;
268         unless ( C4::Context->IsSuperLibrarian() ) {
269             my $validtest = ( $basket->{creationdate} eq '' )
270               || ( $userenv->{branch} eq $basket->{branch} )
271               || ( $userenv->{branch} eq '' )
272               || ( $basket->{branch}  eq '' );
273             unless ($validtest) {
274                 print $query->redirect("../mainpage.pl");
275                 exit 0;
276             }
277         }
278
279         if (!defined $basket->{branch} or $basket->{branch} eq $userenv->{branch}) {
280             push @branches_loop, {
281                 branchcode => $userenv->{branch},
282                 branchname => $userenv->{branchname},
283                 selected => 1,
284             };
285         }
286     } else {
287         # get branches
288         my $branches = Koha::Libraries->search( {}, { order_by => ['branchname'] } )->unblessed;
289         foreach my $branch (@$branches) {
290             my $selected = 0;
291             if (defined $basket->{branch}) {
292                 $selected = 1 if $branch->{branchcode} eq $basket->{branch};
293             } else {
294                 $selected = 1 if $branch->{branchcode} eq C4::Context->userenv->{branch};
295             }
296             push @branches_loop, {
297                 branchcode => $branch->{branchcode},
298                 branchname => $branch->{branchname},
299                 selected => $selected
300             };
301         }
302     }
303
304 #if the basket is closed,and the user has the permission to edit basketgroups, display a list of basketgroups
305     my ($basketgroup, $basketgroups);
306     my $patron = Koha::Patrons->find($loggedinuser);
307     if ($basket->{closedate} && haspermission($patron->userid, { acquisition => 'group_manage'} )) {
308         $basketgroups = GetBasketgroups($basket->{booksellerid});
309         for my $bg ( @{$basketgroups} ) {
310             if ($basket->{basketgroupid} && $basket->{basketgroupid} == $bg->{id}){
311                 $bg->{default} = 1;
312                 $basketgroup = $bg;
313             }
314         }
315     }
316
317     # if the basket is closed, calculate estimated delivery date
318     my $estimateddeliverydate;
319     if( $basket->{closedate} ) {
320         my ($year, $month, $day) = ($basket->{closedate} =~ /(\d+)-(\d+)-(\d+)/);
321         ($year, $month, $day) = Add_Delta_Days($year, $month, $day, $bookseller->deliverytime);
322         $estimateddeliverydate = sprintf( "%04d-%02d-%02d", $year, $month, $day );
323     }
324
325     # if new basket, pre-fill infos
326     $basket->{creationdate} = ""            unless ( $basket->{creationdate} );
327     $basket->{authorisedby} = $loggedinuser unless ( $basket->{authorisedby} );
328
329     my @basketusers_ids = GetBasketUsers($basketno);
330     my @basketusers;
331     foreach my $basketuser_id (@basketusers_ids) {
332         # FIXME Could be improved with a search -in
333         my $basket_patron = Koha::Patrons->find( $basketuser_id );
334         push @basketusers, $basket_patron if $basket_patron;
335     }
336
337     my $active_currency = Koha::Acquisition::Currencies->get_active;
338
339     my @orders = GetOrders( $basketno );
340     my @books_loop;
341
342     my @book_foot_loop;
343     my %foot;
344     my $total_quantity = 0;
345     my $total_tax_excluded = 0;
346     my $total_tax_included = 0;
347     my $total_tax_value = 0;
348     for my $order (@orders) {
349         my $line = get_order_infos( $order, $bookseller);
350         if ( $line->{uncertainprice} ) {
351             $template->param( uncertainprices => 1 );
352         }
353
354         $line->{tax_rate} = $line->{tax_rate_on_ordering} // 0;
355         $line->{tax_value} = $line->{tax_value_on_ordering} // 0;
356
357         push @books_loop, $line;
358
359         $foot{$$line{tax_rate}}{tax_rate} = $$line{tax_rate};
360         $foot{$$line{tax_rate}}{tax_value} += get_rounded_price($$line{tax_value});
361         $total_tax_value += $$line{tax_value};
362         $foot{$$line{tax_rate}}{quantity}  += get_rounded_price($$line{quantity});
363         $total_quantity += $$line{quantity};
364         $foot{$$line{tax_rate}}{total_tax_excluded} += $$line{total_tax_excluded};
365         $total_tax_excluded += $$line{total_tax_excluded};
366         $foot{$$line{tax_rate}}{total_tax_included} += $$line{total_tax_included};
367         $total_tax_included += $$line{total_tax_included};
368     }
369
370     push @book_foot_loop, map {$_} values %foot;
371
372     # Get cancelled orders
373     my @cancelledorders = GetOrders($basketno, { cancelled => 1 });
374     my @cancelledorders_loop;
375     for my $order (@cancelledorders) {
376         my $line = get_order_infos( $order, $bookseller);
377         push @cancelledorders_loop, $line;
378     }
379
380     my $contract = GetContract({
381         contractnumber => $basket->{contractnumber}
382     });
383
384     if ($basket->{basketgroupid}){
385         $basketgroup = GetBasketgroup($basket->{basketgroupid});
386     }
387     my $budgets = GetBudgetHierarchy;
388     my $has_budgets = 0;
389     foreach my $r (@{$budgets}) {
390         next unless (CanUserUseBudget($loggedinuser, $r, $userflags));
391
392         $has_budgets = 1;
393         last;
394     }
395
396     my $basket_obj = Koha::Acquisition::Baskets->find($basketno);
397     my $edi_order = $basket_obj->edi_order;
398
399     $template->param(
400         basketno             => $basketno,
401         basket               => $basket,
402         basketname           => $basket->{'basketname'},
403         basketbranchcode     => $basket->{branch},
404         basketnote           => $basket->{note},
405         basketbooksellernote => $basket->{booksellernote},
406         basketcontractno     => $basket->{contractnumber},
407         basketcontractname   => $contract->{contractname},
408         branches_loop        => \@branches_loop,
409         creationdate         => $basket->{creationdate},
410         edi_order            => $edi_order,
411         authorisedby         => $basket->{authorisedby},
412         authorisedbyname     => $basket->{authorisedbyname},
413         users_ids            => join(':', @basketusers_ids),
414         users                => \@basketusers,
415         closedate            => $basket->{closedate},
416         estimateddeliverydate=> $estimateddeliverydate,
417         is_standing          => $basket->{is_standing},
418         deliveryplace        => $basket->{deliveryplace},
419         billingplace         => $basket->{billingplace},
420         active               => $bookseller->active,
421         booksellerid         => $bookseller->id,
422         booksellername       => $bookseller->name,
423         books_loop           => \@books_loop,
424         book_foot_loop       => \@book_foot_loop,
425         cancelledorders_loop => \@cancelledorders_loop,
426         total_quantity       => $total_quantity,
427         total_tax_excluded   => $total_tax_excluded,
428         total_tax_included   => $total_tax_included,
429         total_tax_value      => $total_tax_value,
430         currency             => $active_currency->currency,
431         listincgst           => $bookseller->listincgst,
432         basketgroups         => $basketgroups,
433         basketgroup          => $basketgroup,
434         grouped              => $basket->{basketgroupid},
435         # The double negatives and booleans here mean:
436         # "A basket cannot be closed if there are no orders in it or it's a standing order basket."
437         #
438         # (The template has another implicit restriction that the order cannot be closed if there
439         # are any orders with uncertain prices.)
440         unclosable           => @orders || @cancelledorders ? $basket->{is_standing} : 1,
441         has_budgets          => $has_budgets,
442         duplinbatch          => $duplinbatch,
443         csv_profiles         => Koha::CsvProfiles->search({ type => 'sql', used_for => 'export_basket' }),
444         available_additional_fields => Koha::AdditionalFields->search( { tablename => 'aqbasket' } ),
445         additional_field_values => { map {
446             $_->field->name => $_->value
447         } Koha::Acquisition::Baskets->find($basketno)->additional_field_values->as_list },
448     );
449 }
450
451 $template->param( messages => \@messages );
452 output_html_with_http_headers $query, $cookie, $template->output;
453
454 sub get_order_infos {
455     my $order = shift;
456     my $bookseller = shift;
457     my $qty = $order->{'quantity'} || 0;
458     if ( !defined $order->{quantityreceived} ) {
459         $order->{quantityreceived} = 0;
460     }
461     my $budget = GetBudget($order->{budget_id});
462     my $basket = GetBasket($order->{basketno});
463
464     my %line = %{ $order };
465     # Don't show unreceived standing orders as received
466     $line{order_received} = ( $qty == $order->{'quantityreceived'} && ( $basket->{is_standing} ? $qty : 1 ) );
467     $line{basketno}       = $basketno;
468     $line{budget_name}    = $budget->{budget_name};
469     $line{sort1_authcat}  = $budget->{sort1_authcat};
470     $line{sort2_authcat}  = $budget->{sort2_authcat};
471
472     # If we have an actual cost that should be the total, otherwise use the ecost
473     $line{unitprice_tax_included} += 0;
474     $line{unitprice_tax_excluded} += 0;
475     my $cost_tax_included = $line{unitprice_tax_included} || $line{ecost_tax_included};
476     my $cost_tax_excluded = $line{unitprice_tax_excluded} || $line{ecost_tax_excluded};
477     $line{total_tax_included} = get_rounded_price($cost_tax_included) * $line{quantity};
478     $line{total_tax_excluded} = get_rounded_price($cost_tax_excluded) * $line{quantity};
479     $line{tax_value} = $line{tax_value_on_ordering};
480     $line{tax_rate} = $line{tax_rate_on_ordering};
481
482     if ( $line{'title'} ) {
483         my $volume      = $order->{'volume'};
484         my $seriestitle = $order->{'seriestitle'};
485         $line{'title'} .= " / $seriestitle" if $seriestitle;
486         $line{'title'} .= " / $volume"      if $volume;
487     }
488
489     my $biblionumber = $order->{'biblionumber'};
490     if ( $biblionumber ) { # The biblio still exists
491         my $biblio = Koha::Biblios->find( $biblionumber );
492         my $countbiblio = $biblio->active_orders->count;
493
494         my $ordernumber       = $order->{'ordernumber'};
495         my $cnt_subscriptions = $biblio->subscriptions->count;
496         my $itemcount         = $biblio->items->count;
497         my $holds_count       = $biblio->holds->count;
498         my $order             = Koha::Acquisition::Orders->find($ordernumber);    # FIXME We should certainly do that at the beginning of this sub
499         my $items   = $order->items;
500         my $invoice = $order->invoice;
501
502         my $itemholds  = $biblio->holds->search({ itemnumber => { -in => [ $items->get_column('itemnumber') ] } })->count;
503
504         # 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
505         $line{can_del_bib} = 1
506             if $countbiblio <= 1 && $itemcount == $items->count && !($cnt_subscriptions) && !($holds_count);
507         $line{items}             = $itemcount - $items->count;
508         $line{left_item}         = 1 if $line{items} >= 1;
509         $line{left_biblio}       = 1 if $countbiblio > 1;
510         $line{biblios}           = $countbiblio - 1;
511         $line{left_subscription} = 1 if $cnt_subscriptions;
512         $line{subscriptions}     = $cnt_subscriptions;
513         ( $holds_count >= 1 ) ? $line{left_holds} = 1 : $line{left_holds} = 0;
514         $line{left_holds_on_order} = 1 if $line{left_holds} == 1 && ( $line{items} == 0 || $itemholds );
515         $line{holds}               = $holds_count;
516         $line{holds_on_order}      = $itemholds ? $itemholds : $holds_count if $line{left_holds_on_order};
517         $line{order_object}        = $order;
518         $line{invoice_object}      = $invoice;
519     } else {
520         $line{deleted_biblio} = Koha::Old::Biblios->find( $order->{deleted_biblionumber} );
521     }
522
523     my $suggestion   = GetSuggestionInfoFromBiblionumber($line{biblionumber});
524     $line{suggestionid}         = $$suggestion{suggestionid};
525     $line{surnamesuggestedby}   = $$suggestion{surnamesuggestedby};
526     $line{firstnamesuggestedby} = $$suggestion{firstnamesuggestedby};
527
528     $line{estimated_delivery_date} = $order->{estimated_delivery_date};
529
530     foreach my $key (qw(transferred_from transferred_to)) {
531         if ($line{$key}) {
532             my $order = GetOrder($line{$key});
533             my $basket = GetBasket($order->{basketno});
534             my $bookseller = Koha::Acquisition::Booksellers->find( $basket->{booksellerid} );
535             $line{$key} = {
536                 order => $order,
537                 basket => $basket,
538                 bookseller => $bookseller,
539                 timestamp => $line{$key . '_timestamp'},
540             };
541         }
542     }
543
544     return \%line;
545 }
546
547 sub edi_close_and_order {
548     my $confirm = $query->param('confirm') || $confirm_pref eq '2';
549     if ($confirm) {
550         my $edi_params = {
551             basketno => $basketno,
552             ean    => $ean,
553         };
554         if ( $basket->{branch} ) {
555             $edi_params->{branchcode} = $basket->{branch};
556         }
557         if ( create_edi_order($edi_params) ) {
558             #$template->param( edifile => 1 );
559         }
560         Koha::Acquisition::Baskets->find($basketno)->close;
561
562         # if requested, create basket group, close it and attach the basket
563         if ( $query->param('createbasketgroup') ) {
564             my $branchcode;
565             if (    C4::Context->userenv
566                 and C4::Context->userenv->{'branch'} )
567             {
568                 $branchcode = C4::Context->userenv->{'branch'};
569             }
570             my $basketgroupid = NewBasketgroup(
571                 {
572                     name          => $basket->{basketname},
573                     booksellerid  => $booksellerid,
574                     deliveryplace => $branchcode,
575                     billingplace  => $branchcode,
576                     closed        => 1,
577                 }
578             );
579             ModBasket(
580                 {
581                     basketno       => $basketno,
582                     basketgroupid  => $basketgroupid
583                 }
584             );
585             print $query->redirect(
586 "/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=$booksellerid&closed=1"
587             );
588         }
589         else {
590             print $query->redirect(
591                 "/cgi-bin/koha/acqui/booksellers.pl?booksellerid=$booksellerid"
592             );
593         }
594         exit;
595     }
596     else {
597         $template->param(
598             edi_confirm     => 1,
599             booksellerid    => $booksellerid,
600             basketno        => $basket->{basketno},
601             basketname      => $basket->{basketname},
602             basketgroupname => $basket->{basketname},
603         );
604         if ($ean) {
605             $template->param( ean => $ean );
606         }
607
608     }
609     return;
610 }