billing cont. refunds..
authorBill Erickson <berick@esilibrary.com>
Tue, 27 May 2014 16:25:55 +0000 (12:25 -0400)
committerBill Erickson <berick@esilibrary.com>
Tue, 27 May 2014 16:25:55 +0000 (12:25 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/circ/patron/t_bills.tt2
Open-ILS/src/templates/staff/circ/patron/t_bills_list.tt2
Open-ILS/web/js/ui/default/staff/circ/patron/bills.js
Open-ILS/web/js/ui/default/staff/services/grid.js
Open-ILS/web/js/ui/default/staff/services/net.js

index 0c57c78..6d68f83 100644 (file)
@@ -6,7 +6,7 @@
       <div class="col-md-4">[% l('Total Owed:') %]</div>
       <div class="col-md-2 strong-text">{{summary.balance_owed() | currency}}</div>
       <div class="col-md-4">[% l('Refunds Available:') %]</div>
-      <div class="col-md-2">{{0 | currency}}</div>
+      <div class="col-md-2">{{refunds_available() | currency}}</div>
     </div>
     <div class="row">
       <div class="col-md-4">[% l('Total Billed:') %]</div>
@@ -18,7 +18,7 @@
       <div class="col-md-4">[% l('Total Paid:') %]</div>
       <div class="col-md-2">{{summary.total_paid() | currency}}</div>
       <div class="col-md-4">[% l('Session Voided:') %]</div>
-      <div class="col-md-2">{{0 | currency}}</div>
+      <div class="col-md-2">{{session_voided | currency}}</div>
     </div>
     <div class="row"><hr/></div>
     <div class="row">
@@ -65,7 +65,7 @@
           <div class="col-md-6">
             <input type="number" min="0" step="any" id="amount-input" 
               ng-model="payment_amount" focus-me="focus_payment" 
-              value="0" class="form-control col-md-6 "/>
+              value="" class="form-control col-md-6 "/>
           </div>
         </div>
         <div class="form-group">
index eb66017..4373b01 100644 (file)
@@ -2,6 +2,8 @@
 <eg-grid
   idl-class="mobts"
   query="gridQuery"
+  sort="gridSort"
+
   on-item-retrieved="gridItemRetrieved"
   on-selection-change="gridSelectionChanged"
   revision="gridRevision"
@@ -33,7 +35,7 @@
   -->
 
   <eg-grid-action label="[% l('Void All Billings') %]" 
-    handler=""></eg-grid-action>
+    handler="voidAllBillings"></eg-grid-action>
 
   <eg-grid-action label="[% l('Refund') %]" 
     handler=""></eg-grid-action>
index 0e6b2fb..d0a3fcf 100644 (file)
@@ -110,6 +110,7 @@ function($scope,  $q , $routeParams,  $locale , egCore , egGridDataProvider , bi
 
     // set up some defaults
     $scope.payment_amount = 0;
+    $scope.session_voided = 0;
     $scope.payment_type = 'cash_payment';
     $scope.focus_payment = true;
     $scope.annotate_payment = false;
@@ -136,10 +137,13 @@ function($scope,  $q , $routeParams,  $locale , egCore , egGridDataProvider , bi
     function selected_payment_info() {
         var info = {owed : 0, billed : 0, paid : 0};
         angular.forEach(selectedItems, function(item) {
-            info.owed   += Number(item.balance_owed);
-            info.billed += Number(item.total_owed);
-            info.paid   += Number(item.total_paid);
+            info.owed   += Number(item.balance_owed) * 100;
+            info.billed += Number(item.total_owed) * 100;
+            info.paid   += Number(item.total_paid) * 100;
         });
+        info.owed /= 100;
+        info.billed /= 100;
+        info.paid /= 100;
         return info;
     }
 
@@ -158,6 +162,14 @@ function($scope,  $q , $routeParams,  $locale , egCore , egGridDataProvider , bi
     $scope.paid_selected = function() {
         return selected_payment_info().paid;
     }
+    $scope.refunds_available = function() {
+        var amount = 0;
+        angular.forEach(allItems, function(item) {
+            if (item.balance_owed < 0) 
+                amount += item.balance_owed * 100;
+        });
+        return -(amount / 100);
+    }
 
     // Avoid using parens [e.g. (1.23)] to indicate negative numbers, 
     // which is the Angular default.
@@ -169,6 +181,7 @@ function($scope,  $q , $routeParams,  $locale , egCore , egGridDataProvider , bi
 
     var query = {usr : billSvc.userId, balance_owed : {'<>' : 0}};
     $scope.gridQuery = function() {return query};
+    $scope.gridSort = ['xact_start']; // default sort
 
     $scope.gridItemRetrieved = function(item) {
         item.payment_pending = 0;
@@ -232,16 +245,20 @@ function($scope,  $q , $routeParams,  $locale , egCore , egGridDataProvider , bi
         return payments;
     }
 
+    function refreshDisplay() {
+        patronSvc.fetchUserStats();
+        $scope.payment_amount = 0;
+        $scope.gridRevision++; // tell the grid to refresh itself
+    }
+
     // generates payments, collects user note if needed, and sends payment
     // to server.
     function sendPayment(note) {
         billSvc.applyPayment(
             $scope.payment_type, generatePayments(), note)
         .then(function() {
-            patronSvc.fetchUserStats();
+            refreshDisplay();
             billSvc.fetchSummary().then(function(s) {$scope.summary = s});
-            $scope.payment_amount = 0;
-            $scope.gridRevision++; // tell the grid to refresh itself
         })
     }
 
@@ -271,11 +288,7 @@ function($scope,  $q , $routeParams,  $locale , egCore , egGridDataProvider , bi
             function(args) {
                 // send the billing to the server using the arguments
                 // provided in the billing dialog, then refresh
-                billSvc.billPatron(args).then(function() {
-                    patronSvc.fetchUserStats();
-                    $scope.payment_amount = 0;
-                    $scope.gridRevision++;
-                });
+                billSvc.billPatron(args).then(refreshDisplay);
             }
         );
     }
@@ -303,6 +316,41 @@ function($scope,  $q , $routeParams,  $locale , egCore , egGridDataProvider , bi
         }
     }
 
+    $scope.voidAllBillings = function(items) {
+        angular.forEach(items, function(item) {
+            egCore.net.request(
+                'open-ils.circ',
+                'open-ils.circ.money.billing.retrieve.all.authoritative',
+                egCore.auth.token(), item.id
+            ).then(function(bills) {
+                var bill_ids = [];
+                var cents = 0;
+                angular.forEach(bills, function(b) {
+                    cents += b.amount() * 100;
+                    bill_ids.push(b.id())
+                });
+
+                $scope.session_voided = 
+                    ($scope.session_voided * 100 + cents) / 100;
+
+                if (bill_ids.length == 0) {
+                    // TODO: warn
+                    return;
+                }
+
+                // TODO: alert of pending voiding
+
+                egCore.net.requestWithParamList(
+                    'open-ils.circ',
+                    'open-ils.circ.money.billing.void',
+                    [egCore.auth.token()].concat(bill_ids)
+                ).then(function(resp) {
+                    if (evt = egCore.evt.parse(resp)) return alert(evt);
+                    refreshDisplay();
+                });
+            });
+        });
+    }
 }])
 
 
index 2c816fb..489f4f6 100644 (file)
@@ -15,6 +15,9 @@ angular.module('egGridMod',
             // changes, the grid will be refreshed.
             query : '=',
 
+            // flattener-style sort array
+            sort : '=',
+
             // if true, grid columns are derived from all non-virtual
             // fields on the base idlClass
             autoFields : '@',
@@ -215,6 +218,10 @@ angular.module('egGridMod',
                     delete $scope.query;
                 }
 
+
+                grid.dataProvider.sort = $scope.sort || [];
+                delete $scope.sort;
+
                 if (angular.isDefined($scope.revision)) {
                     $scope.$watch('revision', function(newVal, oldVal) {
                         if (newVal != oldVal) 
@@ -430,8 +437,8 @@ angular.module('egGridMod',
 
             // fires the action handler function
             $scope.actionLauncher = function(action) {
-                $scope.gridActionsIsOpen = false;
                 action.handler(grid.getSelectedItems());
+                $scope.gridActionsIsOpen = false;
             }
 
             // returns the list of selected item objects
@@ -565,32 +572,6 @@ angular.module('egGridMod',
                     grid.selectOneItem(index);
                     grid.lastSelectedItemIndex = index;
                 }
-
-
-                /*
-                if (grid.onItemSelected) {
-                    // multiple items may be selected / de-selected within a
-                    // single click action.  Find all that have changed state.
-
-                    var all = grid.getSelectedItems();
-                    
-                    // look for items that were originally selected
-                    // which are no longer selected
-                    angular.forEach(origSelected, function(index) {
-                        if (!$scope.selected[index]) {
-                            grid.onItemSelected(
-                                null, grid.getItemByIndex(index), all);
-                        }
-                    });
-
-                    // look for items which are selected now, but were
-                    // not originally selected
-                    angular.forEach(all, function(item) {
-                        if (origSelected.indexOf(grid.indexValue(item)) < 0)
-                            grid.onItemSelected(item, null, all);
-                    });
-                }
-                */
             }
 
             // Builds a sort expression from column sort priorities.
index 1112db8..156d554 100644 (file)
@@ -86,5 +86,15 @@ function($q,  $rootScope,  egEvent) {
         return deferred.promise;
     }
 
+    // In addition to the service and method names, accepts a single array
+    // as the collection of API call parameters.  This array will get 
+    // expanded to individual arguments in the final server call.
+    // This is useful when the server call expects each param to be
+    // a top-level value, but the set of params is dynamic.
+    net.requestWithParamList = function(service, method, params) {
+        var args = [service, method].concat(params);
+        return net.request.apply(net, args);
+    }
+
     return net;
 }]);