JBAS-1728 SCKO Batch renew messages; holds style; etc.
authorBill Erickson <berickxx@gmail.com>
Tue, 27 Jun 2017 22:02:40 +0000 (18:02 -0400)
committerBill Erickson <berickxx@gmail.com>
Thu, 21 Mar 2019 19:46:23 +0000 (15:46 -0400)
Display a summary of message of number of items successfully renewed or
failed during batch renewal.

Only process batch notification info in batch mode.

Style the holds lists headers all the same.

Fix bug where batch renewals would use the wrong circ if items have been
added to the circ list since the patron logged in.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
KCLS/openils/var/templates_kcls/circ/selfcheck/circ_page.tt2
KCLS/openils/var/templates_kcls/circ/selfcheck/holds_page.tt2
Open-ILS/web/css/skin/kcls/selfcheck-default.css
Open-ILS/web/css/skin/kcls/selfcheck.css
Open-ILS/web/js/dojo/openils/circ/nls/selfcheck.js
Open-ILS/web/js/ui/kcls/circ/selfcheck/selfcheck.js

index f104f04..e46bc72 100644 (file)
@@ -18,7 +18,7 @@
   <div class="col-xs-12">
     <table class="table scko-table-striped">
       <tbody id='oils-selfck-circ-out-tbody'>
-        <tr id='oils-selfck-circ-out-row'><td>
+        <tr id='oils-selfck-circ-out-row' class='oils-selfck-items-row'><td>
           <table>
             <tr>
               <th rowspan="5"><input type="checkbox" name="renew_selector" class="oils-selfck-renewal-selector"></th>
@@ -35,4 +35,4 @@
     </table>
   </div>
 </div>
-</div>
\ No newline at end of file
+</div>
index bcf67c7..03c70cf 100644 (file)
@@ -12,7 +12,7 @@
 </div>
 <div class="scko-table">
 <div class="row">
-  <div class="col-md-12 text-center"><label class="scko-table-ready">Items Ready for Pick-Up</label></div>
+  <div class="col-md-12 text-center"><label class="scko-table-header">Items Ready for Pick-Up</label></div>
 </div>
 <div class="row">
   <div class="col-xs-12">
@@ -36,7 +36,7 @@
 </div>
 
 <div class="row">
-  <div class="col-md-12 text-center"><label class="scko-table-holds">Holds</label></div>
+  <div class="col-md-12 text-center"><label class="scko-table-header">Holds</label></div>
 </div>
 <div class="row">
   <div class="col-xs-12">
@@ -55,7 +55,7 @@
 </div>
 
 <div class="row">
-  <div class="col-md-12 text-center"><label class="scko-table-holds scko-table-suspended">Suspended</label></div>
+  <div class="col-md-12 text-center"><label class="scko-table-header">Suspended</label></div>
 </div>
 <div class="row">
   <div class="col-xs-12">
@@ -73,4 +73,4 @@
   </div>
 </div>
 
-</div>
\ No newline at end of file
+</div>
index 108cce5..c10a6bd 100644 (file)
@@ -133,4 +133,4 @@ h2 {
         background:linear-gradient(to bottom, #023a4f 5%, #008ec2 100%);
         background-color:#02729E;
     }
-}
\ No newline at end of file
+}
index 575e8f8..d7f121f 100644 (file)
@@ -165,6 +165,10 @@ h2 {
         top:1px;
     }
 }
+
+.scko-table-header {
+    font-weight:bold;
+}
 .scko-table-ready {
     font-weight:bold;
 }
@@ -267,4 +271,4 @@ body .dijitAlignClient {
 
 .hideMe {
     display: none;
-}
\ No newline at end of file
+}
index 0a9e6d4..cf15eab 100644 (file)
@@ -6,11 +6,13 @@
     "TOTAL_FINES_ACCOUNT" : "Total fines on account: $${0}.",
     "HOLD_STATUS_READY" : "Ready for pickup",
     "HOLD_STATUS_WAITING" : "#${0} in line",
