X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FReserves.pm;h=359bbad97bcd729acc38a8ab4bfb30abece7ccc9;hb=2202ee78c3abf41aa46d131036b1a4162c8faf35;hp=2dd2688fcdc454dc75bd2a2d2539aa5547fc9d32;hpb=b06a289173d0f2e299b0c8652d59d47dc196062c;p=koha_gimpoz diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 2dd2688fcd..359bbad97b 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -2,7 +2,8 @@ package C4::Reserves; # Copyright 2000-2002 Katipo Communications # 2006 SAN Ouest Provence -# 2007 BibLibre Paul POULAIN +# 2007-2010 BibLibre Paul POULAIN +# 2011 Catalyst IT # # This file is part of Koha. # @@ -26,7 +27,6 @@ use C4::Context; use C4::Biblio; use C4::Members; use C4::Items; -use C4::Search; use C4::Circulation; use C4::Accounts; @@ -86,7 +86,7 @@ This modules provides somes functions to deal with reservations. BEGIN { # set the version for version checking $VERSION = 3.01; - require Exporter; + require Exporter; @ISA = qw(Exporter); @EXPORT = qw( &AddReserve @@ -109,6 +109,7 @@ BEGIN { &ModReserveStatus &ModReserveCancelAll &ModReserveMinusPriority + &MoveReserve &CheckReserves &CanBookBeReserved @@ -121,6 +122,7 @@ BEGIN { &AlterPriority &ToggleLowestPriority ); + @EXPORT_OK = qw( MergeHolds ); } =head2 AddReserve @@ -382,9 +384,15 @@ sub GetReservesFromBorrowernumber { 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; } @@ -516,7 +524,7 @@ sub GetOtherReserves { 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'} ) { @@ -731,8 +739,8 @@ sub GetReserveStatus { =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. @@ -760,17 +768,32 @@ sub CheckReserves { my ( $item, $barcode ) = @_; my $dbh = C4::Context->dbh; my $sth; - my $select = " - SELECT items.biblionumber, + my $select; + if (C4::Context->preference('item-level_itypes')){ + $select = " + SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan, items.notforloan AS itemnotforloan, items.itemnumber - FROM items - LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber - LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype - "; - + FROM items + LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber + LEFT JOIN itemtypes ON items.itype = itemtypes.itemtype + "; + } + else { + $select = " + SELECT items.biblionumber, + items.biblioitemnumber, + itemtypes.notforloan, + items.notforloan AS itemnotforloan, + items.itemnumber + FROM items + LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber + LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype + "; + } + if ($item) { $sth = $dbh->prepare("$select WHERE itemnumber = ?"); $sth->execute($item); @@ -782,11 +805,11 @@ sub CheckReserves { # 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 ); @@ -800,10 +823,16 @@ sub CheckReserves { 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::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'}); + next if ($branchitemrule->{'holdallowed'} == 0); + next if (($branchitemrule->{'holdallowed'} == 1) && ($branch ne $borrowerinfo->{'branchcode'})); $priority = $res->{'priority'}; $highest = $res; } @@ -815,11 +844,10 @@ sub CheckReserves { # 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 @@ -1656,11 +1684,22 @@ sub _koha_notify_reserve { my $dbh = C4::Context->dbh; my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); + + # Try to get the borrower's email address + my $to_address; + my $which_address = C4::Context->preference('AutoEmailPrimaryAddress'); + # If the system preference is set to 'first valid' (value == OFF), look up email address + if ($which_address eq 'OFF') { + $to_address = C4::Members::GetFirstValidEmailAddress( $borrowernumber ); + } else { + $to_address = $borrower->{$which_address}; + } + my $letter_code; my $print_mode = 0; my $messagingprefs; - if ( $borrower->{'email'} || $borrower->{'smsalertnumber'} ) { - $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'Hold Filled' } ); + if ( $to_address || $borrower->{'smsalertnumber'} ) { + $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'Hold_Filled' } ); return if ( !defined( $messagingprefs->{'letter_code'} ) ); $letter_code = $messagingprefs->{'letter_code'}; @@ -1777,6 +1816,98 @@ sub _ShiftPriorityByDateAndPriority { 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