circulation cleaning continued: bufixing
[koha.git] / circ / circulation.pl
1 #!/usr/bin/perl
2
3 # Please use 8-character tabs for this file (indents are every 4 characters)
4
5 # written 8/5/2002 by Finlay
6 # script to execute issuing of books
7
8 # Copyright 2000-2002 Katipo Communications
9 #
10 # This file is part of Koha.
11 #
12 # Koha is free software; you can redistribute it and/or modify it under the
13 # terms of the GNU General Public License as published by the Free Software
14 # Foundation; either version 2 of the License, or (at your option) any later
15 # version.
16 #
17 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License along with
22 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23 # Suite 330, Boston, MA  02111-1307 USA
24
25 use strict;
26 use CGI;
27 use C4::Output;
28 use C4::Print;
29 use C4::Auth;
30 use C4::Date;
31 use C4::Interface::CGI::Output;
32 use C4::Branch; # GetBranches
33 use C4::Koha;   # GetPrinter
34 use Date::Calc qw(
35   Today
36   Today_and_Now
37   Add_Delta_YM
38   Add_Delta_Days
39   Date_to_Days
40 );
41
42 use C4::Circulation;
43 use C4::Members;
44 use C4::Biblio;
45 use C4::Reserves2;
46
47 #
48 # PARAMETERS READING
49 #
50 my $query = new CGI;
51
52 my ( $template, $loggedinuser, $cookie ) = get_template_and_user (
53     {
54         template_name   => 'circ/circulation.tmpl',
55         query           => $query,
56         type            => "intranet",
57         authnotrequired => 0,
58         flagsrequired   => { circulate => 1 },
59     }
60 );
61 my $branches = GetBranches();
62
63 my $printers = GetPrinters();
64 my $printer = GetPrinter($query, $printers);
65
66 my $findborrower = $query->param('findborrower');
67 $findborrower =~ s|,| |g;
68 #$findborrower =~ s|'| |g;
69 my $borrowernumber = $query->param('borrowernumber');
70
71 # new op dev the branch and the printer are now defined by the userenv
72 my $branch  = C4::Context->userenv->{'branch'};
73 my $printer = C4::Context->userenv->{'branchprinter'};
74
75 # If Autolocated is not activated, we show the Circulation Parameters to chage settings of librarian
76     if (C4::Context->preference("AutoLocation") ne 1)
77         {
78             $template->param(
79             ManualLocation => 1,
80             );
81         }
82
83 my $barcode        = $query->param('barcode') || '';
84 my $year           = $query->param('year');
85 my $month          = $query->param('month');
86 my $day            = $query->param('day');
87 my $stickyduedate  = $query->param('stickyduedate');
88 my $issueconfirmed = $query->param('issueconfirmed');
89 my $cancelreserve  = $query->param('cancelreserve');
90 my $organisation   = $query->param('organisations');
91 my $print          = $query->param('print');
92
93 #set up cookie.....
94 # my $branchcookie;
95 # my $printercookie;
96 # if ($query->param('setcookies')) {
97 #     $branchcookie = $query->cookie(-name=>'branch', -value=>"$branch", -expires=>'+1y');
98 #     $printercookie = $query->cookie(-name=>'printer', -value=>"$printer", -expires=>'+1y');
99 # }
100
101 my %env
102   ; # FIXME env is used as an "environment" variable. Could be dropped probably...
103
104 #
105 $env{'branchcode'}   = $branch;
106 $env{'printer'}      = $printer;
107 $env{'organisation'} = $organisation;
108
109 # $env{'queue'}=$printer;
110
111 my @datearr = localtime( time() );
112
113 # FIXME - Could just use POSIX::strftime("%Y%m%d", localtime);
114 my $todaysdate =
115     ( 1900 + $datearr[5] )
116   . sprintf( "%0.2d", ( $datearr[4] + 1 ) )
117   . sprintf( "%0.2d", ( $datearr[3] ) );
118
119 # check and see if we should print
120 if ( $barcode eq '' && $print eq 'maybe' ) {
121     $print = 'yes';
122 }
123
124 my $inprocess = $query->param('inprocess');
125 if ( $barcode eq '' ) {
126     $inprocess = '';
127 }
128 else {
129 }
130
131 if ( $barcode eq '' && $query->param('charges') eq 'yes' ) {
132     $template->param(
133         PAYCHARGES     => 'yes',
134         borrowernumber => $borrowernumber
135     );
136 }
137
138 if ( $print eq 'yes' && $borrowernumber ne '' ) {
139     printslip( \%env, $borrowernumber );
140     $query->param( 'borrowernumber', '' );
141     $borrowernumber = '';
142 }
143
144 #
145 # STEP 2 : FIND BORROWER
146 # if there is a list of find borrowers....
147 #
148 my $borrowerslist;
149 my $message;
150 if ($findborrower) {
151     my ( $count, $borrowers ) =
152       BornameSearch( \%env, $findborrower, 'cardnumber', 'web' );
153     my @borrowers = @$borrowers;
154     if ( $#borrowers == -1 ) {
155         $query->param( 'findborrower', '' );
156         $message = "'$findborrower'";
157     }
158     elsif ( $#borrowers == 0 ) {
159         $query->param( 'borrowernumber', $borrowers[0]->{'borrowernumber'} );
160         $query->param( 'barcode',           '' );
161         $borrowernumber = $borrowers[0]->{'borrowernumber'};
162     }
163     else {
164         $borrowerslist = \@borrowers;
165     }
166 }
167
168 # get the borrower information.....
169 my $borrower;
170 my @lines;
171
172 if ($borrowernumber) {
173     $borrower = GetMemberDetails( $borrowernumber, 0 );
174     my ( $od, $issue, $fines ) = borrdata2( \%env, $borrowernumber );
175
176     # Warningdate is the date that the warning starts appearing
177     my ( $today_year,   $today_month,   $today_day )   = Today();
178     my ( $warning_year, $warning_month, $warning_day ) = split /-/,
179       $borrower->{'dateexpiry'};
180
181     # Renew day is calculated by adding the enrolment period to today
182     my ( $renew_year, $renew_month, $renew_day ) =
183       Add_Delta_YM( $today_year, $today_month, $today_day,
184         $borrower->{'enrolmentperiod'}, 0 );
185     # if the expiry date is before today
186     if ( Date_to_Days( $today_year, $today_month, $today_day ) >
187         Date_to_Days( $warning_year, $warning_month, $warning_day ) )
188     {
189
190         #borrowercard expired or nearly expired, warn the librarian
191         $template->param(
192             flagged       => "1",
193             warndeparture => "1",
194             renewaldate   => "$renew_year-$renew_month-$renew_day"
195         );
196     }
197     # check for NotifyBorrowerDeparture
198         if (C4::Context->preference('NotifyBorrowerDeparture') &&
199             Date_to_Days(Add_Delta_Days($warning_year,$warning_month,$warning_day,- C4::Context->preference('NotifyBorrowerDeparture'))) <
200             Date_to_Days( $today_year, $today_month, $today_day ) ) 
201         {
202             $template->param("warndeparture" => 1);
203         }
204     $template->param(
205         overduecount => $od,
206         issuecount   => $issue,
207         finetotal    => $fines
208     );
209 }
210
211 #
212 # STEP 3 : ISSUING
213 #
214 #
215
216 if ($barcode) {
217     $barcode = cuecatbarcodedecode($barcode);
218     my ( $datedue, $invalidduedate ) = fixdate( $year, $month, $day );
219     if ($issueconfirmed) {
220         AddIssue( \%env, $borrower, $barcode, $datedue, $cancelreserve );
221         $inprocess = 1;
222     }
223     else {
224         my ( $error, $question ) =
225           CanBookBeIssued( \%env, $borrower, $barcode, $year, $month, $day,
226             $inprocess );
227         my $noerror    = 1;
228         my $noquestion = 1;
229 #         Get the item title for more information
230     my $getmessageiteminfo  = GetBiblioFromItemNumber( undef, $barcode );
231     
232         foreach my $impossible ( keys %$error ) {
233             $template->param(
234                 $impossible => $$error{$impossible},
235                 IMPOSSIBLE  => 1
236             );
237             $noerror = 0;
238         }
239         foreach my $needsconfirmation ( keys %$question ) {
240             $template->param(
241                 $needsconfirmation => $$question{$needsconfirmation},
242                 getTitleMessageIteminfo => $getmessageiteminfo->{'title'},
243                 NEEDSCONFIRMATION  => 1
244             );
245             $noquestion = 0;
246         }
247         $template->param(
248             day   => $day,
249             month => $month,
250             year  => $year
251         );
252         if ( $noerror && ( $noquestion || $issueconfirmed ) ) {
253             AddIssue( \%env, $borrower, $barcode, $datedue );
254             $inprocess = 1;
255         }
256     }
257     
258 # FIXME If the issue is confirmed, we launch another time borrdata2, now display the issue count after issue 
259         my ( $od, $issue, $fines ) = borrdata2( \%env, $borrowernumber );
260         $template->param(
261         issuecount   => $issue,
262         );
263 }
264
265 # reload the borrower info for the sake of reseting the flags.....
266 if ($borrowernumber) {
267     $borrower = GetMemberDetails( $borrowernumber, 0 );
268 }
269
270 ##################################################################################
271 # BUILD HTML
272 # show all reserves of this borrower, and the position of the reservation ....
273 if ($borrowernumber) {
274
275     # new op dev
276     # now we show the status of the borrower's reservations
277     my @borrowerreserv = GetReservations( 0, $borrowernumber );
278     my @reservloop;
279     my @WaitingReserveLoop;
280     
281     foreach my $num_res (@borrowerreserv) {
282         my %getreserv;
283         my %getWaitingReserveInfo;
284         my %env;
285         my $getiteminfo  = GetBiblioFromItemNumber( $num_res->{'itemnumber'} );
286         my $itemtypeinfo = getitemtypeinfo( $getiteminfo->{'itemtype'} );
287         my ( $transfertwhen, $transfertfrom, $transfertto ) =
288           GetTransfers( $num_res->{'itemnumber'} );
289
290         $getreserv{waiting}       = 0;
291         $getreserv{transfered}    = 0;
292         $getreserv{nottransfered} = 0;
293
294         $getreserv{reservedate}    = format_date( $num_res->{'reservedate'} );
295         $getreserv{biblionumber}   = $getiteminfo->{'biblionumber'};
296         $getreserv{title}          = $getiteminfo->{'title'};
297         $getreserv{itemtype}       = $itemtypeinfo->{'description'};
298         $getreserv{author}         = $getiteminfo->{'author'};
299         $getreserv{barcodereserv}  = $getiteminfo->{'barcode'};
300         $getreserv{itemcallnumber} = $getiteminfo->{'itemcallnumber'};
301
302         #         check if we have a waiting status for reservations
303         if ( $num_res->{'found'} eq 'W' ) {
304             $getreserv{color}   = 'reserved';
305             $getreserv{waiting} = 1;
306 #     genarate information displaying only waiting reserves
307         $getWaitingReserveInfo{title}        = $getiteminfo->{'title'};
308         $getWaitingReserveInfo{itemtype}    = $itemtypeinfo->{'description'};
309         $getWaitingReserveInfo{author}        = $getiteminfo->{'author'};
310         $getWaitingReserveInfo{reservedate}    = format_date( $num_res->{'reservedate'} );
311         if ($getiteminfo->{'holdingbranch'} ne $num_res->{'branchcode'} ) {
312         $getWaitingReserveInfo{waitingat}    = GetBranchName( $num_res->{'branchcode'} );
313         }
314     
315         }
316         #         check transfers with the itemnumber foud in th reservation loop
317         if ($transfertwhen) {
318             $getreserv{color}      = 'transfered';
319             $getreserv{transfered} = 1;
320             $getreserv{datesent}   = format_date($transfertwhen);
321             $getreserv{frombranch} = GetBranchName($transfertfrom);
322         }
323
324         if ( ( $getiteminfo->{'holdingbranch'} ne $num_res->{'branchcode'} )
325             and not $transfertwhen )
326         {
327             $getreserv{nottransfered}   = 1;
328             $getreserv{nottransferedby} =
329               GetBranchName( $getiteminfo->{'holdingbranch'} );
330         }
331
332 #         if we don't have a reserv on item, we put the biblio infos and the waiting position
333         if ( $getiteminfo->{'title'} eq '' ) {
334             my $getbibinfo = GetBiblioItemData( $num_res->{'biblionumber'} );
335             my $getbibtype = getitemtypeinfo( $getbibinfo->{'itemtype'} );
336             $getreserv{color}           = 'inwait';
337             $getreserv{title}           = $getbibinfo->{'title'};
338             $getreserv{waitingposition} = $num_res->{'priority'};
339             $getreserv{nottransfered}   = 0;
340             $getreserv{itemtype}        = $getbibtype->{'description'};
341             $getreserv{author}          = $getbibinfo->{'author'};
342             $getreserv{itemcallnumber}  = '----------';
343
344         }
345         push( @reservloop, \%getreserv );
346
347 #         if we have a reserve waiting, initiate waitingreserveloop
348         if ($getreserv{waiting} eq 1) {
349         push (@WaitingReserveLoop, \%getWaitingReserveInfo)
350         }
351       
352     }
353
354     # return result to the template
355     $template->param( 
356         countreserv => scalar @reservloop,
357         reservloop  => \@reservloop ,
358         WaitingReserveLoop  => \@WaitingReserveLoop,
359     );
360 }
361
362 # make the issued books table.
363 my $todaysissues = '';
364 my $previssues   = '';
365 my @realtodayissues;
366 my @realprevissues;
367 my $allowborrow;
368 ## ADDED BY JF: new itemtype issuingrules counter stuff
369 my $issued_itemtypes_loop;
370 my $issued_itemtypes_count;
371 my $issued_itemtypes_allowed_count;    # hashref with total allowed by itemtype
372 my $issued_itemtypes_remaining;        # hashref with remaining
373 my $issued_itemtypes_flags;            #hashref that stores flags
374
375 if ($borrower) {
376
377 # get each issue of the borrower & separate them in todayissues & previous issues
378     my @todaysissues;
379     my @previousissues;
380     my $issueslist = GetBorrowerIssues($borrower);
381
382     # split in 2 arrays for today & previous
383     my $dbh = C4::Context->dbh;
384     foreach my $it ( @$issueslist ) {
385         my $issuedate = $it->{'timestamp'};
386         $issuedate =~ s/-//g;
387         $issuedate = substr( $issuedate, 0, 8 );
388
389         # to let perl sort this correctly
390         $it->{'timestamp'} =~ s/(-|\:| )//g;
391
392         if ( $todaysdate == $issuedate ) {
393             (
394                 $it->{'charge'},
395                 $it->{'itemtype_charge'}
396               )
397               = GetIssuingCharges(
398                 $it->{'itemnumber'},
399                 $borrower->{'borrowernumber'}
400               );
401             $it->{'charge'} =
402               sprintf( "%.2f", $it->{'charge'} );
403             (
404                 $it->{'can_renew'},
405                 $it->{'can_renew_error'}
406               )
407               = CanBookBeRenewed(
408                 $borrower->{'borrowernumber'},
409                 $it->{'itemnumber'}
410               );
411             my ( $restype, $reserves ) =
412               CheckReserves( $it->{'itemnumber'} );
413             if ($restype) {
414                 $it->{'can_renew'} = 0;
415             }
416             push @todaysissues, $it;
417         }
418         else {
419             (
420                 $it->{'charge'},
421                 $it->{'itemtype_charge'}
422               )
423               = GetIssuingCharges(
424                 $it->{'itemnumber'},
425                 $borrower->{'borrowernumber'}
426               );
427             $it->{'charge'} =
428               sprintf( "%.2f", $it->{'charge'} );
429             (
430                 $it->{'can_renew'},
431                 $it->{'can_renew_error'}
432               )
433               = CanBookBeRenewed(
434                 $borrower->{'borrowernumber'},
435                 $it->{'itemnumber'}
436               );
437             my ( $restype, $reserves ) =
438               CheckReserves( $it->{'itemnumber'} );
439             if ($restype) {
440                 $it->{'can_renew'} = 0;
441             }
442             push @previousissues, $it;
443         }
444     }
445     my $od;    # overdues
446     my $i = 0;
447     my $togglecolor;
448
449     # parses today & build Template array
450     foreach my $book ( sort { $b->{'timestamp'} <=> $a->{'timestamp'} }
451         @todaysissues )
452     {
453         #warn "TIMESTAMP".$book->{'timestamp'};
454         # ADDED BY JF: NEW ITEMTYPE COUNT DISPLAY
455         $issued_itemtypes_count->{ $book->{'itemtype'} }++;
456
457         my $dd      = $book->{'date_due'};
458         my $datedue = $book->{'date_due'};
459
460         #$dd=format_date($dd);
461         $datedue =~ s/-//g;
462         if ( $datedue < $todaysdate ) {
463             $od = 1;
464         }
465         else {
466             $od = 0;
467         }
468         if ( $i % 2 ) {
469             $togglecolor = 0;
470         }
471         else {
472             $togglecolor = 1;
473         }
474         $book->{'togglecolor'} = $togglecolor;
475         $book->{'od'}          = format_date($od);
476         $book->{'dd'}          = format_date($dd);
477         if ( $book->{'author'} eq '' ) {
478             $book->{'author'} = ' ';
479         }
480         push @realtodayissues, $book;
481         $i++;
482     }
483
484     # parses previous & build Template array
485     $i = 0;
486     foreach my $book ( sort { $a->{'date_due'} cmp $b->{'date_due'} }
487         @previousissues )
488     {
489
490         # ADDED BY JF: NEW ITEMTYPE COUNT DISPLAY
491         $issued_itemtypes_count->{ $book->{'itemtype'} }++;
492
493         my $dd      = format_date($book->{'date_due'});
494         my $datedue = format_date($book->{'date_due'});
495
496         #$dd=format_date($dd);
497         my $pcolor = '';
498         my $od     = '';
499         $datedue =~ s/-//g;
500         if ( $datedue < $todaysdate ) {
501             $od = 1;
502         }
503         else {
504             $od = 0;
505         }
506         if ( $i % 2 ) {
507             $togglecolor = 0;
508         }
509         else {
510             $togglecolor = 1;
511         }
512         $book->{'togglecolor'} = $togglecolor;
513         $book->{'dd'}          = $dd;
514         $book->{'od'}          = $od;
515         if ( $book->{'author'} eq '' ) {
516             $book->{'author'} = ' ';
517         }
518         push @realprevissues, $book;
519         $i++;
520     }
521 }
522
523 #### ADDED BY JF FOR COUNTS BY ITEMTYPE RULES
524 # FIXME: This should utilize all the issuingrules options rather than just the defaults
525 # and it should be moved to a module
526 my $dbh = C4::Context->dbh;
527
528 # how many of each is allowed?
529 my $issueqty_sth = $dbh->prepare( "
530 SELECT itemtypes.description AS description,issuingrules.itemtype,maxissueqty
531 FROM issuingrules
532   LEFT JOIN itemtypes ON (itemtypes.itemtype=issuingrules.itemtype)
533   WHERE categorycode=?
534 " );
535 my @issued_itemtypes_count;
536 $issueqty_sth->execute("*");
537 while ( my $data = $issueqty_sth->fetchrow_hashref() ) {
538
539     # subtract how many of each this borrower has
540     $data->{'count'} = $issued_itemtypes_count->{ $data->{'description'} };
541     $data->{'left'}  =
542       ( $data->{'maxissueqty'} -
543           $issued_itemtypes_count->{ $data->{'description'} } );
544
545     # can't have a negative number of remaining
546     if ( $data->{'left'} < 0 ) { $data->{'left'} = "0" }
547     $data->{'flag'} = 1 unless ( $data->{'maxissueqty'} > $data->{'count'} );
548     unless ( ( $data->{'maxissueqty'} < 1 )
549         || ( $data->{'itemtype'} eq "*" )
550         || ( $data->{'itemtype'} eq "CIRC" ) )
551     {
552         push @issued_itemtypes_count, $data;
553     }
554 }
555 $issued_itemtypes_loop = \@issued_itemtypes_count;
556
557 #### / JF
558
559 my @values;
560 my %labels;
561 my $CGIselectborrower;
562 if ($borrowerslist) {
563     foreach (
564         sort {
565                 $a->{'surname'}
566               . $a->{'firstname'} cmp $b->{'surname'}
567               . $b->{'firstname'}
568         } @$borrowerslist
569       )
570     {
571         push @values, $_->{'borrowernumber'};
572         $labels{ $_->{'borrowernumber'} } =
573 "$_->{'surname'}, $_->{'firstname'} ... ($_->{'cardnumber'} - $_->{'categorycode'}) ...  $_->{'address'} ";
574     }
575     $CGIselectborrower = CGI::scrolling_list(
576         -name     => 'borrowernumber',
577         -values   => \@values,
578         -labels   => \%labels,
579         -size     => 7,
580         -tabindex => '',
581         -multiple => 0
582     );
583 }
584
585 #title
586 my $flags = $borrower->{'flags'};
587 my $flag;
588
589 foreach $flag ( sort keys %$flags ) {
590
591     $flags->{$flag}->{'message'} =~ s/\n/<br>/g;
592     if ( $flags->{$flag}->{'noissues'} ) {
593         $template->param(
594             flagged  => 1,
595             noissues => 'true',
596         );
597         if ( $flag eq 'GNA' ) {
598             $template->param( gna => 'true' );
599         }
600         if ( $flag eq 'LOST' ) {
601             $template->param( lost => 'true' );
602         }
603         if ( $flag eq 'DBARRED' ) {
604             $template->param( dbarred => 'true' );
605         }
606         if ( $flag eq 'CHARGES' ) {
607             $template->param(
608                 charges    => 'true',
609                 chargesmsg => $flags->{'CHARGES'}->{'message'}
610             );
611         }
612         if ( $flag eq 'CREDITS' ) {
613             $template->param(
614                 credits    => 'true',
615                 creditsmsg => $flags->{'CREDITS'}->{'message'}
616             );
617         }
618     }
619     else {
620         if ( $flag eq 'CHARGES' ) {
621             $template->param(
622                 charges    => 'true',
623                 flagged    => 1,
624                 chargesmsg => $flags->{'CHARGES'}->{'message'}
625             );
626         }
627         if ( $flag eq 'CREDITS' ) {
628             $template->param(
629                 credits    => 'true',
630                 creditsmsg => $flags->{'CREDITS'}->{'message'}
631             );
632         }
633         if ( $flag eq 'ODUES' ) {
634             $template->param(
635                 odues    => 'true',
636                 flagged  => 1,
637                 oduesmsg => $flags->{'ODUES'}->{'message'}
638             );
639
640             my $items = $flags->{$flag}->{'itemlist'};
641 # useless ???
642 #             {
643 #                 my @itemswaiting;
644 #                 foreach my $item (@$items) {
645 #                     my ($iteminformation) =
646 #                         getiteminformation( $item->{'itemnumber'}, 0 );
647 #                     push @itemswaiting, $iteminformation;
648 #                 }
649 #             }
650             if ( $query->param('module') ne 'returns' ) {
651                 $template->param( nonreturns => 'true' );
652             }
653         }
654         if ( $flag eq 'NOTES' ) {
655             $template->param(
656                 notes    => 'true',
657                 flagged  => 1,
658                 notesmsg => $flags->{'NOTES'}->{'message'}
659             );
660         }
661     }
662 }
663
664 my $amountold = $borrower->{flags}->{'CHARGES'}->{'message'} || 0;
665 my @temp = split( /\$/, $amountold );
666
667 my $CGIorganisations;
668 my $member_of_institution;
669 if ( C4::Context->preference("memberofinstitution") ) {
670     my $organisations = get_institutions();
671     my @orgs;
672     my %org_labels;
673     foreach my $organisation ( keys %$organisations ) {
674         push @orgs, $organisation;
675         $org_labels{$organisation} =
676           $organisations->{$organisation}->{'surname'};
677     }
678     $member_of_institution = 1;
679     $CGIorganisations      = CGI::popup_menu(
680         -id     => 'organisations',
681         -name   => 'organisations',
682         -labels => \%org_labels,
683         -values => \@orgs,
684     );
685 }
686
687 $amountold = $temp[1];
688
689 $template->param(
690     issued_itemtypes_count_loop => $issued_itemtypes_loop,
691     findborrower                => $findborrower,
692     borrower                    => $borrower,
693     borrowernumber              => $borrowernumber,
694     branch                      => $branch,
695     printer                     => $printer,
696     printername                 => $printer,
697     firstname                   => $borrower->{'firstname'},
698     surname                     => $borrower->{'surname'},
699     expiry                      =>
700       $borrower->{'dateexpiry'},    #format_date($borrower->{'dateexpiry'}),
701     categorycode      => $borrower->{'categorycode'},
702     streetaddress     => $borrower->{'address'},
703     emailaddress      => $borrower->{'emailaddress'},
704     borrowernotes     => $borrower->{'borrowernotes'},
705     city              => $borrower->{'city'},
706     phone             => $borrower->{'phone'},
707     cardnumber        => $borrower->{'cardnumber'},
708     amountold         => $amountold,
709     barcode           => $barcode,
710     stickyduedate     => $stickyduedate,
711     message           => $message,
712     CGIselectborrower => $CGIselectborrower,
713     todayissues       => \@realtodayissues,
714     previssues        => \@realprevissues,
715     inprocess         => $inprocess,
716     memberofinstution => $member_of_institution,
717     CGIorganisations  => $CGIorganisations,
718 );
719
720 # set return date if stickyduedate
721 if ($stickyduedate) {
722     my $t_year  = "year" . $year;
723     my $t_month = "month" . $month;
724     my $t_day   = "day" . $day;
725     $template->param(
726         $t_year  => 1,
727         $t_month => 1,
728         $t_day   => 1,
729     );
730 }
731
732 #if ($branchcookie) {
733 #$cookie=[$cookie, $branchcookie, $printercookie];
734 #}
735
736 $template->param(
737     SpecifyDueDate     => C4::Context->preference("SpecifyDueDate")
738 );
739 output_html_with_http_headers $query, $cookie, $template->output;
740
741 ####################################################################
742 # Extra subroutines,,,
743
744 sub cuecatbarcodedecode {
745     my ($barcode) = @_;
746     chomp($barcode);
747     my @fields = split( /\./, $barcode );
748     my @results = map( decode($_), @fields[ 1 .. $#fields ] );
749     if ( $#results == 2 ) {
750         return $results[2];
751     }
752     else {
753         return $barcode;
754     }
755 }