add alerts column to several grids
authorGalen Charlton <gmc@esilibrary.com>
Fri, 14 Oct 2016 20:00:06 +0000 (16:00 -0400)
committerMike Rylander <mrylander@gmail.com>
Mon, 31 Jul 2017 14:19:38 +0000 (10:19 -0400)
The item status, holdings, and checkout grids now have an
alerts column that lists the number of copy alerts associated
with the item as well as a button to manage them.

Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Conflicts:
Open-ILS/web/js/ui/default/staff/cat/item/app.js
Open-ILS/web/js/ui/default/staff/cat/services/holdings.js

Open-ILS/src/templates/staff/cat/catalog/t_holdings.tt2
Open-ILS/src/templates/staff/cat/item/t_list.tt2
Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2
Open-ILS/web/js/ui/default/staff/cat/catalog/app.js
Open-ILS/web/js/ui/default/staff/cat/item/app.js
Open-ILS/web/js/ui/default/staff/cat/services/holdings.js
Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js

index 1082677..52d36da 100644 (file)
     <eg-grid-field label="[% l('Holdable') %]"               datatype="bool" path="holdable"></eg-grid-field>
     <eg-grid-field label="[% l('Age-based Hold Protection') %]" path="age_protect.name"></eg-grid-field>
     <eg-grid-field label="[% l('Reference') %]"              datatype="bool" path="ref"></eg-grid-field>
+    <eg-grid-field label="[% l('Alerts') %]" path="copy_alert_count" handlers="gridCellHandlers" visible compiled>
+      {{item['copy_alert_count']}}
+      <button class="btn btn-sm btn-default" ng-click="col.handlers.copyAlertsEdit(item['id'])">[% l('Manage') %]</button>
+    </eg-grid-field>
   
   </eg-grid>
 </div>
index f08dcd4..0a70dcb 100644 (file)
@@ -77,7 +77,6 @@
     </a>
   </eg-grid-field>
 
-
   <eg-grid-field label="[% l('Acquisition Cost') %]"     path="cost" hidden></eg-grid-field>
   <eg-grid-field label="[% l('Age-Based Hold Protection') %]"  path="age_protect" hidden></eg-grid-field>
   <eg-grid-field label="[% l('Author') %]"               path="call_number.record.simple_record.author"  hidden></eg-grid-field>
   <eg-grid-field label="[% l('TCN') %]"                   path="call_number.record.tcn_value" hidden></eg-grid-field>
   <eg-grid-field label="[% l('TCN Source') %]"            path="call_number.record.tcn_source" hidden></eg-grid-field>
   <eg-grid-field label="[% l('Transaction Complete') %]"  path="_circ.xact_finish" datatype="timestamp" hidden></eg-grid-field>
-</eg-grid>
+  <eg-grid-field label="[% l('Alerts') %]" path="copy_alert_count" handlers="gridCellHandlers" visible compiled>
+    {{item['copy_alert_count']}}
+    <button class="btn btn-sm btn-default" ng-click="col.handlers.copyAlertsEdit(item['id'])">[% l('Manage') %]</button>
+  </eg-grid-field>
+  
 </eg-grid>
 
 <div class="flex-row pad-vert">
index 2bb43ea..a5f5cac 100644 (file)
   <eg-grid-field path="acp.circ_modifier.name" label="[% l('Circulation Modifier') %]"></eg-grid-field>
   <eg-grid-field path="acp.circ_lib.shortname" label="[% l('Circulation Library') %]"></eg-grid-field>
   <eg-grid-field path="acn.owning_lib.shortname" label="[% l('Owning Library') %]"></eg-grid-field>
+
+  <eg-grid-field label="[% l('Alerts') %]" path="copy_alert_count" handlers="gridCellHandlers" visible compiled>
+    {{item['copy_alert_count']}}
+    <button class="btn btn-sm btn-default" ng-click="col.handlers.copyAlertsEdit(item['acp'].id())">[% l('Manage') %]</button>
+  </eg-grid-field>
+
   <eg-grid-field path="circ.*" parent-idl-class="circ" hidden></eg-grid-field>
   <eg-grid-field path="acp.*" parent-idl-class="acp" hidden></eg-grid-field>
   <eg-grid-field path="acn.*" parent-idl-class="acn" hidden></eg-grid-field>
index 88ef6fa..396126f 100644 (file)
@@ -1349,6 +1349,13 @@ function($scope , $routeParams , $location , $window , $q , egCore , egHolds , e
         });
     }
 