-    "CHECKOUT_SUCCESS" : "Checkout of item ${0} succeeded",
+    "CHECKOUT_SUCCESS" : "Check-out of item ${0} succeeded",
     "RENEW_SUCCESS" : "Renewal of item ${0} succeeded",
     "ALREADY_OUT" : "Item ${0} is already checked out",
     "OPEN_CIRCULATION_EXISTS" : "Item ${0} is already checked out to another user",
     "GENERIC_CIRC_FAILURE" : "Unable to process some items. Please see staff.",
+    "BATCH_RENEW_SUCCESS" : "Successfully renewed ${0} items",
+    "BATCH_RENEW_FAILURE" : "Failed to renew ${0} item(s).  Please see staff.",
     "LOGIN_FAILED" : "Login for ${0} failed",
     "LOGIN_BARCODE_DOUBLE" : "Your PIN is needed.",
     "UNKNOWN_ERROR" : "An unhandled exception occurred with error code ${0}",
index b52b924..d867717 100644 (file)
@@ -28,7 +28,6 @@ var selfCheckMgr;
 var itemsOutCirc = [];
 var itemsOutMod = [];
 var itemsOutCopy = [];
-var currentItemsOut = [];
 var readyHolds = false;
 
 // Rest on the Thank You page this many ms.
