562aec57aa3da73259bb8c4bb93673678fbe47b4
[Evergreen.git] / Open-ILS / xul / staff_client / server / patron / user_editor.js
1
2 var cgi                                 = null;
3 var patron                              = null;
4 var advanced                    = false;
5 var SC_FETCH_ALL     = 'open-ils.circ:open-ils.circ.stat_cat.actor.retrieve.all';
6 var SC_CREATE_MAP               = 'open-ils.circ:open-ils.circ.stat_cat.actor.user_map.create';
7 var SV_FETCH_ALL                = 'open-ils.circ:open-ils.circ.survey.retrieve.all';
8 var FETCH_ID_TYPES      = 'open-ils.actor:open-ils.actor.user.ident_types.retrieve';
9 var FETCH_GROUPS                = 'open-ils.actor:open-ils.actor.groups.tree.retrieve';
10 var identTypes                  = null;
11 var groupTree                   = null;
12 var ERRORS                              = ""; /* global set of errors */
13
14 var myPerms             = [ 'CREATE_USER', 'UPDATE_USER', 'CREATE_PATRON_STAT_CAT_ENTRY_MAP' ];
15
16 var pages               = [ 
17         'uedit_userid', 
18         'uedit_contact_info', 
19         'uedit_addresses', 
20         'uedit_groups', 
21         'uedit_stat_cats', 
22         'uedit_surveys',
23         'uedit_finalize',
24         ];
25
26 /* ID's of objects that should be focused when their page is made visible */
27 var pageFocus   = [
28         'ue_barcode',
29         'ue_email1',
30         'ue_addr_label_1',
31         'ue_profile',
32         'ue_stat_cat_selector_1',
33         'ue_survey_selector_1',
34         'ue_view_summary'
35 ];
36
37 var regexes             = {};
38 regexes.phone   = /\d{3}-\d{3}-\d{4}/;
39 regexes.email   = /\w+\@\w+\.\w+/;
40 regexes.date    = /^\d{4}-\d{2}-\d{2}/;
41 regexes.isnum   = /^\d+$/;
42
43 /* fetch the necessary data to start off */
44 function uEditInit() {
45
46         cgi             = new CGI();
47         session = cgi.param('ses');
48         if(cgi.param('adv')) advanced = true 
49         if(!session) throw "User session is not defined";
50
51         fetchUser(session);
52         $('uedit_user').appendChild(text(USER.usrname()));
53         uEditShowPage('uedit_userid');
54
55         setTimeout( 
56                 function() { 
57                         fetchHighestPermOrgs( SESSION, USER.id(), myPerms );
58                         uEditDrawUser(fetchFleshedUser(cgi.param('usr')));
59                         uEditBuildLibSelector();
60                         uEditFetchIDTypes();
61                         uEditFetchAddrs();
62                         uEditFetchGroups();
63                         uEditFetchStatCats();
64                         uEditFetchSurveys();
65                 }, 20 
66         );
67 }
68
69 function uEditNext() {
70         var i = _findActive();
71         if( i < (pages.length - 1)) uEditShowPage(pages[i+1]);
72 }
73
74 function uEditPrev() {
75         var i = _findActive();
76         if( i > 0 ) uEditShowPage(pages[i-1]);
77 }
78
79
80 function uEditShowPage(id) {
81         if( id == null ) return;
82
83         for( var p in pages ) {
84                 var page = pages[p];
85                 hideMe($(page));
86                 removeCSSClass($(page+'_label'), 'label_active');
87         }
88
89         unHideMe($(id));
90         addCSSClass($(id+'_label'), 'label_active');
91         var idx = _findPageIdx(id);
92         var fpage = pageFocus[idx];
93         if(fpage) { $(fpage).focus(); try{$(fpage).select()}catch(e){} }
94
95         unHideMe($('ue_back'));
96         unHideMe($('ue_fwd'));
97
98         if(idx == 0) hideMe($('ue_back'));
99         if(idx == (pages.length-1)) hideMe($('ue_fwd'));
100 }
101
102
103 function _findActive() {
104         for( var p in pages ) {
105                 if(! $(pages[p]).className.match(/hide_me/) )
106                         return parseInt(p);
107         }
108         return null;
109 }
110 function _findPageIdx(name) {
111         for( var i in pages ) {
112                 var page = pages[i];
113                 if( page == name ) return i;
114         }
115         return -1;
116 }
117
118 function uEditAddrHighlight( node, type ) {
119         var tbody = $('ue_address_tbody');
120         for( var c in tbody.childNodes ) {
121                 var row = tbody.childNodes[c];
122                 if(row.nodeType != XML_ELEMENT_NODE ) continue;
123                 var div = $n(row,'ue_addr_'+type+'_yes').parentNode;
124                 removeCSSClass(div, 'addr_info_checked');
125         }
126         addCSSClass(node.parentNode, 'addr_info_checked');
127 }
128
129
130
131 function uEditDrawUser(patron) {
132         if(!patron) return 0;
133 }
134
135 function uEditFetchIDTypes() {
136         var req = new Request(FETCH_ID_TYPES);
137         req.callback(uEditDrawIDTypes);
138         req.send();
139 }
140
141 function uEditDrawIDTypes(r) {
142
143         var types = r.getResultObject();
144         var pri_sel = $('ue_primary_ident_type');
145         var sec_sel = $('ue_secondary_ident_type');
146
147         var idx = 1;
148         for( var t in types ) {
149                 var type = types[t];
150                 setSelectorVal( pri_sel, idx, type.name(), type.id() );
151                 setSelectorVal( sec_sel, idx++, type.name(), type.id() );
152         }
153         identTypes = types;
154 }
155
156 function uEditFetchStatCats() {
157         var req = new Request(SC_FETCH_ALL, SESSION);
158         req.callback(uEditDrawStatCats);
159         req.send();
160 }
161
162 function uEditDrawStatCats(r) {
163         var cats = r.getResultObject();
164         var tbody = $('ue_stat_cat_tbody');
165         var templ = tbody.removeChild($('ue_stat_cat_row'));
166
167         for( var c in cats ) {
168                 var row = templ.cloneNode(true);
169                 uEditInsertCat( tbody, row, cats[c], c );
170                 tbody.appendChild(row);
171         }
172 }
173
174 function uEditInsertCat( tbody, row, cat, idx ) {
175
176         cat.entries().sort(  /* sort the entries by value */
177                 function( a, b ) { 
178                         if( a.value().toLowerCase() > b.value().toLowerCase()) return 1;
179                         if( a.value().toLowerCase() < b.value().toLowerCase()) return -1;
180                         return 0;
181                 }
182         );
183
184         var selector = $n(row, 'ue_stat_cat_selector');
185         if( idx == 0 ) selector.id = 'ue_stat_cat_selector_1'; 
186         $n(row, 'ue_stat_cat_name').appendChild(text(cat.name()));
187         $n(row, 'ue_stat_cat_owner').appendChild(text(fetchOrgUnit(cat.owner()).shortname()));
188
189         var idx = 1;
190         for( var e in cat.entries() ) {
191                 var entry = cat.entries()[e];
192                 setSelectorVal( selector, idx++, entry.value(), entry.id() );
193         }
194 }
195
196 function uEditFetchSurveys() {
197         var req = new Request(SV_FETCH_ALL, SESSION);
198         req.callback(uEditDrawSurveys);
199         req.send();
200 }
201
202 function uEditDrawSurveys(r) {
203
204         var surveys = r.getResultObject();
205         var div = $('uedit_surveys');
206         var table = div.removeChild($('ue_survey_table'));
207
208         var x = 0;
209         for( var s in surveys ) {
210                 var survey = surveys[s];
211                 var clone = table.cloneNode(true);
212                 uEditInsertSurvey( div, clone, survey, x++ );
213                 div.appendChild(clone);
214         }
215 }
216
217 function uEditInsertSurvey( div, table, survey, sidx ) {
218         $n(table, 'ue_survey_name').appendChild(text(survey.name()));
219         $n(table, 'ue_survey_desc').appendChild(text(survey.description()));
220         var tbody = $n(table, 'ue_survey_tbody');
221         var templ = tbody.removeChild($n(table, 'ue_survey_row'));
222
223         var polldiv             = $('ue_survey_answer_poll');
224
225         var idx = 1;
226         for( var q in survey.questions() ) {
227                 var row = templ.cloneNode(true);
228                 uEditInsertSurveyQuestion( div, table, tbody, row, survey, survey.questions()[q], sidx );
229                 tbody.appendChild(row);
230         }
231 }
232
233 function uEditInsertSurveyQuestion( div, table, tbody, row, survey, question, sidx ) {
234
235         $n(row, 'ue_survey_question').appendChild(text(question.question()));
236
237         var selector    = $n(row, 'ue_survey_answer');
238         var polldiv             = $n(row, 'ue_survey_answer_poll');
239         var idx                 = 1;
240         var polltbody   = $n(row, 'ue_survey_answer_poll_tbody');
241         var pollrow             = polltbody.removeChild($n(polltbody, 'ue_survey_answer_poll_row'));
242
243         if( sidx == 0 ) selector.id = 'ue_survey_selector_1'; 
244
245         for( var a in question.answers() ) {
246
247                 var answer = question.answers()[a];
248
249                 if( survey.poll() ) {
250
251                         unHideMe(polldiv);
252                         var prow = pollrow.cloneNode(true);
253                         $n(prow, 'ue_survey_answer_poll_answer').appendChild(text(answer.answer()));
254
255                         $n(prow, 'ue_survey_answer_poll_radio').appendChild(
256                                 elem('input', { 
257                                         type    : 'radio', 
258                                         name    : 'survey_poll_answer_'+survey.id(),
259                                         id              :  answer.id()
260                                 }));
261
262                         polltbody.appendChild(prow);
263
264                 } else {
265
266                         unHideMe(selector.parentNode);
267                         setSelectorVal( selector, idx++, answer.answer(), answer.id() );
268                 }
269         }
270 }
271
272
273 function uEditFetchError(id) { if($(id)) return $(id).innerHTML + "\n"; return "";}
274
275
276 function uEditSaveUser() {
277
278         var card                = null;
279
280         if(patron == null) { 
281                 patron = new au(); 
282                 patron.isnew(1);
283                 card = new ac();
284                 patron.card(-1); /* attach to the virtual id of the card */
285                 patron.cards([card]);
286
287         } else { 
288                 patron.ischanged(1); 
289                 patron.isnew(0);
290         }
291
292         uEditFleshCard(card);
293         uEditAddBasicPatronInfo(patron);
294         uEditAddPhones(patron);
295         uEditAddIdents(patron);
296         uEditAddAddresses(patron);
297         uEditAddGroupsAndPerms(patron);
298
299         if(ERRORS) { alert(ERRORS); ERRORS = ""; }
300         else alert(js2JSON(patron));
301 }
302
303 /* returns true if an error occurred */
304 function uEditSetVal( obj, func, val, regxtype, errtype ) {
305
306         var error = uEditFetchError(errtype);
307         var iserr = false;
308
309         while(1) {
310
311                 if( val == null ) { iserr = true; break; }
312
313                 if(!instanceOf(val, String)) {
314                         try { val = val.value; } catch(e) { return; }
315                 }
316
317                 if(val == "" ) { iserr = true; break; }
318
319                 if(regxtype && regexes[regxtype] 
320                         && !val.match(regexes[regxtype]) ) { iserr = true; break; }
321
322                 try { obj[func](val); } catch(e) {
323                         alert("Error running function: " +func);
324                 }
325
326                 break;
327         }
328
329         if(iserr) { ERRORS += error; return true; }
330         return false;
331 }
332
333
334 function uEditAddBasicPatronInfo(patron) {
335
336
337
338         /* make sure passwords match */
339         var p1 = $('ue_password1').value;
340         var p2 = $('ue_password1').value;
341         if( p1 != p2 || uEditSetVal( patron, "passwd", p1 )) 
342                 ERRORS += uEditFetchError('ue_bad_password');
343
344         uEditSetVal(patron, "usrname", $('ue_username'), null, 'ue_bad_username' );
345         uEditSetVal(patron, "first_given_name", $('ue_firstname'), null, 'ue_bad_firstname' );
346         uEditSetVal(patron, "second_given_name", $('ue_middlename'), null, 'ue_bad_middlename' ); 
347         uEditSetVal(patron, "family_name", $('ue_lastname'), null, 'ue_bad_lastname' ); 
348         uEditSetVal(patron, "dob", $('ue_dob'), 'date', 'ue_bad_dob' );
349
350         patron.suffix($('ue_suffix').value); /* suffis isn't required */
351
352
353         /* make sure emails match */
354         var email       = $('ue_email1').value;
355         var email2      = $('ue_email2').value;
356         if( email != email2 || uEditSetVal(patron, "email", email, 'email' ))
357                 ERRORS += uEditFetchError('ue_bad_email');
358
359         patron.home_ou(getSelectorVal($('ue_org_selector')));
360 }
361
362 function uEditAddPhones(patron) {
363
364
365         /* verifies the phone numbers are formatted correctly */
366         var verify = function(n1, n2, n3) {
367                 var a = n1.value;
368                 var p = n2.value;
369                 var s = n3.value;
370                 if( !a || !p || !s ) return false;
371                 return a + '-' + p + '-' + s;
372         }
373
374
375         var er = 'ue_bad_phone'
376
377         uEditSetVal( patron, "day_phone", 
378                 verify($('ue_day_phone_area'), 
379                 $('ue_day_phone_prefix'), 
380                 $('ue_day_phone_suffix')), 'phone', er );
381
382         uEditSetVal( patron, "evening_phone", 
383                 verify($('ue_night_phone_area'), 
384                 $('ue_night_phone_prefix'), 
385                 $('ue_night_phone_suffix')), 'phone', er );
386
387         uEditSetVal( patron, "other_phone", 
388                 verify($('ue_other_phone_area'), 
389                 $('ue_other_phone_prefix'), 
390                 $('ue_other_phone_suffix')), 'phone', er );
391
392 }
393
394 function uEditFleshCard(card) {
395         if(!card) return "";
396
397         if(uEditSetVal( card, "barcode", $('ue_barcode'), null, 'ue_bad_barcode' ))
398                 return; 
399
400         card.id(-1);
401         card.active(1);
402         return "";
403 }
404
405 function uEditAddIdents(patron) {
406
407         var err = 'ue_no_ident';
408
409         uEditSetVal( patron, "ident_type", 
410                 getSelectorVal($('ue_primary_ident_type')), 'isnum', err );
411
412         uEditSetVal( patron, "ident_type2", 
413                 getSelectorVal($('ue_secondary_ident_type')), 'isnum', err );
414
415         uEditSetVal( patron, "ident_value", 
416                 $('ue_primary_ident'), null, err );
417
418         uEditSetVal( patron, "ident_value2", 
419                 $('ue_secondary_ident'), null, err );
420
421 }
422
423
424 function uEditBuildLibSelector( node, depth, selector ) {
425         if(!selector) selector = $('ue_org_selector');
426         if(!node) { depth = 0; node = globalOrgTree; }
427         
428         var opt = insertSelectorVal( selector, -1, node.name(), node.id(), null, depth++ );
429
430         /* allow these orgs to be selectable via permission? */
431         if(!findOrgType(node.ou_type()).can_have_vols()) opt.disabled = true; 
432
433         if( node.id() == USER.home_ou() ) setSelector(selector, node.id());
434         for( var c in node.children() ) 
435                 uEditBuildLibSelector(node.children()[c], depth, selector);
436 }
437
438 function uEditFetchGroups() {
439         var req = new Request(FETCH_GROUPS);
440         req.callback(uEditDrawGroups);
441         req.send();
442 }
443
444 function uEditDrawGroups(r, tree, depth, selector) {
445
446         if(!tree) {
447                 tree = r.getResultObject();     
448                 depth = 0;
449                 groupTree = tree;
450                 selector = $('ue_profile');
451         }
452
453         insertSelectorVal( selector, -1, tree.name(), tree.id(), null, depth++ );       
454         for( var c in tree.children() ) 
455                 uEditDrawGroups( null, tree.children()[c], depth, selector );
456 }
457
458
459
460 function uEditAddGroupsAndPerms(patron) {
461
462         uEditSetVal( patron, "profile", 
463                 getSelectorVal($('ue_profile')), 'isnum', 'ue_no_profile');
464
465         var expire = $('ue_expire').value;
466         if(expire) 
467                 uEditSetVal( patron, "expire_date", expire, 'date', 'ue_bad_expire' );
468
469         if($('ue_active').checked) patron.active(1);
470         if($('ue_barred').checked) patron.barred(1);
471         if($('ue_group_lead').checked) patron.master_account(1);
472
473         uEditSetVal( patron, "claims_returned_count", 
474                 $('ue_claims_returned'), 'isnum', 'ue_bad_claims_returned');
475
476         if($('ue_alert_message').value) 
477                 uEditSetVal(patron, "alert_message", $('ue_alert_message'));
478 }
479
480
481
482 function uEditAddAddresses(patron) {
483         var tbody = $('ue_address_tbody');      
484
485         for( var r in tbody.childNodes ) {
486                 var row = tbody.childNodes[r];
487                 if(!(row && row.nodeName == 'tr')) continue;
488                 uEditSetAddress( tbody, row );  
489         }
490 }
491
492 /* extracts a single address from the page */
493 function uEditSetAddress( tbody, row ) {
494
495         var label       = $n(row, 'ue_addr_label');
496         var street1     = $n(row, 'ue_addr_street1');
497         var street2     = $n(row, 'ue_addr_street2');
498         var city                = $n(row, 'ue_addr_city');
499         var county      = $n(row, 'ue_addr_county');
500         var state       = $n(row, 'ue_addr_state');
501         var zip         = $n(row, 'ue_addr_zip');
502         var country = $n(row, 'ue_addr_country');
503
504 }
505
506
507 var uEditAddrTemplate;
508 function uEditFetchAddrs() {
509
510         var tbody = $('ue_address_tbody');
511         uEditAddrTemplate = tbody.removeChild($('ue_address_template'));
512
513         $('ue_address_new').onclick = 
514                 function() { tbody.appendChild(uEditAddrTemplate.cloneNode(true)); }
515
516         /* go ahead and add a blank addr */
517         if(!patron) {
518                 var row = uEditAddrTemplate.cloneNode(true);
519                 $n( row, 'ue_addr_label').id = 'ue_addr_label_1';
520                 tbody.appendChild(row); 
521                 return;
522         }
523 }