Booking: This should a) make booking interfaces behave better when a staff
[working/Evergreen.git] / Open-ILS / web / js / ui / default / booking / pull_list.js
1 dojo.require("openils.User");
2 dojo.require("openils.PermaCrud");
3 dojo.require("fieldmapper.OrgUtils");
4 dojo.require("openils.widget.OrgUnitFilteringSelect");
5 dojo.requireLocalization("openils.booking", "pull_list");
6
7 var localeStrings = dojo.i18n.getLocalization("openils.booking", "pull_list");
8 var pcrud = new openils.PermaCrud();
9
10 var owning_lib_selected;
11 var acp_cache = {};
12
13 function init_owning_lib_selector() {
14     var User = new openils.User();
15     User.buildPermOrgSelector(
16         "RETRIEVE_RESERVATION_PULL_LIST", owning_lib_selector, null,
17         function() {
18             owning_lib_selected = owning_lib_selector.getValue();
19             dojo.connect(owning_lib_selector, "onChange",
20                 function() { owning_lib_selected = this.getValue(); }
21             )
22         }
23     );
24 }
25
26 function retrieve_pull_list(ivl_in_days) {
27     var secs = Number(ivl_in_days) * 86400;
28
29     if (isNaN(secs) || secs < 1)
30         throw new Error("Invalid interval");
31
32     return fieldmapper.standardRequest(
33         ["open-ils.booking", "open-ils.booking.reservations.get_pull_list"],
34         [openils.User.authtoken, null, secs, owning_lib_selected]
35     );
36 }
37
38 function dom_table_rowid(resource_id) {
39     return "pull_list_resource_" + resource_id;
40 }
41
42 function generate_result_row(one) {
43     function cell(id, content) {
44         var td = document.createElement("td");
45         if (id != undefined) td.setAttribute("id", id);
46         td.appendChild(document.createTextNode(content));
47         return td;
48     }
49
50     function render_pickup_lib(pickup_lib) {
51         var span = document.createElement("span");
52         if (pickup_lib != owning_lib_selected)
53             span.setAttribute("class", "pull_list_will_transit");
54         span.innerHTML = localeStrings.AT + " " +
55             fieldmapper.aou.findOrgUnit(pickup_lib).shortname();
56         return span;
57     }
58
59     function reservation_info_cell(one) {
60         var td = document.createElement("td");
61         for (var i in one.reservations) {
62             var one_resv = one.reservations[i];
63             var div = document.createElement("div");
64             div.setAttribute("class", "pull_list_resv_detail");
65             var content = [
66                 document.createTextNode(
67                     humanize_timestamp_string(one_resv.start_time()) +
68                     " - " + humanize_timestamp_string(one_resv.end_time())
69                 ),
70                 document.createElement("br"),
71                 render_pickup_lib(one_resv.pickup_lib()),
72                 document.createTextNode(
73                     " " + localeStrings.FOR + " " + formal_name(one_resv.usr())
74                 )
75             ];
76             for (var k in content) { div.appendChild(content[k]); }
77             td.appendChild(div);
78         }
79         return td;
80     }
81
82     var baseid = dom_table_rowid(one.current_resource.id());
83
84     var cells = [];
85     cells.push(cell(undefined, one.target_resource_type.name()));
86     cells.push(cell(undefined, one.current_resource.barcode()));
87     cells.push(cell(baseid + "_call_number", "-"));
88     cells.push(cell(baseid + "_copy_location", "-"));
89     cells.push(reservation_info_cell(one));
90
91     var row = document.createElement("tr");
92     row.setAttribute("id", baseid);
93
94     for (var i in cells) row.appendChild(cells[i]);
95     return row;
96 }
97
98 function render_pull_list_fundamentals(list) {
99     var rows = [];
100
101     for (var i in list)
102         rows.push(generate_result_row(list[i]));
103
104     document.getElementById("the_table_body").innerHTML = "";
105
106     for (var i in rows)
107         document.getElementById("the_table_body").appendChild(rows[i]);
108 }
109
110 function get_all_relevant_acp(list) {
111     var barcodes = [];
112     for (var i in list) {
113         if (list[i].target_resource_type.catalog_item()) {
114             /* There shouldn't be any duplicates. No need to worry bout that */
115             barcodes.push(list[i].current_resource.barcode());
116         }
117     }
118     if (barcodes.length > 0) {
119         var results = fieldmapper.standardRequest(
120             [
121                 "open-ils.booking",
122                 "open-ils.booking.asset.get_copy_fleshed_just_right"
123             ],
124             [openils.User.authtoken, barcodes]
125         );
126
127         if (!results) {
128             alert(localeStrings.COPY_LOOKUP_NO_RESPONSE);
129             return null;
130         } else if (is_ils_event(results)) {
131             alert(my_ils_error(localeStrings.COPY_LOOKUP_ERROR, results));
132             return null;
133         } else {
134             return results;
135         }
136     }
137     return null;
138 }
139
140 function fill_in_pull_list_details(list, acp_cache) {
141     for (var i in list) {
142         var one = list[i];
143         if (one.target_resource_type.catalog_item() == "t") {
144             /* FIXME: This block could stand to be a lot more elegant. */
145             var call_number_el = document.getElementById(
146                 dom_table_rowid(one.current_resource.id()) + "_call_number"
147             );
148             var copy_location_el = document.getElementById(
149                 dom_table_rowid(one.current_resource.id()) + "_copy_location"
150             );
151             var bc = one.current_resource.barcode();
152
153             if (acp_cache[bc]) {
154                 if (call_number_el && acp_cache[bc].call_number()) {
155                     var value = acp_cache[bc].call_number().label();
156                     if (value) call_number_el.innerHTML = value;
157                 }
158                 if (copy_location_el && acp_cache[bc].location()) {
159                     var value = acp_cache[bc].location().name();
160                     if (value) copy_location_el.innerHTML = value;
161                 }
162             } else {
163                 alert(localeStrings.COPY_MISSING + bc);
164             }
165         }
166     }
167 }
168
169 function populate_pull_list(form) {
170     /* Step 1: get the pull list from the server. */
171     try {
172         var results = retrieve_pull_list(form.interval_in_days.value);
173     } catch (E) {
174         alert(localeStrings.PULL_LIST_ERROR + E);
175         return;
176     }
177     if (results == null) {
178         alert(localeStrings.PULL_LIST_NO_RESPONSE);
179         return;
180     } else if (is_ils_event(results)) {
181         alert(my_ils_error(localeStrings.PULL_LIST_ERROR, results));
182         return;
183     }
184
185     if (results.length) {
186         reveal_dom_element(document.getElementById("table_goes_here"));
187         hide_dom_element(document.getElementById("no_results"));
188
189         /* Step 2: render the table with the pull list */
190         render_pull_list_fundamentals(results);
191
192         /* Step 3: asynchronously fill in the copy details we're missing */
193         setTimeout(function() {
194             var acp_cache = {};
195             if ((acp_cache = get_all_relevant_acp(results)))
196                 fill_in_pull_list_details(results, acp_cache);
197         }, 0);
198     } else {
199         hide_dom_element(document.getElementById("table_goes_here"));
200         reveal_dom_element(document.getElementById("no_results"));
201     }
202
203 }
204
205 function my_init() {
206     hide_dom_element(document.getElementById("table_goes_here"));
207     hide_dom_element(document.getElementById("no_results"));
208     init_owning_lib_selector();
209     init_auto_l10n(document.getElementById("auto_l10n_start_here"));
210 }