Bug 9987: Remove DB field aqorders.biblioitemnunmber
[koha.git] / C4 / Reserves.pm
index 585d1e5..5ff12e4 100644 (file)
@@ -735,16 +735,40 @@ sub GetReservesForBranch {
     return (@transreserv);
 }
 
+=head2 GetReserveStatus
+
+  $reservestatus = GetReserveStatus($itemnumber, $biblionumber);
+
+Take an itemnumber or a biblionumber and return the status of the reserve places on it.
+If several reserves exist, the reserve with the lower priority is given.
+
+=cut
+
 sub GetReserveStatus {
-    my ($itemnumber) = @_;
-    
+    my ($itemnumber, $biblionumber) = @_;
+
     my $dbh = C4::Context->dbh;
-    
-    my $itemstatus = $dbh->prepare("SELECT found FROM reserves WHERE itemnumber = ?");
-    
-    $itemstatus->execute($itemnumber);
-    my ($found) = $itemstatus->fetchrow_array;
-    return $found;
+
+    my ($sth, $found, $priority);
+    if ( $itemnumber ) {
+        $sth = $dbh->prepare("SELECT found, priority FROM reserves WHERE itemnumber = ? order by priority LIMIT 1");
+        $sth->execute($itemnumber);
+        ($found, $priority) = $sth->fetchrow_array;
+    }
+
+    if ( $biblionumber and not defined $found and not defined $priority ) {
+        $sth = $dbh->prepare("SELECT found, priority FROM reserves WHERE biblionumber = ? order by priority LIMIT 1");
+        $sth->execute($biblionumber);
+        ($found, $priority) = $sth->fetchrow_array;
+    }
+
+    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
 }
 
 =head2 CheckReserves
@@ -1395,7 +1419,7 @@ be the target of an item-level hold request.
 Note that IsAvailableForItemLevelRequest() does not
 check if the staff operator is authorized to place
 a request on the item - in particular,
-this routine does not check IndependantBranches
+this routine does not check IndependentBranches
 and canreservefromotherbranches.
 
 =cut
@@ -1441,7 +1465,7 @@ sub IsAvailableForItemLevelRequest {
     if (C4::Context->preference('AllowOnShelfHolds')) {
         return $available_per_item;
     } else {
-        return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W")); 
+        return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "Waiting"));
     }
 }
 
@@ -1835,14 +1859,7 @@ sub _koha_notify_reserve {
     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 $to_address = C4::Members::GetNoticeEmailAddress($borrowernumber);
     
     my $letter_code;
     my $print_mode = 0;
@@ -2007,7 +2024,10 @@ sub MoveReserve {
             ModReserveFill($borr_res);
         }
 
-        if ($cancelreserve) { # cancel reserves on this item
+        if ( $cancelreserve eq 'revert' ) { ## Revert waiting reserve to priority 1
+            RevertWaitingStatus({ itemnumber => $itemnumber });
+        }
+        elsif ( $cancelreserve eq 'cancel' || $cancelreserve ) { # cancel reserves on this item
             CancelReserve(0, $res->{'itemnumber'}, $res->{'borrowernumber'});
             CancelReserve($res->{'biblionumber'}, 0, $res->{'borrowernumber'});
         }
@@ -2058,6 +2078,66 @@ sub MergeHolds {
     }
 }
 
+=head2 RevertWaitingStatus
+
+  $success = RevertWaitingStatus({ itemnumber => $itemnumber });
+
+  Reverts a 'waiting' hold back to a regular hold with a priority of 1.
+
+  Caveat: Any waiting hold fixed with RevertWaitingStatus will be an
+          item level hold, even if it was only a bibliolevel hold to
+          begin with. This is because we can no longer know if a hold
+          was item-level or bib-level after a hold has been set to
+          waiting status.
+
+=cut
+
+sub RevertWaitingStatus {
+    my ( $params ) = @_;
+    my $itemnumber = $params->{'itemnumber'};
+
+    return unless ( $itemnumber );
+
+    my $dbh = C4::Context->dbh;
+
+    ## Get the waiting reserve we want to revert
+    my $query = "
+        SELECT * FROM reserves
+        WHERE itemnumber = ?
+        AND found IS NOT NULL
+    ";
+    my $sth = $dbh->prepare( $query );
+    $sth->execute( $itemnumber );
+    my $reserve = $sth->fetchrow_hashref();
+
+    ## Increment the priority of all other non-waiting
+    ## reserves for this bib record
+    $query = "
+        UPDATE reserves
+        SET
+          priority = priority + 1
+        WHERE
+          biblionumber =  ?
+        AND
+          priority > 0
+    ";
+    $sth = $dbh->prepare( $query );
+    $sth->execute( $reserve->{'biblionumber'} );
+
+    ## Fix up the currently waiting reserve
+    $query = "
+    UPDATE reserves
+    SET
+      priority = 1,
+      found = NULL,
+      waitingdate = NULL
+    WHERE
+      reserve_id = ?
+    ";
+    $sth = $dbh->prepare( $query );
+    return $sth->execute( $reserve->{'reserve_id'} );
+}
+
 =head2 ReserveSlip
 
   ReserveSlip($branchcode, $borrowernumber, $biblionumber)
@@ -2081,9 +2161,9 @@ sub ReserveSlip {
         tables => {
             'reserves'    => $reserve,
             'branches'    => $reserve->{branchcode},
-            'borrowers'   => $reserve,
-            'biblio'      => $reserve,
-            'items'       => $reserve,
+            'borrowers'   => $reserve->{borrowernumber},
+            'biblio'      => $reserve->{biblionumber},
+            'items'       => $reserve->{itemnumber},
         },
     );
 }