4 * This provides access to the organizational unit tree and
5 * caches it in browser session storage.
8 * get() - retrieve OU based on ID or aou object
9 * list() - retrieve flattened list of OUs
10 * tree() - retrieve OU as tree
11 * root() - get aou object representing root of the OU tree
12 * ancestors() - get ancestors of supplied OU
13 * descendants() - get descendants of supplied OU
15 * TODO more to document
18 angular.module('egCoreMod')
21 ['$q','egEnv','egAuth','egNet','$injector',
22 function($q, egEnv, egAuth, egNet , $injector) {
26 // org unit settings cache.
27 // This allows the caller to avoid local caches
28 service.cachedSettings = {};
30 service.get = function(node_or_id) {
31 if (typeof node_or_id == 'object')
33 return egEnv.aou.map[node_or_id];
36 service.list = function() {
37 return egEnv.aou.list;
40 service.tree = function() {
41 return egEnv.aou.tree;
45 service.root = function() {
46 return egEnv.aou.list[0];
49 // list of org_unit objects or IDs for ancestors + me
50 service.ancestors = function(node_or_id, as_id) {
51 var node = service.get(node_or_id);
54 while( (node = service.get(node.parent_ou())))
57 return nodes.map(function(n){return Number(n.id())});
61 // tests that a node can have users
62 service.CanHaveUsers = function(node_or_id) {
66 .can_have_users() == 't';
69 // tests that a node can have volumes
70 service.CanHaveVolumes = function(node_or_id) {
74 .can_have_vols() == 't';
77 // list of org_unit objects or IDs for me + descendants
78 service.descendants = function(node_or_id, as_id) {
79 var node = service.get(node_or_id);
84 angular.forEach(n.children(), descend);
88 return nodes.map(function(n){return Number(n.id())});
92 // list of org_unit objects or IDs for ancestors + me + descendants
93 service.fullPath = function(node_or_id, as_id) {
94 var list = service.ancestors(node_or_id).concat(
95 service.descendants(node_or_id).slice(1));
97 return list.map(function(n){return Number(n.id())});
101 var egLovefield = null;
102 // returns a promise, resolved with a hash of setting name =>
103 // setting value for the selected org unit. Org unit defaults to
104 // auth workstation org unit.
105 service.settings = function(names, ou_id) {
107 egLovefield = $injector.get('egLovefield');
111 if (!angular.isArray(names)) names = [names];
114 // for offline, just use whatever we have managed to cache,
115 // even if the value is expired (since we can't refresh it
117 return egLovefield.getSettingsCache(names).then(
120 angular.forEach(settings, function (s) {
121 hash[s.name] = s.value;
123 return $q.when(hash);
125 function() {return $q.when({})} // Not Supported
130 if (!egAuth.user()) return $q.when();
132 ou_id = ou_id || egAuth.user().ws_ou();
133 if (ou_id != egAuth.user().ws_ou()) {
134 // we only cache settings for the current working location;
135 // if we have requested settings for some other org unit,
136 // skip the cache and pull settings directly from the server
137 return service.settingsFromServer(names, ou_id);
140 var deferred = $q.defer();
143 angular.forEach(names, function(name) {
144 if (!angular.isDefined(service.cachedSettings[name]))
145 // we don't have a value for this setting yet
149 // only retrieve uncached values
151 if (names.length == 0)
152 return $q.when(service.cachedSettings);
154 // get settings from offline cache where possible;
155 // otherwise, get settings from server
156 egLovefield.getSettingsCache(names)
157 .then(function(settings) {
159 // populate values from offline cache
160 angular.forEach(settings, function (s) {
161 service.cachedSettings[s.name] = s.value;
164 // check if any requested settings were not in offline cache
166 angular.forEach(names, function(name) {
167 if (!angular.isDefined(service.cachedSettings[name]))
171 if (uncached.length == 0) {
172 // all requested settings were in the offline cache already
173 deferred.resolve(service.cachedSettings);
175 // cache was missing some settings; grab those from the server
176 service.settingsFromServer(uncached, ou_id)
178 deferred.resolve(service.cachedSettings);
182 return deferred.promise;
185 service.settingsFromServer = function(names, ou_id) {
187 egLovefield = $injector.get('egLovefield');
191 if (!angular.isArray(names)) names = [names];
193 var deferred = $q.defer();
194 ou_id = ou_id || egAuth.user().ws_ou();
195 var here = (ou_id == egAuth.user().ws_ou());
199 'open-ils.actor.ou_setting.ancestor_default.batch',
200 ou_id, names, egAuth.token()
201 ).then(function(blob) {
203 angular.forEach(blob, function(val, key) {
204 // val is either null or a structure containing the value
205 settings[key] = val ? val.value : null;
206 if (here) service.cachedSettings[key] = settings[key];
209 return egLovefield.setSettingsCache(settings).then(
211 // resolve with cached settings if 'here', since 'settings'
212 // will only contain settings we had to retrieve
213 deferred.resolve(here ? service.cachedSettings : settings);
216 deferred.resolve(here ? service.cachedSettings : settings);
220 return deferred.promise;