1 dojo.require("dojo.string");
2 dojo.require('dijit.layout.ContentPane');
3 dojo.require('openils.PermaCrud');
5 var pcrud = new openils.PermaCrud();
10 var invoiceLinkDialogManager;
12 function AcqPoNoteTable() {
15 this.notesTbody = dojo.byId("acq-po-notes-tbody");
16 this.notesRow = this.notesTbody.removeChild(dojo.byId("acq-po-notes-row"));
18 dojo.byId("acq-po-notes-back-button").onclick = function() { self.hide(); };
19 dojo.byId("acq-po-view-notes").onclick = function() { self.show(); };
21 /* widgets' event properties are cased likeThis */
22 acqPoCreateNoteSubmit.onClick = function() {
23 if (!acqPoCreateNoteText.attr("value")) return;
26 var note = new acqpon();
28 Boolean(acqPoCreateNoteVendorPublic.attr('checked'))
30 note.value(acqPoCreateNoteText.attr("value"));
31 note.purchase_order(PO.id());
35 self.updatePoNotes(note);
37 /* reset fields for next use */
38 acqPoCreateNoteText.attr("value", "");
39 acqPoCreateNoteVendorPublic.attr("checked", false);
42 this.drawPoNote = function(note) {
46 var row = dojo.clone(this.notesRow);
48 nodeByName("value", row).innerHTML = note.value();
50 if (openils.Util.isTrue(note.vendor_public()))
51 nodeByName("vendor_public", row).innerHTML =
52 localeStrings.VENDOR_PUBLIC;
54 nodeByName("delete", row).onclick = function() {
56 self.notesTbody.removeChild(row);
60 if (note.edit_time()) {
61 nodeByName("edit_time", row).innerHTML =
62 dojo.date.locale.format(
63 dojo.date.stamp.fromISOString(note.edit_time()),
64 {"formatLength": "short"}
68 self.notesTbody.appendChild(row);
71 this.drawPoNotes = function() {
76 return (a.edit_time() < b.edit_time()) ? 1 : -1;
81 /* remove old renderings of notes */
82 dojo.empty(this.notesTbody);
84 PO.notes().forEach(function(o) { self.drawPoNote(o); });
87 this.updatePoNotesCount = function() {
88 dojo.byId("acq-po-view-notes").innerHTML =
89 "(" + PO.notes().length + ")";
92 this.updatePoNotes = function(newNote) {
97 if (o.ischanged() || o.isnew() || o.isdeleted())
102 if (notes.length < 1)
105 progressDialog.show();
107 fieldmapper.standardRequest(
108 ["open-ils.acq", "open-ils.acq.po_note.cud.batch"], {
110 "params": [openils.User.authtoken, notes],
111 "onresponse": function(r) {
112 var resp = openils.Util.readResponse(r);
114 progressDialog.update(resp);
116 if (!resp.note.isdeleted()) {
117 resp.note.isnew(false);
118 resp.note.ischanged(false);
119 PO.notes().push(resp.note);
123 "oncomplete": function() {
125 /* remove the old changed notes */
131 o.ischanged() || o.isnew() ||
139 progressDialog.hide();
140 self.updatePoNotesCount();
147 this.hide = function() {
148 openils.Util.hide("acq-po-notes-div");
149 liTable.show("list");
153 this.show = function() {
157 openils.Util.show("acq-po-notes-div");
161 function updatePoState(po_info) {
162 var data = po_info[PO.id()];
164 for (var key in data)
170 function cancellationUpdater(r) {
171 var r = openils.Util.readResponse(r);
173 if (r.po) updatePoState(r.po);
175 for (var id in r.li) {
176 liTable.liCache[id].state(r.li[id].state);
177 liTable.liCache[id].cancel_reason(r.li[id].cancel_reason);
178 liTable.updateLiState(liTable.liCache[id]);
181 if (r.lid && liTable.copyCache) {
182 for (var id in r.lid) {
183 if (liTable.copyCache[id]) {
184 liTable.copyCache[id].cancel_reason(
185 r.lid[id].cancel_reason
187 liTable.updateLidState(liTable.copyCache[id]);
194 function makeProviderLink(node, provider) {
197 "href": oilsBasePath + "/conify/global/acq/provider/" + provider.id(),
198 "innerHTML": provider.name() + " (" + provider.code() + ")",
204 function makePrepayWidget(node, prepay) {
206 openils.Util.addCSSClass(node, "oils-acq-po-prepay");
207 node.innerHTML = localeStrings.YES;
209 openils.Util.removeCSSClass(node, "oils-acq-po-prepay");
210 node.innerHTML = localeStrings.NO;
214 function makeCancelWidget(node, labelnode) {
215 openils.Util.hide("acq-po-choose-cancel-reason");
217 if (PO.cancel_reason()) {
218 labelnode.innerHTML = localeStrings.CANCEL_REASON;
219 node.innerHTML = PO.cancel_reason().description() + " (" +
220 PO.cancel_reason().label() + ")";
221 } else if (["on-order", "pending"].indexOf(PO.state()) == -1) {
222 dojo.destroy(this.oldTip);
223 labelnode.innerHTML = "";
226 dojo.destroy(this.oldTip);
227 labelnode.innerHTML = localeStrings.CANCEL;
229 if (!acqPoCancelReasonSubmit._prepared) {
230 var widget = new openils.widget.AutoFieldWidget({
231 "fmField": "cancel_reason",
233 "parentNode": dojo.byId("acq-po-cancel-reason"),
234 "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
239 acqPoCancelReasonSubmit.onClick = function() {
240 if (w.attr("value")) {
241 if (confirm(localeStrings.PO_CANCEL_CONFIRM)) {
242 fieldmapper.standardRequest(
244 "open-ils.acq.purchase_order.cancel"],
247 openils.User.authtoken,
252 "oncomplete": cancellationUpdater
258 acqPoCancelReasonSubmit._prepared = true;
262 openils.Util.show("acq-po-choose-cancel-reason", "inline");
266 function prepareInvoiceFeatures() {
267 /* show the count of related invoices on the "view invoices" button */
268 fieldmapper.standardRequest(
269 ["open-ils.acq", "open-ils.acq.invoice.unified_search.atomic"], {
271 openils.User.authtoken,
272 {"acqpo":[{"id": PO.id()}]},
278 "oncomplete": function(r) {
279 dojo.byId("acq-po-view-invoice-count").innerHTML =
280 openils.Util.readResponse(r).length;
285 /* view invoices button */
286 dijit.byId("acq-po-view-invoice-link").onClick = function() {
287 location.href = oilsBasePath + "/acq/search/unified?so=" +
288 base64Encode({"jub":[{"purchase_order": PO.id()}]}) +
292 /* create invoice button */
293 dijit.byId("acq-po-create-invoice-link").onClick = function() {
294 location.href = oilsBasePath +
295 "/acq/invoice/view?create=1&attach_po=" + PO.id();
298 openils.Util.show("acq-po-invoice-stuff", "table-cell");
301 function renderPo() {
302 dojo.byId("acq-po-view-id").innerHTML = PO.id();
303 dojo.byId("acq-po-view-name").innerHTML = PO.name();
305 dojo.byId("acq-po-view-provider"),
308 dojo.byId("acq-po-view-total-li").innerHTML = PO.lineitem_count();
309 dojo.byId("acq-po-view-total-enc").innerHTML = PO.amount_encumbered().toFixed(2);
310 dojo.byId("acq-po-view-total-spent").innerHTML = PO.amount_spent().toFixed(2);
311 dojo.byId("acq-po-view-state").innerHTML = PO.state(); // TODO i18n
313 if(PO.order_date()) {
314 openils.Util.show('acq-po-activated-on', 'inline');
315 dojo.byId('acq-po-activated-on').innerHTML =
316 dojo.string.substitute(
317 localeStrings.PO_ACTIVATED_ON, [
318 openils.Util.timeStamp(PO.order_date(), {formatLength:'short'})
325 dojo.byId("acq-po-view-prepay"),
326 openils.Util.isTrue(PO.prepayment_required())
329 dojo.byId("acq-po-view-cancel-reason"),
330 dojo.byId("acq-po-cancel-label")
332 // dojo.byId("acq-po-view-notes").innerHTML = PO.notes().length;
333 poNoteTable.updatePoNotesCount();
335 if (PO.state() == "pending") {
336 checkCouldActivatePo();
337 if (PO.lineitem_count() > 1)
338 openils.Util.show("acq-po-split");
340 dojo.byId("acq-po-activate-checking").innerHTML = localeStrings.NO;
343 // XXX we probably don't *always* need to do this...
345 PO.po_items().forEach(
346 function(po_item) { poItemTable.addItem(po_item); }
351 "acq-po-view-history", "href",
352 oilsBasePath + "/acq/po/history/" + PO.id()
354 openils.Util.show("acq-po-view-history", "inline");
356 prepareInvoiceFeatures();
361 /* set up li table */
362 liTable = new AcqLiTable();
365 liTable.poUpdateCallback = updatePoState;
367 /* set up po notes table */
368 poNoteTable = new AcqPoNoteTable();
370 /* retrieve data and populate */
371 fieldmapper.standardRequest(
372 ['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
374 params: [openils.User.authtoken, poId, {
375 "flesh_provider": true,
376 "flesh_price_summary": true,
377 "flesh_lineitem_count": true,
379 "flesh_po_items": true
381 oncomplete: function(r) {
382 PO = openils.Util.readResponse(r); /* save PO globally */
385 poItemTable = new PoItemTable(PO, pcrud);
392 var totalEstimated = 0;
394 fieldmapper.standardRequest(
395 ['open-ils.acq', 'open-ils.acq.lineitem.search'],
398 openils.User.authtoken,
399 [{purchase_order:poId}, {"order_by": {"jub": "id ASC"}}],
400 {flesh_attrs:true, flesh_notes:true, flesh_cancel_reason:true, clear_marc:true}
402 onresponse: function(r) {
404 liTable.show('list');
405 var li = openils.Util.readResponse(r);
406 // TODO: Add po_item's to total estimated amount
407 totalEstimated += (Number(li.item_count() || 0) * Number(li.estimated_unit_price() || 0));
408 liTable.addLineitem(li);
411 oncomplete : function() {
412 dojo.byId("acq-po-view-total-estimated").innerHTML = totalEstimated.toFixed(2);
413 if (liFocus) liTable.drawCopies(liFocus);
414 if(zeroLi) openils.Util.show('acq-po-no-lineitems');
421 {purchase_order : poId},
424 oncomplete : function(r) {
425 var resp = openils.Util.readResponse(r);
428 dojo.byId('acq-po-view-edi-messages').innerHTML = '(' + resp.length + ')';
429 dojo.byId('acq-po-view-edi-messages').setAttribute('href', oilsBasePath + '/acq/po/edi_messages/' + poId);
431 dojo.byId('acq-po-view-edi-messages').innerHTML = '0';
432 dojo.byId('acq-po-view-edi-messages').setAttribute('href', '');
439 function checkCouldActivatePo() {
440 var d = dojo.byId("acq-po-activate-checking");
441 var a = dojo.byId("acq-po-activate-link");
442 d.innerHTML = localeStrings.PO_CHECKING;
447 fieldmapper.standardRequest(
448 ["open-ils.acq", "open-ils.acq.purchase_order.activate.dry_run"], {
449 "params": [openils.User.authtoken, PO.id()],
451 "onresponse": function(r) {
452 if ((r = openils.Util.readResponse(r, true /* eventOk */))) {
453 if (typeof(r.textcode) != "undefined") {
455 case "ACQ_FUND_EXCEEDS_STOP_PERCENT":
458 case "ACQ_FUND_EXCEEDS_WARN_PERCENT":
467 "oncomplete": function() {
468 /* XXX in the future, this might be tweaked to display info
469 * about more than one stop or warning event from the ML. */
470 if (!(warnings.length || stops.length || other.length)) {
471 d.innerHTML = localeStrings.PO_COULD_ACTIVATE;
472 openils.Util.show(a, "inline");
475 /* XXX make the textcode part a tooltip one day */
476 d.innerHTML = localeStrings.NO + ": " +
477 other[0].desc + " (" + other[0].textcode + ")";
478 openils.Util.hide(a);
479 } else if (stops.length) {
481 dojo.string.substitute(
482 localeStrings.PO_STOP_BLOCKS_ACTIVATION, [
483 stops[0].payload.fund.code(),
484 stops[0].payload.fund.year()
487 openils.Util.hide(a);
489 PO._warning_hack = true;
491 dojo.string.substitute(
492 localeStrings.PO_WARNING_NO_BLOCK_ACTIVATION, [
493 warnings[0].payload.fund.code(),
494 warnings[0].payload.fund.year()
497 openils.Util.show(a, "inline");
505 function activatePo() {
506 if (openils.Util.isTrue(PO.prepayment_required())) {
507 if (!confirm(localeStrings.PREPAYMENT_REQUIRED_REMINDER))
511 if (PO._warning_hack) {
512 if (!confirm(localeStrings.PO_FUND_WARNING_CONFIRM))
516 liTable.showAssetCreator(activatePoStage2);
519 function activatePoStage2() {
521 var want_refresh = false;
522 progressDialog.show(true);
523 fieldmapper.standardRequest(
524 ["open-ils.acq", "open-ils.acq.purchase_order.activate"], {
526 "params": [openils.User.authtoken, PO.id()],
527 "onresponse": function(r) {
528 want_refresh = Boolean(openils.Util.readResponse(r));
530 "oncomplete": function() {
531 progressDialog.hide();
533 location.href = location.href;
540 progressDialog.show(true);
543 fieldmapper.standardRequest(
544 ['open-ils.acq', 'open-ils.acq.purchase_order.split_by_lineitems'],
546 params: [openils.User.authtoken, PO.id()],
547 onresponse : function(r) {
548 list = openils.Util.readResponse(r);
550 oncomplete : function() {
551 progressDialog.hide();
553 location.href = oilsBasePath + '/acq/po/search/' +
560 progressDialog.hide();
565 function updatePoName() {
566 var value = prompt('Enter new purchase order name:', PO.name()); // TODO i18n
567 if(!value || value == PO.name()) return;
570 oncomplete : function(r, cudResults) {
571 var stat = cudResults[0];
573 dojo.byId('acq-po-view-name').innerHTML = value;
578 openils.Util.addOnLoad(init);