]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/ui/default/acq/common/li_table.js
if the bibs and holdings have already been loaded into the ILS, the marc from the...
[Evergreen.git] / Open-ILS / web / js / ui / default / acq / common / li_table.js
1 dojo.require('dojo.date.locale');
2 dojo.require('dojo.date.stamp');
3 dojo.require('dijit.form.Button');
4 dojo.require('dijit.form.TextBox');
5 dojo.require('dijit.form.FilteringSelect');
6 dojo.require('dijit.form.Textarea');
7 dojo.require('dijit.ProgressBar');
8 dojo.require('openils.User');
9 dojo.require('openils.Util');
10 dojo.require('openils.acq.Lineitem');
11 dojo.require('openils.acq.PO');
12 dojo.require('openils.acq.Picklist');
13 dojo.require('openils.widget.AutoFieldWidget');
14 dojo.require('dojo.data.ItemFileReadStore');
15 dojo.require('openils.widget.ProgressDialog');
16 dojo.require('openils.PermaCrud');
17
18 dojo.requireLocalization('openils.acq', 'acq');
19 var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
20
21 function AcqLiTable() {
22
23     var self = this;
24     this.liCache = {};
25     this.toggleState = false;
26     this.tbody = dojo.byId('acq-lit-tbody');
27     this.selectors = [];
28     this.authtoken = openils.User.authtoken;
29     this.rowTemplate = this.tbody.removeChild(dojo.byId('acq-lit-row'));
30     this.copyTbody = dojo.byId('acq-lit-li-details-tbody');
31     this.copyRow = this.copyTbody.removeChild(dojo.byId('acq-lit-li-details-row'));
32     this.copyBatchRow = dojo.byId('acq-lit-li-details-batch-row');
33     this.copyBatchWidgets = {};
34     this.liNotesTbody = dojo.byId('acq-lit-notes-tbody');
35     this.liNotesRow = this.liNotesTbody.removeChild(dojo.byId('acq-lit-notes-row'));
36
37     dojo.connect(acqLitLiActionsSelector, 'onChange', 
38         function() { 
39             self.applySelectedLiAction(this.attr('value')) 
40             acqLitLiActionsSelector.attr('value', '_');
41         });
42
43     acqLitCreatePoSubmit.onClick = function() {
44         acqLitPoCreateDialog.hide();
45         self._createPO(acqLitPoCreateDialog.getValues());
46     }
47
48     acqLitSavePlButton.onClick = function() {
49         acqLitSavePlDialog.hide();
50         self._savePl(acqLitSavePlDialog.getValues());
51     }
52
53     dojo.byId('acq-lit-notes-new-button').onclick = function(){acqLitCreateLiNoteDialog.show();}
54
55     dojo.byId('acq-lit-select-toggle').onclick = function(){self.toggleSelect()};
56     dojo.byId('acq-lit-info-back-button').onclick = function(){self.show('list')};
57     dojo.byId('acq-lit-copies-back-button').onclick = function(){self.show('list')};
58     dojo.byId('acq-lit-notes-back-button').onclick = function(){self.show('list')};
59
60     this.reset = function() {
61         while(self.tbody.childNodes[0])
62             self.tbody.removeChild(self.tbody.childNodes[0]);
63         self.selectors = [];
64     };
65     
66     this.setNext = function(handler) {
67         var link = dojo.byId('acq-lit-next');
68         if(handler) {
69             dojo.style(link, 'visibility', 'visible');
70             link.onclick = handler;
71         } else {
72             dojo.style(link, 'visibility', 'hidden');
73         }
74     };
75
76     this.setPrev = function(handler) {
77         var link = dojo.byId('acq-lit-prev');
78         if(handler) {
79             dojo.style(link, 'visibility', 'visible'); 
80             link.onclick = handler; 
81         } else {
82             dojo.style(link, 'visibility', 'hidden');
83         }
84     };
85
86     this.show = function(div) {
87         openils.Util.hide('acq-lit-table-div');
88         openils.Util.hide('acq-lit-info-div');
89         openils.Util.hide('acq-lit-li-details');
90         openils.Util.hide('acq-lit-notes-div');
91         switch(div) {
92             case 'list':
93                 openils.Util.show('acq-lit-table-div');
94                 break;
95             case 'info':
96                 openils.Util.show('acq-lit-info-div');
97                 break;
98             case 'copies':
99                 openils.Util.show('acq-lit-li-details');
100                 break;
101             case 'notes':
102                 openils.Util.show('acq-lit-notes-div');
103                 break;
104             default:
105                 if(div) 
106                     openils.Util.show(div);
107         }
108     }
109
110     this.hide = function() {
111         this.show(null);
112     }
113
114     this.toggleSelect = function() {
115         if(self.toggleState) 
116             dojo.forEach(self.selectors, function(i){i.checked = false});
117         else 
118             dojo.forEach(self.selectors, function(i){i.checked = true});
119         self.toggleState = !self.toggleState;
120     };
121
122
123     /** @param all If true, assume all are selected */
124     this.getSelected = function(all) {
125         var selected = [];
126         dojo.forEach(self.selectors, 
127             function(i) { 
128                 if(i.checked || all)
129                     selected.push(self.liCache[i.parentNode.parentNode.getAttribute('li')]);
130             }
131         );
132         return selected;
133     };
134
135     this.setRowAttr = function(td, liWrapper, field, type) {
136         var val = liWrapper.findAttr(field, type || 'lineitem_marc_attr_definition') || '';
137         td.appendChild(document.createTextNode(val));
138     };
139
140     this.addLineitem = function(li) {
141         this.liCache[li.id()] = li;
142
143         // sort the lineitem notes on edit_time
144         if(!li.lineitem_notes()) li.lineitem_notes([]);
145
146         var liWrapper = new openils.acq.Lineitem({lineitem:li});
147         var row = self.rowTemplate.cloneNode(true);
148         row.setAttribute('li', li.id());
149         var tds = dojo.query('[attr]', row);
150         dojo.forEach(tds, function(td) {self.setRowAttr(td, liWrapper, td.getAttribute('attr'), td.getAttribute('attr_type'));});
151         dojo.query('[name=source_label]', row)[0].appendChild(document.createTextNode(li.source_label()));
152
153         var isbn = liWrapper.findAttr('isbn', 'lineitem_marc_attr_definition');
154         if(isbn) {
155             // XXX media prefix for added content
156             dojo.query('[name=jacket]', row)[0].setAttribute('src', '/opac/extras/ac/jacket/small/' + isbn);
157         }
158
159         dojo.query('[attr=title]', row)[0].onclick = function() {self.drawInfo(li.id())};
160         dojo.query('[name=copieslink]', row)[0].onclick = function() {self.drawCopies(li.id())};
161         dojo.query('[name=count]', row)[0].innerHTML = li.item_count() || 0;
162         dojo.query('[name=notes_count]', row)[0].innerHTML = li.lineitem_notes().length;
163         dojo.query('[name=noteslink]', row)[0].onclick = function() {self.drawLiNotes(li)};
164
165         var priceInput = dojo.query('[name=price]', row)[0];
166         var priceData = liWrapper.getPrice();
167         priceInput.value = (priceData) ? priceData.price : '';
168         priceInput.onchange = function() { self.updateLiPrice(priceInput, li) };
169
170         var recv_link = dojo.query('[name=receive_link]', row)[0];
171         if(li.state() == 'received') {
172             openils.Util.hide(recv_link)
173         } else {
174             recv_link.onclick = function() {
175                 self.receiveLi(li);
176                 openils.Util.hide(recv_link)
177             }
178         }
179
180         self.tbody.appendChild(row);
181         self.selectors.push(dojo.query('[name=selectbox]', row)[0]);
182     };
183
184     this.drawLiNotes = function(li) {
185         var self = this;
186
187         li.lineitem_notes(
188             li.lineitem_notes().sort(
189                 function(a, b) { 
190                     if(a.edit_time() < b.edit_time()) return 1;
191                     return -1;
192                 }
193             )
194         );
195
196         while(this.liNotesTbody.childNodes[0])
197             this.liNotesTbody.removeChild(this.liNotesTbody.childNodes[0]);
198         this.show('notes');
199
200         acqLitCreateLiNoteSubmit.onClick = function() {
201             acqLitCreateLiNoteDialog.hide();
202             var value = acqLitCreateLiNoteDialog.getValues().note;
203             if(!value) return;
204             var note = new fieldmapper.acqlin();
205             note.isnew(true);
206             note.value(value);
207             li.lineitem_notes().push(note);
208             note.lineitem(li.id());
209             self.addLiNote(li, note);
210         }
211
212         dojo.byId('acq-lit-notes-save-button').onclick = function() {
213             self.updateLiNotes(li);
214         }
215
216         dojo.forEach(li.lineitem_notes(), function(note) { self.addLiNote(li, note) });
217     }
218
219     this.addLiNote = function(li, note) {
220         var self = this;
221         var row = self.liNotesRow.cloneNode(true);
222         dojo.query('[name=creator]', row)[0].innerHTML = note.creator() || ''; /* XXX */
223         dojo.query('[name=editor]', row)[0].innerHTML = note.editor() || ''; /* XXX */
224
225         if(note.create_time()) {
226             dojo.query('[name=create_time]', row)[0].innerHTML = 
227                 dojo.date.locale.format(
228                     dojo.date.stamp.fromISOString(note.create_time()), 
229                     {formatLength:'short'});
230         }
231
232         if(note.edit_time()) {
233             dojo.query('[name=edit_time]', row)[0].innerHTML = 
234                 dojo.date.locale.format(
235                     dojo.date.stamp.fromISOString(note.edit_time()), 
236                     {formatLength:'short'});
237         }
238
239         new openils.widget.AutoFieldWidget({
240             fmField : 'value',
241             fmObject : note,
242             parentNode : dojo.query('[name=value]', row)[0],
243             widgetClass : 'dijit.form.Textarea',
244         }).build(
245             function(w) {
246                 dojo.connect(w, 'onChange', 
247                     function() {
248                         note.value(this.attr('value')); 
249                         note.ischanged(true);
250                     }
251                 );
252             }
253         );
254
255         dojo.query('[name=delete]', row)[0].onclick = function() {
256             note.isdeleted(true);
257             self.liNotesTbody.removeChild(row);
258         };
259
260         self.liNotesTbody.appendChild(row);
261     }
262
263     this.updateLiNotes = function(li) {
264         progressDialog.show();
265
266         var notes = li.lineitem_notes().filter(
267             function(note) {
268                 if(note.ischanged() || note.isnew() || note.isdeleted())
269                     return note;
270             }
271         );
272
273         fieldmapper.standardRequest(
274             ['open-ils.acq', 'open-ils.acq.lineitem_note.cud.batch'],
275             {   async : true,
276                 params : [this.authtoken, notes],
277                 onresponse : function(r) {
278                     var resp = openils.Util.readResponse(r);
279
280                     if(resp.complete) {
281                         progressDialog.hide();
282                         self.drawLiNotes(li);
283                         return;
284                     }
285
286                     progressDialog.update(resp);
287
288                     var newnote = resp.note;
289                     var oldnote = li.lineitem_notes().filter(function(n) { return (n.value() == newnote.value()) })[0];
290                     var notes = li.lineitem_notes().filter(function(n) { return (n.value() != newnote.value()) });
291
292                     if(!openils.Util.isTrue(oldnote.isdeleted())) 
293                         notes.push(newnote);
294                     li.lineitem_notes(notes);
295                 },
296             }
297         );
298     }
299
300     this.updateLiPrice = function(input, li) {
301
302         var price = input.value;
303         var liWrapper = new openils.acq.Lineitem({lineitem:li});
304         var oldPrice = liWrapper.getPrice() || null;
305
306         if(oldPrice) oldPrice = oldPrice.price;
307         if(price == oldPrice) return;
308
309         fieldmapper.standardRequest(
310             ['open-ils.acq', 'open-ils.acq.lineitem_local_attr.set'],
311             {   async : true,
312                 params : [this.authtoken, li.id(), 'estimated_price', price],
313                 oncomplete : function(r) {
314                     openils.Util.readResponse(r);
315                 }
316             }
317         );
318     }
319
320     this.removeLineitem = function(liId) {
321         this.tbody.removeChild(dojo.query('[li='+liId+']', this.tbody)[0]);
322         delete this.liCache[liId];
323     }
324
325     this.drawInfo = function(liId) {
326         this.show('info');
327         openils.acq.Lineitem.fetchAttrDefs(
328             function() { 
329                 self._fetchLineitem(liId, function(li){self._drawInfo(li);}); 
330             } 
331         );
332     };
333
334     this._fetchLineitem = function(liId, handler) {
335
336         var li = this.liCache[liId];
337         if(li && li.marc() && li.lineitem_details())
338             return handler(li);
339         
340         fieldmapper.standardRequest(
341             ['open-ils.acq', 'open-ils.acq.lineitem.retrieve'],
342             {   async: true,
343
344                 params: [self.authtoken, liId, {
345                     flesh_attrs: true,
346                     flesh_li_details: true,
347                     flesh_fund_debit: true }],
348
349                 oncomplete: function(r) {
350                     var li = openils.Util.readResponse(r);
351                     handler(li)
352                 }
353             }
354         );
355     };
356
357     this._drawInfo = function(li) {
358
359         acqLitEditOrderMarc.onClick = function() { self.editOrderMarc(li); }
360         acqLitEditILSMarc.onClick = function() { self.editILSMarc(li); }
361
362         if(li.eg_bib_id()) {
363             openils.Util.hide('acq-lit-marc-order-record-label');
364             openils.Util.hide(acqLitEditOrderMarc.domNode);
365             openils.Util.show('acq-lit-marc-real-record-label');
366             openils.Util.show(acqLitEditILSMarc.domNode);
367         } else {
368             openils.Util.show('acq-lit-marc-order-record-label');
369             openils.Util.show(acqLitEditOrderMarc.domNode);
370             openils.Util.hide('acq-lit-marc-real-record-label');
371             openils.Util.hide(acqLitEditILSMarc.domNode);
372         }
373
374         this.drawMarcHTML(li);
375         this.infoTbody = dojo.byId('acq-lit-info-tbody');
376
377         if(!this.infoRow)
378             this.infoRow = this.infoTbody.removeChild(dojo.byId('acq-lit-info-row'));
379         while(this.infoTbody.childNodes[0])
380             this.infoTbody.removeChild(this.infoTbody.childNodes[0]);
381
382         for(var i = 0; i < li.attributes().length; i++) {
383             var attr = li.attributes()[i];
384             var row = this.infoRow.cloneNode(true);
385
386             var type = attr.attr_type().replace(/lineitem_(.*)_attr_definition/, '$1');
387             var name = openils.acq.Lineitem.attrDefs[type].filter(
388                 function(a) {
389                     return (a.code() == attr.attr_name());
390                 }
391             ).pop().description();
392
393             dojo.query('[name=label]', row)[0].appendChild(document.createTextNode(name));
394             dojo.query('[name=value]', row)[0].appendChild(document.createTextNode(attr.attr_value()));
395             this.infoTbody.appendChild(row);
396         }
397
398         if(li.eg_bib_id()) {
399             openils.Util.show('acq-lit-info-cat-link');
400             var link = dojo.byId('acq-lit-info-cat-link').getElementsByTagName('a')[0];
401             var href = link.getAttribute('href');
402             if(href.match(/=$/))
403                 link.setAttribute('href',  href + li.eg_bib_id());
404         } else {
405             openils.Util.hide('acq-lit-info-cat-link');
406         }
407     };
408
409     this.drawMarcHTML = function(li) {
410         var params = [null, true, li.marc()];
411         if(li.eg_bib_id()) 
412             params = [li.eg_bib_id(), true];
413
414         fieldmapper.standardRequest(
415             ['open-ils.search', 'open-ils.search.biblio.record.html'],
416             {   async: true,
417                 params: params,
418                 oncomplete: function(r) {
419                     dojo.byId('acq-lit-marc-div').innerHTML = 
420                         openils.Util.readResponse(r);
421                 }
422             }
423         );
424     }
425
426     this.drawCopies = function(liId) {
427         this.show('copies');
428         var self = this;
429         this.copyCache = {};
430         this.copyWidgetCache = {};
431
432         acqLitSaveCopies.onClick = function() { self.saveCopyChanges(liId) };
433         acqLitBatchUpdateCopies.onClick = function() { self.batchCopyUpdate() };
434
435         while(this.copyTbody.childNodes[0])
436             this.copyTbody.removeChild(this.copyTbody.childNodes[0]);
437
438         this._drawBatchCopyWidgets();
439
440         this._fetchDistribFormulas(
441             function() {
442                 openils.acq.Lineitem.fetchAttrDefs(
443                     function() { 
444                         self._fetchLineitem(liId, function(li){self._drawCopies(li);}); 
445                     } 
446                 );
447             }
448         );
449     };
450
451     this._fetchDistribFormulas = function(onload) {
452         if(this.distribForms) {
453             onload();
454         } else {
455             var self = this;
456             fieldmapper.standardRequest(
457                 ['open-ils.acq', 'open-ils.acq.distribution_formula.ranged.retrieve.atomic'],
458                 {   async: true,
459                     params: [openils.User.authtoken],
460                     oncomplete: function(r) {
461                         self.distribForms = openils.Util.readResponse(r);
462                         self.distribFormulaStore = 
463                             new dojo.data.ItemFileReadStore(
464                                 {data:acqdf.toStoreData(self.distribForms)});
465                         onload();
466                     }
467                 }
468             );
469         }
470     }
471
472     this._drawBatchCopyWidgets = function() {
473         var row = this.copyBatchRow;
474         dojo.forEach(['fund', 'owning_lib', 'location', 'circ_modifier', 'cn_label'],
475             function(field) {
476                 if(self.copyBatchRowDrawn) {
477                     self.copyBatchWidgets[field].attr('value', null);
478                 } else {
479                     var widget = new openils.widget.AutoFieldWidget({
480                         fmField : field,
481                         fmClass : 'acqlid',
482                         parentNode : dojo.query('[name='+field+']', row)[0],
483                         orgLimitPerms : ['CREATE_PICKLIST'],
484                         dijitArgs : {required:false}
485                     });
486                     widget.build();
487                     self.copyBatchWidgets[field] = widget.widget;
488                 }
489             }
490         );
491         this.copyBatchRowDrawn = true;
492     };
493
494     this.batchCopyUpdate = function() {
495         var self = this;
496         var fields = ['fund', 'owning_lib', 'location', 'circ_modifier', 'cn_label'];
497         for(var k in this.copyWidgetCache) {
498             var cache = this.copyWidgetCache[k];
499             dojo.forEach(fields, function(f) {
500                 var newval = self.copyBatchWidgets[f].attr('value');
501                 if(newval) cache[f].attr('value', newval);
502             });
503         }
504     };
505
506     this._drawCopies = function(li) {
507         acqLitAddCopyCount.onClick = function() { 
508             var count = acqLitCopyCountInput.attr('value');
509             for(var i = 0; i < count; i++)
510                 self.addCopy(li); 
511         }
512         if(li.lineitem_details().length > 0) {
513             dojo.forEach(li.lineitem_details(),
514                 function(copy) {
515                     self.addCopy(li, copy);
516                 }
517             );
518         } else {
519             self.addCopy(li);
520         }
521     };
522
523     this.virtCopyId = -1;
524     this.addCopy = function(li, copy) {
525         var row = this.copyRow.cloneNode(true);
526         this.copyTbody.appendChild(row);
527         var self = this;
528
529         if(!copy) {
530             copy = new fieldmapper.acqlid();
531             copy.isnew(true);
532             copy.id(this.virtCopyId--);
533             copy.lineitem(li.id());
534         }
535
536         this.copyCache[copy.id()] = copy;
537         row.setAttribute('copy_id', copy.id());
538         self.copyWidgetCache[copy.id()] = {};
539
540         dojo.forEach(['fund', 'owning_lib', 'location', 'barcode', 'cn_label', 'circ_modifier', 'note'],
541             function(field) {
542                 var widget = new openils.widget.AutoFieldWidget({
543                     fmObject : copy,
544                     fmField : field,
545                     fmClass : 'acqlid',
546                     parentNode : dojo.query('[name='+field+']', row)[0],
547                     orgLimitPerms : ['CREATE_PICKLIST'],
548                     readOnly : self.isPO
549                 });
550                 widget.build(
551                     // make sure we capture the value from any async widgets
552                     function(w, ww) { copy[field](ww.getFormattedValue()) }
553                 );
554                 dojo.connect(widget.widget, 'onChange', 
555                     function(val) { 
556                         if(copy.isnew() || val != copy[field]()) {
557                             // prevent setting ischanged() automatically on widget load for existing copies
558                             copy[field](widget.getFormattedValue()) 
559                             copy.ischanged(true);
560                         }
561                     }
562                 );
563                 self.copyWidgetCache[copy.id()][field] = widget.widget;
564             }
565         );
566
567         var recv_link = dojo.query('[name=receive]', row)[0];
568         if(copy.recv_time()) {
569             openils.Util.hide(recv_link);
570         } else {
571             recv_link.onclick = function() {
572                 self.receiveLid(copy);
573                 openils.Util.hide(recv_link);
574             }
575         }
576
577         if(this.isPO) {
578             openils.Util.hide(dojo.query('[name=delete]', row)[0].parentNode);
579         } else {
580             dojo.query('[name=delete]', row)[0].onclick = 
581                 function() { self.deleteCopy(row) };
582         }
583     };
584
585     this.deleteCopy = function(row) {
586         var copy = this.copyCache[row.getAttribute('copy_id')];
587         copy.isdeleted(true);
588         if(copy.isnew())
589             delete this.copyCache[copy.id()];
590         this.copyTbody.removeChild(row);
591     }
592
593     this.saveCopyChanges = function(liId) {
594         var self = this;
595         var copies = [];
596
597         openils.Util.show('acq-lit-update-copies-progress');
598
599         for(var id in this.copyCache) {
600             var c = this.copyCache[id];
601             if(c.isnew() || c.ischanged() || c.isdeleted()) {
602                 if(c.id() < 0) c.id(null);
603                 copies.push(c);
604             }
605         }
606
607         if(copies.length == 0)
608             return;
609
610         fieldmapper.standardRequest(
611             ['open-ils.acq', 'open-ils.acq.lineitem_detail.cud.batch'],
612             {   async: true,
613                 params: [openils.User.authtoken, copies],
614                 onresponse: function(r) {
615                     var res = openils.Util.readResponse(r);
616                     litUpdateCopiesProgress.update(res);
617                 },
618                 oncomplete: function() {
619                     openils.Util.hide('acq-lit-update-copies-progress');
620                     self.drawCopies(liId); 
621                 }
622             }
623         );
624     }
625
626     this.applySelectedLiAction = function(action) {
627         var self = this;
628         switch(action) {
629
630             case 'delete_selected':
631                 this._deleteLiList(self.getSelected());
632                 break;
633
634             case 'create_order':
635
636                 if(!this.createPoProviderSelector) {
637                     var widget = new openils.widget.AutoFieldWidget({
638                         fmField : 'provider',
639                         fmClass : 'acqpo',
640                         parentNode : dojo.byId('acq-lit-po-provider'),
641                         orgLimitPerms : ['CREATE_PURCHASE_ORDER'],
642                     });
643                     widget.build(
644                         function(w) { self.createPoProviderSelector = w; }
645                     );
646                 }
647          
648                 acqLitPoCreateDialog.show();
649                 break;
650
651             case 'save_picklist':
652                 this._loadPLSelect();
653                 acqLitSavePlDialog.show();
654                 break;
655
656             case 'print_po':
657                 this.printPO();
658                 break;
659
660             case 'receive_po':
661                 this.receivePO();
662                 break;
663
664             case 'rollback_receive_po':
665                 this.rollbackPoReceive();
666                 break;
667
668             case 'create_assets':
669                 this.createAssets();
670                 break;
671         }
672     }
673
674     this.createAssets = function() {
675         if(!this.isPO) return;
676         if(!confirm(localeStrings.CREATE_PO_ASSETS_CONFIRM)) return;
677         this.show('acq-lit-progress-numbers');
678         var self = this;
679         fieldmapper.standardRequest(
680             ['open-ils.acq', 'open-ils.acq.purchase_order.assets.create'],
681             {   async: true,
682                 params: [this.authtoken, this.isPO],
683                 onresponse: function(r) {
684                     var resp = openils.Util.readResponse(r);
685                     self._updateProgressNumbers(resp, true);
686                 }
687             }
688         );
689     }
690
691     this.printPO = function() {
692         if(!this.isPO) return;
693         progressDialog.show(true);
694         fieldmapper.standardRequest(
695             ['open-ils.acq', 'open-ils.acq.purchase_order.format'],
696             {   async: true,
697                 params: [this.authtoken, this.isPO, 'html'],
698                 oncomplete: function(r) {
699                     progressDialog.hide();
700                     var evt = openils.Util.readResponse(r);
701                     if(evt && evt.template_output()) {
702                         win = window.open('','', 'resizable,width=800,height=600,scrollbars=1');
703                         win.document.body.innerHTML = evt.template_output().data();
704                     }
705                 }
706             }
707         );
708     }
709
710
711     this.receivePO = function() {
712         if(!this.isPO) return;
713         this.show('acq-lit-progress-numbers');
714         var self = this;
715         fieldmapper.standardRequest(
716             ['open-ils.acq', 'open-ils.acq.purchase_order.receive'],
717             {   async: true,
718                 params: [this.authtoken, this.isPO],
719                 onresponse : function(r) {
720                     var resp = openils.Util.readResponse(r);
721                     self._updateProgressNumbers(resp, true);
722                 },
723             }
724         );
725     }
726
727     this.receiveLi = function(li) {
728         if(!this.isPO) return;
729         progressDialog.show(true);
730         fieldmapper.standardRequest(
731             ['open-ils.acq', 'open-ils.acq.lineitem.receive'],
732             {   async: true,
733                 params: [this.authtoken, li.id()],
734                 onresponse : function(r) {
735                     var resp = openils.Util.readResponse(r);
736                     progressDialog.hide();
737                 },
738             }
739         );
740     }
741
742     this.receiveLid = function(li) {
743         if(!this.isPO) return;
744         progressDialog.show(true);
745         fieldmapper.standardRequest(
746             ['open-ils.acq', 'open-ils.acq.lineitem_detail.receive'],
747             {   async: true,
748                 params: [this.authtoken, li.id()],
749                 onresponse : function(r) {
750                     var resp = openils.Util.readResponse(r);
751                     progressDialog.hide();
752                 },
753             }
754         );
755     }
756
757     this.rollbackPoReceive = function() {
758         if(!this.isPO) return;
759         if(!confirm(localeStrings.ROLLBACK_PO_RECEIVE_CONFIRM)) return;
760         this.show('acq-lit-progress-numbers');
761         var self = this;
762         fieldmapper.standardRequest(
763             ['open-ils.acq', 'open-ils.acq.purchase_order.receive.rollback'],
764             {   async: true,
765                 params: [this.authtoken, this.isPO],
766                 onresponse : function(r) {
767                     var resp = openils.Util.readResponse(r);
768                     self._updateProgressNumbers(resp, true);
769                 },
770             }
771         );
772     }
773
774     this._updateProgressNumbers = function(resp, reloadOnComplete) {
775         if(!resp) return;
776         dojo.byId('acq-pl-lit-li-processed').innerHTML = resp.li;
777         dojo.byId('acq-pl-lit-lid-processed').innerHTML = resp.lid;
778         dojo.byId('acq-pl-lit-debits-processed').innerHTML = resp.debits_accrued;
779         dojo.byId('acq-pl-lit-bibs-processed').innerHTML = resp.bibs;
780         dojo.byId('acq-pl-lit-indexed-processed').innerHTML = resp.indexed;
781         dojo.byId('acq-pl-lit-copies-processed').innerHTML = resp.copies;
782         if(resp.complete && reloadOnComplete) 
783             location.href = location.href;
784     }
785
786
787     this._createPO = function(fields) {
788         this.show('acq-lit-progress-numbers');
789         var po = new fieldmapper.acqpo();
790         po.provider(this.createPoProviderSelector.attr('value'));
791
792         var selected = this.getSelected( (fields.create_from == 'all') );
793         if(selected.length == 0) return;
794
795         var max = selected.length * 3;
796
797         var self = this;
798         fieldmapper.standardRequest(
799             ['open-ils.acq', 'open-ils.acq.purchase_order.create'],
800             {   async: true,
801                 params: [
802                     openils.User.authtoken, 
803                     po, 
804                     {
805                         lineitems : selected.map(function(li) { return li.id() }),
806                         create_assets : fields.create_assets[0],
807                     }
808                 ],
809
810                 onresponse : function(r) {
811                     var resp = openils.Util.readResponse(r);
812                     self._updateProgressNumbers(resp);
813                     if(resp.complete) 
814                         location.href = oilsBasePath + '/eg/acq/po/view/' + resp.purchase_order.id();
815                 }
816             }
817         );
818     }
819
820     this._deleteLiList = function(list, idx) {
821         if(idx == null) idx = 0;
822         if(idx >= list.length) return;
823         var liId = list[idx].id();
824         fieldmapper.standardRequest(
825             ['open-ils.acq', 'open-ils.acq.lineitem.delete'],
826             {   async: true,
827                 params: [openils.User.authtoken, liId],
828                 oncomplete: function(r) {
829                     self.removeLineitem(liId);
830                     self._deleteLiList(list, ++idx);
831                 }
832             }
833         );
834     }
835
836     this.editOrderMarc = function(li) {
837
838         /*  To run in Firefox directly, must set signed.applets.codebase_principal_support
839             to true in about:config */
840
841         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
842         win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
843
844         var self = this;
845         win.xulG = {
846             record : {marc : li.marc()},
847             save : {
848                 label: 'Save Record', // XXX I18N
849                 func: function(xmlString) {
850                     li.marc(xmlString);
851                     fieldmapper.standardRequest(
852                         ['open-ils.acq', 'open-ils.acq.lineitem.update'],
853                         {   async: true,
854                             params: [openils.User.authtoken, li],
855                             oncomplete: function(r) {
856                                 openils.Util.readResponse(r);
857                                 win.close();
858                                 self.drawInfo(li.id())
859                             }
860                         }
861                     );
862                 },
863             }
864         };
865     }
866
867
868     this.editILSMarc = function(li) {
869
870         /*  To run in Firefox directly, must set signed.applets.codebase_principal_support
871             to true in about:config */
872
873         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
874         win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
875
876         var bib = new openils.PermaCrud().retrieve('bre', li.eg_bib_id());
877
878         var self = this;
879         win.xulG = {
880             record : {marc : li.marc()},
881             save : {
882                 label: 'Save Record', // XXX I18N
883                 func: function(xmlString) {
884                     bib.marc(xmlString);
885                     fieldmapper.standardRequest(
886                         ['open-ils.cat', 'open-ils.cat.biblio.record_entry.update'],
887                         {   async: true,
888                             params: [openils.User.authtoken, bib],
889                             oncomplete: function(r) {
890                                 openils.Util.readResponse(r);
891                                 win.close();
892                                 self.drawInfo(li.id())
893                             }
894                         }
895                     );
896                 },
897             }
898         };
899     }
900
901     this._savePl = function(values) {
902         var self = this;
903         var selected = this.getSelected( (values.which == 'all') );
904         openils.Util.show('acq-lit-generic-progress');
905
906         if(values.new_name) {
907             openils.acq.Picklist.create(
908                 {name: values.new_name}, 
909                 function(id) {
910                     self._updateLiList(id, selected, 0, 
911                         function(){
912                             location.href = oilsBasePath + '/eg/acq/picklist/view/' + id;
913                         });
914                 }
915             );
916         } else if(values.existing_pl) {
917             // update lineitems to use an existing picklist
918             self._updateLiList(values.existing_pl, selected, 0, 
919                 function(){
920                     location.href = oilsBasePath + '/eg/acq/picklist/view/' + values.existing_pl;
921                 });
922         }
923     }
924
925     this._updateLiList = function(pl, list, idx, oncomplete) {
926         if(idx >= list.length) return oncomplete();
927         var li = list[idx];
928         li.picklist(pl);
929         litGenericProgress.update({maximum: list.length, progress: idx});
930         new openils.acq.Lineitem({lineitem:li}).update(
931             function(r) {
932                 self._updateLiList(pl, list, ++idx, oncomplete);
933             }
934         );
935     }
936
937     this._loadPLSelect = function() {
938         if(this._plSelectLoaded) return;
939         var plList = [];
940         function handleResponse(r) {
941             plList.push(r.recv().content());
942         }
943         var method = 'open-ils.acq.picklist.user.retrieve';
944         fieldmapper.standardRequest(
945             ['open-ils.acq', method],
946             {   async: true,
947                 params: [this.authtoken],
948                 onresponse: handleResponse,
949                 oncomplete: function() {
950                     self._plSelectLoaded = true;
951                     acqLitAddExistingSelect.store = 
952                         new dojo.data.ItemFileReadStore({data:acqpl.toStoreData(plList)});
953                     acqLitAddExistingSelect.setValue();
954                 }
955             }
956         );
957     }
958 }
959
960
961