checkin receipt; hatch requiredness repairs
authorBill Erickson <berick@esilibrary.com>
Mon, 23 Jun 2014 20:52:33 +0000 (16:52 -0400)
committerBill Erickson <berick@esilibrary.com>
Mon, 23 Jun 2014 20:52:33 +0000 (16:52 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/circ/checkin/index.tt2
Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2
Open-ILS/src/templates/staff/share/print_templates/t_checkin.tt2 [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
Open-ILS/web/js/ui/default/staff/circ/services/circ.js
Open-ILS/web/js/ui/default/staff/services/hatch.js
Open-ILS/web/js/ui/default/staff/services/print.js

index 4eb198b..c7d6cf9 100644 (file)
 
 [% INCLUDE 'staff/circ/checkin/t_checkin_table.tt2' %]
 
+<div class="flex-row pad-vert">
+  <div class="flex-cell"></div>
+  <div class="pad-horiz">
+    <button class="btn btn-default" 
+      ng-click="print_receipt()">[% l('Print Receipt') %]</button>
+  </div>
+  <div class="checkbox" ng-if="using_hatch">
+    <label>
+      <input ng-model="show_print_dialog" type="checkbox"/>
+      [% l('Show Print Dialog') %]
+    </label>
+  </div>
+  <div class="pad-horiz" ng-if="using_hatch"></div>
+  <div class="checkbox">
+    <label>
+      <input ng-model="trim_list" type="checkbox"/>
+      [% l('Trim List (20 Rows)') %]
+    </label>
+  </div>
+  <div class="pad-horiz"></div>
+  <div class="checkbox">
+    <label>
+      <input ng-model="strict_barcode" type="checkbox"/>
+      [% l('Strict Barcode') %]
+    </label>
+  </div>
+</div>
+
+
 [% END %]
index 0cd4ce4..b64c468 100644 (file)
@@ -93,8 +93,8 @@
       [% l('Strict Barcode') %]
     </label>
   </div>
-  <div class="pad-horiz"></div>
-  <div class="checkbox">
+  <div class="pad-horiz" ng-if="using_hatch"></div>
+  <div class="checkbox" ng-if="using_hatch">
     <label>
       <input ng-model="show_print_dialog" type="checkbox"/>
       [% l('Show Print Dialog') %]
diff --git a/Open-ILS/src/templates/staff/share/print_templates/t_checkin.tt2 b/Open-ILS/src/templates/staff/share/print_templates/t_checkin.tt2
new file mode 100644 (file)
index 0000000..7bc56e4
--- /dev/null
@@ -0,0 +1,17 @@
+<div>
+  <div>[% l('Welcome to [_1]', '{{current_location.name}}') %]</div>
+  <div>[% l('You checked in the following items:') %]</div>
+  <hr/>
+  <ol>
+    <li ng-repeat="checkin in checkins">
+      <div>{{checkin.title}}</div>
+      <span>[% l('Barcode: ') %]</span>
+      <span>{{checkin.copy_barcode}}</span>
+      <span>[% l('Call Number: ') %]</span>
+      <span>{{checkin.call_number.label || "[% l("Not Cataloged") %]"}}</span>
+    </li>
+  </ol>
+  <hr/>
+  <div>{{current_location.shortname}} {{today | date:'short'}}</div>
+  <br/>
+</div>
index 04119c6..0c2205c 100644 (file)
@@ -30,6 +30,10 @@ function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc)  {
     $scope.focusMe = true;
     $scope.checkins = checkinSvc.checkins;
     $scope.checkinArgs = {backdate : new Date()}
+
+    $scope.using_hatch = egCore.hatchAvailable || 
+        egCore.hatch.getLocalItem('eg.hatch.required');
+
     var today = new Date();
 
     $scope.$watch('checkinArgs.backdate', function(newval) {
@@ -63,10 +67,17 @@ function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc)  {
                     delete params.backdate;
             }
 
-            egCirc.checkin(angular.copy(params))
+            var options = {check_barcode : $scope.strict_barcode};
+
+            egCirc.checkin(angular.copy(params, options))
             .then(function(final_resp) {
                 final_resp.evt.index = checkinSvc.checkins.length;
+                final_resp.evt.copy_barcode = params.copy_barcode;
+
                 checkinSvc.checkins.unshift(final_resp.evt);
+                if (checkinSvc.checkins.length > 20)
+                    checkinSvc.checkins = checkinSvc.checkins.splice(0, 20);
+
                 checkinGrid.refresh();
 
                 // in case we lost focus to a dialog
@@ -78,5 +89,37 @@ function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc)  {
 
         $scope.focusMe = true;
     }
+
+    $scope.print_receipt = function() {
+        var print_data = {checkins : []}
+
+        if (checkinSvc.checkins.length == 0) return $q.when();
+
+
+        angular.forEach(checkinSvc.checkins, function(evt) {
+
+            var checkin = {
+                copy : egCore.idl.toHash(evt.payload.copy) || {},
+                copy_barcode : evt.copy_barcode,
+            }
+
+            checkin.title = evt.payload.record ? evt.payload.record.title() :
+                (checkin.copy ? checkin.copy.dummy_title : '');
+
+            checkin.call_number = 
+                typeof checkin.copy.call_number == 'object' ?
+                    checkin.copy.call_number :
+                    egCore.idl.toHash(evt.payload.volume);
+
+            print_data.checkins.push(checkin);
+        });
+
+        return egCore.print.print({
+            template : 'checkin', 
+            scope : print_data,
+            show_dialog : $scope.show_print_dialog
+        });
+    }
+
 }])
 
index a032464..d4b7928 100644 (file)
@@ -32,6 +32,9 @@ function($scope , $q , $modal , $routeParams , egCore , egUser , patronSvc ,
         );
     }
 
