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]
143 alert(localeStrings.NO_SUCH_RETURNABLE_RESOURCE);
144 } else if (is_ils_error(r)) {
145 alert(my_ils_error(localeStrings.RETURNABLE_RESOURCE_ERROR, r));
147 var new_barcode = r.usr().card().barcode();
148 if (this.patron_barcode && this.patron_barcode != new_barcode) {
149 /* XXX make this more subtle, i.e. flash something in background */
150 alert(localeStrings.NOTICE_CHANGE_OF_PATRON);
152 this.patron_barcode = new_barcode;
153 var ret = this.return(r);
155 alert(localeStrings.RETURN_NO_RESPONSE);
156 } else if (is_ils_error(ret)) {
157 alert(my_ils_error(localeStrings.RETURN_ERROR, ret));
159 /* XXX speedbump should go, but something has to happen else
160 * there's no indication to staff that anything happened when
161 * starting from a fresh (blank) return interface.
163 alert(localeStrings.RETURN_SUCCESS);
165 this.populate(); /* Won't recurse with no args. All is well. */
168 Populator.prototype.populate = function(barcode, which) {
170 if (barcode.patron) {
171 this.patron_barcode = barcode.patron;
173 else if (barcode.resource) { /* resource OR patron, not both */
174 if (!this.return_by_resource(barcode.resource))
178 if (!this.patron_barcode) {
179 alert(localeStrings.NO_PATRON_BARCODE);
183 if (!which) which = this.all;
185 var result = fieldmapper.standardRequest(
186 ["open-ils.booking", "open-ils.booking.reservations.get_captured"],
187 [xulG.auth.session.key, this.patron_barcode, which]
191 this.patron_barcode = undefined;
192 alert(localeStrings.RESERVATIONS_NO_RESPONSE);
193 } else if (is_ils_error(result)) {
194 this.patron_barcode = undefined;
195 alert(my_ils_error(localeStrings.RESERVATIONS_ERROR, result));
197 for (var k in result)
198 this["populate_" + k](result[k]);
201 Populator.prototype.toggle_anyness = function(any, which) {
202 var widget = this.widgets[which].domNode;
203 var empty_alternate = document.getElementById("no_" + widget.id);
204 var controls = document.getElementById("controls_" + widget.id);
206 reveal_dom_element(widget);
207 if (empty_alternate) hide_dom_element(empty_alternate);
208 if (controls) reveal_dom_element(controls);
210 hide_dom_element(widget);
211 if (empty_alternate) reveal_dom_element(empty_alternate);
212 if (controls) hide_dom_element(controls);
215 Populator.prototype.pickup = function(reservation) {
216 return fieldmapper.standardRequest(
217 ["open-ils.circ", "open-ils.circ.reservation.pickup"],
218 [xulG.auth.session.key, {
219 "patron_barcode": this.patron_barcode,
220 "reservation": reservation
224 Populator.prototype.return = function(reservation) {
225 return fieldmapper.standardRequest(
226 ["open-ils.circ", "open-ils.circ.reservation.return"],
227 [xulG.auth.session.key, {
228 "patron_barcode": this.patron_barcode,
229 "reservation": reservation.id()
230 /* yeah just id here ------^; lack of parallelism */
234 Populator.prototype.act_on_selected = function(how, which) {
235 var widget = this.widgets[which];
236 var cache = this.cache[which];
237 var no_response_msg = localeStrings[how.toUpperCase() + "_NO_RESPONSE"];
238 var error_msg = localeStrings[how.toUpperCase() + "_ERROR"];
240 var selected_id_list =
241 widget.selection.getSelected().map(function(o) { return o.id[0]; });
243 if (!selected_id_list || !selected_id_list.length) {
244 alert(localeStrings.SELECT_SOMETHING);
248 var reservations = selected_id_list.map(function(o) { return cache[o]; });
250 /* Do we have to process these one at a time? I think so... */
251 for (var i in reservations) {
252 var result = this[how](reservations[i]);
254 alert(no_response_msg);
255 } else if (is_ils_error(result)) {
256 alert(my_ils_error(error_msg, result));
265 Populator.prototype.reset = function() {
266 for (var k in this.widgets) {
267 this.hide_container(this.widgets[k]);
269 this.patron_barcode = undefined;
270 if (this.primary_input) {
271 this.primary_input.value = "";
272 this.primary_input.focus();