checkin; backdate post checkin
authorBill Erickson <berick@esilibrary.com>
Wed, 25 Jun 2014 15:08:22 +0000 (11:08 -0400)
committerBill Erickson <berick@esilibrary.com>
Wed, 25 Jun 2014 15:08:22 +0000 (11:08 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/circ/checkin/t_checkin_table.tt2
Open-ILS/src/templates/staff/circ/share/t_backdate_dialog.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/services/circ.js

index 4b9024d..79392c1 100644 (file)
     handler="fetchLastCircPatron"
     label="[% l('Retrieve Last Patron Who Circulated Item') %]">
   </eg-grid-action>
+  <eg-grid-action 
+    handler="showBackdateDialog"
+    label="[% l('Backdate Post-Checkin') %]">
+  </eg-grid-action>
 
   <eg-grid-field label="[% l('Alert Msg') %]"   
     path="acp.alert_message"></eg-grid-field>
@@ -34,7 +38,7 @@
     path='circ.id'></eg-grid-field>
 
   <eg-grid-field label="[% l('Checkin Date') %]"    
-    path='circ.checkin_time'></eg-grid-field>
+    path='circ.checkin_time' dateformat='short'></eg-grid-field>
 
   <eg-grid-field label="[% l('Family Name') %]"    
     path='au.family_name'></eg-grid-field>
@@ -59,7 +63,7 @@
   </eg-grid-field>
 
   <eg-grid-field label="[% l('Due Date') %]"    
-    path='circ.due_date' hidden></eg-grid-field>
+    path='circ.due_date' dateformat='short' hidden></eg-grid-field>
 
   <eg-grid-field label="[% l('Author') %]"      
     path="author" hidden></eg-grid-field>
diff --git a/Open-ILS/src/templates/staff/circ/share/t_backdate_dialog.tt2 b/Open-ILS/src/templates/staff/circ/share/t_backdate_dialog.tt2
new file mode 100644 (file)
index 0000000..034e909
--- /dev/null
@@ -0,0 +1,24 @@
+<div class="modal-header">
+  <button type="button" class="close" 
+    ng-click="cancel()" aria-hidden="true">&times;</button>
+  <h4 class="modal-title">
+    [% l('Backdate Already Checked-In Circulations') %]
+  </h4>
+</div>
+<div class="modal-body">
+  <div>[% l('Number of circulations selected: [_1]', '{{dialog.num_circs}}') %]</div>
+  <div class="pad-vert">
+    <progress max="dialog.num_circs" value="dialog.num_processed"></progress>
+  </div>
+  <div class="pad-vert row">
+    <div class="col-md-6">[% l('Effective Date:') %]</div>
+    <div class="col-md-6">
+      <input eg-date-input required 
+        class="form-control" ng-model="dialog.backdate"/>
+    </div>
+  </div>
+</div>
+<div class="modal-footer">
+  <button class="btn btn-primary" ng-click="ok()">[% l('Submit') %]</button>
+  <button class="btn btn-warning" ng-click="cancel()">[% l('Cancel') %]</button>
+</div>
index 840ddb5..f40415c 100644 (file)
@@ -213,10 +213,8 @@ function($scope , $q , $window , $location , egCore , checkinSvc , egGridDataPro
         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) {
+        egCirc.last_copy_circ(checkin.acp.id())
+        .then(function(circ) {
 
             if (circ) {
                 // jump to the patron UI (separate app)
@@ -230,5 +228,23 @@ function($scope , $q , $window , $location , egCore , checkinSvc , egGridDataPro
         });
     }
 
+    $scope.showBackdateDialog = function(items) {
+        var circ_ids = [];
+
+        angular.forEach(items, function(item) {
+            if (item.circ) circ_ids.push(item.circ.id());
+        });
+
+        if (circ_ids.length) {
+            egCirc.backdate_dialog(circ_ids).then(function(result) {
+                angular.forEach(items, function(item) {
+                    item.circ.checkin_time(result.backdate);
+                })
+            });
+            // TODO: support grid row styling
+            checkinGrid.refresh();
+        }
+    }
+
 }])
 
index deab3a5..1eaa702 100644 (file)
@@ -598,6 +598,13 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         });
     }
 
+    service.last_copy_circ = function(copy_id) {
+        return egCore.pcrud.search('circ', 
+            {target_copy : copy_id},
+            {order_by : {circ : 'xact_start desc' }, limit : 1}
+        );
+    }
+
     service.circ_exists_dialog = function(evt, params, options) {
         return $modal.open({
             templateUrl: './circ/share/t_circ_exists_dialog',
@@ -614,10 +621,7 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
             resolve : {
                 // fetch the conflicting open circulation
                 openCirc : function() {
-                    return egCore.pcrud.search('circ', 
-                        {target_copy : evt.payload.copy.id()},
-                        {order_by : {circ : 'xact_start desc' }, limit : 1}
-                    );
+                    return service.last_copy_circ(evt.payload.copy.id());
                 }
             }
         }).result.then(
@@ -637,6 +641,60 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         );
     }
 
+    service.batch_backdate = function(circ_ids, backdate) {
+        return egCore.net.request(
+            'open-ils.circ',
+            'open-ils.circ.post_checkin_backdate.batch',
+            egCore.auth.token(), circ_ids, backdate);
+    }
+
+    service.backdate_dialog = function(circ_ids) {
+        return $modal.open({
+            templateUrl: './circ/share/t_backdate_dialog',
+            controller: 
+                       ['$scope','$modalInstance',
+                function($scope , $modalInstance) {
+
+                var today = new Date();
+                $scope.dialog = {
+                    num_circs : circ_ids.length,
+                    num_processed : 0,
+                    backdate : today
+                }
+
+                $scope.$watch('dialog.backdate', function(newval) {
+                    if (newval && newval > today) 
+                        $scope.dialog.backdate = today;
+                });
+
+
+                $scope.cancel = function() { 
+                    $modalInstance.dismiss();
+                }
+
+                $scope.ok = function() { 
+
+                    var bd = $scope.dialog.backdate.toISOString().replace(/T.*/,'');
+                    service.batch_backdate(circ_ids, bd)
+                    .then(
+                        function() { // on complete
+                            $modalInstance.close({backdate : bd});
+                        },
+                        null,
+                        function(resp) { // on response
+                            console.debug('backdate returned ' + resp);
+                            if (resp == '1') {
+                                $scope.num_processed++;
+                            } else {
+                                console.error(egCore.evt.parse(resp));
+                            }
+                        }
+                    );
+                }
+            }]
+        }).result;
+    }
+
 
     // alert when copy location alert_message is set.
     // This does not affect processing, it only produces a click-through