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