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
31 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
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
78 # make all your functions, whether exported or not;
80 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
86 my ($itemnumber,$borrowernumber)=@_;
88 # step 1 : cancel the reservation
89 my $CancelReserve = CancelReserve(0,$itemnumber,$borrowernumber);
91 # step 2 launch the subroutine of the others reserves
92 my ($messages,$nextreservinfo) = OtherReserves($itemnumber);
94 return ($messages,$nextreservinfo);
98 New op dev: check queued list of this document and check if this document must be transfered
105 my ($restype,$checkreserves) = CheckReserves($itemnumber);
108 my $iteminfo = C4::Circulation::Circ2::getiteminformation(\%env,$itemnumber);
109 if ($iteminfo->{'holdingbranch'} ne $checkreserves->{'branchcode'}){
110 $messages->{'transfert'} = $checkreserves->{'branchcode'};
112 # minus priorities of others reservs
113 MinusPriority($itemnumber,$checkreserves->{'borrowernumber'},$iteminfo->{'biblionumber'});
114 # launch the subroutine dotransfer
115 C4::Circulation::Circ2::dotransfer($itemnumber,$iteminfo->{'holdingbranch'},$checkreserves->{'branchcode'}),
118 # step 2b : case of a reservation on the same branch, set the waiting status
120 $messages->{'waiting'} = 1;
121 MinusPriority($itemnumber,$checkreserves->{'borrowernumber'},$iteminfo->{'biblionumber'});
122 SetWaitingStatus($itemnumber);
125 $nextreservinfo = $checkreserves->{'borrowernumber'};
128 return ($messages,$nextreservinfo);
132 Reduce the values of queuded list
136 my ($itemnumber,$borrowernumber,$biblionumber)=@_;
137 # first step update the value of the first person on reserv
138 my $dbh = C4::Context->dbh;
139 my $sth_upd=$dbh->prepare("UPDATE reserves SET priority = 0 , itemnumber = ?
140 WHERE cancellationdate is NULL
142 AND biblionumber=?");
143 $sth_upd->execute($itemnumber,$borrowernumber,$biblionumber);
146 # second step update all others reservs
147 my $sth_oth=$dbh->prepare("SELECT priority,borrowernumber,biblionumber,reservedate FROM reserves WHERE priority !='0' AND cancellationdate is NULL");
149 while (my ($priority,$borrowernumber,$biblionumber,$reservedate)=$sth_oth->fetchrow_array){
151 my $sth_upd_oth = $dbh->prepare("UPDATE reserves SET priority = ?
152 WHERE biblionumber = ?
153 AND borrowernumber = ?
154 AND reservedate = ?");
155 $sth_upd_oth->execute($priority,$biblionumber,$borrowernumber,$reservedate);
156 $sth_upd_oth->finish;
164 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
168 # 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
169 sub SetWaitingStatus{
170 # first : check if we have a reservation for this item .
172 my $dbh = C4::Context->dbh;
173 my $sth_find=$dbh->prepare("SELECT priority,borrowernumber from reserves WHERE itemnumber=? and cancellationdate is NULL and found is NULL and priority='0'");
174 $sth_find->execute($itemnumber);
175 my ($priority,$borrowernumber) = $sth_find->fetchrow_array;
177 if (not $borrowernumber){
181 # step 2 : if we have a borrowernumber, we update the value found to 'W' for notify the borrower
182 my $sth_set=$dbh->prepare("UPDATE reserves SET found='W',waitingdate = now() where borrowernumber=? AND itemnumber=? AND found is null");
183 $sth_set->execute($borrowernumber,$itemnumber);
189 sub FastFindReserves {
190 my ($itemnumber,$borrowernumber)=@_;
192 my $dbh = C4::Context->dbh;
193 my $sth_res=$dbh->prepare("SELECT reservedate,borrowernumber from reserves WHERE itemnumber=? and cancellationdate is NULL AND (found != 'F' or found is null)");
194 $sth_res->execute($itemnumber);
195 my ($reservedate,$borrowernumber)=$sth_res->fetchrow_array;
197 return($reservedate,$borrowernumber);
199 if ($borrowernumber){
200 my $dbh = C4::Context->dbh;
201 my $sth_find=$dbh->prepare("SELECT * from reserves WHERE borrowernumber=? and cancellationdate is NULL and (found != 'F' or found is null) order by reservedate");
202 $sth_find->execute($borrowernumber);
205 while (my $data=$sth_find->fetchrow_hashref){
206 $borrowerreserv[$i]=$data;
210 return (@borrowerreserv);
219 ($count, $results) = &FindReserves($biblionumber, $borrowernumber);
221 Looks books up in the reserves. C<$biblionumber> is the biblionumber
222 of the book to look up. C<$borrowernumber> is the borrower number of a
223 patron whose books to look up.
225 Either C<$biblionumber> or C<$borrowernumber> may be the empty string,
226 but not both. If both are specified, C<&FindReserves> looks up the
227 given book for the given patron. If only C<$biblionumber> is
228 specified, C<&FindReserves> looks up that book for all patrons. If
229 only C<$borrowernumber> is specified, C<&FindReserves> looks up all of
230 that patron's reserves. If neither is specified, C<&FindReserves>
233 For each book thus found, C<&FindReserves> checks the reserve
234 constraints and does something I don't understand.
236 C<&FindReserves> returns a two-element array:
238 C<$count> is the number of elements in C<$results>.
240 C<$results> is a reference to an array of references of hashes. Each hash
241 has for keys a list of column from reserves table (see details in function).
246 my ($bib, $bor) = @_;
247 my $dbh = C4::Context->dbh;
250 # Find the desired items in the reserves
253 timestamp AS rtimestamp,
261 WHERE cancellationdate IS NULL
262 AND (found <> \'F\' OR found IS NULL)
274 AND borrowernumber = ?
282 my $sth=$dbh->prepare($query);
283 $sth->execute(@bind);
285 while (my $data = $sth->fetchrow_hashref){
286 # FIXME - What is this if-statement doing? How do constraints work?
287 if ($data->{constrainttype} eq 'o') {
289 SELECT biblioitemnumber
290 FROM reserveconstraints
291 WHERE biblionumber = ?
292 AND borrowernumber = ?
295 my $csth=$dbh->prepare($query);
297 $data->{biblionumber},
298 $data->{borrowernumber},
299 $data->{reservedate},
301 my ($bibitemno) = $csth->fetchrow_array;
303 # Look up the book we just found.
304 my $bdata = bibitemdata($bibitemno);
305 # Add the results of this latest search to the current
307 # FIXME - An 'each' would probably be more efficient.
308 foreach my $key (keys %$bdata) {
309 $data->{$key} = $bdata->{$key};
312 push @results, $data;
316 return($#results+1,\@results);
319 sub GetNumberReservesFromBorrower {
320 my ($borrowernumber) = @_;
322 my $dbh = C4::Context->dbh;
325 SELECT COUNT(*) AS counter
327 WHERE borrowernumber = ?
328 AND cancellationdate IS NULL
329 AND (found != \'F\' OR found IS NULL)
331 my $sth = $dbh->prepare($query);
332 $sth->execute($borrowernumber);
333 my $row = $sth->fetchrow_hashref;
336 return $row->{counter};
339 sub GetFirstReserveDateFromItem {
340 my ($itemnumber) = @_;
342 my $dbh = C4::Context->dbh;
348 AND cancellationdate IS NULL
349 AND (found != \'F\' OR found IS NULL)
351 my $sth = $dbh->prepare($query);
352 $sth->execute($itemnumber);
353 my $row = $sth->fetchrow_hashref;
356 return $row->{reservedate};
361 ($status, $reserve) = &CheckReserves($itemnumber, $barcode);
363 Find a book in the reserves.
365 C<$itemnumber> is the book's item number. C<$barcode> is its barcode.
366 Either one, but not both, may be false. If both are specified,
367 C<&CheckReserves> uses C<$itemnumber>.
369 $itemnubmer can be false, in which case uses the barcode. (Never uses
370 both. $itemnumber gets priority).
372 As I understand it, C<&CheckReserves> looks for the given item in the
373 reserves. If it is found, that's a match, and C<$status> is set to
376 Otherwise, it finds the most important item in the reserves with the
377 same biblio number as this book (I'm not clear on this) and returns it
378 with C<$status> set to C<Reserved>.
380 C<&CheckReserves> returns a two-element list:
382 C<$status> is either C<Waiting>, C<Reserved> (see above), or 0.
384 C<$reserve> is the reserve item that matched. It is a
385 reference-to-hash whose keys are mostly the fields of the reserves
386 table in the Koha database.
391 my ($item, $barcode) = @_;
392 # warn "In CheckReserves: itemnumber = $item";
393 my $dbh = C4::Context->dbh;
396 my $qitem=$dbh->quote($item);
397 # Look up the item by itemnumber
398 $sth=$dbh->prepare("SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan
399 FROM items, biblioitems, itemtypes
400 WHERE items.biblioitemnumber = biblioitems.biblioitemnumber
401 AND biblioitems.itemtype = itemtypes.itemtype
402 AND itemnumber=$qitem");
404 my $qbc=$dbh->quote($barcode);
405 # Look up the item by barcode
406 $sth=$dbh->prepare("SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan
407 FROM items, biblioitems, itemtypes
408 WHERE items.biblioitemnumber = biblioitems.biblioitemnumber
409 AND biblioitems.itemtype = itemtypes.itemtype
411 # FIXME - This function uses $item later on. Ought to set it here.
414 my ($biblio, $bibitem, $notforloan) = $sth->fetchrow_array;
416 # if item is not for loan it cannot be reserved either.....
417 return (0, 0) if ($notforloan);
418 # get the reserves...
419 # Find this item in the reserves
420 my ($count, @reserves) = Findgroupreserve($bibitem, $biblio);
421 # $priority and $highest are used to find the most important item
422 # in the list returned by &Findgroupreserve. (The lower $priority,
423 # the more important the item.)
424 # $highest is the most important item we've seen so far.
425 my $priority = 10000000;
428 foreach my $res (@reserves) {
429 # FIXME - $item might be undefined or empty: the caller
430 # might be searching by barcode.
431 if ($res->{'itemnumber'} == $item) {
433 return ("Waiting", $res);
435 # See if this item is more important than what we've got
437 if ($res->{'priority'} != 0 && $res->{'priority'} < $priority) {
438 $priority = $res->{'priority'};
445 # If we get this far, then no exact match was found. Print the
446 # most important item on the list. I think this tells us who's
447 # next in line to get this book.
448 if ($highest) { # FIXME - $highest might be undefined
449 $highest->{'itemnumber'} = $item;
450 return ("Reserved", $highest);
458 &CancelReserve($biblionumber, $itemnumber, $borrowernumber);
462 Use either C<$biblionumber> or C<$itemnumber> to specify the item to
463 cancel, but not both: if both are given, C<&CancelReserve> does
466 C<$borrowernumber> is the borrower number of the patron on whose
467 behalf the book was reserved.
469 If C<$biblionumber> was given, C<&CancelReserve> also adjusts the
470 priorities of the other people who are waiting on the book.
475 my ($biblio, $item, $borr) = @_;
476 my $dbh = C4::Context->dbh;
477 #warn "In CancelReserve";
478 if (($item and $borr) and (not $biblio)) {
479 # removing a waiting reserve record....
480 # update the database...
481 my $sth = $dbh->prepare("update reserves set cancellationdate = now(),
485 and borrowernumber = ?");
486 $sth->execute($item,$borr);
489 if (($biblio and $borr) and (not $item)) {
490 # removing a reserve record....
491 # get the prioritiy on this record....
493 my $sth=$dbh->prepare("SELECT priority FROM reserves
494 WHERE biblionumber = ?
495 AND borrowernumber = ?
496 AND cancellationdate is NULL
497 AND (found <> 'F' or found is NULL)");
498 $sth->execute($biblio,$borr);
499 ($priority) = $sth->fetchrow_array;
502 # update the database, removing the record...
503 $sth = $dbh->prepare("update reserves set cancellationdate = now(),
506 where biblionumber = ?
507 and borrowernumber = ?
508 and cancellationdate is NULL
509 and (found <> 'F' or found is NULL)");
510 $sth->execute($biblio,$borr);
512 # now fix the priority on the others....
513 fixpriority($priority, $biblio);
519 &FillReserve($reserve);
521 Fill a reserve. If I understand this correctly, this means that the
522 reserved book has been found and given to the patron who reserved it.
524 C<$reserve> specifies the reserve to fill. It is a reference-to-hash
525 whose keys are fields from the reserves table in the Koha database.
531 my $dbh = C4::Context->dbh;
533 # fill in a reserve record....
534 # FIXME - Remove some of the redundancy here
535 my $biblio = $res->{'biblionumber'}; my $qbiblio =$biblio;
536 my $borr = $res->{'borrowernumber'};
537 my $resdate = $res->{'reservedate'};
539 # get the priority on this record....
542 my $query = "SELECT priority FROM reserves
543 WHERE biblionumber = ?
544 AND borrowernumber = ?
545 AND reservedate = ?";
546 my $sth=$dbh->prepare($query);
547 $sth->execute($qbiblio,$borr,$resdate);
548 ($priority) = $sth->fetchrow_array;
552 # update the database...
554 my $query = "UPDATE reserves SET found = 'F',
556 WHERE biblionumber = ?
558 AND borrowernumber = ?";
559 my $sth = $dbh->prepare($query);
560 $sth->execute($qbiblio,$resdate,$borr);
564 # now fix the priority on the others (if the priority wasn't
565 # already sorted!)....
566 unless ($priority == 0) {
567 fixpriority($priority, $biblio);
571 # Only used internally
572 # Decrements (makes more important) the reserves for all of the
573 # entries waiting on the given book, if their priority is > $priority.
575 my ($priority, $biblio) = @_;
576 my $dbh = C4::Context->dbh;
577 my ($count, $reserves) = FindReserves($biblio);
578 foreach my $rec (@$reserves) {
579 if ($rec->{'priority'} > $priority) {
580 my $sth = $dbh->prepare("UPDATE reserves SET priority = ?
581 WHERE biblionumber = ?
582 AND borrowernumber = ?
583 AND reservedate = ?");
584 $sth->execute($rec->{'priority'},$rec->{'biblionumber'},$rec->{'borrowernumber'},$rec->{'reservedate'});
592 my ($item, $borr) = @_;
593 my $dbh = C4::Context->dbh;
594 # get priority and biblionumber....
595 my $sth = $dbh->prepare("SELECT reserves.priority as priority,
596 reserves.biblionumber as biblionumber,
597 reserves.branchcode as branchcode,
598 reserves.timestamp as timestamp
600 WHERE reserves.biblionumber = items.biblionumber
601 AND items.itemnumber = ?
602 AND reserves.borrowernumber = ?
603 AND reserves.cancellationdate is NULL
604 AND (reserves.found <> 'F' or reserves.found is NULL)");
605 $sth->execute($item,$borr);
606 my $data = $sth->fetchrow_hashref;
608 my $biblio = $data->{'biblionumber'};
609 my $timestamp = $data->{'timestamp'};
610 # update reserves record....
611 $sth = $dbh->prepare("UPDATE reserves SET priority = 0, found = 'W', itemnumber = ?
612 WHERE borrowernumber = ?
615 $sth->execute($item,$borr,$biblio,$timestamp);
617 # now fix up the remaining priorities....
618 fixpriority($data->{'priority'}, $biblio);
619 my $branchcode = $data->{'branchcode'};
626 my $dbh = C4::Context->dbh;
628 my $sth = $dbh->prepare("SELECT * FROM reserves
629 WHERE borrowernumber = ?
630 AND reserves.found = 'W'
631 AND cancellationdate is NULL");
632 $sth->execute($borr);
633 while (my $data=$sth->fetchrow_hashref) {
634 push(@itemswaiting,$data);
637 return (scalar(@itemswaiting),\@itemswaiting);
640 =item Findgroupreserve
642 ($count, @results) = &Findgroupreserve($biblioitemnumber, $biblionumber);
644 I don't know what this does, because I don't understand how reserve
645 constraints work. I think the idea is that you reserve a particular
646 biblio, and the constraint allows you to restrict it to a given
647 biblioitem (e.g., if you want to borrow the audio book edition of "The
648 Prophet", rather than the first available publication).
650 C<&Findgroupreserve> returns a two-element array:
652 C<$count> is the number of elements in C<@results>.
654 C<@results> is an array of references-to-hash whose keys are mostly
655 fields from the reserves table of the Koha database, plus
660 sub Findgroupreserve {
661 my ($bibitem,$biblio)=@_;
662 my $dbh = C4::Context->dbh;
663 my $sth=$dbh->prepare("SELECT reserves.biblionumber AS biblionumber,
664 reserves.borrowernumber AS borrowernumber,
665 reserves.reservedate AS reservedate,
666 reserves.branchcode AS branchcode,
667 reserves.cancellationdate AS cancellationdate,
668 reserves.found AS found,
669 reserves.reservenotes AS reservenotes,
670 reserves.priority AS priority,
671 reserves.timestamp AS timestamp,
672 reserveconstraints.biblioitemnumber AS biblioitemnumber,
673 reserves.itemnumber AS itemnumber
674 FROM reserves LEFT JOIN reserveconstraints
675 ON reserves.biblionumber = reserveconstraints.biblionumber
676 WHERE reserves.biblionumber = ?
677 AND ( ( reserveconstraints.biblioitemnumber = ?
678 AND reserves.borrowernumber = reserveconstraints.borrowernumber
679 AND reserves.reservedate =reserveconstraints.reservedate )
680 OR reserves.constrainttype='a' )
681 AND reserves.cancellationdate is NULL
682 AND (reserves.found <> 'F' or reserves.found is NULL)");
683 $sth->execute($biblio, $bibitem);
685 while (my $data=$sth->fetchrow_hashref){
686 push(@results,$data);
689 return(scalar(@results),@results);
692 # FIXME - A somewhat different version of this function appears in
693 # C4::Reserves. Pick one and stick with it.
696 my ($env,$branch,$borrnum,$biblionumber,$constraint,$bibitems,$priority,$notes,$title,$checkitem,$found)= @_;
697 my $fee=CalcReserveFee($env,$borrnum,$biblionumber,$constraint,$bibitems);
698 my $dbh = C4::Context->dbh;
699 my $const = lc substr($constraint,0,1);
700 my @datearr = localtime(time);
701 my $resdate =(1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
703 # If the reserv had the waiting status, we had the value of the resdate
705 $waitingdate = $resdate;
708 # updates take place here
711 my $nextacctno = &getnextacctno($env,$borrnum,$dbh);
712 my $usth = $dbh->prepare("insert into accountlines
713 (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
715 (?,?,now(),?,?,'Res',?)");
716 $usth->execute($borrnum,$nextacctno,$fee,"Reserve Charge - $title",$fee);
720 my $sth = $dbh->prepare("insert into reserves
721 (borrowernumber,biblionumber,reservedate,branchcode,constrainttype,priority,reservenotes,itemnumber,found,waitingdate)
722 values (?,?,?,?,?,?,?,?,?,?)");
723 $sth->execute($borrnum,$biblionumber,$resdate,$branch,$const,$priority,$notes,$checkitem,$found,$waitingdate);
726 if (($const eq "o") || ($const eq "e")) {
727 my $numitems = @$bibitems;
729 while ($i < $numitems) {
730 my $biblioitem = @$bibitems[$i];
731 my $sth = $dbh->prepare("insert into
733 (borrowernumber,biblionumber,reservedate,biblioitemnumber)
735 $sth->execute($borrnum,$biblionumber,$resdate,$biblioitem);
744 # FIXME - A functionally identical version of this function appears in
745 # C4::Reserves. Pick one and stick with it.
746 # XXX - Internal use only
747 # FIXME - opac-reserves.pl need to use it, temporarily put into @EXPORT
749 my ($env,$borrnum,$biblionumber,$constraint,$bibitems) = @_;
751 my $dbh = C4::Context->dbh;
752 my $const = lc substr($constraint,0,1);
753 my $sth = $dbh->prepare("SELECT * FROM borrowers,categories
754 WHERE (borrowernumber = ?)
755 AND (borrowers.categorycode = categories.categorycode)");
756 $sth->execute($borrnum);
757 my $data = $sth->fetchrow_hashref;
759 my $fee = $data->{'reservefee'};
760 my $cntitems = @->$bibitems;
762 # check for items on issue
763 # first find biblioitem records
765 my $sth1 = $dbh->prepare("SELECT * FROM biblio,biblioitems
766 WHERE (biblio.biblionumber = ?)
767 AND (biblio.biblionumber = biblioitems.biblionumber)");
768 $sth1->execute($biblionumber);
769 while (my $data1=$sth1->fetchrow_hashref) {
771 push @biblioitems,$data1;
775 while ($x < $cntitems) {
776 if (@$bibitems->{'biblioitemnumber'} == $data->{'biblioitemnumber'}) {
783 push @biblioitems,$data1;
787 push @biblioitems,$data1;
793 my $cntitemsfound = @biblioitems;
797 while ($x < $cntitemsfound) {
798 my $bitdata = $biblioitems[$x];
799 my $sth2 = $dbh->prepare("SELECT * FROM items
800 WHERE biblioitemnumber = ?");
801 $sth2->execute($bitdata->{'biblioitemnumber'});
802 while (my $itdata=$sth2->fetchrow_hashref) {
803 my $sth3 = $dbh->prepare("SELECT * FROM issues
805 AND returndate IS NULL");
806 $sth3->execute($itdata->{'itemnumber'});
807 if (my $isdata=$sth3->fetchrow_hashref) {
814 if ($allissued == 0) {
815 my $rsth = $dbh->prepare("SELECT * FROM reserves WHERE biblionumber = ?");
816 $rsth->execute($biblionumber);
817 if (my $rdata = $rsth->fetchrow_hashref) {
829 my ($env,$bornumber,$dbh)=@_;
831 my $sth = $dbh->prepare("select * from accountlines
832 where (borrowernumber = ?)
833 order by accountno desc");
834 $sth->execute($bornumber);
835 if (my $accdata=$sth->fetchrow_hashref){
836 $nextaccntno = $accdata->{'accountno'} + 1;
839 return($nextaccntno);
844 #subroutine to update a reserve
845 my ($rank,$biblio,$borrower,$del,$branch)=@_;
846 my $dbh = C4::Context->dbh;
848 my $sth = $dbh->prepare("Update reserves set priority=?,branchcode=? where
849 biblionumber=? and borrowernumber=?");
850 $sth->execute($rank,$branch,$biblio,$borrower);
853 my $sth=$dbh->prepare("Select * from reserves where biblionumber=? and
855 $sth->execute($biblio,$borrower);
856 my $data=$sth->fetchrow_hashref;
858 $sth=$dbh->prepare("Select * from reserves where biblionumber=? and
859 priority > ? and cancellationdate is NULL
860 order by priority") || die $dbh->errstr;
861 $sth->execute($biblio,$data->{'priority'}) || die $sth->errstr;
862 while (my $data=$sth->fetchrow_hashref){
863 $data->{'priority'}--;
864 my $sth3=$dbh->prepare("Update reserves set priority=?
865 where biblionumber=? and borrowernumber=?");
866 $sth3->execute($data->{'priority'},$data->{'biblionumber'},$data->{'borrowernumber'}) || die $sth3->errstr;
870 $sth=$dbh->prepare("update reserves set cancellationdate=now() where biblionumber=?
871 and borrowernumber=?");
872 $sth->execute($biblio,$borrower);
879 #subroutine to update a reserve
880 my ($rank,$biblio,$borrower,$branch)=@_;
881 return if $rank eq "W";
882 return if $rank eq "n";
883 my $dbh = C4::Context->dbh;
884 if ($rank eq "del") {
885 my $sth=$dbh->prepare("UPDATE reserves SET cancellationdate=now()
886 WHERE biblionumber = ?
887 AND borrowernumber = ?
888 AND cancellationdate is NULL
889 AND (found <> 'F' or found is NULL)");
890 $sth->execute($biblio, $borrower);
893 my $sth=$dbh->prepare("UPDATE reserves SET priority = ? ,branchcode = ?, itemnumber = NULL, found = NULL
894 WHERE biblionumber = ?
895 AND borrowernumber = ?
896 AND cancellationdate is NULL
897 AND (found <> 'F' or found is NULL)");
898 $sth->execute($rank, $branch, $biblio, $borrower);
904 sub getreservetitle {
905 my ($biblio,$bor,$date,$timestamp)=@_;
906 my $dbh = C4::Context->dbh;
907 my $sth=$dbh->prepare("Select * from reserveconstraints,biblioitems where
908 reserveconstraints.biblioitemnumber=biblioitems.biblioitemnumber
909 and reserveconstraints.biblionumber=? and reserveconstraints.borrowernumber
910 = ? and reserveconstraints.reservedate=? and
911 reserveconstraints.timestamp=?");
912 $sth->execute($biblio,$bor,$date,$timestamp);
913 my $data=$sth->fetchrow_hashref;