1 dojo.require('dijit.form.Form');
2 dojo.require('dijit.form.Button');
3 dojo.require('dijit.form.CheckBox');
4 dojo.require('dijit.form.FilteringSelect');
5 dojo.require('dijit.form.NumberTextBox');
6 dojo.require('dojo.data.ItemFileWriteStore');
7 dojo.require('dojo.date.locale');
8 dojo.require('dojo.date.stamp');
9 dojo.require('openils.User');
10 dojo.require('openils.Util');
11 dojo.require('openils.widget.AutoGrid');
12 dojo.require('openils.widget.AutoFieldWidget');
13 dojo.require('openils.PermaCrud');
17 var general_po_search_opts = {"order_by": {"acqpo": "edit_time DESC"}};
19 function getPOOwner(rowIndex, item) {
21 var data = this.grid.store.getValue(item, 'owner');
22 return new openils.User({id:data}).user.usrname();
25 function doSearch(fields) {
26 _last_fields = dojo.clone(fields); /* Save for re-use */
27 var metapo_view = false;
29 /* Remove the metapo_view field from 'fields'... we'll use it later */
30 if (fields.metapo_view && fields.metapo_view[0]) {
32 delete fields.metapo_view;
36 !(fields.id && fields.id.constructor.name == 'Array') &&
40 for(var k in fields) {
41 if(fields[k] == '' || fields[k] == null)
45 // ID search trumps other searches
46 fields = {id:fields.id};
51 for(var k in fields) some = true;
52 if(!some) fields.id = {'!=' : null};
56 openils.Util.hide("holds_po_grid");
59 if (metaPO) metaPO.myHide();
60 openils.Util.show("holds_po_grid");
62 poGrid.loadAll(general_po_search_opts, fields);
68 new openils.widget.AutoFieldWidget({
71 parentNode : dojo.byId('po-search-provider-selector'),
72 orgLimitPerms : ['VIEW_PURCHASE_ORDER'],
73 dijitArgs : {name:'provider', required:false}
76 new openils.widget.AutoFieldWidget({
78 fmField : 'ordering_agency',
79 parentNode : dojo.byId('po-search-agency-selector'),
80 orgLimitPerms : ['VIEW_PURCHASE_ORDER'],
81 dijitArgs : {name:'ordering_agency', required:false}
84 if (poIds && poIds.length > 0) {
85 dijit.byId("metapo_view").attr("checked", true);
86 doSearch({"id": poIds, "metapo_view": [true] /* [sic] */});
88 doSearch({"ordering_agency": openils.User.user.ws_ou()});
92 function loadMetaPO(fields) {
93 var pcrud = new openils.PermaCrud();
94 var po_list = pcrud.search("acqpo", fields, general_po_search_opts);
95 if (!po_list || !po_list.length) {
96 alert(localeStrings.NO_PO_RESULTS);
99 metaPO = new AcqLiTable();
100 metaPo.enableActionsDropdownOptions("po");
102 /* We need to know the width (in cells) of the template row for
103 * the LI table, and we don't want to hardcode it here. */
104 metaPO.n_cells = dojo.query("> td", metaPO.rowTemplate).length;
106 metaPO._copy_count_cb = function(liId, count) {
107 var poId = this.liCache[liId].purchase_order();
109 if (this.copy_counts[poId] == undefined)
110 this.copy_counts[poId] = {};
111 this.copy_counts[poId][liId] = count;
113 this.renderCopyCounts(poId);
114 this.renderSummary("copies");
116 metaPO.myHide = function() {
118 openils.Util.hide("oils-acq-holds-metapo-summary");
120 metaPO.renderSummary = function(part) {
122 /* The idea here will be that if "part" is defined, we'll
123 * just update that part of the metaPO summary, otherwise,
124 * the whole thing. */
125 if (part != undefined) {
126 var target = dojo.byId("oils-acq-metapo-summary-" + part);
129 target.innerHTML = self.copiesTotal();
132 target.innerHTML = self.working_po_list.length;
134 /* Any numeric fields should be named here. */
135 case "amount_encumbered":
137 target.innerHTML = self.numericFieldTotal(part);
140 /* assume a field on the acqpo's themselves */
141 target.innerHTML = self.anyFieldTotal(part);
145 openils.Util.show("oils-acq-holds-metapo-summary");
146 self.totalable_fields.forEach(
147 function(f) { self.renderSummary(f); }
151 metaPO.numericFieldTotal = function(field) {
153 var pennies = self.working_po_list.reduce(
154 /* working_po_list contains unfleshed acqpo's, so we must
155 * find the same PO in the poCache */
157 c = self.poCache[c.id()][field]();
158 return p + Number(c) * 100;
161 return pennies / 100;
163 metaPO.anyFieldTotal = function(field) {
165 return self.working_po_list.reduce(
166 /* working_po_list contains unfleshed acqpo's, so we must
167 * find the same PO in the poCache */
169 c = self.poCache[c.id()][field]();
170 return p + Number(c);
174 metaPO.renderCopyCounts = function(poId) {
176 dojo.query("td#oils-acq-po-heading-" + poId +
177 ' span span[attr="copies"]')[0].innerHTML =
178 this.copiesByPOId(poId);
183 metaPO.sectionHeadingById = function(id) {
184 var headings = dojo.query("#po-heading-" + id, this.tbody);
185 if (headings.length != 1) {
186 alert(localeStrings.PO_HEADING_ERROR);
192 metaPO.sectionHeadingByPOId = function(poId) {
193 return this.sectionHeadingById(this.sections_by_poid[poId]);
195 metaPO.addSection = function(po) {
196 var s = this.sections_by_poid[po.id()] = this.sections++;
198 this.tbody.appendChild(
200 "class": "acq-lit-po-heading", "id": "po-heading-" + s
206 metaPO.addLineitemToSection = function(li, section) {
208 this.addLineitem(li, true /* skip_final_placement */),
209 this.sectionHeadingById(section),
213 metaPO.generateActivator = function(id) {
215 progressDialog.show(true);
217 fieldmapper.standardRequest(
219 "open-ils.acq.purchase_order.activate"], {
221 "params": [openils.User.authtoken, id],
222 "oncomplete": function() {
223 progressDialog.hide();
224 doSearch(_last_fields);
229 progressDialog.hide();
234 metaPO.renderHeading = function(poId) {
236 var td = dojo.create("td", {"colspan": self.n_cells});
237 td.id = "oils-acq-po-heading-" + poId;
239 /* Build our HTML structure from the template... */
240 dojo.query("> span", "oils-acq-po-heading-template").forEach(
241 function(s) { td.appendChild(s.cloneNode(true)); }
244 /* Some fields straight from the PO object... */
245 self.po_fields_for_display.forEach(
247 dojo.query('[attr="' + f + '"]', td)[0].innerHTML =
248 self.poCache[poId][f]();
252 /* The name field needs special treatment: it's a link */
254 dojo.query('a[attr="name"]', td)[0],
256 oilsBasePath + '/acq/po/view/' + poId
259 /* Show an "activate" link, or not, based on "state"... */
260 var a = dojo.query('a[attr="activator"]', td)[0];
261 if (self.poCache[poId].state() == "pending") {
262 a.onclick = self.generateActivator(poId);
263 openils.Util.show(a, "inline");
265 openils.Util.hide(a);
268 /* Put the new heading cell in place... */
269 dojo.place(td, self.sectionHeadingByPOId(poId), "only");
271 /* And finally, render copy info (must happen _after_ heading
272 * is attached to the DOM tree */
273 this.renderCopyCounts(poId);
275 metaPO.copiesByPOId = function(poId) {
276 if (!this.copy_counts[poId]) return undefined;
278 for (var liId in this.copy_counts[poId]) {
279 total += this.copy_counts[poId][liId];
283 metaPO.copiesTotal = function() {
285 for (var poId in this.copy_counts)
286 total += this.copiesByPOId(poId);
289 metaPO.myReset = function() {
292 this.sections_by_poid = {};
293 this.copy_counts = {};
294 this.po_fields_for_display = [
295 "name", "lineitem_count", "amount_encumbered",
296 "amount_spent", "state"
298 this.totalable_fields = [
299 "po", "lineitem_count", "copies",
300 "amount_encumbered", "amount_spent"
302 openils.Util.hide("oils-acq-holds-metapo-summary");
304 metaPO.populate = function(list) {
308 self.working_po_list = [];
310 progressDialog.show(true);
311 list.forEach(function(po) {
312 var sec = self.addSection(po);
313 fieldmapper.standardRequest(
314 ["open-ils.acq", "open-ils.acq.lineitem.search"], {
317 openils.User.authtoken,
318 {"purchase_order": po.id()},
319 {"flesh_attrs": true, "flesh_notes": true}
321 "onresponse": function(r) {
322 var li = openils.Util.readResponse(r);
323 if (li) /* sometimes empty string: disregard */
324 self.addLineitemToSection(li, sec);
326 "oncomplete": function(r) {
327 self.working_po_list.push(po);
328 self.renderHeading(po.id());
329 self.renderSummary();
330 /* This mechanism avoids calling .show() too
331 * often or before results are ready, and
332 * thus smooths out DOM rendering glitches. */
333 if (++done >= list.length) {
336 progressDialog.hide();
342 /* This mechanism sees to it that we call .show() at least once
343 * even if the search result population seems to be timing
349 progressDialog.hide();
351 }, 10000 /* 10 seconds: make this configurable? */
358 metaPO.populate(po_list);
362 openils.Util.addOnLoad(loadForm);