1 package C4::Circulation::Circ2; #assumes C4/Circulation/Returns
3 #package to deal with Returns
4 #written 3/11/99 by olwen@katipo.co.nz
12 use C4::Circulation::Main;
14 use C4::Circulation::Renewals;
20 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
22 # set the version for version checking
26 @EXPORT = qw(&getpatroninformation ¤tissues &getiteminformation &findborrower &issuebook &returnbook);
27 %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ],
29 # your exported package globals go here,
30 # as well as any optionally exported functions
32 @EXPORT_OK = qw($Var1 %Hashit);
35 # non-exported package globals go here
36 #use vars qw(@more $stuff);
38 # initalize package globals, first exported ones
43 # then the others (which are still accessible as $Some::Module::stuff)
47 # all file-scoped lexicals must be created before
48 # the functions below that use them.
50 # file-private lexicals go here
54 # here's a file-private function as a closure,
55 # callable as &$priv_func; it cannot be prototyped.
60 # make all your functions, whether exported or not;
62 sub getpatroninformation {
63 my ($env, $borrowernumber,$cardnumber) = @_;
66 if ($borrowernumber) {
67 $sth=$dbh->prepare("select * from borrowers where borrowernumber=$borrowernumber");
68 } elsif ($cardnumber) {
69 $sth=$dbh->prepare("select * from borrowers where cardnumber=$cardnumber");
71 # error condition. This subroutine must be called with either a
72 # borrowernumber or a card number.
73 $env->{'apierror'}="invalid borrower information passed to getpatroninformation subroutine";
77 my $borrower=$sth->fetchrow_hashref;
78 my $flags=patronflags($env, $borrower, $dbh);
81 return($borrower, $flags);
86 my ($env,$patroninformation,$dbh) = @_;
87 my $amount = checkaccount($env,$patroninformation->{'borrowernumber'}, $dbh);
90 $flaginfo{'message'}='Patron owes $amount';
92 $flaginfo{'noissues'}=1;
94 $flags{'CHARGES'}=\%flaginfo;
96 if ($patroninformation->{'gonenoaddress'} == 1) {
98 $flaginfo{'message'}='Borrower has no valid address.';
99 $flaginfo{'noissues'}=1;
100 $flags{'GNA'}=\%flaginfo;
102 if ($patroninformation->{'lost'} == 1) {
104 $flaginfo{'message'}='Borrower\'s card reported lost.';
105 $flaginfo{'noissues'}=1;
106 $flags{'LOST'}=\%flaginfo;
108 if ($patroninformation->{'borrowernotes'}) {
110 $flaginfo{'message'}="Note: $patroninformation->{'borrowernotes'}";
111 $flags{'NOTES'}=\%flaginfo;
113 my ($odues) = checkoverdues($env,$patroninformation->{'borrowernumber'},$dbh);
116 $flaginfo{'message'}="Overdue Items";
117 $flags{'ODUES'}=\%flaginfo;
119 my ($nowaiting,$itemswaiting) = checkwaiting($env,$dbh,$patroninformation->{'borrowernumber'});
122 $flaginfo{'message'}="Reserved items available";
123 $flaginfo{'itemlist'}=$itemswaiting;
124 $flaginfo{'itemfields'}=['barcode', 'title', 'author', 'dewey', 'subclass', 'holdingbranch'];
125 $flags{'WAITING'}=\%flaginfo;
136 my ($env, $borrower) = @_;
140 my $borrowernumber=$borrower->{'borrowernumber'};
141 my $sth=$dbh->prepare("select * from issues,items,biblio where borrowernumber=$borrowernumber and issues.itemnumber=items.itemnumber and items.biblionumber=biblio.biblionumber and returndate is null order by date_due");
143 while (my $data = $sth->fetchrow_hashref) {
144 my $datedue=$data->{'date_due'};
145 my $itemnumber=$data->{'itemnumber'};
146 my ($iteminformation) = getiteminformation($env, $itemnumber,0);
147 open O, ">>/root/tkcirc.out";
148 print O "Getting item info for $itemnumber $iteminformation->{'barcode'}.\n";
150 $iteminformation->{'datedue'}=$datedue;
151 $currentissues{$counter}=$iteminformation;
156 return(\%currentissues);
159 sub getiteminformation {
160 my ($env, $itemnumber, $barcode) = @_;
164 $sth=$dbh->prepare("select * from biblio,items,biblioitems where items.itemnumber=$itemnumber and biblio.biblionumber=items.biblionumber and biblioitems.biblioitemnumber = items.biblioitemnumber");
166 my $q_barcode=$dbh->quote($barcode);
167 $sth=$dbh->prepare("select * from biblio,items,biblioitems where items.barcode=$q_barcode and biblio.biblionumber=items.biblionumber and biblioitems.biblioitemnumber = items.biblioitemnumber");
169 $env->{'apierror'}="getiteminformation() subroutine must be called with either an itemnumber or a barcode";
174 my $iteminformation=$sth->fetchrow_hashref;
177 $iteminformation->{'dewey'}=~s/0*$//;
178 return($iteminformation);
182 my ($env, $key) = @_;
185 my $q_key=$dbh->quote($key);
186 my $sth=$dbh->prepare("select * from borrowers where cardnumber=$q_key");
189 my ($borrower)=$sth->fetchrow_hashref;
190 push (@borrowers, $borrower);
192 $q_key=$dbh->quote("$key%");
194 $sth=$dbh->prepare("select * from borrowers where surname like $q_key");
196 while (my $borrower = $sth->fetchrow_hashref) {
197 push (@borrowers, $borrower);
205 sub currentborrower {
206 my ($env, $itemnumber, $dbh) = @_;
207 my $q_itemnumber=$dbh->quote($itemnumber);
208 my $sth=$dbh->prepare("select borrowers.borrowernumber from
209 issues,borrowers where issues.itemnumber=$q_itemnumber and
210 issues.borrowernumber=borrowers.borrowernumber and issues.returndate is
213 my ($previousborrower)=$sth->fetchrow;
214 return($previousborrower);
219 # Check for reserves for biblio
220 my ($env,$dbh,$itemnum)=@_;
222 my $query = "select * from reserves,items
223 where (items.itemnumber = '$itemnum')
224 and (reserves.cancellationdate is NULL)
225 and (items.biblionumber = reserves.biblionumber)
226 and ((reserves.found = 'W')
227 or (reserves.found is null))
229 my $sth = $dbh->prepare($query);
232 if (my $data=$sth->fetchrow_hashref) {
234 my $const = $data->{'constrainttype'};
236 $resbor = $data->{'borrowernumber'};
239 my $cquery = "select * from reserveconstraints,items
240 where (borrowernumber='$data->{'borrowernumber'}')
241 and reservedate='$data->{'reservedate'}'
242 and reserveconstraints.biblionumber='$data->{'biblionumber'}'
243 and (items.itemnumber=$itemnum and
244 items.biblioitemnumber = reserveconstraints.biblioitemnumber)";
245 my $csth = $dbh->prepare($cquery);
247 if (my $cdata=$csth->fetchrow_hashref) {$found = 1;}
249 if ($found eq 1) {$resbor = $data->{'borrowernumber'};}
251 if ($found eq 0) {$resbor = $data->{'borrowernumber'};}
257 return ($resbor,$resrec);
262 my ($env, $patroninformation, $barcode, $responses) = @_;
264 my $iteminformation=getiteminformation($env, 0, $barcode);
266 my ($rejected,$question,$defaultanswer,$questionnumber, $noissue);
268 if ($iteminformation->{'notforloan'} == 1) {
269 $rejected="Item not for loan.";
272 if ($iteminformation->{'wthdrawn'} == 1) {
273 $rejected="Item withdrawn.";
276 if ($iteminformation->{'restricted'} == 1) {
277 $rejected="Restricted item.";
280 if ($iteminformation->{'itemtype'} eq 'REF') {
281 $rejected="Reference item: Not for loan.";
284 my ($currentborrower) = currentborrower($env, $iteminformation->{'itemnumber'}, $dbh);
285 if ($currentborrower eq $patroninformation->{'borrowernumber'}) {
286 # Already issued to current borrower
287 my ($renewstatus) = renewstatus($env,$dbh,$patroninformation->{'borrowernumber'}, $iteminformation->{'itemnumber'});
288 if ($renewstatus == 0) {
289 $rejected="No more renewals allowed for this item.";
292 if ($responses->{4} eq '') {
294 $question="Book is issued to this borrower.\nRenew?";
297 } elsif ($responses->{4} eq 'Y') {
298 renewbook($env,$dbh, $patroninformation->{'borrowernumber'}, $iteminformation->{'itemnumber'});
305 } elsif ($currentborrower ne '') {
306 my ($currborrower, $cbflags)=getpatroninformation($env,$currentborrower,0);
307 if ($responses->{1} eq '') {
309 $question="Issued to $currborrower->{'firstname'} $currborrower->{'surname'} ($currborrower->{'cardnumber'}).\nMark as returned?";
312 } elsif ($responses->{1} eq 'Y') {
313 returnbook($env,$iteminformation->{'barcode'});
320 my ($resbor, $resrec) = checkreserve($env, $dbh, $iteminformation->{'itemnumber'});
322 if ($resbor eq $patroninformation->{'borrowernumber'}) {
323 my $rquery = "update reserves set found = 'F' where reservedate = '$resrec->{'reservedate'}' and borrowernumber = '$resrec->{'borrowernumber'}' and biblionumber = '$resrec->{'biblionumber'}'";
324 my $rsth = $dbh->prepare($rquery);
327 } elsif ($resbor ne "") {
328 my $resborrower=getpatroninformation($env, $resbor,0);
329 if ($responses->{2} eq '') {
331 $question="Reserved for $resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'}\nAllow issue?";
334 } elsif ($responses->{2} eq 'N') {
335 printreserve($env, $resrec, $resborrower, $iteminformation);
339 if ($responses->{3} eq '') {
341 $question="Cancel reserve for $resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'}?";
344 } elsif ($responses->{3} eq 'Y') {
345 my $rquery = "update reserves set found = 'F' where reservedate = '$resrec->{'reservedate'}' and borrowernumber = '$resrec->{'borrowernumber'}' and biblionumber = '$resrec->{'biblionumber'}'";
346 my $rsth = $dbh->prepare($rquery);
354 unless (($question) || ($rejected) || ($noissue)) {
356 if ($iteminformation->{'loanlength'}) {
357 $loanlength=$iteminformation->{'loanlength'};
360 my $datedue=time+($loanlength)*86400;
361 my @datearr = localtime($datedue);
362 $dateduef = (1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
363 my $sth=$dbh->prepare("insert into issues (borrowernumber, itemnumber, date_due, branchcode) values ($patroninformation->{'borrowernumber'}, $iteminformation->{'itemnumber'}, '$dateduef', '$env->{'branchcode'}')");
366 $iteminformation->{'issues'}++;
367 $sth=$dbh->prepare("update items set issues=$iteminformation->{'issues'} where itemnumber=$iteminformation->{'itemnumber'}");
372 return ($iteminformation, $dateduef, $rejected, $question, $questionnumber, $defaultanswer);
377 my ($env,$dbh,$itemnumber)= @_;
378 my $br = $env->{'branchcode'};
379 my $query = "update items
380 set datelastseen = now(), holdingbranch = '$br'
381 where (itemnumber = '$itemnumber')";
382 my $sth = $dbh->prepare($query);
388 my ($env, $barcode) = @_;
389 my ($messages, $overduecharge);
391 my ($iteminformation) = getiteminformation($env, 0, $barcode);
393 if ($iteminformation) {
394 my $sth=$dbh->prepare("select * from issues where (itemnumber='$iteminformation->{'itemnumber'}') and (returndate is null)");
396 my ($currentborrower) = currentborrower($env, $iteminformation->{'itemnumber'}, $dbh);
397 ($borrower)=getpatroninformation($env,$currentborrower,0);
399 my @datearr = localtime(time);
400 my $dateret = (1900+$datearr[5])."-".$datearr[4]."-".$datearr[3];
401 my $query = "update issues set returndate = now(), branchcode ='$env->{'branchcode'}' where (borrowernumber = $borrower->{'borrowernumber'}) and (itemnumber = $iteminformation->{'itemnumber'}) and (returndate is null)";
402 my $sth = $dbh->prepare($query);
405 updatelastseen($env,$dbh,$iteminformation->{'itemnumber'});
408 # check for overdue fine
411 $sth=$dbh->prepare("select * from accountlines where (borrowernumber=$borrower->{'borrowernumber'}) and (itemnumber = $iteminformation->{'itemnumber'}) and (accounttype='FU' or accounttype='O')");
413 # alter fine to show that the book has been returned
414 if (my $data = $sth->fetchrow_hashref) {
415 my $usth=$dbh->prepare("update accountlines set accounttype='F' where (borrowernumber=$borrower->{'borrowernumber'}) and (itemnumber=$iteminformation->{'itemnumber'}) and (acccountno='$data->{'accountno'}')");
418 $overduecharge=$data->{'amountoutstanding'};
421 # check for charge made for lost book
422 $sth=$dbh->prepare("select * from accountlines where (borrowernumber=$borrower->{'borrowernumber'}) and (itemnumber = $iteminformation->{'itemnumber'}) and (accounttype='L')");
424 if (my $data = $sth->fetchrow_hashref) {
425 # writeoff this amount
427 my $amount = $data->{'amount'};
428 my $acctno = $data->{'accountno'};
430 if ($data->{'amountoutstanding'} == $amount) {
431 $offset = $data->{'amount'};
434 $offset = $amount - $data->{'amountoutstanding'};
435 $amountleft = $data->{'amountoutstanding'} - $amount;
437 my $uquery = "update accountlines
438 set accounttype = 'LR',amountoutstanding='0'
439 where (borrowernumber = $borrower->{'borrowernumber'})
440 and (itemnumber = $iteminformation->{'itemnumber'})
441 and (accountno = '$acctno') ";
442 my $usth = $dbh->prepare($uquery);
445 my $nextaccntno = C4::Accounts::getnextacctno($env,$borrower->{'borrowernumber'},$dbh);
446 $uquery = "insert into accountlines
447 (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
448 values ($borrower->{'borrowernumber'},$nextaccntno,now(),0-$amount,'Book Returned',
450 $usth = $dbh->prepare($uquery);
453 $uquery = "insert into accountoffsets
454 (borrowernumber, accountno, offsetaccount, offsetamount)
455 values ($borrower->{'borrowernumber'},$data->{'accountno'},$nextaccntno,$offset)";
456 $usth = $dbh->prepare($uquery);
463 UpdateStats($env,'branch','return','0','',$iteminformation->{'itemnumber'});
464 return ($iteminformation, $borrower, $messages, $overduecharge);
467 END { } # module clean-up code here (global destructor)