From: Bill Erickson Date: Wed, 28 May 2014 14:48:05 +0000 (-0400) Subject: xact details page cont. X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=21659036e7ec7ec32605f3d910cdd557cf724369;p=working%2FEvergreen.git xact details page cont. Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/templates/staff/circ/patron/index.tt2 b/Open-ILS/src/templates/staff/circ/patron/index.tt2 index 05b3ef3076..ed33ead0db 100644 --- a/Open-ILS/src/templates/staff/circ/patron/index.tt2 +++ b/Open-ILS/src/templates/staff/circ/patron/index.tt2 @@ -29,7 +29,8 @@ angular.module('egCoreMod').run(['egStrings', function(s) { s.ANNOTATE_PAYMENT_MSG = "[% l('Please annotate this payment') %]"; s.CONFIRM_REFUND_PAYMENT = - "[% |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 %]" + "[% |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}}') %]"; }]); diff --git a/Open-ILS/src/templates/staff/circ/patron/t_bills_list.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_bills_list.tt2 index b88ff6e8b4..241869eae2 100644 --- a/Open-ILS/src/templates/staff/circ/patron/t_bills_list.tt2 +++ b/Open-ILS/src/templates/staff/circ/patron/t_bills_list.tt2 @@ -3,6 +3,7 @@ idl-class="mobts" query="gridQuery" sort="gridSort" + activate-item="activateBill" on-item-retrieved="gridItemRetrieved" on-selection-change="gridSelectionChanged" diff --git a/Open-ILS/src/templates/staff/circ/patron/t_search_results.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_search_results.tt2 index 38e715cd82..16ba3da07b 100644 --- a/Open-ILS/src/templates/staff/circ/patron/t_search_results.tt2 +++ b/Open-ILS/src/templates/staff/circ/patron/t_search_results.tt2 @@ -1,5 +1,5 @@ [% l('Transaction Details') %] +

[% l('Details for Transaction #[_1]', '{{xact.id()}}') %]

[% l('Summary') %]

