X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FReserves2.pm;h=5db1226fe20a1d4942ff4d11889ba05baa57200c;hb=83c378e2edf455be2b93b53759690c18c6968036;hp=421142fe497f04ce586653f23bb0c328704a767a;hpb=6800d04813de4fb6bc77386d63ec2b05799e91b7;p=koha.git diff --git a/C4/Reserves2.pm b/C4/Reserves2.pm index 421142fe49..5db1226fe2 100755 --- a/C4/Reserves2.pm +++ b/C4/Reserves2.pm @@ -1,6 +1,7 @@ -package C4::Reserves2; +# -*- tab-width: 8 -*- +# NOTE: This file uses standard 8-character tabs -# $Id$ +package C4::Reserves2; # Copyright 2000-2002 Katipo Communications # @@ -19,23 +20,24 @@ package C4::Reserves2; # 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::Context; +use C4::Biblio; use C4::Search; - # FIXME - C4::Reserves2 uses C4::Search, which uses C4::Reserves2. - # So Perl complains that all of the functions here get redefined. -#use C4::Accounts; +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 - FIXME +C4::Reserves2 - Koha functions for dealing with reservation. =head1 SYNOPSIS @@ -43,7 +45,7 @@ C4::Reserves2 - FIXME =head1 DESCRIPTION -FIXME +this modules provides somes functions to deal with reservations. =head1 FUNCTIONS @@ -52,13 +54,247 @@ FIXME =cut @ISA = qw(Exporter); -@EXPORT = qw(&FindReserves &CheckReserves &CheckWaiting &CancelReserve &FillReserve &ReserveWaiting &CreateReserve &updatereserves &UpdateReserve &getreservetitle &Findgroupreserve); + +# 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 - ($count, $results) = &FindReserves($biblionumber, $borrowernumber); + $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 @@ -77,93 +313,166 @@ constraints and does something I don't understand. C<&FindReserves> returns a two-element array: -C<$count> is the number of elements in C<$results>. - -C<$results> is a reference-to-array; each element is a -reference-to-hash, whose keys are (I think) all of the fields of the -reserves, borrowers, and biblio tables of the Koha database. +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 = C4::Context->dbh; - # Find the desired items in the reserves - my $query="SELECT *,reserves.branchcode,biblio.title AS btitle - FROM reserves,borrowers,biblio "; - # FIXME - These three bits of SQL seem to contain a fair amount of - # redundancy. Wouldn't it be better to have a @clauses array, add - # one or two clauses as necessary, then join(" AND ", @clauses) ? - if ($bib ne ''){ - $bib = $dbh->quote($bib); - if ($bor ne ''){ - # Both $bib and $bor specified - # Find a particular book for a particular patron - $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 { - # $bib specified, but not $bor - # Find a particular book for all patrons - $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 { - # FIXME - Check that $bor was given - - # No $bib given. - # Find all books for the given patron. - $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; - # FIXME - $i is unnecessary and bogus - my $i=0; - my @results; - while (my $data=$sth->fetchrow_hashref){ - # FIXME - What is this if-statement doing? How do constraints work? - if ($data->{'constrainttype'} eq 'o') { - my $conquery = "SELECT biblioitemnumber FROM reserveconstraints - WHERE biblionumber = ? - AND borrowernumber = ? - AND reservedate = ?"; - my $csth=$dbh->prepare($conquery); - # FIXME - Why use separate variables for this? - my $bibn = $data->{'biblionumber'}; - my $born = $data->{'borrowernumber'}; - my $resd = $data->{'reservedate'}; - $csth->execute($bibn, $born, $resd); - my ($bibitemno) = $csth->fetchrow_array; - $csth->finish; - # Look up the book we just found. - my $bdata = C4::Search::bibitemdata($bibitemno); - # 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}; - } - } - $results[$i]=$data; # FIXME - Use push @results - $i++; - } -# print $query; - $sth->finish; - 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); @@ -194,38 +503,50 @@ reference-to-hash whose keys are mostly the fields of the reserves table in the Koha database. =cut + #' sub CheckReserves { - my ($item, $barcode) = @_; -# warn "In CheckReserves: itemnumber = $item"; + my ( $item, $barcode ) = @_; my $dbh = C4::Context->dbh; my $sth; if ($item) { - my $qitem=$dbh->quote($item); - # Look up the item by itemnumber - $sth=$dbh->prepare("SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan - FROM items, biblioitems, itemtypes - WHERE items.biblioitemnumber = biblioitems.biblioitemnumber - AND biblioitems.itemtype = itemtypes.itemtype - AND itemnumber=$qitem"); - } else { - my $qbc=$dbh->quote($barcode); - # Look up the item by barcode - $sth=$dbh->prepare("SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan - FROM items, biblioitems, itemtypes - WHERE items.biblioitemnumber = biblioitems.biblioitemnumber - AND biblioitems.itemtype = itemtypes.itemtype - AND barcode=$qbc"); - # FIXME - This function uses $item later on. Ought to set it here. + 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, $notforloan) = $sth->fetchrow_array; + my ( $biblio, $bibitem, $notforloan ) = $sth->fetchrow_array; $sth->finish; -# if item is not for loan it cannot be reserved either..... - return (0, 0) if ($notforloan); -# get the reserves... + + # 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 ($count, @reserves) = Findgroupreserve($bibitem, $biblio); + 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.) @@ -233,34 +554,39 @@ sub CheckReserves { my $priority = 10000000; my $highest; if ($count) { - 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; - } - } - } + 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); + if ($highest) { # FIXME - $highest might be undefined + $highest->{'itemnumber'} = $item; + return ( "Reserved", $highest ); + } + else { + return ( 0, 0 ); } } +#------------------------------------------------------------------------------------- + =item CancelReserve &CancelReserve($biblionumber, $itemnumber, $borrowernumber); @@ -278,58 +604,65 @@ 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 ( $biblio, $item, $borr ) = @_; my $dbh = C4::Context->dbh; - #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... - # FIXME - Use $dbh->do() - 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); - # get the prioritiy on this record.... - 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... - # FIXME - There's already a $query in this scope. - 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)"; - # FIXME - There's already a $sth in this scope. - my $sth = $dbh->prepare($query); - $sth->execute; - $sth->finish; - # now fix the priority on the others.... - fixpriority($priority, $biblio); + 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); @@ -341,426 +674,721 @@ 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 = C4::Context->dbh; # fill in a reserve record.... - # FIXME - Remove some of the redundancy here - 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); + my $qbiblio = $res->{'biblionumber'}; + my $borr = $res->{'borrowernumber'}; + my $resdate = $res->{'reservedate'}; + # get the priority on this record.... - my $query = "SELECT priority FROM reserves - WHERE biblionumber = $qbiblio - AND borrowernumber = $borr - AND reservedate = $resdate)"; - my $sth=$dbh->prepare($query); - $sth->execute; - my ($priority) = $sth->fetchrow_array; + my $priority; + my $query = "SELECT priority + FROM reserves + WHERE biblionumber = ? + AND borrowernumber = ? + AND reservedate = ?"; + my $sth = $dbh->prepare($query); + $sth->execute( $qbiblio, $borr, $resdate ); + ($priority) = $sth->fetchrow_array; $sth->finish; + # update the database... - # FIXME - There's already a $query in this scope. - my $query = "UPDATE reserves SET found = 'F', - priority = 0 - WHERE biblionumber = $qbiblio - AND reservedate = $resdate - AND borrowernumber = $borr"; - # FIXME - There's already a $sth in this scope. - my $sth = $dbh->prepare($query); - $sth->execute; + $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, $biblio); + unless ( $priority == 0 ) { + FixPriority( $priority, $qbiblio ); } } -# Only used internally -# Decrements (makes more important) the reserves for all of the -# entries waiting on the given book, if their priority is > $priority. -sub fixpriority { - my ($priority, $biblio) = @_; +#------------------------------------------------------------------------------------- + +=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; - my ($count, $reserves) = FindReserves($biblio); - foreach my $rec (@$reserves) { - if ($rec->{'priority'} > $priority) { - # FIXME - Rewrite this without so much duplication and - # redundancy - 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; - } + 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; } } -# XXX - POD +#------------------------------------------------------------------------------------- + +=item ReserveWaiting + +branchcode = &ReserveWaiting($item,$borr); +this function set FOUND to 'W' for Waiting into the database. + +=cut + sub ReserveWaiting { - my ($item, $borr) = @_; + my ( $item, $borr,$diffBranchSend ) = @_; my $dbh = C4::Context->dbh; - $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, - reserves.timestamp as timestamp - 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)"; + + # 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 $biblio = $data->{'biblionumber'}; my $timestamp = $data->{'timestamp'}; - my $q_biblio = $dbh->quote($biblio); - my $q_timestamp = $dbh->quote($timestamp); - warn "Timestamp: ".$timestamp."\n"; -# update reserves record.... - $query = "UPDATE reserves SET priority = 0, found = 'W', itemnumber = $item - WHERE borrowernumber = $borr - AND biblionumber = $q_biblio - AND timestamp = $q_timestamp"; - warn "Query: ".$query."\n"; + + # 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; -# 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; } -# XXX - POD -sub CheckWaiting { - my ($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; - $borr = $dbh->quote($borr); 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(); - # FIXME - Use 'push' - 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 - ($count, @results) = &Findgroupreserve($biblioitemnumber, $biblionumber); + @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 a two-element array: - -C<$count> is the number of elements in C<@results>. - +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 = C4::Context->dbh; - $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; - # FIXME - $i is unnecessary and bogus - my $i=0; - my @results; - while (my $data=$sth->fetchrow_hashref){ - $results[$i]=$data; # FIXME - Use push - $i++; - } - $sth->finish; - 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; } -# FIXME - A somewhat different version of this function appears in -# C4::Reserves. Pick one and stick with it. -# XXX - POD +=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,$borrnum,$biblionumber,$constraint,$bibitems,$priority,$notes,$title)= @_; - my $fee=CalcReserveFee($env,$borrnum,$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]; - #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 ( + $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(); + $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; - 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 = C4::Context->dbh; - my $const = lc substr($constraint,0,1); - my $query = "SELECT * FROM borrowers,categories - WHERE (borrowernumber = ?) - AND (borrowers.categorycode = categories.categorycode)"; - my $sth = $dbh->prepare($query); - $sth->execute($borrnum); - 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 + 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)"; - my $sth1 = $dbh->prepare($query1); - $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 $query2 = "SELECT * FROM items - WHERE biblioitemnumber = ?"; - my $sth2 = $dbh->prepare($query2); - $sth2->execute($bitdata->{'biblioitemnumber'}); - while (my $itdata=$sth2->fetchrow_hashref) { - my $query3 = "SELECT * FROM issues + 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"; - - my $sth3 = $dbh->prepare($query3); - $sth3->execute($itdata->{'itemnumber'}); - if (my $isdata=$sth3->fetchrow_hashref) { - } else { - $allissued = 0; - } - } - $x++; - } - if ($allissued == 0) { - my $rquery = "SELECT * FROM reserves WHERE biblionumber = ?"; - my $rsth = $dbh->prepare($rquery); - $rsth->execute($biblionumber); - if (my $rdata = $rsth->fetchrow_hashref) { - } else { - $fee = 0; - } + 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; + + # print "fee $fee"; + return $fee; } -# XXX - Internal use -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); +# 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; } -# XXX - POD -sub updatereserves{ - #subroutine to update a reserve - my ($rank,$biblio,$borrower,$del,$branch)=@_; - my $dbh = C4::Context->dbh; - 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; +=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; + return ($nextaccntno); } -# XXX - POD +#------------------------------------------------------------------------------------- + +=item UpdateReserve + +&UpdateReserve($rank,$biblio,$borrower,$branch) + +=cut + sub UpdateReserve { #subroutine to update a reserve - my ($rank,$biblio,$borrower,$branch)=@_; - return if $rank eq "W"; - return if $rank eq "n"; + 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 = "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 = "UPDATE reserves SET priority = ? ,branchcode = ?, itemnumber = NULL, 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, $biblio, $borrower); - $sth->finish; + 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); } } -# XXX - POD -sub getreservetitle { - my ($biblio,$bor,$date,$timestamp)=@_; - my $dbh = C4::Context->dbh; - 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; -# print $query; - return($data); +=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 +