fix for :
[koha.git] / C4 / Reserves2.pm
1 # -*- tab-width: 8 -*-
2 # NOTE: This file uses standard 8-character tabs
3
4 package C4::Reserves2;
5
6 # $Id$
7
8 # Copyright 2000-2002 Katipo Communications
9 #
10 # This file is part of Koha.
11 #
12 # Koha is free software; you can redistribute it and/or modify it under the
13 # terms of the GNU General Public License as published by the Free Software
14 # Foundation; either version 2 of the License, or (at your option) any later
15 # version.
16 #
17 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License along with
22 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23 # Suite 330, Boston, MA  02111-1307 USA
24
25 use strict;
26 require Exporter;
27 use DBI;
28 use C4::Context;
29 use C4::Search;
30         # FIXME - C4::Reserves2 uses C4::Search, which uses C4::Reserves2.
31         # So Perl complains that all of the functions here get redefined.
32 #use C4::Accounts;
33
34 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
35
36 # set the version for version checking
37 $VERSION = 0.01;
38
39 =head1 NAME
40
41 C4::Reserves2 - FIXME
42
43 =head1 SYNOPSIS
44
45   use C4::Reserves2;
46
47 =head1 DESCRIPTION
48
49 FIXME
50
51 =head1 FUNCTIONS
52
53 =over 2
54
55 =cut
56
57 @ISA = qw(Exporter);
58 # FIXME Take out CalcReserveFee after it can be removed from opac-reserves.pl
59 @EXPORT = qw(
60     &FindReserves
61     &CheckReserves
62     &CheckWaiting
63     &CancelReserve
64     &CalcReserveFee
65     &FillReserve
66     &ReserveWaiting
67     &CreateReserve
68     &updatereserves
69     &UpdateReserve
70     &getreservetitle
71     &Findgroupreserve
72 );
73
74 # make all your functions, whether exported or not;
75
76 =item FindReserves
77
78   ($count, $results) = &FindReserves($biblionumber, $borrowernumber);
79
80 Looks books up in the reserves. C<$biblionumber> is the biblionumber
81 of the book to look up. C<$borrowernumber> is the borrower number of a
82 patron whose books to look up.
83
84 Either C<$biblionumber> or C<$borrowernumber> may be the empty string,
85 but not both. If both are specified, C<&FindReserves> looks up the
86 given book for the given patron. If only C<$biblionumber> is
87 specified, C<&FindReserves> looks up that book for all patrons. If
88 only C<$borrowernumber> is specified, C<&FindReserves> looks up all of
89 that patron's reserves. If neither is specified, C<&FindReserves>
90 barfs.
91
92 For each book thus found, C<&FindReserves> checks the reserve
93 constraints and does something I don't understand.
94
95 C<&FindReserves> returns a two-element array:
96
97 C<$count> is the number of elements in C<$results>.
98
99 C<$results> is a reference-to-array; each element is a
100 reference-to-hash, whose keys are (I think) all of the fields of the
101 reserves, borrowers, and biblio tables of the Koha database.
102
103 =cut
104 #'
105 sub FindReserves {
106         my ($bib,$bor)=@_;
107         my $dbh = C4::Context->dbh;
108         # Find the desired items in the reserves
109         my $query="SELECT *,reserves.branchcode,biblio.title AS btitle, reserves.timestamp as rtimestamp FROM reserves,borrowers,biblio ";
110         # FIXME - These three bits of SQL seem to contain a fair amount of
111         # redundancy. Wouldn't it be better to have a @clauses array, add
112         # one or two clauses as necessary, then join(" AND ", @clauses) ?
113         # FIXME: not keen on quote() and interpolation either, but it looks safe
114         if ($bib ne ''){
115                 $bib = $dbh->quote($bib);
116                 if ($bor ne ''){
117                         # Both $bib and $bor specified
118                         # Find a particular book for a particular patron
119                         $bor = $dbh->quote($bor);
120                         $query .=  " where reserves.biblionumber   = $bib
121                                                 and borrowers.borrowernumber = $bor
122                                                 and reserves.borrowernumber = borrowers.borrowernumber
123                                                 and biblio.biblionumber     = $bib
124                                                 and cancellationdate is NULL
125                                                 and (found <> 'F' or found is NULL)";
126                 } else {
127                         # $bib specified, but not $bor
128                         # Find a particular book for all patrons
129                         $query .= " where reserves.borrowernumber = borrowers.borrowernumber
130                                         and biblio.biblionumber     = $bib
131                                         and reserves.biblionumber   = $bib
132                                         and cancellationdate is NULL
133                                         and (found <> 'F' or found is NULL)";
134                 }
135         } else {
136                 # FIXME - Check that $bor was given
137                 # No $bib given.
138                 # Find all books for the given patron.
139                 $query .= " where borrowers.borrowernumber = $bor
140                                         and reserves.borrowernumber  = borrowers.borrowernumber
141                                         and reserves.biblionumber    = biblio.biblionumber
142                                         and cancellationdate is NULL and
143                                         (found <> 'F' or found is NULL)";
144         }
145         $query.=" order by priority";
146         my $sth=$dbh->prepare($query);
147         $sth->execute;
148         my @results;
149         while (my $data=$sth->fetchrow_hashref){
150                 # FIXME - What is this if-statement doing? How do constraints work?
151                 if ($data->{'constrainttype'} eq 'o') {
152                         my $csth=$dbh->prepare("SELECT biblioitemnumber FROM reserveconstraints
153                                                         WHERE biblionumber   = ?
154                                                         AND borrowernumber = ?
155                                                         AND reservedate    = ?");
156                         $csth->execute($data->{'biblionumber'}, $data->{'borrowernumber'}, $data->{'reservedate'});
157                         my ($bibitemno) = $csth->fetchrow_array;
158                         $csth->finish;
159                         # Look up the book we just found.
160                         my $bdata = C4::Search::bibitemdata($bibitemno);
161                         # Add the results of this latest search to the current
162                         # results.
163                         # FIXME - An 'each' would probably be more efficient.
164                         foreach my $key (keys %$bdata) {
165                                 $data->{$key} = $bdata->{$key};
166                         }
167                 }
168                 push @results, $data;
169         }
170         $sth->finish;
171         return($#results+1,\@results);
172 }
173
174 =item CheckReserves
175
176   ($status, $reserve) = &CheckReserves($itemnumber, $barcode);
177
178 Find a book in the reserves.
179
180 C<$itemnumber> is the book's item number. C<$barcode> is its barcode.
181 Either one, but not both, may be false. If both are specified,
182 C<&CheckReserves> uses C<$itemnumber>.
183
184 $itemnubmer can be false, in which case uses the barcode. (Never uses
185 both. $itemnumber gets priority).
186
187 As I understand it, C<&CheckReserves> looks for the given item in the
188 reserves. If it is found, that's a match, and C<$status> is set to
189 C<Waiting>.
190
191 Otherwise, it finds the most important item in the reserves with the
192 same biblio number as this book (I'm not clear on this) and returns it
193 with C<$status> set to C<Reserved>.
194
195 C<&CheckReserves> returns a two-element list:
196
197 C<$status> is either C<Waiting>, C<Reserved> (see above), or 0.
198
199 C<$reserve> is the reserve item that matched. It is a
200 reference-to-hash whose keys are mostly the fields of the reserves
201 table in the Koha database.
202
203 =cut
204 #'
205 sub CheckReserves {
206     my ($item, $barcode) = @_;
207 #    warn "In CheckReserves: itemnumber = $item";
208     my $dbh = C4::Context->dbh;
209     my $sth;
210     if ($item) {
211         my $qitem=$dbh->quote($item);
212         # Look up the item by itemnumber
213         $sth=$dbh->prepare("SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan
214                              FROM items, biblioitems, itemtypes
215                             WHERE items.biblioitemnumber = biblioitems.biblioitemnumber
216                               AND biblioitems.itemtype = itemtypes.itemtype
217                               AND itemnumber=$qitem");
218     } else {
219         my $qbc=$dbh->quote($barcode);
220         # Look up the item by barcode
221         $sth=$dbh->prepare("SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan
222                              FROM items, biblioitems, itemtypes
223                             WHERE items.biblioitemnumber = biblioitems.biblioitemnumber
224                               AND biblioitems.itemtype = itemtypes.itemtype
225                               AND barcode=$qbc");
226         # FIXME - This function uses $item later on. Ought to set it here.
227     }
228     $sth->execute;
229     my ($biblio, $bibitem, $notforloan) = $sth->fetchrow_array;
230     $sth->finish;
231 # if item is not for loan it cannot be reserved either.....
232     return (0, 0) if ($notforloan);
233 # get the reserves...
234     # Find this item in the reserves
235     my ($count, @reserves) = Findgroupreserve($bibitem, $biblio);
236     # $priority and $highest are used to find the most important item
237     # in the list returned by &Findgroupreserve. (The lower $priority,
238     # the more important the item.)
239     # $highest is the most important item we've seen so far.
240     my $priority = 10000000;
241     my $highest;
242     if ($count) {
243         foreach my $res (@reserves) {
244             # FIXME - $item might be undefined or empty: the caller
245             # might be searching by barcode.
246             if ($res->{'itemnumber'} == $item) {
247                 # Found it
248                 return ("Waiting", $res);
249             } else {
250                 # See if this item is more important than what we've got
251                 # so far.
252                 if ($res->{'priority'} != 0 && $res->{'priority'} < $priority) {
253                     $priority = $res->{'priority'};
254                     $highest = $res;
255                 }
256             }
257         }
258     }
259
260     # If we get this far, then no exact match was found. Print the
261     # most important item on the list. I think this tells us who's
262     # next in line to get this book.
263     if ($highest) {     # FIXME - $highest might be undefined
264         $highest->{'itemnumber'} = $item;
265         return ("Reserved", $highest);
266     } else {
267         return (0, 0);
268     }
269 }
270
271 =item CancelReserve
272
273   &CancelReserve($biblionumber, $itemnumber, $borrowernumber);
274
275 Cancels a reserve.
276
277 Use either C<$biblionumber> or C<$itemnumber> to specify the item to
278 cancel, but not both: if both are given, C<&CancelReserve> does
279 nothing.
280
281 C<$borrowernumber> is the borrower number of the patron on whose
282 behalf the book was reserved.
283
284 If C<$biblionumber> was given, C<&CancelReserve> also adjusts the
285 priorities of the other people who are waiting on the book.
286
287 =cut
288 #'
289 sub CancelReserve {
290     my ($biblio, $item, $borr) = @_;
291     my $dbh = C4::Context->dbh;
292     #warn "In CancelReserve";
293     if (($item and $borr) and (not $biblio)) {
294                 # removing a waiting reserve record....
295                 # update the database...
296                 my $sth = $dbh->prepare("update reserves set cancellationdate = now(),
297                                                                                         found            = Null,
298                                                                                         priority         = 0
299                                                                         where itemnumber       = ?
300                                                                                 and borrowernumber   = ?");
301                 $sth->execute($item,$borr);
302                 $sth->finish;
303     }
304     if (($biblio and $borr) and (not $item)) {
305                 # removing a reserve record....
306                 # get the prioritiy on this record....
307                 my $priority;
308                 my $sth=$dbh->prepare("SELECT priority FROM reserves
309                                                                                 WHERE biblionumber   = ?
310                                                                                 AND borrowernumber = ?
311                                                                                 AND cancellationdate is NULL
312                                                                                 AND (found <> 'F' or found is NULL)");
313                 $sth->execute($biblio,$borr);
314                 ($priority) = $sth->fetchrow_array;
315                 $sth->finish;
316
317                 # update the database, removing the record...
318                 my $sth = $dbh->prepare("update reserves set cancellationdate = now(),
319                                                                                         found            = Null,
320                                                                                         priority         = 0
321                                                                         where biblionumber     = ?
322                                                                                 and borrowernumber   = ?
323                                                                                 and cancellationdate is NULL
324                                                                                 and (found <> 'F' or found is NULL)");
325                 $sth->execute($biblio,$borr);
326                 $sth->finish;
327                 # now fix the priority on the others....
328                 fixpriority($priority, $biblio);
329     }
330 }
331
332 =item FillReserve
333
334   &FillReserve($reserve);
335
336 Fill a reserve. If I understand this correctly, this means that the
337 reserved book has been found and given to the patron who reserved it.
338
339 C<$reserve> specifies the reserve to fill. It is a reference-to-hash
340 whose keys are fields from the reserves table in the Koha database.
341
342 =cut
343 #'
344 sub FillReserve {
345     my ($res) = @_;
346     my $dbh = C4::Context->dbh;
347
348     # fill in a reserve record....
349     # FIXME - Remove some of the redundancy here
350     my $biblio = $res->{'biblionumber'}; my $qbiblio =$biblio;
351     my $borr = $res->{'borrowernumber'}; 
352     my $resdate = $res->{'reservedate'}; 
353
354     # get the priority on this record....
355     my $priority;
356     {
357     my $query = "SELECT priority FROM reserves
358                                 WHERE biblionumber   = ?
359                                   AND borrowernumber = ?
360                                   AND reservedate    = ?";
361     my $sth=$dbh->prepare($query);
362     $sth->execute($qbiblio,$borr,$resdate);
363     ($priority) = $sth->fetchrow_array;
364     $sth->finish;
365     }
366
367     # update the database...
368     {
369     my $query = "UPDATE reserves SET found            = 'F',
370                                      priority         = 0
371                                WHERE biblionumber     = ?
372                                  AND reservedate      = ?
373                                  AND borrowernumber   = ?";
374     my $sth = $dbh->prepare($query);
375     $sth->execute($qbiblio,$resdate,$borr);
376     $sth->finish;
377     }
378
379     # now fix the priority on the others (if the priority wasn't
380     # already sorted!)....
381     unless ($priority == 0) {
382         fixpriority($priority, $biblio);
383     }
384 }
385
386 # Only used internally
387 # Decrements (makes more important) the reserves for all of the
388 # entries waiting on the given book, if their priority is > $priority.
389 sub fixpriority {
390     my ($priority, $biblio) =  @_;
391     my $dbh = C4::Context->dbh;
392     my ($count, $reserves) = FindReserves($biblio);
393     foreach my $rec (@$reserves) {
394         if ($rec->{'priority'} > $priority) {
395             my $sth = $dbh->prepare("UPDATE reserves SET priority = ?
396                                WHERE biblionumber     = ?
397                                  AND borrowernumber   = ?
398                                  AND reservedate      = ?");
399             $sth->execute($rec->{'priority'},$rec->{'biblionumber'},$rec->{'borrowernumber'},$rec->{'reservedate'});
400             $sth->finish;
401         }
402     }
403 }
404
405 # XXX - POD
406 sub ReserveWaiting {
407     my ($item, $borr) = @_;
408     my $dbh = C4::Context->dbh;
409 # get priority and biblionumber....
410     my $sth = $dbh->prepare("SELECT reserves.priority     as priority,
411                         reserves.biblionumber as biblionumber,
412                         reserves.branchcode   as branchcode,
413                         reserves.timestamp     as timestamp
414                       FROM reserves,items
415                      WHERE reserves.biblionumber   = items.biblionumber
416                        AND items.itemnumber        = ?
417                        AND reserves.borrowernumber = ?
418                        AND reserves.cancellationdate is NULL
419                        AND (reserves.found <> 'F' or reserves.found is NULL)");
420     $sth->execute($item,$borr);
421     my $data = $sth->fetchrow_hashref;
422     $sth->finish;
423     my $biblio = $data->{'biblionumber'};
424     my $timestamp = $data->{'timestamp'};
425 # update reserves record....
426     $sth = $dbh->prepare("UPDATE reserves SET priority = 0, found = 'W', itemnumber = ?
427                             WHERE borrowernumber = ?
428                               AND biblionumber = ?
429                               AND timestamp = ?");
430     $sth->execute($item,$borr,$biblio,$timestamp);
431     $sth->finish;
432 # now fix up the remaining priorities....
433     fixpriority($data->{'priority'}, $biblio);
434     my $branchcode = $data->{'branchcode'};
435     return $branchcode;
436 }
437
438 # XXX - POD
439 sub CheckWaiting {
440     my ($borr)=@_;
441     my $dbh = C4::Context->dbh;
442     my @itemswaiting;
443     my $sth = $dbh->prepare("SELECT * FROM reserves
444                          WHERE borrowernumber = ?
445                            AND reserves.found = 'W'
446                            AND cancellationdate is NULL");
447     $sth->execute($borr);
448     while (my $data=$sth->fetchrow_hashref) {
449           push(@itemswaiting,$data);
450     }
451     $sth->finish;
452     return (scalar(@itemswaiting),\@itemswaiting);
453 }
454
455 =item Findgroupreserve
456
457   ($count, @results) = &Findgroupreserve($biblioitemnumber, $biblionumber);
458
459 I don't know what this does, because I don't understand how reserve
460 constraints work. I think the idea is that you reserve a particular
461 biblio, and the constraint allows you to restrict it to a given
462 biblioitem (e.g., if you want to borrow the audio book edition of "The
463 Prophet", rather than the first available publication).
464
465 C<&Findgroupreserve> returns a two-element array:
466
467 C<$count> is the number of elements in C<@results>.
468
469 C<@results> is an array of references-to-hash whose keys are mostly
470 fields from the reserves table of the Koha database, plus
471 C<biblioitemnumber>.
472
473 =cut
474 #'
475 sub Findgroupreserve {
476   my ($bibitem,$biblio)=@_;
477   my $dbh = C4::Context->dbh;
478   my $sth=$dbh->prepare("SELECT reserves.biblionumber               AS biblionumber,
479                       reserves.borrowernumber             AS borrowernumber,
480                       reserves.reservedate                AS reservedate,
481                       reserves.branchcode                 AS branchcode,
482                       reserves.cancellationdate           AS cancellationdate,
483                       reserves.found                      AS found,
484                       reserves.reservenotes               AS reservenotes,
485                       reserves.priority                   AS priority,
486                       reserves.timestamp                  AS timestamp,
487                       reserveconstraints.biblioitemnumber AS biblioitemnumber,
488                       reserves.itemnumber                 AS itemnumber
489                  FROM reserves LEFT JOIN reserveconstraints
490                    ON reserves.biblionumber = reserveconstraints.biblionumber
491                 WHERE reserves.biblionumber = ?
492                   AND ( ( reserveconstraints.biblioitemnumber = ?
493                       AND reserves.borrowernumber = reserveconstraints.borrowernumber
494                       AND reserves.reservedate    =reserveconstraints.reservedate )
495                    OR reserves.constrainttype='a' )
496                   AND reserves.cancellationdate is NULL
497                   AND (reserves.found <> 'F' or reserves.found is NULL)");
498   $sth->execute($biblio, $bibitem);
499   my @results;
500   while (my $data=$sth->fetchrow_hashref){
501     push(@results,$data);
502   }
503   $sth->finish;
504   return(scalar(@results),@results);
505 }
506
507 # FIXME - A somewhat different version of this function appears in
508 # C4::Reserves. Pick one and stick with it.
509 # XXX - POD
510 sub CreateReserve {
511   my
512 ($env,$branch,$borrnum,$biblionumber,$constraint,$bibitems,$priority,$notes,$title)= @_;
513   my $fee=CalcReserveFee($env,$borrnum,$biblionumber,$constraint,$bibitems);
514   my $dbh = C4::Context->dbh;
515   my $const = lc substr($constraint,0,1);
516   my @datearr = localtime(time);
517   my $resdate =(1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
518   #eval {
519   # updates take place here
520   if ($fee > 0) {
521 #    print $fee;
522     my $nextacctno = &getnextacctno($env,$borrnum,$dbh);
523     my $usth = $dbh->prepare("insert into accountlines
524     (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
525                                                           values
526     (?,?,now(),?,?,'Res',?)");
527     $usth->execute($borrnum,$nextacctno,$fee,'Reserve Charge - $title',$fee);
528     $usth->finish;
529   }
530   #if ($const eq 'a'){
531     my $sth = $dbh->prepare("insert into reserves
532    (borrowernumber,biblionumber,reservedate,branchcode,constrainttype,priority,reservenotes)
533     values (?,?,?,?,?,?,?)");
534     $sth->execute($borrnum,$biblionumber,$resdate,$branch,$const,$priority,$notes);
535     $sth->finish;
536   #}
537   if (($const eq "o") || ($const eq "e")) {
538     my $numitems = @$bibitems;
539     my $i = 0;
540     while ($i < $numitems) {
541       my $biblioitem = @$bibitems[$i];
542       my $sth = $dbh->prepare("insert into
543       reserveconstraints
544       (borrowernumber,biblionumber,reservedate,biblioitemnumber)
545       values (?,?,?,?)");
546       $sth->execute($borrnum,$biblionumber,$resdate,$biblioitem);
547       $sth->finish;
548       $i++;
549     }
550   }
551 #  print $query;
552   return();
553 }
554
555 # FIXME - A functionally identical version of this function appears in
556 # C4::Reserves. Pick one and stick with it.
557 # XXX - Internal use only
558 # FIXME - opac-reserves.pl need to use it, temporarily put into @EXPORT
559 sub CalcReserveFee {
560   my ($env,$borrnum,$biblionumber,$constraint,$bibitems) = @_;
561   #check for issues;
562   my $dbh = C4::Context->dbh;
563   my $const = lc substr($constraint,0,1);
564   my $sth = $dbh->prepare("SELECT * FROM borrowers,categories
565                 WHERE (borrowernumber = ?)
566                   AND (borrowers.categorycode = categories.categorycode)");
567   $sth->execute($borrnum);
568   my $data = $sth->fetchrow_hashref;
569   $sth->finish();
570   my $fee = $data->{'reservefee'};
571   my $cntitems = @->$bibitems;
572   if ($fee > 0) {
573     # check for items on issue
574     # first find biblioitem records
575     my @biblioitems;
576     my $sth1 = $dbh->prepare("SELECT * FROM biblio,biblioitems
577                    WHERE (biblio.biblionumber = ?)
578                      AND (biblio.biblionumber = biblioitems.biblionumber)");
579     $sth1->execute($biblionumber);
580     while (my $data1=$sth1->fetchrow_hashref) {
581       if ($const eq "a") {
582         push @biblioitems,$data1;
583       } else {
584         my $found = 0;
585         my $x = 0;
586         while ($x < $cntitems) {
587           if (@$bibitems->{'biblioitemnumber'} == $data->{'biblioitemnumber'}) {
588             $found = 1;
589           }
590           $x++;
591         }
592         if ($const eq 'o') {
593           if ( $found == 1) {
594             push @biblioitems,$data1;
595           }
596         } else {
597           if ($found == 0) {
598             push @biblioitems,$data1;
599           }
600         }
601       }
602     }
603     $sth1->finish;
604     my $cntitemsfound = @biblioitems;
605     my $issues = 0;
606     my $x = 0;
607     my $allissued = 1;
608     while ($x < $cntitemsfound) {
609       my $bitdata = $biblioitems[$x];
610       my $sth2 = $dbh->prepare("SELECT * FROM items
611                      WHERE biblioitemnumber = ?");
612       $sth2->execute($bitdata->{'biblioitemnumber'});
613       while (my $itdata=$sth2->fetchrow_hashref) {
614         my $sth3 = $dbh->prepare("SELECT * FROM issues
615                        WHERE itemnumber = ?
616                          AND returndate IS NULL");
617         $sth3->execute($itdata->{'itemnumber'});
618         if (my $isdata=$sth3->fetchrow_hashref) {
619         } else {
620           $allissued = 0;
621         }
622       }
623       $x++;
624     }
625     if ($allissued == 0) {
626       my $rsth = $dbh->prepare("SELECT * FROM reserves WHERE biblionumber = ?");
627       $rsth->execute($biblionumber);
628       if (my $rdata = $rsth->fetchrow_hashref) {
629       } else {
630         $fee = 0;
631       }
632     }
633   }
634 #  print "fee $fee";
635   return $fee;
636 }
637
638 # XXX - Internal use
639 sub getnextacctno {
640   my ($env,$bornumber,$dbh)=@_;
641   my $nextaccntno = 1;
642   my $sth = $dbh->prepare("select * from accountlines
643   where (borrowernumber = ?)
644   order by accountno desc");
645   $sth->execute($bornumber);
646   if (my $accdata=$sth->fetchrow_hashref){
647     $nextaccntno = $accdata->{'accountno'} + 1;
648   }
649   $sth->finish;
650   return($nextaccntno);
651 }
652
653 # XXX - POD
654 sub updatereserves{
655   #subroutine to update a reserve
656   my ($rank,$biblio,$borrower,$del,$branch)=@_;
657   my $dbh = C4::Context->dbh;
658   if ($del == 0){
659     my $sth = $dbh->prepare("Update reserves set priority=?,branchcode=? where
660     biblionumber=? and borrowernumber=?");
661     $sth->execute($rank,$branch,$biblio,$borrower);
662     $sth->finish();
663   } else {
664     my $sth=$dbh->prepare("Select * from reserves where biblionumber=? and
665     borrowernumber=?");
666     $sth->execute($biblio,$borrower);
667     my $data=$sth->fetchrow_hashref;
668     $sth->finish();
669     $sth=$dbh->prepare("Select * from reserves where biblionumber=? and
670     priority > ? and cancellationdate is NULL
671     order by priority") || die $dbh->errstr;
672     $sth->execute($biblio,$data->{'priority'}) || die $sth->errstr;
673     while (my $data=$sth->fetchrow_hashref){
674       $data->{'priority'}--;
675       my $sth3=$dbh->prepare("Update reserves set priority=?
676       where biblionumber=? and borrowernumber=?");
677       $sth3->execute($data->{'priority'},$data->{'biblionumber'},$data->{'borrowernumber'}) || die $sth3->errstr;
678       $sth3->finish();
679     }
680     $sth->finish();
681     $sth=$dbh->prepare("update reserves set cancellationdate=now() where biblionumber=?
682     and borrowernumber=?");
683     $sth->execute($biblio,$borrower);
684     $sth->finish;
685   }
686 }
687
688 # XXX - POD
689 sub UpdateReserve {
690     #subroutine to update a reserve
691     my ($rank,$biblio,$borrower,$branch)=@_;
692     return if $rank eq "W";
693     return if $rank eq "n";
694     my $dbh = C4::Context->dbh;
695     if ($rank eq "del") {
696         my $sth=$dbh->prepare("UPDATE reserves SET cancellationdate=now()
697                                    WHERE biblionumber   = ?
698                                      AND borrowernumber = ?
699                                      AND cancellationdate is NULL
700                                      AND (found <> 'F' or found is NULL)");
701         $sth->execute($biblio, $borrower);
702         $sth->finish;
703     } else {
704         my $sth=$dbh->prepare("UPDATE reserves SET priority = ? ,branchcode = ?, itemnumber = NULL, found = NULL
705                                    WHERE biblionumber   = ?
706                                      AND borrowernumber = ?
707                                      AND cancellationdate is NULL
708                                      AND (found <> 'F' or found is NULL)");
709         $sth->execute($rank, $branch, $biblio, $borrower);
710         $sth->finish;
711     }
712 }
713
714 # XXX - POD
715 sub getreservetitle {
716  my ($biblio,$bor,$date,$timestamp)=@_;
717  my $dbh = C4::Context->dbh;
718  my $sth=$dbh->prepare("Select * from reserveconstraints,biblioitems where
719  reserveconstraints.biblioitemnumber=biblioitems.biblioitemnumber
720  and reserveconstraints.biblionumber=? and reserveconstraints.borrowernumber
721  = ? and reserveconstraints.reservedate=? and
722  reserveconstraints.timestamp=?");
723  $sth->execute($biblio,$bor,$date,$timestamp);
724  my $data=$sth->fetchrow_hashref;
725  $sth->finish;
726  return($data);
727 }