2 # NOTE: This file uses standard 8-character tabs
8 # Copyright 2000-2002 Katipo Communications
10 # This file is part of Koha.
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
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.
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
30 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
31 my $library_name = C4::Context->preference("LibraryName");
33 # set the version for version checking
55 # FIXME Take out CalcReserveFee after it can be removed from opac-reserves.pl
74 GetFirstReserveDateFromItem
75 GetNumberReservesFromBorrower
79 # make all your functions, whether exported or not;
81 New op dev for the circulation based on item, global is a function to cancel reserv,check other reserves, and transfer document if it's necessary
87 my ($itemnumber,$borrowernumber)=@_;
89 # step 1 : cancel the reservation
90 my $CancelReserve = CancelReserve(0,$itemnumber,$borrowernumber);
92 # step 2 launch the subroutine of the others reserves
93 my ($messages,$nextreservinfo) = OtherReserves($itemnumber);
95 return ($messages,$nextreservinfo);
99 New op dev: check queued list of this document and check if this document must be transfered
106 my ($restype,$checkreserves) = CheckReserves($itemnumber);
109 my $iteminfo = C4::Circulation::Circ2::getiteminformation(\%env,$itemnumber);
110 if ($iteminfo->{'holdingbranch'} ne $checkreserves->{'branchcode'}){
111 $messages->{'transfert'} = $checkreserves->{'branchcode'};
113 # minus priorities of others reservs
114 MinusPriority($itemnumber,$checkreserves->{'borrowernumber'},$iteminfo->{'biblionumber'});
115 # launch the subroutine dotransfer
116 C4::Circulation::Circ2::dotransfer($itemnumber,$iteminfo->{'holdingbranch'},$checkreserves->{'branchcode'}),
119 # step 2b : case of a reservation on the same branch, set the waiting status
121 $messages->{'waiting'} = 1;
122 MinusPriority($itemnumber,$checkreserves->{'borrowernumber'},$iteminfo->{'biblionumber'});
123 SetWaitingStatus($itemnumber);
126 $nextreservinfo = $checkreserves->{'borrowernumber'};
129 return ($messages,$nextreservinfo);
133 Reduce the values of queuded list
137 my ($itemnumber,$borrowernumber,$biblionumber)=@_;
138 # first step update the value of the first person on reserv
139 my $dbh = C4::Context->dbh;
140 my $sth_upd=$dbh->prepare("UPDATE reserves SET priority = 0 , itemnumber = ?
141 WHERE cancellationdate is NULL
143 AND biblionumber=?");
144 $sth_upd->execute($itemnumber,$borrowernumber,$biblionumber);
147 # second step update all others reservs
148 my $sth_oth=$dbh->prepare("SELECT priority,borrowernumber,biblionumber,reservedate FROM reserves WHERE priority !='0' AND cancellationdate is NULL");
150 while (my ($priority,$borrowernumber,$biblionumber,$reservedate)=$sth_oth->fetchrow_array){
152 my $sth_upd_oth = $dbh->prepare("UPDATE reserves SET priority = ?
153 WHERE biblionumber = ?
154 AND borrowernumber = ?
155 AND reservedate = ?");
156 $sth_upd_oth->execute($priority,$biblionumber,$borrowernumber,$reservedate);
157 $sth_upd_oth->finish;
165 New op dev for the circulation based on item, global is a function to cancel reserv,check other reserves, and transfer document if it's necessary
169 # we check if we have a reserves with itemnumber (New op system of reserves), if we found one, we update the status of the reservation when we have : 'priority' = 0, and we have an itemnumber
170 sub SetWaitingStatus{
171 # first : check if we have a reservation for this item .
173 my $dbh = C4::Context->dbh;
174 my $sth_find=$dbh->prepare("SELECT priority,borrowernumber from reserves WHERE itemnumber=? and cancellationdate is NULL and found is NULL and priority='0'");
175 $sth_find->execute($itemnumber);
176 my ($priority,$borrowernumber) = $sth_find->fetchrow_array;
178 if (not $borrowernumber){
182 # step 2 : if we have a borrowernumber, we update the value found to 'W' for notify the borrower
183 my $sth_set=$dbh->prepare("UPDATE reserves SET found='W',waitingdate = now() where borrowernumber=? AND itemnumber=? AND found is null");
184 $sth_set->execute($borrowernumber,$itemnumber);
190 sub FastFindReserves {
191 my ($itemnumber,$borrowernumber)=@_;
193 my $dbh = C4::Context->dbh;
194 my $sth_res=$dbh->prepare("SELECT reservedate,borrowernumber from reserves WHERE itemnumber=? and cancellationdate is NULL AND (found != 'F' or found is null)");
195 $sth_res->execute($itemnumber);
196 my ($reservedate,$borrowernumber)=$sth_res->fetchrow_array;
198 return($reservedate,$borrowernumber);
200 if ($borrowernumber){
201 my $dbh = C4::Context->dbh;
202 my $sth_find=$dbh->prepare("SELECT * from reserves WHERE borrowernumber=? and cancellationdate is NULL and (found != 'F' or found is null) order by reservedate");
203 $sth_find->execute($borrowernumber);
206 while (my $data=$sth_find->fetchrow_hashref){
207 $borrowerreserv[$i]=$data;
211 return (@borrowerreserv);
220 ($count, $results) = &FindReserves($biblionumber, $borrowernumber);
222 Looks books up in the reserves. C<$biblionumber> is the biblionumber
223 of the book to look up. C<$borrowernumber> is the borrower number of a
224 patron whose books to look up.
226 Either C<$biblionumber> or C<$borrowernumber> may be the empty string,
227 but not both. If both are specified, C<&FindReserves> looks up the
228 given book for the given patron. If only C<$biblionumber> is
229 specified, C<&FindReserves> looks up that book for all patrons. If
230 only C<$borrowernumber> is specified, C<&FindReserves> looks up all of
231 that patron's reserves. If neither is specified, C<&FindReserves>
234 For each book thus found, C<&FindReserves> checks the reserve
235 constraints and does something I don't understand.
237 C<&FindReserves> returns a two-element array:
239 C<$count> is the number of elements in C<$results>.
241 C<$results> is a reference to an array of references of hashes. Each hash
242 has for keys a list of column from reserves table (see details in function).
247 my ($bib, $bor) = @_;
248 my $dbh = C4::Context->dbh;
251 # Find the desired items in the reserves
254 timestamp AS rtimestamp,
262 WHERE cancellationdate IS NULL
263 AND (found <> \'F\' OR found IS NULL)
275 AND borrowernumber = ?
283 my $sth=$dbh->prepare($query);
284 $sth->execute(@bind);
287 while (my $data = $sth->fetchrow_hashref){
288 # FIXME - What is this if-statement doing? How do constraints work?
289 if ($data->{constrainttype} eq 'o') {
291 SELECT biblioitemnumber
292 FROM reserveconstraints
293 WHERE biblionumber = ?
294 AND borrowernumber = ?
297 my $csth=$dbh->prepare($query);
299 $data->{biblionumber},
300 $data->{borrowernumber},
301 $data->{reservedate},
305 while (my $bibitemnos = $csth->fetchrow_array){
306 push (@bibitemno,$bibitemnos);
308 my $count = @bibitemno;
310 # if we have two or more different specific itemtypes
311 # reserved by same person on same day
314 warn "bibitemno $bibitemno[$i]";
315 $bdata = C4::Search::bibitemdata($bibitemno[$i]);
318 # Look up the book we just found.
319 $bdata = C4::Search::bibitemdata($bibitemno[0]);
322 # Add the results of this latest search to the current
324 # FIXME - An 'each' would probably be more efficient.
325 foreach my $key (keys %$bdata) {
326 $data->{$key} = $bdata->{$key};
329 push @results, $data;
333 return($#results+1,\@results);
336 sub GetNumberReservesFromBorrower {
337 my ($borrowernumber) = @_;
339 my $dbh = C4::Context->dbh;
342 SELECT COUNT(*) AS counter
344 WHERE borrowernumber = ?
345 AND cancellationdate IS NULL
346 AND (found != \'F\' OR found IS NULL)
348 my $sth = $dbh->prepare($query);
349 $sth->execute($borrowernumber);
350 my $row = $sth->fetchrow_hashref;
353 return $row->{counter};
356 sub GetFirstReserveDateFromItem {
357 my ($itemnumber) = @_;
359 my $dbh = C4::Context->dbh;
365 AND cancellationdate IS NULL
366 AND (found != \'F\' OR found IS NULL)
368 my $sth = $dbh->prepare($query);
369 $sth->execute($itemnumber);
370 my $row = $sth->fetchrow_hashref;
373 return $row->{reservedate};
378 ($status, $reserve) = &CheckReserves($itemnumber, $barcode);
380 Find a book in the reserves.
382 C<$itemnumber> is the book's item number. C<$barcode> is its barcode.
383 Either one, but not both, may be false. If both are specified,
384 C<&CheckReserves> uses C<$itemnumber>.
386 $itemnubmer can be false, in which case uses the barcode. (Never uses
387 both. $itemnumber gets priority).
389 As I understand it, C<&CheckReserves> looks for the given item in the
390 reserves. If it is found, that's a match, and C<$status> is set to
393 Otherwise, it finds the most important item in the reserves with the
394 same biblio number as this book (I'm not clear on this) and returns it
395 with C<$status> set to C<Reserved>.
397 C<&CheckReserves> returns a two-element list:
399 C<$status> is either C<Waiting>, C<Reserved> (see above), or 0.
401 C<$reserve> is the reserve item that matched. It is a
402 reference-to-hash whose keys are mostly the fields of the reserves
403 table in the Koha database.
408 my ($item, $barcode) = @_;
409 # warn "In CheckReserves: itemnumber = $item";
410 my $dbh = C4::Context->dbh;
413 my $qitem=$dbh->quote($item);
414 # Look up the item by itemnumber
415 $sth=$dbh->prepare("SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan
416 FROM items, biblioitems, itemtypes
417 WHERE items.biblioitemnumber = biblioitems.biblioitemnumber
418 AND biblioitems.itemtype = itemtypes.itemtype
419 AND itemnumber=$qitem");
421 my $qbc=$dbh->quote($barcode);
422 # Look up the item by barcode
423 $sth=$dbh->prepare("SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan
424 FROM items, biblioitems, itemtypes
425 WHERE items.biblioitemnumber = biblioitems.biblioitemnumber
426 AND biblioitems.itemtype = itemtypes.itemtype
428 # FIXME - This function uses $item later on. Ought to set it here.
431 my ($biblio, $bibitem, $notforloan) = $sth->fetchrow_array;
433 # if item is not for loan it cannot be reserved either.....
434 return (0, 0) if ($notforloan);
435 # get the reserves...
436 # Find this item in the reserves
437 my ($count, @reserves) = Findgroupreserve($bibitem, $biblio);
438 # $priority and $highest are used to find the most important item
439 # in the list returned by &Findgroupreserve. (The lower $priority,
440 # the more important the item.)
441 # $highest is the most important item we've seen so far.
442 my $priority = 10000000;
445 foreach my $res (@reserves) {
446 # FIXME - $item might be undefined or empty: the caller
447 # might be searching by barcode.
448 if ($res->{'itemnumber'} == $item) {
450 return ("Waiting", $res);
452 # See if this item is more important than what we've got
454 if ($res->{'priority'} != 0 && $res->{'priority'} < $priority) {
455 $priority = $res->{'priority'};
462 # If we get this far, then no exact match was found. Print the
463 # most important item on the list. I think this tells us who's
464 # next in line to get this book.
465 if ($highest) { # FIXME - $highest might be undefined
466 $highest->{'itemnumber'} = $item;
467 return ("Reserved", $highest);
475 &CancelReserve($biblionumber, $itemnumber, $borrowernumber);
479 Use either C<$biblionumber> or C<$itemnumber> to specify the item to
480 cancel, but not both: if both are given, C<&CancelReserve> does
483 C<$borrowernumber> is the borrower number of the patron on whose
484 behalf the book was reserved.
486 If C<$biblionumber> was given, C<&CancelReserve> also adjusts the
487 priorities of the other people who are waiting on the book.
492 my ($biblio, $item, $borr) = @_;
493 my $dbh = C4::Context->dbh;
494 #warn "In CancelReserve";
495 if (($item and $borr) and (not $biblio)) {
496 # removing a waiting reserve record....
497 # update the database...
498 my $sth = $dbh->prepare("update reserves set cancellationdate = now(),
502 and borrowernumber = ?");
503 $sth->execute($item,$borr);
506 if (($biblio and $borr) and (not $item)) {
507 # removing a reserve record....
508 # get the prioritiy on this record....
510 my $sth=$dbh->prepare("SELECT priority FROM reserves
511 WHERE biblionumber = ?
512 AND borrowernumber = ?
513 AND cancellationdate is NULL
514 AND (found <> 'F' or found is NULL)");
515 $sth->execute($biblio,$borr);
516 ($priority) = $sth->fetchrow_array;
519 # update the database, removing the record...
520 $sth = $dbh->prepare("update reserves set cancellationdate = now(),
523 where biblionumber = ?
524 and borrowernumber = ?
525 and cancellationdate is NULL
526 and (found <> 'F' or found is NULL)");
527 $sth->execute($biblio,$borr);
529 # now fix the priority on the others....
530 fixpriority($priority, $biblio);
536 &FillReserve($reserve);
538 Fill a reserve. If I understand this correctly, this means that the
539 reserved book has been found and given to the patron who reserved it.
541 C<$reserve> specifies the reserve to fill. It is a reference-to-hash
542 whose keys are fields from the reserves table in the Koha database.
548 my $dbh = C4::Context->dbh;
550 # fill in a reserve record....
551 # FIXME - Remove some of the redundancy here
552 my $biblio = $res->{'biblionumber'}; my $qbiblio =$biblio;
553 my $borr = $res->{'borrowernumber'};
554 my $resdate = $res->{'reservedate'};
556 # get the priority on this record....
559 my $query = "SELECT priority FROM reserves
560 WHERE biblionumber = ?
561 AND borrowernumber = ?
562 AND reservedate = ?";
563 my $sth=$dbh->prepare($query);
564 $sth->execute($qbiblio,$borr,$resdate);
565 ($priority) = $sth->fetchrow_array;
569 # update the database...
571 my $query = "UPDATE reserves SET found = 'F',
573 WHERE biblionumber = ?
575 AND borrowernumber = ?";
576 my $sth = $dbh->prepare($query);
577 $sth->execute($qbiblio,$resdate,$borr);
581 # now fix the priority on the others (if the priority wasn't
582 # already sorted!)....
583 unless ($priority == 0) {
584 fixpriority($priority, $biblio);
588 # Only used internally + reorder_reserve.pl
589 # Changed how this functions works #
590 # Now just gets an array of reserves in the rank order and updates them with
591 # the array index (+1 as array starts from 0)
592 # and if $rank is supplied will splice item from the array and splice it back in again
593 # in new priority rank
595 my ($biblio,$borrowernumber,$rank) = @_;
596 my $dbh = C4::Context->dbh;
598 warn "BIB: $biblio, BORR: $borrowernumber, RANK: $rank";
601 CancelReserve($biblio,undef,$borrowernumber);
603 if($rank eq "W" || $rank eq "0"){
604 # make sure priority for waiting items is 0
605 my $sth=$dbh->prepare("UPDATE reserves SET priority = 0
606 WHERE biblionumber = ?
607 AND borrowernumber = ?
608 AND cancellationdate is NULL
610 $sth->execute($biblio,$borrowernumber);
615 my $sth=$dbh->prepare("SELECT borrowernumber, reservedate, constrainttype FROM reserves
616 WHERE biblionumber = ?
617 AND cancellationdate is NULL
618 AND ((found <> 'F' and found <> 'W') or found is NULL) ORDER BY priority ASC");
619 $sth->execute($biblio);
620 while(my $line = $sth->fetchrow_hashref){
621 push(@reservedates,$line);
622 push(@priority,$line);
624 # To find the matching index
626 my $key = -1; # to allow for 0 to be a valid result
627 for ($i = 0; $i < @priority; $i++) {
628 if ($borrowernumber == $priority[$i]->{'borrowernumber'}) {
629 $key = $i; # save the index
634 # if index exists in array then move it to new position
635 if($key>-1 && $rank ne 'del' && $rank > 0){
636 my $new_rank = $rank-1; # $new_rank is what you want the new index to be in the array
637 my $moving_item = splice(@priority, $key, 1);
638 splice(@priority, $new_rank, 0, $moving_item);
640 # now fix the priority on those that are left....
641 for(my $j=0;$j<@priority;$j++){
642 # warn "update reserves set priority = ".($j+1)." where biblionumber = $biblio and borrowernumber = $priority[$j]->{'borrowernumber'} ";
643 # warn "and reservedate =$priority[$j]->{'reservedate'}";
644 my $sth = $dbh->prepare("UPDATE reserves SET priority = " . ($j+1 ) . "
645 WHERE biblionumber = ?
646 AND borrowernumber = ?
647 AND reservedate = ? and found is null");
648 $sth->execute($biblio,$priority[$j]->{'borrowernumber'},$priority[$j]->{'reservedate'});
655 my ($item, $borr) = @_;
656 my $dbh = C4::Context->dbh;
657 # get priority and biblionumber....
658 my $sth = $dbh->prepare("SELECT reserves.priority as priority,
659 reserves.biblionumber as biblionumber,
660 reserves.branchcode as branchcode,
661 reserves.timestamp as timestamp
663 WHERE reserves.biblionumber = items.biblionumber
664 AND items.itemnumber = ?
665 AND reserves.borrowernumber = ?
666 AND reserves.cancellationdate is NULL
667 AND (reserves.found <> 'F' or reserves.found is NULL)");
668 $sth->execute($item,$borr);
669 my $data = $sth->fetchrow_hashref;
671 my $biblio = $data->{'biblionumber'};
672 my $timestamp = $data->{'timestamp'};
673 # update reserves record....
674 $sth = $dbh->prepare("UPDATE reserves SET priority = 0, found = 'W', itemnumber = ?
675 WHERE borrowernumber = ?
678 $sth->execute($item,$borr,$biblio,$timestamp);
680 # now fix up the remaining priorities....
681 fixpriority($data->{'priority'}, $biblio);
682 my $branchcode = $data->{'branchcode'};
689 my $dbh = C4::Context->dbh;
691 my $sth = $dbh->prepare("SELECT * FROM reserves
692 WHERE borrowernumber = ?
693 AND reserves.found = 'W'
694 AND cancellationdate is NULL");
695 $sth->execute($borr);
696 while (my $data=$sth->fetchrow_hashref) {
697 push(@itemswaiting,$data);
700 return (scalar(@itemswaiting),\@itemswaiting);
703 =item Findgroupreserve
705 ($count, @results) = &Findgroupreserve($biblioitemnumber, $biblionumber);
707 I don't know what this does, because I don't understand how reserve
708 constraints work. I think the idea is that you reserve a particular
709 biblio, and the constraint allows you to restrict it to a given
710 biblioitem (e.g., if you want to borrow the audio book edition of "The
711 Prophet", rather than the first available publication).
713 C<&Findgroupreserve> returns a two-element array:
715 C<$count> is the number of elements in C<@results>.
717 C<@results> is an array of references-to-hash whose keys are mostly
718 fields from the reserves table of the Koha database, plus
723 sub Findgroupreserve {
724 my ($bibitem,$biblio)=@_;
725 my $dbh = C4::Context->dbh;
726 my $sth=$dbh->prepare("SELECT reserves.biblionumber AS biblionumber,
727 reserves.borrowernumber AS borrowernumber,
728 reserves.reservedate AS reservedate,
729 reserves.branchcode AS branchcode,
730 reserves.cancellationdate AS cancellationdate,
731 reserves.found AS found,
732 reserves.reservenotes AS reservenotes,
733 reserves.priority AS priority,
734 reserves.timestamp AS timestamp,
735 reserveconstraints.biblioitemnumber AS biblioitemnumber,
736 reserves.itemnumber AS itemnumber
737 FROM reserves LEFT JOIN reserveconstraints
738 ON reserves.biblionumber = reserveconstraints.biblionumber
739 WHERE reserves.biblionumber = ?
740 AND ( ( reserveconstraints.biblioitemnumber = ?
741 AND reserves.borrowernumber = reserveconstraints.borrowernumber
742 AND reserves.reservedate =reserveconstraints.reservedate )
743 OR reserves.constrainttype='a' )
744 AND reserves.cancellationdate is NULL
745 AND (reserves.found <> 'F' or reserves.found is NULL)");
746 $sth->execute($biblio, $bibitem);
748 while (my $data=$sth->fetchrow_hashref){
749 push(@results,$data);
752 return(scalar(@results),@results);
755 # FIXME - A somewhat different version of this function appears in
756 # C4::Reserves. Pick one and stick with it.
759 my ($env,$branch,$borrnum,$biblionumber,$constraint,$bibitems,$priority,$notes,$title,$checkitem,$found)= @_;
761 if($library_name =~ /Horowhenua/){
762 $fee = CalcHLTReserveFee($env,$borrnum,$biblionumber,$constraint,$bibitems);
764 $fee = CalcReserveFee($env,$borrnum,$biblionumber,$constraint,$bibitems);
766 my $dbh = C4::Context->dbh;
767 my $const = lc substr($constraint,0,1);
768 my @datearr = localtime(time);
769 my $resdate =(1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
771 # If the reserv had the waiting status, we had the value of the resdate
773 $waitingdate = $resdate;
776 # updates take place here
779 my $nextacctno = &getnextacctno($env,$borrnum,$dbh);
780 my $usth = $dbh->prepare("insert into accountlines
781 (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
783 (?,?,now(),?,?,'Res',?)");
784 $usth->execute($borrnum,$nextacctno,$fee,"Reserve Charge - $title",$fee);
788 my $sth = $dbh->prepare("insert into reserves
789 (borrowernumber,biblionumber,reservedate,branchcode,constrainttype,priority,reservenotes,itemnumber,found,waitingdate)
790 values (?,?,?,?,?,?,?,?,?,?)");
791 $sth->execute($borrnum,$biblionumber,$resdate,$branch,$const,$priority,$notes,$checkitem,$found,$waitingdate);
794 if (($const eq "o") || ($const eq "e")) {
795 my $numitems = @$bibitems;
797 while ($i < $numitems) {
798 my $biblioitem = @$bibitems[$i];
799 my $sth = $dbh->prepare("insert into
801 (borrowernumber,biblionumber,reservedate,biblioitemnumber)
803 $sth->execute($borrnum,$biblionumber,$resdate,$biblioitem);
812 # FIXME - A functionally identical version of this function appears in
813 # C4::Reserves. Pick one and stick with it.
814 # XXX - Internal use only
815 # FIXME - opac-reserves.pl need to use it, temporarily put into @EXPORT
817 my ($env,$borrnum,$biblionumber,$constraint,$bibitems) = @_;
819 my $dbh = C4::Context->dbh;
820 my $const = lc substr($constraint,0,1);
821 my $sth = $dbh->prepare("SELECT * FROM borrowers,categories
822 WHERE (borrowernumber = ?)
823 AND (borrowers.categorycode = categories.categorycode)");
824 $sth->execute($borrnum);
825 my $data = $sth->fetchrow_hashref;
827 my $fee = $data->{'reservefee'};
828 my $cntitems = @->$bibitems;
830 # check for items on issue
831 # first find biblioitem records
833 my $sth1 = $dbh->prepare("SELECT * FROM biblio,biblioitems
834 WHERE (biblio.biblionumber = ?)
835 AND (biblio.biblionumber = biblioitems.biblionumber)");
836 $sth1->execute($biblionumber);
837 while (my $data1=$sth1->fetchrow_hashref) {
839 push @biblioitems,$data1;
843 while ($x < $cntitems) {
844 if (@$bibitems->{'biblioitemnumber'} == $data->{'biblioitemnumber'}) {
851 push @biblioitems,$data1;
855 push @biblioitems,$data1;
861 my $cntitemsfound = @biblioitems;
865 while ($x < $cntitemsfound) {
866 my $bitdata = $biblioitems[$x];
867 my $sth2 = $dbh->prepare("SELECT * FROM items
868 WHERE biblioitemnumber = ?");
869 $sth2->execute($bitdata->{'biblioitemnumber'});
870 while (my $itdata=$sth2->fetchrow_hashref) {
871 my $sth3 = $dbh->prepare("SELECT * FROM issues
873 AND returndate IS NULL");
874 $sth3->execute($itdata->{'itemnumber'});
875 if (my $isdata=$sth3->fetchrow_hashref) {
882 if ($allissued == 0) {
883 my $rsth = $dbh->prepare("SELECT * FROM reserves WHERE biblionumber = ?");
884 $rsth->execute($biblionumber);
885 if (my $rdata = $rsth->fetchrow_hashref) {
895 # The following are junior and young adult item types that should not incur a
898 # Juniors: BJC, BJCN, BJF, BJK, BJM, BJN, BJP, BJSF, BJSN, DJ, DJP, FJ, JVID,
899 # VJ, VJP, PJ, TJ, TJP, VJ, VJP.
901 # Young adults: BYF, BYN, BYP, DY, DYP, PY, PYP, TY, TYP, VY, VYP.
903 # All other item types should incur a reserve charge.
904 sub CalcHLTReserveFee {
905 my ($env,$borrnum,$biblionumber,$constraint,$bibitems) = @_;
906 my $dbh = C4::Context->dbh;
907 my $sth = $dbh->prepare("SELECT * FROM borrowers,categories
908 WHERE (borrowernumber = ?)
909 AND (borrowers.categorycode = categories.categorycode)");
910 $sth->execute($borrnum);
911 my $data = $sth->fetchrow_hashref;
913 my $fee = $data->{'reservefee'};
916 my @nocharge = qw/BJC BJCN BJF BJK BJM BJN BJP BJSF BJSN DJ DJP FJ NJ CJ VJ VJP PJ TJ TJP BYF BYN BYP DY DYP PY PYP TY TYP VY VYP/;
917 my $sth = $dbh->prepare("SELECT * FROM biblio,biblioitems
918 WHERE (biblio.biblionumber = ?)
919 AND (biblio.biblionumber = biblioitems.biblionumber)");
920 $sth->execute($biblionumber);
921 my $data=$sth->fetchrow_hashref;
922 my $itemtype = $data->{'itemtype'};
923 for (my $i = 0; $i < @nocharge; $i++) {
924 if ($itemtype eq $nocharge[$i]) {
933 warn "BOB DEBUG: Fee is $fee";
941 my ($env,$bornumber,$dbh)=@_;
943 my $sth = $dbh->prepare("select * from accountlines
944 where (borrowernumber = ?)
945 order by accountno desc");
946 $sth->execute($bornumber);
947 if (my $accdata=$sth->fetchrow_hashref){
948 $nextaccntno = $accdata->{'accountno'} + 1;
951 return($nextaccntno);
956 #subroutine to update a reserve
957 my ($rank,$biblio,$borrower,$del,$branch)=@_;
958 my $dbh = C4::Context->dbh;
960 my $sth = $dbh->prepare("Update reserves set priority=?,branchcode=? where
961 biblionumber=? and borrowernumber=?");
962 $sth->execute($rank,$branch,$biblio,$borrower);
965 my $sth=$dbh->prepare("Select * from reserves where biblionumber=? and
967 $sth->execute($biblio,$borrower);
968 my $data=$sth->fetchrow_hashref;
970 $sth=$dbh->prepare("Select * from reserves where biblionumber=? and
971 priority > ? and cancellationdate is NULL
972 order by priority") || die $dbh->errstr;
973 $sth->execute($biblio,$data->{'priority'}) || die $sth->errstr;
974 while (my $data=$sth->fetchrow_hashref){
975 $data->{'priority'}--;
976 my $sth3=$dbh->prepare("Update reserves set priority=?
977 where biblionumber=? and borrowernumber=?");
978 $sth3->execute($data->{'priority'},$data->{'biblionumber'},$data->{'borrowernumber'}) || die $sth3->errstr;
982 $sth=$dbh->prepare("update reserves set cancellationdate=now() where biblionumber=?
983 and borrowernumber=?");
984 $sth->execute($biblio,$borrower);
991 #subroutine to update a reserve
992 my ($rank,$biblio,$borrower,$branch)=@_;
993 return if $rank eq "W";
994 return if $rank eq "n";
995 my $dbh = C4::Context->dbh;
996 if ($rank eq "del") {
997 my $sth=$dbh->prepare("UPDATE reserves SET cancellationdate=now()
998 WHERE biblionumber = ?
999 AND borrowernumber = ?
1000 AND cancellationdate is NULL
1001 AND (found <> 'F' or found is NULL)");
1002 $sth->execute($biblio, $borrower);
1005 my $sth=$dbh->prepare("UPDATE reserves SET priority = ? ,branchcode = ?, itemnumber = NULL, found = NULL
1006 WHERE biblionumber = ?
1007 AND borrowernumber = ?
1008 AND cancellationdate is NULL
1009 AND (found <> 'F' or found is NULL)");
1010 $sth->execute($rank, $branch, $biblio, $borrower);
1016 sub getreservetitle {
1017 my ($biblio,$bor,$date,$timestamp)=@_;
1018 my $dbh = C4::Context->dbh;
1019 my $sth=$dbh->prepare("Select * from reserveconstraints,biblioitems where
1020 reserveconstraints.biblioitemnumber=biblioitems.biblioitemnumber
1021 and reserveconstraints.biblionumber=? and reserveconstraints.borrowernumber
1022 = ? and reserveconstraints.reservedate=? and
1023 reserveconstraints.timestamp=?");
1024 $sth->execute($biblio,$bor,$date,$timestamp);
1025 my $data=$sth->fetchrow_hashref;