items out claims never checked out; renew; renew all
authorBill Erickson <berick@esilibrary.com>
Tue, 1 Jul 2014 18:55:14 +0000 (14:55 -0400)
committerBill Erickson <berick@esilibrary.com>
Tue, 1 Jul 2014 18:55:14 +0000 (14:55 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/circ/patron/index.tt2
Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
Open-ILS/src/templates/staff/circ/share/circ_strings.tt2
Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
Open-ILS/web/js/ui/default/staff/circ/services/circ.js
Open-ILS/web/js/ui/default/staff/services/grid.js

index 0bcdbcc..9d9a809 100644 (file)
@@ -35,6 +35,8 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
     "[% |l('{{xactIds}}') -%]Are you sure you would like to refund excess payment on bills [_1]?  This action will simply put the amount in the Payment Pending column as a negative value.  You must still select Apply Payment!  Certain types of payments may not be refunded.  The refund may be applied to checked transactions that follow the refunded transaction.[% END %]";
   s.EDIT_BILL_PAY_NOTE = "[% l('Enter new note for #[_1]:','{{ids}}') %]";
   s.GROUP_ADD_USER = "[% l('Enter the patron barcode') %]";
+  s.RENEW_ITEMS = "[% l('Renew Items?') %]";
+  s.RENEW_ALL_ITEMS = "[% l('Renew All Items?') %]";
 }]);
 </script>
 
index c4c3fb6..32cb268 100644 (file)
@@ -8,22 +8,18 @@
   items-provider="gridDataProvider"
   persist-key="circ.patron.items_out">
 
-  <eg-grid-action 
-    handler="print_receipt"
-    label="[% l('Print Item Receipt') %]">
-  </eg-grid-action>
-  <eg-grid-action 
-    handler="edit_due_date"
-    label="[% l('Edit Due Date') %]">
-  </eg-grid-action>
-  <eg-grid-action 
-    handler="mark_lost"
-    label="[% l('Mark Lost (By Patron)') %]">
-  </eg-grid-action>
-  <eg-grid-action 
-    handler="mark_claims_returned"
-    label="[% l('Mark Claims Returned') %]">
-  </eg-grid-action>
+  <eg-grid-action handler="print_receipt"
+    label="[% l('Print Item Receipt') %]"></eg-grid-action>
+  <eg-grid-action handler="edit_due_date"
+    label="[% l('Edit Due Date') %]"></eg-grid-action>
+  <eg-grid-action handler="mark_lost"
+    label="[% l('Mark Lost (By Patron)') %]"></eg-grid-action>
+  <eg-grid-action handler="mark_claims_returned"
+    label="[% l('Mark Claims Returned') %]"></eg-grid-action>
+  <eg-grid-action handler="mark_claims_never_checked_out"
+    label="[% l('Mark Claims Never Checked Out') %]"></eg-grid-action>
+  <eg-grid-action handler="renew" label="[% l('Renew') %]"></eg-grid-action>
+  <eg-grid-action handler="renew_all" label="[% l('Renew All') %]"></eg-grid-action>
 
   <eg-grid-field label="[% l('Circ ID') %]" path='id'></eg-grid-field>
   <eg-grid-field label="[% l('Barcode') %]" path='target_copy.barcode'>
index 8f77b44..195d502 100644 (file)
@@ -30,6 +30,8 @@ s.ROUTE_TO_CATALOGING = '[% l("Cataloging") %]';
 s.COPY_IN_TRANSIT = '[% l("Copy is In-Transit") %]';
 s.TOO_MANY_CLAIMS_RETURNED = 
   '[% l("Patron exceeds claims returned count.  Force this action?") %]';
+s.MARK_NEVER_CHECKED_OUT = 
+  '[% l("Mark Never Checked Out: [_1]", "{{barcodes.toString()}}") %]'
 }]);
 </script>
 
index d790570..71cc6a3 100644 (file)
@@ -5,9 +5,9 @@
 angular.module('egPatronApp').controller('PatronItemsOutCtrl',
 
        ['$scope','$q','$routeParams','egCore','egUser','patronSvc',
-        'egGridDataProvider','$modal','egCirc',
+        'egGridDataProvider','$modal','egCirc','egConfirmDialog',
 function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc , 
-         egGridDataProvider , $modal , egCirc) {
+         egGridDataProvider , $modal , egCirc , egConfirmDialog) {
 
     $scope.initTab('items_out', $routeParams.id);
 
@@ -22,7 +22,7 @@ function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc ,
     var display_lo = Number(
         egCore.env.aous['ui.circ.items_out.longoverdue']) || 1;
     var display_cr = Number(
-        egCore.env.aous['ui.circ.items_out.claimsreturned']) || 1;
+        egCore.env.aous['ui.circ.items_out.claimsreturned']) || 2;
 
     var provider = egGridDataProvider.instance({});
     $scope.gridDataProvider = provider;
@@ -218,44 +218,60 @@ function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc ,
         });
     }
 
