1 angular.module('egHoldingsMod', ['egCoreMod','egGridMod'])
3 .factory('holdingsSvc',
5 function(egCore , $q) {
7 var service = function() {
9 this.copies = []; // record search results
10 this.index = 0; // search grid index
15 service.prototype.flesh = {
18 acp : ['status','location','circ_lib','parts','age_protect','copy_alerts'],
19 acn : ['prefix','suffix','copies']
23 service.prototype.fetchAgain = function() {
33 // resolved with the last received copy
34 service.prototype.fetch = function(opts) {
37 if (svc.ongoing && svc.p) {
39 console.log('Canceling fetch for org '+ svc.org.id());
40 if (svc.p.reject) svc.p.reject();
47 var empty = opts.empty;
49 if (!rid) return $q.when();
50 if (!org) return $q.when();
58 svc.empty = opts.empty;
63 var org_list = egCore.org.descendants(org.id(), true);
64 console.log('Holdings fetch with: rid='+rid+' org='+org_list+' copy='+copy+' vol='+vol+' empty='+empty);
66 var p = egCore.pcrud.search(
68 {record : rid, owning_lib : org_list, deleted : 'f'},
71 function() { // finished
73 svc.copies = svc.copies.sort(
75 function compare_array (x, y, i) {
76 if (x[i] && y[i]) { // both have values
77 if (x[i] == y[i]) { // need to look deeper
78 return compare_array(x, y, ++i);
81 if (x[i] < y[i]) { // x is first
83 } else if (x[i] > y[i]) { // y is first
87 } else { // no orgs to compare ...
94 var owner_order = compare_array(a.owner_list, b.owner_list, 0);
96 // now compare on CN label
97 if (a.call_number.label < b.call_number.label) return -1;
98 if (a.call_number.label > b.call_number.label) return 1;
101 if (a.copy_number < b.copy_number) return -1;
102 if (a.copy_number > b.copy_number) return 1;
105 if (a.barcode < b.barcode) return -1;
106 if (a.barcode > b.barcode) return 1;
112 // create virtual field for displaying active parts
113 angular.forEach(svc.copies, function (cp) {
114 cp.monograph_parts = '';
115 if (cp.parts && cp.parts.length > 0) {
116 cp.monograph_parts = cp.parts.map(function(obj) { return obj.label; }).join();
120 // create virtual field for copy alert count
121 angular.forEach(svc.copies, function (cp) {
122 cp.copy_alert_count = cp.copy_alerts.length;
125 // create a label using just the unique part of the owner list
128 angular.forEach(svc.copies, function (cp) {
129 if (!prev_owner_list) {
130 cp.owner_label = cp.owner_list.join(' ... ');
132 var current_owner_list = cp.owner_list.slice();
133 while (current_owner_list[1] && prev_owner_list[1] && current_owner_list[0] == prev_owner_list[0]) {
134 current_owner_list.shift();
135 prev_owner_list.shift();
137 cp.owner_label = current_owner_list.join(' ... ');
141 prev_owner_list = cp.owner_list.slice();
144 var new_list = svc.copies;
145 if (!copy || !vol) { // collapse copy rows, supply a count instead
150 var current_blob = { copy_count : 0 };
151 angular.forEach(new_list, function (cp) {
153 prev_key = cp.owner_list.join('') + cp.call_number.label;
154 if (cp.barcode) current_blob.copy_count = 1;
155 current_blob.index = index++;
156 current_blob.id_list = cp.id_list;
157 if (cp.raw) current_blob.raw = cp.raw;
158 current_blob.call_number = cp.call_number;
159 current_blob.owner_list = cp.owner_list;
160 current_blob.owner_label = cp.owner_label;
161 current_blob.owner_id = cp.owner_id;
163 var current_key = cp.owner_list.join('') + cp.call_number.label;
164 if (prev_key == current_key) { // collapse into current_blob
165 current_blob.copy_count++;
166 current_blob.id_list = current_blob.id_list.concat(cp.id_list);
167 current_blob.raw = current_blob.raw.concat(cp.raw);
169 current_blob.barcode = current_blob.copy_count;
170 cp_list.push(current_blob);
171 prev_key = current_key;
172 current_blob = { copy_count : 0 };
173 if (cp.barcode) current_blob.copy_count = 1;
174 current_blob.index = index++;
175 current_blob.id_list = cp.id_list;
176 if (cp.raw) current_blob.raw = cp.raw;
177 current_blob.owner_label = cp.owner_label;
178 current_blob.owner_id = cp.owner_id;
179 current_blob.call_number = cp.call_number;
180 current_blob.owner_list = cp.owner_list;
185 current_blob.barcode = current_blob.copy_count;
186 cp_list.push(current_blob);
189 if (!vol) { // do the same for vol rows
194 current_blob = { copy_count : 0 };
195 angular.forEach(cp_list, function (cp) {
197 prev_key = cp.owner_list.join('');
198 current_blob.index = index++;
199 current_blob.id_list = cp.id_list;
200 if (cp.raw) current_blob.raw = cp.raw;
201 current_blob.cn_count = 1;
202 current_blob.copy_count = cp.copy_count;
203 current_blob.owner_list = cp.owner_list;
204 current_blob.owner_label = cp.owner_label;
205 current_blob.owner_id = cp.owner_id;
207 var current_key = cp.owner_list.join('');
208 if (prev_key == current_key) { // collapse into current_blob
209 current_blob.cn_count++;
210 current_blob.copy_count += cp.copy_count;
211 current_blob.id_list = current_blob.id_list.concat(cp.id_list);
212 if (cp.raw) current_blob.raw = current_blob.raw.concat(cp.raw);
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 prev_key = current_key;
218 current_blob = { copy_count : 0 };
219 current_blob.index = index++;
220 current_blob.id_list = cp.id_list;
221 if (cp.raw) current_blob.raw = cp.raw;
222 current_blob.owner_label = cp.owner_label;
223 current_blob.owner_id = cp.owner_id;
224 current_blob.cn_count = 1;
225 current_blob.copy_count = cp.copy_count;
226 current_blob.owner_list = cp.owner_list;
231 current_blob.barcode = current_blob.copy_count;
232 current_blob.call_number = { label : current_blob.cn_count };
233 cn_list.push(current_blob);
239 svc.copies = new_list;
245 // notify reads the stream of copies, one at a time.
247 if (p.cancel) return;
249 var copies = cn.copies().filter(function(cp){ return cp.deleted() == 'f' });
252 angular.forEach(copies, function (cp) {
256 var owner_id = cn.owning_lib();
257 var owner = egCore.org.get(owner_id);
259 var owner_name_list = [];
260 while (owner.parent_ou()) { // we're going to skip the top of the tree...
261 owner_name_list.unshift(owner.shortname());
262 owner = egCore.org.get(owner.parent_ou());
267 angular.forEach(copies, function (cp) {
268 var flat_cp = egCore.idl.toHash(cp);
269 flat_cp.owner_id = owner_id;
270 flat_cp.owner_list = owner_name_list;
271 flat_cp.id_list = [flat_cp.id];
276 svc.copies = svc.copies.concat(flat);
281 owner_list : owner_name_list,
282 call_number: egCore.idl.toHash(cn),
296 .directive("egVolumeList", function () {
304 templateUrl: './cat/share/t_volume_list',
306 ['$scope','holdingsSvc','egCore','egGridDataProvider','$uibModal',
307 function($scope , holdingsSvc , egCore , egGridDataProvider, $uibModal) {
308 var holdingsSvcInst = new holdingsSvc();
310 $scope.holdingsGridControls = {};
311 $scope.holdingsGridDataProvider = egGridDataProvider.instance({
312 get : function(offset, count) {
313 return this.arrayNotifier(holdingsSvcInst.copies, offset, count);
317 function gatherHoldingsIds () {
320 $scope.holdingsGridControls.allItems(),
321 function (item) { cp_id_list = cp_id_list.concat(item.id_list) }
326 var spawn_volume_editor = function (copies_too) {
329 'open-ils.actor.anon_cache.set_value',
330 null, 'edit-these-copies', {
331 record_id: $scope.recordId,
332 copies: gatherHoldingsIds(),
334 hide_copies : ((copies_too) ? false : true)
336 ).then(function(key) {
339 templateUrl: './cat/share/t_embedded_volcopy',
342 windowClass: 'eg-wide-modal',
344 ['$scope', '$uibModalInstance', function($scope, $uibModalInstance) {
346 egCore.env.basePath + 'cat/volcopy/' + key + '/embedded';
347 $scope.ok = function(args) { $uibModalInstance.close(args) }
348 $scope.cancel = function () { $uibModalInstance.dismiss() }
350 }).result.then(function() {
356 $scope.edit_volumes = function() {
357 spawn_volume_editor(false);
359 $scope.edit_copies = function() {
360 spawn_volume_editor(true);
363 function load_holdings() {
364 holdingsSvcInst.fetch({
365 rid : $scope.recordId,
366 org : egCore.org.root(),
371 $scope.holdingsGridDataProvider.refresh();
374 $scope.$watch('recordId',
375 function(newVal, oldVal) {
376 if (newVal && newVal !== oldVal) {