]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/cat/services/holdings.js
webstaff: break holdingsSvc out of catalog/app.js
[Evergreen.git] / Open-ILS / web / js / ui / default / staff / cat / services / holdings.js
1 angular.module('egHoldingsMod', ['egCoreMod'])
2
3 .factory('holdingsSvc', 
4        ['egCore','$q',
5 function(egCore , $q) {
6
7     var service = {
8         ongoing : false,
9         copies : [], // record search results
10         index : 0, // search grid index
11         org : null,
12         rid : null
13     };
14
15     service.flesh = {   
16         flesh : 2, 
17         flesh_fields : {
18             acp : ['status','location'],
19             acn : ['prefix','suffix','copies']
20         }
21     }
22
23     service.fetchAgain = function() {
24         return service.fetch({
25             rid: service.rid,
26             org: service.org,
27             copy: service.copy,
28             vol: service.vol,
29             empty: service.empty
30         })
31     }
32
33     // resolved with the last received copy
34     service.fetch = function(opts) {
35         if (service.ongoing) {
36             console.log('Skipping fetch, ongoing = true');
37             return $q.when();
38         }
39
40         var rid = opts.rid;
41         var org = opts.org;
42         var copy = opts.copy;
43         var vol = opts.vol;
44         var empty = opts.empty;
45
46         if (!rid) return $q.when();
47         if (!org) return $q.when();
48
49         service.ongoing = true;
50
51         service.rid = rid;
52         service.org = org;
53         service.copy = opts.copy;
54         service.vol = opts.vol;
55         service.empty = opts.empty;
56
57         service.copies = [];
58         service.index = 0;
59
60         var org_list = egCore.org.descendants(org.id(), true);
61         console.log('Holdings fetch with: rid='+rid+' org='+org_list+' copy='+copy+' vol='+vol+' empty='+empty);
62
63         return egCore.pcrud.search(
64             'acn',
65             {record : rid, owning_lib : org_list, deleted : 'f'},
66             service.flesh
67         ).then(
68             function() { // finished
69                 service.copies = service.copies.sort(
70                     function (a, b) {
71                         function compare_array (x, y, i) {
72                             if (x[i] && y[i]) { // both have values
73                                 if (x[i] == y[i]) { // need to look deeper
74                                     return compare_array(x, y, ++i);
75                                 }
76
77                                 if (x[i] < y[i]) { // x is first
78                                     return -1;
79                                 } else if (x[i] > y[i]) { // y is first
80                                     return 1;
81                                 }
82
83                             } else { // no orgs to compare ...
84                                 if (x[i]) return -1;
85                                 if (y[i]) return 1;
86                             }
87                             return 0;
88                         }
89
90                         var owner_order = compare_array(a.owner_list, b.owner_list, 0);
91                         if (!owner_order) {
92                             // now compare on CN label
93                             if (a.call_number.label < b.call_number.label) return -1;
94                             if (a.call_number.label > b.call_number.label) return 1;
95
96                             // try copy number
97                             if (a.copy_number < b.copy_number) return -1;
98                             if (a.copy_number > b.copy_number) return 1;
99
100                             // finally, barcode
101                             if (a.barcode < b.barcode) return -1;
102                             if (a.barcode > b.barcode) return 1;
103                         }
104                         return owner_order;
105                     }
106                 );
107
108                 // create a label using just the unique part of the owner list
109                 var index = 0;
110                 var prev_owner_list;
111                 angular.forEach(service.copies, function (cp) {
112                     if (!prev_owner_list) {
113                         cp.owner_label = cp.owner_list.join(' ... ');
114                     } else {
115                         var current_owner_list = cp.owner_list.slice();
116                         while (current_owner_list[1] && prev_owner_list[1] && current_owner_list[0] == prev_owner_list[0]) {
117                             current_owner_list.shift();
118                             prev_owner_list.shift();
119                         }
120                         cp.owner_label = current_owner_list.join(' ... ');
121                     }
122
123                     cp.index = index++;
124                     prev_owner_list = cp.owner_list.slice();
125                 });
126
127                 var new_list = service.copies;
128                 if (!copy || !vol) { // collapse copy rows, supply a count instead
129
130                     index = 0;
131                     var cp_list = [];
132                     var prev_key;
133                     var current_blob = { copy_count : 0 };
134                     angular.forEach(new_list, function (cp) {
135                         if (!prev_key) {
136                             prev_key = cp.owner_list.join('') + cp.call_number.label;
137                             if (cp.barcode) current_blob.copy_count = 1;
138                             current_blob.index = index++;
139                             current_blob.id_list = cp.id_list;
140                             if (cp.raw) current_blob.raw = cp.raw;
141                             current_blob.call_number = cp.call_number;
142                             current_blob.owner_list = cp.owner_list;
143                             current_blob.owner_label = cp.owner_label;
144                             current_blob.owner_id = cp.owner_id;
145                         } else {
146                             var current_key = cp.owner_list.join('') + cp.call_number.label;
147                             if (prev_key == current_key) { // collapse into current_blob
148                                 current_blob.copy_count++;
149                                 current_blob.id_list = current_blob.id_list.concat(cp.id_list);
150                                 current_blob.raw = current_blob.raw.concat(cp.raw);
151                             } else {
152                                 current_blob.barcode = current_blob.copy_count;
153                                 cp_list.push(current_blob);
154                                 prev_key = current_key;
155                                 current_blob = { copy_count : 0 };
156                                 if (cp.barcode) current_blob.copy_count = 1;
157                                 current_blob.index = index++;
158                                 current_blob.id_list = cp.id_list;
159                                 if (cp.raw) current_blob.raw = cp.raw;
160                                 current_blob.owner_label = cp.owner_label;
161                                 current_blob.owner_id = cp.owner_id;
162                                 current_blob.call_number = cp.call_number;
163                                 current_blob.owner_list = cp.owner_list;
164                             }
165                         }
166                     });
167
168                     current_blob.barcode = current_blob.copy_count;
169                     cp_list.push(current_blob);
170                     new_list = cp_list;
171
172                     if (!vol) { // do the same for vol rows
173
174                         index = 0;
175                         var cn_list = [];
176                         prev_key = '';
177                         current_blob = { copy_count : 0 };
178                         angular.forEach(cp_list, function (cp) {
179                             if (!prev_key) {
180                                 prev_key = cp.owner_list.join('');
181                                 current_blob.index = index++;
182                                 current_blob.id_list = cp.id_list;
183                                 if (cp.raw) current_blob.raw = cp.raw;
184                                 current_blob.cn_count = 1;
185                                 current_blob.copy_count = cp.copy_count;
186                                 current_blob.owner_list = cp.owner_list;
187                                 current_blob.owner_label = cp.owner_label;
188                                 current_blob.owner_id = cp.owner_id;
189                             } else {
190                                 var current_key = cp.owner_list.join('');
191                                 if (prev_key == current_key) { // collapse into current_blob
192                                     current_blob.cn_count++;
193                                     current_blob.copy_count += cp.copy_count;
194                                     current_blob.id_list = current_blob.id_list.concat(cp.id_list);
195                                     if (cp.raw) current_blob.raw = current_blob.raw.concat(cp.raw);
196                                 } else {
197                                     current_blob.barcode = current_blob.copy_count;
198                                     current_blob.call_number = { label : current_blob.cn_count };
199                                     cn_list.push(current_blob);
200                                     prev_key = current_key;
201                                     current_blob = { copy_count : 0 };
202                                     current_blob.index = index++;
203                                     current_blob.id_list = cp.id_list;
204                                     if (cp.raw) current_blob.raw = cp.raw;
205                                     current_blob.owner_label = cp.owner_label;
206                                     current_blob.owner_id = cp.owner_id;
207                                     current_blob.cn_count = 1;
208                                     current_blob.copy_count = cp.copy_count;
209                                     current_blob.owner_list = cp.owner_list;
210                                 }
211                             }
212                         });
213     
214                         current_blob.barcode = current_blob.copy_count;
215                         current_blob.call_number = { label : current_blob.cn_count };
216                         cn_list.push(current_blob);
217                         new_list = cn_list;
218     
219                     }
220                 }
221
222                 service.copies = new_list;
223                 service.ongoing = false;
224             },
225
226             null, // error
227
228             // notify reads the stream of copies, one at a time.
229             function(cn) {
230
231                 var copies = cn.copies().filter(function(cp){ return cp.deleted() == 'f' });
232                 cn.copies([]);
233
234                 angular.forEach(copies, function (cp) {
235                     cp.call_number(cn);
236                 });
237
238                 var owner_id = cn.owning_lib();
239                 var owner = egCore.org.get(owner_id);
240
241                 var owner_name_list = [];
242                 while (owner.parent_ou()) { // we're going to skip the top of the tree...
243                     owner_name_list.unshift(owner.name());
244                     owner = egCore.org.get(owner.parent_ou());
245                 }
246
247                 if (copies[0]) {
248                     var flat = [];
249                     angular.forEach(copies, function (cp) {
250                         var flat_cp = egCore.idl.toHash(cp);
251                         flat_cp.owner_id = owner_id;
252                         flat_cp.owner_list = owner_name_list;
253                         flat_cp.id_list = [flat_cp.id];
254                         flat_cp.raw = [cp];
255                         flat.push(flat_cp);
256                     });
257
258                     service.copies = service.copies.concat(flat);
259                 } else if (empty) {
260                     service.copies.push({
261                         owner_id   : owner_id,
262                         owner_list : owner_name_list,
263                         call_number: egCore.idl.toHash(cn),
264                         raw_call_number: cn
265                     });
266                 }
267
268                 return cn;
269             }
270         );
271     }
272
273     return service;
274 }]);