+    // Reload the user to pick up changes in items out, fines, etc.
+    // Reload circs since LOST, etc. items may no longer be applicable for display.
+    function reset_page() {
+        patronSvc.refreshPrimary();
+        patronSvc.items_out = []; 
+        patronSvc.items_out_ids = [];
+        provider.refresh() 
+    }
+
+    function batch_action_with_barcodes(items, action) {
+        if (!items.length) return;
+        var barcodes = items.map(function(circ) 
+            { return circ.target_copy().barcode() });
+        action(barcodes).then(reset_page);
+    }
     $scope.mark_lost = function(items) {
+        batch_action_with_barcodes(items, egCirc.mark_lost);
+    }
+    $scope.mark_claims_returned = function(items) {
+        batch_action_with_barcodes(items, egCirc.mark_claims_returned_dialog);
+    }
+    $scope.mark_claims_never_checked_out = function(items) {
+        batch_action_with_barcodes(items, egCirc.mark_claims_never_checked_out);
+    }
+
+    $scope.renew = function(items, msg) {
         if (!items.length) return;
 
-        var barcodes = items.map(function(circ) {
-            return circ.target_copy().barcode()
-        });
+        var barcodes = items.map(function(circ) 
+            { return circ.target_copy().barcode() });
 
-        egCirc.mark_lost(barcodes)
-        .then(function() { 
-            // reload the user to pick up changes in items out, fines, etc.
-            patronSvc.refreshPrimary();
+        if (!msg) msg = egCore.strings.RENEW_ITEMS;
 
-            // reload circs since LOST items may no longer be applicable
-            // for display.
-            patronSvc.items_out = []; 
-            patronSvc.items_out_ids = [];
-            provider.refresh() 
+        return egConfirmDialog.open(msg, barcodes.join(' '), {}).result
+        .then(function() {
+            function do_one() {
+                var bc = barcodes.pop();
+                if (!bc) { reset_page(); return }
+                // finally -> continue even when one fails
+                egCirc.renew({copy_barcode : bc}).finally(do_one);
+            }
+            do_one();
         });
     }
 
-    $scope.mark_claims_returned = function(items) {
-        if (!items.length) return;
-
-        var barcodes = items.map(function(circ) {
-            return circ.target_copy().barcode()
-        });
-
-        egCirc.mark_claims_returned_dialog(barcodes)
-        .then(function() { 
-            // reload the user to pick up changes in items out, fines, etc.
-            patronSvc.refreshPrimary();
-
-            // reload circs since LOST items may no longer be applicable
-            // for display.
-            patronSvc.items_out = []; 
-            patronSvc.items_out_ids = [];
-            provider.refresh() 
+    $scope.renew_all = function() {
+        var circs = patronSvc.items_out.filter(function(circ) {
+            // all others will be rejected at the server
+            return (
+                !circ.stop_fines() ||
+                circ.stop_fines() == 'MAXFINES'
+            );
         });
+        $scope.renew(circs, egCore.strings.RENEW_ALL_ITEMS);
     }
 
 }]);
index 5238a56..6f89d8a 100644 (file)
@@ -934,8 +934,10 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
                             $modalInstance.close();
                             return;
                         }
+
+                        // finally -> continue even when one fails
                         service.mark_claims_returned(bc, date)
-                        .then(function(barcode) {
+                        .finally(function(barcode) {
                             if (barcode) deferred.notify(barcode);
                             mark_one();
                         });
@@ -947,6 +949,38 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         }).result;
     }
 
+    // serially checks in each barcode with claims_never_checked_out set
+    // returns promise, notified on each barcode, resolved after all
+    // checkins are complete.
+    service.mark_claims_never_checked_out = function(barcodes) {
+        if (!barcodes.length) return;
+
+        var deferred = $q.defer();
+        egConfirmDialog.open(
+            egCore.strings.MARK_NEVER_CHECKED_OUT, '', {barcodes : barcodes}
+
+        ).result.then(function() {
+            function mark_one() {
+                var bc = barcodes.pop();
+
+                if (!bc) { // all done
+                    deferred.resolve();
+                    return;
+                }
+
+                service.checkin(
+                    {claims_never_checked_out : true, copy_barcode : bc})
+                .finally(function() { 
+                    deferred.notify(bc);
+                    mark_one();
+                })
+            }
+            mark_one();
+        });
+
+        return deferred.promise;
+    }
+
     service.mark_damaged = function(copy_ids) {
         return egConfirmDialog.open(
             egCore.strings.MARK_DAMAGED_CONFIRM, '',
index 836ea3c..9c01269 100644 (file)
@@ -435,7 +435,7 @@ angular.module('egGridMod',
                     action.handler(grid.getSelectedItems());
                 } catch(E) {
                     console.error('Error executing handler for "' 
-                        + action.label + '" => ' + E);
+                        + action.label + '" => ' + E + "\n" + E.stack);
                 }
             }