]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/ui/default/acq/common/li_table.js
wrap the ils-marc edit button in a perm
[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.price.set'],
311             {   async : true,
312                 params : [this.authtoken, li.id(), 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         if(li.eg_bib_id()) {
426             if(this.canEditILSMarc === true) {
427                 acqLitEditILSMarc.attr('disabled', false);
428             } else {
429                 if(this.canEditILSMarc === false) {
430                     acqLitEditILSMarc.attr('disabled', true);
431                 } else {
432                     var self = this;
433                     new openils.User().getPermOrgList('UPDATE_RECORD', 
434                         function(list) { 
435                             if(list.length > 0) {
436                                 self.canEditILSMarc = true;
437                                 acqLitEditILSMarc.attr('disabled', false);
438                             } else {
439                                 self.canEditILSMarc = false;
440                                 acqLitEditILSMarc.attr('disabled', true);
441                             }
442                         }
443                     );
444                 }
445             }
446         }
447     }
448
449     this.drawCopies = function(liId) {
450         this.show('copies');
451         var self = this;
452         this.copyCache = {};
453         this.copyWidgetCache = {};
454
455         acqLitSaveCopies.onClick = function() { self.saveCopyChanges(liId) };
456         acqLitBatchUpdateCopies.onClick = function() { self.batchCopyUpdate() };
457
458         while(this.copyTbody.childNodes[0])
459             this.copyTbody.removeChild(this.copyTbody.childNodes[0]);
460
461         this._drawBatchCopyWidgets();
462
463         this._fetchDistribFormulas(
464             function() {
465                 openils.acq.Lineitem.fetchAttrDefs(
466                     function() { 
467                         self._fetchLineitem(liId, function(li){self._drawCopies(li);}); 
468                     } 
469                 );
470             }
471         );
472     };
473
474     this._fetchDistribFormulas = function(onload) {
475         if(this.distribForms) {
476             onload();
477         } else {
478             var self = this;
479             fieldmapper.standardRequest(
480                 ['open-ils.acq', 'open-ils.acq.distribution_formula.ranged.retrieve.atomic'],
481                 {   async: true,
482                     params: [openils.User.authtoken],
483                     oncomplete: function(r) {
484                         self.distribForms = openils.Util.readResponse(r);
485                         self.distribFormulaStore = 
486                             new dojo.data.ItemFileReadStore(
487                                 {data:acqdf.toStoreData(self.distribForms)});
488                         onload();
489                     }
490                 }
491             );
492         }
493     }
494
495     this._drawBatchCopyWidgets = function() {
496         var row = this.copyBatchRow;
497         dojo.forEach(['fund', 'owning_lib', 'location', 'circ_modifier', 'cn_label'],
498             function(field) {
499                 if(self.copyBatchRowDrawn) {
500                     self.copyBatchWidgets[field].attr('value', null);
501                 } else {
502                     var widget = new openils.widget.AutoFieldWidget({
503                         fmField : field,
504                         fmClass : 'acqlid',
505                         parentNode : dojo.query('[name='+field+']', row)[0],
506                         orgLimitPerms : ['CREATE_PICKLIST'],
507                         dijitArgs : {required:false}
508                     });
509                     widget.build();
510                     self.copyBatchWidgets[field] = widget.widget;
511                 }
512             }
513         );
514         this.copyBatchRowDrawn = true;
515     };
516
517     this.batchCopyUpdate = function() {
518         var self = this;
519         var fields = ['fund', 'owning_lib', 'location', 'circ_modifier', 'cn_label'];
520         for(var k in this.copyWidgetCache) {
521             var cache = this.copyWidgetCache[k];
522             dojo.forEach(fields, function(f) {
523                 var newval = self.copyBatchWidgets[f].attr('value');
524                 if(newval) cache[f].attr('value', newval);
525             });
526         }
527     };
528
529     this._drawCopies = function(li) {
530         acqLitAddCopyCount.onClick = function() { 
531             var count = acqLitCopyCountInput.attr('value');
532             for(var i = 0; i < count; i++)
533                 self.addCopy(li); 
534         }
535         if(li.lineitem_details().length > 0) {
536             dojo.forEach(li.lineitem_details(),
537                 function(copy) {
538                     self.addCopy(li, copy);
539                 }
540             );
541         } else {
542             self.addCopy(li);
543         }
544     };
545
546     this.virtCopyId = -1;
547     this.addCopy = function(li, copy) {
548         var row = this.copyRow.cloneNode(true);
549         this.copyTbody.appendChild(row);
550         var self = this;
551
552         if(!copy) {
553             copy = new fieldmapper.acqlid();
554             copy.isnew(true);
555             copy.id(this.virtCopyId--);
556             copy.lineitem(li.id());
557         }
558
559         this.copyCache[copy.id()] = copy;
560         row.setAttribute('copy_id', copy.id());
561         self.copyWidgetCache[copy.id()] = {};
562
563         dojo.forEach(['fund', 'owning_lib', 'location', 'barcode', 'cn_label', 'circ_modifier', 'note'],
564             function(field) {
565                 var widget = new openils.widget.AutoFieldWidget({
566                     fmObject : copy,
567                     fmField : field,
568                     fmClass : 'acqlid',
569                     parentNode : dojo.query('[name='+field+']', row)[0],
570                     orgLimitPerms : ['CREATE_PICKLIST'],
571                     readOnly : self.isPO
572                 });
573                 widget.build(
574                     // make sure we capture the value from any async widgets
575                     function(w, ww) { copy[field](ww.getFormattedValue()) }
576                 );
577                 dojo.connect(widget.widget, 'onChange', 
578                     function(val) { 
579                         if(copy.isnew() || val != copy[field]()) {
580                             // prevent setting ischanged() automatically on widget load for existing copies
581                             copy[field](widget.getFormattedValue()) 
582                             copy.ischanged(true);
583                         }
584                     }
585                 );
586                 self.copyWidgetCache[copy.id()][field] = widget.widget;
587             }
588         );
589
590         var recv_link = dojo.query('[name=receive]', row)[0];
591         if(copy.recv_time()) {
592             openils.Util.hide(recv_link);
593         } else {
594             recv_link.onclick = function() {
595                 self.receiveLid(copy);
596                 openils.Util.hide(recv_link);
597             }
598         }
599
600         if(this.isPO) {
601             openils.Util.hide(dojo.query('[name=delete]', row)[0].parentNode);
602         } else {
603             dojo.query('[name=delete]', row)[0].onclick = 
604                 function() { self.deleteCopy(row) };
605         }
606     };
607
608     this.deleteCopy = function(row) {
609         var copy = this.copyCache[row.getAttribute('copy_id')];
610         copy.isdeleted(true);
611         if(copy.isnew())
612             delete this.copyCache[copy.id()];
613         this.copyTbody.removeChild(row);
614     }
615
616     this.saveCopyChanges = function(liId) {
617         var self = this;
618         var copies = [];
619
620         openils.Util.show('acq-lit-update-copies-progress');
621
622         for(var id in this.copyCache) {
623             var c = this.copyCache[id];
624             if(c.isnew() || c.ischanged() || c.isdeleted()) {
625                 if(c.id() < 0) c.id(null);
626                 copies.push(c);
627             }
628         }
629
630         if(copies.length == 0)
631             return;
632
633         fieldmapper.standardRequest(
634             ['open-ils.acq', 'open-ils.acq.lineitem_detail.cud.batch'],
635             {   async: true,
636                 params: [openils.User.authtoken, copies],
637                 onresponse: function(r) {
638                     var res = openils.Util.readResponse(r);
639                     litUpdateCopiesProgress.update(res);
640                 },
641                 oncomplete: function() {
642                     openils.Util.hide('acq-lit-update-copies-progress');
643                     self.drawCopies(liId); 
644                 }
645             }
646         );
647     }
648
649     this.applySelectedLiAction = function(action) {
650         var self = this;
651         switch(action) {
652
653             case 'delete_selected':
654                 this._deleteLiList(self.getSelected());
655                 break;
656
657             case 'create_order':
658
659                 if(!this.createPoProviderSelector) {
660                     var widget = new openils.widget.AutoFieldWidget({
661                         fmField : 'provider',
662                         fmClass : 'acqpo',
663                         parentNode : dojo.byId('acq-lit-po-provider'),
664                         orgLimitPerms : ['CREATE_PURCHASE_ORDER'],
665                     });
666                     widget.build(
667                         function(w) { self.createPoProviderSelector = w; }
668                     );
669                 }
670          
671                 acqLitPoCreateDialog.show();
672                 break;
673
674             case 'save_picklist':
675                 this._loadPLSelect();
676                 acqLitSavePlDialog.show();
677                 break;
678
679             case 'print_po':
680                 this.printPO();
681                 break;
682
683             case 'receive_po':
684                 this.receivePO();
685                 break;
686
687             case 'rollback_receive_po':
688                 this.rollbackPoReceive();
689                 break;
690
691             case 'create_assets':
692                 this.createAssets();
693                 break;
694         }
695     }
696
697     this.createAssets = function() {
698         if(!this.isPO) return;
699         if(!confirm(localeStrings.CREATE_PO_ASSETS_CONFIRM)) return;
700         this.show('acq-lit-progress-numbers');
701         var self = this;
702         fieldmapper.standardRequest(
703             ['open-ils.acq', 'open-ils.acq.purchase_order.assets.create'],
704             {   async: true,
705                 params: [this.authtoken, this.isPO],
706                 onresponse: function(r) {
707                     var resp = openils.Util.readResponse(r);
708                     self._updateProgressNumbers(resp, true);
709                 }
710             }
711         );
712     }
713
714     this.printPO = function() {
715         if(!this.isPO) return;
716         progressDialog.show(true);
717         fieldmapper.standardRequest(
718             ['open-ils.acq', 'open-ils.acq.purchase_order.format'],
719             {   async: true,
720                 params: [this.authtoken, this.isPO, 'html'],
721                 oncomplete: function(r) {
722                     progressDialog.hide();
723                     var evt = openils.Util.readResponse(r);
724                     if(evt && evt.template_output()) {
725                         win = window.open('','', 'resizable,width=800,height=600,scrollbars=1');
726                         win.document.body.innerHTML = evt.template_output().data();
727                     }
728                 }
729             }
730         );
731     }
732
733
734     this.receivePO = function() {
735         if(!this.isPO) return;
736         this.show('acq-lit-progress-numbers');
737         var self = this;
738         fieldmapper.standardRequest(
739             ['open-ils.acq', 'open-ils.acq.purchase_order.receive'],
740             {   async: true,
741                 params: [this.authtoken, this.isPO],
742                 onresponse : function(r) {
743                     var resp = openils.Util.readResponse(r);
744                     self._updateProgressNumbers(resp, true);
745                 },
746             }
747         );
748     }
749
750     this.receiveLi = function(li) {
751         if(!this.isPO) return;
752         progressDialog.show(true);
753         fieldmapper.standardRequest(
754             ['open-ils.acq', 'open-ils.acq.lineitem.receive'],
755             {   async: true,
756                 params: [this.authtoken, li.id()],
757                 onresponse : function(r) {
758                     var resp = openils.Util.readResponse(r);
759                     progressDialog.hide();
760                 },
761             }
762         );
763     }
764
765     this.receiveLid = function(li) {
766         if(!this.isPO) return;
767         progressDialog.show(true);
768         fieldmapper.standardRequest(
769             ['open-ils.acq', 'open-ils.acq.lineitem_detail.receive'],
770             {   async: true,
771                 params: [this.authtoken, li.id()],
772                 onresponse : function(r) {
773                     var resp = openils.Util.readResponse(r);
774                     progressDialog.hide();
775                 },
776             }
777         );
778     }
779
780     this.rollbackPoReceive = function() {
781         if(!this.isPO) return;
782         if(!confirm(localeStrings.ROLLBACK_PO_RECEIVE_CONFIRM)) return;
783         this.show('acq-lit-progress-numbers');
784         var self = this;
785         fieldmapper.standardRequest(
786             ['open-ils.acq', 'open-ils.acq.purchase_order.receive.rollback'],
787             {   async: true,
788                 params: [this.authtoken, this.isPO],
789                 onresponse : function(r) {
790                     var resp = openils.Util.readResponse(r);
791                     self._updateProgressNumbers(resp, true);
792                 },
793             }
794         );
795     }
796
797     this._updateProgressNumbers = function(resp, reloadOnComplete) {
798         if(!resp) return;
799         dojo.byId('acq-pl-lit-li-processed').innerHTML = resp.li;
800         dojo.byId('acq-pl-lit-lid-processed').innerHTML = resp.lid;
801         dojo.byId('acq-pl-lit-debits-processed').innerHTML = resp.debits_accrued;
802         dojo.byId('acq-pl-lit-bibs-processed').innerHTML = resp.bibs;
803         dojo.byId('acq-pl-lit-indexed-processed').innerHTML = resp.indexed;
804         dojo.byId('acq-pl-lit-copies-processed').innerHTML = resp.copies;
805         if(resp.complete && reloadOnComplete) 
806             location.href = location.href;
807     }
808
809
810     this._createPO = function(fields) {
811         this.show('acq-lit-progress-numbers');
812         var po = new fieldmapper.acqpo();
813         po.provider(this.createPoProviderSelector.attr('value'));
814
815         var selected = this.getSelected( (fields.create_from == 'all') );
816         if(selected.length == 0) return;
817
818         var max = selected.length * 3;
819
820         var self = this;
821         fieldmapper.standardRequest(
822             ['open-ils.acq', 'open-ils.acq.purchase_order.create'],
823             {   async: true,
824                 params: [
825                     openils.User.authtoken, 
826                     po, 
827                     {
828                         lineitems : selected.map(function(li) { return li.id() }),
829                         create_assets : fields.create_assets[0],
830                     }
831                 ],
832
833                 onresponse : function(r) {
834                     var resp = openils.Util.readResponse(r);
835                     self._updateProgressNumbers(resp);
836                     if(resp.complete) 
837                         location.href = oilsBasePath + '/eg/acq/po/view/' + resp.purchase_order.id();
838                 }
839             }
840         );
841     }
842
843     this._deleteLiList = function(list, idx) {
844         if(idx == null) idx = 0;
845         if(idx >= list.length) return;
846         var liId = list[idx].id();
847         fieldmapper.standardRequest(
848             ['open-ils.acq', 'open-ils.acq.lineitem.delete'],
849             {   async: true,
850                 params: [openils.User.authtoken, liId],
851                 oncomplete: function(r) {
852                     self.removeLineitem(liId);
853                     self._deleteLiList(list, ++idx);
854                 }
855             }
856         );
857     }
858
859     this.editOrderMarc = function(li) {
860
861         /*  To run in Firefox directly, must set signed.applets.codebase_principal_support
862             to true in about:config */
863
864         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
865         win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
866
867         var self = this;
868         win.xulG = {
869             record : {marc : li.marc()},
870             save : {
871                 label: 'Save Record', // XXX I18N
872                 func: function(xmlString) {
873                     li.marc(xmlString);
874                     fieldmapper.standardRequest(
875                         ['open-ils.acq', 'open-ils.acq.lineitem.update'],
876                         {   async: true,
877                             params: [openils.User.authtoken, li],
878                             oncomplete: function(r) {
879                                 openils.Util.readResponse(r);
880                                 win.close();
881                                 self.drawInfo(li.id())
882                             }
883                         }
884                     );
885                 },
886             }
887         };
888     }
889
890
891     this.editILSMarc = function(li) {
892
893         /*  To run in Firefox directly, must set signed.applets.codebase_principal_support
894             to true in about:config */
895
896         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
897         win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
898
899         var bib = new openils.PermaCrud().retrieve('bre', li.eg_bib_id());
900
901         var self = this;
902         win.xulG = {
903             record : {marc : li.marc()},
904             save : {
905                 label: 'Save Record', // XXX I18N
906                 func: function(xmlString) {
907                     bib.marc(xmlString);
908                     fieldmapper.standardRequest(
909                         ['open-ils.cat', 'open-ils.cat.biblio.record_entry.update'],
910                         {   async: true,
911                             params: [openils.User.authtoken, bib],
912                             oncomplete: function(r) {
913                                 openils.Util.readResponse(r);
914                                 win.close();
915                                 self.drawInfo(li.id())
916                             }
917                         }
918                     );
919                 },
920             }
921         };
922     }
923
924     this._savePl = function(values) {
925         var self = this;
926         var selected = this.getSelected( (values.which == 'all') );
927         openils.Util.show('acq-lit-generic-progress');
928
929         if(values.new_name) {
930             openils.acq.Picklist.create(
931                 {name: values.new_name}, 
932                 function(id) {
933                     self._updateLiList(id, selected, 0, 
934                         function(){
935                             location.href = oilsBasePath + '/eg/acq/picklist/view/' + id;
936                         });
937                 }
938             );
939         } else if(values.existing_pl) {
940             // update lineitems to use an existing picklist
941             self._updateLiList(values.existing_pl, selected, 0, 
942                 function(){
943                     location.href = oilsBasePath + '/eg/acq/picklist/view/' + values.existing_pl;
944                 });
945         }
946     }
947
948     this._updateLiList = function(pl, list, idx, oncomplete) {
949         if(idx >= list.length) return oncomplete();
950         var li = list[idx];
951         li.picklist(pl);
952         litGenericProgress.update({maximum: list.length, progress: idx});
953         new openils.acq.Lineitem({lineitem:li}).update(
954             function(r) {
955                 self._updateLiList(pl, list, ++idx, oncomplete);
956             }
957         );
958     }
959
960     this._loadPLSelect = function() {
961         if(this._plSelectLoaded) return;
962         var plList = [];
963         function handleResponse(r) {
964             plList.push(r.recv().content());
965         }
966         var method = 'open-ils.acq.picklist.user.retrieve';
967         fieldmapper.standardRequest(
968             ['open-ils.acq', method],
969             {   async: true,
970                 params: [this.authtoken],
971                 onresponse: handleResponse,
972                 oncomplete: function() {
973                     self._plSelectLoaded = true;
974                     acqLitAddExistingSelect.store = 
975                         new dojo.data.ItemFileReadStore({data:acqpl.toStoreData(plList)});
976                     acqLitAddExistingSelect.setValue();
977                 }
978             }
979         );
980     }
981 }
982
983
984