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