Made some changes to checkreserve and find_reserves, so that items are always display...
[koha.git] / C4 / Circulation / Circ2.pm
1 package C4::Circulation::Circ2;
2
3 #package to deal with Returns
4 #written 3/11/99 by olwen@katipo.co.nz
5
6 use strict;
7 require Exporter;
8 use DBI;
9 use C4::Database;
10 #use C4::Accounts;
11 #use C4::InterfaceCDK;
12 #use C4::Circulation::Main;
13 #use C4::Format;
14 #use C4::Circulation::Renewals;
15 #use C4::Scan;
16 use C4::Stats;
17 #use C4::Search;
18 #use C4::Print;
19
20 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
21   
22 # set the version for version checking
23 $VERSION = 0.01;
24     
25 @ISA = qw(Exporter);
26 @EXPORT = qw(&getbranches &getprinters &getpatroninformation &currentissues &getiteminformation &findborrower &issuebook &returnbook);
27 %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],
28                   
29 # your exported package globals go here,
30 # as well as any optionally exported functions
31
32 @EXPORT_OK   = qw($Var1 %Hashit);
33
34
35 # non-exported package globals go here
36 #use vars qw(@more $stuff);
37         
38 # initalize package globals, first exported ones
39
40 my $Var1   = '';
41 my %Hashit = ();
42                     
43 # then the others (which are still accessible as $Some::Module::stuff)
44 my $stuff  = '';
45 my @more   = ();
46         
47 # all file-scoped lexicals must be created before
48 # the functions below that use them.
49                 
50 # file-private lexicals go here
51 my $priv_var    = '';
52 my %secret_hash = ();
53                             
54 # here's a file-private function as a closure,
55 # callable as &$priv_func;  it cannot be prototyped.
56 my $priv_func = sub {
57   # stuff goes here.
58 };
59                                                     
60 # make all your functions, whether exported or not;
61
62
63 sub getbranches {
64     my ($env) = @_;
65     my %branches;
66     my $dbh=&C4Connect;  
67     my $sth=$dbh->prepare("select * from branches");
68     $sth->execute;
69     while (my $branch=$sth->fetchrow_hashref) {
70 #       (next) if ($branch->{'branchcode'} eq 'TR');
71         $branches{$branch->{'branchcode'}}=$branch;
72     }
73     $dbh->disconnect;
74     return (\%branches);
75 }
76
77
78 sub getprinters {
79     my ($env) = @_;
80     my %printers;
81     my $dbh=&C4Connect;  
82     my $sth=$dbh->prepare("select * from printers");
83     $sth->execute;
84     while (my $printer=$sth->fetchrow_hashref) {
85         $printers{$printer->{'printqueue'}}=$printer;
86     }
87     $dbh->disconnect;
88     return (\%printers);
89 }
90
91
92
93 sub getpatroninformation {
94 # returns 
95     my ($env, $borrowernumber,$cardnumber) = @_;
96     my $dbh=&C4Connect;  
97     my $sth;
98     open O, ">>/root/tkcirc.out";
99     print O "Looking up patron $borrowernumber / $cardnumber\n";
100     if ($borrowernumber) {
101         $sth=$dbh->prepare("select * from borrowers where borrowernumber=$borrowernumber");
102     } elsif ($cardnumber) {
103         $sth=$dbh->prepare("select * from borrowers where cardnumber=$cardnumber");
104     } else {
105          # error condition.  This subroutine must be called with either a
106          # borrowernumber or a card number.
107         $env->{'apierror'}="invalid borrower information passed to getpatroninformation subroutine";
108          return();
109     }
110     $sth->execute;
111     my $borrower=$sth->fetchrow_hashref;
112     my $flags=patronflags($env, $borrower, $dbh);
113     $sth->finish;
114     $dbh->disconnect;
115     print O "$borrower->{'surname'} <---\n";
116     close O;
117     $borrower->{'flags'}=$flags;
118     return($borrower, $flags);
119 }
120
121
122
123
124
125 sub getiteminformation {
126 # returns a hash of item information given either the itemnumber or the barcode
127     my ($env, $itemnumber, $barcode) = @_;
128     my $dbh=&C4Connect;
129     my $sth;
130     if ($itemnumber) {
131         $sth=$dbh->prepare("select * from biblio,items,biblioitems where items.itemnumber=$itemnumber and biblio.biblionumber=items.biblionumber and biblioitems.biblioitemnumber = items.biblioitemnumber");
132     } elsif ($barcode) {
133         my $q_barcode=$dbh->quote($barcode);
134         $sth=$dbh->prepare("select * from biblio,items,biblioitems where items.barcode=$q_barcode and biblio.biblionumber=items.biblionumber and biblioitems.biblioitemnumber = items.biblioitemnumber");
135     } else {
136         $env->{'apierror'}="getiteminformation() subroutine must be called with either an itemnumber or a barcode";
137         # Error condition.  
138         return();
139     }
140     $sth->execute;
141     my $iteminformation=$sth->fetchrow_hashref;
142     $sth->finish;
143     if ($iteminformation) {
144         $sth=$dbh->prepare("select date_due from issues where itemnumber=$iteminformation->{'itemnumber'} and isnull(returndate)");
145         $sth->execute;
146         my ($date_due) = $sth->fetchrow;
147         $iteminformation->{'date_due'}=$date_due;
148         $sth->finish;
149         #$iteminformation->{'dewey'}=~s/0*$//;
150         ($iteminformation->{'dewey'} == 0) && ($iteminformation->{'dewey'}='');
151         $sth=$dbh->prepare("select * from itemtypes where itemtype='$iteminformation->{'itemtype'}'");
152         $sth->execute;
153         my $itemtype=$sth->fetchrow_hashref;
154         $iteminformation->{'loanlength'}=$itemtype->{'loanlength'};
155         $sth->finish;
156     }
157     $dbh->disconnect;
158     return($iteminformation);
159 }
160
161 sub findborrower {
162 # returns an array of borrower hash references, given a cardnumber or a partial
163 # surname 
164     my ($env, $key) = @_;
165     my $dbh=&C4Connect;
166     my @borrowers;
167     my $q_key=$dbh->quote($key);
168     my $sth=$dbh->prepare("select * from borrowers where cardnumber=$q_key");
169     $sth->execute;
170     if ($sth->rows) {
171         my ($borrower)=$sth->fetchrow_hashref;
172         push (@borrowers, $borrower);
173     } else {
174         $q_key=$dbh->quote("$key%");
175         $sth->finish;
176         $sth=$dbh->prepare("select * from borrowers where surname like $q_key");
177         $sth->execute;
178         while (my $borrower = $sth->fetchrow_hashref) {
179             push (@borrowers, $borrower);
180         }
181     }
182     $sth->finish;
183     $dbh->disconnect;
184     return(\@borrowers);
185 }
186
187
188 sub issuebook {
189     my ($env, $patroninformation, $barcode, $responses) = @_;
190     my $dbh=&C4Connect;
191     my $iteminformation=getiteminformation($env, 0, $barcode);
192     my ($datedue);
193     my ($rejected,$question,$defaultanswer,$questionnumber, $noissue);
194     SWITCH: {
195         if ($patroninformation->{'gonenoaddress'}) {
196             $rejected="Patron is gone, with no known address.";
197             last SWITCH;
198         }
199         if ($patroninformation->{'lost'}) {
200             $rejected="Patron's card has been reported lost.";
201             last SWITCH;
202         }
203         my $amount = checkaccount($env,$patroninformation->{'borrowernumber'}, $dbh);
204         if ($amount>5) {
205             $rejected=sprintf "Patron owes \$%.02f.", $amount;
206             last SWITCH;
207         }
208         unless ($iteminformation) {
209             $rejected="$barcode is not a valid barcode.";
210             last SWITCH;
211         }
212         if ($iteminformation->{'notforloan'} == 1) {
213             $rejected="Item not for loan.";
214             last SWITCH;
215         }
216         if ($iteminformation->{'wthdrawn'} == 1) {
217             $rejected="Item withdrawn.";
218             last SWITCH;
219         }
220         if ($iteminformation->{'restricted'} == 1) {
221             $rejected="Restricted item.";
222             last SWITCH;
223         }
224         if ($iteminformation->{'itemtype'} eq 'REF') {
225             $rejected="Reference item:  Not for loan.";
226             last SWITCH;
227         }
228         my ($currentborrower) = currentborrower($env, $iteminformation->{'itemnumber'}, $dbh);
229         if ($currentborrower eq $patroninformation->{'borrowernumber'}) {
230 # Already issued to current borrower
231             my ($renewstatus) = renewstatus($env,$dbh,$patroninformation->{'borrowernumber'}, $iteminformation->{'itemnumber'});
232             if ($renewstatus == 0) {
233                 $rejected="No more renewals allowed for this item.";
234                 last SWITCH;
235             } else {
236                 if ($responses->{4} eq '') {
237                     $questionnumber=4;
238                     $question="Book is issued to this borrower.\nRenew?";
239                     $defaultanswer='Y';
240                     last SWITCH;
241                 } elsif ($responses->{4} eq 'Y') {
242                     my $charge=calc_charges($env, $dbh, $iteminformation->{'itemnumber'}, $patroninformation->{'borrowernumber'});
243                     if ($charge > 0) {
244                         createcharge($env, $dbh, $iteminformation->{'itemnumber'}, $patroninformation->{'borrowernumber'}, $charge);
245                         $iteminformation->{'charge'}=$charge;
246                     }
247                     &UpdateStats($env,$env->{'branchcode'},'renew',$charge,'',$iteminformation->{'itemnumber'},$iteminformation->{'itemtype'});
248                     renewbook($env,$dbh, $patroninformation->{'borrowernumber'}, $iteminformation->{'itemnumber'});
249                     $noissue=1;
250                 } else {
251                     $rejected=-1;
252                     last SWITCH;
253                 }
254             }
255         } elsif ($currentborrower ne '') {
256             my ($currborrower, $cbflags)=getpatroninformation($env,$currentborrower,0);
257             if ($responses->{1} eq '') {
258                 $questionnumber=1;
259                 $question="Issued to $currborrower->{'firstname'} $currborrower->{'surname'} ($currborrower->{'cardnumber'}).\nMark as returned?";
260                 $defaultanswer='Y';
261                 last SWITCH;
262             } elsif ($responses->{1} eq 'Y') {
263                 returnbook($env,$iteminformation->{'barcode'});
264             } else {
265                 $rejected=-1;
266                 last SWITCH;
267             }
268         }
269
270         my ($resbor, $resrec) = checkreserve($env, $dbh, $iteminformation->{'itemnumber'});
271
272         if ($resbor eq $patroninformation->{'borrowernumber'}) {
273              my $rquery = "update reserves set found = 'F' where reservedate = '$resrec->{'reservedate'}' and borrowernumber = '$resrec->{'borrowernumber'}' and biblionumber = '$resrec->{'biblionumber'}'";
274              my $rsth = $dbh->prepare($rquery);
275              $rsth->execute;
276              $rsth->finish;
277         } elsif ($resbor ne "") {
278             my ($resborrower, $flags)=getpatroninformation($env, $resbor,0);
279             if ($responses->{2} eq '') {
280                 $questionnumber=2;
281                 $question="Reserved for $resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'}) since $resrec->{'reservedate'}\nAllow issue?";
282                 $defaultanswer='N';
283                 last SWITCH;
284             } elsif ($responses->{2} eq 'N') {
285                 #printreserve($env, $resrec, $resborrower, $iteminformation);
286                 $rejected=-1;
287                 last SWITCH;
288             } else {
289                 if ($responses->{3} eq '') {
290                     $questionnumber=3;
291                     $question="Cancel reserve for $resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'})?";
292                     $defaultanswer='N';
293                     last SWITCH;
294                 } elsif ($responses->{3} eq 'Y') {
295                     my $rquery = "update reserves set found = 'F' where reservedate = '$resrec->{'reservedate'}' and borrowernumber = '$resrec->{'borrowernumber'}' and biblionumber = '$resrec->{'biblionumber'}'";
296                     my $rsth = $dbh->prepare($rquery);
297                     $rsth->execute;
298                     $rsth->finish;
299                 }
300             }
301         }
302     }
303     my $dateduef;
304     unless (($question) || ($rejected) || ($noissue)) {
305         my $loanlength=21;
306         if ($iteminformation->{'loanlength'}) {
307             $loanlength=$iteminformation->{'loanlength'};
308         }
309         my $ti=time;
310         my $datedue=time+($loanlength)*86400;
311         my @datearr = localtime($datedue);
312         $dateduef = (1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
313         if ($env->{'datedue'}) {
314             $dateduef=$env->{'datedue'};
315         }
316         my $sth=$dbh->prepare("insert into issues (borrowernumber, itemnumber, date_due, branchcode) values ($patroninformation->{'borrowernumber'}, $iteminformation->{'itemnumber'}, '$dateduef', '$env->{'branchcode'}')");
317         $sth->execute;
318         $sth->finish;
319         $iteminformation->{'issues'}++;
320         $sth=$dbh->prepare("update items set issues=$iteminformation->{'issues'} where itemnumber=$iteminformation->{'itemnumber'}");
321         $sth->execute;
322         $sth->finish;
323         my $charge=calc_charges($env, $dbh, $iteminformation->{'itemnumber'}, $patroninformation->{'borrowernumber'});
324         if ($charge > 0) {
325             createcharge($env, $dbh, $iteminformation->{'itemnumber'}, $patroninformation->{'borrowernumber'}, $charge);
326             $iteminformation->{'charge'}=$charge;
327         }
328         &UpdateStats($env,$env->{'branchcode'},'issue',$charge,'',$iteminformation->{'itemnumber'},$iteminformation->{'itemtype'});
329     }
330     my $message='';
331     if ($iteminformation->{'charge'}) {
332         $message=sprintf "Rental charge of \$%.02f applies.", $iteminformation->{'charge'};
333     }
334     $dbh->disconnect;
335     return ($iteminformation, $dateduef, $rejected, $question, $questionnumber, $defaultanswer, $message);
336 }
337
338
339 sub returnbook {
340     my ($env, $barcode) = @_;
341     my ($messages, $overduecharge);
342     my $dbh=&C4Connect;
343     my ($iteminformation) = getiteminformation($env, 0, $barcode);
344     my $borrower;
345     if ($iteminformation) {
346         my $sth=$dbh->prepare("select * from issues where (itemnumber='$iteminformation->{'itemnumber'}') and (returndate is null)");
347         $sth->execute;
348         my ($currentborrower) = currentborrower($env, $iteminformation->{'itemnumber'}, $dbh);
349         updatelastseen($env,$dbh,$iteminformation->{'itemnumber'});
350         if ($currentborrower) {
351             ($borrower)=getpatroninformation($env,$currentborrower,0);
352             my @datearr = localtime(time);
353             my $dateret = (1900+$datearr[5])."-".$datearr[4]."-".$datearr[3];
354             my $query = "update issues set returndate = now(), branchcode ='$env->{'branchcode'}' where (borrowernumber = $borrower->{'borrowernumber'}) and (itemnumber = $iteminformation->{'itemnumber'}) and (returndate is null)";
355             my $sth = $dbh->prepare($query);
356             $sth->execute;
357             $sth->finish;
358
359
360             # check for overdue fine
361
362             $overduecharge;
363             $sth=$dbh->prepare("select * from accountlines where (borrowernumber=$borrower->{'borrowernumber'}) and (itemnumber = $iteminformation->{'itemnumber'}) and (accounttype='FU' or accounttype='O')");
364             $sth->execute;
365             # alter fine to show that the book has been returned
366             if (my $data = $sth->fetchrow_hashref) {
367                 my $usth=$dbh->prepare("update accountlines set accounttype='F' where (borrowernumber=$borrower->{'borrowernumber'}) and (itemnumber=$iteminformation->{'itemnumber'}) and (acccountno='$data->{'accountno'}')");
368                 $usth->execute();
369                 $usth->finish();
370                 $overduecharge=$data->{'amountoutstanding'};
371             }
372             $sth->finish;
373             # check for charge made for lost book
374             $sth=$dbh->prepare("select * from accountlines where (borrowernumber=$borrower->{'borrowernumber'}) and (itemnumber = $iteminformation->{'itemnumber'}) and (accounttype='L')");
375             $sth->execute;
376             if (my $data = $sth->fetchrow_hashref) {
377                 # writeoff this amount
378                 my $offset;
379                 my $amount = $data->{'amount'};
380                 my $acctno = $data->{'accountno'};
381                 my $amountleft;
382                 if ($data->{'amountoutstanding'} == $amount) {
383                     $offset = $data->{'amount'};
384                     $amountleft = 0;
385                 } else {
386                     $offset = $amount - $data->{'amountoutstanding'};
387                     $amountleft = $data->{'amountoutstanding'} - $amount;
388                 }
389                 my $uquery = "update accountlines
390                   set accounttype = 'LR',amountoutstanding='0'
391                   where (borrowernumber = $borrower->{'borrowernumber'})
392                   and (itemnumber = $iteminformation->{'itemnumber'})
393                   and (accountno = '$acctno') ";
394                 my $usth = $dbh->prepare($uquery);
395                 $usth->execute();
396                 $usth->finish;
397                 my $nextaccntno = C4::Accounts::getnextacctno($env,$borrower->{'borrowernumber'},$dbh);
398                 $uquery = "insert into accountlines
399                   (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
400                   values ($borrower->{'borrowernumber'},$nextaccntno,now(),0-$amount,'Book Returned',
401                   'CR',$amountleft)";
402                 $usth = $dbh->prepare($uquery);
403                 $usth->execute;
404                 $usth->finish;
405                 $uquery = "insert into accountoffsets
406                   (borrowernumber, accountno, offsetaccount,  offsetamount)
407                   values ($borrower->{'borrowernumber'},$data->{'accountno'},$nextaccntno,$offset)";
408                 $usth = $dbh->prepare($uquery);
409                 $usth->execute;
410                 $usth->finish;
411             }
412             $sth->finish;
413         }
414         my ($resfound,$resrec) = find_reserves($env, $dbh, $iteminformation->{'itemnumber'});
415         if ($resfound eq 'y') {
416            my ($borrower) = getpatroninformation($env,$resrec->{'borrowernumber'},0);
417            #printreserve($env,$resrec,$resborrower,$itemrec);
418            my ($branches) = getbranches();
419            my $branchname=$branches->{$resrec->{'branchcode'}}->{'branchname'};
420            push (@$messages, "<b><font color=red>RESERVED</font></b> for collection by $borrower->{'firstname'} $borrower->{'surname'} ($borrower->{'cardnumber'}) at $branchname");
421         }
422         UpdateStats($env,'branch','return','0','',$iteminformation->{'itemnumber'});
423     }
424     $dbh->disconnect;
425     return ($iteminformation, $borrower, $messages, $overduecharge);
426 }
427
428
429 sub patronflags {
430 # Original subroutine for Circ2.pm
431     my %flags;
432     my ($env,$patroninformation,$dbh) = @_;
433     my $amount = checkaccount($env,$patroninformation->{'borrowernumber'}, $dbh);
434     if ($amount>0) { 
435         my %flaginfo;
436         $flaginfo{'message'}=sprintf "Patron owes \$%.02f", $amount; 
437         if ($amount>5) {
438             $flaginfo{'noissues'}=1;
439         }
440         $flags{'CHARGES'}=\%flaginfo;
441     }
442     if ($patroninformation->{'gonenoaddress'} == 1) {
443         my %flaginfo;
444         $flaginfo{'message'}='Borrower has no valid address.'; 
445         $flaginfo{'noissues'}=1;
446         $flags{'GNA'}=\%flaginfo;
447     }
448     if ($patroninformation->{'lost'} == 1) {
449         my %flaginfo;
450         $flaginfo{'message'}='Borrower\'s card reported lost.'; 
451         $flaginfo{'noissues'}=1;
452         $flags{'LOST'}=\%flaginfo;
453     }
454     if ($patroninformation->{'borrowernotes'}) {
455         my %flaginfo;
456         $flaginfo{'message'}="$patroninformation->{'borrowernotes'}";
457         $flags{'NOTES'}=\%flaginfo;
458     }
459     my ($odues, $itemsoverdue) = checkoverdues($env,$patroninformation->{'borrowernumber'},$dbh);
460     if ($odues > 0) {
461         my %flaginfo;
462         $flaginfo{'message'}="Patron has overdue items";
463         $flaginfo{'itemlist'}=$itemsoverdue;
464         foreach (sort {$a->{'date_due'} cmp $b->{'date_due'}} @$itemsoverdue) {
465             $flaginfo{'itemlisttext'}.="$_->{'date_due'} $_->{'barcode'} $_->{'title'} \n";
466         }
467         $flags{'ODUES'}=\%flaginfo;
468     }
469     my ($nowaiting,$itemswaiting) = checkwaiting($env,$dbh,$patroninformation->{'borrowernumber'});
470     if ($nowaiting>0) {
471         my %flaginfo;
472         $flaginfo{'message'}="Reserved items available";
473         $flaginfo{'itemlist'}=$itemswaiting;
474         $flaginfo{'itemfields'}=['barcode', 'title', 'author', 'dewey', 'subclass', 'holdingbranch'];
475         $flags{'WAITING'}=\%flaginfo;
476     }
477     my $flag;
478     my $key;
479     return(\%flags);
480 }
481
482
483 sub checkoverdues {
484 # From Main.pm, modified to return a list of overdueitems, in addition to a count
485   #checks whether a borrower has overdue items
486   my ($env,$bornum,$dbh)=@_;
487   my @datearr = localtime;
488   my $today = ($datearr[5] + 1900)."-".($datearr[4]+1)."-".$datearr[3];
489   my @overdueitems;
490   my $count=0;
491   my $query = "Select * from issues,biblio,biblioitems,items where items.biblioitemnumber=biblioitems.biblioitemnumber and items.biblionumber=biblio.biblionumber and issues.itemnumber=items.itemnumber and borrowernumber=$bornum and returndate is NULL and date_due < '$today'";
492   my $sth=$dbh->prepare($query);
493   $sth->execute;
494   while (my $data = $sth->fetchrow_hashref) {
495       push (@overdueitems, $data);
496       $count++;
497   }
498   $sth->finish;
499   return ($count, \@overdueitems);
500 }
501
502 sub updatelastseen {
503 # Stolen from Returns.pm
504     my ($env,$dbh,$itemnumber)= @_;
505     my $br = $env->{'branchcode'};
506     my $query = "update items 
507     set datelastseen = now(), holdingbranch = '$br'
508     where (itemnumber = '$itemnumber')";
509     my $sth = $dbh->prepare($query);
510     $sth->execute;
511     $sth->finish;
512
513
514 sub currentborrower {
515 # Original subroutine for Circ2.pm
516     my ($env, $itemnumber, $dbh) = @_;
517     my $q_itemnumber=$dbh->quote($itemnumber);
518     my $sth=$dbh->prepare("select borrowers.borrowernumber from
519     issues,borrowers where issues.itemnumber=$q_itemnumber and
520     issues.borrowernumber=borrowers.borrowernumber and issues.returndate is
521     NULL");
522     $sth->execute;
523     my ($previousborrower)=$sth->fetchrow;
524     return($previousborrower);
525 }
526
527 sub checkreserve {
528 # Stolen from Main.pm
529   # Check for reserves for biblio 
530   my ($env,$dbh,$itemnum)=@_;
531   my $resbor = "";
532   my $query = "select * from reserves,items 
533     where (items.itemnumber = '$itemnum')
534     and (reserves.cancellationdate is NULL)
535     and (items.biblionumber = reserves.biblionumber)
536     and ((reserves.found = 'W')
537     or (reserves.found is null)) 
538     order by priority";
539   my $sth = $dbh->prepare($query);
540   $sth->execute();
541   my $resrec;
542   my $data=$sth->fetchrow_hashref;
543   while ($data && $resbor eq '') {
544     $resrec=$data;
545     my $const = $data->{'constrainttype'};
546     if ($const eq "a") {
547       $resbor = $data->{'borrowernumber'};
548     } else {
549       my $found = 0;
550       my $cquery = "select * from reserveconstraints,items 
551          where (borrowernumber='$data->{'borrowernumber'}') 
552          and reservedate='$data->{'reservedate'}'
553          and reserveconstraints.biblionumber='$data->{'biblionumber'}'
554          and (items.itemnumber=$itemnum and 
555          items.biblioitemnumber = reserveconstraints.biblioitemnumber)";
556       my $csth = $dbh->prepare($cquery);
557       $csth->execute;
558       if (my $cdata=$csth->fetchrow_hashref) {$found = 1;}
559       if ($const eq 'o') {
560         if ($found eq 1) {$resbor = $data->{'borrowernumber'};}
561       } else {
562         if ($found eq 0) {$resbor = $data->{'borrowernumber'};}
563       }
564       $csth->finish();
565     }
566     $data=$sth->fetchrow_hashref;
567   }
568   $sth->finish;
569   return ($resbor,$resrec);
570 }
571
572 sub currentissues {
573 # New subroutine for Circ2.pm
574     my ($env, $borrower) = @_;
575     my $dbh=&C4Connect;
576     my %currentissues;
577     my $counter=1;
578     my $borrowernumber=$borrower->{'borrowernumber'};
579     my $crit='';
580     if ($env->{'todaysissues'}) {
581         my @datearr = localtime(time());
582         my $today = (1900+$datearr[5]).sprintf "0%02d", ($datearr[4]+1).sprintf "%02d", $datearr[3];
583         $crit=" and issues.timestamp like '$today%' ";
584     }
585     if ($env->{'nottodaysissues'}) {
586         my @datearr = localtime(time());
587         my $today = (1900+$datearr[5]).sprintf "0%02d", ($datearr[4]+1).sprintf "%02d", $datearr[3];
588         $crit=" and !(issues.timestamp like '$today%') ";
589     }
590     my $select="select * from issues,items,biblioitems,biblio where borrowernumber=$borrowernumber and issues.itemnumber=items.itemnumber and items.biblionumber=biblio.biblionumber and items.biblioitemnumber=biblioitems.biblioitemnumber and returndate is null $crit order by date_due";
591 #    print $select;
592     my $sth=$dbh->prepare($select);
593     $sth->execute;
594     while (my $data = $sth->fetchrow_hashref) {
595         $data->{'dewey'}=~s/0*$//;
596         ($data->{'dewey'} == 0) && ($data->{'dewey'}='');
597         my $datedue=$data->{'date_due'};
598         my $itemnumber=$data->{'itemnumber'};
599         $currentissues{$counter}=$data;
600         $counter++;
601     }
602     $sth->finish;
603     $dbh->disconnect;
604     return(\%currentissues);
605 }
606
607 sub checkwaiting {
608 #Stolen from Main.pm
609   # check for reserves waiting
610   my ($env,$dbh,$bornum)=@_;
611   my @itemswaiting;
612   my $query = "select * from reserves
613     where (borrowernumber = '$bornum')
614     and (reserves.found='W') and cancellationdate is NULL";
615   my $sth = $dbh->prepare($query);
616   $sth->execute();
617   my $cnt=0;
618   if (my $data=$sth->fetchrow_hashref) {
619     @itemswaiting[$cnt] =$data;
620     $cnt ++
621   }
622   $sth->finish;
623   return ($cnt,\@itemswaiting);
624 }
625
626
627 sub checkaccount  {
628 # Stolen from Accounts.pm
629   #take borrower number
630   #check accounts and list amounts owing
631   my ($env,$bornumber,$dbh)=@_;
632   my $sth=$dbh->prepare("Select sum(amountoutstanding) from accountlines where
633   borrowernumber=$bornumber and amountoutstanding<>0");
634   $sth->execute;
635   my $total=0;
636   while (my $data=$sth->fetchrow_hashref){
637     $total=$total+$data->{'sum(amountoutstanding)'};
638   }
639   $sth->finish;
640   # output(1,2,"borrower owes $total");
641   #if ($total > 0){
642   #  # output(1,2,"borrower owes $total");
643   #  if ($total > 5){
644   #    reconcileaccount($env,$dbh,$bornumber,$total);
645   #  }
646   #}
647   #  pause();
648   return($total);
649 }    
650
651 sub renewstatus {
652 # Stolen from Renewals.pm
653   # check renewal status
654   my ($env,$dbh,$bornum,$itemno)=@_;
655   my $renews = 1;
656   my $renewokay = 0;
657   my $q1 = "select * from issues 
658     where (borrowernumber = '$bornum')
659     and (itemnumber = '$itemno') 
660     and returndate is null";
661   my $sth1 = $dbh->prepare($q1);
662   $sth1->execute;
663   if (my $data1 = $sth1->fetchrow_hashref) {
664     my $q2 = "select renewalsallowed from items,biblioitems,itemtypes
665        where (items.itemnumber = '$itemno')
666        and (items.biblioitemnumber = biblioitems.biblioitemnumber) 
667        and (biblioitems.itemtype = itemtypes.itemtype)";
668     my $sth2 = $dbh->prepare($q2);
669     $sth2->execute;     
670     if (my $data2=$sth2->fetchrow_hashref) {
671       $renews = $data2->{'renewalsallowed'};
672     }
673     if ($renews > $data1->{'renewals'}) {
674       $renewokay = 1;
675     }
676     $sth2->finish;
677   }   
678   $sth1->finish;
679   return($renewokay);    
680 }
681
682 sub renewbook {
683 # Stolen from Renewals.pm
684   # mark book as renewed
685   my ($env,$dbh,$bornum,$itemno,$datedue)=@_;
686   $datedue=$env->{'datedue'};
687   if ($datedue eq "" ) {    
688     my $loanlength=21;
689     my $query= "Select * from biblioitems,items,itemtypes
690        where (items.itemnumber = '$itemno')
691        and (biblioitems.biblioitemnumber = items.biblioitemnumber)
692        and (biblioitems.itemtype = itemtypes.itemtype)";
693     my $sth=$dbh->prepare($query);
694     $sth->execute;
695     if (my $data=$sth->fetchrow_hashref) {
696       $loanlength = $data->{'loanlength'}
697     }
698     $sth->finish;
699     my $ti = time;
700     my $datedu = time + ($loanlength * 86400);
701     my @datearr = localtime($datedu);
702     $datedue = (1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
703   }
704   my @date = split("-",$datedue);
705   my $odatedue = (@date[2]+0)."-".(@date[1]+0)."-".@date[0];
706   my $issquery = "select * from issues where borrowernumber='$bornum' and
707     itemnumber='$itemno' and returndate is null";
708   my $sth=$dbh->prepare($issquery);
709   $sth->execute;
710   my $issuedata=$sth->fetchrow_hashref;
711   $sth->finish;
712   my $renews = $issuedata->{'renewals'} +1;
713   my $updquery = "update issues 
714     set date_due = '$datedue', renewals = '$renews'
715     where borrowernumber='$bornum' and
716     itemnumber='$itemno' and returndate is null";
717   my $sth=$dbh->prepare($updquery);
718   
719   $sth->execute;
720   $sth->finish;
721   return($odatedue);
722 }
723
724 sub calc_charges {
725 # Stolen from Issues.pm
726 # calculate charges due
727     my ($env, $dbh, $itemno, $bornum)=@_;
728     my $charge=0;
729     my $item_type;
730     my $q1 = "select itemtypes.itemtype,rentalcharge from items,biblioitems,itemtypes where (items.itemnumber ='$itemno') and (biblioitems.biblioitemnumber = items.biblioitemnumber) and (biblioitems.itemtype = itemtypes.itemtype)";
731     my $sth1= $dbh->prepare($q1);
732     $sth1->execute;
733     if (my $data1=$sth1->fetchrow_hashref) {
734         $item_type = $data1->{'itemtype'};
735         $charge = $data1->{'rentalcharge'};
736         my $q2 = "select rentaldiscount from borrowers,categoryitem 
737         where (borrowers.borrowernumber = '$bornum') 
738         and (borrowers.categorycode = categoryitem.categorycode)
739         and (categoryitem.itemtype = '$item_type')";
740         my $sth2=$dbh->prepare($q2);
741         $sth2->execute;
742         if (my $data2=$sth2->fetchrow_hashref) {
743             my $discount = $data2->{'rentaldiscount'};
744             $charge = ($charge *(100 - $discount)) / 100;
745         }
746         $sth2->{'finish'};
747     }      
748     $sth1->finish;
749     return ($charge);
750 }
751
752 sub createcharge {
753 #Stolen from Issues.pm
754     my ($env,$dbh,$itemno,$bornum,$charge) = @_;
755     my $nextaccntno = getnextacctno($env,$bornum,$dbh);
756     my $query = "insert into accountlines (borrowernumber,itemnumber,accountno,date,amount, description,accounttype,amountoutstanding) values ($bornum,$itemno,$nextaccntno,now(),$charge,'Rental','Rent',$charge)";
757     my $sth = $dbh->prepare($query);
758     $sth->execute;
759     $sth->finish;
760 }
761
762
763 sub getnextacctno {
764 # Stolen from Accounts.pm
765     my ($env,$bornumber,$dbh)=@_;
766     my $nextaccntno = 1;
767     my $query = "select * from accountlines where (borrowernumber = '$bornumber') order by accountno desc";
768     my $sth = $dbh->prepare($query);
769     $sth->execute;
770     if (my $accdata=$sth->fetchrow_hashref){
771         $nextaccntno = $accdata->{'accountno'} + 1;
772     }
773     $sth->finish;
774     return($nextaccntno);
775 }
776
777 sub find_reserves {
778 # Stolen from Returns.pm
779   my ($env,$dbh,$itemno) = @_;
780   my ($itemdata) = getiteminformation($env,$itemno,0);
781   my $query = "select * from reserves where 
782   ((reserves.found = 'W')                                   
783   or (reserves.found is null)) 
784   and biblionumber = $itemdata->{'biblionumber'} and cancellationdate is NULL
785   order by priority,reservedate ";
786   my $sth = $dbh->prepare($query);
787   $sth->execute;
788   my $resfound = "n";
789   my $resrec;
790   my $lastrec;
791   while (($resrec=$sth->fetchrow_hashref) && ($resfound eq "n")) {
792       $lastrec=$resrec;
793     if ($resrec->{'found'} eq "W") {
794       if ($resrec->{'itemnumber'} eq $itemno) {
795         $resfound = "y";
796       }
797     } 
798     if ($resrec->{'constrainttype'} eq "a") {
799       $resfound = "y";
800     } else {
801       my $conquery = "select * from reserveconstraints where borrowernumber
802 = $resrec->{'borrowernumber'} and reservedate = '$resrec->{'reservedate'}' and biblionumber = $resrec->{'biblionumber'} and biblioitemnumber = $itemdata->{'biblioitemnumber'}";
803       my $consth = $dbh->prepare($conquery);
804       $consth->execute;
805       if (my $conrec=$consth->fetchrow_hashref) {
806         if ($resrec->{'constrainttype'} eq "o") {
807            $resfound = "y";
808          }
809       } else {
810         if ($resrec->{'constrainttype'} eq "e") {
811           $resfound = "y";
812         }
813       }
814       $consth->finish;
815     }
816     if ($resfound eq "y") {
817       my $updquery = "update reserves 
818         set found = 'W',itemnumber='$itemno'
819         where borrowernumber = $resrec->{'borrowernumber'}
820         and reservedate = '$resrec->{'reservedate'}'
821         and biblionumber = $resrec->{'biblionumber'}";
822       my $updsth = $dbh->prepare($updquery);
823       $updsth->execute;
824       $updsth->finish;
825       my $itbr = $resrec->{'branchcode'};
826       if ($resrec->{'branchcode'} ne $env->{'branchcode'}) {
827          my $updquery = "update items
828           set holdingbranch = 'TR'
829           where itemnumber = $itemno";
830         my $updsth = $dbh->prepare($updquery);
831         $updsth->execute;
832         $updsth->finish;
833       } 
834     }
835   }
836   $sth->finish;
837   return ($resfound,$lastrec);
838 }
839
840 END { }       # module clean-up code here (global destructor)