1 /* This module depends on common.js being loaded, as well as the
2 * localization (Dojo/nls) for pickup and return . */
4 dojo.require("dojo.data.ItemFileReadStore");
6 function Populator(widgets, primary_input) {
7 this.widgets = widgets;
10 for (var k in widgets) this.all.push(k);
12 if (primary_input) this.primary_input = primary_input;
15 this.prepare_empty_stores();
18 Populator.prototype.prepare_cache = function(data) {
20 for (var k in this.all) this.cache[this.all[k]] = {};
22 Populator.prototype.prepare_empty_stores = function(data) {
23 this.empty_stores = {};
25 for (var i in this.all) {
26 var name = this.all[i];
28 if (this.widgets[name] && this["flatten_" + name]) {
29 this.empty_stores[name] =
30 new dojo.data.ItemFileReadStore({
31 "data": this["flatten_" + name]([])
33 this.widgets[name].setStore(this.empty_stores[name]);
37 Populator.prototype.flatten_ready = function(data) {
41 "items": data.map(function(o) {
44 "type": o.target_resource_type().name(),
45 "resource": o.current_resource().barcode(),
46 "start_time": humanize_timestamp_string(o.start_time()),
47 "end_time": humanize_timestamp_string(o.end_time())
52 Populator.prototype.flatten_out = function(data) {
56 "items": data.map(function(o) {
59 "type": o.target_resource_type().name(),
60 "resource": o.current_resource().barcode(),
61 "pickup_time": humanize_timestamp_string(o.pickup_time()),
62 "end_time": humanize_timestamp_string(o.end_time())
67 Populator.prototype.flatten_in = function(data) {
71 "items": data.map(function(o) {
74 "type": o.target_resource_type().name(),
75 "resource": o.current_resource().barcode(),
76 "due_time": humanize_timestamp_string(o.end_time()),
77 "return_time": humanize_timestamp_string(o.return_time())
82 Populator.prototype.reveal_container = function(widget) {
83 var el = document.getElementById("contains_" + widget.id);
84 if (el) reveal_dom_element(el);
86 Populator.prototype.hide_container = function(widget) {
87 var el = document.getElementById("contains_" + widget.id);
88 if (el) hide_dom_element(el);
90 Populator.prototype.populate_ready = function(data) {
91 return this._populate_any_resv_grid(data, "ready");
93 Populator.prototype.populate_out = function(data) {
94 return this._populate_any_resv_grid(data, "out");
96 Populator.prototype.populate_in = function(data) {
97 return this._populate_any_resv_grid(data, "in");
99 Populator.prototype._populate_any_resv_grid = function(data, which) {
100 var flattener = this["flatten_" + which];
101 var widget = this.widgets[which];
102 var cache = this.cache[which];
103 var empty_store = this.empty_stores[which];
105 this.reveal_container(widget);
107 if (!data || !data.length) {
108 widget.setStore(empty_store);
109 this.toggle_anyness(false, which);
111 for (var i in data) cache[data[i].id()] = data[i];
114 new dojo.data.ItemFileReadStore({"data": flattener(data)})
117 this.toggle_anyness(true, which);
119 /* Arrrgh! Horrid but necessary: */
120 setTimeout(function() { widget.sort(); }, 100);
123 Populator.prototype.populate_patron = function(data) {
124 var h2 = document.createElement("h2");
125 h2.setAttribute("class", "booking");
126 h2.appendChild(document.createTextNode(formal_name(data)));
128 this.widgets.patron.innerHTML = "";
129 this.widgets.patron.appendChild(h2);
131 this.reveal_container(this.widgets.patron);
132 /* Maybe add patron's home OU or something here later... */
134 Populator.prototype.return_by_resource = function(barcode) {
135 /* XXX instead of talking to the server every time we do this, we could
136 * also check the "out" cache, iff we have one. */
137 var r = fieldmapper.standardRequest(
139 "open-ils.booking.reservations.by_returnable_resource_barcode"],
140 [xulG.auth.session.key, barcode]
142 if (!r || r.length < 1) {
143 alert(localeStrings.NO_SUCH_RETURNABLE_RESOURCE);
144 } else if (is_ils_event(r)) {
145 alert(my_ils_error(localeStrings.RETURNABLE_RESOURCE_ERROR, r));
148 var new_barcode = r.usr().card().barcode();
150 alert(localeStrings.RETURN_ERROR + "\nr: " + js2JSON(r) + "\n" + E);
153 if (this.patron_barcode && this.patron_barcode != new_barcode) {
154 /* XXX make this more subtle, i.e. flash something in background */
155 alert(localeStrings.NOTICE_CHANGE_OF_PATRON);
157 this.patron_barcode = new_barcode;
158 var ret = this.return(r);
160 alert(localeStrings.RETURN_NO_RESPONSE);
161 } else if (is_ils_event(ret) && ret.textcode != "SUCCESS") {
162 alert(my_ils_error(localeStrings.RETURN_ERROR, ret));
164 /* XXX speedbump should go, but something has to happen else
165 * there's no indication to staff that anything happened when
166 * starting from a fresh (blank) return interface.
168 alert(localeStrings.RETURN_SUCCESS);
170 this.populate(); /* Won't recurse with no args. All is well. */
173 Populator.prototype.populate = function(barcode, which) {
175 if (barcode.patron) {
176 this.patron_barcode = barcode.patron;
178 else if (barcode.resource) { /* resource OR patron, not both */
179 if (!this.return_by_resource(barcode.resource))
183 if (!this.patron_barcode) {
184 alert(localeStrings.NO_PATRON_BARCODE);
188 if (!which) which = this.all;
190 var result = fieldmapper.standardRequest(
191 ["open-ils.booking", "open-ils.booking.reservations.get_captured"],
192 [xulG.auth.session.key, this.patron_barcode, which]
196 this.patron_barcode = undefined;
197 alert(localeStrings.RESERVATIONS_NO_RESPONSE);
198 } else if (is_ils_event(result)) {
199 this.patron_barcode = undefined;
200 alert(my_ils_error(localeStrings.RESERVATIONS_ERROR, result));
202 for (var k in result)
203 this["populate_" + k](result[k]);
206 Populator.prototype.toggle_anyness = function(any, which) {
207 var widget = this.widgets[which].domNode;
208 var empty_alternate = document.getElementById("no_" + widget.id);
209 var controls = document.getElementById("controls_" + widget.id);
211 reveal_dom_element(widget);
212 if (empty_alternate) hide_dom_element(empty_alternate);
213 if (controls) reveal_dom_element(controls);
215 hide_dom_element(widget);
216 if (empty_alternate) reveal_dom_element(empty_alternate);
217 if (controls) hide_dom_element(controls);
220 Populator.prototype.pickup = function(reservation) {
221 return fieldmapper.standardRequest(
222 ["open-ils.circ", "open-ils.circ.reservation.pickup"],
223 [xulG.auth.session.key, {
224 "patron_barcode": this.patron_barcode,
225 "reservation": reservation
229 Populator.prototype.return = function(reservation) {
230 return fieldmapper.standardRequest(
231 ["open-ils.circ", "open-ils.circ.reservation.return"],
232 [xulG.auth.session.key, {
233 "patron_barcode": this.patron_barcode,
234 "reservation": reservation.id()
235 /* yeah just id here ------^; lack of parallelism */
239 Populator.prototype.act_on_selected = function(how, which) {
240 var widget = this.widgets[which];
241 var cache = this.cache[which];
242 var no_response_msg = localeStrings[how.toUpperCase() + "_NO_RESPONSE"];
243 var error_msg = localeStrings[how.toUpperCase() + "_ERROR"];
245 var selected_id_list =
246 widget.selection.getSelected().map(function(o) { return o.id[0]; });
248 if (!selected_id_list || !selected_id_list.length) {
249 alert(localeStrings.SELECT_SOMETHING);
253 var reservations = selected_id_list.map(function(o) { return cache[o]; });
255 /* Do we have to process these one at a time? I think so... */
256 for (var i in reservations) {
257 var result = this[how](reservations[i]);
259 alert(no_response_msg);
260 } else if (is_ils_event(result) && result.textcode != "SUCCESS") {
261 alert(my_ils_error(error_msg, result));
270 Populator.prototype.reset = function() {
271 for (var k in this.widgets) {
272 this.hide_container(this.widgets[k]);
274 this.patron_barcode = undefined;
276 if (typeof(this._extra_resetting) == "function")
277 this._extra_resetting();
279 if (this.primary_input) {
280 this.primary_input.value = "";
281 this.primary_input.focus();