MARC strip fields for Acquisitions
[working/Evergreen.git] / Open-ILS / web / js / ui / default / acq / common / vlagent.js
1 dojo.require('openils.widget.AutoFieldWidget');
2 dojo.require('openils.PermaCrud');
3 dojo.require('openils.XUL');
4 dojo.require('dojox.form.CheckedMultiSelect');
5
6 var xulStorage = openils.XUL.localStorage();
7 var storekey = 'eg.acq.upload.';
8 var osetkey = 'acq.upload.default.';
9 var persistOrgSettings;
10
11 // map local dijit keys/names to their org setting counterparts
12 var setNameMap = {
13     match_set : 'vandelay.match_set',
14     merge_profile : 'vandelay.merge_profile',
15     create_assets : 'vandelay.load_item_for_imported',
16     match_quality_ratio : 'vandelay.quality_ratio',
17     auto_overlay_1match : 'vandelay.merge_on_single',
18     import_no_match : 'vandelay.import_non_matching',
19     fall_through_merge_profile : 'vandelay.low_quality_fall_thru_profile',
20     auto_overlay_exact : 'vandelay.merge_on_exact',
21     auto_overlay_best_match : 'vandelay.merge_on_best'
22 }
23
24 // per-UI setting to change this?
25 // if true, set default widget values from org settings
26 // (when defined) regardless of any locally persisted value
27 var ouSettingTrumpsPersist = true;
28
29 function VLAgent(args) {
30     args = args || {};
31     for (var key in args) { 
32         this[key] = args[key]; 
33     }
34
35     this.widgets = [  
36         {key : 'import_no_match'},
37         {key : 'auto_overlay_exact'},
38         {key : 'auto_overlay_1match'},
39         {key : 'auto_overlay_best_match'},
40         {key : 'match_quality_ratio'},
41         {key : 'queue_name'},
42         {key : 'create_assets'},
43         {key : 'match_set', cls : 'vms'},
44         {key : 'bib_source', cls : 'cbs'},
45         {key : 'merge_profile', cls : 'vmp'},
46         {key : 'fall_through_merge_profile', cls : 'vmp'},
47         {key : 'existing_queue', cls : 'vbq'},
48         {key : 'strip_field_groups', cls : 'vibtg'}
49     ];
50
51     this.loaded = false;
52
53     this.init = function(oncomplete) {
54         var self = this;
55
56         // load org unit persist setting values
57         fieldmapper.standardRequest(
58             ['open-ils.actor','open-ils.actor.ou_setting.ancestor_default.batch'],
59             {   async : true,
60                 params : [
61                     new openils.User().user.ws_ou(),
62                     [   osetkey + 'create_po',
63                         osetkey + 'activate_po',
64                         osetkey + 'provider',
65                         osetkey + 'vandelay.match_set',
66                         osetkey + 'vandelay.merge_profile',
67                         osetkey + 'vandelay.import_non_matching',
68                         osetkey + 'vandelay.merge_on_exact',
69                         osetkey + 'vandelay.merge_on_best',
70                         osetkey + 'vandelay.merge_on_single',
71                         osetkey + 'vandelay.quality_ratio',
72                         osetkey + 'vandelay.low_quality_fall_thru_profile',
73                         osetkey + 'vandelay.load_item_for_imported'
74                     ]
75                 ],
76                 oncomplete : function(r) {
77                     persistOrgSettings = openils.Util.readResponse(r);
78                     self.init2();
79                     if (oncomplete) 
80                         oncomplete();
81                 }
82             }
83         );
84     };
85
86     this.init2 = function() {
87         var self = this;
88         // fetch the strip field groups, then continue init-ing
89
90         var owner = fieldmapper.aou.orgNodeTrail(
91             fieldmapper.aou.findOrgUnit(new openils.User().user.ws_ou()));
92
93         new openils.PermaCrud().search('vibtg',
94             {   always_apply : 'f',
95                 owner: owner.map(function(org) { return org.id(); })
96             }, 
97             {   order_by : {vibtg : ['label']},
98                 async: true,
99                 oncomplete: function(r) {
100                     var trashGroups = openils.Util.readResponse(r);
101                     var sel = dijit.byId('acq_vl:strip_field_groups');
102
103                     var widg = self.widgets.filter(function(w) {
104                         return w.key == 'strip_field_groups'})[0];
105                     widg.dijit = sel;
106
107                     if (trashGroups.length == 0) {
108                         openils.Util.hide('vl-trash-groups-row');
109
110                     } else {
111
112                         dojo.forEach(trashGroups, function(grp) {
113                             var sn = fieldmapper.aou.findOrgUnit(
114                                 grp.owner()).shortname();
115                             var opt = {
116                                 label : grp.label() + ' (' + sn + ')',
117                                 value : grp.id()
118                             };
119                             sel.addOption(opt);
120                         });
121
122                         self.readCachedValue(sel, 'strip_field_groups');
123                     }
124
125                     self.init3();
126                 }
127             }
128         );
129
130     },
131
132     this.init3 = function() {
133         var self = this;
134
135         dojo.forEach(this.widgets,
136             function(widg) {
137                 var key = widg.key;
138
139                 // strip-fields widget built above
140                 if (key == 'strip_field_groups') return;
141
142                 if (widg.cls) { // selectors
143
144                     new openils.widget.AutoFieldWidget({
145                         fmClass : widg.cls,
146                         selfReference : true,
147                         orgLimitPerms : [self.limitPerm || 'CREATE_PURCHASE_ORDER'],
148                         parentNode : dojo.byId('acq_vl:' + key),
149                         searchFilter : (widg.cls == 'vbq') ? {queue_type : 'acq'} : null,
150                         useWriteStore :  (widg.cls == 'vbq')
151                     }).build(function(dij) { 
152                         widg.dijit = dij; 
153                         if (!key.match(/queue/))
154                             self.readCachedValue(dij, key);
155                         self.attachOnChange(widg);
156                     }); 
157
158                 } else { // bools
159                     widg.dijit = dijit.byId('acq_vl:' + key);
160                     if (!widg.dijit) return; // some fields optional
161                     if (!key.match(/queue/))
162                         self.readCachedValue(widg.dijit, key);
163                     self.attachOnChange(widg);
164                 }
165             }
166         );
167         
168         // loaded != all widgets are done rendering,
169         // only that init() has been called.
170         this.loaded = true;
171     }
172
173     this.attachOnChange = function(widg) {
174         var self = this;
175         var qInputChange;
176
177         var qSelChange = function(val) {
178             // user selected a queue from the selector;  clear the text input 
179             // and set the item import profile already defined for the queue
180
181             var qInput = self.getDijit('queue_name');
182             var matchSetSelector = self.getDijit('match_set');
183             var qSelector = self.getDijit('existing_queue');
184
185             if(val) {
186                 qSelector.store.fetch({
187                     query : {id : val+''},
188                     onComplete : function(items) {
189                         matchSetSelector.attr('value', items[0].match_set[0] || '');
190                         matchSetSelector.attr('disabled', true);
191                     }
192                 });
193             } else {
194                 matchSetSelector.attr('value', '');
195                 matchSetSelector.attr('disabled', false);
196             }
197
198             // detach and reattach to avoid onchange firing while when we clear
199             dojo.disconnect(qInput._onchange);
200             qInput.attr('value', '');
201             qInput._onchange = dojo.connect(qInput, 'onChange', qInputChange);
202         }
203
204         qInputChange = function(val) {
205
206             var qSelector = self.getDijit('existing_queue');
207             var matchSetSelector = self.getDijit('match_set');
208             var foundMatch = false;
209
210             if (val) {
211
212                 // if the user entered the name of an existing queue, update the 
213                 // queue selector to match the value (and clear the text input 
214                 // via qselector onchange)
215                 qSelector.store.fetch({
216                     query:{name:val},
217                     onComplete:function(items) {
218                         if(items.length == 0) return;
219                         var item = items[0];
220                         qSelector.attr('value', item.id);
221                         foundMatch = true;
222                     }
223                 });
224             }
225
226             if (!foundMatch) {
227                 self.getDijit('match_set').attr('disabled', false);
228                 dojo.disconnect(qSelector._onchange);
229                 qSelector.attr('value', '');
230                 qSelector._onchange = dojo.connect(qSelector, 'onChange', qSelChange);
231             }
232         }
233
234         if (widg.key == 'existing_queue') {
235             var qSelector = self.getDijit('existing_queue');
236             qSelector._onchange = dojo.connect(qSelector, 'onChange', qSelChange);
237         } else if(widg.key == 'queue_name') {
238             var qInput = self.getDijit('queue_name');
239             qInput._onchange = dojo.connect(qInput, 'onChange', qInputChange);
240         }
241     }
242
243     this.getDijit = function(key) {
244         return this.widgets.filter(function(w) {return (w.key == key)})[0].dijit;
245     }
246
247     this.values = function() {
248         var self = this;
249         var values = {};
250         dojo.forEach(this.widgets,
251             function(widg) {
252                 if (widg.dijit) {
253                     values[widg.key] = widg.dijit.attr('value');
254                     if (!widg.key.match(/queue/))
255                         self.writeCachedValue(widg.dijit, widg.key);
256                 }
257             }
258         );
259         return values;
260     }
261
262     this.handleResponse = function(resp, oncomplete) {
263         if(!resp) return;
264         var res = {}
265
266         console.log('vandelay import returned : ' + js2JSON(resp));
267
268         // update the display counts
269         dojo.byId('acq_vl:li-processed').innerHTML = resp.li;
270         dojo.byId('acq_vl:vqbr-processed').innerHTML = resp.vqbr;
271         dojo.byId('acq_vl:bibs-processed').innerHTML = resp.bibs;
272         dojo.byId('acq_vl:lid-processed').innerHTML = resp.lid;
273         dojo.byId('acq_vl:debits-processed').innerHTML = resp.debits_accrued;
274         dojo.byId('acq_vl:copies-processed').innerHTML = resp.copies;
275
276         if (resp.complete) {
277
278             if(resp.picklist) {
279                 res.picklist_url = oilsBasePath + '/acq/picklist/view/' + resp.picklist.id();
280             } 
281
282             if(resp.purchase_order) {
283                 res.po_url = oilsBasePath + '/acq/po/view/' + resp.purchase_order.id();
284             }
285
286             if (resp.queue) {
287                 var newQid = resp.queue.id();
288                 res.queue_url = oilsBasePath + '/vandelay/vandelay?qtype=bib&qid=' + newQid;
289
290                 var qInput = this.getDijit('queue_name');
291
292                 if (newQName = qInput.attr('value')) {
293                     // user created a new queue.  Fetch the new queue object,
294                     // replace the ReadStore with a WriteStore and insert.
295                     qInput.attr('value', '');
296                     var qSelector = this.getDijit('existing_queue');
297                     var newQ = new openils.PermaCrud().retrieve('vbq', newQid);
298                     qSelector.store.newItem(newQ.toStoreItem());
299                     qSelector.attr('value', newQid);
300                 }
301             }
302
303             if (oncomplete) 
304                 oncomplete(resp, res);
305
306             return res;
307         }
308
309         return false; // not yet complete
310     };
311
312     this.readCachedValue = function(dij, key, ousOnly) {
313         var val;
314         var setname = osetkey + (setNameMap[key] ? setNameMap[key] : key);
315
316         if (ouSettingTrumpsPersist && persistOrgSettings[setname]) {
317             val = persistOrgSettings[setname].value;
318         } else {
319             if (!ousOnly)
320                 val = xulStorage.getItem(storekey + key);
321             if (!val && persistOrgSettings[setname])
322                 val = persistOrgSettings[setname].value;
323         }
324
325         if (val) dij.attr('value', val);
326         return val;
327     };
328
329     this.writeCachedValue = function(dij, key) {
330         var setname = osetkey + (setNameMap[key] ? setNameMap[key] : key);
331
332         if (ouSettingTrumpsPersist && persistOrgSettings[setname]) {
333             // don't muck up localStorage if we're using org settings
334             xulStorage.removeItem(storekey + key);
335
336         } else {
337             var val = dij.attr('value');
338
339             if (val === null || val === false || val == '') {
340                 xulStorage.removeItem(storekey + key);
341             } else {
342                 xulStorage.setItem(storekey + key, val);
343             }
344         }
345     };
346 }