@@ -226,7 +225,7 @@ SelfCheckManager.prototype.init = function() {
         
         // Patron barcode via cgi param.  Mainly used for debugging and
         // only works if password is not required by policy
-        this.loginPatron(this.cgi.param('patron'));
+        this.loginPatron(this.cgi.param('patron'), this.cgi.param('password'));
 
     } else {
         this.drawLoginPage();
@@ -645,31 +644,30 @@ function handleCheckedItems(circs) {
     var self = selfCheckMgr;
     var row = self.outTemplate.cloneNode(true);
 
-    if(circs.length) {
-        for(circ = 0; circ < circs.length; circ++) {
-            var row = self.outTemplate.cloneNode(true);
-            currentItemsOut.push(circs[circ]);
-            self.byName(row,'barcode').innerHTML = circs[circ].copy.barcode();
-            self.byName(row, 'title').innerHTML = circs[circ].record.title();
-            self.byName(row, 'author').innerHTML = circs[circ].record.author();
-            self.byName(row, 'remaining_renewals').innerHTML = circs[circ].circ.renewal_remaining();
-            
-            if(dojo.date.stamp.fromISOString(circs[circ].circ.due_date()) < (new Date()))
-                self.byName(row,'due_date').style.color="red";
-            
-            self.byName(row,'due_date').innerHTML = dojo.date.locale.format(
-                dojo.date.stamp.fromISOString(circs[circ].circ.due_date()),
-                {selector: 'date', fullYear: true}
-            );
-            if(circs[circ].circ.renewal_remaining() < 1) {
-                self.byName(row, 'renew_selector').checked = false;
-                self.byName(row, 'renew_selector').setAttribute('disabled', true);
-            }
-            self.byName(row,'format').innerHTML = circs[circ].record.types_of_resource()[0];
-            self.itemsOutTbody.appendChild(row);
-        }
-    }
+    dojo.forEach(circs, function(circ) {
 
+        var row = self.outTemplate.cloneNode(true);
+        row.setAttribute('copy_barcode', circ.copy.barcode());
+
+        self.byName(row,'barcode').innerHTML = circ.copy.barcode();
+        self.byName(row, 'title').innerHTML = circ.record.title();
+        self.byName(row, 'author').innerHTML = circ.record.author();
+        self.byName(row, 'remaining_renewals').innerHTML = circ.circ.renewal_remaining();
+        
+        if(dojo.date.stamp.fromISOString(circ.circ.due_date()) < (new Date()))
+            self.byName(row,'due_date').style.color="red";
+        
+        self.byName(row,'due_date').innerHTML = dojo.date.locale.format(
+            dojo.date.stamp.fromISOString(circ.circ.due_date()),
+            {selector: 'date', fullYear: true}
+        );
+        if(circ.circ.renewal_remaining() < 1) {
+            self.byName(row, 'renew_selector').checked = false;
+            self.byName(row, 'renew_selector').setAttribute('disabled', true);
+        }
+        self.byName(row,'format').innerHTML = circ.record.types_of_resource()[0];
+        self.itemsOutTbody.appendChild(row);
+    });
 }
 
 SelfCheckManager.prototype.goToTab = function(name) {
@@ -703,21 +701,40 @@ SelfCheckManager.prototype.goToTab = function(name) {
  * Renew ticked checkbox items
  */
 SelfCheckManager.prototype.renewItems = function() {
+    var self = this;
 
-    var checkboxes = document.getElementsByClassName('oils-selfck-renewal-selector');
-    var itemsToRenew = [];
-    for(var checkbox = 0; checkbox < checkboxes.length; checkbox++) {
-        if(checkboxes[checkbox].checked == true) {
-            itemsToRenew.push(currentItemsOut[checkbox]);
-        }
-        checkboxes[checkbox].checked = false;
-    }
+    var rows = document.getElementsByClassName('oils-selfck-items-row');
+    var renew_count = 0;
+    var success_count = 0;
 
-    for(var item = 0; item < itemsToRenew.length; item++) {
-        this.renew(itemsToRenew[item].copy.barcode())
-    }
+    dojo.forEach(rows, function(row) {
+        var checkbox = self.byName(row, 'renew_selector');
+        if (!checkbox.checked) return;
+
+        renew_count++;
+        checkbox.checked = false; // de-select all
+
+        var stat = self.renew(row.getAttribute('copy_barcode'), false, true);
+        if (stat.success) success_count++;
+    });
 
     this.drawCircPage();
+
+    // Display a generic success/failure batch renewal notification
+    if (success_count == renew_count) {
+        this.handleAlert(
+            dojo.string.substitute(
+                localeStrings.BATCH_RENEW_SUCCESS, [success_count]),
+            false, 'checkout-success'
+        );
+
+    } else {
+        this.handleAlert(
+            dojo.string.substitute(
+                localeStrings.BATCH_RENEW_FAILURE, 
+                [renew_count - success_count]
+            ), true, 'checkout-failure');
+    }
 }
 
 
@@ -1089,7 +1106,7 @@ SelfCheckManager.prototype.failPartMessage = function(result) {
     }
 }
 
-SelfCheckManager.prototype.handleXactResult = function(action, item, result) {
+SelfCheckManager.prototype.handleXactResult = function(action, item, result, isBatch) {
     var displayText = '';
 
     // If true, the display message is important enough to pop up.  Whether or not
@@ -1100,6 +1117,7 @@ SelfCheckManager.prototype.handleXactResult = function(action, item, result) {
     var overrideEvents = this.orgSettings[SET_AUTO_OVERRIDE_EVENTS];
     var blockStatuses = this.orgSettings[SET_BLOCK_CHECKOUT_ON_COPY_STATUS];
     result.payload = payload;
+    var success = false;
 
     if(result.textcode == 'NO_SESSION') {
 
@@ -1127,6 +1145,7 @@ SelfCheckManager.prototype.handleXactResult = function(action, item, result) {
             this.displayCheckout(result, 'renew');
         }
 
+        success = true;
         this.checkouts.push({circ : result.payload.circ.id()});
         sound = 'checkout-success';
         this.updateScanBox();
@@ -1276,15 +1295,16 @@ SelfCheckManager.prototype.handleXactResult = function(action, item, result) {
         }
     }
 
-    this.handleAlert(displayText, popup, sound);
-    return {};
+    // avoid per-item notifications in batch mode.
+    if (!isBatch) this.handleAlert(displayText, popup, sound);
+    return {success : success};
 }
 
 
 /**
  * Renew an item
  */
-SelfCheckManager.prototype.renew = function(barcode, override) {
+SelfCheckManager.prototype.renew = function(barcode, override, isBatch) {
 
     var method = 'open-ils.circ.renew';
     if(override) method += '.override';
@@ -1301,10 +1321,12 @@ SelfCheckManager.prototype.renew = function(barcode, override) {
         ]}
     );
 
-    var stat = this.handleXactResult('renew', barcode, result);
+    var stat = this.handleXactResult('renew', barcode, result, isBatch);
+
+    if (stat.override)
+        return this.renew(barcode, true, isBatch);
 
-    if(stat.override)
-        this.renew(barcode, true);
+    return stat;
 }
 
 /**