[% l('Billing Location') %]
{{xact.billing_location().shortname()}}
-
-
-
[% l('Bill #') %]
-
{{xact.id()}}
[% l('Total Billed') %]
{{xact.total_owed() | currency}}
[% l('Title') %]
@@ -42,6 +38,24 @@
[% l('Checked In') %]
{{xact.circulation().checkin_time() | date:'short'}}
+
+
[% l('Barcode') %]
+ +
[% l('Call Number') %]
+
+ {{xact.circulation().target_copy().call_number().label()}} +
+
[% l('Location') %]
+
+ {{xact.circulation().target_copy().location().name()}} +
+
+ @@ -54,6 +68,13 @@ auto-fields="true" page-size="10" items-provider="billGridProvider"> + + + + +
@@ -65,5 +86,7 @@ auto-fields="true" page-size="10" items-provider="paymentGridProvider"> + diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js b/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js index c5fe127470..d509a440f8 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js +++ b/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js @@ -111,6 +111,74 @@ function($q , egCore , patronSvc) { }); } + service.fetchXact = function(id) { + return egCore.pcrud.retrieve('mobts', id, + { flesh : 5, + flesh_fields : { + mobts : ['circulation','grocery'], + circ : ['target_copy'], + acp : ['call_number','location'], + acn : ['record'], + bre : ['simple_record'] + }, + select : { bre : ['id'] } // avoid MARC + }, + {authoritative : true} + ).then(function(xact) { + xact.billing_location(egCore.org.get(xact.billing_location())); + return xact; + }); + } + + service.fetchBills = function(xact_id) { + return egCore.net.request( + 'open-ils.circ', + 'open-ils.circ.money.billing.retrieve.all.authoritative', + egCore.auth.token(), xact_id + ); + } + + service.fetchPayments = function(xact_id) { + return egCore.net.request( + 'open-ils.circ', + 'open-ils.circ.money.payment.retrieve.all.authoritative', + egCore.auth.token(), xact_id + ); + } + + service.voidBills = function(bill_ids) { + return 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); + return resp; + }); + } + + service.updateBillNotes = function(note, ids) { + return egCore.net.requestWithParamList( + 'open-ils.circ', + 'open-ils.circ.money.billing.note.edit', + [egCore.auth.token(), note].concat(ids) + ).then(function(resp) { + if (evt = egCore.evt.parse(resp)) return alert(evt); + return resp; + }); + } + + service.updatePaymentNotes = function(note, ids) { + return egCore.net.requestWithParamList( + 'open-ils.circ', + 'open-ils.circ.money.payment.note.edit', + [egCore.auth.token(), note].concat(ids) + ).then(function(resp) { + if (evt = egCore.evt.parse(resp)) return alert(evt); + return resp; + }); + } + return service; }]) @@ -325,7 +393,7 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location, $scope.applyPayment = function() { if ($scope.annotate_payment) { egPromptDialog.open( - egCore.strings.ANNOTATE_PAYMENT_MSG, + egCore.strings.ANNOTATE_PAYMENT_MSG, '', {ok : function(value) {sendPayment(value)}} ); } else { @@ -335,11 +403,8 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location, $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) { + + billSvc.fetchBills(item.id).then(function(bills) { var bill_ids = []; var cents = 0; angular.forEach(bills, function(b) { @@ -357,12 +422,7 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location, // 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); + billSvc.voidBills(bill_ids).then(function() { refreshDisplay(); }); }); @@ -396,40 +456,25 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location, $location.path('/circ/patron/' + patronSvc.current.id() + '/bill/' + all[0].id); } + + $scope.activateBill = function(xact) { + $scope.showFullDetails([xact]); + } + }]) /** * Displays details of a single transaction */ .controller('XactDetailsCtrl', - ['$scope','$q','$routeParams','egCore','egGridDataProvider', -function($scope, $q , $routeParams , egCore , egGridDataProvider) { + ['$scope','$q','$routeParams','egCore','egGridDataProvider','patronSvc','billSvc','egPromptDialog', +function($scope, $q , $routeParams , egCore , egGridDataProvider , patronSvc , billSvc , egPromptDialog) { $scope.initTab('bills', $routeParams.id); var xact_id = $routeParams.xact_id; var bills = []; var payments = []; - egCore.pcrud.retrieve('mobts', xact_id, - { flesh : 5, - flesh_fields : { - mobts : ['circulation','grocery'], - circ : ['target_copy'], - acp : ['call_number'], - acn : ['record'], - bre : ['simple_record'] - }, - // avoid fetching the MARC blob by specifying which - // fields on the bre to select. More may be needed. - // note that fleshed fields are explicitly selected. - select : { bre : ['id'] } - }, - {authoritative : true} - ).then(function(xact) { - xact.billing_location(egCore.org.get(xact.billing_location())); - $scope.xact = xact; - }); - // --- bills grid var billProvider = egGridDataProvider.instance(); billProvider.get = function(offset, count) { @@ -438,15 +483,6 @@ function($scope, $q , $routeParams , egCore , egGridDataProvider) { billProvider.itemFieldValue = billProvider.nestedItemFieldValue; $scope.billGridProvider = billProvider; - egCore.net.request( - 'open-ils.circ', - 'open-ils.circ.money.billing.retrieve.all.authoritative', - egCore.auth.token(), xact_id - ).then(function(mbs) { - bills = mbs; - billProvider.increment(); - }); - // --- payments grid var paymentProvider = egGridDataProvider.instance(); paymentProvider.get = function(offset, count) { @@ -455,15 +491,91 @@ function($scope, $q , $routeParams , egCore , egGridDataProvider) { paymentProvider.itemFieldValue = paymentProvider.nestedItemFieldValue; $scope.paymentGridProvider = paymentProvider; - egCore.net.request( - 'open-ils.circ', - 'open-ils.circ.money.payment.retrieve.all.authoritative', - egCore.auth.token(), xact_id - ).then(function(mps) { - payments = mps; - paymentProvider.increment(); + // -- actions + $scope.voidBillings = function(bill_list) { + var bill_ids = []; + angular.forEach(bill_list, function(b) { + if (b.voided() != 't') bill_ids.push(b.id()); + }); + + if (bill_ids.length == 0) { + // TODO: warn + return; + } + + billSvc.voidBills(bill_ids).then(function() { + + // refresh bills and summary data + // note: no need to update payments + patronSvc.fetchUserStats(); + + billSvc.fetchXact(xact_id).then(function(xact) { + $scope.xact = xact + }); + + billSvc.fetchBills(xact_id).then(function(bs) { + bills = bs; + billProvider.increment(); + }); + }); + } + + // batch-edit billing and payment notes, depending on 'type' + function editNotes(selected, type) { + var notes = selected.map(function(b){ return b.note() }).join(','); + var ids = selected.map(function(b){ return b.id() }); + + // show the note edit prompt + egPromptDialog.open( + egCore.strings.EDIT_BILL_PAY_NOTE, notes, { + ids : ''+ids, + ok : function(value) { + + var func = 'updateBillNotes'; + if (type == 'payment') func = 'updatePaymentNotes'; + + billSvc[func](value, ids).then(function() { + + if (type == 'payment') { + billSvc.fetchPayments(xact_id).then(function(ps) { + payments = ps; + paymentProvider.increment(); + }); + + } else { + billSvc.fetchBills(xact_id).then(function(bs) { + bills = bs; + billProvider.increment(); + }); + } + }); + } + } + ); + } + + $scope.editBillNotes = function(selected) { + editNotes(selected, 'bill'); + } + + $scope.editPaymentNotes = function(selected) { + editNotes(selected, 'payment'); + } + + // -- retrieve our data + billSvc.fetchXact(xact_id).then(function(xact) { + $scope.xact = xact; }); + billSvc.fetchBills(xact_id).then(function(bs) { + bills = bs; + billProvider.increment(); + }); + + billSvc.fetchPayments(xact_id).then(function(ps) { + payments = ps; + paymentProvider.increment(); + }); }]) diff --git a/Open-ILS/web/js/ui/default/staff/services/grid.js b/Open-ILS/web/js/ui/default/staff/services/grid.js index cf80393b4d..6be5c1b48c 100644 --- a/Open-ILS/web/js/ui/default/staff/services/grid.js +++ b/Open-ILS/web/js/ui/default/staff/services/grid.js @@ -99,9 +99,9 @@ angular.module('egGridMod', controller : [ '$scope','$q','egCore','egGridFlatDataProvider','$location', - 'egGridColumnsProvider','$filter','$window','$sce', + 'egGridColumnsProvider','$filter','$window','$sce','$timeout', function($scope, $q , egCore, egGridFlatDataProvider , $location, - egGridColumnsProvider , $filter , $window , $sce) { + egGridColumnsProvider , $filter , $window , $sce , $timeout) { var grid = this; @@ -438,10 +438,22 @@ angular.module('egGridMod', return ''+item; } - // fires the action handler function + // fires the action handler function for a context action $scope.actionLauncher = function(action) { - action.handler(grid.getSelectedItems()); $scope.gridActionsIsOpen = false; + + if (!action.handler) { + console.error( + 'No handler specified for "' + action.label + '"'); + return; + } + + try { + action.handler(grid.getSelectedItems()); + } catch(E) { + console.error('Error executing handler for "' + + action.label + '" => ' + E); + } } // returns the list of selected item objects diff --git a/Open-ILS/web/js/ui/default/staff/services/ui.js b/Open-ILS/web/js/ui/default/staff/services/ui.js index ac090b107b..6aec308d30 100644 --- a/Open-ILS/web/js/ui/default/staff/services/ui.js +++ b/Open-ILS/web/js/ui/default/staff/services/ui.js @@ -141,10 +141,15 @@ function($modal, $interpolate) { }]) /** - * egPromptDialog.open("some message goes {{here}}", { - * here : 'foo', - * ok : function(value) {console.log(value)}, - * cancel : function() {}}); + * egPromptDialog.open( + * "prompt message goes {{here}}", + * promptValue, // optional + * { + * here : 'foo', + * ok : function(value) {console.log(value)}, + * cancel : function() {console.log('prompt denied')} + * } + * ); */ .factory('egPromptDialog', @@ -152,13 +157,13 @@ function($modal, $interpolate) { function($modal, $interpolate) { var service = {}; - service.open = function(message, msg_scope) { + service.open = function(message, promptValue, msg_scope) { return $modal.open({ templateUrl: './share/t_prompt_dialog', controller: ['$scope', '$modalInstance', function($scope, $modalInstance) { $scope.message = $interpolate(message)(msg_scope); - $scope.args = {value : ''}; + $scope.args = {value : promptValue || ''}; $scope.focus = true; $scope.ok = function() { if (msg_scope.ok) msg_scope.ok($scope.args.value);