item status flesh repair; checkin cont.
authorBill Erickson <berick@esilibrary.com>
Wed, 25 Jun 2014 14:00:32 +0000 (10:00 -0400)
committerBill Erickson <berick@esilibrary.com>
Wed, 25 Jun 2014 14:00:32 +0000 (10:00 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/circ/checkin/index.tt2
Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2
Open-ILS/src/templates/staff/circ/share/t_event_override_dialog.tt2
Open-ILS/src/templates/staff/share/t_autogrid.tt2
Open-ILS/web/js/ui/default/staff/cat/item/app.js
Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
Open-ILS/web/js/ui/default/staff/circ/services/circ.js
Open-ILS/web/js/ui/default/staff/services/grid.js

index 63e4773..272212b 100644 (file)
   </div>
 </div>
 
-<div ng-if="already_checked_in" class="col-md-6 alert alert-danger">
-  [% l('[_1] was already checked in.', '{{already_checked_in}}') %]
+<div ng-if="alert" class="col-md-6 alert alert-danger">
+  <span ng-if="alert.already_checked_in">
+    [% l('[_1] was already checked in.', '{{alert.already_checked_in}}') %]
+  </span>
+  <span ng-if="alert.item_never_circed">
+    [% l('Item [_1] has never circulated.', '{{alert.item_never_circed}}') %]
+  </span>
 </div>
 
 <hr/>
index 1822671..4b9024d 100644 (file)
@@ -8,6 +8,12 @@
   grid-controls="gridControls"
   persist-key="circ.checkin">
 
+
+  <eg-grid-action 
+    handler="fetchLastCircPatron"
+    label="[% l('Retrieve Last Patron Who Circulated Item') %]">
+  </eg-grid-action>
+
   <eg-grid-field label="[% l('Alert Msg') %]"   
     path="acp.alert_message"></eg-grid-field>
 
   <eg-grid-field label="[% l('Start') %]"    
     path='circ.xact_start'></eg-grid-field>
 
-  <eg-grid-field label="[% l('Title') %]"       
-    path="title"></eg-grid-field>
+  <eg-grid-field label="[% l('Title') %]" path="title">
+    <a target="_self" href="[% ctx.base_path %]/opac/record/{{record.doc_id()}}">
+      {{item.title}}
+    </a>
+  </eg-grid-field>
 
   <eg-grid-field label="[% l('Due Date') %]"    
     path='circ.due_date' hidden></eg-grid-field>
index 219848c..fd19858 100644 (file)
@@ -17,7 +17,7 @@
  session will auto-override this event[% END %]</i>
     <br/><br/>
     <input type="submit" class="btn btn-primary" 
-        value="[% l('Force Checkout?') %]"/>
+        value="[% l('Force Action?') %]"/>
     <button class="btn btn-warning" 
       ng-click="cancel($event)">[% l('Cancel') %]</button>
   </div>
index 5e5568d..65ed458 100644 (file)
     </button>
 
     <!-- actions drop-down menu -->
-    <div class="btn-group" ng-if="actions.length" 
-      is-open="gridActionsIsOpen" dropdown>                                                  
+    <div class="btn-group" ng-if="actions.length" dropdown>                                                  
       <button type="button" class="btn btn-default dropdown-toggle"
         ng-class="{disabled : false}">
         [% l('Actions') %] <span class="caret"></span>                       
       </button>                                                              
       <ul class="dropdown-menu pull-right">                                  
         <li ng-class="{disabled : false}" ng-repeat="action in actions">
-          <a href ng-click="actionLauncher(action)">{{action.label}}</a>
+          <a href dropdown-toggle 
+            ng-click="actionLauncher(action)">{{action.label}}</a>
         </li>                                                                
       </ul>
     </div>
index a104e75..71d45cd 100644 (file)
@@ -246,15 +246,7 @@ function($scope , $q , $location , $routeParams , egCore , itemSvc , egBilling)
             var copy = res.copy;
             itemSvc.copy = copy;
 
-            if (copyId && copyId != copy.id()) {
-                // if a new barcode is scanned in the detail view,
-                // update the url to match the ID of the new copy
-                $location.path('/cat/item/' + copy.id() + '/' + $scope.tab);
-                deferred.reject(); // avoid propagation of data fetch calls
-                return;
-            }
 
-            copyId = copy.id();
             $scope.copy = copy;
             $scope.recordId = copy.call_number().record().id();
             $scope.summaryRecord = itemSvc.copy.call_number().record();
@@ -274,6 +266,18 @@ function($scope , $q , $location , $routeParams , egCore , itemSvc , egBilling)
                 function(field) { copy[field](Boolean(copy[field]() == 't')) }
             );
 
