# Copyright 2000-2002 Katipo Communications
# 2006 SAN Ouest Provence
# 2007-2010 BibLibre Paul POULAIN
+# 2011 Catalyst IT
#
# This file is part of Koha.
#
use C4::Biblio;
use C4::Members;
use C4::Items;
-use C4::Search;
use C4::Circulation;
use C4::Accounts;
BEGIN {
# set the version for version checking
$VERSION = 3.01;
- require Exporter;
+ require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(
&AddReserve
&ModReserveStatus
&ModReserveCancelAll
&ModReserveMinusPriority
+ &MoveReserve
&CheckReserves
&CanBookBeReserved
&AlterPriority
&ToggleLowestPriority
);
+ @EXPORT_OK = qw( MergeHolds );
}
=head2 AddReserve
sub CanBookBeReserved{
my ($borrowernumber, $biblionumber) = @_;
- my @items = GetItemsInfo($biblionumber);
+ my @items = get_itemnumbers_of($biblionumber);
+ #get items linked via host records
+ my @hostitems = get_hostitemnumbers_of($biblionumber);
+ if (@hostitems){
+ push (@items,@hostitems);
+ }
+
foreach my $item (@items){
- return 1 if CanItemBeReserved($borrowernumber, $item->{itemnumber});
+ return 1 if CanItemBeReserved($borrowernumber, $item);
}
return 0;
}
my ($itemnumber) = @_;
my $messages;
my $nextreservinfo;
- my ( $restype, $checkreserves ) = CheckReserves($itemnumber);
+ my ( undef, $checkreserves, undef ) = CheckReserves($itemnumber);
if ($checkreserves) {
my $iteminfo = GetItem($itemnumber);
if ( $iteminfo->{'holdingbranch'} ne $checkreserves->{'branchcode'} ) {
=head2 CheckReserves
- ($status, $reserve) = &CheckReserves($itemnumber);
- ($status, $reserve) = &CheckReserves(undef, $barcode);
+ ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber);
+ ($status, $reserve, $all_reserves) = &CheckReserves(undef, $barcode);
Find a book in the reserves.
# note: we get the itemnumber because we might have started w/ just the barcode. Now we know for sure we have it.
my ( $biblio, $bibitem, $notforloan_per_itemtype, $notforloan_per_item, $itemnumber ) = $sth->fetchrow_array;
- return ( 0, 0 ) unless $itemnumber; # bail if we got nothing.
+ return ( '' ) unless $itemnumber; # bail if we got nothing.
# if item is not for loan it cannot be reserved either.....
# execpt where items.notforloan < 0 : This indicates the item is holdable.
- return ( 0, 0 ) if ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
+ return ( '' ) if ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
# Find this item in the reserves
my @reserves = _Findgroupreserve( $bibitem, $biblio, $itemnumber );
my $priority = 10000000;
foreach my $res (@reserves) {
if ( $res->{'itemnumber'} == $itemnumber && $res->{'priority'} == 0) {
- return ( "Waiting", $res ); # Found it
+ return ( "Waiting", $res, \@reserves ); # Found it
} else {
# See if this item is more important than what we've got so far
if ( $res->{'priority'} && $res->{'priority'} < $priority ) {
- my $borrowerinfo=C4::Members::GetMemberDetails($res->{'borrowernumber'});
+ my $borrowerinfo=C4::Members::GetMember(borrowernumber => $res->{'borrowernumber'});
my $iteminfo=C4::Items::GetItem($itemnumber);
my $branch=C4::Circulation::_GetCircControlBranch($iteminfo,$borrowerinfo);
my $branchitemrule = C4::Circulation::GetBranchItemRule($branch,$iteminfo->{'itype'});
# We return the most important (i.e. next) reservation.
if ($highest) {
$highest->{'itemnumber'} = $item;
- return ( "Reserved", $highest );
- }
- else {
- return ( 0, 0 );
+ return ( "Reserved", $highest, \@reserves );
}
+
+ return ( '' );
}
=head2 CancelExpiredReserves
return $new_priority; # so the caller knows what priority they wind up receiving
}
+=head2 MoveReserve
+
+ MoveReserve( $itemnumber, $borrowernumber, $cancelreserve )
+
+Use when checking out an item to handle reserves
+If $cancelreserve boolean is set to true, it will remove existing reserve
+
+=cut
+
+sub MoveReserve {
+ my ( $itemnumber, $borrowernumber, $cancelreserve ) = @_;
+
+ my ( $restype, $res, $all_reserves ) = CheckReserves( $itemnumber );
+ return unless $res;
+
+ my $biblionumber = $res->{biblionumber};
+ my $biblioitemnumber = $res->{biblioitemnumber};
+
+ if ($res->{borrowernumber} == $borrowernumber) {
+ ModReserveFill($res);
+ }
+ else {
+ # warn "Reserved";
+ # The item is reserved by someone else.
+ # Find this item in the reserves
+
+ my $borr_res;
+ foreach (@$all_reserves) {
+ $_->{'borrowernumber'} == $borrowernumber or next;
+ $_->{'biblionumber'} == $biblionumber or next;
+
+ $borr_res = $_;
+ last;
+ }
+
+ if ( $borr_res ) {
+ # The item is reserved by the current patron
+ ModReserveFill($borr_res);
+ }
+
+ if ($cancelreserve) { # cancel reserves on this item
+ CancelReserve(0, $res->{'itemnumber'}, $res->{'borrowernumber'});
+ CancelReserve($res->{'biblionumber'}, 0, $res->{'borrowernumber'});
+ }
+ }
+}
+
+=head2 MergeHolds
+
+ MergeHolds($dbh,$to_biblio, $from_biblio);
+
+This shifts the holds from C<$from_biblio> to C<$to_biblio> and reorders them by the date they were placed
+
+=cut
+
+sub MergeHolds {
+ my ( $dbh, $to_biblio, $from_biblio ) = @_;
+ my $sth = $dbh->prepare(
+ "SELECT count(*) as reservenumber FROM reserves WHERE biblionumber = ?"
+ );
+ $sth->execute($from_biblio);
+ if ( my $data = $sth->fetchrow_hashref() ) {
+
+ # holds exist on old record, if not we don't need to do anything
+ $sth = $dbh->prepare(
+ "UPDATE reserves SET biblionumber = ? WHERE biblionumber = ?");
+ $sth->execute( $to_biblio, $from_biblio );
+
+ # Reorder by date
+ # don't reorder those already waiting
+
+ $sth = $dbh->prepare(
+"SELECT * FROM reserves WHERE biblionumber = ? AND (found <> ? AND found <> ? OR found is NULL) ORDER BY reservedate ASC"
+ );
+ my $upd_sth = $dbh->prepare(
+"UPDATE reserves SET priority = ? WHERE biblionumber = ? AND borrowernumber = ?
+ AND reservedate = ? AND constrainttype = ? AND (itemnumber = ? or itemnumber is NULL) "
+ );
+ $sth->execute( $to_biblio, 'W', 'T' );
+ my $priority = 1;
+ while ( my $reserve = $sth->fetchrow_hashref() ) {
+ $upd_sth->execute(
+ $priority, $to_biblio,
+ $reserve->{'borrowernumber'}, $reserve->{'reservedate'},
+ $reserve->{'constrainttype'}, $reserve->{'itemnumber'}
+ );
+ $priority++;
+ }
+ }
+}
+
+
=head1 AUTHOR
Koha Development Team <http://koha-community.org/>