+    $scope.using_hatch = egCore.hatchAvailable || 
+        egCore.hatch.getLocalItem('eg.hatch.required');
+
     // avoid multiple, in-flight attempts on the same barcode
     var pending_barcodes = {};
 
index 80a6d72..1b370af 100644 (file)
@@ -61,7 +61,7 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         var promise = options.check_barcode ? 
             service.test_barcode(params.copy_barcode) : $q.when();
 
-        // avoid double-checks on override, etc.
+        // avoid re-check on override, etc.
         delete options.check_barcode;
 
         return promise.then(function() {
@@ -109,16 +109,25 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
     service.checkin = function(params, options) {
         if (!options) options = {};
 
-        var method = 'open-ils.circ.checkin';
-        if (options.override) method += '.override';
+        var promise = options.check_barcode ? 
+            service.test_barcode(params.copy_barcode) : $q.when();
 
-        return egCore.net.request(
-            'open-ils.circ', method, egCore.auth.token(), params
+        // avoid re-check on override, etc.
+        delete options.check_barcode;
 
-        ).then(function(evt) {
+        return promise.then(function() {
 
-            if (angular.isArray(evt)) evt = evt[0];
-            return service.handle_checkin_response(evt, params, options);
+            var method = 'open-ils.circ.checkin';
+            if (options.override) method += '.override';
+
+            return egCore.net.request(
+                'open-ils.circ', method, egCore.auth.token(), params
+
+            ).then(function(evt) {
+
+                if (angular.isArray(evt)) evt = evt[0];
+                return service.handle_checkin_response(evt, params, options);
+            });
         });
     }
 
index bd3f178..f679dc5 100644 (file)
@@ -35,7 +35,6 @@ angular.module('egCoreMod')
     service.socket = null;
     service.hatchAvailable = null;
     service.defaultHatchURL = 'wss://localhost:8443/hatch'; 
-    service.hatchRequired = false;
 
     // write a message to the Hatch websocket
     service.sendToHatch = function(msg) {
@@ -57,16 +56,17 @@ angular.module('egCoreMod')
 
         msg.msgid = service.msgId++;
         msg.deferred = $q.defer();
-        service.messages[msg.msgid] = msg;
 
         if (service.hatchAvailable === false) { // Hatch is closed
             msg.deferred.reject(msg);
 
         } else if (service.hatchAvailable === true) { // Hatch is open
             // Hatch is known to be open
+            service.messages[msg.msgid] = msg;
             service.sendToHatch(msg);
 
         } else {  // Hatch status unknown; attempt to connect
+            service.messages[msg.msgid] = msg;
             service.pending.push(msg);
             service.hatchConnect();
         }
@@ -100,39 +100,14 @@ angular.module('egCoreMod')
         } 
     }
 
-    // pass each request off to its local handler function
-    service.handleRequestsLocally = function() {
-        service.socket = null;
-        service.hatchAvailable = false;
-
-        while ( (msg = service.pending.shift()) ) {
-
-            if (service.hatchRequired) {
-                throw new Error(
-                    "egHatch : attempt to perform '" + msg.action + 
-                    "' operation failed because no connection to Hatch could be " +
-                    "established and egHatch.hatchRequired is set to TRUE"
-                );
-            }
-
-            if (msg.localHandler) {
-                msg.content = msg.localHandler(msg);
-            } else {
-                msg.error = 
-                    'no fall-thru handler for requested action: ' 
-                    + msg.action;
-            }
-
-            service.resolveRequest(msg); 
-        }
-    }
-
     service.hatchClosed = function() {
         service.socket = null;
         service.printers = [];
         service.printConfig = {};
-        while ( (msg = service.pending.shift()) ) 
+        while ( (msg = service.pending.shift()) ) {
             msg.deferred.reject(msg);
+            delete service.messages[msg.msgid];
+        }
         if (service.onHatchClose)
             service.onHatchClose();
     }
@@ -142,6 +117,18 @@ angular.module('egCoreMod')
             || service.defaultHatchURL;
     }
 
+    // Returns true if Hatch is required or if we are currently
+    // communicating with the Hatch service. 
+    service.usingHatch = function() {
+        return egCore.hatchAvailable || service.hatchRequired();
+    }
+
+    // Returns true if this browser (via localStorage) is 
+    // configured to require Hatch.
+    service.hatchRequired = function() {
+        return service.getLocalItem('eg.hatch.required');
+    }
+
     service.hatchConnect = function() {
 
         if (service.socket && 
@@ -291,6 +278,11 @@ angular.module('egCoreMod')
     service.getItem = function(key) {
         return service.getRemoteItem(key)['catch'](
             function(msg) {
+                if (service.hatchRequired()) {
+                    console.error("Unable to getItem: " + key
+                     + "; hatchRequired=true, but hatch is not connected");
+                     return null;
+                }
                 return service.getLocalItem(msg.key);
             }
         );
@@ -313,6 +305,11 @@ angular.module('egCoreMod')
         var str = JSON.stringify(value);
         return service.setRemoteItem(key, str)['catch'](
             function(msg) {
+                if (service.hatchRequired()) {
+                    console.error("Unable to setItem: " + key
+                     + "; hatchRequired=true, but hatch is not connected");
+                     return null;
+                }
                 return service.setLocalItem(msg.key, null, str);
             }
         );
@@ -341,7 +338,12 @@ angular.module('egCoreMod')
     service.appendItem = function(key, value) {
         return service.appendRemoteItem(key, value)['catch'](
             function(msg) {
-                return service.appendLocalItem(msg.key, msg.value);
+                if (service.hatchRequired()) {
+                    console.error("Unable to appendItem: " + key
+                     + "; hatchRequired=true, but hatch is not connected");
+                     return null;
+                }
+                service.appendLocalItem(msg.key, msg.value);
             }
         );
     }
@@ -393,6 +395,11 @@ angular.module('egCoreMod')
     service.getKeys = function(prefix) {
         return service.getRemoteKeys(prefix)['catch'](
             function() { 
+                if (service.hatchRequired()) {
+                    console.error("Unable to get pref keys; "
+                     + "hatchRequired=true, but hatch is not connected");
+                     return [];
+                }
                 return service.getLocalKeys(prefix) 
             }
         );
index 7c0ef05..bcb8aa2 100644 (file)
@@ -69,14 +69,23 @@ function($q , $window , $timeout , $http , egHatch , egAuth , egIDL , egOrg) {
             promise = $q.when();
         }
 
+        // TODO: link print context to template type
+        var context = args.context || 'default';
+
         return promise.then(function(html) {
 
-            return egHatch.remotePrint(args.context,
+            return egHatch.remotePrint(context,
                 args.content_type, html, args.show_dialog)['catch'](
 
                 function(msg) {
                     // remote print not available; 
 
+                    if (egHatch.hatchRequired()) {
+                        console.error("Unable to print data; "
+                         + "hatchRequired=true, but hatch is not connected");
+                         return $q.reject();
+                    }
+
                     if (args.content_type != 'text/html') {
                         // text content does require compilation 
                         // (absorption) for browser printing