+            // finally, if this is a different copy, redirect.
+            // Note that we flesh first since the copy we just
+            // fetched will be used after the redirect.
+            if (copyId && copyId != copy.id()) {
+                // if a new barcode is scanned in the detail view,
+                // update the url to match the ID of the new copy
+                $location.path('/cat/item/' + copy.id() + '/' + $scope.tab);
+                deferred.reject(); // avoid propagation of data fetch calls
+                return;
+            }
+            copyId = copy.id();
+
             deferred.resolve();
         });
 
index 6d21dd8..840ddb5 100644 (file)
@@ -17,8 +17,8 @@ angular.module('egCheckinApp', ['ngRoute', 'ui.bootstrap',
  * Manages checkin
  */
 .controller('CheckinCtrl',
-       ['$scope','$q','egCore','checkinSvc','egGridDataProvider','egCirc',
-function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc)  {
+       ['$scope','$q','$window','$location','egCore','checkinSvc','egGridDataProvider','egCirc',
+function($scope , $q , $window , $location , egCore , checkinSvc , egGridDataProvider , egCirc)  {
 
     var suppress_popups = false;
     var today = new Date();
@@ -106,6 +106,7 @@ function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc)  {
         var compiled = compile_checkin_args(args);
         args.copy_barcode = ''; // reset UI for next scan
         $scope.focusMe = true;
+        delete $scope.alert;
 
         var params = compiled.params;
         var options = compiled.options;
@@ -113,12 +114,12 @@ function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc)  {
         if (!params.copy_barcode) return;
 
         if (seen_barcodes[params.copy_barcode]) {
-            $scope.already_checked_in = params.copy_barcode;
+            $scope.alert = {already_checked_in : params.copy_barcode};
             return;
         }
 
         seen_barcodes[params.copy_barcode] = true;
-        delete $scope.already_checked_in;
+        delete $scope.alert;
 
         var row_item = {
             index : checkinSvc.checkins.length,
@@ -205,5 +206,29 @@ function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc)  {
         });
     }
 
+
+    // --- context menu actions
+    //
+    $scope.fetchLastCircPatron = function(items) {
+        var checkin = items[0];
+        if (!checkin || !checkin.acp) return;
+
+        egCore.pcrud.search('circ', 
+            {target_copy : checkin.acp.id()},
+            {order_by : {circ : 'xact_start desc' }, limit : 1}
+        ).then(function(circ) {
+
+            if (circ) {
+                // jump to the patron UI (separate app)
+                $window.location.href = $location
+                    .path('/circ/patron/' + circ.usr() + '/checkout')
+                    .absUrl();
+                return;
+            }
+
+            $scope.alert = {item_never_circed : checkin.acp.barcode()};
+        });
+    }
+
 }])
 
index 04a8262..deab3a5 100644 (file)
@@ -198,7 +198,7 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
             case 'COPY_ALERT_MESSAGE':
                 return service.copy_alert_dialog(evt, params, options, 'checkout');
             default: 
-                return service.override_dialog(evt, params, options);
+                return service.override_dialog(evt, params, options, 'checkin');
         }
     }
 
