Remove broken error message
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / admin / transit_list.js
1 dump('entering admin.transit_list.js\n');
2
3 if (typeof admin == 'undefined') admin = {};
4 admin.transit_list = function (params) {
5
6     JSAN.use('util.error'); this.error = new util.error();
7     JSAN.use('util.network'); this.network = new util.network(); JSAN.use('util.file');
8     JSAN.use('util.date'); JSAN.use('util.widgets'); JSAN.use('util.fm_utils'); JSAN.use('util.functional');
9     JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
10 }
11
12 admin.transit_list.prototype = {
13
14     'init' : function( params ) {
15
16         var obj = this;
17
18         var x = document.getElementById('libmenu_placeholder');
19         util.widgets.remove_children( x );
20
21         var file; var list_data; var ml; 
22
23         file = new util.file('offline_ou_list'); 
24         if (file._file.exists()) {
25             list_data = file.get_object(); file.close();
26             ml = util.widgets.make_menulist( list_data[0], list_data[1] );
27             ml.setAttribute('id','libmenu'); document.getElementById('libmenu_placeholder').appendChild(ml);
28             ml.addEventListener(
29                 'command',
30                 function(ev) {
31                     var file = new util.file('transit_list_prefs.'+obj.data.server_unadorned);
32                     util.widgets.save_attributes(file, { 'libmenu' : [ 'value' ] });
33                 },
34                 false
35             );
36         } else {
37             throw(document.getElementById('adminStrings').getString('staff.admin.transit_list.missing_list') + '\n');
38         }
39
40         file = new util.file('transit_list_prefs.'+obj.data.server_unadorned);
41         util.widgets.load_attributes(file);
42         ml.value = ml.getAttribute('value');
43         if (! ml.value) {
44             ml.value = obj.data.list.au[0].ws_ou();
45             ml.setAttribute('value',ml.value);
46         }
47
48         x.appendChild( ml );
49
50         obj.list_init();
51         obj.controller_init();
52         //obj.kick_off();
53
54     },
55
56     'sdate' : null,
57     'edate' : null,
58
59     'handle_date' : function(value,end_of_day) {
60         try {
61             var _date = null;
62
63             /* The Beginning */
64             if (value.match(/The Beginning/)) {
65                 _date = new Date(); _date.setTime( 0 );
66             }
67
68             /* Today */
69             if (value.match(/^Today$/i)) {
70                 _date = new Date(); _date = util.date.buildDate( _date.getFullYear(), _date.getMonth()+1, _date.getDate(), 0, 0, 0); // morning
71             }
72
73             /* handle YYYY-MM-DD */
74             var _string = value.match(/(\d\d\d\d)[\-\/](\d\d?)[\-\/](\d\d?)/);
75             if (_string) {
76                 if (util.date.check('YYYY-MM-DD',_string[1]+'-'+_string[2]+'-'+_string[3])) {
77                     _date = util.date.buildDate( _string[1], _string[2], _string[3], 0, 0, 0);
78                 } else {
79                     alert(document.getElementById('adminStrings').getFormattedString('staff.admin.transit_list.invalid_date', [_string])); 
80                     _date = new Date(); _date = util.date.buildDate( _date.getFullYear(), _date.getMonth()+1, _date.getDate(), 0, 0, 0); // morning
81                 }
82             }
83
84             /* handle relative dates */
85             var interval = value.match(/Today \- (.+)/);
86             if (interval) {
87                 _date = new Date(); _date = util.date.buildDate( _date.getFullYear(), _date.getMonth()+1, _date.getDate(), 0, 0, 0); // morning
88                 _date.setTime( _date.getTime() - util.date.interval_to_seconds(interval[1])*1000 );
89             }
90
91             if (! util.date.check('YYYY-MM-DD',util.date.formatted_date(_date,"%F")) ) { 
92                 alert(document.getElementById('adminStrings').getFormattedString('staff.admin.transit_list.invalid_date', [_date, util.date.formatted_date(_date,"%F")])); 
93                 _date = new Date(); _date = util.date.buildDate( _date.getFullYear(), _date.getMonth()+1, _date.getDate(), 0, 0, 0); // morning
94             }
95                 
96             if (end_of_day) { // This just handles calendar days.. if we wanted to support (Today-1 month,Today-1 month), I'll need a better library, or a query to postgres
97                 _date.setTime( _date.getTime() + util.date.interval_to_seconds('1 day')*1000 - util.date.interval_to_seconds('1 second')*1000 );
98             }
99
100             return util.date.formatted_date(_date,'%{iso8601}');
101         } catch(E) {
102             try { obj.error.standard_unexpected_error_alert(document.getElementById('adminStrings').getString('staff.admin.transit_list.date_processing.error'),E); } catch(F) { alert(E); }
103             _date = new Date(); _date = util.date.buildDate( _date.getFullYear(), _date.getMonth()+1, _date.getDate(), 0, 0, 0); // morning
104             return util.date.formatted_date(_date,'%{iso8601}');
105         }
106     },
107
108     'kick_off' : function() {
109         var obj = this;
110         try {
111             obj.list.clear();
112             obj.sdate = obj.handle_date( document.getElementById('sdate').value, false );
113             obj.edate = obj.handle_date( document.getElementById('edate').value, true );
114             var sdate; var edate;
115             if (obj.sdate < obj.edate) {
116                 sdate = obj.sdate; edate = obj.edate;
117             } else {
118                 sdate = obj.edate; edate = obj.sdate;
119             }
120             obj.network.simple_request('FM_ATC_RETRIEVE_VIA_AOU',[ ses(), /*obj.data.list.au[ 0 ].ws_ou()*/ document.getElementById('libmenu').value, sdate, edate ], 
121                 function(req) {
122                     try {
123                         var robj = req.getResultObject();
124                         if (typeof robj.ilsevent != 'undefined') throw(robj);
125
126                         JSAN.use('util.exec'); 
127                         var exec = new util.exec(2);
128                         var exec2 = new util.exec(2);
129
130                         function gen_list_append(id,which_list) {
131                             return function() {
132                                 switch(which_list) {
133                                     case 0: obj.list.append( { 'row' : { 'my' : { 'transit_id' : id } }, 'no_auto_select' : true } ); break;
134                                     case 1: obj.list.append( { 'row' : { 'my' : { 'transit_id' : id } }, 'no_auto_select' : true } ); break;
135                                 }
136                             };
137                         }
138
139                         var rows = []; 
140
141                         if (document.getElementById('transit_direction').value=='transit_from') for (var i = 0; i < robj.from.length; i++) {
142                             //get_transit(robj.from[i], 0);
143                             rows.push( gen_list_append(robj.from[i],0) );
144                         }
145
146                         if (document.getElementById('transit_direction').value=='transit_to') for (var i = 0; i < robj.to.length; i++) {
147                             //get_transit(robj.to[i], 1);
148                             rows.push( gen_list_append(robj.to[i],1) );
149                         }
150                 
151                         if (rows.length > 0) {
152                             exec.chain( rows );
153                         } else {
154                             alert(document.getElementById('adminStrings').getString('staff.admin.transit_list.no_match'));
155                         }
156
157                     } catch(E) {
158                         try { obj.error.standard_unexpected_error_alert(document.getElementById('adminStrings').getString('staff.admin.transit_list.retrieving_transit.error'),E); } catch(F) { alert(E); }
159                     }
160                 }
161             );
162         } catch(E) {
163             try { obj.error.standard_unexpected_error_alert(document.getElementById('adminStrings').getString('staff.admin.transit_list.preretrieving_transit.error'),E); } catch(F) { alert(E); }
164         }
165     },
166
167     'list_init' : function() {
168
169         var obj = this;
170
171         obj.selection_list = [];
172
173         JSAN.use('circ.util'); 
174         var columns = circ.util.transit_columns(
175             {
176                 'transit_source' : { 'hidden' : false },
177                 'transit_source_send_time' : { 'hidden' : false },
178                 'transit_dest_lib' : { 'hidden' : false },
179                 'transit_item_barcode' : { 'hidden' : false },
180                 'transit_item_title' : { 'hidden' : false },
181             },
182             {
183                 'just_these' : [
184                     'transit_id',
185                     'transit_source',
186                     'transit_source_send_time',
187                     'transit_dest_lib',
188                     'transit_item_barcode',
189                     'transit_item_title',
190                     'transit_item_author',
191                     'transit_item_callnumber',
192                     'transit_target_copy',
193                 ]
194             }
195         ).concat( 
196             circ.util.hold_columns(
197                 {
198                     'request_time' : { 'hidden' : false },
199                 },
200                 {
201                     'just_these' : [
202                         'request_time',
203                         'capture_time',
204                         'hold_type',
205                         'expire_date',
206                         'patron_first_given_name',
207                         'patron_family_name',
208                         'patron_barcode',
209                     ],
210                 }
211             ) 
212         );
213
214         JSAN.use('util.list'); 
215         obj.list = new util.list('transit_list');
216         obj.list.init( 
217             { 
218                 'columns' : columns, 
219                 'retrieve_row' : function(params) {
220                     var row = params.row;
221                     try {
222                         obj.get_transit_and_hold_and_run_func(
223                             row.my.transit_id,
224                             function(transit,hold) { return obj.get_rest_of_row_given_transit_and_hold(params,transit,hold); }
225                         );
226                     } catch(E) {
227                         try { obj.error.standard_unexpected_error_alert(document.getElementById('adminStrings').getString('staff.admin.transit_list.retrieving_row.error'),E); } catch(F) { alert(E); }
228                     }
229                 },
230                 'on_select' : function(ev) {
231                     try {
232                         JSAN.use('util.functional');
233                         var sel = obj.list.retrieve_selection();
234                         obj.selection_list = util.functional.map_list(
235                             sel,
236                             function(o) { return JSON2js(o.getAttribute('retrieve_id')); }
237                         );
238                         obj.error.sdump('D_TRACE','admin.transit_list: selection list = ' + js2JSON(obj.selection_list) );
239                         if (obj.selection_list.length == 0) {
240                             obj.controller.view.sel_edit.setAttribute('disabled','true');
241                             obj.controller.view.sel_opac.setAttribute('disabled','true');
242                             obj.controller.view.sel_bucket.setAttribute('disabled','true');
243                             obj.controller.view.sel_copy_details.setAttribute('disabled','true');
244                             obj.controller.view.sel_patron.setAttribute('disabled','true');
245                             obj.controller.view.sel_transit_abort.setAttribute('disabled','true');
246                             obj.controller.view.sel_clip.setAttribute('disabled','true');
247                         } else {
248                             obj.controller.view.sel_edit.setAttribute('disabled','false');
249                             obj.controller.view.sel_opac.setAttribute('disabled','false');
250                             obj.controller.view.sel_patron.setAttribute('disabled','false');
251                             obj.controller.view.sel_bucket.setAttribute('disabled','false');
252                             obj.controller.view.sel_copy_details.setAttribute('disabled','false');
253                             obj.controller.view.sel_transit_abort.setAttribute('disabled','false');
254                             obj.controller.view.sel_clip.setAttribute('disabled','false');
255                         }
256                     } catch(E) {
257                         alert('FIXME: ' + E);
258                     }
259                 },
260             }
261         );
262     },
263
264     'get_transit_and_hold_and_run_func' : function (transit_id,do_this) {
265         var obj = this;
266         obj.network.simple_request('FM_ATC_RETRIEVE', [ ses(), transit_id ],
267             function(req2) {
268                 try {
269                     var r_atc = req2.getResultObject();
270                     if (typeof r_atc.ilsevent != 'undefined') throw(r_atc);
271
272                     if (instanceOf(r_atc,atc)) {
273                         do_this(r_atc,null);
274                     } else if (instanceOf(r_atc,ahtc)) {
275                         obj.network.simple_request('FM_AHR_RETRIEVE', [ ses(), r_atc.hold() ],
276                             function(req3) {
277                                 try {
278                                     var r_ahr = req3.getResultObject();
279                                     if (typeof r_ahr.ilsevent != 'undefined') throw(r_ahr);
280                                     if (r_ahr.length == 0) {
281                                         // This can apparently happen under normal operating conditions when "checkout fills related hold" is active.
282                                         // So don't throw an error, just pretend that it wasn't a hold transit.
283                                         do_this(r_atc,null);
284                                     } else {
285                                         if (instanceOf(r_ahr[0],ahr)) {
286                                             do_this(r_atc,r_ahr[0]);
287                                         } else {
288                                             throw(r_ahr);
289                                         }
290                                     }
291                                 } catch(E) {
292                                     try { obj.error.standard_unexpected_error_alert(document.getElementById('adminStrings').getFormattedString('staff.admin.transit_list.empty_array.error', [r_atc.hold(), transit_id]),E); } catch(F) { alert(E); }
293                                     do_this(r_atc,null);
294                                 }
295                             }
296                         );
297                     } else {
298                         throw(r_atc);
299                     }
300
301                 } catch(E) {
302                     try { obj.error.standard_unexpected_error_alert(document.getElementById('adminStrings').getFormattedString('staff.admin.transit_list.transit_id.error', [transit_id]),E); } catch(F) { alert(E); }
303                 }
304             }
305         );
306     },
307
308     'get_rest_of_row_given_transit_and_hold' : function(params,transit,hold) {
309         var obj = this;
310         var row = params.row;
311
312         row.my.atc = transit;
313         if (hold) row.my.ahr = hold;
314
315         obj.network.simple_request(
316             'FM_ACP_RETRIEVE',
317             [ row.my.atc.target_copy() ],
318             function(req) {
319                 try { 
320                     var r_acp = req.getResultObject();
321                     if (typeof r_acp.ilsevent != 'undefined') throw(r_acp);
322                     row.my.acp = r_acp;
323
324                     obj.network.simple_request(
325                         'FM_ACN_RETRIEVE.authoritative',
326                         [ r_acp.call_number() ],
327                         function(req2) {
328                             try {
329                                 var r_acn = req2.getResultObject();
330                                 if (typeof r_acn.ilsevent != 'undefined') throw(r_acn);
331                                 row.my.acn = r_acn;
332
333                                 if (row.my.acn.record() > 0) {
334                                     obj.network.simple_request(
335                                         'MODS_SLIM_RECORD_RETRIEVE.authoritative',
336                                         [ r_acn.record() ],
337                                         function(req3) {
338                                             try {
339                                                 var r_mvr = req3.getResultObject();
340                                                 if (typeof r_mvr.ilsevent != 'undefined') throw(r_mvr);
341                                                 row.my.mvr = r_mvr;
342
343                                                 params.treeitem_node.setAttribute(
344                                                     'retrieve_id', js2JSON( { 
345                                                         'copy_id' : row.my.acp ? row.my.acp.id() : null, 
346                                                         'doc_id' : row.my.mvr ? row.my.mvr.doc_id() : null,  
347                                                         'barcode' : row.my.acp ? row.my.acp.barcode() : null, 
348                                                         'acp_id' : row.my.acp ? row.my.acp.id() : null, 
349                                                         'acn_id' : row.my.acn ? row.my.acn.id() : null,  
350                                                         'atc_id' : row.my.atc ? row.my.atc.id() : null,  
351                                                         'ahr_id' : row.my.ahr ? row.my.ahr.id() : null,  
352                                                     } )
353                                                 );
354                                                 if (typeof params.on_retrieve == 'function') {
355                                                     params.on_retrieve(row);
356                                                 }
357                                             } catch(E) {
358                                                 try { obj.error.standard_unexpected_error_alert('retrieving mvr',E); } catch(F) { alert(E); }
359                                             }
360                                         }
361                                     );
362                                 } else {
363                                     params.treeitem_node.setAttribute(
364                                         'retrieve_id', js2JSON( { 
365                                             'copy_id' : row.my.acp ? row.my.acp.id() : null, 
366                                             'doc_id' : row.my.mvr ? row.my.mvr.doc_id() : null,  
367                                             'barcode' : row.my.acp ? row.my.acp.barcode() : null, 
368                                             'acp_id' : row.my.acp ? row.my.acp.id() : null, 
369                                             'acn_id' : row.my.acn ? row.my.acn.id() : null,  
370                                             'atc_id' : row.my.atc ? row.my.atc.id() : null,  
371                                             'ahr_id' : row.my.ahr ? row.my.ahr.id() : null,  
372                                         } )
373                                     );
374                                     if (typeof params.on_retrieve == 'function') {
375                                         params.on_retrieve(row);
376                                     }
377                                 }
378                     
379                             } catch(E) {
380                                 try { obj.error.standard_unexpected_error_alert('retrieving acn',E); } catch(F) { alert(E); }
381                             }
382                         }
383                     );
384
385
386                 } catch(E) {
387                     try { obj.error.standard_unexpected_error_alert('retrieving acp',E); } catch(F) { alert(E); }
388                 }
389             }
390         );
391     },
392
393     'controller_init' : function() {
394         var obj = this;
395
396         JSAN.use('util.controller'); obj.controller = new util.controller();
397         obj.controller.init(
398             {
399                 'control_map' : {
400                     'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ],
401                     'sel_clip' : [ ['command'], function() { obj.list.clipboard(); } ],
402                     'sel_edit' : [ ['command'], function() { try { obj.spawn_copy_editor(0); } catch(E) { alert(E); } } ],
403                     'sel_opac' : [ ['command'], function() { JSAN.use('cat.util'); cat.util.show_in_opac(obj.selection_list); } ],
404                     'sel_transit_abort' : [ ['command'], function() { JSAN.use('circ.util'); circ.util.abort_transits(obj.selection_list); } ],
405                     'sel_patron' : [ ['command'], function() { JSAN.use('circ.util'); circ.util.show_last_few_circs(obj.selection_list); } ],
406                     'sel_copy_details' : [ ['command'],
407                         function() {
408                             JSAN.use('circ.util');
409                             circ.util.item_details_new(
410                                 util.functional.map_list(
411                                     obj.selection_list,
412                                     function(o) { return o.barcode; }
413                                 )
414                             );
415                         } ],
416                     'sel_bucket' : [ ['command'], function() { JSAN.use('cat.util'); cat.util.add_copies_to_bucket(obj.selection_list); } ],
417                     'cmd_print_list' : [ ['command'], function() { obj.print_list(0); } ],
418                     'cmd_kick_off' : [ ['command'], function(ev) { ev.target.disabled = true; obj.kick_off(); } ],
419                     'sdate' : [ ['change'], function(ev) { ev.target.value = obj.handle_date(ev.target.value,false); obj.sdate = ev.target.value; /*alert('obj.sdate='+obj.sdate);*/ } ],
420                     'edate' : [ ['change'], function(ev) { ev.target.value = obj.handle_date(ev.target.value,true); obj.edate = ev.target.value; /*alert('obj.edate='+obj.edate);*/ } ],
421                 }
422             }
423         );
424         this.controller.render();
425
426     },
427
428     'print_list' : function(which_list) {
429         var obj = this;
430         try {
431             var list = which_list == 0 ? obj.list : obj.list2;
432             var p = { 
433                 'template' : 'transit_list'
434             };
435             list.print(p);
436         } catch(E) {
437             obj.error.standard_unexpected_error_alert('print',E); 
438         }
439     },
440     
441     'spawn_copy_editor' : function(which_list) {
442
443         var obj = this;
444
445         JSAN.use('util.functional');
446
447         var list = which_list == 0 ? obj.selection_list : obj.selection_list2;
448
449         list = util.functional.map_list(
450             list,
451             function (o) {
452                 return o.copy_id;
453             }
454         );
455
456         JSAN.use('cat.util'); cat.util.spawn_copy_editor( { 'copy_ids' : list, 'edit' : 1 } );
457
458     },
459
460 }
461
462 dump('exiting admin.transit_list.js\n');