X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FReserves2.pm;h=5db1226fe20a1d4942ff4d11889ba05baa57200c;hb=83c378e2edf455be2b93b53759690c18c6968036;hp=fb31de210b8fafeda6d4d792b0dab167a932fc08;hpb=0e69a3906ea55acf81b982bbf440bd1cf0c7e7d9;p=koha.git diff --git a/C4/Reserves2.pm b/C4/Reserves2.pm index fb31de210b..5db1226fe2 100755 --- a/C4/Reserves2.pm +++ b/C4/Reserves2.pm @@ -1,531 +1,1394 @@ -package C4::Reserves2; #asummes C4/Reserves2 +# -*- tab-width: 8 -*- +# NOTE: This file uses standard 8-character tabs -#requires DBI.pm to be installed -#uses DBD:Pg +package C4::Reserves2; + +# Copyright 2000-2002 Katipo Communications +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +# $Id$ use strict; require Exporter; -use DBI; -use C4::Database; -#use C4::Accounts; +use C4::Context; +use C4::Biblio; +use C4::Search; +use C4::Circulation::Circ2; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); - +my $library_name = C4::Context->preference("LibraryName"); + # set the version for version checking -$VERSION = 0.01; - +$VERSION = do { my @v = '$Revision$' =~ /\d+/g; shift(@v) . "." . join( "_", map { sprintf "%03d", $_ } @v ); }; + +=head1 NAME + +C4::Reserves2 - Koha functions for dealing with reservation. + +=head1 SYNOPSIS + + use C4::Reserves2; + +=head1 DESCRIPTION + +this modules provides somes functions to deal with reservations. + +=head1 FUNCTIONS + +=over 2 + +=cut + @ISA = qw(Exporter); -@EXPORT = qw(&FindReserves &CheckReserves &CheckWaiting &CancelReserve &FillReserve &ReserveWaiting &CreateReserve &updatereserves &getreservetitle &Findgroupreserve); -%EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], - -# your exported package globals go here, -# as well as any optionally exported functions - -@EXPORT_OK = qw($Var1 %Hashit); - - -# non-exported package globals go here -use vars qw(@more $stuff); - -# initalize package globals, first exported ones - -my $Var1 = ''; -my %Hashit = (); - -# then the others (which are still accessible as $Some::Module::stuff) -my $stuff = ''; -my @more = (); - -# all file-scoped lexicals must be created before -# the functions below that use them. - -# file-private lexicals go here -my $priv_var = ''; -my %secret_hash = (); - -# here's a file-private function as a closure, -# callable as &$priv_func; it cannot be prototyped. -my $priv_func = sub { - # stuff goes here. -}; - + +# FIXME Take out CalcReserveFee after it can be removed from opac-reserves.pl +@EXPORT = qw( + &FindReserves + &CheckReserves + &GetWaitingReserves + &CancelReserve + &CalcReserveFee + &FillReserve + &ReserveWaiting + &CreateReserve + &UpdateReserve + &GetReserveTitle + &GetReservations + &SetWaitingStatus + &GlobalCancel + &MinusPriority + &OtherReserves + &GetFirstReserveDateFromItem + &CountReservesFromBorrower + &FixPriority + &FindReservesInQueue +); + # make all your functions, whether exported or not; +=item GlobalCancel + +($messages,$nextreservinfo) = &GlobalCancel($itemnumber,$borrowernumber); + + 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 + +=cut + +#' +sub GlobalCancel { + my $messages; + my $nextreservinfo; + my ( $itemnumber, $borrowernumber ) = @_; + + #step 1 : cancel the reservation + my $CancelReserve = CancelReserve( undef, $itemnumber, $borrowernumber ); + + #step 2 launch the subroutine of the others reserves + ( $messages, $nextreservinfo ) = OtherReserves($itemnumber); + + return ( $messages, $nextreservinfo ); +} + +=item OtherReserves + +($messages,$nextreservinfo)=$OtherReserves(itemnumber); + +Check queued list of this document and check if this document must be transfered + +=cut + +#' +sub OtherReserves { + my ($itemnumber) = @_; + my $messages; + my $nextreservinfo; + my ( $restype, $checkreserves ) = CheckReserves($itemnumber); + if ($checkreserves) { + my $iteminfo = C4::Circulation::Circ2::getiteminformation($itemnumber,undef); + if ( $iteminfo->{'holdingbranch'} ne $checkreserves->{'branchcode'} ) { + $messages->{'transfert'} = $checkreserves->{'branchcode'}; + #minus priorities of others reservs + MinusPriority( + $itemnumber, + $checkreserves->{'borrowernumber'}, + $iteminfo->{'biblionumber'} + ); + + #launch the subroutine dotransfer + C4::Circulation::Circ2::dotransfer( + $itemnumber, + $iteminfo->{'holdingbranch'}, + $checkreserves->{'branchcode'} + ), + ; + } + + #step 2b : case of a reservation on the same branch, set the waiting status + else { + $messages->{'waiting'} = 1; + MinusPriority( + $itemnumber, + $checkreserves->{'borrowernumber'}, + $iteminfo->{'biblionumber'} + ); + SetWaitingStatus($itemnumber); + } + + $nextreservinfo = $checkreserves->{'borrowernumber'}; + } + + return ( $messages, $nextreservinfo ); +} + +=item MinusPriority + +&MinusPriority($itemnumber,$borrowernumber,$biblionumber) + +Reduce the values of queuded list + +=cut + +#' +sub MinusPriority { + my ( $itemnumber, $borrowernumber, $biblionumber ) = @_; + + #first step update the value of the first person on reserv + my $dbh = C4::Context->dbh; + my $query = qq/ + UPDATE reserves + SET priority = 0 , itemnumber = ? + WHERE cancellationdate IS NULL + AND borrowernumber=? + AND biblionumber=? + /; + my $sth_upd = $dbh->prepare($query); + $sth_upd->execute( $itemnumber, $borrowernumber, $biblionumber ); + $sth_upd->finish; + # second step update all others reservs + $query = qq/ + SELECT priority,borrowernumber,biblionumber,reservedate + FROM reserves + WHERE priority !='0' + AND biblionumber = ? + AND cancellationdate IS NULL + /; + my $sth_oth = $dbh->prepare($query); + $sth_oth->execute($biblionumber); + while ( my ( $priority, $borrowernumber, $biblionumber, $reservedate ) = + $sth_oth->fetchrow_array ) + { + $priority--; + $query = qq/ + UPDATE reserves + SET priority = ? + WHERE biblionumber = ? + AND borrowernumber = ? + AND reservedate = ? + /; + my $sth_upd_oth = $dbh->prepare($query); + $sth_upd_oth->execute( $priority, $biblionumber, $borrowernumber, + $reservedate ); + $sth_upd_oth->finish; + } + $sth_oth->finish; +} + +=item SetWaitingStatus + +&SetWaitingStatus($itemnumber); + +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 + +=cut + +sub SetWaitingStatus { + + #first : check if we have a reservation for this item . + my ($itemnumber) = @_; + my $dbh = C4::Context->dbh; + my $query = qq/ + SELECT priority,borrowernumber + FROM reserves + WHERE itemnumber=? + AND cancellationdate IS NULL + AND found IS NULL AND priority='0' + /; + my $sth_find = $dbh->prepare($query); + $sth_find->execute($itemnumber); + my ( $priority, $borrowernumber ) = $sth_find->fetchrow_array; + $sth_find->finish; + return unless $borrowernumber; + +# step 2 : if we have a borrowernumber, we update the value found to 'W' to notify the borrower + $query = qq/ + UPDATE reserves + SET found='W',waitingdate = now() + WHERE borrowernumber=? + AND itemnumber=? + AND found IS NULL + /; + my $sth_set = $dbh->prepare($query); + $sth_set->execute( $borrowernumber, $itemnumber ); + $sth_set->finish; +} + +=item GetReservations + +@borrowerreserv=&GetReservations($itemnumber,$borrowernumber); + +this function get the list of reservation for an C<$itemnumber> or C<$borrowernumber> +given on input arg. You should give $itemnumber OR $borrowernumber but not both. + +=cut + +sub GetReservations { + my ( $itemnumber, $borrowernumber ) = @_; + if ($itemnumber) { + my $dbh = C4::Context->dbh; + my $query = qq/ + SELECT reservedate,borrowernumber + FROM reserves + WHERE itemnumber=? + AND cancellationdate IS NULL + AND (found <> 'F' OR found IS NULL) + /; + my $sth_res = $dbh->prepare($query); + $sth_res->execute($itemnumber); + my ( $reservedate, $borrowernumber ) = $sth_res->fetchrow_array; + return ( $reservedate, $borrowernumber ); + } + if ($borrowernumber) { + my $dbh = C4::Context->dbh; + my $query = qq/ + SELECT * + FROM reserves + WHERE borrowernumber=? + AND cancellationdate IS NULL + AND (found != 'F' or found is null) + ORDER BY reservedate + /; + + my $sth_find = $dbh->prepare($query); + $sth_find->execute($borrowernumber); + my @borrowerreserv; + while ( my $data = $sth_find->fetchrow_hashref ) { + push @borrowerreserv, $data; + } + return @borrowerreserv; + } +} + +=item FindReserves + + $results = &FindReserves($biblionumber, $borrowernumber); + +Looks books up in the reserves. C<$biblionumber> is the biblionumber +of the book to look up. C<$borrowernumber> is the borrower number of a +patron whose books to look up. + +Either C<$biblionumber> or C<$borrowernumber> may be the empty string, +but not both. If both are specified, C<&FindReserves> looks up the +given book for the given patron. If only C<$biblionumber> is +specified, C<&FindReserves> looks up that book for all patrons. If +only C<$borrowernumber> is specified, C<&FindReserves> looks up all of +that patron's reserves. If neither is specified, C<&FindReserves> +barfs. + +For each book thus found, C<&FindReserves> checks the reserve +constraints and does something I don't understand. + +C<&FindReserves> returns a two-element array: + +C<$results> is a reference to an array of references of hashes. Each hash +has for keys a list of column from reserves table (see details in function). + +=cut + +#' sub FindReserves { - my ($bib,$bor) = @_; - my $dbh = C4Connect; - my $query = "SELECT *,reserves.branchcode,biblio.title AS btitle - FROM reserves,borrowers,biblio "; - if ($bib ne ''){ - $bib = $dbh->quote($bib); - if ($bor ne ''){ - $bor = $dbh->quote($bor); - $query .= " where reserves.biblionumber = $bib - and borrowers.borrowernumber = $bor - and reserves.borrowernumber = borrowers.borrowernumber - and biblio.biblionumber = $bib - and cancellationdate is NULL - and (found <> 'F' or found is NULL)"; - } else { - $query .= " where reserves.borrowernumber = borrowers.borrowernumber - and biblio.biblionumber = $bib - and reserves.biblionumber = $bib - and cancellationdate is NULL - and (found <> 'F' or found is NULL)"; - } - } else { - $query .= " where borrowers.borrowernumber = $bor - and reserves.borrowernumber = borrowers.borrowernumber - and reserves.biblionumber = biblio.biblionumber - and cancellationdate is NULL and - (found <> 'F' or found is NULL)"; - } - $query.=" order by priority"; - my $sth=$dbh->prepare($query); - $sth->execute; - my $i=0; - my @results; - while (my $data=$sth->fetchrow_hashref){ - $results[$i]=$data; - $i++; - } -# print $query; - $sth->finish; - $dbh->disconnect; - return($i,\@results); + my ( $biblionumber, $bor ) = @_; + my $dbh = C4::Context->dbh; + my @bind; + + # Find the desired items in the reserves + my $query = qq/ + SELECT branchcode, + timestamp AS rtimestamp, + priority, + biblionumber, + borrowernumber, + reservedate, + constrainttype, + found, + itemnumber + FROM reserves + WHERE cancellationdate IS NULL + AND (found <> \'F\' OR found IS NULL) + /; + + if ( $biblionumber ne '' ) { + $query .= ' + AND biblionumber = ? + '; + push @bind, $biblionumber; + } + + if ( $bor ne '' ) { + $query .= ' + AND borrowernumber = ? + '; + push @bind, $bor; + } + + $query .= ' + ORDER BY priority + '; + my $sth = $dbh->prepare($query); + $sth->execute(@bind); + my @results; + my $i = 0; + while ( my $data = $sth->fetchrow_hashref ) { + + # FIXME - What is this if-statement doing? How do constraints work? + if ( $data->{constrainttype} eq 'o' ) { + $query = ' + SELECT biblioitemnumber + FROM reserveconstraints + WHERE biblionumber = ? + AND borrowernumber = ? + AND reservedate = ? + '; + my $csth = $dbh->prepare($query); + $csth->execute( $data->{biblionumber}, $data->{borrowernumber}, + $data->{reservedate}, ); + + my @bibitemno; + while ( my $bibitemnos = $csth->fetchrow_array ) { + push( @bibitemno, $bibitemnos ); + } + my $count = @bibitemno; + + # if we have two or more different specific itemtypes + # reserved by same person on same day + my $bdata; + if ( $count > 1 ) { + $bdata = GetBiblioItemData( $bibitemno[$i] ); + $i++; + } + else { + + # Look up the book we just found. + $bdata = GetBiblioItemData( $bibitemno[0] ); + } + $csth->finish; + + # Add the results of this latest search to the current + # results. + # FIXME - An 'each' would probably be more efficient. + foreach my $key ( keys %$bdata ) { + $data->{$key} = $bdata->{$key}; + } + } + push @results, $data; + } + $sth->finish; + + return ( $#results + 1, \@results ); +} + +#------------------------------------------------------------------------------------- + +=item CountReservesFromBorrower + +$number = &CountReservesFromBorrower($borrowernumber); + +this function returns the number of reservation for a borrower given on input arg. + +=cut + +sub CountReservesFromBorrower { + my ($borrowernumber) = @_; + + my $dbh = C4::Context->dbh; + + my $query = ' + SELECT COUNT(*) AS counter + FROM reserves + WHERE borrowernumber = ? + AND cancellationdate IS NULL + AND (found != \'F\' OR found IS NULL) + '; + my $sth = $dbh->prepare($query); + $sth->execute($borrowernumber); + my $row = $sth->fetchrow_hashref; + $sth->finish; + + return $row->{counter}; } +#------------------------------------------------------------------------------------- + +=item GetFirstReserveDateFromItem + +$date = GetFirstReserveDateFromItem($itemnumber) + +this function returns the first date a item has been reserved. + +=cut + +sub GetFirstReserveDateFromItem { + my ($itemnumber) = @_; + + my $dbh = C4::Context->dbh; + + my $query = ' + SELECT reservedate, + borrowernumber, + branchcode + FROM reserves + WHERE itemnumber = ? + AND cancellationdate IS NULL + AND (found != \'F\' OR found IS NULL) + '; + my $sth = $dbh->prepare($query); + $sth->execute($itemnumber); + my $row = $sth->fetchrow_hashref; + + return ($row->{reservedate},$row->{borrowernumber},$row->{branchcode}); +} + +#------------------------------------------------------------------------------------- + +=item CheckReserves + + ($status, $reserve) = &CheckReserves($itemnumber, $barcode); + +Find a book in the reserves. + +C<$itemnumber> is the book's item number. C<$barcode> is its barcode. +Either one, but not both, may be false. If both are specified, +C<&CheckReserves> uses C<$itemnumber>. + +$itemnubmer can be false, in which case uses the barcode. (Never uses +both. $itemnumber gets priority). + +As I understand it, C<&CheckReserves> looks for the given item in the +reserves. If it is found, that's a match, and C<$status> is set to +C. + +Otherwise, it finds the most important item in the reserves with the +same biblio number as this book (I'm not clear on this) and returns it +with C<$status> set to C. + +C<&CheckReserves> returns a two-element list: + +C<$status> is either C, C (see above), or 0. + +C<$reserve> is the reserve item that matched. It is a +reference-to-hash whose keys are mostly the fields of the reserves +table in the Koha database. + +=cut + +#' sub CheckReserves { - my ($item) = @_; - my $dbh=C4Connect; - my $qitem=$dbh->quote($item); -# get the biblionumber... - my $sth=$dbh->prepare("select biblionumber, biblioitemnumber from items where itemnumber=$qitem"); + my ( $item, $barcode ) = @_; + my $dbh = C4::Context->dbh; + my $sth; + if ($item) { + my $qitem = $dbh->quote($item); + # Look up the item by itemnumber + my $query = qq( + SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan + FROM items, biblioitems, itemtypes + WHERE items.biblioitemnumber = biblioitems.biblioitemnumber + AND biblioitems.itemtype = itemtypes.itemtype + AND itemnumber=$qitem + ); + $sth = $dbh->prepare($query); + } + else { + my $qbc = $dbh->quote($barcode); + # Look up the item by barcode + my $query = qq( + SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan + FROM items, biblioitems, itemtypes + WHERE items.biblioitemnumber = biblioitems.biblioitemnumber + AND biblioitems.itemtype = itemtypes.itemtype + AND barcode=$qbc + ); + $sth = $dbh->prepare($query); + + # FIXME - This function uses $item later on. Ought to set it here. + } $sth->execute; - my ($biblio, $bibitem) = $sth->fetchrow_array; + my ( $biblio, $bibitem, $notforloan ) = $sth->fetchrow_array; $sth->finish; - $dbh->disconnect; -# get the reserves... - my ($count, @reserves) = Findgroupreserve($bibitem, $biblio); - my $priority = 10000000; + + # if item is not for loan it cannot be reserved either..... + return ( 0, 0 ) if $notforloan; + + # get the reserves... + # Find this item in the reserves + my @reserves = Findgroupreserve( $bibitem, $biblio ); + my $count = scalar @reserves; + + # $priority and $highest are used to find the most important item + # in the list returned by &Findgroupreserve. (The lower $priority, + # the more important the item.) + # $highest is the most important item we've seen so far. + my $priority = 10000000; my $highest; if ($count) { - foreach my $res (@reserves) { - if ($res->{'itemnumber'} == $item) { - return ("Waiting", $res); - } else { - if ($res->{'priority'} < $priority) { - $priority = $res->{'priority'}; - $highest = $res; - } - } - } - $highest->{'itemnumber'} = $item; - return ("Reserved", $highest); - } else { - return (0, 0); + foreach my $res (@reserves) { + # FIXME - $item might be undefined or empty: the caller + # might be searching by barcode. + if ( $res->{'itemnumber'} == $item ) { + # Found it + return ( "Waiting", $res ); + } + else { + # See if this item is more important than what we've got + # so far. + if ( $res->{'priority'} != 0 && $res->{'priority'} < $priority ) + { + $priority = $res->{'priority'}; + $highest = $res; + } + } + } + } + + # If we get this far, then no exact match was found. Print the + # most important item on the list. I think this tells us who's + # next in line to get this book. + if ($highest) { # FIXME - $highest might be undefined + $highest->{'itemnumber'} = $item; + return ( "Reserved", $highest ); + } + else { + return ( 0, 0 ); } } +#------------------------------------------------------------------------------------- + +=item CancelReserve + + &CancelReserve($biblionumber, $itemnumber, $borrowernumber); + +Cancels a reserve. + +Use either C<$biblionumber> or C<$itemnumber> to specify the item to +cancel, but not both: if both are given, C<&CancelReserve> does +nothing. + +C<$borrowernumber> is the borrower number of the patron on whose +behalf the book was reserved. + +If C<$biblionumber> was given, C<&CancelReserve> also adjusts the +priorities of the other people who are waiting on the book. + +=cut + +#' sub CancelReserve { - my ($biblio, $item, $borr) = @_; - my $dbh=C4Connect; - warn "In CancelReserve"; - if (($item and $borr) and (not $biblio)) { -# removing a waiting reserve record.... - $item = $dbh->quote($item); - $borr = $dbh->quote($borr); -# update the database... - my $query = "update reserves set cancellationdate = now(), - found = Null, - priority = 0 - where itemnumber = $item - and borrowernumber = $borr"; - my $sth = $dbh->prepare($query); - $sth->execute; - $sth->finish; - } - if (($biblio and $borr) and (not $item)) { -# removing a reserve record.... - my $q_biblio = $dbh->quote($biblio); - $borr = $dbh->quote($borr); -# fix up the priorities on the other records.... - my $query = "SELECT priority FROM reserves - WHERE biblionumber = $q_biblio - AND borrowernumber = $borr - AND cancellationdate is NULL - AND (found <> 'F' or found is NULL)"; - my $sth=$dbh->prepare($query); - $sth->execute; - my ($priority) = $sth->fetchrow_array; - $sth->finish; -# update the database, removing the record... - my $query = "update reserves set cancellationdate = now(), - found = Null, - priority = 0 - where biblionumber = $q_biblio - and borrowernumber = $borr - and cancellationdate is NULL - and (found <> 'F' or found is NULL)"; - my $sth = $dbh->prepare($query); - $sth->execute; - $sth->finish; -# now fix the priority on the others.... - fixpriority($priority, $biblio); - } - $dbh->disconnect; + my ( $biblio, $item, $borr ) = @_; + my $dbh = C4::Context->dbh; + if ( ( $item and $borr ) and ( not $biblio ) ) { + # removing a waiting reserve record.... + # update the database... + my $query = qq/ + UPDATE reserves + SET cancellationdate = now(), + found = Null, + priority = 0 + WHERE itemnumber = ? + AND borrowernumber = ? + /; + my $sth = $dbh->prepare($query); + $sth->execute( $item, $borr ); + $sth->finish; + } + if ( ( $biblio and $borr ) and ( not $item ) ) { + # removing a reserve record.... + # get the prioritiy on this record.... + my $priority; + my $query = qq/ + SELECT priority FROM reserves + WHERE biblionumber = ? + AND borrowernumber = ? + AND cancellationdate IS NULL + AND itemnumber IS NULL + AND (found <> 'F' OR found IS NULL) + /; + my $sth = $dbh->prepare($query); + $sth->execute( $biblio, $borr ); + ($priority) = $sth->fetchrow_array; + $sth->finish; + $query = qq/ + UPDATE reserves + SET cancellationdate = now(), + found = Null, + priority = 0 + WHERE biblionumber = ? + AND borrowernumber = ? + AND cancellationdate IS NULL + AND (found <> 'F' or found IS NULL) + /; + + # update the database, removing the record... + $sth = $dbh->prepare($query); + $sth->execute( $biblio, $borr ); + $sth->finish; + + # now fix the priority on the others.... + FixPriority( $priority, $biblio ); + } } +#------------------------------------------------------------------------------------- +=item FillReserve + + &FillReserve($reserve); + +Fill a reserve. If I understand this correctly, this means that the +reserved book has been found and given to the patron who reserved it. + +C<$reserve> specifies the reserve to fill. It is a reference-to-hash +whose keys are fields from the reserves table in the Koha database. + +=cut + +#' sub FillReserve { my ($res) = @_; - my $dbh=C4Connect; -# removing a waiting reserve record.... - my $biblio = $res->{'biblionumber'}; my $qbiblio = $dbh->quote($biblio); - my $borr = $res->{'borrowernumber'}; $borr = $dbh->quote($borr); - my $resdate = $res->{'reservedate'}; $resdate = $dbh->quote($resdate); -# update the database... - my $query = "UPDATE reserves SET found = 'F', - priority = 0 - WHERE biblionumber = $qbiblio - AND reservedate = $resdate - AND borrowernumber = $borr"; + my $dbh = C4::Context->dbh; + # fill in a reserve record.... + my $qbiblio = $res->{'biblionumber'}; + my $borr = $res->{'borrowernumber'}; + my $resdate = $res->{'reservedate'}; + + # get the priority on this record.... + my $priority; + my $query = "SELECT priority + FROM reserves + WHERE biblionumber = ? + AND borrowernumber = ? + AND reservedate = ?"; my $sth = $dbh->prepare($query); - $sth->execute; + $sth->execute( $qbiblio, $borr, $resdate ); + ($priority) = $sth->fetchrow_array; $sth->finish; - $dbh->disconnect; -# now fix the priority on the others.... - fixpriority($res->{'priority'}, $biblio); + + # update the database... + $query = "UPDATE reserves + SET found = 'F', + priority = 0 + WHERE biblionumber = ? + AND reservedate = ? + AND borrowernumber = ? + "; + $sth = $dbh->prepare($query); + $sth->execute( $qbiblio, $resdate, $borr ); + $sth->finish; + + # now fix the priority on the others (if the priority wasn't + # already sorted!).... + unless ( $priority == 0 ) { + FixPriority( $priority, $qbiblio ); + } } -sub fixpriority { - my ($priority, $biblio) = @_; - my $dbh = C4Connect; - my ($count, $reserves) = FindReserves($biblio); - foreach my $rec (@$reserves) { - if ($rec->{'priority'} > $priority) { - my $newpr = $rec->{'priority'}; $newpr = $dbh->quote($newpr - 1); - my $nbib = $rec->{'biblionumber'}; $nbib = $dbh->quote($nbib); - my $nbor = $rec->{'borrowernumber'}; $nbor = $dbh->quote($nbor); - my $nresd = $rec->{'reservedate'}; $nresd = $dbh->quote($nresd); - my $query = "UPDATE reserves SET priority = $newpr - WHERE biblionumber = $nbib - AND borrowernumber = $nbor - AND reservedate = $nresd"; - warn $query; - my $sth = $dbh->prepare($query); - $sth->execute; - $sth->finish; - } - } - $dbh->disconnect; +#------------------------------------------------------------------------------------- + +=item FixPriority + +&FixPriority($biblio,$borrowernumber,$rank); + + Only used internally (so don't export it) + Changed how this functions works # + Now just gets an array of reserves in the rank order and updates them with + the array index (+1 as array starts from 0) + and if $rank is supplied will splice item from the array and splice it back in again + in new priority rank + +=cut + +sub FixPriority { + my ( $biblio, $borrowernumber, $rank ) = @_; + my $dbh = C4::Context->dbh; + if ( $rank eq "del" ) { + CancelReserve( $biblio, undef, $borrowernumber ); + } + if ( $rank eq "W" || $rank eq "0" ) { + + # make sure priority for waiting items is 0 + my $query = qq/ + UPDATE reserves + SET priority = 0 + WHERE biblionumber = ? + AND borrowernumber = ? + AND cancellationdate IS NULL + AND found ='W' + /; + my $sth = $dbh->prepare($query); + $sth->execute( $biblio, $borrowernumber ); + } + my @priority; + my @reservedates; + + # get whats left +# FIXME adding a new security in returned elements for changing priority, +# now, we don't care anymore any reservations with itemnumber linked (suppose a waiting reserve) + my $query = qq/ + SELECT borrowernumber, reservedate, constrainttype + FROM reserves + WHERE biblionumber = ? + AND cancellationdate IS NULL + AND itemnumber IS NULL + AND ((found <> 'F' and found <> 'W') or found is NULL) + ORDER BY priority ASC + /; + my $sth = $dbh->prepare($query); + $sth->execute($biblio); + while ( my $line = $sth->fetchrow_hashref ) { + push( @reservedates, $line ); + push( @priority, $line ); + } + + # To find the matching index + my $i; + my $key = -1; # to allow for 0 to be a valid result + for ( $i = 0 ; $i < @priority ; $i++ ) { + if ( $borrowernumber == $priority[$i]->{'borrowernumber'} ) { + $key = $i; # save the index + last; + } + } + + # if index exists in array then move it to new position + if ( $key > -1 && $rank ne 'del' && $rank > 0 ) { + my $new_rank = $rank - + 1; # $new_rank is what you want the new index to be in the array + my $moving_item = splice( @priority, $key, 1 ); + splice( @priority, $new_rank, 0, $moving_item ); + } + + # now fix the priority on those that are left.... + $query = " + UPDATE reserves + SET priority = ? + WHERE biblionumber = ? + AND borrowernumber = ? + AND reservedate = ? + AND found IS NULL + "; + $sth = $dbh->prepare($query); + for ( my $j = 0 ; $j < @priority ; $j++ ) { + $sth->execute( + $j + 1, $biblio, + $priority[$j]->{'borrowernumber'}, + $priority[$j]->{'reservedate'} + ); + $sth->finish; + } } +#------------------------------------------------------------------------------------- + +=item ReserveWaiting +branchcode = &ReserveWaiting($item,$borr); +this function set FOUND to 'W' for Waiting into the database. + +=cut sub ReserveWaiting { - my ($item, $borr) = @_; - my $dbh = C4Connect; - $item = $dbh->quote($item); - $borr = $dbh->quote($borr); -# get priority and biblionumber.... - my $query = "SELECT reserves.priority as priority, - reserves.biblionumber as biblionumber, - reserves.branchcode as branchcode - FROM reserves,items - WHERE reserves.biblionumber = items.biblionumber - AND items.itemnumber = $item - AND reserves.borrowernumber = $borr - AND reserves.cancellationdate is NULL - AND (reserves.found <> 'F' or reserves.found is NULL)"; + my ( $item, $borr,$diffBranchSend ) = @_; + my $dbh = C4::Context->dbh; + + # get priority and biblionumber.... + my $query = qq/ + SELECT reserves.priority as priority, + reserves.biblionumber as biblionumber, + reserves.branchcode as branchcode, + reserves.timestamp as timestamp + FROM reserves,items + WHERE reserves.biblionumber = items.biblionumber + AND items.itemnumber = ? + AND reserves.borrowernumber = ? + AND reserves.cancellationdate IS NULL + AND (reserves.found <> 'F' OR reserves.found IS NULL) + /; my $sth = $dbh->prepare($query); - $sth->execute; + $sth->execute( $item, $borr ); my $data = $sth->fetchrow_hashref; $sth->finish; - my $biblio = $data->{'biblionumber'}; - my $q_biblio = $dbh->quote($biblio); -# update reserves record.... - $query = "UPDATE reserves SET priority = 0, found = 'W', itemnumber = $item - WHERE borrowernumber = $borr AND biblionumber = $q_biblio"; + my $biblio = $data->{'biblionumber'}; + my $timestamp = $data->{'timestamp'}; + + # update reserves record.... + if ($diffBranchSend) { + $query = qq/ + UPDATE reserves + SET priority = 0, + itemnumber = ? + WHERE borrowernumber = ? + AND biblionumber = ? + AND timestamp = ? + /; + } + else { + $query = qq/ + UPDATE reserves + SET priority = 0, + found = 'W', + waitingdate=now(), + itemnumber = ? + WHERE borrowernumber = ? + AND biblionumber = ? + AND timestamp = ? + /; + } $sth = $dbh->prepare($query); - $sth->execute; + $sth->execute( $item, $borr, $biblio, $timestamp ); $sth->finish; - $dbh->disconnect; -# now fix up the remaining priorities.... - fixpriority($data->{'priority'}, $biblio); + + # now fix up the remaining priorities.... + FixPriority( $data->{'priority'}, $biblio ); my $branchcode = $data->{'branchcode'}; return $branchcode; } -sub CheckWaiting { - my ($borr)=@_; - my $dbh = C4Connect; - $borr = $dbh->quote($borr); +#------------------------------------------------------------------------------------- + +=item GetWaitingReserves + +\@itemswaiting=GetWaitingReserves($borr); + +this funtion fetch the list of waiting reserves from database. + +=cut + +sub GetWaitingReserves { + my ($borr) = @_; + my $dbh = C4::Context->dbh; my @itemswaiting; - my $query = "SELECT * FROM reserves - WHERE borrowernumber = $borr - AND reserves.found = 'W' - AND cancellationdate is NULL"; + my $query = qq/ + SELECT * + FROM reserves + WHERE borrowernumber = ? + AND reserves.found = 'W' + AND cancellationdate IS NULL + /; my $sth = $dbh->prepare($query); - $sth->execute(); - my $cnt=0; - if (my $data=$sth->fetchrow_hashref) { - @itemswaiting[$cnt] =$data; - $cnt ++; + $sth->execute($borr); + while ( my $data = $sth->fetchrow_hashref ) { + push( @itemswaiting, $data ); } $sth->finish; - return ($cnt,\@itemswaiting); + return \@itemswaiting; } +#------------------------------------------------------------------------------------- + +=item Findgroupreserve + + @results = &Findgroupreserve($biblioitemnumber, $biblionumber); + +****** FIXME ****** +I don't know what this does, because I don't understand how reserve +constraints work. I think the idea is that you reserve a particular +biblio, and the constraint allows you to restrict it to a given +biblioitem (e.g., if you want to borrow the audio book edition of "The +Prophet", rather than the first available publication). + +C<&Findgroupreserve> returns : +C<@results> is an array of references-to-hash whose keys are mostly +fields from the reserves table of the Koha database, plus +C. + +=cut + +#' sub Findgroupreserve { - my ($bibitem,$biblio)=@_; - my $dbh=C4Connect; - $bibitem=$dbh->quote($bibitem); - my $query = "SELECT reserves.biblionumber AS biblionumber, - reserves.borrowernumber AS borrowernumber, - reserves.reservedate AS reservedate, - reserves.branchcode AS branchcode, - reserves.cancellationdate AS cancellationdate, - reserves.found AS found, - reserves.reservenotes AS reservenotes, - reserves.priority AS priority, - reserves.timestamp AS timestamp, - reserveconstraints.biblioitemnumber AS biblioitemnumber, - reserves.itemnumber AS itemnumber - FROM reserves LEFT JOIN reserveconstraints - ON reserves.biblionumber = reserveconstraints.biblionumber - WHERE reserves.biblionumber = $biblio - AND ( ( reserveconstraints.biblioitemnumber = $bibitem - AND reserves.borrowernumber = reserveconstraints.borrowernumber - AND reserves.reservedate =reserveconstraints.reservedate ) - OR reserves.constrainttype='a' ) - AND reserves.cancellationdate is NULL - AND (reserves.found <> 'F' or reserves.found is NULL)"; - my $sth=$dbh->prepare($query); - $sth->execute; - my $i=0; - my @results; - while (my $data=$sth->fetchrow_hashref){ - $results[$i]=$data; - $i++; - } - $sth->finish; - $dbh->disconnect; - return($i,@results); + my ( $bibitem, $biblio ) = @_; + my $dbh = C4::Context->dbh; + my $query = qq/ + SELECT reserves.biblionumber AS biblionumber, + reserves.borrowernumber AS borrowernumber, + reserves.reservedate AS reservedate, + reserves.branchcode AS branchcode, + reserves.cancellationdate AS cancellationdate, + reserves.found AS found, + reserves.reservenotes AS reservenotes, + reserves.priority AS priority, + reserves.timestamp AS timestamp, + reserveconstraints.biblioitemnumber AS biblioitemnumber, + reserves.itemnumber AS itemnumber + FROM reserves + LEFT JOIN reserveconstraints ON reserves.biblionumber = reserveconstraints.biblionumber + WHERE reserves.biblionumber = ? + AND ( ( reserveconstraints.biblioitemnumber = ? + AND reserves.borrowernumber = reserveconstraints.borrowernumber + AND reserves.reservedate =reserveconstraints.reservedate ) + OR reserves.constrainttype='a' ) + AND reserves.cancellationdate is NULL + AND (reserves.found <> 'F' or reserves.found is NULL) + /; + my $sth = $dbh->prepare($query); + $sth->execute( $biblio, $bibitem ); + my @results; + while ( my $data = $sth->fetchrow_hashref ) { + push( @results, $data ); + } + $sth->finish; + return @results; } -sub CreateReserve { - my -($env,$branch,$borrnum,$biblionumber,$constraint,$bibitems,$priority,$notes,$title)= @_; - my $fee=CalcReserveFee($env,$borrnum,$biblionumber,$constraint,$bibitems); - my $dbh = &C4Connect; - my $const = lc substr($constraint,0,1); - my @datearr = localtime(time); - my $resdate =(1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3]; - #eval { - # updates take place here - if ($fee > 0) { -# print $fee; - my $nextacctno = &getnextacctno($env,$borrnum,$dbh); - my $updquery = "insert into accountlines - (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding) - values - ($borrnum,$nextacctno,now(),$fee,'Reserve Charge - $title','Res',$fee)"; - my $usth = $dbh->prepare($updquery); - $usth->execute; - $usth->finish; - } - #if ($const eq 'a'){ - my $query="insert into reserves - (borrowernumber,biblionumber,reservedate,branchcode,constrainttype,priority,reservenotes) - values -('$borrnum','$biblionumber','$resdate','$branch','$const','$priority','$notes')"; - my $sth = $dbh->prepare($query); - $sth->execute(); +=item CreateReserve + +CreateReserve($env,$branch,$borrowernumber,$biblionumber,$constraint,$bibitems,$priority,$notes,$title,$checkitem,$found) + +FIXME - A somewhat different version of this function appears in +C4::Reserves. Pick one and stick with it. + +=cut + +sub CreateReserve { + my ( + $env, $branch, $borrowernumber, $biblionumber, + $constraint, $bibitems, $priority, $notes, + $title, $checkitem, $found + ) = @_; + my $fee; + if ( $library_name =~ /Horowhenua/ ) { + $fee = + CalcHLTReserveFee( $env, $borrowernumber, $biblionumber, $constraint, + $bibitems ); + } + else { + $fee = + CalcReserveFee( $env, $borrowernumber, $biblionumber, $constraint, + $bibitems ); + } + my $dbh = C4::Context->dbh; + my $const = lc substr( $constraint, 0, 1 ); + my @datearr = localtime(time); + my $resdate = + ( 1900 + $datearr[5] ) . "-" . ( $datearr[4] + 1 ) . "-" . $datearr[3]; + my $waitingdate; + + # If the reserv had the waiting status, we had the value of the resdate + if ( $found eq 'W' ) { + $waitingdate = $resdate; + } + + #eval { + # updates take place here + if ( $fee > 0 ) { + my $nextacctno = &getnextacctno( $env, $borrowernumber, $dbh ); + my $query = qq/ + INSERT INTO accountlines + (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding) + VALUES + (?,?,now(),?,?,'Res',?) + /; + my $usth = $dbh->prepare($query); + $usth->execute( $borrowernumber, $nextacctno, $fee, + "Reserve Charge - $title", $fee ); + $usth->finish; + } + + #if ($const eq 'a'){ + my $query = qq/ + INSERT INTO reserves + (borrowernumber,biblionumber,reservedate,branchcode,constrainttype, + priority,reservenotes,itemnumber,found,waitingdate) + VALUES + (?,?,?,?,?, + ?,?,?,?,?) + /; + my $sth = $dbh->prepare($query); + $sth->execute( + $borrowernumber, $biblionumber, $resdate, $branch, + $const, $priority, $notes, $checkitem, + $found, $waitingdate + ); $sth->finish; - #} - if (($const eq "o") || ($const eq "e")) { - my $numitems = @$bibitems; - my $i = 0; - while ($i < $numitems) { - my $biblioitem = @$bibitems[$i]; - my $query = "insert into - reserveconstraints - (borrowernumber,biblionumber,reservedate,biblioitemnumber) - values - ('$borrnum','$biblionumber','$resdate','$biblioitem')"; - my $sth = $dbh->prepare($query); - $sth->execute(); - $sth->finish; - $i++; - } - } -# print $query; - $dbh->disconnect(); - return(); -} + + #} + if ( ( $const eq "o" ) || ( $const eq "e" ) ) { + my $numitems = @$bibitems; + my $i = 0; + while ( $i < $numitems ) { + my $biblioitem = @$bibitems[$i]; + my $query = qq/ + INSERT INTO reserveconstraints + (borrowernumber,biblionumber,reservedate,biblioitemnumber) + VALUES + (?,?,?,?) + /; + my $sth = $dbh->prepare(""); + $sth->execute( $borrowernumber, $biblionumber, $resdate, + $biblioitem ); + $sth->finish; + $i++; + } + } + return; +} + +# FIXME - A functionally identical version of this function appears in +# C4::Reserves. Pick one and stick with it. +# XXX - Internal use only +# FIXME - opac-reserves.pl need to use it, temporarily put into @EXPORT sub CalcReserveFee { - my ($env,$borrnum,$biblionumber,$constraint,$bibitems) = @_; - #check for issues; - my $dbh = &C4Connect; - my $const = lc substr($constraint,0,1); - my $query = "select * from borrowers,categories - where (borrowernumber = '$borrnum') - and (borrowers.categorycode = categories.categorycode)"; - my $sth = $dbh->prepare($query); - $sth->execute; - my $data = $sth->fetchrow_hashref; - $sth->finish(); - my $fee = $data->{'reservefee'}; - my $cntitems = @->$bibitems; - if ($fee > 0) { - # check for items on issue - # first find biblioitem records - my @biblioitems; - my $query1 = "select * from biblio,biblioitems - where (biblio.biblionumber = '$biblionumber') - and (biblio.biblionumber = biblioitems.biblionumber)"; - my $sth1 = $dbh->prepare($query1); - $sth1->execute(); - while (my $data1=$sth1->fetchrow_hashref) { - if ($const eq "a") { - push @biblioitems,$data1; - } else { - my $found = 0; - my $x = 0; - while ($x < $cntitems) { - if (@$bibitems->{'biblioitemnumber'} == $data->{'biblioitemnumber'}) { - $found = 1; - } - $x++; - } - if ($const eq 'o') { - if ( $found == 1) { - push @biblioitems,$data1; - } - } else { - if ($found == 0) { - push @biblioitems,$data1; - } - } - } - } - $sth1->finish; - my $cntitemsfound = @biblioitems; - my $issues = 0; - my $x = 0; - my $allissued = 1; - while ($x < $cntitemsfound) { - my $bitdata = @biblioitems[$x]; - my $query2 = "select * from items - where biblioitemnumber = '$bitdata->{'biblioitemnumber'}'"; - my $sth2 = $dbh->prepare($query2); - $sth2->execute; - while (my $itdata=$sth2->fetchrow_hashref) { - my $query3 = "select * from issues - where itemnumber = '$itdata->{'itemnumber'}' and - returndate is null"; - - my $sth3 = $dbh->prepare($query3); - $sth3->execute(); - if (my $isdata=$sth3->fetchrow_hashref) { - } else { - $allissued = 0; - } - } - $x++; - } - if ($allissued == 0) { - my $rquery = "select * from reserves - where biblionumber = '$biblionumber'"; - my $rsth = $dbh->prepare($rquery); - $rsth->execute(); - if (my $rdata = $rsth->fetchrow_hashref) { - } else { - $fee = 0; - } - } - } -# print "fee $fee"; - $dbh->disconnect(); - return $fee; -} - -sub getnextacctno { - my ($env,$bornumber,$dbh)=@_; - my $nextaccntno = 1; - my $query = "select * from accountlines - where (borrowernumber = '$bornumber') - order by accountno desc"; - my $sth = $dbh->prepare($query); - $sth->execute; - if (my $accdata=$sth->fetchrow_hashref){ - $nextaccntno = $accdata->{'accountno'} + 1; - } - $sth->finish; - return($nextaccntno); -} - -sub updatereserves{ - #subroutine to update a reserve - my ($rank,$biblio,$borrower,$del,$branch)=@_; - my $dbh=C4Connect; - my $query="Update reserves "; - if ($del ==0){ - $query.="set priority='$rank',branchcode='$branch' where - biblionumber=$biblio and borrowernumber=$borrower"; - } else { - $query="Select * from reserves where biblionumber=$biblio and - borrowernumber=$borrower"; - my $sth=$dbh->prepare($query); - $sth->execute; - my $data=$sth->fetchrow_hashref; + my ( $env, $borrowernumber, $biblionumber, $constraint, $bibitems ) = @_; + + #check for issues; + my $dbh = C4::Context->dbh; + my $const = lc substr( $constraint, 0, 1 ); + my $query = qq/ + SELECT * FROM borrowers,categories + WHERE borrowernumber = ? + AND borrowers.categorycode = categories.categorycode + /; + my $sth = $dbh->prepare($query); + $sth->execute($borrowernumber); + my $data = $sth->fetchrow_hashref; + $sth->finish(); + my $fee = $data->{'reservefee'}; + my $cntitems = @- > $bibitems; + + if ( $fee > 0 ) { + + # check for items on issue + # first find biblioitem records + my @biblioitems; + my $sth1 = $dbh->prepare( + "SELECT * FROM biblio,biblioitems + WHERE (biblio.biblionumber = ?) + AND (biblio.biblionumber = biblioitems.biblionumber)" + ); + $sth1->execute($biblionumber); + while ( my $data1 = $sth1->fetchrow_hashref ) { + if ( $const eq "a" ) { + push @biblioitems, $data1; + } + else { + my $found = 0; + my $x = 0; + while ( $x < $cntitems ) { + if ( @$bibitems->{'biblioitemnumber'} == + $data->{'biblioitemnumber'} ) + { + $found = 1; + } + $x++; + } + if ( $const eq 'o' ) { + if ( $found == 1 ) { + push @biblioitems, $data1; + } + } + else { + if ( $found == 0 ) { + push @biblioitems, $data1; + } + } + } + } + $sth1->finish; + my $cntitemsfound = @biblioitems; + my $issues = 0; + my $x = 0; + my $allissued = 1; + while ( $x < $cntitemsfound ) { + my $bitdata = $biblioitems[$x]; + my $sth2 = $dbh->prepare( + "SELECT * FROM items + WHERE biblioitemnumber = ?" + ); + $sth2->execute( $bitdata->{'biblioitemnumber'} ); + while ( my $itdata = $sth2->fetchrow_hashref ) { + my $sth3 = $dbh->prepare( + "SELECT * FROM issues + WHERE itemnumber = ? + AND returndate IS NULL" + ); + $sth3->execute( $itdata->{'itemnumber'} ); + if ( my $isdata = $sth3->fetchrow_hashref ) { + } + else { + $allissued = 0; + } + } + $x++; + } + if ( $allissued == 0 ) { + my $rsth = + $dbh->prepare("SELECT * FROM reserves WHERE biblionumber = ?"); + $rsth->execute($biblionumber); + if ( my $rdata = $rsth->fetchrow_hashref ) { + } + else { + $fee = 0; + } + } + } + + # print "fee $fee"; + return $fee; +} + +# The following are junior and young adult item types that should not incur a +# reserve charge. +# +# Juniors: BJC, BJCN, BJF, BJK, BJM, BJN, BJP, BJSF, BJSN, DJ, DJP, FJ, JVID, +# VJ, VJP, PJ, TJ, TJP, VJ, VJP. +# +# Young adults: BYF, BYN, BYP, DY, DYP, PY, PYP, TY, TYP, VY, VYP. +# +# All other item types should incur a reserve charge. +sub CalcHLTReserveFee { + my ( $env, $borrowernumber, $biblionumber, $constraint, $bibitems ) = @_; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( + "SELECT * FROM borrowers,categories + WHERE (borrowernumber = ?) + AND (borrowers.categorycode = categories.categorycode)" + ); + $sth->execute($borrowernumber); + my $data = $sth->fetchrow_hashref; + $sth->finish(); + my $fee = $data->{'reservefee'}; + + my $matchno; + 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/; + $sth = $dbh->prepare( + "SELECT * FROM biblio,biblioitems + WHERE (biblio.biblionumber = ?) + AND (biblio.biblionumber = biblioitems.biblionumber)" + ); + $sth->execute($biblionumber); + $data = $sth->fetchrow_hashref; + my $itemtype = $data->{'itemtype'}; + for ( my $i = 0 ; $i < @nocharge ; $i++ ) { + if ( $itemtype eq $nocharge[$i] ) { + $matchno++; + last; + } + } + + if ( $matchno > 0 ) { + $fee = 0; + } + return $fee; +} + +=item GetNextAccountNumber + +GetNextAccountNumber() + +=cut + +sub GetNextAccountNumber { + my ( $env, $borrowernumber, $dbh ) = @_; + my $nextaccntno = 1; + my $sth = $dbh->prepare( + "select * from accountlines + where (borrowernumber = ?) + order by accountno desc" + ); + $sth->execute($borrowernumber); + if ( my $accdata = $sth->fetchrow_hashref ) { + $nextaccntno = $accdata->{'accountno'} + 1; + } $sth->finish; - $query="Select * from reserves where biblionumber=$biblio and - priority > '$data->{'priority'}' and cancellationdate is NULL - order by priority"; - my $sth2=$dbh->prepare($query) || die $dbh->errstr; - $sth2->execute || die $sth2->errstr; - while (my $data=$sth2->fetchrow_hashref){ - $data->{'priority'}--; - $query="Update reserves set priority=$data->{'priority'} where - biblionumber=$data->{'biblionumber'} and - borrowernumber=$data->{'borrowernumber'}"; - my $sth3=$dbh->prepare($query); - $sth3->execute || die $sth3->errstr; - $sth3->finish; - } - $sth2->finish; - $query="update reserves set cancellationdate=now() where biblionumber=$biblio - and borrowernumber=$borrower"; - } - my $sth=$dbh->prepare($query); - $sth->execute; - $sth->finish; - $dbh->disconnect; + return ($nextaccntno); } -sub getreservetitle { - my ($biblio,$bor,$date,$timestamp)=@_; - my $dbh=C4Connect; - my $query="Select * from reserveconstraints,biblioitems where - reserveconstraints.biblioitemnumber=biblioitems.biblioitemnumber - and reserveconstraints.biblionumber=$biblio and reserveconstraints.borrowernumber - = $bor and reserveconstraints.reservedate='$date' and - reserveconstraints.timestamp=$timestamp"; - my $sth=$dbh->prepare($query); - $sth->execute; - my $data=$sth->fetchrow_hashref; - $sth->finish; - $dbh->disconnect; -# print $query; - return($data); +#------------------------------------------------------------------------------------- + +=item UpdateReserve + +&UpdateReserve($rank,$biblio,$borrower,$branch) + +=cut + +sub UpdateReserve { + #subroutine to update a reserve + my ( $rank, $biblio, $borrower, $branch , $itemnumber) = @_; + return if $rank eq "W"; + return if $rank eq "n"; + my $dbh = C4::Context->dbh; + if ( $rank eq "del" ) { + my $query = qq/ + UPDATE reserves + SET cancellationdate=now() + WHERE biblionumber = ? + AND borrowernumber = ? + AND cancellationdate is NULL + AND (found <> 'F' or found is NULL) + /; + my $sth = $dbh->prepare($query); + $sth->execute( $biblio, $borrower ); + $sth->finish; + + } + else { + my $query = qq/ + UPDATE reserves SET priority = ? ,branchcode = ?, itemnumber = ?, found = NULL + WHERE biblionumber = ? + AND borrowernumber = ? + AND cancellationdate is NULL + AND (found <> 'F' or found is NULL) + /; + my $sth = $dbh->prepare($query); + $sth->execute( $rank, $branch,$itemnumber, $biblio, $borrower); + $sth->finish; + FixPriority( $biblio, $borrower, $rank); + } +} + +=item GetReserveTitle + +$data = GetReserveTitle($biblio,$bor,$date,$timestamp); + +=cut + +sub GetReserveTitle { + my ( $biblio, $bor, $date, $timestamp ) = @_; + my $dbh = C4::Context->dbh; + my $query = qq/ + SELECT * + FROM reserveconstraints,biblioitems + WHERE reserveconstraints.biblioitemnumber=biblioitems.biblioitemnumber + AND reserveconstraints.biblionumber=? + AND reserveconstraints.borrowernumber = ? + AND reserveconstraints.reservedate=? + AND reserveconstraints.timestamp=? + /; + my $sth = $dbh->prepare($query); + $sth->execute( $biblio, $bor, $date, $timestamp ); + my $data = $sth->fetchrow_hashref; + $sth->finish; + return $data; +} + +=item FindReservesInQueue + + $results = &FindReservesInQueue($biblionumber); + +Simple variant of FindReserves, exept the result is now displaying only the queue list of reservations with the same biblionumber (At this time only displayed in request.pl) + +C<&FindReservesInQueue> returns a two-element array: + +C<$results> is a reference to an array of references of hashes. Each hash +has for keys a list of column from reserves table (see details in function). + +=cut + +#' + +sub FindReservesInQueue { + my ($biblionumber) = @_; + my $dbh = C4::Context->dbh; + + # Find the desired items in the reserves + my $query = qq/ + SELECT branchcode, + timestamp AS rtimestamp, + priority, + biblionumber, + borrowernumber, + reservedate, + constrainttype, + found, + itemnumber + FROM reserves + WHERE cancellationdate IS NULL + AND biblionumber = ? + AND (found <> \'F\' OR found IS NULL) + AND priority <> \'0\' + ORDER BY priority + /; + my $sth = $dbh->prepare($query); + $sth->execute($biblionumber); + my @results; + my $i = 0; + while ( my $data = $sth->fetchrow_hashref ) { + + # FIXME - What is this if-statement doing? How do constraints work? + if ( $data->{constrainttype} eq 'o' ) { + $query = ' + SELECT biblioitemnumber + FROM reserveconstraints + WHERE biblionumber = ? + AND borrowernumber = ? + AND reservedate = ? + '; + my $csth = $dbh->prepare($query); + $csth->execute( $data->{biblionumber}, $data->{borrowernumber}, + $data->{reservedate}, ); + + my @bibitemno; + while ( my $bibitemnos = $csth->fetchrow_array ) { + push( @bibitemno, $bibitemnos ); + } + my $count = @bibitemno; + + # if we have two or more different specific itemtypes + # reserved by same person on same day + my $bdata; + if ( $count > 1 ) { + $bdata = GetBiblioItemData( $bibitemno[$i] ); + $i++; + } + else { + # Look up the book we just found. + $bdata = GetBiblioItemData( $bibitemno[0] ); + } + $csth->finish; + + # Add the results of this latest search to the current + # results. + # FIXME - An 'each' would probably be more efficient. + foreach my $key ( keys %$bdata ) { + $data->{$key} = $bdata->{$key}; + } + } + push @results, $data; + } + $sth->finish; + + return ( $#results + 1, \@results ); } +=back +=head1 AUTHOR +Koha Developement team +=cut - -END { } # module clean-up code here (global destructor)