LP#1673870: Support placing and canceling OverDrive holds
authorJeff Davis <jdavis@sitka.bclibraries.ca>
Wed, 28 Jun 2017 20:36:24 +0000 (13:36 -0700)
committerBill Erickson <berickxx@gmail.com>
Fri, 1 Sep 2017 20:06:50 +0000 (16:06 -0400)
Signed-off-by: Jeff Davis <jdavis@sitka.bclibraries.ca>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/EbookAPI.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/EbookAPI/OverDrive.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/EbookAPI/Test.pm
Open-ILS/src/templates/opac/parts/ebook_api/base_js.tt2
Open-ILS/web/js/ui/default/opac/ebook_api/ebook.js

index e09282e..d6961a8 100644 (file)
@@ -481,7 +481,7 @@ __PACKAGE__->register_method(
 # - barcode: patron barcode
 #
 sub do_xact {
-    my ($self, $conn, $auth, $session_id, $title_id, $barcode) = @_;
+    my ($self, $conn, $auth, $session_id, $title_id, $barcode, $email) = @_;
 
     my $action;
     if ($self->api_name =~ /checkout/) {
@@ -508,7 +508,13 @@ sub do_xact {
     my $user_token = $handler->do_patron_auth($barcode);
 
     # handler method constructs and submits request (and handles any external authentication)
-    my $res = $handler->$action($title_id, $user_token);
+    my $res;
+    # place_hold has email as optional additional param
+    if ($action eq 'place_hold') {
+        $res = $handler->place_hold($title_id, $user_token, $email);
+    } else {
+        $res = $handler->$action($title_id, $user_token);
+    }
     if (defined ($res)) {
         return $res;
     } else {
index 6134594..9549fa4 100644 (file)
@@ -555,6 +555,59 @@ sub checkin {
     return;
 }
 
+sub place_hold {
+    my ($self, $title_id, $patron_token, $email) = @_;
+    my $fields = [
+        {
+            name  => 'reserveId',
+            value => $title_id
+        }
+    ];
+    if ($email) {
+        push @$fields, { name => 'emailAddress', value => $email };
+        # TODO: Use autoCheckout=true when we have a patron email?
+    } else {
+        push @$fields, { name => 'ignoreEmail', value => 'true' };
+    }
+    my $request_content = { fields => $fields };
+    my $req = {
+        method  => 'POST',
+        uri     => $self->{circulation_base_uri} . "/patrons/me/holds",
+        content => OpenSRF::Utils::JSON->perl2JSON($request_content)
+    };
+    if (my $res = $self->handle_http_request($req, $self->{session_id})) {
+        if ($res->{content}->{holdPlacedDate}) {
+            return {
+                queue_position => $res->{content}->{holdListPosition},
+                queue_size => $res->{content}->{numberOfHolds},
+                expire_date => (defined $res->{content}->{holdExpires}) ? $res->{content}->{holdExpires} : undef
+            };
+        }
+        $logger->error("EbookAPI: place hold failed for OverDrive title $title_id");
+        return { error_msg => "Could not place hold." };
+    }
+    $logger->error("EbookAPI: no response received from OverDrive server");
+    return;
+}
+
+sub cancel_hold {
+    my ($self, $title_id, $patron_token) = @_;
+    my $req = {
+        method  => 'DELETE',
+        uri     => $self->{circulation_base_uri} . "/patrons/me/holds/$title_id"
+    };
+    if (my $res = $self->handle_http_request($req, $self->{session_id})) {
+        if ($res->{status} =~ /^204/) {
+            return {};
+        } else {
+            $logger->error("EbookAPI: cancel hold failed for OverDrive title $title_id");
+            return { error_msg => ( (defined $res->{content}) ? $res->{content} : 'Could not cancel hold' ) };
+        }
+    }
+    $logger->error("EbookAPI: no response received from OverDrive server");
+    return;
+}
+
 # List of patron checkouts:
 # GET http://patron.api.overdrive.com/v1/patrons/me/checkouts
 # User-Agent: {Your application}
index a6f3e3f..adab52c 100644 (file)
@@ -368,6 +368,9 @@ sub place_hold {
     # Patron ID or patron auth token, as returned by do_patron_auth().
     my $user_token = shift;
 
+    # Email address of patron (optional, not used here).
+    my $email = shift;
+
     # If hold is successfully placed, return a hashref with the following
     # fields:
     # - queue_position: this user's position in hold queue for this title
index 9d8b06f..30ee0f5 100644 (file)
@@ -58,6 +58,11 @@ ebook_action.vendor = '[% CGI.param("vendor") %]';
 // user- or login-specific vars
 var authtoken = '[% ctx.authtoken %]';
 var patron_id = '[% ctx.active_card %]'; // using barcode of active card as patron ID
+[%- IF ctx.user.email %]
+var patron_email = '[% ctx.user.email | html %]';
+[%- ELSE %]
+var patron_email = null;
+[%- END %]
 
 var myopac_page;
 [% IF myopac_page %]
index f074926..5119507 100644 (file)
@@ -91,7 +91,7 @@ Ebook.prototype.placeHold = function(authtoken, patron_id, callback) {
     var ebook = this;
     new OpenSRF.ClientSession('open-ils.ebook_api').request({
         method: 'open-ils.ebook_api.place_hold',
-        params: [ authtoken, ses, ebook.id, patron_id ],
+        params: [ authtoken, ses, ebook.id, patron_id, patron_email ],
         async: true,
         oncomplete: function(r) {
             var resp = r.recv();