From 6053e2ed8f2b0f40a7b5fdc9927954faf88490fb Mon Sep 17 00:00:00 2001
From: Julian Maurice <julian.maurice@biblibre.com>
Date: Wed, 3 Oct 2012 13:23:04 +0200
Subject: [PATCH] Bug 8868: ILS-DI: CancelHold needs to take a reserve_id

CancelHold takes two parameters: patron_id and item_id.
If item_id is considered as an itemnumber, holds on title can't be
canceled.
If item_id is considered as a biblionumber, all holds on this
biblionumber (for a borrower) will be canceled.

So CancelHold have to consider item_id as a reserve_id.

Added subroutines C4::Reserves::GetReserve and
C4::Reserves::CancelReserveFromId
C4::ILSDI::Services::GetRecords now returns the reserve_id

Signed-off-by: Leila and Sonia <koha.aixmarseille@gmail.com>
---
 C4/ILSDI/Services.pm |   30 +++++------------
 C4/Reserves.pm       |   83 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 91 insertions(+), 22 deletions(-)

diff --git a/C4/ILSDI/Services.pm b/C4/ILSDI/Services.pm
index 68cbdb3..aa9ba11 100644
--- a/C4/ILSDI/Services.pm
+++ b/C4/ILSDI/Services.pm
@@ -26,7 +26,7 @@ use C4::Circulation;
 use C4::Branch;
 use C4::Accounts;
 use C4::Biblio;
-use C4::Reserves qw(AddReserve CancelReserve GetReservesFromBiblionumber GetReservesFromBorrowernumber CanBookBeReserved CanItemBeReserved);
+use C4::Reserves qw(AddReserve GetReservesFromBiblionumber GetReservesFromBorrowernumber CanBookBeReserved CanItemBeReserved);
 use C4::Context;
 use C4::AuthoritiesMarc;
 use C4::ILSDI::Utility;
@@ -730,9 +730,9 @@ Cancels an active reserve request for the borrower.
 Parameters:
 
   - patron_id (Required)
-	a borrowernumber
+        a borrowernumber
   - item_id (Required)
-	an itemnumber 
+        a reserve_id
 
 =cut
 
@@ -744,25 +744,13 @@ sub CancelHold {
     my $borrower = GetMemberDetails( $borrowernumber );
     return { code => 'PatronNotFound' } unless $$borrower{borrowernumber};
 
-    # Get the item or return an error code
-    my $itemnumber = $cgi->param('item_id');
-    my $item = GetItem( $itemnumber );
-    return { code => 'RecordNotFound' } unless $$item{itemnumber};
-
-    # Get borrower's reserves
-    my @reserves = GetReservesFromBorrowernumber( $borrowernumber, undef );
-    my @reserveditems;
-
-    # ...and loop over it to build an array of reserved itemnumbers
-    foreach my $reserve (@reserves) {
-        push @reserveditems, $reserve->{'itemnumber'};
-    }
-
-    # if the item was not reserved by the borrower, returns an error code
-    return { code => 'NotCanceled' } unless any { $itemnumber eq $_ } @reserveditems;
+    # Get the reserve or return an error code
+    my $reserve_id = $cgi->param('item_id');
+    my $reserve = C4::Reserves::GetReserve($reserve_id);
+    return { code => 'RecordNotFound' } unless $reserve;
+    return { code => 'RecordNotFound' } unless ($reserve->{borrowernumber} == $borrowernumber);
 
-    # Cancel the reserve
-    CancelReserve( $itemnumber, undef, $borrowernumber );
+    C4::Reserves::CancelReserveFromId($reserve_id);
 
     return { code => 'Canceled' };
 }
diff --git a/C4/Reserves.pm b/C4/Reserves.pm
index ba12cf5..fbc547f 100644
--- a/C4/Reserves.pm
+++ b/C4/Reserves.pm
@@ -103,6 +103,7 @@ BEGIN {
         &GetReserveFee
         &GetReserveInfo
         &GetReserveStatus
+        &GetReserve
         
         &GetOtherReserves
         
@@ -118,6 +119,7 @@ BEGIN {
         &CanBookBeReserved
 	&CanItemBeReserved
         &CancelReserve
+        &CancelReserveFromId
         &CancelExpiredReserves
 
         &AutoUnsuspendReserves
@@ -260,7 +262,8 @@ sub GetReservesFromBiblionumber {
 
     # Find the desired items in the reserves
     my $query = "
-        SELECT  branchcode,
+        SELECT  reserve_id,
+                branchcode,
                 timestamp AS rtimestamp,
                 priority,
                 biblionumber,
@@ -771,6 +774,34 @@ sub GetReserveStatus {
     #empty string here will remove need for checking undef, or less log lines
 }
 
+=head2 GetReserve
+
+    my $reserve = C4::Reserves::GetReserve($reserve_id);
+
+Take a reserve_id and returns a hashref containing reserve informations.
+Return undef if reserve_id doesn't exist.
+
+=cut
+
+sub GetReserve {
+    my ($reserve_id) = @_;
+
+    return unless $reserve_id;
+
+    my $dbh = C4::Context->dbh;
+    my $query = qq{
+        SELECT *
+        FROM reserves
+        WHERE reserve_id = ?
+    };
+    my $sth = $dbh->prepare($query);
+
+    $sth->execute($reserve_id);
+    my $reserve = $sth->fetchrow_hashref;
+
+    return $reserve;
+}
+
 =head2 CheckReserves
 
   ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber);
@@ -1047,6 +1078,56 @@ sub CancelReserve {
     }
 }
 
+=head2 CancelReserveFromId
+
+    C4::Reserves::CancelReserveFromId($reserve_id);
+
+Cancel a reserve, given its reserve_id
+
+=cut
+
+sub CancelReserveFromId {
+    my ($reserve_id) = @_;
+
+    my $reserve = GetReserve($reserve_id);
+    if ($reserve) {
+        my $dbh = C4::Context->dbh;
+
+        # update the database, removing the record...
+        my $query = qq{
+            UPDATE reserves
+            SET cancellationdate = NOW(),
+                found = NULL,
+                priority = 0
+            WHERE reserve_id = ?
+        };
+        my $sth = $dbh->prepare($query);
+        $sth->execute($reserve_id);
+        $sth->finish;
+
+        $query = qq{
+            INSERT INTO old_reserves
+            SELECT * FROM reserves
+            WHERE reserve_id = ?
+        };
+        $sth = $dbh->prepare($query);
+        $sth->execute($reserve_id);
+
+        $query = qq{
+            DELETE FROM reserves
+            WHERE reserve_id = ?
+        };
+        $sth = $dbh->prepare($query);
+        $sth->execute($reserve_id);
+
+        # now fix the priority on the others...
+        _FixPriority( $reserve->{biblionumber}, $reserve->{borrowernumber} );
+    }
+
+    return $reserve;
+}
+
+
 =head2 ModReserve
 
   ModReserve($rank, $biblio, $borrower, $branch[, $itemnumber])
-- 
1.7.2.5