@@ -228,7 +228,7 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
             case 'COPY_ALERT_MESSAGE':
                 return service.copy_alert_dialog(evt, params, options, 'checkin');
             default: 
-                return service.override_dialog(evt, params, options);
+                return service.override_dialog(evt, params, options, 'checkin');
         }
     }
 
@@ -394,7 +394,7 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
 
     // opens a dialog asking the user if they would like to override
     // the returned event.
-    service.override_dialog = function(evt, params, options) {
+    service.override_dialog = function(evt, params, options, action) {
         return $modal.open({
             templateUrl: './circ/share/t_event_override_dialog',
             controller: 
@@ -411,9 +411,16 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
             }]
         }).result.then(
             function() {
+                options.override = true;
+
+                if (action == 'checkin') {
+                    return service.checkin(params, options);
+                }
+
+                // checkout/renew support override-after-first
                 if (service.checkout_auto_override_after_first.indexOf(evt.textcode) > -1)
                     service.auto_override_checkout_events[evt.textcode] = true;
-                options.override = true;
+
                 return service.checkout(params, options);
             }
         );
@@ -667,24 +674,57 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
             return service.handle_overridable_checkin_event(evt, params, options);
 
         switch (evt.textcode) {
+
             case 'SUCCESS':
             case 'NO_CHANGE':
 
-                if (copy.status().id() == 8 // on holds shelf
-                    && hold 
-                    && hold.pickup_lib() == egCore.auth.user().ws_ou()) {
-                    // inform user if the item is on the local holds shelf
-                    
-                    return service.route_dialog(
-                        './circ/share/t_hold_shelf_dialog', 
-                        evt, params, options
-                    ).then(function() { return final_resp });
-
-                } else {
-
-                    // see if the copy location is configured to alert
-                    return service.handle_checkin_loc_alert(evt, params, options)
-                    .then(function() {return final_resp});
+                switch(Number(copy.status().id())) {
+
+                    case 0: /* AVAILABLE */                                        
+                    case 4: /* MISSING */                                          
+                    case 7: /* RESHELVING */ 
+
+                        // see if the copy location requires an alert
+                        return service.handle_checkin_loc_alert(evt, params, options)
+                        .then(function() {return final_resp});
+
+                    case 8: /* ON HOLDS SHELF */
+
+                        
+                        if (hold) {
+
+                            if (hold.pickup_lib() == egCore.auth.user().ws_ou()) {
+                                // inform user if the item is on the local holds shelf
+                            
+                                return service.route_dialog(
+                                    './circ/share/t_hold_shelf_dialog', 
+                                    evt, params, options
+                                ).then(function() { return final_resp });
+
+                            } else {
+                                // normally, if the hold was on the shelf at a 
+                                // different location, it would be put into 
+                                // transit, resulting in a ROUTE_ITEM event.
+                                return $q.when(final_resp);
+                            }
+                        } else {
+
+                            console.error('checkin: item on holds shelf, '
+                                + 'but hold info not returned from checkin');
+                            return $q.when(final_resp);
+                        }
+
+                    case 11: /* CATALOGING */
+                        return $q.when(final_resp);
+
+                    case 15: /* ON_RESERVATION_SHELF */
+                        // TODO: show booking reservation dialog
+                        return $q.when(final_resp);
+
+                    default:
+                        console.error('Unhandled checkin copy status: ' 
+                            + copy.status().id() + ' : ' + copy.status().name());
+                        return $q.when(final_resp);
                 }
                 
             case 'ROUTE_ITEM':
index e5847c3..a21ba78 100644 (file)
@@ -420,8 +420,6 @@ angular.module('egGridMod',
 
             // fires the action handler function for a context action
             $scope.actionLauncher = function(action) {
-                $scope.gridActionsIsOpen = false;
-
                 if (!action.handler) {
                     console.error(
                         'No handler specified for "' + action.label + '"');