From: Bill Erickson Date: Mon, 9 Jun 2014 14:33:32 +0000 (-0400) Subject: move shared billing bits to external service X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=c4da43169e5f59c7021659150d19ebbf56c6f0bf;p=working%2FEvergreen.git move shared billing bits to external service 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 0e638a8420..853304f1b5 100644 --- a/Open-ILS/src/templates/staff/circ/patron/index.tt2 +++ b/Open-ILS/src/templates/staff/circ/patron/index.tt2 @@ -9,6 +9,7 @@ + diff --git a/Open-ILS/src/templates/staff/circ/patron/t_bill_history_xacts.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_bill_history_xacts.tt2 index e72b8dd172..a349ec93b7 100644 --- a/Open-ILS/src/templates/staff/circ/patron/t_bill_history_xacts.tt2 +++ b/Open-ILS/src/templates/staff/circ/patron/t_bill_history_xacts.tt2 @@ -9,7 +9,7 @@ revision="xactRevision"> + label="[% l('Add Billing') %]" handler="addBilling"> diff --git a/Open-ILS/src/templates/staff/circ/patron/t_bill_patron_dialog.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_bill_patron_dialog.tt2 deleted file mode 100644 index 2170d32820..0000000000 --- a/Open-ILS/src/templates/staff/circ/patron/t_bill_patron_dialog.tt2 +++ /dev/null @@ -1,93 +0,0 @@ - -
- -
- - diff --git a/Open-ILS/src/templates/staff/circ/share/t_bill_patron_dialog.tt2 b/Open-ILS/src/templates/staff/circ/share/t_bill_patron_dialog.tt2 new file mode 100644 index 0000000000..b946b8cbe7 --- /dev/null +++ b/Open-ILS/src/templates/staff/circ/share/t_bill_patron_dialog.tt2 @@ -0,0 +1,93 @@ + +
+ +
+ + 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 0e0e93c937..4c7676eda3 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 @@ -48,109 +48,6 @@ function($q , egCore , patronSvc) { }); } - service.fetchBillingTypes = function() { - if (egCore.env.cbt) - return $q.when(egCore.env.cbt.list); - - return egCore.pcrud.search('cbt', - { // first 100 are reserved for system-generated bills - id : {'>' : 100}, - owner : egCore.org.ancestors( - egCore.auth.user().ws_ou(), true) - }, - {}, {atomic : true} - ).then(function(list) { - egCore.env.absorbList(list, 'cbt'); - return list; - }); - } - - service.createGroceryXact = function(args) { - var groc = new egCore.idl.mg(); - groc.billing_location(egCore.auth.user().ws_ou()); - groc.note(args.note); - groc.usr(patronSvc.current.id()); - - // create the xact - return egCore.net.request( - 'open-ils.circ', - 'open-ils.circ.money.grocery.create', - egCore.auth.token(), groc - - // create the billing on the new xact - ).then(function(xact_id) { - if (evt = egCore.evt.parse(xact_id)) - return alert(evt); - return xact_id; - }); - } - - service.createBilling = function(xact_id, args) { - var bill = new egCore.idl.mb(); - bill.xact(xact_id); - bill.amount(args.amount); - bill.btype(args.billingType); - bill.billing_type(egCore.env.cbt.map[args.billingType].name()); - bill.note(args.note); - - return egCore.net.request( - 'open-ils.circ', - 'open-ils.circ.money.billing.create', - egCore.auth.token(), bill - - // check the billing response - ).then(function(bill_id) { - if (evt = egCore.evt.parse(bill_id)) { - alert(evt); - } else { - return bill_id; - } - }); - } - - service.billPatron = function(args, xact) { - - // apply a billing to an existing transaction - if (xact) return service.createBilling(xact.id, args); - - // create a new grocery xact, then apply a billing - return service.createGroceryXact(args) - .then(function(xact_id) { - return service.createBilling(xact_id, args); - }); - } - - service.xactFlesh = { - flesh : 5, - flesh_fields : { - mbt : ['summary','circulation','grocery','reservation'], - circ : ['target_copy'], - acp : ['call_number','location','status','age_protect'], - acn : ['record'], - bre : ['simple_record'] - }, - select : { bre : ['id'] } // avoid MARC - } - - service.fetchXact = function(id) { - return egCore.pcrud.retrieve( - 'mbt', id, service.xactFlesh, {authoritative : true} - ).then(function(xact) { - - /* mobts has billing_location, but mbts does not - * only the xact detail page shows it now, so maybe move - * this into the template... - * - var loc; - if (xact.circulation()) loc = xact.circulation().circ_lib(); - if (xact.reservation()) loc = xact.reservation().pickup_lib(); - if (xact.grocery()) loc = xact.grocery().billing_location(); - xact.billing_location(egCore.org.get(loc)); - */ - return xact; - }); - } - service.fetchBills = function(xact_id) { var bills = []; return egCore.pcrud.search('mb', @@ -215,8 +112,10 @@ function($q , egCore , patronSvc) { .controller('PatronBillsCtrl', ['$scope','$q','$routeParams','egCore','egConfirmDialog','$location', 'egGridDataProvider','billSvc','patronSvc','egPromptDialog','$modal', + 'egBilling', function($scope , $q , $routeParams , egCore , egConfirmDialog , $location, - egGridDataProvider , billSvc , patronSvc , egPromptDialog , $modal) { + egGridDataProvider , billSvc , patronSvc , egPromptDialog , $modal, + egBilling) { $scope.initTab('bills', $routeParams.id); billSvc.userId = $routeParams.id; @@ -437,49 +336,18 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location, // For now, only adds billing to first selected item. // Could do batches later if needed $scope.addBilling = function(all) { - if (all[0]) showBillDialog(all[0]); + if (all[0]) { + egBilling.showBillDialog({ + xact : egCore.idl.flatToNestedHash(all[0]), + patron : $scope.patron() + }).then(refreshDisplay); + } } $scope.showBillDialog = function($event) { - showBillDialog(); - } - - function showBillDialog(xact) { - return $modal.open({ - templateUrl: './circ/patron/t_bill_patron_dialog', - controller: - ['$scope','$modalInstance','$timeout','billingTypes', - function($scope , $modalInstance , $timeout , billingTypes) { - $scope.focus = true; - $scope.xact = xact; - $scope.patron = patronSvc.current; - $scope.billingTypes = billingTypes; - $scope.location = egCore.org.get(egCore.auth.user().ws_ou()), - $scope.billArgs = { - billingType : 101 // default to stock Misc. billing type - } - $scope.ok = function(args) { $modalInstance.close(args) } - $scope.cancel = function () { $modalInstance.dismiss() } - $scope.updateDefaultPrice = function() { - var type = billingTypes.filter(function(t) { - return t.id() == $scope.billArgs.billingType })[0]; - if (type.default_price() && !$scope.billArgs.amount) - $scope.billArgs.amount = Number(type.default_price()); - } - }], - resolve : { - // if we don't already have them, fetch the billing types - billingTypes : function() { - return billSvc.fetchBillingTypes(); - } - } - }).result.then( - function(args) { - // send the billing to the server using the arguments - // provided in the billing dialog, then refresh - billSvc.billPatron(args, xact).then(refreshDisplay); - } - ); + egBilling.showBillDialog({ + patron : $scope.patron() + }).then(refreshDisplay); } // Select refunds adds all refunds to the existing selection. @@ -634,8 +502,8 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location, * Displays details of a single transaction */ .controller('XactDetailsCtrl', - ['$scope','$q','$routeParams','egCore','egGridDataProvider','patronSvc','billSvc','egPromptDialog', -function($scope, $q , $routeParams , egCore , egGridDataProvider , patronSvc , billSvc , egPromptDialog) { + ['$scope','$q','$routeParams','egCore','egGridDataProvider','patronSvc','billSvc','egPromptDialog','egBilling', +function($scope, $q , $routeParams , egCore , egGridDataProvider , patronSvc , billSvc , egPromptDialog , egBilling) { $scope.initTab('bills', $routeParams.id); var xact_id = $routeParams.xact_id; @@ -668,7 +536,7 @@ function($scope, $q , $routeParams , egCore , egGridDataProvider , patronSvc , // note: no need to update payments patronSvc.fetchUserStats(); - billSvc.fetchXact(xact_id).then(function(xact) { + egBilling.fetchXact(xact_id).then(function(xact) { $scope.xact = xact }); @@ -711,7 +579,7 @@ function($scope, $q , $routeParams , egCore , egGridDataProvider , patronSvc , } // -- retrieve our data - billSvc.fetchXact(xact_id).then(function(xact) { + egBilling.fetchXact(xact_id).then(function(xact) { $scope.xact = xact; // set the title. only needs to be done on initial page load @@ -757,8 +625,8 @@ function($scope, $q , $routeParams , egCore , patronSvc , billSvc , egPromptDia .controller('BillXactHistoryCtrl', - ['$scope','$q','egCore','patronSvc','billSvc','egPromptDialog','$location', -function($scope, $q , egCore , patronSvc , billSvc , egPromptDialog , $location) { + ['$scope','$q','egCore','patronSvc','billSvc','egPromptDialog','$location','egBilling', +function($scope, $q , egCore , patronSvc , billSvc , egPromptDialog , $location , egBilling) { $scope.gridControls = { selectedItems : function(){return []}, @@ -766,6 +634,7 @@ function($scope, $q , egCore , patronSvc , billSvc , egPromptDialog , $location $scope.showFullDetails([item]); } } + $scope.xactRevision = 0; // TODO; move me to service function selected_payment_info() { @@ -805,6 +674,18 @@ function($scope, $q , egCore , patronSvc , billSvc , egPromptDialog , $location $location.path('/circ/patron/' + patronSvc.current.id() + '/bill/' + all[0].id); } + + // For now, only adds billing to first selected item. + // Could do batches later if needed + $scope.addBilling = function(all) { + if (all[0]) { + egBilling.showBillDialog({ + xact : egCore.idl.flatToNestedHash(all[0]), + patron : $scope.patron() + }).then(function() { $scope.xactRevision++; }) + } + } + }]) .controller('BillPaymentHistoryCtrl', diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/billing.js b/Open-ILS/web/js/ui/default/staff/circ/services/billing.js new file mode 100644 index 0000000000..4f10f8f03f --- /dev/null +++ b/Open-ILS/web/js/ui/default/staff/circ/services/billing.js @@ -0,0 +1,162 @@ +/** + * Shared services for patron billing. + * + */ + +angular.module('egCoreMod') + +.factory('egBilling', + ['$modal','$q','egCore','egUser', +function($modal , $q , egCore , egUser) { + + var service = {}; + + service.fetchXact = function(xact_id) { + return egCore.pcrud.retrieve('mbt', { + flesh : 5, + flesh_fields : { + mbt : ['summary','circulation','grocery','reservation'], + circ: ['target_copy'], + acp : ['call_number','location','status','age_protect'], + acn : ['record'], + bre : ['simple_record'] + }, + select : {bre : ['id']}}, // avoid MARC + {authoritative : true} + ); + } + + service.billPatron = function(args, xact) { + // apply a billing to an existing transaction + if (xact) return service.createBilling(xact.id, args); + + // create a new grocery xact, then apply a billing + return service.createGroceryXact(args) + .then(function(xact_id) { + return service.createBilling(xact_id, args); + }); + } + + service.createGroceryXact = function(args) { + var groc = new egCore.idl.mg(); + groc.billing_location(egCore.auth.user().ws_ou()); + groc.note(args.note); + groc.usr(args.patron_id); + + // create the xact + return egCore.net.request( + 'open-ils.circ', + 'open-ils.circ.money.grocery.create', + egCore.auth.token(), groc + + // create the billing on the new xact + ).then(function(xact_id) { + if (evt = egCore.evt.parse(xact_id)) + return alert(evt); + return xact_id; + }); + } + + service.fetchBillingTypes = function() { + if (egCore.env.cbt) + return $q.when(egCore.env.cbt.list); + + return egCore.pcrud.search('cbt', + { // first 100 are reserved for system-generated bills + id : {'>' : 100}, + owner : egCore.org.ancestors( + egCore.auth.user().ws_ou(), true) + }, + {}, {atomic : true} + ).then(function(list) { + egCore.env.absorbList(list, 'cbt'); + return list; + }); + } + + service.createBilling = function(xact_id, args) { + var bill = new egCore.idl.mb(); + bill.xact(xact_id); + bill.amount(args.amount); + bill.btype(args.billingType); + bill.billing_type(egCore.env.cbt.map[args.billingType].name()); + bill.note(args.note); + + return egCore.net.request( + 'open-ils.circ', + 'open-ils.circ.money.billing.create', + egCore.auth.token(), bill + + // check the billing response + ).then(function(bill_id) { + if (evt = egCore.evt.parse(bill_id)) { + alert(evt); + } else { + return bill_id; + } + }); + } + + + // args: + // xact OR xact_id : if null, creates a grocery xact + // patron OR patron_id + service.showBillDialog = function(args) { + + return $modal.open({ + templateUrl: './circ/share/t_bill_patron_dialog', + controller: + ['$scope','$modalInstance','$timeout','billingTypes','xact','patron', + function($scope , $modalInstance , $timeout , billingTypes , xact , patron) { + console.debug('billing patron ' + patron.id()); + $scope.focus = true; + $scope.xact = xact; + $scope.patron = patron; + $scope.billingTypes = billingTypes; + $scope.location = egCore.org.get(egCore.auth.user().ws_ou()), + $scope.billArgs = { + billingType : 101, // default to stock Misc. billing type + xact : xact, + patron_id : patron.id() + } + $scope.ok = function(args) { $modalInstance.close(args) } + $scope.cancel = function () { $modalInstance.dismiss() } + $scope.updateDefaultPrice = function() { + var type = billingTypes.filter(function(t) { + return t.id() == $scope.billArgs.billingType })[0]; + if (type.default_price() && !$scope.billArgs.amount) + $scope.billArgs.amount = Number(type.default_price()); + } + }], + resolve : { + // if we don't already have them, fetch the billing types + billingTypes : function() { + return service.fetchBillingTypes(); + }, + + xact : function() { + if (args.xact) return $q.when(args.xact); + if (args.xact_id) return service.fetchXact(args.xact_id); + return $q.when(); + }, + + patron : function() { + return $q.when(args.patron) || egUser.get(args.patron_id); + } + + } + }).result.then( + function(args) { + // send the billing to the server using the arguments + // provided in the billing dialog, then refresh + return service.billPatron(args, args.xact); + } + ); + } + + return service; +}]); + + + +