+    $scope.gridCellHandlers = {};
+    $scope.gridCellHandlers.copyAlertsEdit = function(id) {
+        egCirc.manage_copy_alerts([id]).then(function() {
+            // update grid items?
+        });
+    };
+
     $scope.transferItems = function (){
         var xfer_target = egCore.hatch.getLocalItem('eg.cat.item_transfer_target');
         var copy_ids = gatherSelectedHoldingsIds();
index 8807bff..de3e52e 100644 (file)
@@ -60,7 +60,7 @@ function(egCore , egCirc , $uibModal , $q , $timeout , $window , egConfirmDialog
         flesh : 3, 
         flesh_fields : {
             acp : ['call_number','location','status','location','floating','circ_modifier',
-                'age_protect','circ_lib'],
+                'age_protect','circ_lib','copy_alerts'],
             acn : ['record','prefix','suffix','label_class'],
             bre : ['simple_record','creator','editor']
         },
@@ -87,6 +87,57 @@ function(egCore , egCirc , $uibModal , $q , $timeout , $window , egConfirmDialog
         },
         order_by : {circ : 'xact_start desc'},
         limit :  1
+    };
+
+    // resolved with the last received copy
+    service.fetch = function(barcode, id, noListDupes) {
+        var promise;
+
+        if (barcode) {
+            promise = egCore.pcrud.search('acp', 
+                {barcode : barcode, deleted : 'f'}, service.flesh);
+        } else {
+            promise = egCore.pcrud.retrieve('acp', id, service.flesh);
+        }
+
+        var lastRes;
+        return promise.then(
+            function() {return lastRes},
+            null, // error
+
+            // notify reads the stream of copies, one at a time.
+            function(copy) {
+
+                var flatCopy;
+
+                egCore.pcrud.search('aihu', 
+                    {item : copy.id()}, {}, {idlist : true, atomic : true})
+                .then(function(uses) { 
+                    copy._inHouseUseCount = uses.length;
+                });
+
+                if (noListDupes) {
+                    // use the existing copy if possible
+                    flatCopy = service.copies.filter(
+                        function(c) {return c.id == copy.id()})[0];
+                }
+
+                if (!flatCopy) {
+                    flatCopy = egCore.idl.toHash(copy, true);
+                    flatCopy.index = service.index++;
+                    flatCopy.copy_alert_count = copy.copy_alerts().filter(function(aca) {
+                        return !aca.ack_time();
+                    }).length;
+
+                    service.copies.unshift(flatCopy);
+                }
+
+                return lastRes = {
+                    copy : copy, 
+                    index : flatCopy.index
+                }
+            }
+        );
     }
 
     //Retrieve separate copy, combcirc, and accs information
@@ -713,6 +764,13 @@ function(egCore , egCirc , $uibModal , $q , $timeout , $window , egConfirmDialog
         });
     }
 
+    $scope.gridCellHandlers = {};
+    $scope.gridCellHandlers.copyAlertsEdit = function(id) {
+        egCirc.manage_copy_alerts([id]).then(function() {
+            // update grid items?
+        });
+    };
+
     $scope.showBibHolds = function () {
         angular.forEach(gatherSelectedRecordIds(), function (r) {
             var url = egCore.env.basePath + 'cat/catalog/record/' + r + '/holds';
index 3f4ec7d..67c64b2 100644 (file)
@@ -15,7 +15,7 @@ function(egCore , $q) {
     service.prototype.flesh = {   
         flesh : 2, 
         flesh_fields : {
-            acp : ['status','location','circ_lib','parts','age_protect'],
+            acp : ['status','location','circ_lib','parts','age_protect','copy_alerts'],
             acn : ['prefix','suffix','copies']
         }
     }
@@ -117,6 +117,11 @@ function(egCore , $q) {
                     }
                 });
 
+                // create virtual field for copy alert count
+                angular.forEach(svc.copies, function (cp) {
+                    cp.copy_alert_count = cp.copy_alerts.length;
+                });
+
                 // create a label using just the unique part of the owner list
                 var index = 0;
                 var prev_owner_list;
index 362e036..d0fe14c 100644 (file)
@@ -202,6 +202,17 @@ function($scope , $q , $routeParams , egCore , egUser , patronSvc ,
             // Non-cat circs don't return the full list of circs.
             // Refresh the list of non-cat circs from the server.
             patronSvc.getUserNonCats(patronSvc.current.id());
+            row_item.copy_alert_count = 0;
+        } else {
+            row_item.copy_alert_count = 0;
+            egCore.pcrud.search(
+                'aca',
+                { copy : co_resp.data.acp.id(), ack_time : null },
+                null,
+                { atomic : true }
+            ).then(function(list) {
+                row_item.copy_alert_count = list.length;
+            });
         }
     }
 
@@ -225,6 +236,13 @@ function($scope , $q , $routeParams , egCore , egUser , patronSvc ,
         });
     }
 
+    $scope.gridCellHandlers = {};
+    $scope.gridCellHandlers.copyAlertsEdit = function(id) {
+        egCirc.manage_copy_alerts([id]).then(function() {
+            // update grid items?
+        });
+    };
+
     $scope.print_receipt = function() {
         var print_data = {circulations : []}