fb79a4cca178ce2cde314cf795d84e4400310f0f
[working/Evergreen.git] / Open-ILS / web / js / ui / default / opac / ebook_api / loggedin.js
1 /*
2  * variables defined in base_js.tt2:
3  *
4  * ou
5  * vendor_list = [ 'ebook_test' ]
6  * authtoken
7  * patron_id (barcode)
8  * myopac_page
9  * progress_icon (probably not done right)
10  *
11  * base_js.tt2 also "imports" dojo.cookie and a bunch of ebook_api JS
12  */
13
14 // Array of objects representing this patron's relationship with a specific vendor.
15 var relations = [];
16
17 // Transaction cache.
18 var xacts = {
19     checkouts: [],
20     holds_pending: [],
21     holds_ready: []
22 };
23
24 // Ebook to perform actions on.
25 var active_ebook;
26 if (typeof ebook_action.title_id !== 'undefined') {
27     active_ebook = new Ebook(ebook_action.vendor, ebook_action.title_id);
28 }
29
30 dojo.addOnLoad(function() {
31
32     dojo.forEach(vendor_list, function(v) {
33         var rel = new Relation(v, patron_id);
34         relations.push(rel);
35     });
36
37     // Pull patron transaction info from cache (cookie), if available.
38     // Otherwise, do a live lookup against all enabled vendors.
39     if (dojo.cookie('ebook_xact_cache')) {
40         getCachedTransactions();
41         addTotalsToPage();
42         addTransactionsToPage();
43     } else {
44         console.log('retrieving patron transaction info for all vendors');
45         dojo.forEach(relations, function(rel) {
46             checkSession(rel.vendor, function(ses) {
47                 rel.getTransactions( function(r) {
48                     addTransactionsToCache(r);
49                 });
50             });
51         });
52     }
53
54 });
55
56 // Update current page with cross-vendor transaction totals.
57 function addTotalsToPage() {
58     console.log('updating page with transaction totals');
59     updateDashboard();
60     updateMyAccountSummary();
61 }
62
63 // Update current page with detailed transaction info, where appropriate.
64 function addTransactionsToPage() {
65     if (myopac_page) {
66         console.log('updating page with cached transaction details, if applicable');
67         if (myopac_page === 'ebook_circs')
68             updateCheckoutView();
69         if (myopac_page === 'ebook_holds')
70             updateHoldView();
71         if (myopac_page === 'ebook_holds_ready')
72             updateHoldReadyView();
73     }
74 }
75         
76 function updateDashboard() {
77     console.log('updating dashboard');
78     var total_checkouts = (typeof xacts.checkouts === 'undefined') ? '-' : xacts.checkouts.length;
79     var total_holds_pending = (typeof xacts.holds_pending === 'undefined') ? '-' : xacts.holds_pending.length;
80     var total_holds_ready = (typeof xacts.holds_ready === 'undefined') ? '-' : xacts.holds_ready.length;
81     // update totals
82     dojo.byId('dash_e_checked').innerHTML = total_checkouts;
83     dojo.byId('dash_e_holds').innerHTML = total_holds_pending;
84     dojo.byId('dash_e_pickup').innerHTML = total_holds_ready;
85     // unhide ebook dashboard
86     dojo.removeClass('dashboard_e', "hidden");
87 }
88
89 function updateMyAccountSummary() {
90     if (myopac_page === 'main') {
91         console.log('updating account summary');
92         var total_checkouts = (typeof xacts.checkouts === 'undefined') ? '-' : xacts.checkouts.length;
93         var total_holds_pending = (typeof xacts.holds_pending === 'undefined') ? '-' : xacts.holds_pending.length;
94         var total_holds_ready = (typeof xacts.holds_ready === 'undefined') ? '-' : xacts.holds_ready.length;
95         // update totals
96         dojo.byId('acct_sum_ebook_circ_total').innerHTML = total_checkouts;
97         dojo.byId('acct_sum_ebook_hold_total').innerHTML = total_holds_pending;
98         dojo.byId('acct_sum_ebook_hold_ready_total').innerHTML = total_holds_ready;
99         // unhide display elements
100         dojo.removeClass('acct_sum_ebook_circs', "hidden");
101         dojo.removeClass('acct_sum_ebook_holds', "hidden");
102         dojo.removeClass('acct_sum_ebook_holds_ready', "hidden");
103     }
104 }
105
106 function updateCheckoutView() {
107     if (typeof ebook_action.type !== 'undefined') {
108         if (ebook_action.type == 'checkout') {
109             getReadyForCheckout();
110         }
111     } else if (xacts.checkouts.length < 1) {
112         dojo.removeClass('no_ebook_circs', "hidden");
113     } else {
114         dojo.forEach(xacts.checkouts, function(x) {
115             dojo.empty('ebook_circs_main_table_body');
116             var dl_link = '<a href="' + x.download_url + '">' + l_strings.download + '</a>';
117             var tr = dojo.create("tr", null, dojo.byId('ebook_circs_main_table_body'));
118             dojo.create("td", { innerHTML: x.title }, tr);
119             dojo.create("td", { innerHTML: x.author }, tr);
120             dojo.create("td", { innerHTML: x.due_date }, tr);
121             dojo.create("td", { innerHTML: dl_link}, tr);
122             // TODO: more actions (renew, checkin)
123         });
124         dojo.addClass('no_ebook_circs', "hidden");
125         dojo.removeClass('ebook_circs_main', "hidden");
126     }
127 }
128
129 function updateHoldView() {
130     var holds_pending = xacts.holds_pending;
131     var holds_ready = xacts.holds_ready;
132
133     // combine all holds into a single list, ready-for-checkout holds first
134     var holds = holds_ready.concat(holds_pending);
135
136     if (holds.length < 1) {
137         dojo.removeClass('no_ebook_holds', "hidden");
138     } else {
139         dojo.forEach(holds, function(h) {
140             var hold_status;
141             if (h.is_ready) {
142                 hold_status = l_strings.ready_for_checkout;
143             } else if (h.is_frozen) {
144                 hold_status = l_strings.suspended;
145             } else {
146                 hold_status = h.queue_position + ' / ' + h.queue_size;
147             }
148             dojo.empty('ebook_holds_main_table_body');
149             var tr = dojo.create("tr", null, dojo.byId('ebook_holds_main_table_body'));
150             dojo.create("td", { innerHTML: h.title }, tr);
151             dojo.create("td", { innerHTML: h.author }, tr);
152             dojo.create("td", { innerHTML: h.expire_date }, tr);
153             dojo.create("td", { innerHTML: hold_status }, tr);
154             dojo.create("td", null, tr); // TODO actions
155         });
156         dojo.addClass('no_ebook_holds', "hidden");
157         dojo.removeClass('ebook_holds_main', "hidden");
158     }
159 }
160
161 function updateHoldReadyView() {
162     var holds = xacts.holds_ready;
163     if (holds.length < 1) {
164         dojo.removeClass('no_ebook_holds', "hidden");
165     } else {
166         dojo.forEach(holds, function(h) {
167             dojo.empty('ebook_holds_main_table_body');
168             var tr = dojo.create("tr", null, dojo.byId('ebook_holds_main_table_body'));
169             dojo.create("td", { innerHTML: h.title }, tr);
170             dojo.create("td", { innerHTML: h.author }, tr);
171             dojo.create("td", { innerHTML: h.expire_date }, tr);
172             dojo.create("td", null, tr); // TODO actions
173         });
174         dojo.addClass('no_ebook_holds', "hidden");
175         dojo.removeClass('ebook_holds_main', "hidden");
176     }
177 }
178
179 // set up page for user to perform a checkout
180 function getReadyForCheckout() {
181     if (typeof active_ebook === 'undefined') {
182         console.log('No active ebook specified, cannot prepare for checkout');
183         dojo.removeClass('ebook_checkout_failed', "hidden");
184     } else {
185         active_ebook.getDetails( function(ebook) {
186             dojo.empty('ebook_circs_main_table_body');
187             var tr = dojo.create("tr", null, dojo.byId('ebook_circs_main_table_body'));
188             dojo.create("td", { innerHTML: ebook.title }, tr);
189             dojo.create("td", { innerHTML: ebook.author }, tr);
190             dojo.create("td", null, tr);
191             dojo.create("td", { id: "checkout-button-td" }, tr);
192             var button = dojo.create("input", { id: "checkout-button", type: "button", value: l_strings.checkout }, dojo.byId('checkout-button-td'));
193             ebook.conns.checkout = dojo.connect(button, 'onclick', "doCheckout");
194             dojo.removeClass('ebook_circs_main', "hidden");
195         });
196     }
197 }
198
199 // check out our active ebook
200 function doCheckout() {
201     active_ebook.checkout(authtoken, patron_id, function(resp) {
202         if (resp.due_date) {
203             console.log('Checkout succeeded!');
204             dojo.destroy('checkout-button');
205             dojo.removeClass('ebook_checkout_succeeded', "hidden");
206             // add our successful checkout to top of transaction cache
207             var new_xact = {
208                 title_id: active_ebook.id,
209                 title: active_ebook.title,
210                 author: active_ebook.author,
211                 due_date: resp.due_date,
212                 download_url: '' // TODO - for OverDrive, user must "lock in" a format first!
213             };
214             xacts.checkouts.unshift(new_xact);
215             // unset variables related to the transaction we have performed,
216             // to avoid any weirdness on page reload
217             ebook_action = {};
218             active_ebook = undefined;
219             // update page to account for successful checkout
220             addTotalsToPage();
221             addTransactionsToPage();
222             // clear transaction cache to force a refresh on next page load
223             dojo.cookie('ebook_xact_cache', '', {path: '/', expires: '-1h'});
224         } else {
225             console.log('Checkout failed: ' + resp.error_msg);
226             dojo.removeClass('ebook_checkout_failed', "hidden");
227         }
228         // When we switch to jQuery, we can use .one() instead of .on(),
229         // obviating the need for an explicit disconnect here.
230         dojo.disconnect(active_ebook.conns.checkout);
231     });
232 }
233
234 // deserialize transactions from cache, returning them as a JS object
235 function getCachedTransactions() {
236     console.log('retrieving cached transaction details');
237     var cache_obj;
238     var current_cache = dojo.cookie('ebook_xact_cache');
239     if (current_cache) {
240         cache_obj = JSON.parse(current_cache);
241         xacts.checkouts = cache_obj.checkouts;
242         xacts.holds_pending = cache_obj.holds_pending;
243         xacts.holds_ready = cache_obj.holds_ready;
244     }
245     return cache_obj;
246 }
247
248 // add a single vendor's transactions to transaction cache
249 function addTransactionsToCache(rel) {
250     console.log('updating transaction cache');
251     var v = rel.vendor;
252     var updated_xacts = {
253         checkouts: [],
254         holds_pending: [],
255         holds_ready: []
256     };
257     // preserve any transactions with other vendors
258     dojo.forEach(xacts.checkouts, function(xact) {
259         if (xact.vendor !== v)
260             updated_xacts.checkouts.push(xact);
261     });
262     dojo.forEach(xacts.holds_pending, function(xact) {
263         if (xact.vendor !== v)
264             updated_xacts.holds_pending.push(xact);
265     });
266     dojo.forEach(xacts.holds_ready, function(xact) {
267         if (xact.vendor !== v)
268             updated_xacts.holds_ready.push(xact);
269     });
270     // add transactions from current vendor
271     dojo.forEach(rel.checkouts, function(xact) {
272         updated_xacts.checkouts.push(xact);
273     });
274     dojo.forEach(rel.holds_pending, function(xact) {
275         updated_xacts.holds_pending.push(xact);
276     });
277     dojo.forEach(rel.holds_ready, function(xact) {
278         updated_xacts.holds_ready.push(xact);
279     });
280     // TODO sort transactions by date
281     // save transactions to cache
282     xacts = updated_xacts;
283     var new_cache = JSON.stringify(xacts);
284     dojo.cookie('ebook_xact_cache', new_cache, {path: '/'});
285     // update current page
286     addTotalsToPage();
287     addTransactionsToPage();
288 }
289