Bug 8307: QA Followup for finishreceive.pl
[koha.git] / C4 / Reserves.pm
index 7f95a26..d1bca25 100644 (file)
@@ -131,6 +131,8 @@ BEGIN {
         &ReserveSlip
         &ToggleSuspend
         &SuspendAll
+
+        &GetReservesControlBranch
     );
     @EXPORT_OK = qw( MergeHolds );
 }    
@@ -213,6 +215,7 @@ sub AddReserve {
                 'branches'  => $branch_details,
                 'borrowers' => $borrower,
                 'biblio'    => $biblionumber,
+                'items'     => $checkitem,
             },
         ) ) {
 
@@ -253,7 +256,6 @@ sub AddReserve {
 
 sub GetReserve {
     my ($reserve_id) = @_;
-    #warn "C4::Reserves::GetReserve( $reserve_id )";
 
     my $dbh = C4::Context->dbh;
     my $query = "SELECT * FROM reserves WHERE reserve_id = ?";
@@ -275,9 +277,11 @@ of the reserves and an arrayref pointing to the reserves for C<$biblionumber>.
 sub GetReservesFromBiblionumber {
     my ($biblionumber) = shift or return (0, []);
     my ($all_dates) = shift;
+    my ($itemnumber) = shift;
     my $dbh   = C4::Context->dbh;
 
     # Find the desired items in the reserves
+    my @params;
     my $query = "
         SELECT  reserve_id,
                 branchcode,
@@ -296,12 +300,17 @@ sub GetReservesFromBiblionumber {
                 suspend_until
         FROM     reserves
         WHERE biblionumber = ? ";
+    push( @params, $biblionumber );
     unless ( $all_dates ) {
-        $query .= "AND reservedate <= CURRENT_DATE()";
+        $query .= " AND reservedate <= CAST(NOW() AS DATE) ";
+    }
+    if ( $itemnumber ) {
+        $query .= " AND ( itemnumber IS NULL OR itemnumber = ? )";
+        push( @params, $itemnumber );
     }
     $query .= "ORDER BY priority";
     my $sth = $dbh->prepare($query);
-    $sth->execute($biblionumber);
+    $sth->execute( @params );
     my @results;
     my $i = 0;
     while ( my $data = $sth->fetchrow_hashref ) {
@@ -511,11 +520,22 @@ sub CanItemBeReserved{
     }
     
     # we check if it's ok or not
-    if( $reservecount < $allowedreserves ){
-        return 1;
-    }else{
+    if( $reservecount >= $allowedreserves ){
         return 0;
     }
+
+    # If reservecount is ok, we check item branch if IndependentBranches is ON
+    # and canreservefromotherbranches is OFF
+    if ( C4::Context->preference('IndependentBranches')
+        and !C4::Context->preference('canreservefromotherbranches') )
+    {
+        my $itembranch = $item->{homebranch};
+        if ($itembranch ne $borrower->{branchcode}) {
+            return 0;
+        }
+    }
+
+    return 1;
 }
 #--------------------------------------------------------------------------------
 =head2 GetReserveCount
@@ -612,7 +632,6 @@ sub GetReserveFee {
     my $sth = $dbh->prepare($query);
     $sth->execute($borrowernumber);
     my $data = $sth->fetchrow_hashref;
-    $sth->finish();
     my $fee      = $data->{'reservefee'};
     my $cntitems = @- > $bibitems;
 
@@ -653,7 +672,6 @@ sub GetReserveFee {
                 }
             }
         }
-        $sth1->finish;
         my $cntitemsfound = @biblioitems;
         my $issues        = 0;
         my $x             = 0;
@@ -789,20 +807,23 @@ sub GetReserveStatus {
     if(defined $found) {
         return 'Waiting'  if $found eq 'W' and $priority == 0;
         return 'Finished' if $found eq 'F';
-        return 'Reserved' if $priority > 0;
     }
-    return '';
-    #empty string here will remove need for checking undef, or less log lines
+
+    return 'Reserved' if $priority > 0;
+
+    return ''; # empty string here will remove need for checking undef, or less log lines
 }
 
 =head2 CheckReserves
 
   ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber);
   ($status, $reserve, $all_reserves) = &CheckReserves(undef, $barcode);
+  ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber,undef,$lookahead);
 
 Find a book in the reserves.
 
 C<$itemnumber> is the book's item number.
+C<$lookahead> is the number of days to look in advance for future reserves.
 
 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
@@ -823,7 +844,7 @@ table in the Koha database.
 =cut
 
 sub CheckReserves {
-    my ( $item, $barcode ) = @_;
+    my ( $item, $barcode, $lookahead_days) = @_;
     my $dbh = C4::Context->dbh;
     my $sth;
     my $select;
@@ -870,7 +891,7 @@ sub CheckReserves {
     return ( '' ) if  ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
 
     # Find this item in the reserves
-    my @reserves = _Findgroupreserve( $bibitem, $biblio, $itemnumber );
+    my @reserves = _Findgroupreserve( $bibitem, $biblio, $itemnumber, $lookahead_days);
 
     # $priority and $highest are used to find the most important item
     # in the list returned by &_Findgroupreserve. (The lower $priority,
@@ -887,7 +908,7 @@ sub CheckReserves {
                 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 $branch = GetReservesControlBranch( $iteminfo, $borrowerinfo );
                     my $branchitemrule = C4::Circulation::GetBranchItemRule($branch,$iteminfo->{'itype'});
                     next if ($branchitemrule->{'holdallowed'} == 0);
                     next if (($branchitemrule->{'holdallowed'} == 1) && ($branch ne $borrowerinfo->{'branchcode'}));
@@ -996,7 +1017,6 @@ sub CancelReserve {
     ";
     my $sth = $dbh->prepare($query);
     $sth->execute( $reserve_id );
-    $sth->finish;
 
     $query = "
         INSERT INTO old_reserves
@@ -1079,7 +1099,6 @@ sub ModReserve {
         ";
         my $sth = $dbh->prepare($query);
         $sth->execute( $reserve_id );
-        $sth->finish;
         $query = "
             INSERT INTO old_reserves
             SELECT *
@@ -1103,7 +1122,6 @@ sub ModReserve {
         ";
         my $sth = $dbh->prepare($query);
         $sth->execute( $rank, $branchcode, $itemnumber, $reserve_id );
-        $sth->finish;
 
         if ( defined( $suspend_until ) ) {
             if ( $suspend_until ) {
@@ -1149,7 +1167,6 @@ sub ModReserveFill {
     my $sth = $dbh->prepare($query);
     $sth->execute( $biblionumber, $borrowernumber, $resdate );
     ($priority) = $sth->fetchrow_array;
-    $sth->finish;
 
     # update the database...
     $query = "UPDATE reserves
@@ -1161,7 +1178,6 @@ sub ModReserveFill {
                 ";
     $sth = $dbh->prepare($query);
     $sth->execute( $biblionumber, $resdate, $borrowernumber );
-    $sth->finish;
 
     # move to old_reserves
     $query = "INSERT INTO old_reserves
@@ -1439,7 +1455,7 @@ sub IsAvailableForItemLevelRequest {
     $available_per_item = 0 if $item->{itemlost} or
                                ( $item->{notforloan} > 0 ) or
                                ($item->{damaged} and not C4::Context->preference('AllowHoldsOnDamagedItems')) or
-                               $item->{wthdrawn} or
+                               $item->{withdrawn} or
                                $notforloan_per_itemtype;
 
 
@@ -1503,7 +1519,6 @@ sub ToggleLowestPriority {
 
     my $sth = $dbh->prepare( "UPDATE reserves SET lowestPriority = NOT lowestPriority WHERE reserve_id = ?");
     $sth->execute( $reserve_id );
-    $sth->finish;
     
     _FixPriority( $reserve_id, '999999' );
 }
@@ -1521,7 +1536,7 @@ be cleared when it is unsuspended.
 sub ToggleSuspend {
     my ( $reserve_id, $suspend_until ) = @_;
 
-    $suspend_until = output_pref( dt_from_string( $suspend_until ), 'iso' ) if ( $suspend_until );
+    $suspend_until = output_pref({ dt => dt_from_string( $suspend_until ), dateformat => 'iso' }) if ( $suspend_until );
 
     my $do_until = ( $suspend_until ) ? '?' : 'NULL';
 
@@ -1538,7 +1553,6 @@ sub ToggleSuspend {
     push( @params, $reserve_id );
 
     $sth->execute( @params );
-    $sth->finish;
 }
 
 =head2 SuspendAll
@@ -1594,7 +1608,6 @@ sub SuspendAll {
     $dbh = C4::Context->dbh;
     $sth = $dbh->prepare( $query );
     $sth->execute( @query_params );
-    $sth->finish;
 }
 
 
@@ -1678,7 +1691,6 @@ sub _FixPriority {
             $j + 1,
             $priority[$j]->{'reserve_id'}
         );
-        $sth->finish;
     }
     
     $sth = $dbh->prepare( "SELECT reserve_id FROM reserves WHERE lowestPriority = 1 ORDER BY priority" );
@@ -1693,11 +1705,12 @@ sub _FixPriority {
 
 =head2 _Findgroupreserve
 
-  @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber);
+  @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber, $lookahead);
 
 Looks for an item-specific match first, then for a title-level match, returning the
 first match found.  If neither, then we look for a 3rd kind of match based on
 reserve constraints.
+Lookahead is the number of days to look in advance.
 
 TODO: add more explanation about reserve constraints
 
@@ -1709,7 +1722,7 @@ C<biblioitemnumber>.
 =cut
 
 sub _Findgroupreserve {
-    my ( $bibitem, $biblio, $itemnumber ) = @_;
+    my ( $bibitem, $biblio, $itemnumber, $lookahead) = @_;
     my $dbh   = C4::Context->dbh;
 
     # TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var.
@@ -1734,11 +1747,11 @@ sub _Findgroupreserve {
         AND priority > 0
         AND item_level_request = 1
         AND itemnumber = ?
-        AND reservedate <= CURRENT_DATE()
+        AND reservedate <= DATE_ADD(NOW(),INTERVAL ? DAY)
         AND suspend = 0
     /;
     my $sth = $dbh->prepare($item_level_target_query);
-    $sth->execute($itemnumber);
+    $sth->execute($itemnumber, $lookahead||0);
     my @results;
     if ( my $data = $sth->fetchrow_hashref ) {
         push( @results, $data );
@@ -1765,11 +1778,11 @@ sub _Findgroupreserve {
         AND priority > 0
         AND item_level_request = 0
         AND hold_fill_targets.itemnumber = ?
-        AND reservedate <= CURRENT_DATE()
+        AND reservedate <= DATE_ADD(NOW(),INTERVAL ? DAY)
         AND suspend = 0
     /;
     $sth = $dbh->prepare($title_level_target_query);
-    $sth->execute($itemnumber);
+    $sth->execute($itemnumber, $lookahead||0);
     @results = ();
     if ( my $data = $sth->fetchrow_hashref ) {
         push( @results, $data );
@@ -1797,11 +1810,11 @@ sub _Findgroupreserve {
           AND reserves.reservedate    = reserveconstraints.reservedate )
           OR  reserves.constrainttype='a' )
           AND (reserves.itemnumber IS NULL OR reserves.itemnumber = ?)
-          AND reserves.reservedate <= CURRENT_DATE()
+          AND reserves.reservedate <= DATE_ADD(NOW(),INTERVAL ? DAY)
           AND suspend = 0
     /;
     $sth = $dbh->prepare($query);
-    $sth->execute( $biblio, $bibitem, $itemnumber );
+    $sth->execute( $biblio, $bibitem, $itemnumber, $lookahead||0);
     @results = ();
     while ( my $data = $sth->fetchrow_hashref ) {
         push( @results, $data );
@@ -2155,8 +2168,11 @@ sub ReserveSlip {
 
 #   return unless ( C4::Context->boolean_preference('printreserveslips') );
 
-    my $reserve = GetReserveInfo($borrowernumber,$biblionumber )
-      or return;
+    my $reserve_id = GetReserveId({
+        biblionumber => $biblionumber,
+        borrowernumber => $borrowernumber
+    }) or return;
+    my $reserve = GetReserveInfo($reserve_id) or return;
 
     return  C4::Letters::GetPreparedLetter (
         module => 'circulation',
@@ -2172,6 +2188,32 @@ sub ReserveSlip {
     );
 }
 
+=head2 GetReservesControlBranch
+
+  my $reserves_control_branch = GetReservesControlBranch($item, $borrower);
+
+  Return the branchcode to be used to determine which reserves
+  policy applies to a transaction.
+
+  C<$item> is a hashref for an item. Only 'homebranch' is used.
+
+  C<$borrower> is a hashref to borrower. Only 'branchcode' is used.
+
+=cut
+
+sub GetReservesControlBranch {
+    my ( $item, $borrower ) = @_;
+
+    my $reserves_control = C4::Context->preference('ReservesControlBranch');
+
+    my $branchcode =
+        ( $reserves_control eq 'ItemHomeLibrary' ) ? $item->{'homebranch'}
+      : ( $reserves_control eq 'PatronLibrary' )   ? $borrower->{'branchcode'}
+      :                                              undef;
+
+    return $branchcode;
+}
+
 =head1 AUTHOR
 
 Koha Development Team <http://koha-community.org/>