webstaff: Add modal "request items" to holding view
authorMike Rylander <mrylander@gmail.com>
Thu, 3 Sep 2015 16:42:33 +0000 (12:42 -0400)
committerJason Stephenson <jstephenson@mvlc.org>
Mon, 14 Sep 2015 19:44:19 +0000 (15:44 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson@mvlc.org>
Open-ILS/src/templates/staff/base_js.tt2
Open-ILS/src/templates/staff/cat/catalog/t_holdings.tt2
Open-ILS/src/templates/staff/cat/catalog/t_request_items.tt2 [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/cat/catalog/app.js
Open-ILS/web/js/ui/default/staff/services/coresvc.js
Open-ILS/web/js/ui/default/staff/services/user.js

index 5e60ee0..97a2ce0 100644 (file)
@@ -28,6 +28,7 @@
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/hatch.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/print.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/coresvc.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/user.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/navbar.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/statusbar.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
index 5ef56d1..154bb4f 100644 (file)
@@ -33,6 +33,9 @@
       checkbox="holdings_show_vols"
       checked="holdings_show_vols"/>
 
+    <eg-grid-action handler="requestItems"
+      label="[% l('Request Items') %]"></eg-grid-action>
+
     <eg-grid-action handler="selectedHoldingsItemStatus" group="[% l('Show') %]"
       label="[% l('Item Status (list)') %]"></eg-grid-action>
     <eg-grid-action handler="selectedHoldingsItemStatusDetail" group="[% l('Show') %]"
diff --git a/Open-ILS/src/templates/staff/cat/catalog/t_request_items.tt2 b/Open-ILS/src/templates/staff/cat/catalog/t_request_items.tt2
new file mode 100644 (file)
index 0000000..f28a521
--- /dev/null
@@ -0,0 +1,48 @@
+<form ng-submit="ok(hold_data)" role="form">
+  <div class="modal-header">
+    <button type="button" class="close" ng-click="cancel()" 
+      aria-hidden="true">&times;</button>
+    <h4 class="modal-title">[% l('Request Items') %]</h4>
+  </div>
+  <div class="modal-body">
+    <div class="row">
+      <div class="col-md-6">
+        <div class="input-group">
+          <span class="input-group-addon">[% l('User Barcode') %]</span>
+          <input class="form-control" type="text" focus-me="true"
+            ng-model="barcode" required placeholder="[% l('User Barcode') %]"/>
+        </div>
+      </div>
+      <div class="col-md-6"> {{user_name}} </div>
+    </div>
+    <div class="row pad-vert">
+      <div class="col-md-6">
+        <div class="input-group">
+          <span class="input-group-addon">[% l('Hold Type') %]</span>
+          <select class="form-control" required ng-model="hold_data.hold_type">
+            <option value="C">[% l('Copy Hold') %]</option>
+            <option value="R" selected>[% l('Recall Hold') %]</option>
+            <option value="F">[% l('Force Hold') %]</option>
+          </select>
+        </div>
+      </div>
+      <div class="col-md-6">
+        <div class="input-group">
+          <span class="input-group-addon">[% l('Pickup Lib') %]</span>
+          <eg-org-selector selected="hold_data.pickup_lib" disableTest="cant_have_vols"></eg-org-selector>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="modal-footer">
+    <div class="row">
+      <div class="col-md-6">
+        [% l('Number of items: ') %] {{hold_data.copy_list.length}}
+      </div>
+      <div class="col-md-6 pull-right">
+        <input type="submit" class="btn btn-primary" value="[% l('OK') %]" ng-disabled="!hold_data.user"/>
+        <button class="btn btn-warning" ng-click="cancel($event)">[% l('Cancel') %]</button>
+      </div>
+    </div>
+  </div>
+</form>
index 2608418..a709f04 100644 (file)
@@ -7,13 +7,13 @@
  *
  */
 
-angular.module('egCatalogApp', ['ui.bootstrap','ngRoute','egCoreMod','egGridMod', 'egMarcMod'])
+angular.module('egCatalogApp', ['ui.bootstrap','ngRoute','egCoreMod','egGridMod', 'egMarcMod', 'egUserMod'])
 
 .config(function($routeProvider, $locationProvider, $compileProvider) {
     $locationProvider.html5Mode(true);
     $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export
 
-    var resolver = {delay : ['egCore','egStartup', function(egCore,  egStartup) {
+    var resolver = {delay : ['egCore','egStartup','egUser', function(egCore, egStartup, egUser) {
         egCore.env.classLoaders.aous = function() {
             return egCore.org.settings([
                 'cat.marc_control_number_identifier'
@@ -227,9 +227,9 @@ function($scope , $routeParams , $location , $window , $q , egCore) {
 
 .controller('CatalogCtrl',
        ['$scope','$routeParams','$location','$window','$q','egCore','egHolds','egCirc',
-        'egGridDataProvider','egHoldGridActions','$timeout','holdingsSvc',
+        'egGridDataProvider','egHoldGridActions','$timeout','$modal','holdingsSvc','egUser',
 function($scope , $routeParams , $location , $window , $q , egCore , egHolds , egCirc, 
-         egGridDataProvider , egHoldGridActions , $timeout , holdingsSvc) {
+         egGridDataProvider , egHoldGridActions , $timeout , $modal , holdingsSvc , egUser) {
 
     // set record ID on page load if available...
     $scope.record_id = $routeParams.record_id;
@@ -316,6 +316,75 @@ function($scope , $routeParams , $location , $window , $q , egCore , egHolds , e
         }
     });
 
+    $scope.requestItems = function() {
+        var copy_list = gatherSelectedHoldingsIds();
+        if (copy_list.length == 0) return;
+
+        return $modal.open({
+            templateUrl: './cat/catalog/t_request_items',
+            animation: true,
+            controller:
+                   ['$scope','$modalInstance',
+            function($scope , $modalInstance) {
+                $scope.user = null;
+                $scope.first_user_fetch = true;
+
+                $scope.hold_data = {
+                    hold_type : 'C',
+                    copy_list : copy_list,
+                    pickup_lib: egCore.org.get(egCore.auth.user().ws_ou()),
+                    user      : egCore.auth.user().id()
+                };
+
+                egUser.get( $scope.hold_data.user ).then(function(u) {
+                    $scope.user = u;
+                    $scope.barcode = u.card().barcode();
+                    $scope.user_name = egUser.format_name(u);
+                    $scope.hold_data.user = u.id();
+                });
+
+                $scope.user_name = '';
+                $scope.barcode = '';
+                $scope.$watch('barcode', function (n) {
+                    if (!$scope.first_user_fetch) {
+                        egUser.getByBarcode(n).then(function(u) {
+                            $scope.user = u;
+                            $scope.user_name = egUser.format_name(u);
+                            $scope.hold_data.user = u.id();
+                        }, function() {
+                            $scope.user = null;
+                            $scope.user_name = '';
+                            delete $scope.hold_data.user;
+                        });
+                    }
+                    $scope.first_user_fetch = false;
+                });
+
+                $scope.ok = function(h) {
+                    var args = {
+                        patronid  : h.user,
+                        hold_type : h.hold_type,
+                        pickup_lib: h.pickup_lib.id(),
+                        depth     : 0
+                    };
+
+                    egCore.net.request(
+                        'open-ils.circ',
+                        'open-ils.circ.holds.test_and_create.batch.override',
+                        egCore.auth.token(), args, h.copy_list
+                    );
+
+                    $modalInstance.close();
+                }
+
+                $scope.cancel = function($event) {
+                    $modalInstance.dismiss();
+                    $event.preventDefault();
+                }
+            }]
+        });
+    }
+
     // refresh the list of holdings when the record_id is changed.
     $scope.holdings_record_id_changed = function(id) {
         if ($scope.record_id != id) $scope.record_id = id;
@@ -486,7 +555,6 @@ function($scope , $routeParams , $location , $window , $q , egCore , egHolds , e
                 'eg.cat.item_transfer_target',
                 $scope.holdingsGridControls.selectedItems()[0].call_number.id
             );
-            console.log('item_transfer_dest: '+$scope.holdingsGridControls.selectedItems()[0].call_number.id);
         }
     }
 
@@ -495,7 +563,6 @@ function($scope , $routeParams , $location , $window , $q , egCore , egHolds , e
             'eg.cat.volume_transfer_target',
             $scope.holdingsGridControls.selectedItems()[0].owner_id
         );
-        console.log('vol_transfer_dest: '+$scope.holdingsGridControls.selectedItems()[0].owner_id);
     }
 
     $scope.selectedHoldingsItemStatusDetail = function (){
index de502cd..57b8361 100644 (file)
@@ -10,7 +10,7 @@ angular.module('egCoreMod')
 .factory('egCore', 
        ['egIDL','egNet','egEnv','egOrg','egPCRUD','egEvent','egAuth',
         'egPerm','egHatch','egPrint','egStartup','egStrings','egDate',
-function(egIDL , egNet , egEnv , egOrg , egPCRUD , egEvent , egAuth , 
+function(egIDL , egNet , egEnv , egOrg , egPCRUD , egEvent , egAuth ,
          egPerm , egHatch , egPrint , egStartup , egStrings , egDate) {
 
     return {
index 0ed5cac..f2a70c1 100644 (file)
@@ -20,9 +20,20 @@ function($q,  $timeout,  egNet,  egAuth,  egOrg) {
         ]
     };
 
+    service.format_name = function(patron_obj) {
+        var patron_name = ( patron_obj.prefix() ? patron_obj.prefix() + ' ' : '') +
+            patron_obj.family_name() + ', ' +
+            patron_obj.first_given_name() + ' ' +
+            ( patron_obj.second_given_name() ? patron_obj.second_given_name() + ' ' : '' ) +
+            ( patron_obj.suffix() ? patron_obj.suffix() : '');
+        return patron_name;
+    };
+
     service.get = function(userId, args) {
         var deferred = $q.defer();
 
+        if (!userId) deferred.reject();
+
         var fields = service.defaultFleshFields;
         if (args) {
             if (args.useFields) { 
@@ -51,6 +62,19 @@ function($q,  $timeout,  egNet,  egAuth,  egOrg) {
         return deferred.promise;
     };
 
+    service.getByBarcode = function(barcode, args) {
+        return egNet.request(
+            'open-ils.pcrud',
+            'open-ils.pcrud.search.ac.atomic',
+            egAuth.token(), {barcode:barcode}
+        ).then( function(card) {
+            if (card && angular.isArray(card) && card[0] && card[0].classname == 'ac') {
+                return service.get(card[0].usr(), args)
+            }
+            return service.get(null);
+        }) 
+    };
+
     return service;
 }]);