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