]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/ue.js
fixed issue where deleting all addresses makes it impossible to create a new one
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / patron / ue.js
1 var cgi                                                 = null;
2 var clone                                               = false;
3 var patron                                              = null;
4 var counter                                             = 0;
5 var identTypesCache                     = {};
6 var statCatsCache                               = {};
7 var surveysCache                                = {};
8 var surveyQuestionsCache        = {};
9 var surveyAnswersCache          = {};
10 var userCache                                   = {};
11 var groupsCache                         = {};
12 var netLevelsCache                      = {};
13
14
15 /* fetch the necessary data to start off */
16 function uEditInit() {
17
18         cgi             = new CGI();
19         session = cgi.param('ses');
20         clone           = cgi.param('clone');
21         if(!session) throw "User session is not defined";
22
23         fetchUser(session);
24         $('uedit_user').appendChild(text(USER.usrname()));
25
26         setTimeout( function() { 
27                 uEditBuild(); uEditShowPage('uedit_userid'); }, 20 );
28 }
29
30 /* ------------------------------------------------------------------------------ */
31 /* Fetch code
32 /* ------------------------------------------------------------------------------ */
33 function uEditFetchIdentTypes() {
34         var req = new Request(FETCH_ID_TYPES);
35         req.send(true);
36         return req.result();
37 }
38
39 function uEditFetchStatCats() {
40         var req = new Request(SC_FETCH_ALL, SESSION);
41         req.send(true);
42         return req.result();
43 }
44
45 function uEditFetchSurveys() {
46         var req = new Request(SV_FETCH_ALL, SESSION);
47         req.send(true);
48         return req.result();
49 }
50
51 function uEditFetchGroups() {
52         var req = new Request(FETCH_GROUPS);
53         req.send(true);
54         return req.result();
55 }
56
57 function uEditFetchNetLevels() {
58         var req = new Request(FETCH_NET_LEVELS, SESSION);
59         req.send(true);
60         return req.result();
61 }
62 /* ------------------------------------------------------------------------------ */
63
64
65
66 /* fetches necessary and builds the UI */
67 function uEditBuild() {
68         //fetchHighestPermOrgs( SESSION, USER.id(), myPerms );
69
70         uEditBuildLibSelector();
71         patron = fetchFleshedUser(cgi.param('usr'));
72         if(!patron) patron = uEditNewPatron(); 
73
74
75         uEditDraw( 
76                 uEditFetchIdentTypes(),
77                 uEditFetchGroups(),
78                 uEditFetchStatCats(),
79                 uEditFetchSurveys(),
80                 uEditFetchNetLevels()
81                 );
82
83         if(patron.isnew()) {
84                 if(clone) 
85                         uEditClone(clone);
86                 else 
87                         uEditCreateNewAddr();
88         }
89
90         if(!patron.isnew()) {
91                 $('ue_barcode').disabled = true;
92                 unHideMe($('ue_mark_card_lost'));
93                 unHideMe($('ue_reset_pw'));
94         }
95 }
96
97
98 /* creates a new patron object with card attached */
99 var uEditCardVirtId = -1;
100 function uEditNewPatron() {
101         var patron = new au(); 
102         patron.isnew(1);
103         patron.id(-1);
104         card = new ac();
105         card.id(uEditCardVirtId--);
106         card.isnew(1);
107         patron.card(card);
108         patron.cards([card]);
109         patron.stat_cat_entries([]);
110         patron.survey_responses([]);
111         patron.addresses([]);
112         patron.home_ou(USER.ws_ou());
113         uEditMakeRandomPw(patron);
114         return patron;
115 }
116
117 function uEditMakeRandomPw(patron) {
118         var rand  = Math.random();
119         rand = parseInt(rand * 10000) + '';
120         while(rand.length < 4) rand += '0';
121         appendClear($('ue_password_plain'),text(rand));
122         unHideMe($('ue_password_gen'));
123         patron.passwd(rand);
124         return rand;
125 }
126
127 function uEditResetPw() { 
128         var pw = uEditMakeRandomPw(patron);     
129         $('ue_password1').value = pw;
130         $('ue_password2').value = pw;
131 }
132
133 function uEditClone(clone) {
134
135         var cloneUser = fetchFleshedUser(clone);
136         patron.usrgroup(cloneUser.usrgroup());
137
138         if( cloneUser.day_phone() )
139                 $('ue_day_phone').value = cloneUser.day_phone();
140         if( cloneUser.evening_phone() )
141                 $('ue_night_phone').value = cloneUser.evening_phone();
142         if( cloneUser.other_phone() )
143                 $('ue_other_phone').value = cloneUser.other_phone();
144         setSelector($('ue_org_selector'), cloneUser.home_ou());
145
146
147         setSelector($('ue_profile'), cloneUser.profile());
148
149         /* force the expire date to be set */
150         $('ue_profile').onchange();
151
152         for( var a in cloneUser.addresses() ) {
153                 var addr = cloneUser.addresses()[a];
154                 if( addr.id() == cloneUser.mailing_address().id() )
155                         patron.mailing_address(addr);
156                 if( addr.id() == cloneUser.billing_address().id() )
157                         patron.billing_address(addr);
158                 patron.addresses().push(addr);
159         }
160
161         uEditBuildAddrs(patron);
162 }
163
164
165 /* Creates a new blank address, 
166         adds it to the user and the fields array */
167 var uEditVirtualAddrId = -1;
168 function uEditCreateNewAddr() {
169         var addr = new aua();
170         addr.id(uEditVirtualAddrId--);
171         addr.isnew(1);
172         addr.usr(patron.id());
173         addr.country(defaultCountry);
174         if(!patron.addresses()) 
175                 patron.addresses([]);
176         if(patron.addresses().length == 0) {
177                 patron.mailing_address(addr);
178                 patron.billing_address(addr);
179         }
180         uEditBuildAddrFields(patron, addr);
181         patron.addresses().push(addr);
182         uEditIterateFields(function(f) { uEditCheckValid(f); });
183         uEditCheckErrors();
184 }
185
186
187 /* kicks off the UI drawing */
188 function uEditDraw(identTypes, groups, statCats, surveys, netLevels ) {
189         hideMe($('uedit_loading'));
190         unHideMe($('ue_maintd'));
191
192         dataFields = [];
193         uEditDrawIDTypes(identTypes);
194         uEditDrawGroups(groups);
195         uEditDrawStatCats(statCats);
196         uEditDrawSurveys(surveys);
197         uEditDrawNetLevels(netLevels);
198         uEditDefineData(patron);
199
200         uEditIterateFields(function(f) { uEditActivateField(f) });
201         uEditIterateFields(function(f) { uEditCheckValid(f); });
202         uEditCheckErrors();
203 }
204
205
206 /** Applies the event handlers and sets the data for the field */
207 function uEditActivateField(field) {
208
209         if( field.widget.id ) {
210                 field.widget.node = $(field.widget.id);
211
212         } else {
213                 field.widget.node = 
214                         $n(field.widget.base, field.widget.name);
215         }
216
217         uEditSetOnchange(field);
218
219         if(field.widget.onblur) {
220                 field.widget.node.onblur = 
221                         function() { field.widget.onblur(field); };
222         }
223
224         field.widget.node.disabled = field.widget.disabled;
225         var val = field.object[field.key]();
226         if(val == null) return;
227
228         if( field.widget.type == 'input' )
229                 field.widget.node.value = val;
230
231         if( field.widget.type == 'select' )
232                 setSelector(field.widget.node, val);
233
234         if( field.widget.type == 'checkbox' )
235                 field.widget.node.checked = 
236                         (val && val != 'f') ? true : false;
237
238         if( field.widget.onload ) 
239                 field.widget.onload(val);
240
241         /*
242         alert(field.key);
243         if(field.key == 'ident_value') alert(field.widget.onblur);
244         */
245
246 }
247
248
249 /* set up the onchange event for the field */
250 function uEditSetOnchange(field) {
251         var func = function() {uEditOnChange( field );}
252         field.widget.node.onchange = func;
253
254         if(field.widget.type != 'select')
255                 field.widget.node.onkeyup = func;
256 }
257
258 /* find the current value of the field object's widget */
259 function uEditNodeVal(field) {
260         if(field.widget.type == 'input')
261                 return field.widget.node.value;
262
263         if(field.widget.type == 'checkbox')
264                 return field.widget.node.checked;
265
266         if(field.widget.type == 'select')
267                 return getSelectorVal(field.widget.node);
268 }
269
270
271 /* update a field value */
272 function uEditOnChange(field) {
273
274         var newval = uEditNodeVal(field);
275         field.object[field.key](newval);
276         field.object.ischanged(1);
277
278         if(field.widget.onpostchange)
279                 field.widget.onpostchange(field, newval);
280
281
282         uEditIterateFields(function(f) { uEditCheckValid(f); });
283         uEditCheckErrors();
284 }
285
286
287 function uEditCheckValid(field) {
288         var newval = uEditNodeVal(field);
289         if(newval) {
290
291                 if(field.widget.regex) { 
292                         if(newval.match(field.widget.regex)) 
293                                 removeCSSClass(field.widget.node, CSS_INVALID_DATA);
294                         else
295                                 addCSSClass(field.widget.node, CSS_INVALID_DATA);
296
297                 } else {
298                         removeCSSClass(field.widget.node, CSS_INVALID_DATA);
299                 }
300
301         } else {
302
303                 if(field.required) {
304                         addCSSClass(field.widget.node, CSS_INVALID_DATA);
305
306                 } else {
307                         removeCSSClass(field.widget.node, CSS_INVALID_DATA);
308                 }
309         }
310 }
311
312 /* find a field object by object key */
313 function uEditFindFieldByKey(key) {
314         var fields = grep( dataFields,
315                 function(item) { return (item.key == key); });
316         return (fields) ? fields[0] : null;
317 }
318
319 /* find a list of fields by object key */
320 function uEditFindFieldsByKey(key) {
321         return grep( dataFields,
322                 function(item) { return (item.key == key); });
323 }
324
325 /* find a field object by widget id */
326 function uEditFindFieldByWId(id) {
327         var fields = grep( dataFields,
328                 function(item) { return (item.widget.id == id); });
329         return (fields) ? fields[0] : null;
330 }
331
332
333 function uEditIterateFields(callback) {
334         for( var f in dataFields ) 
335                 callback(dataFields[f]);
336 }
337
338
339 function uEditGetErrorStrings() {
340         var errors = [];
341         uEditIterateFields(
342                 function(field) { 
343                         if(field.errkey) {
344                                 if( field.widget.node.className.indexOf(CSS_INVALID_DATA) != -1) {
345                                         var str = $(field.errkey).innerHTML;
346                                         if(str) errors.push(str);
347                                 }
348                         }
349                 }
350         );
351
352
353         /* munge up something for all of the required surveys 
354                 (which are not registered with the fields) */
355
356         /* AWAITS POLICY DECISION */
357
358         /*
359         var rows = $('ue_survey_table').getElementsByTagName('tr');
360         for( var r in rows ) {
361
362                 var row = rows[r];
363                 var sel = $n(row, 'ue_survey_answer');
364                 if(!sel) continue;
365                 var qstn = row.getAttribute('question');
366
367                 if(qstn) {
368                         qstn            = surveyQuestionsCache[qstn];
369                         survey  = surveysCache[qstn.survey()];
370                         var val = getSelectorVal(sel);
371                         if(!val && survey.required() && survey.required() != 'f')
372                                 errors.push($('ue_bad_survey').innerHTML);
373                 }
374         }
375         */
376
377         /* ------------------------------------------------------------ */
378
379         if(errors[0]) return errors;
380         return null;
381 }
382
383 function uEditAlertErrors() {
384         var errors = uEditGetErrorStrings();
385         if(!errors) return false;
386         alert(errors.join("\n"));
387         return true;
388 }
389
390
391 /* send the user to the database */
392 function uEditSaveUser(cloneme) {
393
394         if(uEditGetErrorStrings()) {
395                 uEditAlertErrors();
396                 return;
397         }
398
399         /* null is unique in the db, but '' is not */
400         if( ! patron.ident_value() ) patron.ident_value(null);
401         if( ! patron.ident_value2() ) patron.ident_value2(null);
402
403         var req = new Request(UPDATE_PATRON, SESSION, patron);
404         req.send(true);
405         var newuser = req.result();
406
407         var evt;
408         if( (evt = checkILSEvent(newuser)) || ! newuser ) {
409                 if(evt) alert(js2JSON(newuser));
410                 return;
411
412         } else {
413                 alert($('ue_success').innerHTML);
414         }
415
416         if(cloneme) {
417                 /* if the user we just created was a clone, and we want to clone it,
418                 we really want to clone the original */
419                 if( clone ) cloneme = clone;
420                 else cloneme = newuser.id();
421         }
422
423         if (window.xulG && typeof window.xulG.on_save == 'function') {
424                 window.xulG.on_save(newuser, cloneme); 
425
426         } else {
427
428                 var href = location.href;
429
430                 href = href.replace(/\&?usr=\d+/, '');
431                 href = href.replace(/\&?clone=\d+/, '');
432
433                 if( cloneme ) href += '&clone=' + cloneme;
434                 location.href = href;
435         }
436 }
437
438 function uEditCancel() {
439         var href = location.href;
440         href = href.replace(/\&?usr=\d+/, '');
441         href = href.replace(/\&?clone=\d+/, '');
442         location.href = href;
443 }
444
445
446 var uEditDupHashes = {};
447 var uEditDupTemplate;
448
449 function uEditRunDupeSearch(type, search_hash) {
450
451         if(!patron.isnew()) return;
452
453         _debug('dup search: ' + js2JSON(search_hash));
454
455         var req = new Request(PATRON_SEARCH, SESSION, search_hash);
456
457         var container = $('dup_div_container');
458         if(!uEditDupTemplate)
459                 uEditDupTemplate = container.removeChild($('dup_div'));
460
461         /* clear any existing dups for this type */
462         iterate( container.getElementsByTagName('div'),
463                 function(d) {
464                         if( d.getAttribute('type') == type ) {
465                                 container.removeChild(d)
466                                 return;
467                         }
468                 }
469         );
470
471         req.callback(
472                 function(r) {
473                         uEditHandleDupResults( r.getResultObject(), search_hash, type, container );
474                 }
475         );
476         req.send();
477 }
478
479
480 function uEditHandleDupResults(ids, search_hash, type, container) {
481
482         _debug('dup search results: ' + js2JSON(ids));
483
484         if(!(ids && ids[0]))  /* no results */
485                 return uEditDupHashes[type] = null;
486
487         /* add a dup link to the UI and plug in the data */
488         var node = uEditDupTemplate.cloneNode(true);
489         container.appendChild(node);
490         node.setAttribute('type', type);
491
492         var link = $n(node, 'link');
493         link.setAttribute('type', type);
494         unHideMe(link);
495         $n(node,'count').appendChild(text(ids.length));
496
497         for( var o in search_hash ) 
498                 $n(node, 'data').appendChild(
499                         text(search_hash[o].value + ' '));
500
501         uEditDupHashes[type] = search_hash;
502
503         switch(type) {
504                 case 'ident' :
505                         if(confirm($('ue_dup_ident1').innerHTML)) 
506                                 uEditShowSearch(null, type);
507                         break;
508         }
509 }
510
511
512 function uEditShowSearch(link,type) {
513         if(!type) type = link.getAttribute('type');
514         if(window.xulG)
515                 window.xulG.spawn_search(uEditDupHashes[type]); 
516         else alert('Search would be:\n' + js2JSON(uEditDupHashes[type]));
517 }
518
519 function uEditMarkCardLost() {
520
521         for( var c in patron.cards() ) {
522
523                 var card = patron.cards()[c];
524                 if( patron.card().id() == card.id() ) {
525
526                         /* de-activite the current card */
527                         card.ischanged(1);
528                         card.active(0);
529
530                         /* create a new card for the patron */
531                         var newcard = new ac();
532                         newcard.id(uEditCardVirtId--);
533                         newcard.isnew(1);
534                         patron.card(newcard);
535                         patron.cards().push(newcard);
536
537
538                         /* reset the widget */
539                         var field = uEditFindFieldByWId('ue_barcode');
540                         field.widget.node.disabled = false;
541                         field.widget.node.value = "";
542                         field.widget.node.onchange();
543                         field.object = newcard;
544                 }
545         }
546 }
547
548
549 function compactArray(arr) {
550         var a = [];
551         for( var i = 0; arr && i < arr.length; i++ ) {
552                 if( arr[i] != null )
553                         a.push(arr[i]);
554         }
555         return a;
556 }