LP#1697954 Hold details API additional fleshing
authorBill Erickson <berickxx@gmail.com>
Wed, 21 Jun 2017 16:09:37 +0000 (12:09 -0400)
committerMike Rylander <mrylander@gmail.com>
Fri, 30 Jun 2017 14:44:29 +0000 (10:44 -0400)
* Support new flesh options in hold details retrieval API:

include_current_copy
include_usr
include_cancel_cause
include_requestor

* Teach browser client code to use the new flesh options.  This reduces
  the number of API calls significantly for rendering holds grids.

* Add debug logging to existing local-flesh calls to indicate when/if
  additional API fleshing may be needed.

* Remove TODO comment about batching holds to avoid cstore exhaustion,
  which was fixed with LP#1653001.  However, leave the batching in place
  since it noticeably improves UI responsiveness, at the cost of a few
  extra API calls.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
Open-ILS/web/js/ui/default/staff/circ/services/holds.js

index 9c1ca72..a331fac 100644 (file)
@@ -3377,15 +3377,14 @@ sub uber_hold_impl {
     my($e, $hold_id, $args) = @_;
     $args ||= {};
 
-    my $hold = $e->retrieve_action_hold_request(
-        [
-            $hold_id,
-            {
-                flesh => 1,
-                flesh_fields => { ahr => [ 'current_copy', 'usr', 'notes' ] }
-            }
-        ]
-    ) or return $e->event;
+    my $flesh_fields = ['current_copy', 'usr', 'notes'];
+    push (@$flesh_fields, 'requestor') if $args->{include_requestor};
+    push (@$flesh_fields, 'cancel_cause') if $args->{include_cancel_cause};
+
+    my $hold = $e->retrieve_action_hold_request([
+        $hold_id,
+        {flesh => 1, flesh_fields => {ahr => $flesh_fields}}
+    ]) or return $e->event;
 
     if($hold->usr->id ne $e->requestor->id) {
         # caller is asking for someone else's hold
@@ -3405,12 +3404,13 @@ sub uber_hold_impl {
     $hold->usr($user->id);
 
 
-    my( $mvr, $volume, $copy, $issuance, $part, $bre ) = find_hold_mvr($e, $hold, $args->{suppress_mvr});
+    my( $mvr, $volume, $copy, $issuance, $part, $bre ) = find_hold_mvr($e, $hold, $args);
 
     flesh_hold_notices([$hold], $e) unless $args->{suppress_notices};
     flesh_hold_transits([$hold]) unless $args->{suppress_transits};
 
     my $details = retrieve_hold_queue_status_impl($e, $hold);
+    $hold->usr($user) if $args->{include_usr}; # re-flesh
 
     my $resp = {
         hold    => $hold,
@@ -3446,13 +3446,14 @@ sub uber_hold_impl {
 # hold is all about
 # -----------------------------------------------------
 sub find_hold_mvr {
-    my( $e, $hold, $no_mvr ) = @_;
+    my( $e, $hold, $args ) = @_;
 
     my $tid;
     my $copy;
     my $volume;
     my $issuance;
     my $part;
+    my $no_mvr = $args->{suppress_mvr};
 
     if( $hold->hold_type eq OILS_HOLD_TYPE_METARECORD ) {
         my $mr = $e->retrieve_metabib_metarecord($hold->target)
@@ -3494,7 +3495,7 @@ sub find_hold_mvr {
 
     if(!$copy and ref $hold->current_copy ) {
         $copy = $hold->current_copy;
-        $hold->current_copy($copy->id);
+        $hold->current_copy($copy->id) unless $args->{include_current_copy};
     }
 
     if(!$volume and $copy) {
index ab0b07d..53cd39c 100644 (file)
@@ -14,11 +14,7 @@ function($uibModal , $q , egCore , egConfirmDialog , egAlertDialog) {
     service.fetch_holds = function(hold_ids) {
         var deferred = $q.defer();
 
-        // FIXME: large batches using .authoritative result in many 
-        // stranded cstore backends on the server.  Needs investigation.
-        // For now, collect holds in a series of small batches.
-        // Fetch them serially both to avoid the above problem and
-        // to maintain order.
+        // Fetch hold details in batches for better UI responsiveness.
         var batch_size = 5;
         var index = 0;
 
@@ -37,7 +33,12 @@ function($uibModal , $q , egCore , egConfirmDialog , egAlertDialog) {
             egCore.net.request(
                 'open-ils.circ',
                 'open-ils.circ.hold.details.batch.retrieve.authoritative',
-                egCore.auth.token(), ids
+                egCore.auth.token(), ids, {
+                    include_current_copy : true,
+                    include_usr          : true,
+                    include_cancel_cause : true,
+                    include_requestor    : true
+                }
 
             ).then(
                 one_batch,  // kick off the next batch
@@ -452,14 +453,23 @@ function($uibModal , $q , egCore , egConfirmDialog , egAlertDialog) {
         hold.current_shelf_lib(egCore.org.get(hold.current_shelf_lib()));
         hold_data.id = hold.id();
 
-        if (hold.requestor() && typeof hold.requestor() != 'object')
+        // TODO: LP#1697954 fleshing calls below are deprecated in favor
+        // of API fleshing.
+
+        if (hold.requestor() && typeof hold.requestor() != 'object') {
+            console.debug('fetching hold requestor');
             egCore.pcrud.retrieve('au',hold.requestor()).then(function(u) { hold.requestor(u) });
+        }
 
-        if (hold.cancel_cause() && typeof hold.cancel_cause() != 'object')
+        if (hold.cancel_cause() && typeof hold.cancel_cause() != 'object') {
+            console.debug('fetching hold cancel cause');
             egCore.pcrud.retrieve('ahrcc',hold.cancel_cause()).then(function(c) { hold.cancel_cause(c) });
+        }
 
-        if (hold.usr() && typeof hold.usr() != 'object')
+        if (hold.usr() && typeof hold.usr() != 'object') {
+            console.debug('fetching hold user');
             egCore.pcrud.retrieve('au',hold.usr()).then(function(u) { hold.usr(u) });
+        }
 
         // current_copy is not always fleshed in the API
         if (hold.current_copy() && typeof hold.current_copy() != 'object') {
@@ -621,8 +631,12 @@ function($window , $location , $timeout , egCore , egHolds , egCirc) {
                     egCore.net.request(
                         'open-ils.circ',
                         'open-ils.circ.hold.details.retrieve.authoritative',
-                        egCore.auth.token(), $scope.holdId
-
+                        egCore.auth.token(), $scope.holdId, {
+                            include_current_copy : true,
+                            include_usr          : true,
+                            include_cancel_cause : true,
+                            include_requestor    : true
+                        }
                     ).then(function(hold_data) { 
                         egHolds.local_flesh(hold_data);