From 7965395c4c721b5b6aaa2e6138a35b13d5746eea Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 16 Nov 2009 23:09:12 +0000 Subject: [PATCH] Started porting the self-check web interface over to the new hotness that is dojo/template-toolkit. New features on the horizon (circ/fine/holds summary data, holds list, credit card payments, etc.). About half of the old functionality has been ported. Many TODO items in the code. stay tuned git-svn-id: svn://svn.open-ils.org/ILS/trunk@14930 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/web/css/skin/default/selfcheck.css | 81 +++++ .../js/ui/default/circ/selfcheck/selfcheck.js | 314 ++++++++++++++++++ .../default/circ/selfcheck/circ_page.tt2 | 50 +++ .../templates/default/circ/selfcheck/main.tt2 | 34 ++ .../default/circ/selfcheck/patron_login.tt2 | 7 + 5 files changed, 486 insertions(+) create mode 100644 Open-ILS/web/css/skin/default/selfcheck.css create mode 100644 Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js create mode 100644 Open-ILS/web/templates/default/circ/selfcheck/circ_page.tt2 create mode 100644 Open-ILS/web/templates/default/circ/selfcheck/main.tt2 create mode 100644 Open-ILS/web/templates/default/circ/selfcheck/patron_login.tt2 diff --git a/Open-ILS/web/css/skin/default/selfcheck.css b/Open-ILS/web/css/skin/default/selfcheck.css new file mode 100644 index 0000000000..a47dc6f016 --- /dev/null +++ b/Open-ILS/web/css/skin/default/selfcheck.css @@ -0,0 +1,81 @@ + +#oils-selfck-top-div { + width: 99%; + padding: 10px; + margin: 0px; + height: 180px; + border: 1px solid #888; + text-align: center; + font-weight:bold; +} + +#oils-selfck-user-banner { + position:fixed; + top:30px; + right:30px; +} + +#oils-selfck-logo-div { + margin: 20px; +} + +#oils-selfck-scan-text { + margin: 10px; +} + +#oils-selfck-bottom-div { + width: 100%; + padding: 10px; +} + +#oils-self-circ-pic-cell { + width: 43px; +} + +.oils-selfck-jacket { + height: 50px; + width: 40px; + border: none; +} + +#oils-selfck-circ-table { + width: 100%; +} + +#oils-selfck-circ-table thead { + font-weight: bold; +} + +#oils-selfck-circ-table-div { + width: 70%; + position: float; + float: left; + border-right: 1px solid #888; +} + +#oils-selfck-circ-info-div { + width: 28%; + float: right; +} + +#oils-selfck-circ-info-div fieldset { + margin: 20px; + padding: 10px; + border: 2px dashed #888; + -moz-border-radius: 3px; +} + +#oils-selfck-circ-info-div fieldset legend { + font-weight: bold; +} + + + +/* +#oils-selfck-main-table {width: 100%} +#oils-selfck-main-table td { + padding: 5px; + border: 1px solid #888; +} +#oils-selfck-main-table- td { +*/ diff --git a/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js b/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js new file mode 100644 index 0000000000..e9c6dd2a5d --- /dev/null +++ b/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js @@ -0,0 +1,314 @@ +dojo.require('openils.CGI'); +dojo.require('openils.Util'); +dojo.require('openils.User'); +dojo.require('openils.Event'); + +const SET_BARCODE_REGEX = 'opac.barcode_regex'; +const SET_PATRON_TIMEOUT = 'circ.selfcheck.patron_login_timeout'; +const SET_ALERT_ON_CHECKOUT_EVENT = 'circ.selfcheck.alert_on_checkout_event'; +const SET_AUTO_OVERRIDE_EVENTS = 'circ.selfcheck.auto_override_checkout_events'; +const SET_PATRON_PASSWORD_REQUIRED = 'circ.selfcheck.patron_password_required'; + +function SelfCheckManager() { + + this.cgi = new openils.CGI(); + this.staff = null; + this.workstation = null; + this.authtoken = null; + + this.patron = null; + this.patronBarcodeRegex = null; + + // current item barcode + this.itemBarcode = null; + + // are we currently performing a renewal? + this.isRenewal = false; + + // is a transaction pending? + this.pendingXact = false; + + // dict of org unit settings for "here" + this.orgSettings = {}; +} + +/** + * Fetch the org-unit settings, initialize the display, etc. + */ +SelfCheckManager.prototype.init = function() { + + this.staff = openils.User.user; + this.workstation = openils.User.workstation; + this.authtoken = openils.User.authtoken; + this.loadOrgSettings(); + + if(this.cgi.param('patron')) { + // Patron barcode via cgi param. Mainly used for debugging. + this.loginPatron(this.cgi.param('patron')); + } else { + this.drawLoginPage(); + } +} + +/** + * Loads the org unit settings + */ +SelfCheckManager.prototype.loadOrgSettings = function() { + + var settings = fieldmapper.aou.fetchOrgSettingBatch( + this.staff.ws_ou(), [ + SET_BARCODE_REGEX, + SET_PATRON_TIMEOUT, + SET_ALERT_ON_CHECKOUT_EVENT, + SET_AUTO_OVERRIDE_EVENTS, + ] + ); + + for(k in settings) { + if(settings[k]) + this.orgSettings[k] = settings[k].value; + } + + if(settings[SET_BARCODE_REGEX]) + this.patronBarcodeRegex = new RegExp(settings[SET_BARCODE_REGEX].value); +} + +SelfCheckManager.prototype.drawLoginPage = function() { + var self = this; + + var bcHandler = function(barcode) { + // handle patron barcode entry + + if(self.orgSettings[SET_PATRON_PASSWORD_REQUIRED]) { + + // password is required. wire up the scan box to read it + self.updateScanBox( + 'Please enter your password', // TODO i18n + false, + function(pw) { self.loginPatron(barcode, ps); } + ); + + dojo.connect(selfckScanBox, 'onKeyDown', pwHandler); + + } else { + // password is not required, go ahead and login + self.loginPatron(barcode); + } + }; + + this.updateScanBox( + 'Please log in with your library barcode.', // TODO + false, + bcHandler + ); +} + +/** + * Login the patron. + */ +SelfCheckManager.prototype.loginPatron = function(barcode, passwd) { + + if(this.orgSettings[SET_PATRON_PASSWORD_REQUIRED]) { + + // patron password is required. Verify it. + + var res = fieldmapper.standardRequest( + ['open-ils.actor', 'open-ils.actor.verify_user_password'], + {params : [this.authtoken, barcode, null, hex_md5(passwd)]} + ); + + if(res == 0) { + return alert('login failed'); // TODO + } + } + + // retrieve the fleshed user by barcode + this.patron = fieldmapper.standardRequest( + ['open-ils.actor', 'open-ils.actor.user.fleshed.retrieve_by_barcode'], + {params : [this.authtoken, barcode]} + ); + + var evt = openils.Event.parse(this.patron); + if(evt) { + + // User login failed, why? + + switch(evt.textcode) { + + case 'ACTOR_USER_NOT_FOUND': + return alert('user not found'); // TODO + + case 'NO_SESSION': + return alert('staff login timed out'); // TODO + + default: + return alert('unexpected patron login error occured: ' + evt.textcode); // TODO + } + } + + // patron login succeeded + dojo.byId('oils-selfck-user-banner').innerHTML = 'Welcome, ' + this.patron.usrname(); // TODO i18n + this.drawCircPage(); +} + + +/** + * Manages the main input box + * @param str The context message to display with the box + * @param clearOnly Don't update the context message, just clear the value and re-focus + * @param handler Optional "on-enter" handler. + */ +SelfCheckManager.prototype.updateScanBox = function(str, clearOnly, handler) { + + if(!clearOnly) + dojo.byId('oils-selfck-scan-text').innerHTML = str; + selfckScanBox.attr('value', ''); + selfckScanBox.focus(); + + if(handler) { + dojo.connect(selfckScanBox, 'onKeyDown', + function(e) { + if(e.keyCode != dojo.keys.ENTER) + return; + handler(selfckScanBox.attr('value')); + } + ); + } +} + +/** + * Sets up the checkout/renewal interface + */ +SelfCheckManager.prototype.drawCircPage = function() { + + var self = this; + this.updateScanBox( + 'Please enter an item barcode', // TODO i18n + false, + function(barcode) { self.checkout(barcode); } + ); + + openils.Util.show('oils-selfck-circ-page'); + + this.circTbody = dojo.byId('oils-selfck-circ-tbody'); + if(!this.circTemplate) + this.circTemplate = this.circTbody.removeChild(dojo.byId('oils-selfck-circ-row')); +} + + + +/** + * Check out a single item. If the item is already checked + * out to the patron, redirect to renew() + */ +SelfCheckManager.prototype.checkout = function(barcode, override) { + + if(!barcode) { + this.updateScanbox(null, true); + return; + } + + // TODO see if it's a patron barcode + // TODO see if this item has already been checked out in this session + + var method = 'open-ils.circ.checkout.full'; + if(override) method += '.override'; + + var result = fieldmapper.standardRequest( + ['open-ils.circ', 'open-ils.circ.checkout.full'], + {params: [ + this.authtoken, { + patron_id : this.patron.id(), + copy_barcode : barcode + } + ]} + ); + + + if(dojo.isArray(result)) { + // list of results. See if we can override all of them. + + } else { + var evt = openils.Event.parse(result); + + switch(evt.textcode) { + // standard result events + + case 'SUCCESS': + this.displayCheckout(evt); + break; + + case 'OPEN_CIRCULATION_EXISTS': + // TODO renewal + break; + + case 'NO_SESSION': + // TODO logout staff + break; + } + } + + console.log("Circ resulted in " + js2JSON(result)); +} + +/** + * Renew an item + */ +SelfCheckManager.prototype.renew = function() { +} + +/** + * Display the result of a checkout or renewal in the items out table + */ +SelfCheckManager.prototype.displayCheckout = function(evt) { + var copy = evt.payload.copy; + var record = evt.payload.record; + var circ = evt.payload.circ; + var row = this.circTemplate.cloneNode(true); + + /* + if(record.isbn()) { + var pic = $n(template, 'jacket'); + pic.setAttribute('src', '/opac/ac/jacket/small/' + cleanISBN(record.isbn())); + } + */ + + this.byName('barcode', row).innerHTML = copy.barcode(); + this.byName('title', row).innerHTML = record.title(); + this.byName('author', row).innerHTML = record.author(); + this.circTbody.appendChild(row); +} + + +SelfCheckManager.prototype.byName = function(node, name) { + return dojo.query('[name=' + name+']', node)[0]; +} + +/** + * Print a receipt + */ +SelfCheckManager.prototype.printReceipt = function() { +} + +/** + * Build the patron holds table + */ +SelfCheckManager.prototype.displayHolds = function() { +} + + +/** + * Logout the patron and return to the login page + */ +SelfCheckManager.prototype.logoutPatron = function() { +} + + +/** + * Fire up the manager on page load + */ +openils.Util.addOnLoad( + function() { + new SelfCheckManager().init(); + } +); diff --git a/Open-ILS/web/templates/default/circ/selfcheck/circ_page.tt2 b/Open-ILS/web/templates/default/circ/selfcheck/circ_page.tt2 new file mode 100644 index 0000000000..6461b1a906 --- /dev/null +++ b/Open-ILS/web/templates/default/circ/selfcheck/circ_page.tt2 @@ -0,0 +1,50 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + +
BarcodeTitleAuthorDue DateRenewal LeftType
+ Checkout + +
+
+ +
+
+ Items Checked Out +
+
Total items this session: FOO
+
Total items on account: BAR
+
+
+
+ Holds Ready for Pickup +
You have FOO items ready for pickup
+
For mor information, see Hold Details
+
+
+ Fines +
Total fines on account: $FOO
+
Pay fines with Credit Card
+
+
+ diff --git a/Open-ILS/web/templates/default/circ/selfcheck/main.tt2 b/Open-ILS/web/templates/default/circ/selfcheck/main.tt2 new file mode 100644 index 0000000000..1fd3596ef8 --- /dev/null +++ b/Open-ILS/web/templates/default/circ/selfcheck/main.tt2 @@ -0,0 +1,34 @@ +[% ctx.page_title = 'Self Checkout' %] +[% WRAPPER default/base.tt2 %] + + + +
+
+
+ +
+
+
+ Please log in with your library barcode. +
+ +
+
+
+ + + +
+ +[% END %] + + + diff --git a/Open-ILS/web/templates/default/circ/selfcheck/patron_login.tt2 b/Open-ILS/web/templates/default/circ/selfcheck/patron_login.tt2 new file mode 100644 index 0000000000..da65d791de --- /dev/null +++ b/Open-ILS/web/templates/default/circ/selfcheck/patron_login.tt2 @@ -0,0 +1,7 @@ +
Please login using your library barcode
+
+ +
+ -- 2.43.2