[open-ils-commits] r14930 - in trunk/Open-ILS/web: css/skin/default js/ui/default js/ui/default/circ js/ui/default/circ/selfcheck templates/default templates/default/circ templates/default/circ/selfcheck (erickson)

svn at svn.open-ils.org svn at svn.open-ils.org
Mon Nov 16 18:09:19 EST 2009


Author: erickson
Date: 2009-11-16 18:09:12 -0500 (Mon, 16 Nov 2009)
New Revision: 14930

Added:
   trunk/Open-ILS/web/css/skin/default/selfcheck.css
   trunk/Open-ILS/web/js/ui/default/circ/
   trunk/Open-ILS/web/js/ui/default/circ/selfcheck/
   trunk/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js
   trunk/Open-ILS/web/templates/default/circ/
   trunk/Open-ILS/web/templates/default/circ/selfcheck/
   trunk/Open-ILS/web/templates/default/circ/selfcheck/circ_page.tt2
   trunk/Open-ILS/web/templates/default/circ/selfcheck/main.tt2
   trunk/Open-ILS/web/templates/default/circ/selfcheck/patron_login.tt2
Log:

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



Added: trunk/Open-ILS/web/css/skin/default/selfcheck.css
===================================================================
--- trunk/Open-ILS/web/css/skin/default/selfcheck.css	                        (rev 0)
+++ trunk/Open-ILS/web/css/skin/default/selfcheck.css	2009-11-16 23:09:12 UTC (rev 14930)
@@ -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 {
+*/

Added: trunk/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js	                        (rev 0)
+++ trunk/Open-ILS/web/js/ui/default/circ/selfcheck/selfcheck.js	2009-11-16 23:09:12 UTC (rev 14930)
@@ -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();
+    }
+);

Added: trunk/Open-ILS/web/templates/default/circ/selfcheck/circ_page.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/circ/selfcheck/circ_page.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/circ/selfcheck/circ_page.tt2	2009-11-16 23:09:12 UTC (rev 14930)
@@ -0,0 +1,50 @@
+<div id='oils-selfck-circ-table-div'>
+    <table id='oils-selfck-circ-table'>
+        <thead>
+            <tr>
+                <td id='oils-self-circ-pic-cell'></td>
+                <td>Barcode</td>
+                <td>Title</td>
+                <td>Author</td>
+                <td>Due Date</td>
+                <td>Renewal Left</td>
+                <td>Type</td>
+            </tr>
+        </thead>
+        <tbody id='oils-selfck-circ-tbody'>
+            <tr id='oils-selfck-circ-row'>
+                <td><img class='oils-selfck-jacket' name='jacket'></img></td>
+                <td name='barcode'></td>
+                <td name='title'></td>
+                <td name='author'></td>
+                <td name='due_date'></td>
+                <td name='remaining'></td>
+                <td>
+                    <span name='cotype_co'>Checkout</span>
+                    <span name='cotype_rn' class='hidden'>Renewal</span>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+</div>
+
+<div id='oils-selfck-circ-info-div'>
+    <fieldset>
+        <legend>Items Checked Out</legend>
+        <div>
+            <div>Total items this session: FOO</div>
+            <div>Total items on account: BAR</div>
+        </div>
+    </fieldset>
+    <fieldset>
+        <legend>Holds Ready for Pickup</legend>
+        <div>You have FOO items ready for pickup</div>
+        <div>For mor information, see <a href='foo'>Hold Details</a></div>
+    </fieldset>
+    <fieldset>
+        <legend>Fines</legend>
+        <div>Total fines on account: $FOO</div>
+        <div>Pay fines with <a href='foo'>Credit Card</a></div>
+    </fieldset>
+</div>
+

Added: trunk/Open-ILS/web/templates/default/circ/selfcheck/main.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/circ/selfcheck/main.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/circ/selfcheck/main.tt2	2009-11-16 23:09:12 UTC (rev 14930)
@@ -0,0 +1,34 @@
+[% ctx.page_title = 'Self Checkout' %]
+[% WRAPPER default/base.tt2 %]
+<script src='[% ctx.media_prefix %]/js/ui/default/circ/selfcheck/selfcheck.js'> </script>
+<link rel='stylesheet' type='text/css' href='[% ctx.media_prefix %]/css/skin/[% ctx.skin %]/selfcheck.css'></link>
+
+<div id='oils-selfck-top-div'>
+    <div id='oils-selfck-user-banner'></div>
+    <div id='oils-selfck-logo-div'>
+        <img src='[% ctx.media_prefix %]/images/eg_logo.jpg'/>
+    </div>
+    <div id='oils-selfck-scan-div'>
+        <div id='oils-selfck-scan-text'>
+            Please log in with your library barcode.
+        </div>
+        <input jsId='selfckScanBox' dojoType='dijit.form.TextBox'></input>
+    </div>
+</div>
+<div id='oils-selfck-bottom-div'>
+    <div id='oils-selfck-circ-page' class='hidden'>
+        <!-- Checkout / renewal interface -->
+        [% INCLUDE 'default/circ/selfcheck/circ_page.tt2' %]
+    </div>
+    <div id='oils-selfck-holds-page' class='hidden'>
+        <!-- Patron holds interface -->
+    </div>
+    <div id='oils-selfck-payment-page' class='hidden'>
+        <!-- Credit Card payments interface -->
+    </div>
+</div>
+
+[% END %]
+
+
+

Added: trunk/Open-ILS/web/templates/default/circ/selfcheck/patron_login.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/circ/selfcheck/patron_login.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/circ/selfcheck/patron_login.tt2	2009-11-16 23:09:12 UTC (rev 14930)
@@ -0,0 +1,7 @@
+<div>Please login using your library barcode</div>
+<div class='oils-selfck-login-box'>
+    <input jsId='selfckBarcodeBox' dojoType='dijit.form.TextBox'></input>
+</div>
+<div id='oils-selfck-login-pw' class='hidden oils-selfck-login-box'>
+    <input jsId='selfckPwBox' dojoType='dijit.form.TextBox'></input>
+</div>



More information about the open-ils-commits mailing list