]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/booking/populator.js
Stab at matching up reservation.js with the pluralized, JSON-compliant Dojo NLS file
[working/Evergreen.git] / Open-ILS / web / js / ui / default / booking / populator.js
1 /* This module depends on common.js being loaded, as well as the
2  * localization (Dojo/nls) for pickup and return . */
3
4 dojo.require("dojo.data.ItemFileReadStore");
5
6 function Populator(widgets, primary_input) {
7     this.widgets = widgets;
8
9     this.all = [];
10     for (var k in widgets) this.all.push(k);
11
12     if (primary_input) this.primary_input = primary_input;
13
14     this.prepare_cache();
15     this.prepare_empty_stores();
16     this.reset();
17 }
18 Populator.prototype.prepare_cache = function(data) {
19     this.cache = {};
20     for (var k in this.all) this.cache[this.all[k]] = {};
21 };
22 Populator.prototype.prepare_empty_stores = function(data) {
23     this.empty_stores = {};
24
25     for (var i in this.all) {
26         var name = this.all[i];
27
28         if (this.widgets[name] && this["flatten_" + name]) {
29             this.empty_stores[name] =
30                 new dojo.data.ItemFileReadStore({
31                     "data": this["flatten_" + name]([])
32                 });
33             this.widgets[name].setStore(this.empty_stores[name]);
34         }
35     }
36 };
37 Populator.prototype.flatten_ready = function(data) {
38     return {
39         "label": "id",
40         "identifier": "id",
41         "items": data.map(function(o) {
42             return {
43                 "id": o.id(),
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())
48             };
49         })
50     };
51 };
52 Populator.prototype.flatten_out = function(data) {
53     return {
54         "label": "id",
55         "identifier": "id",
56         "items": data.map(function(o) {
57             return {
58                 "id": o.id(),
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())
63             };
64         })
65     };
66 };
67 Populator.prototype.flatten_in = function(data) {
68     return {
69         "label": "id",
70         "identifier": "id",
71         "items": data.map(function(o) {
72             return {
73                 "id": o.id(),
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())
78             };
79         })
80     };
81 };
82 Populator.prototype.reveal_container = function(widget) {
83     var el = document.getElementById("contains_" + widget.id);
84     if (el) reveal_dom_element(el);
85 };
86 Populator.prototype.hide_container = function(widget) {
87     var el = document.getElementById("contains_" + widget.id);
88     if (el) hide_dom_element(el);
89 };
90 Populator.prototype.populate_ready = function(data) {
91     return this._populate_any_resv_grid(data, "ready");
92 };
93 Populator.prototype.populate_out = function(data) {
94     return this._populate_any_resv_grid(data, "out");
95 };
96 Populator.prototype.populate_in = function(data) {
97     return this._populate_any_resv_grid(data, "in");
98 };
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];
104
105     this.reveal_container(widget);
106
107     if (!data || !data.length) {
108         widget.setStore(empty_store);
109         this.toggle_anyness(false, which);
110     } else {
111         for (var i in data) cache[data[i].id()] = data[i];
112
113         widget.setStore(
114             new dojo.data.ItemFileReadStore({"data": flattener(data)})
115         );
116
117         this.toggle_anyness(true, which);
118
119         /* Arrrgh! Horrid but necessary: */
120         setTimeout(function() { widget.sort(); }, 100);
121     }
122 };
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)));
127
128     this.widgets.patron.innerHTML = "";
129     this.widgets.patron.appendChild(h2);
130
131     this.reveal_container(this.widgets.patron);
132     /* Maybe add patron's home OU or something here later... */
133 };
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(
138         ["open-ils.booking",
139         "open-ils.booking.reservations.by_returnable_resource_barcode"],
140         [xulG.auth.session.key, barcode]
141     );
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));
146     } else {
147         try {
148             var new_barcode = r.usr().card().barcode();
149         } catch (E) {
150             alert(localeStrings.RETURN_ERROR + "\nr: " + js2JSON(r) + "\n" + E);
151             return;
152         }
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);
156         }
157         this.patron_barcode = new_barcode;
158         var ret = this.return(r);
159         if (!ret) {
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));
163         } else {
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.
167              */
168             alert(localeStrings.RETURN_SUCCESS);
169         }
170         this.populate(); /* Won't recurse with no args. All is well. */
171     }
172 };
173 Populator.prototype.populate = function(barcode, which) {
174     if (barcode) {
175         if (barcode.patron) {
176             this.patron_barcode = barcode.patron;
177         }
178         else if (barcode.resource) { /* resource OR patron, not both */
179             if (!this.return_by_resource(barcode.resource))
180                 return;
181         }
182     }
183     if (!this.patron_barcode) {
184         alert(localeStrings.NO_PATRON_BARCODE);
185         return;
186     }
187
188     if (!which) which = this.all;
189
190     var result = fieldmapper.standardRequest(
191         ["open-ils.booking", "open-ils.booking.reservations.get_captured"],
192         [xulG.auth.session.key, this.patron_barcode, which]
193     );
194
195     if (!result) {
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));
201     } else {
202         for (var k in result)
203             this["populate_" + k](result[k]);
204     }
205 };
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);
210     if (any) {
211         reveal_dom_element(widget);
212         if (empty_alternate) hide_dom_element(empty_alternate);
213         if (controls) reveal_dom_element(controls);
214     } else {
215         hide_dom_element(widget);
216         if (empty_alternate) reveal_dom_element(empty_alternate);
217         if (controls) hide_dom_element(controls);
218     }
219 };
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
226         }]
227     );
228 };
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 */
236         }]
237     );
238 };
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"];
244
245     var selected_id_list =
246         widget.selection.getSelected().map(function(o) { return o.id[0]; });
247
248     if (!selected_id_list || !selected_id_list.length) {
249         alert(localeStrings.SELECT_SOMETHING);
250         return;
251     }
252
253     var reservations = selected_id_list.map(function(o) { return cache[o]; });
254
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]);
258         if (!result) {
259             alert(no_response_msg);
260         } else if (is_ils_event(result) && result.textcode != "SUCCESS") {
261             alert(my_ils_error(error_msg, result));
262         } else {
263             continue;
264         }
265         break;
266     }
267
268     this.populate();
269 };
270 Populator.prototype.reset = function() {
271     for (var k in this.widgets) {
272         this.hide_container(this.widgets[k]);
273     }
274     this.patron_barcode = undefined;
275
276     if (typeof(this._extra_resetting) == "function")
277         this._extra_resetting();
278
279     if (this.primary_input) {
280         this.primary_input.value = "";
281         this.primary_input.focus();
282     }
283 };