]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/reports/oils_rpt_report_editor.js
LP#1329503 report editing misc. repairs
[working/Evergreen.git] / Open-ILS / web / reports / oils_rpt_report_editor.js
1 dojo.requireLocalization("openils.reports", "reports");
2
3 var rpt_strings = dojo.i18n.getLocalization("openils.reports", "reports");
4
5 oilsRptSetSubClass('oilsRptReportEditor', 'oilsRptObject');
6 var oilsRptReportEditorFolderTree;
7
8 function oilsRptReportEditor(rptObject, folderWindow, readonly) {
9         var tmpl = rptObject.templateObject;
10         var rpt = rptObject.reportObject;
11         this.folderWindow = folderWindow;
12     this.readonly = readonly;
13
14         this.template = tmpl;
15         this.report = rpt;
16
17     if (rpt && rpt.runs() && rpt.runs().length)
18         this.last_run = rpt.runs()[rpt.runs().length - 1];
19
20         appendClear(DOM.oils_rpt_report_editor_template_name, tmpl.name());
21         appendClear(DOM.oils_rpt_report_editor_template_creator, tmpl.owner().usrname());
22         appendClear(DOM.oils_rpt_report_editor_template_description, tmpl.description());
23     
24     appendClear(DOM.oils_rpt_report_editor_cols,'');
25         iterate(rptObject.def.select, 
26                 function(i) {
27                         if(i)
28                                 DOM.oils_rpt_report_editor_cols.appendChild(text(i.alias));
29                                 DOM.oils_rpt_report_editor_cols.appendChild(document.createElement('br'));
30                 }
31         );
32
33 /*
34 oils_rpt_editor_pivot_label
35 oils_rpt_editor_pivot_data
36 */
37
38     var hasAgg = false;
39     iterate(rptObject.def.select, 
40         function(i) {
41             if(OILS_RPT_TRANSFORMS[i.column.transform].aggregate) 
42                 hasAgg = true; 
43         }
44     );
45
46     while(DOM.oils_rpt_editor_pivot_label.getElementsByTagName('option').length > 1)
47         DOM.oils_rpt_editor_pivot_label.removeChild(DOM.oils_rpt_editor_pivot_label.lastChild);
48
49     while(DOM.oils_rpt_editor_pivot_data.lastChild)
50         DOM.oils_rpt_editor_pivot_data.removeChild(DOM.oils_rpt_editor_pivot_data.lastChild);
51
52     if(hasAgg) {
53         unHideMe(DOM.oils_rpt_editor_pivot_label_row);
54         unHideMe(DOM.oils_rpt_editor_pivot_data_row);
55
56         for(var i in rptObject.def.select) {
57             var col = rptObject.def.select[i];
58             if(OILS_RPT_TRANSFORMS[col.column.transform].aggregate) 
59                insertSelectorVal(DOM.oils_rpt_editor_pivot_data, -1, col.alias, parseInt(i)+1);
60             else
61                insertSelectorVal(DOM.oils_rpt_editor_pivot_label, -1, col.alias, parseInt(i)+1);
62         }
63
64     } else {
65         hideMe(DOM.oils_rpt_editor_pivot_label_row);
66         hideMe(DOM.oils_rpt_editor_pivot_data_row);
67     }
68  
69
70         if( rpt ) {
71         // populate the report edit form w/ report data
72
73         this.orig_rpt_name = rpt.name();
74
75                 DOM.oils_rpt_report_editor_name.value = rpt.name();
76                 DOM.oils_rpt_report_editor_name.onchange(); // validation
77                 DOM.oils_rpt_report_editor_desc.value = rpt.description();
78
79         if (rpt.recur() == 't') {
80             DOM.oils_rpt_recur.checked = true;
81             DOM.oils_rpt_recur.onclick(); // enable recurrance selector
82         }
83
84         if (rpt.recurrence()) {
85             var parts = rpt.recurrence().split(/ /);
86             setSelector(DOM.oils_rpt_recur_count, parts[0]);
87             setSelector(DOM.oils_rpt_recur_interval_type, parts[1]);
88         }
89
90         if (run = this.last_run) {
91                     DOM.oils_rpt_report_editor_name.disabled = true;
92                     DOM.oils_rpt_report_editor_desc.disabled = true;
93             DOM.oils_rpt_format_csv.checked = run.csv_format() == 't';
94             DOM.oils_rpt_format_excel.checked = run.excel_format() == 't';
95             DOM.oils_rpt_format_html.checked = run.html_format() == 't';
96             DOM.oils_rpt_format_chart_bar.checked = run.chart_bar() == 't';
97             DOM.oils_rpt_format_chart_line.checked = run.chart_line() == 't';
98         }
99         }
100
101     if (this.readonly) {
102         DOM.oils_rpt_report_editor_name.disabled = true;
103         DOM.oils_rpt_report_editor_desc.disabled = true;
104         DOM.oils_rpt_recur.disabled = true;
105         DOM.oils_rpt_recur_count.disabled = true;
106         DOM.oils_rpt_recur_interval_type.disabled = true;
107         DOM.oils_rpt_report_editor_run_now.disabled = true;
108         DOM.oils_rpt_format_csv.disabled = true;
109         DOM.oils_rpt_format_excel.disabled = true;
110         DOM.oils_rpt_format_html.disabled = true;
111         DOM.oils_rpt_format_chart_bar.disabled = true;
112         DOM.oils_rpt_format_chart_line.disabled = true;
113         DOM.oils_rpt_param_editor_sched_email.disabled = true;
114
115         hideMe(DOM.oils_rpt_report_editor_save);
116         hideMe(DOM.oils_rpt_report_editor_save_new);
117         hideMe(DOM.oils_rpt_report_editor_cancel);
118         unHideMe(DOM.oils_rpt_report_editor_exit);
119
120     } else {
121         // these DOM elements are shared across instances
122         // of the UI.  Re-enable everything.
123         DOM.oils_rpt_report_editor_name.disabled = false;
124         DOM.oils_rpt_report_editor_desc.disabled = false;
125         DOM.oils_rpt_recur.disabled = false;
126         DOM.oils_rpt_recur_count.disabled = false;
127         DOM.oils_rpt_recur_interval_type.disabled = false;
128         DOM.oils_rpt_report_editor_run_now.disabled = false;
129         DOM.oils_rpt_format_csv.disabled = false;
130         DOM.oils_rpt_format_excel.disabled = false;
131         DOM.oils_rpt_format_html.disabled = false;
132         DOM.oils_rpt_format_chart_bar.disabled = false;
133         DOM.oils_rpt_format_chart_line.disabled = false;
134         DOM.oils_rpt_param_editor_sched_email.disabled = false;
135         DOM.oils_rpt_report_editor_save.disabled = false;
136
137         unHideMe(DOM.oils_rpt_report_editor_save);
138         unHideMe(DOM.oils_rpt_report_editor_cancel);
139         hideMe(DOM.oils_rpt_report_editor_exit);
140
141     }
142
143     // avoid showing save-as-new for new reports, since the
144     // regular save button acts as save-as-new
145     if (rpt && !this.readonly) {
146         unHideMe(DOM.oils_rpt_report_editor_save_new);
147     } else {
148         hideMe(DOM.oils_rpt_report_editor_save_new);
149     }
150
151         this.paramEditor = new oilsRptParamEditor(
152                 rptObject, DOM.oils_rpt_param_editor_tbody, this.readonly);
153         this.paramEditor.draw();
154
155         removeChildren(DOM.oils_rpt_report_editor_selected_folder);
156         removeChildren(DOM.oils_rpt_output_selected_folder);
157
158         var obj = this;
159         oilsRptBuildFolder(
160                 'report',
161                 DOM.oils_rpt_report_editor_dest_folder,
162                 'oilsRptReportEditorFolderTree',
163                 rpt_strings.REPORT_EDITOR_REPORT_FOLDERS,
164                 function(node) { 
165                         appendClear(DOM.oils_rpt_report_editor_selected_folder, node.folder.name());
166                         obj.selectedFolder = node; 
167         },
168         null,
169         function(node) {
170             // apply the previously selected report folder
171             if (rpt && rpt.folder() == node.folder.id()) {
172                             appendClear(DOM.oils_rpt_report_editor_selected_folder, node.folder.name());
173                             obj.selectedFolder = node; 
174             }
175         }
176     );
177
178         oilsRptBuildFolder(
179                 'output',
180                 DOM.oils_rpt_output_dest_folder,
181                 'oilsRptReportEditorOutputTree',
182                 rpt_strings.REPORT_EDITOR_OUTPUT_FOLDERS,
183                 function(node) { 
184                         appendClear(DOM.oils_rpt_output_selected_folder, node.folder.name());
185                         obj.selectedOutputFolder = node; 
186         },
187         null,
188         function(node) {
189             // apply the previously selected output folder
190             if (obj.last_run && obj.last_run.folder() == node.folder.id()) {
191                             appendClear(DOM.oils_rpt_output_selected_folder, node.folder.name());
192                             obj.selectedOutputFolder = node; 
193             }
194         }
195     );
196
197
198         var obj = this;
199         DOM.oils_rpt_report_editor_save.onclick = function(){obj.save();}
200         DOM.oils_rpt_report_editor_save_new.onclick = function(){obj.save({save_new : true});}
201         DOM.oils_rpt_report_editor_exit.onclick = function(){obj.exit();}
202         DOM.oils_rpt_report_editor_cancel.onclick = function(){obj.exit();}
203
204         DOM.oils_rpt_param_editor_sched_email.value = 
205         this.last_run ? this.last_run.email() : USER.email();
206
207         DOM.oils_rpt_param_editor_sched_start_date.value = mkYearMonDay();
208
209         _debug("fleshing template:\n" + tmpl.name() + '\n' + formatJSON(tmpl.data()));
210 }
211
212
213 // options.save_new : save as a new report, even if we
214 // were editing an exitingn report.
215 //
216 // options.modify_schedule : update the pending schedule
217 // object instead of creating a new one.
218 oilsRptReportEditor.prototype.save = function(options) {
219     if (!options) options = {};
220
221         if(!this.selectedFolder) 
222                 return alert(rpt_strings.REPORT_EDITOR_PROVIDE_FOLDER_ALERT);
223
224         if(!DOM.oils_rpt_report_editor_name.value)
225                 return alert(rpt_strings.REPORT_EDITOR_ENTER_NAME_ALERT);
226
227         if(!this.selectedOutputFolder) 
228                 return alert(rpt_strings.REPORT_EDITOR_PROVIDE_OUTPUT_ALERT);
229
230         var report = this.report;
231
232     if (report && options.save_new) {
233         // user is saving an existing report as a new report.
234         // The new report must have a different name.
235         if (DOM.oils_rpt_report_editor_name.value == this.orig_rpt_name) 
236             return alert(rpt_strings.REPORT_EDITOR_ENTER_NEW_NAME_ALERT);
237
238         report = null;
239     }
240
241     if (!report) {
242         report = new rr();
243         report.isnew(true);
244             report.owner( USER.id() );
245             report.template( this.template.id() );
246     }
247
248         report.folder( this.selectedFolder.folder.id() );
249         report.name( DOM.oils_rpt_report_editor_name.value );
250         report.description( DOM.oils_rpt_report_editor_desc.value );
251         report.recur(this.paramEditor.recur());
252         report.recurrence(this.paramEditor.recurInterval());
253
254         /* collect the param data */
255         var data = {};
256         for( var p in this.paramEditor.params ) {
257                 var par = this.paramEditor.params[p];
258                 _debug("adding report param "+par.key+" to report data");
259                 var val = par.widget.getValue();
260
261                 if(!val || val.length == 0 )
262                         return alertId('oils_rpt_empty_param');
263
264                 if( typeof val == 'object') {
265                         for( var i = i; i < val.length; i++ ) {
266                                 _debug("looking at widget value" + val[i]);
267                                 if( val[i] == '' || val[i] == null ) 
268                                         return alertId('oils_rpt_empty_param');
269                         }
270                 }
271
272                 data[par.key] = val;
273         }
274
275     if(getSelectorVal(DOM.oils_rpt_editor_pivot_data)) {
276         data.__pivot_label = getSelectorVal(DOM.oils_rpt_editor_pivot_label);
277         data.__pivot_data = getSelectorVal(DOM.oils_rpt_editor_pivot_data);
278     }
279
280
281         data = js2JSON(data);
282         _debug("complete report data = "+data);
283         report.data(data);
284
285         _debug("Built report:\n"+js2JSON(report));
286
287
288         var time;
289         if( DOM.oils_rpt_report_editor_run_now.checked ) {
290                 DOM.oils_rpt_report_editor_run_now.checked = false;
291                 time = 'now';
292
293         } else {
294
295                 var dt = DOM.oils_rpt_param_editor_sched_start_date.value;
296                 if(!dt || !dt.match(/^\d{4}-\d{2}-\d{2}$/) ) {
297                         /* for now.. make this better in the future */
298                         alert(rpt_strings.REPORT_EDITOR_INVALID_DATE_ALERT);
299                         return;
300                 }
301                 var hour = getSelectorVal(DOM.oils_rpt_param_editor_sched_start_hour);
302                 time = dt +'T'+hour+':00';
303                 _debug("built run_time "+time);
304         }
305
306     // if the last run has yet to actually start, then we update it
307     // instead of creating a new one.
308     var schedule = options.save_new ? null : this.last_run;
309
310     if (schedule && !schedule.start_time()) {
311         if (!options.modify_schedule) {
312             // warn the user that this action will modify an existing
313             // schedule object if they continue
314             return this.showPendingScheduleDialog();
315         }
316     } else {
317         // no schedules exist or the most recent one has already
318         // started.  Create a new one.
319             schedule = new rs();
320         schedule.isnew(true);
321     }
322
323         schedule.folder(this.selectedOutputFolder.folder.id());
324         schedule.email(DOM.oils_rpt_param_editor_sched_email.value);
325         schedule.run_time(time);
326         schedule.runner(USER.id());
327
328         schedule.excel_format((DOM.oils_rpt_format_excel.checked) ? 't' : 'f');
329         schedule.html_format((DOM.oils_rpt_format_html.checked) ? 't' : 'f');
330         schedule.csv_format((DOM.oils_rpt_format_csv.checked) ? 't' : 'f');
331         //schedule.chart_pie((DOM.oils_rpt_format_chart_pie.checked) ? 't' : 'f');
332         schedule.chart_bar((DOM.oils_rpt_format_chart_bar.checked) ? 't' : 'f');
333         schedule.chart_line((DOM.oils_rpt_format_chart_line.checked) ? 't' : 'f');
334
335         debugFMObject(report);
336         debugFMObject(schedule);
337
338     if (report.isnew()) {
339         this.createReport(report, schedule);
340     } else {
341         this.updateReport(report, schedule);
342     }
343 }
344
345 // Modify an existing report.
346 // Modify or create the schedule depending on isnew()
347 oilsRptReportEditor.prototype.updateReport = function(report, schedule) {
348
349     var this_ = this;
350     function success() {
351         oilsRptAlertSuccess();
352         this_.exit();
353     }
354
355     oilsRptUpdateReport(report, function(ok) {
356         if (!ok) return oilsRptAlertFailure();
357
358         if (schedule.isnew()) {
359
360             var req = new Request(OILS_RPT_CREATE_SCHEDULE, SESSION, schedule);
361             req.callback(function(res) {
362                 if(checkILSEvent(res)) 
363                     return alertILSEvent(res);
364                 success();
365             });
366             req.send()
367
368         } else {
369
370             oilsRptUpdateSchedule(schedule, function(ok2) {
371                 if (ok2) return success();
372                 _debug("schedule update failed " + js2JSON(schedule));
373                 oilsRptAlertFailure();
374             });
375         }
376     });
377 }
378
379 oilsRptReportEditor.prototype.createReport = function(report, schedule) {
380         var obj = this;
381     var folderReq = new Request(OILS_RPT_REPORT_EXISTS, SESSION, report);
382     folderReq.callback(
383         function(r1) {
384             if(r1.getResultObject() == 1) {
385                 alertId('oils_rpt_report_exists');
386                 return;
387             } else {
388                 var req = new Request(OILS_RPT_CREATE_REPORT, SESSION, report, schedule );
389                 req.callback(
390                     function(r) {
391                         var res = r.getResultObject();
392                         if(checkILSEvent(res)) {
393                             alertILSEvent(res);
394                         } else {
395                             if( res && res != '0' ) {
396                                 oilsRptAlertSuccess();
397                                 obj.exit();
398                             }
399                         }
400                     }
401                 );
402                 req.send();
403             }
404         }
405     );
406     folderReq.send();
407 }
408
409 oilsRptReportEditor.prototype.showPendingScheduleDialog = function() {
410     hideMe(DOM.oils_rpt_editor_table);
411     unHideMe(DOM.oils_rpt_editor_sched_confirm);
412
413     function close() {
414         unHideMe(DOM.oils_rpt_editor_table);
415         hideMe(DOM.oils_rpt_editor_sched_confirm);
416     }
417
418     var this_ = this;
419     DOM.oils_rpt_report_editor_sched_apply.onclick = function() {
420         close();
421         this_.save({modify_schedule : true});
422     }
423
424     DOM.oils_rpt_report_editor_sched_asnew.onclick = function() {
425
426         if (DOM.oils_rpt_report_editor_name.value == this_.orig_rpt_name) {
427             // user is saving as new but has not yet modified the name
428             // Prompt for a new name, then udpate the name entry so save() 
429             // will see it.  Don't let them escape until they comply.
430             var new_name;
431             while (true) { 
432
433                 new_name = prompt(
434                     rpt_strings.REPORT_EDITOR_ENTER_NEW_NAME_ALERT, 
435                     this_.orig_rpt_name
436                 );
437                 
438                 if (new_name && new_name != this_.orig_rpt_name)
439                     break;
440             }
441
442             DOM.oils_rpt_report_editor_name.value = new_name;
443         } 
444
445         close();
446         this_.save({save_new : true})
447     }
448     DOM.oils_rpt_report_editor_sched_cancel.onclick = close;
449 }
450
451
452 oilsRptReportEditor.prototype.exit = function() {
453     unHideMe(DOM.oils_rpt_folder_window_contents_table);                   
454     unHideMe(DOM.oils_rpt_folder_table_right_td);
455     hideMe(DOM.oils_rpt_folder_table_alt_td);
456     hideMe(DOM.oils_rpt_editor_div);
457 }