8c1c406f31d6577d401a980cf366ed4a2e3c2323
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / circ / services / billing.js
1 /**
2  * Shared services for patron billing.
3  * 
4  */
5
6 angular.module('egCoreMod')
7
8 .factory('egBilling', 
9        ['$uibModal','$q','egCore',
10 function($uibModal , $q , egCore) {
11
12     var service = {};
13
14     // fetch a fleshed money.billable_xact
15     service.fetchXact = function(xact_id) {
16         return egCore.pcrud.retrieve('mbt', xact_id, {
17             flesh : 5,
18             flesh_fields : {
19                 mbt : ['summary','circulation','grocery','reservation'],
20                 circ: ['target_copy'],
21                 acp : ['call_number','location','status','age_protect'],
22                 acn : ['record'],
23                 bre : ['simple_record']
24             },
25             select : {bre : ['id']}}, // avoid MARC
26             {authoritative : true}
27         );
28     }
29
30     // apply a patron billing.  If no xact is provided, a grocery xact is
31     // created.
32     service.billPatron = function(args, xact) {
33         // apply a billing to an existing transaction
34         if (xact) return service.createBilling(xact.id, args);
35
36         // create a new grocery xact, then apply a billing
37         return service.createGroceryXact(args)
38         .then(function(xact_id) { 
39             return service.createBilling(xact_id, args);
40         });
41     }
42
43     // create a new grocery xact
44     service.createGroceryXact = function(args) {
45         var groc = new egCore.idl.mg();
46         groc.billing_location(egCore.auth.user().ws_ou());
47         groc.note(args.note);
48         groc.usr(args.patron_id);
49         
50         // create the xact
51         return egCore.net.request(
52             'open-ils.circ',
53             'open-ils.circ.money.grocery.create',
54             egCore.auth.token(), groc
55
56         // create the billing on the new xact
57         ).then(function(xact_id) {
58             if (evt = egCore.evt.parse(xact_id)) 
59                 return alert(evt);
60             return xact_id;
61         });
62     }
63
64     // fetch the org-focused billing types
65     // Cache on egEnv
66     service.fetchBillingTypes = function() {
67         if (egCore.env.cbt) {
68             return $q.when(egCore.env.cbt.list);
69         }
70
71         return egCore.net.request(
72             'open-ils.circ',
73             'open-ils.circ.billing_type.ranged.retrieve.all',
74             egCore.auth.token(),
75             egCore.auth.user().ws_ou()
76         ).then(function(list) {
77             list = list.filter(function(item) {
78                 // first 100 are reserved for system-generated bills
79                 return item.id() > 100;
80             });
81             egCore.env.absorbList(list, 'cbt');
82             return list;
83         });
84     }
85
86     // create a patron billing
87     service.createBilling = function(xact_id, args) {
88         var bill = new egCore.idl.mb();
89         bill.xact(xact_id);
90         bill.amount(args.amount);
91         bill.btype(args.billingType);
92         bill.billing_type(egCore.env.cbt.map[args.billingType].name());
93         bill.note(args.note);
94
95         return egCore.net.request(
96             'open-ils.circ', 
97             'open-ils.circ.money.billing.create',
98             egCore.auth.token(), bill
99
100         // check the billing response
101         ).then(function(bill_id) {
102             if (evt = egCore.evt.parse(bill_id)) {
103                 alert(evt);
104             } else {
105                 return bill_id;
106             }
107         });
108     }
109
110
111     // Show the billing dialog.  
112     // Allows users to select amount, billing type, and note.
113     // args:
114     //   xact OR xact_id : if null, creates a grocery xact
115     //   patron OR patron_id
116     service.showBillDialog = function(args) {
117
118         return $uibModal.open({
119             templateUrl: './circ/share/t_bill_patron_dialog',
120             backdrop: 'static',
121             controller: 
122                    ['$scope','$uibModalInstance','$timeout','billingTypes','xact','patron',
123             function($scope , $uibModalInstance , $timeout , billingTypes , xact , patron) {
124                 console.debug('billing patron ' + patron.id());
125                 $scope.focus = true;
126                 if (xact && xact._isfieldmapper)
127                     xact = egCore.idl.toHash(xact);
128                 $scope.xact = xact;
129                 $scope.patron = patron;
130                 $scope.billingTypes = billingTypes;
131                 $scope.location = egCore.org.get(egCore.auth.user().ws_ou()),
132                 $scope.billArgs = {
133                     billingType : 101, // default to stock Misc. billing type
134                     xact : xact,
135                     patron_id : patron.id()
136                 }
137                 $scope.ok = function(args) { $uibModalInstance.close(args) }
138                 $scope.cancel = function () { $uibModalInstance.dismiss() }
139                 $scope.updateDefaultPrice = function() {
140                     var type = billingTypes.filter(function(t) {
141                         return t.id() == $scope.billArgs.billingType })[0];
142                     if (type.default_price() && !$scope.billArgs.amount) 
143                         $scope.billArgs.amount = Number(type.default_price());
144                 }
145             }],
146             resolve : {
147                 // if we don't already have them, fetch the billing types
148                 billingTypes : function() {
149                     return service.fetchBillingTypes();
150                 }, 
151
152                 xact : function() {
153                     if (args.xact) return $q.when(args.xact);
154                     if (args.xact_id) return service.fetchXact(args.xact_id);
155                     return $q.when();
156                 },
157
158                 patron : function() {
159                     if (args.patron) return $q.when(args.patron);
160                     return  egCore.pcrud.retrieve('au', args.patron_id,
161                         {flesh : 1, flesh_fields : {au : ['card']}});
162                 }
163
164             }
165         }).result.then(
166             function(args) {
167                 // send the billing to the server using the arguments
168                 // provided in the billing dialog, then refresh
169                 return service.billPatron(args, args.xact);
170             }
171         );
172     }
173
174     return service;
175 }]);
176