]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/serial/sdist_editor.js
Merge branch 'master' of git://git.evergreen-ils.org/Evergreen into ttopac
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / serial / sdist_editor.js
1 dump('entering serial/sdist_editor.js\n');
2 // vim:noet:sw=4:ts=4:
3
4 JSAN.use('serial.editor_base');
5
6 if (typeof serial == 'undefined') serial = {};
7 serial.sdist_editor = function (params) {
8     try {
9         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
10         JSAN.use('util.error'); this.error = new util.error();
11         JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
12         JSAN.use('util.network'); this.network = new util.network();
13     } catch(E) {
14         dump('serial/sdist_editor: ' + E + '\n');
15     }
16
17     /* This keeps track of what fields have been edited for styling purposes */
18     this.changed = {};
19
20     /* This holds the original values for prepopulating the field editors */
21     this.editor_values = {};
22
23     // setup sre arrays
24     this.sre_id_map = {};
25     this.sres_ou_map = {};
26     this.build_sre_maps();
27
28     // update sre maps on demand
29     var obj = this;
30     window.parent.addEventListener("MFHDChange", function() {obj.build_sre_maps()}, false);
31 };
32
33 serial.sdist_editor.prototype = {
34     // we could do this with non-standard '__proto__' property instead
35     'editor_base_init' : serial.editor_base.editor_base_init,
36     'editor_base_apply' : serial.editor_base.editor_base_apply,
37     'editor_base_save' : serial.editor_base.editor_base_save,
38
39     'fm_type' : 'sdist',
40     'fm_type_plural' : 'sdists',
41     'can_have_notes' : true,
42
43     'init' : function (params) {
44         var obj = this;
45
46         params.retrieve_function = 'FM_SDIST_FLESHED_BATCH_RETRIEVE.authoritative';
47
48         obj.editor_base_init(params);
49
50         obj.multi_org_edit = false;
51         var org_unit = obj.sdists[0].holding_lib();
52         for (var i = 1; i < obj.sdists.length; i++) {
53             if (obj.sdists[i].holding_lib() != org_unit) {
54                 obj.multi_org_edit = true;
55                 break;
56             }
57         }        
58
59         /* Do it */
60         obj.summarize( obj.sdists );
61         obj.render();
62     },
63
64     /******************************************************************************************************/
65     /* Restore backup copies */
66
67     'reset' :  serial.editor_base.editor_base_reset,
68
69     /******************************************************************************************************/
70     /* Apply a value to a specific field on all the copies being edited */
71
72     'apply' : function(field,value) {
73         var obj = this;
74
75         var field_name_list = ['bind_call_number','receive_call_number','bind_unit_template','receive_unit_template','record_entry'];
76
77         // null out call number if the holding lib is changed
78         obj.holding_lib_changed = (field == 'holding_lib');
79         var loop_func = function(sdist) {
80             if (obj.holding_lib_changed) {
81                 for (var i = 0; i < field_name_list.length; i++) {
82                     sdist[field_name_list[i]](null);
83                     obj.changed[fieldmapper.IDL.fmclasses.sdist.field_map[field_name_list[i]].label] = true;
84                 }
85             }
86         }
87
88         // check for blank drop-down submits
89         for (var i = 0; i < field_name_list.length; i++) {
90             if (field == field_name_list[i] && value === '') {
91                 value = null;
92                 break;
93             }
94         }
95         obj.editor_base_apply(field, value, loop_func);
96         obj.holding_lib_changed = false;
97     },
98
99     /******************************************************************************************************/
100
101     'render_call_number' : function(cn) {
102         var obj = this;
103         if (cn == null) { // true for both 'null' AND undefined
104             return '';
105         } else if (typeof cn != 'object') {
106             return obj.acn_label_map[cn];
107         } else {
108             return cn.label()
109         }
110     },
111
112     'render_unit_template' : function(ut) {
113         var obj = this;
114         if (ut == null) { // true for both 'null' AND undefined
115             return '';
116         } else if (typeof ut != 'object') {
117             return obj.act_name_map[ut];
118         } else {
119             return ut.name()
120         }
121     },
122
123     'render_record_entry' : function(sre) {
124         var obj = this;
125         var sre_id;
126         if (sre == null) { // true for both 'null' AND undefined
127             return '';
128         } else if (typeof sre != 'object') {
129             sre_id = sre;
130         } else {
131             sre_id = sre.id();
132         }
133         return obj.sre_id_map[sre_id].label;
134     },
135
136     'init_panes' : function () {
137         var obj = this;
138         obj.panes_and_field_names = {
139
140         /* These get shown in the left panel */
141         '_editor_left_pane' :
142         [
143             [
144                 'id',
145                 { 
146                     //input: 'c = function(v){ obj.apply("distribution",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
147
148                 }
149             ],
150             [
151                 'label',
152                 { 
153                     input: 'c = function(v){ obj.apply("label",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.setAttribute("value",obj.editor_values.label); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
154                     value_key: 'label',
155                     required: true
156                 }
157             ],
158             [
159                 'summary_method',
160                 {
161                     render: 'obj.summary_methods[fm.summary_method()]',
162                     input: 'c = function(v){ obj.apply("summary_method",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_object_to_list( obj.summary_methods, function(obj,i) { return [ obj[i], i ]; })); x.setAttribute("value",obj.editor_values.summary_method); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
163                     value_key: 'summary_method',
164                     dropdown_key: 'fm.summary_method() == null ? null : fm.summary_method()'
165                 }
166             ],
167             [
168                 'unit_label_prefix',
169                 {
170                     input: 'c = function(v){ obj.apply("unit_label_prefix",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.setAttribute("value",obj.editor_values.unit_label_prefix); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
171                     value_key: 'unit_label_prefix'
172                 }
173             ],
174             [
175                 'unit_label_suffix',
176                 { 
177                     input: 'c = function(v){ obj.apply("unit_label_suffix",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.setAttribute("value",obj.editor_values.unit_label_suffix); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
178                     value_key: 'unit_label_suffix'
179                 }
180             ],
181         ],
182         /* These get shown in the right panel */
183             '_editor_right_pane' :
184         [
185             [
186                 'holding_lib',
187                 {
188                     render: 'typeof fm.holding_lib() == "object" ? fm.holding_lib().shortname() : obj.data.hash.aou[ fm.holding_lib() ].shortname()',
189                     input: 'c = function(v){ if (obj.editor_values.holding_lib != v) obj.apply("holding_lib",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( obj.data.list.aou, function(myobj) { var sname = myobj.shortname(); for (i = sname.length; i < 20; i++) sname += " "; return [ myobj.name() ? sname + " " + myobj.name() : myobj.shortname(), myobj.id(), ( ! get_bool( obj.data.hash.aout[ myobj.ou_type() ].can_have_vols() ) ), ( obj.data.hash.aout[ myobj.ou_type() ].depth() * 2), ]; }), obj.data.list.au[0].ws_ou()); x.setAttribute("value",obj.editor_values.holding_lib); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
190                     value_key: 'holding_lib',
191                     dropdown_key: 'typeof fm.holding_lib() == "object" ? fm.holding_lib().id() : fm.holding_lib()',
192                 }
193             ],
194         ],
195         /* These get shown in the right 'library-specific-options' panel */
196         '_editor_lso_pane' :
197         [
198             [
199                 'record_entry',
200                 {
201                     render: 'obj.render_record_entry(fm.record_entry())',
202                     input: 'if(!obj.multi_org_edit) { c = function(v){ obj.apply("record_entry",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( obj.get_sre_details_list(), function(obj) { return [ obj.label, obj.id ]; }).sort()); x.setAttribute("value",obj.editor_values.record_entry); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false); }',
203                     value_key: 'record_entry',
204                     dropdown_key: 'fm.record_entry() == null ? null : typeof fm.record_entry() == "object" ? fm.record_entry().id() : fm.record_entry()'
205                 }
206             ],
207             [
208                 'receive_call_number',
209                 {
210                     render: 'obj.render_call_number(fm.receive_call_number())',
211                     input: 'if(!obj.multi_org_edit) { c = function(v){ obj.apply("receive_call_number",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( obj.get_acn_list(), function(obj) { return [ obj.label(), obj.id() ]; }).sort()); x.setAttribute("value",obj.editor_values.receive_call_number); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false); }',
212                     value_key: 'receive_call_number',
213                     dropdown_key: 'fm.receive_call_number() == null ? null : typeof fm.receive_call_number() == "object" ? fm.receive_call_number().id() : fm.receive_call_number()'
214                 }
215             ],
216             [
217                 'bind_call_number',
218                 {
219                     render: 'obj.render_call_number(fm.bind_call_number())',
220                     input: 'if(!obj.multi_org_edit) { c = function(v){ obj.apply("bind_call_number",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( obj.get_acn_list(), function(obj) { return [ obj.label(), obj.id() ]; }).sort()); x.setAttribute("value",obj.editor_values.bind_call_number); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false); }',
221                     value_key: 'bind_call_number',
222                     dropdown_key: 'fm.bind_call_number() == null ? null : typeof fm.bind_call_number() == "object" ? fm.bind_call_number().id() : fm.bind_call_number()'
223                 }
224             ],
225             [
226                 'receive_unit_template',
227                 {
228                     render: 'obj.render_unit_template(fm.receive_unit_template())',
229                     input: 'if(!obj.multi_org_edit) { c = function(v){ obj.apply("receive_unit_template",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( obj.get_act_list(), function(obj) { return [ obj.name(), obj.id() ]; }).sort()); x.setAttribute("value",obj.editor_values.receive_unit_template); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false); }',
230                     value_key: 'receive_unit_template',
231                     dropdown_key: 'fm.receive_unit_template() == null ? null : typeof fm.receive_unit_template() == "object" ? fm.receive_unit_template().id() : fm.receive_unit_template()'
232                 }
233             ],
234             [
235                 'bind_unit_template',
236                 {
237                     render: 'obj.render_unit_template(fm.bind_unit_template())',
238                     input: 'if(!obj.multi_org_edit) { c = function(v){ obj.apply("bind_unit_template",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( obj.get_act_list(), function(obj) { return [ obj.name(), obj.id() ]; }).sort()); x.setAttribute("value",obj.editor_values.bind_unit_template); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false); }',
239                     value_key: 'bind_unit_template',
240                     dropdown_key: 'fm.bind_unit_template() == null ? null : typeof fm.bind_unit_template() == "object" ? fm.bind_unit_template().id() : fm.bind_unit_template()'
241                 }
242             ],
243         ],
244
245         };
246         for (i in obj.panes_and_field_names) {
247             obj.panes_and_field_names[obj.xul_id_prefix + i] = obj.panes_and_field_names[i];
248             delete obj.panes_and_field_names[i];
249         }
250     },
251
252     /******************************************************************************************************/
253     /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
254
255     'summarize' :  serial.editor_base.editor_base_summarize,
256
257     /******************************************************************************************************/
258     /* Display the summarized data and inputs for editing */
259
260     'render' :  serial.editor_base.editor_base_render,
261
262     /******************************************************************************************************/
263     /* This actually draws the change button and input widget for a given field */
264     'render_input' : serial.editor_base.editor_base_render_input,
265
266     /******************************************************************************************************/
267     /* save the distributions */
268
269     'save' : function() {
270         var obj = this;
271         obj.editor_base_save('open-ils.serial.distribution.fleshed.batch.update');
272     },
273
274     /******************************************************************************************************/
275     /* spawn notes interface */
276
277     'notes' : function() {
278         var obj = this;
279         JSAN.use('util.window'); var win = new util.window();
280         win.open(
281             urls.XUL_SERIAL_NOTES, 
282             //+ '?copy_id=' + window.escape(obj.sdists[0].id()),
283             $('serialStrings').getString('staff.serial.sdist_editor.notes'),'chrome,resizable,modal',
284             { 'object_id' : obj.sdists[0].id(), 'function_type' : 'SDISTN', 'object_type' : 'distribution', 'constructor' : sdistn }
285         );
286     },
287
288     /******************************************************************************************************/
289     'save_attributes' : serial.editor_base.editor_base_save_attributes,
290
291     /******************************************************************************************************/
292     /* Build maps of sre details for both display and selection purposes */
293
294     'build_sre_maps' : function() {
295         var obj = this;
296         try {
297             obj.sre_id_map = {};
298             obj.sres_ou_map = {};
299             var parent_g = window.parent.g;
300             if (parent_g.mfhd) {
301                 var mfhd_details = parent_g.mfhd.details;
302                 for (var i = 0; i < mfhd_details.length; i++) {
303                     var mfhd_detail = {};
304                     for (j in mfhd_details[i]) {
305                         mfhd_detail[j] = mfhd_details[i][j];
306                     }
307                     mfhd_detail.label = mfhd_detail.label + ' (' + (mfhd_detail.entryNum + 1) + ')';
308                     var sre_id = mfhd_detail.id;
309                     var org_unit_id = mfhd_detail.owning_lib;
310                     obj.sre_id_map[sre_id] = mfhd_detail;
311                     if (!obj.sres_ou_map[org_unit_id]) {
312                         obj.sres_ou_map[org_unit_id] = [];
313                     }
314                     obj.sres_ou_map[org_unit_id].push(mfhd_detail);
315                 }
316             }
317         } catch(E) {
318             obj.error.standard_unexpected_error_alert('build_sre_maps',E);
319         }
320     },
321
322     /******************************************************************************************************/
323     /* This returns a list of sre details appropriate for the distributions being edited */
324
325     'get_sre_details_list' : function() {
326         var obj = this;
327         try {
328             /* we only show this list if dealing with one org_unit, default to first sdist*/
329             var lib_id = typeof obj.sdists[0].holding_lib() == 'object' ? obj.sdists[0].holding_lib().id() : obj.sdists[0].holding_lib();
330             var sre_details_list = obj.sres_ou_map[lib_id];
331             if (sre_details_list == null) {
332                 return [{'label' : $('serialStrings').getString('staff.serial.sdist_editor.no_mfhd_available.label'), 'id' : ''}];
333             } else {
334                 return sre_details_list;
335             }
336         } catch(E) {
337             obj.error.standard_unexpected_error_alert('get_sre_details_list',E);
338             return [];
339         }
340     },
341
342     /******************************************************************************************************/
343     /* This returns a list of acn's appropriate for the distributions being edited */
344
345     'get_acn_list' : function() {
346         var obj = this;
347         try {
348             var lib_id = typeof obj.sdists[0].holding_lib() == 'object' ? obj.sdists[0].holding_lib().id() : obj.sdists[0].holding_lib();
349
350             if (!obj.acn_lists) {
351                 obj.acn_lists = {};
352             }
353
354             // return cached version if we have it
355             // TODO: clear cache on holding_lib change? (cannot remember how to reproduce this bug)
356             if (obj.acn_lists[lib_id]) {
357                 return obj.acn_lists[lib_id];
358             }
359
360             var acn_list = obj.network.request(
361                 'open-ils.pcrud',
362                 'open-ils.pcrud.search.acn',
363                 [ ses(), {"record" : obj.docid, "owning_lib" : lib_id, "deleted" : 'f' }, {"order_by" : {"acn" : "label"} } ]
364             );
365
366             if (!acn_list) {
367                 return [];
368             } else if (!acn_list.length) {
369                 acn_list = [acn_list];
370             }
371
372             // build label map
373             obj.acn_label_map = {};
374             for (i = 0; i < acn_list.length; i++) {
375                 obj.acn_label_map[acn_list[i].id()] = acn_list[i].label();
376             }
377
378             // cache the list
379             obj.acn_lists[lib_id] = acn_list;
380             return acn_list;
381
382         } catch(E) {
383             obj.error.standard_unexpected_error_alert('get_acn_list',E);
384             return [];
385         }
386     },
387
388     /******************************************************************************************************/
389     /* This returns a list of asset copy templates appropriate for the distributions being edited */
390
391     'get_act_list' : function() {
392         var obj = this;
393         try {
394             /* we only show this list if dealing with one org_unit, default to first sdist*/
395             var lib_id = typeof obj.sdists[0].holding_lib() == 'object' ? obj.sdists[0].holding_lib().id() : obj.sdists[0].holding_lib();
396
397             if (!obj.act_lists) {
398                 obj.act_lists = {};
399             }
400
401             // return cached version if we have it
402             if (obj.act_lists[lib_id]) {
403                 return obj.act_lists[lib_id];
404             }
405             
406             var act_list = obj.network.request(
407                 'open-ils.pcrud',
408                 'open-ils.pcrud.search.act',
409                 [ ses(), {"owning_lib" : lib_id }, {"order_by" : {"act" : "name"} } ]
410             );
411
412             if (act_list == null) {
413                 return [];
414             } else if (!act_list.length) {
415                 act_list = [act_list];
416             }
417
418             // build name map
419             obj.act_name_map = {};
420             for (i = 0; i < act_list.length; i++) {
421                 obj.act_name_map[act_list[i].id()] = act_list[i].name();
422             }
423
424             // cache the list
425             obj.act_lists[lib_id] = act_list;
426             return act_list;
427         } catch(E) {
428             obj.error.standard_unexpected_error_alert('get_act_list',E);
429             return [];
430         }
431     },
432     /******************************************************************************************************/
433     'summary_methods' : {
434         "add_to_sre" : $('serialStrings').getString('staff.serial.sdist_editor.add_to_sre.label'),
435         "merge_with_sre" : $('serialStrings').getString('staff.serial.sdist_editor.merge_with_sre.label'),
436         "use_sre_only" : $('serialStrings').getString('staff.serial.sdist_editor.use_sre_only.label'),
437         "use_sdist_only" : $('serialStrings').getString('staff.serial.sdist_editor.use_sdist_only.label'),
438     }
439 };
440
441 dump('exiting serial/sdist_editor.js\n');