[open-ils-commits] [GIT] Evergreen ILS branch master updated. 34b334fb49e57c72454820dd1a188991cb91d3cd

Evergreen Git git at git.evergreen-ils.org
Thu Feb 12 12:05:21 EST 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  34b334fb49e57c72454820dd1a188991cb91d3cd (commit)
       via  c67694794cad3fba07af81b3fadd5777c88d22b7 (commit)
       via  158d365bbad58df9783b7ec2338d5f462f2ab7fc (commit)
       via  75e466ec7beb7fa7a1af1eb2b430edaa492fc3dd (commit)
       via  8cc0b1c02681a4462313d4f2bdd1c7ab8c6d44e2 (commit)
       via  884a75ee4fdae2e7c8ce9a6cae2a2c7a98b7c3bf (commit)
       via  62497d71eaefa88809aee052b0ab7081fd7802bf (commit)
       via  f985e0d91d0591321d6e776e189657cb359c6fe6 (commit)
       via  87960a121a73aefa7bcad3bb6513a48596704483 (commit)
       via  c213d2fd4372004d7fc0307480b5751d774a8e6d (commit)
       via  dfb3810197c7138fde9292945ee56ab72afecb2e (commit)
       via  c9c44036eb7d640519e5b1ff638cccff3e9c5aac (commit)
       via  9a95b21d7dcd5e3cdf84e6c1f515863b98f7244b (commit)
       via  75ac833a0eecfa4dddec70ebd197fb683bdf9e8a (commit)
       via  27b3ee4e33c7b1c90325a019b04c1c96cc2f8773 (commit)
       via  0bc1a174b0ed23b34921b4b9ad66731a96202859 (commit)
       via  b481c74c0a2ad59fad2ad2e90d6d3957b9800c14 (commit)
       via  d37e4d0bbaa9292577e413f1cb4166222411123c (commit)
       via  bf5052ff0fe997d5c6b51ef196774952a68289ee (commit)
       via  7f6170bd1cca9fe41d7f6074e118231dda5e04e3 (commit)
       via  2c7d8eb5085e283d7e0e702e41053db58e5ef251 (commit)
       via  49c1dbc6f06a299ecbf1780f5b3439322f5b38aa (commit)
       via  09ed139f362b41a93da82afb8457dfa623ac8374 (commit)
       via  032944674c518d3fe99b9830f2ecdbbb71d559e3 (commit)
       via  c5670d423867fd13ca1e175bde954836b69e3b75 (commit)
       via  f577998f61a22c503b9c64865044d44f4d99a6dd (commit)
       via  8d4528d0c4495b7b68b699a37c5f2897015a48ff (commit)
       via  9133c6f3fd31eb66c580d53b39810215356b6207 (commit)
       via  ab2f8bd76707647800d9e860319eff10e676bf45 (commit)
       via  0cdb0e5a40f5fe3c78750e193369706467754d63 (commit)
       via  354ada2cf8af416d9634a09cc81922a5ca052f30 (commit)
       via  843d2a2ebdfc161ea5883bb0e420dbf9bb8fff42 (commit)
       via  0331e15f55c8c07a2188df66134402b746a28bb1 (commit)
       via  d14fc8865e68d8157956aed023a4cecc68b2dc90 (commit)
       via  ddf43665a6ad9050599d4cc63225b3d4b48231c5 (commit)
       via  93c8a2e347804b89b59d7feb311cf09574122c0e (commit)
       via  466345920c0f7fa7d3cbb2f97462cd84a05621ba (commit)
       via  e705bbe28430a26c9da76ea0edbde5fb6484256c (commit)
       via  21e13fdfb07d26dce0440815817d737313ffddf9 (commit)
       via  428a96c5292ea4b910fc6f58f8f8ca0006090c8b (commit)
       via  751688cb2dca5e313faed3131b02d2f3b80ac4e6 (commit)
       via  d2c2967141402219c589ef2a17c3de5379a944c5 (commit)
       via  6f7277e56ed56558483af7818f39939c10f1317c (commit)
       via  434f2de78ea8fb8470b7668ef4c76bc27dfe3288 (commit)
       via  df2c16dc63c16ee37e7beb938ae1f5eb85580ffc (commit)
      from  4ef6f4bcd58e87d452e3bf0f4f01020aec57078c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 34b334fb49e57c72454820dd1a188991cb91d3cd
Author: Mike Rylander <mrylander at gmail.com>
Date:   Fri Jan 30 13:04:42 2015 -0500

    LP#1402797 Check for a copy before trying to use it -- fixes non-cat checkout failure
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/circ.js b/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
index 29dec1e..27d8ed4 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
@@ -221,7 +221,7 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         data.hold = payload.hold;
         data.record = payload.record;
         data.acp = payload.copy;
-        data.acn = payload.volume ?  payload.volume : payload.copy.call_number();
+        data.acn = payload.volume ?  payload.volume : payload.copy ? payload.copy.call_number() : null;
         data.au = payload.patron;
         data.transit = payload.transit;
         data.status = payload.status;

commit c67694794cad3fba07af81b3fadd5777c88d22b7
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Dec 31 16:05:53 2014 -0500

    LP#1402797 browser client noncat circ display
    
    Adds a new tab to the patron items out page for Non-Cataloged
    Circulations.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
index 5c87466..ca3eef1 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
@@ -1,6 +1,6 @@
 <!-- items out list -->
 
-<div ng-if="show_alt_circs">
+<div>
   <!-- only show the main vs. alt circ list tabs if the alt
       circ list is meant to display -->
   <ul class="nav nav-tabs">
@@ -9,20 +9,40 @@
         [% l('Items Checked Out') %] ({{main_list.length}})
       </a>
     </li>
-    <li ng-class="{active : items_out_display == 'alt'}">
+    <li ng-if="show_alt_circs" ng-class="{active : items_out_display == 'alt'}">
       <a href ng-click="show_alt_list()">
         [% l('Other/Special Circulations') %] ({{alt_list.length}})
       </a>
     </li>
+    <li ng-class="{active : items_out_display == 'noncat'}">
+      <a href ng-click="show_noncat_list()">
+        [% l('Non-Cataloged Circulations') %] ({{noncat_list.length}})
+      </a>
+    </li>
   </ul>
 </div>
-<div ng-if="!show_alt_circs" class="strong-text-2">
-  [% l('Items Checked Out') %]
-</div>
 
 <div class="tab-content">
   <div class="tab-pane active">
+
+<eg-grid
+  ng-if="items_out_display == 'noncat'"
+  idl-class="ancc"
+  id-field="id"
+  features="-sort,-multisort"
+  items-provider="gridDataProvider"
+  persist-key="circ.patron.items_out.noncat">
+
+  <eg-grid-field label="[% l('Circ ID') %]" path='id'></eg-grid-field>
+  <eg-grid-field label="[% l('Item Type') %]" path='item_type.name'></eg-grid-field>
+  <eg-grid-field label="[% l('Checkout Library') %]" path='circ_lib.shortname'></eg-grid-field>
+  <eg-grid-field label="[% l('Checkout Date') %]" path='circ_time' dateformat='short'></eg-grid-field>
+  <eg-grid-field label="[% l('Due Date') %]" path='duedate' dateformat='short'></eg-grid-field>
+  <eg-grid-field label="[% l('Checkout Staff') %]" path='staff.usrname'></eg-grid-field>
+</eg-grid>
+
 <eg-grid
+  ng-if="items_out_display != 'noncat'"
   idl-class="circ"
   id-field="id"
   features="-sort,-multisort"
@@ -71,5 +91,7 @@
   <eg-grid-field path="target_copy.call_number.record.*" hidden></eg-grid-field>
   <eg-grid-field path="target_copy.call_number.record.simple_record.*" hidden></eg-grid-field>
 </eg-grid>
+</div>
+
   </div>
 </div>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
index 7558251..f8f4dd8 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
@@ -9,7 +9,16 @@ angular.module('egPatronApp')
         'egGridDataProvider','$modal','egCirc','egConfirmDialog','egBilling',
 function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc , 
          egGridDataProvider , $modal , egCirc , egConfirmDialog , egBilling) {
-    $scope.initTab('items_out', $routeParams.id);
+
+    // list of noncatatloged circulations. Define before initTab to 
+    // avoid any possibility of race condition, since they are loaded
+    // during init, but may be referenced before init completes.
+    $scope.noncat_list = [];
+
+    $scope.initTab('items_out', $routeParams.id).then(function() {
+        // sort inline to support paging
+        $scope.noncat_list = patronSvc.noncat_ids.sort();
+    });
 
     // cache of circ objects for grid display
     patronSvc.items_out = [];
@@ -60,6 +69,13 @@ function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc ,
         provider.refresh();
     }
 
+    $scope.show_noncat_list = function() {
+        // don't need a full reset_page() to swap tabs
+        $scope.items_out_display = 'noncat';
+        patronSvc.items_out = [];
+        provider.refresh();
+    }
+
     // Reload the user to pick up changes in items out, fines, etc.
     // Reload circs since the contents of the main vs. alt list may
     // have changed.
@@ -112,6 +128,35 @@ function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc ,
         });
     }
 
+    function fetch_noncat_circs(id_list, offset, count) {
+        if (!id_list.length) return $q.when();
+
+        return egCore.pcrud.search('ancc', {id : id_list},
+            {   flesh : 1,
+                flesh_fields : {ancc : ['item_type','staff']},
+                limit  : count,
+                offset : offset,
+                // we need an order-by to support paging
+                order_by : {circ : ['circ_time']} 
+
+        }).then(null, null, function(noncat_circ) {
+
+            // calculate the virtual due date from the item type duration
+            var seconds = egCore.date.intervalToSeconds(
+                noncat_circ.item_type().circ_duration());
+            var d = new Date(Date.parse(noncat_circ.circ_time()));
+            d.setSeconds(d.getSeconds() + seconds);
+            noncat_circ.duedate(d.toISOString());
+
+            // local flesh org unit
+            noncat_circ.circ_lib(egCore.org.get(noncat_circ.circ_lib()));
+
+            patronSvc.items_out.push(noncat_circ); // cache it
+            return noncat_circ;
+        });
+    }
+
+
     // decide which list each circ belongs to
     function promote_circs(list, display_code, open) {
         if (open) {                                                    
@@ -167,6 +212,11 @@ function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc ,
                 patronSvc.items_out, offset, count);
         }
 
+        if ($scope.items_out_display == 'noncat') {
+            // if there are any noncat circ IDs, we already have them
+            return fetch_noncat_circs(id_list, offset, count);
+        }
+
         // See if we have the circ IDs for this range already loaded.
         // this would happen navigating to a subsequent page.
         if (id_list[offset]) {

commit 158d365bbad58df9783b7ec2338d5f462f2ab7fc
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Dec 31 16:00:06 2014 -0500

    LP#1402797 browser client noncat counts in patron summary
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_summary.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_summary.tt2
index 1f09c77..8c803cf 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_summary.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_summary.tt2
@@ -81,6 +81,11 @@
       <div class="col-md-5">[% l('Lost') %]</div>
       <div class="col-md-7">{{patron_stats().checkouts.lost}}</div>
     </div>
+    <div class="row" 
+      ng-class="{'patron-summary-alert' : patron_stats().checkouts.lost}">
+      <div class="col-md-5">[% l('Non-Cataloged') %]</div>
+      <div class="col-md-7">{{patron_stats().checkouts.noncat}}</div>
+    </div>
     <div class="row">
       <div class="col-md-5">[% l('Holds') %]</div>
       <div class="col-md-7">
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index d8b373a..d3c0add 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -233,6 +233,7 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
         service.hold_ids = [];
         service.checkout_overrides = {};
         service.patron_stats = null;
+        service.noncat_ids = [];
         service.hasAlerts = false;
         service.alertsShown = false;
         service.patronExpired = false;
@@ -487,6 +488,18 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
         );
     }
 
+    // Fetches the IDs of any active non-cat checkouts for the current
+    // user.  Also sets the patron_stats non_cat count value to match.
+    service.getUserNonCats = function(id) {
+        return egCore.net.request(
+            'open-ils.circ',
+            'open-ils.circ.open_non_cataloged_circulation.user.authoritative',
+            egCore.auth.token(), id
+        ).then(function(noncat_ids) {
+            service.noncat_ids = noncat_ids;
+            service.patron_stats.checkouts.noncat = noncat_ids.length;
+        });
+    }
 
     // grab additional circ info
     service.fetchUserStats = function() {
@@ -508,7 +521,10 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
                 }
             );
 
-            return service.fetchGroupFines();
+            // run these two in parallel
+            var p1 = service.getUserNonCats(service.current.id());
+            var p2 = service.fetchGroupFines();
+            return $q.all([p1, p2]);
         });
     }
 

commit 75e466ec7beb7fa7a1af1eb2b430edaa492fc3dd
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Dec 31 15:28:48 2014 -0500

    LP#1402797 browser client interval parser
    
    Adds a new service on the core module for adding date handling
    utilities.  Included in this commit is a new function:
    
    egDate.intervalToSeconds(interval);
    
    Includes Gruntfile additions and unit tests.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/base_js.tt2 b/Open-ILS/src/templates/staff/base_js.tt2
index 76bc5a3..9cf9d69 100644
--- a/Open-ILS/src/templates/staff/base_js.tt2
+++ b/Open-ILS/src/templates/staff/base_js.tt2
@@ -30,6 +30,7 @@
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/navbar.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/statusbar.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/date.js"></script>
 
 [% ELSE %]
 
diff --git a/Open-ILS/web/js/ui/default/staff/Gruntfile.js b/Open-ILS/web/js/ui/default/staff/Gruntfile.js
index eb004dc..a3ba032 100644
--- a/Open-ILS/web/js/ui/default/staff/Gruntfile.js
+++ b/Open-ILS/web/js/ui/default/staff/Gruntfile.js
@@ -102,6 +102,7 @@ module.exports = function(grunt) {
             'services/navbar.js',
             'services/statusbar.js',
             'services/ui.js',
+            'services/date.js',
         ],
         dest: 'build/js/<%= pkg.name %>.<%= pkg.version %>.min.js'
       }
diff --git a/Open-ILS/web/js/ui/default/staff/services/coresvc.js b/Open-ILS/web/js/ui/default/staff/services/coresvc.js
index 6909978..de502cd 100644
--- a/Open-ILS/web/js/ui/default/staff/services/coresvc.js
+++ b/Open-ILS/web/js/ui/default/staff/services/coresvc.js
@@ -9,9 +9,9 @@ angular.module('egCoreMod')
 
 .factory('egCore', 
        ['egIDL','egNet','egEnv','egOrg','egPCRUD','egEvent','egAuth',
-        'egPerm','egHatch','egPrint','egStartup','egStrings',
+        'egPerm','egHatch','egPrint','egStartup','egStrings','egDate',
 function(egIDL , egNet , egEnv , egOrg , egPCRUD , egEvent , egAuth , 
-         egPerm , egHatch , egPrint , egStartup , egStrings) {
+         egPerm , egHatch , egPrint , egStartup , egStrings , egDate) {
 
     return {
         idl     : egIDL,
@@ -25,7 +25,8 @@ function(egIDL , egNet , egEnv , egOrg , egPCRUD , egEvent , egAuth ,
         hatch   : egHatch,
         print   : egPrint,
         startup : egStartup,
-        strings : egStrings
+        strings : egStrings,
+        date    : egDate
     };
 
 }]);
diff --git a/Open-ILS/web/js/ui/default/staff/services/date.js b/Open-ILS/web/js/ui/default/staff/services/date.js
new file mode 100644
index 0000000..629b799
--- /dev/null
+++ b/Open-ILS/web/js/ui/default/staff/services/date.js
@@ -0,0 +1,61 @@
+/**
+ * Core Service - egDate
+ *
+ * Date utility functions.
+ *
+ */
+angular.module('egCoreMod')
+
+.factory('egDate', function() {
+
+    var service = {};
+
+    /**
+     * Converts an interval string to seconds.
+     *
+     * egDate.intervalToSeconds('1 min 2 seconds')) => 62
+     * egDate.intervalToSeconds('2 days')) => 172800
+     * egDate.intervalToSeconds('02:00:23')) => 7223
+     */
+    service.intervalToSeconds = function(interval) {
+        var d = new Date();
+        var start = d.getTime();
+        var parts = interval.split(' ');
+
+        for(var i = 0; i < parts.length; i += 2)  {
+
+            if (!parts[i+1]) {
+                // interval is a bare hour:min:sec string
+                var times = parts[i].split(':');
+                d.setHours(d.getHours() + Number(times[0]));
+                d.setMinutes(d.getMinutes() + Number(times[1]));
+                d.setSeconds(d.getSeconds() + Number(times[2]));
+                continue;
+            }
+
+            var count = Number(parts[i]);
+            var type = parts[i+1].replace(/s?,?$/,'');
+
+            if (type.match(/^s/)) {
+                d.setSeconds(d.getSeconds() + count);
+            } else if (type.match(/^min/)) {
+                d.setMinutes(d.getMinutes() + count);
+            } else if (type.match(/^h/)) {
+                d.setHours(d.getHours() + count);
+            } else if (type.match(/^d/)) {
+                d.setDate(d.getDate() + count);
+            } else if (type.match(/^mon/)) {
+                d.setMonth(d.getMonth() + count);
+            } else if (type.match(/^y/)) {
+                d.setFullYear(d.getFullYear() + count);
+            }
+        }
+
+        return Number((d.getTime() - start) / 1000);
+    }
+
+    return service;
+})
+
+
+
diff --git a/Open-ILS/web/js/ui/default/staff/test/karma.conf.js b/Open-ILS/web/js/ui/default/staff/test/karma.conf.js
index a27ca66..5b9a272 100644
--- a/Open-ILS/web/js/ui/default/staff/test/karma.conf.js
+++ b/Open-ILS/web/js/ui/default/staff/test/karma.conf.js
@@ -40,6 +40,7 @@ module.exports = function(config){
       'services/statusbar.js',
       'services/grid.js',
       'services/navbar.js',
+      'services/date.js',
       // load app scripts
       'app.js',
       'circ/**/*.js',
diff --git a/Open-ILS/web/js/ui/default/staff/test/unit/egDate.js b/Open-ILS/web/js/ui/default/staff/test/unit/egDate.js
new file mode 100644
index 0000000..f55fe9f
--- /dev/null
+++ b/Open-ILS/web/js/ui/default/staff/test/unit/egDate.js
@@ -0,0 +1,18 @@
+'use strict';
+
+describe('egDate', function(){
+    beforeEach(module('egCoreMod'));
+
+    it('should parse a simple interval', inject(function(egDate) {
+        expect(egDate.intervalToSeconds('2 days')).toBe(172800);
+    }));
+
+    it('should parse a combined interval', inject(function(egDate) {
+        expect(egDate.intervalToSeconds('1 min 2 seconds')).toBe(62);
+    }));
+
+    it('should parse a time interval', inject(function(egDate) {
+        expect(egDate.intervalToSeconds('02:00:23')).toBe(7223);
+    }));
+
+});

commit 8cc0b1c02681a4462313d4f2bdd1c7ab8c6d44e2
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Dec 31 15:26:03 2014 -0500

    LP#1402797 PCRUD access for noncat circs in IDL
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 87a0604..273512f 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -6692,7 +6692,7 @@ SELECT  usr,
             </actions>
         </permacrud>
 	</class>
-	<class id="ancc" controller="open-ils.cstore" oils_obj:fieldmapper="action::non_cataloged_circulation" oils_persist:tablename="action.non_cataloged_circulation" reporter:core="true" reporter:label="Non-cataloged Circulation">
+	<class id="ancc" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="action::non_cataloged_circulation" oils_persist:tablename="action.non_cataloged_circulation" reporter:core="true" reporter:label="Non-cataloged Circulation">
 		<fields oils_persist:primary="id" oils_persist:sequence="action.non_cataloged_circulation_id_seq">
 			<field reporter:label="Circulating Library" name="circ_lib"  reporter:datatype="org_unit"/>
 			<field reporter:label="Circulation Date/Time" name="circ_time" reporter:datatype="timestamp"/>
@@ -6708,6 +6708,11 @@ SELECT  usr,
 			<link field="patron" reltype="has_a" key="id" map="" class="au"/>
 			<link field="circ_lib" reltype="has_a" key="id" map="" class="aou"/>
 		</links>
+		<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+			<actions>
+				<retrieve permission="VIEW_CIRCULATIONS" context_field="circ_lib" />
+			</actions>
+		</permacrud>
 	</class>
 	<class id="moucs" controller="open-ils.cstore" oils_obj:fieldmapper="money::open_user_circulation_summary" oils_persist:tablename="money.open_usr_circulation_summary" reporter:label="Open User Circulation Summary">
 		<fields oils_persist:primary="usr" oils_persist:sequence="">

commit 884a75ee4fdae2e7c8ce9a6cae2a2c7a98b7c3bf
Author: Bill Erickson <berickxx at gmail.com>
Date:   Fri Jan 2 11:21:43 2015 -0500

    LP#1402797 patron search form focus repairs cont.
    
    Building on Mike's original work, use Angular ng-mouseover and the
    Angular $document built-in.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_search.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_search.tt2
index b2034f9..bc4e92a 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_search.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_search.tt2
@@ -26,23 +26,23 @@
             ng-model="searchArgs.second_given_name" placeholder="[% l('Middle Name') %]"/>
         </div>
 
-        <div class="col-md-2" onmouseover="window.prevElement=document.activeElement">
+        <div class="col-md-2" ng-mouseover="setLastFormElement()">
           <input type="submit" class="btn btn-default" value="[% l('Search') %]"/>
         </div>
 
-        <div class="col-md-2" onmouseover="window.prevElement=document.activeElement">
+        <div class="col-md-2" ng-mouseover="setLastFormElement()">
           <input type="reset" class="btn btn-default" ng-click="clearForm()" 
             value="[% l('Clear Form') %]"/>
         </div>
 
         <div class="col-md-2">
           <button class="btn btn-default" ng-click="applyShowExtras($event, true)" 
-            onmouseover="window.prevElement=document.activeElement"
+            ng-mouseover="setLastFormElement()"
             title="[% l('Show More Fields') %]" ng-show="!showExtras">
             <span class="glyphicon glyphicon-circle-arrow-down"></span>
           </button>
           <button class="btn btn-default" ng-click="applyShowExtras($event, false)" 
-            onmouseover="window.prevElement=document.activeElement"
+            ng-mouseover="setLastFormElement()"
             title="[% l('Show Fewer Fields') %]" ng-show="showExtras">
             <span class="glyphicon glyphicon-circle-arrow-up"></span>
           </button>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index 3ce36c5..d8b373a 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -716,9 +716,9 @@ function($scope , $location , egCore , egConfirmDialog , egUser , patronSvc) {
  */
 .controller('PatronSearchCtrl',
        ['$scope','$q','$routeParams','$timeout','$window','$location','egCore',
-       '$filter','egUser', 'patronSvc','egGridDataProvider',
+       '$filter','egUser', 'patronSvc','egGridDataProvider','$document',
 function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore,
-        $filter,  egUser,  patronSvc , egGridDataProvider) {
+        $filter,  egUser,  patronSvc , egGridDataProvider , $document) {
 
     $scope.initTab('search');
     $scope.focusMe = true;
@@ -727,6 +727,9 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore,
         home_ou : egCore.org.tree()
     };
 
+    // last used patron search form element
+    var lastFormElement;
+
     $scope.gridControls = {
         activateItem : function(item) {
             $location.path('/circ/patron/' + item.id() + '/checkout');
@@ -886,7 +889,7 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore,
 
     $scope.clearForm = function () {
         $scope.searchArgs={};
-        window.prevElement.focus();
+        if (lastFormElement) lastFormElement.focus();
     }
 
     $scope.applyShowExtras = function($event, bool) {
@@ -897,7 +900,7 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore,
             $scope.showExtras = false;
             egCore.hatch.removeItem('eg.circ.patron.search.show_extras');
         }
-        window.prevElement.focus();
+        if (lastFormElement) lastFormElement.focus();
         $event.preventDefault();
     }
 
@@ -960,12 +963,16 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore,
         return sort;
     }
 
+    $scope.setLastFormElement = function() {
+        lastFormElement = $document[0].activeElement;
+    }
+
     // search form submit action; tells the results grid to
     // refresh itself.
     $scope.search = function(args) { // args === $scope.searchArgs
         if (args && Object.keys(args).length) 
             $scope.gridControls.refresh();
-        window.prevElement.focus();
+        if (lastFormElement) lastFormElement.focus();
     }
 
     // TODO: move this into the (forthcoming) grid row activate action

commit 62497d71eaefa88809aee052b0ab7081fd7802bf
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Fri Dec 26 22:46:31 2014 +0000

    LP#1402797 use null as default payment amount
    
    This means that operator does not have to select the
    previous default of "0" in the control to clear it out.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js b/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js
index cee0f0f..1d6f371 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js
@@ -123,7 +123,7 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location,
 
     // set up some defaults
     $scope.check_number = 0;
-    $scope.payment_amount = 0;
+    $scope.payment_amount = null;
     $scope.session_voided = 0;
     $scope.payment_type = 'cash_payment';
     $scope.focus_payment = true;
@@ -267,7 +267,7 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location,
     function refreshDisplay() {
         patronSvc.fetchUserStats();
         billSvc.fetchSummary().then(function(s) {$scope.summary = s});
-        $scope.payment_amount = 0;
+        $scope.payment_amount = null;
         $scope.gridControls.refresh();
     }
 

commit f985e0d91d0591321d6e776e189657cb359c6fe6
Author: Bill Erickson <berickxx at gmail.com>
Date:   Mon Dec 15 13:47:51 2014 -0500

    LP#1402797 webby: catalog record -> view holds org filter repair
    
    Selecting a pickup library from the filter in the Catalog -> View Holds
    UI shows holds for the selected org unit and descendant org units.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/cat/catalog/app.js b/Open-ILS/web/js/ui/default/staff/cat/catalog/app.js
index 8c06ad5..9b466a9 100644
--- a/Open-ILS/web/js/ui/default/staff/cat/catalog/app.js
+++ b/Open-ILS/web/js/ui/default/staff/cat/catalog/app.js
@@ -101,7 +101,7 @@ function($scope , $routeParams , $location , $q , egCore , egHolds,
             'open-ils.circ',
             'open-ils.circ.holds.retrieve_all_from_title',
             egCore.auth.token(), $scope.record_id, 
-            {pickup_lib : $scope.pickup_ou.id()}
+            {pickup_lib : egCore.org.descendants($scope.pickup_ou.id(), true)}
         ).then(
             function(hold_data) {
                 angular.forEach(hold_data, function(list, type) {

commit 87960a121a73aefa7bcad3bb6513a48596704483
Author: Bill Erickson <berickxx at gmail.com>
Date:   Mon Dec 15 13:46:14 2014 -0500

    LP#1402797 Repair browser client dropdown buttons - #2
    
    Repairs egOrgSelector.
    
    Angular-ui-bootstrap as of version ~0.11.2 does not want bare
    "dropdown-toggle" attributes within action link tags.  When present,
    they prevent the dropdown button from opening.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/services/ui.js b/Open-ILS/web/js/ui/default/staff/services/ui.js
index c960ffb..35e6887 100644
--- a/Open-ILS/web/js/ui/default/staff/services/ui.js
+++ b/Open-ILS/web/js/ui/default/staff/services/ui.js
@@ -215,7 +215,7 @@ function($modal, $interpolate) {
            + '</button>'
            + '<ul class="dropdown-menu">'
              + '<li ng-repeat="org in orgList" ng-hide="hiddenTest(org.id)">'
-               + '<a href dropdown-toggle ng-click="orgChanged(org)"'
+               + '<a href ng-click="orgChanged(org)"'
                  + 'style="padding-left: {{org.depth * 10 + 5}}px">'
                  + '{{org.shortname}}'
                + '</a>'

commit c213d2fd4372004d7fc0307480b5751d774a8e6d
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Dec 17 11:31:24 2014 -0500

    LP#1402797 Allow, and use, disabling of button-ish anchors
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/index.tt2 b/Open-ILS/src/templates/staff/circ/patron/index.tt2
index 9048faa..bb0d2f8 100644
--- a/Open-ILS/src/templates/staff/circ/patron/index.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/index.tt2
@@ -77,10 +77,10 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
   <div class="col-md-9">
     <ul class="nav nav-pills nav-pills-like-tabs">
       <li ng-class="{active : tab == 'checkout', disabled : !patron()}">
-        <a href="./circ/patron/{{patron().id()}}/checkout">[% l('Check Out') %]</a>
+        <a a-disabled="!patron()" href="./circ/patron/{{patron().id()}}/checkout">[% l('Check Out') %]</a>
       </li>
       <li ng-class="{active : tab == 'items_out', disabled : !patron()}">
-        <a href="./circ/patron/{{patron().id()}}/items_out">
+        <a a-disabled="!patron()" href="./circ/patron/{{patron().id()}}/items_out">
           [% l('Items Out') %] 
           <span ng-if="patron()"><!-- lack of space / newline below intentional -->
           (<span ng-class="{'patron-summary-alert-small' : patron_stats().checkouts.overdue}">{{patron_stats().checkouts.total_out}}</span>)
@@ -88,7 +88,7 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
         </a>
       </li>
       <li ng-class="{active : tab == 'holds', disabled : !patron()}">
-        <a href="./circ/patron/{{patron().id()}}/holds">
+        <a a-disabled="!patron()" href="./circ/patron/{{patron().id()}}/holds">
           [% l('Holds') %]
           <span ng-if="patron()">
             (<span>{{patron_stats().holds.total}} / {{patron_stats().holds.ready}}</span>)
@@ -96,7 +96,7 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
         </a>
       </li>
       <li ng-class="{active : tab == 'bills', disabled : !patron()}">
-        <a href="./circ/patron/{{patron().id()}}/bills">
+        <a a-disabled="!patron()" href="./circ/patron/{{patron().id()}}/bills">
           [% l('Bills') %]
           <span ng-if="patron()">
             (<span ng-class="{'patron-summary-alert-small' : patron_stats().fines.balance_owed}">{{patron_stats().fines.balance_owed | currency}}</span>)
@@ -104,13 +104,13 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
         </a>
       </li>
       <li ng-class="{active : tab == 'messages', disabled : !patron()}">
-        <a href="./circ/patron/{{patron().id()}}/messages">[% l('Messages') %]</a>
+        <a a-disabled="!patron()" href="./circ/patron/{{patron().id()}}/messages">[% l('Messages') %]</a>
       </li>
       <li ng-class="{active : tab == 'edit', disabled : !patron()}">
         <a href="./circ/patron/{{patron().id()}}/edit">[% l('Edit') %]</a>
       </li>
       <li class="dropdown" ng-class="{active : tab == 'other', disabled : !patron()}">
-        <a href class="dropdown-toggle" data-toggle="dropdown">
+        <a a-disabled="!patron()" href class="dropdown-toggle" data-toggle="dropdown">
             [% l('Other') %]
             <b class="caret"></b>
         </a>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index 25800d3..3ce36c5 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -1529,3 +1529,28 @@ function($scope , $routeParams , $window , $location , egCore) {
     $scope.user_perms_url = url;
 }])
 
+.directive('aDisabled', function() {
+    return {
+        compile: function(tElement, tAttrs, transclude) {
+            //Disable ngClick
+            tAttrs["ngClick"] = ("ng-click", "!("+tAttrs["aDisabled"]+") && ("+tAttrs["ngClick"]+")");
+
+            //Toggle "disabled" to class when aDisabled becomes true
+            return function (scope, iElement, iAttrs) {
+                scope.$watch(iAttrs["aDisabled"], function(newValue) {
+                    if (newValue !== undefined) {
+                        iElement.toggleClass("disabled", newValue);
+                    }
+                });
+
+                //Disable href on click
+                iElement.on("click", function(e) {
+                    if (scope.$eval(iAttrs["aDisabled"])) {
+                        e.preventDefault();
+                    }
+                });
+            };
+        }
+    };
+})
+

commit dfb3810197c7138fde9292945ee56ab72afecb2e
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Dec 17 10:57:28 2014 -0500

    LP#1402797 Only enable the Apply Payment button when a bill is selected
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_bills.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_bills.tt2
index 317bd08..99abe6f 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_bills.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_bills.tt2
@@ -83,7 +83,11 @@
             <input id="annotate-payment" type="checkbox" ng-model="annotate_payment"/>
           </div>
           <div class="col-md-6">
-            <button type="submit" class="btn btn-default">[% l('Apply Payment') %]</button>
+            <button
+                type="submit"
+                class="btn btn-default"
+                ng-disabled="!gridControls.selectedItems().length"
+            >[% l('Apply Payment') %]</button>
           </div>
         </div>
       </fieldset>

commit c9c44036eb7d640519e5b1ff638cccff3e9c5aac
Author: Bill Erickson <berickxx at gmail.com>
Date:   Fri Dec 12 17:27:06 2014 -0500

    LP#1402797 webby: checkin fine tally patron bills link
    
    Checkin fine tally display now acts as a link which opens a new tab to
    the patron bills page for the current checkin patron when fines exist.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/checkin/t_checkin.tt2 b/Open-ILS/src/templates/staff/circ/checkin/t_checkin.tt2
index 1d8c466..c578efa 100644
--- a/Open-ILS/src/templates/staff/circ/checkin/t_checkin.tt2
+++ b/Open-ILS/src/templates/staff/circ/checkin/t_checkin.tt2
@@ -91,7 +91,10 @@
     <span>[% l('Fine Tally:') %]</span>
     <span class="pad-horiz alert alert-danger">{{fine_total | currency}}</span>
     <span ng-if="billable_barcode">
-      <span>[% l('Transaction for [_1] billed:', '{{billable_barcode}}') %]</span>
+      <!-- note: this forces a new tab -->
+      <a href='./circ/patron/{{billable_user_id}}/bills' target='_blank'>
+        <span>[% l('Transaction for [_1] billed:', '{{billable_barcode}}') %]</span>
+      </a>
       <span class="pad-horiz alert alert-danger">{{billable_amount | currency}}</span>
     </span>
   </div>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js b/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
index 79b1fd7..dd3fe8f 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js
@@ -162,6 +162,7 @@ function($scope , $q , $window , $location , egCore , checkinSvc , egGridDataPro
         delete $scope.alert;
         delete $scope.billable_amount;
         delete $scope.billable_barcode;
+        delete $scope.billable_user_id;
 
         var params = compiled.params;
         var options = compiled.options;
@@ -191,6 +192,7 @@ function($scope , $q , $window , $location , egCore , checkinSvc , egGridDataPro
                 if (amt != 0) {
                     $scope.billable_barcode = row_item.copy_barcode;
                     $scope.billable_amount = amt;
+                    $scope.billable_user_id = row_item.circ.usr();
                     $scope.fine_total = 
                         ($scope.fine_total * 100 + amt * 100) / 100;
                 }

commit 9a95b21d7dcd5e3cdf84e6c1f515863b98f7244b
Author: Mike Rylander <mrylander at gmail.com>
Date:   Fri Dec 12 16:43:53 2014 -0500

    LP#1402797 Actually do search button, too
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index 14d699c..25800d3 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -965,6 +965,7 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore,
     $scope.search = function(args) { // args === $scope.searchArgs
         if (args && Object.keys(args).length) 
             $scope.gridControls.refresh();
+        window.prevElement.focus();
     }
 
     // TODO: move this into the (forthcoming) grid row activate action

commit 75ac833a0eecfa4dddec70ebd197fb683bdf9e8a
Author: Mike Rylander <mrylander at gmail.com>
Date:   Fri Dec 12 16:41:24 2014 -0500

    LP#1402797 Focus patron search field on search, expand, clear
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_search.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_search.tt2
index 29abb40..b2034f9 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_search.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_search.tt2
@@ -26,21 +26,23 @@
             ng-model="searchArgs.second_given_name" placeholder="[% l('Middle Name') %]"/>
         </div>
 
-        <div class="col-md-2">
+        <div class="col-md-2" onmouseover="window.prevElement=document.activeElement">
           <input type="submit" class="btn btn-default" value="[% l('Search') %]"/>
         </div>
 
-        <div class="col-md-2">
-          <input type="reset" class="btn btn-default" ng-click="searchArgs={}" 
+        <div class="col-md-2" onmouseover="window.prevElement=document.activeElement">
+          <input type="reset" class="btn btn-default" ng-click="clearForm()" 
             value="[% l('Clear Form') %]"/>
         </div>
 
         <div class="col-md-2">
           <button class="btn btn-default" ng-click="applyShowExtras($event, true)" 
+            onmouseover="window.prevElement=document.activeElement"
             title="[% l('Show More Fields') %]" ng-show="!showExtras">
             <span class="glyphicon glyphicon-circle-arrow-down"></span>
           </button>
           <button class="btn btn-default" ng-click="applyShowExtras($event, false)" 
+            onmouseover="window.prevElement=document.activeElement"
             title="[% l('Show Fewer Fields') %]" ng-show="showExtras">
             <span class="glyphicon glyphicon-circle-arrow-up"></span>
           </button>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index 49d1e24..14d699c 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -884,6 +884,11 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore,
         return d;
     }
 
+    $scope.clearForm = function () {
+        $scope.searchArgs={};
+        window.prevElement.focus();
+    }
+
     $scope.applyShowExtras = function($event, bool) {
         if (bool) {
             $scope.showExtras = true;
@@ -892,6 +897,7 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore,
             $scope.showExtras = false;
             egCore.hatch.removeItem('eg.circ.patron.search.show_extras');
         }
+        window.prevElement.focus();
         $event.preventDefault();
     }
 

commit 27b3ee4e33c7b1c90325a019b04c1c96cc2f8773
Author: Mike Rylander <mrylander at gmail.com>
Date:   Fri Dec 12 14:02:29 2014 -0500

    LP#1402797 Use .finally() instead of hash-y syntax~
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
index 1150026..1dff72b 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
@@ -140,7 +140,7 @@ function($scope , $q , $modal , $routeParams , egCore , egUser , patronSvc ,
                 $scope.gridDataProvider.refresh();
             }
 
-        )['finally'](function() {
+        ).finally(function() {
 
             // regardless of the outcome of the circ, remove the 
             // barcode from the pending list.

commit 0bc1a174b0ed23b34921b4b9ad66731a96202859
Author: Mike Rylander <mrylander at gmail.com>
Date:   Fri Dec 12 14:01:59 2014 -0500

    LP#1402797 Apply focus in the .finally() in case there was a popup
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
index 6b87ed4..1150026 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
@@ -91,7 +91,7 @@ function($scope , $q , $modal , $routeParams , egCore , egUser , patronSvc ,
             });
         }
 
-        $scope.focusMe; // return focus to barcode input
+        $scope.focusMe = true; // return focus to barcode input
     }
 
     function send_checkout(params) {
@@ -146,6 +146,8 @@ function($scope , $q , $modal , $routeParams , egCore , egUser , patronSvc ,
             // barcode from the pending list.
             if (params.copy_barcode)
                 delete pending_barcodes[params.copy_barcode];
+
+            $scope.focusMe = true; // return focus to barcode input
         });
     }
 

commit b481c74c0a2ad59fad2ad2e90d6d3957b9800c14
Author: Jason Etheridge <jason at esilibrary.com>
Date:   Fri Dec 5 16:59:30 2014 -0500

    LP#1402797 fix checkout focus after patron load
    
    Thanks to berick and jcamins, and to eeevil for actually nailing the solution
    
    Signed-off-by: Jason Etheridge <jason at esilibrary.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
index 5ee1bc5..6b87ed4 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
@@ -10,8 +10,9 @@ angular.module('egPatronApp').controller('PatronCheckoutCtrl',
 function($scope , $q , $modal , $routeParams , egCore , egUser , patronSvc , 
          egGridDataProvider , $location , $timeout , egCirc) {
 
-    $scope.initTab('checkout', $routeParams.id);
-    $scope.focusMe = true;
+    $scope.initTab('checkout', $routeParams.id).finally(function(){
+        $scope.focusMe = true;
+    });
     $scope.checkouts = patronSvc.checkouts;
     $scope.checkoutArgs = {
         noncat_type : 'barcode',

commit d37e4d0bbaa9292577e413f1cb4166222411123c
Author: Bill Erickson <berickxx at gmail.com>
Date:   Thu Dec 4 17:22:46 2014 -0500

    LP#1402797 Repair browser client dropdown buttons
    
    Angular-ui-bootstrap as of version ~0.11.2 does not want bare
    "dropdown-toggle" attributes within action link tags.  When present,
    they prevent the dropdown button from opening.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/cat/catalog/t_catalog.tt2 b/Open-ILS/src/templates/staff/cat/catalog/t_catalog.tt2
index 47f1c6f..0549d7d 100644
--- a/Open-ILS/src/templates/staff/cat/catalog/t_catalog.tt2
+++ b/Open-ILS/src/templates/staff/cat/catalog/t_catalog.tt2
@@ -16,16 +16,16 @@
         <span class="caret"></span>
       </button>
       <ul class="dropdown-menu dropdown-menu-right" role="menu">
-        <li><a href dropdown-toggle ng-click="set_record_tab('catalog')">
+        <li><a href ng-click="set_record_tab('catalog')">
             [% l('OPAC View') %]</a></li>
-        <li><a href dropdown-toggle ng-click="set_record_tab('marc_html')">
+        <li><a href ng-click="set_record_tab('marc_html')">
             [% l('MARC View') %]</a></li>
         <li class="divider"></li>
-        <li><a href dropdown-toggle ng-click="set_record_tab('holds')">
+        <li><a href ng-click="set_record_tab('holds')">
             [% l('View Holds') %]</a></li>
-        <li><a href dropdown-toggle ng-click="mark_hold_transfer_dest()">
+        <li><a href ng-click="mark_hold_transfer_dest()">
             [% l('Mark as Title Hold Transfer Destination') %]</a></li>
-        <li><a href dropdown-toggle ng-click="transfer_holds_to_marked()">
+        <li><a href ng-click="transfer_holds_to_marked()">
             [% l('Transfer All Title Holds') %]</a></li>
       </ul>
     </div>
diff --git a/Open-ILS/src/templates/staff/circ/checkin/t_checkin.tt2 b/Open-ILS/src/templates/staff/circ/checkin/t_checkin.tt2
index 83b88f5..1d8c466 100644
--- a/Open-ILS/src/templates/staff/circ/checkin/t_checkin.tt2
+++ b/Open-ILS/src/templates/staff/circ/checkin/t_checkin.tt2
@@ -139,7 +139,7 @@
       </button>
       <ul class="dropdown-menu pull-right">
         <li>
-          <a href dropdown-toggle 
+          <a href
             ng-click="toggle_mod('no_precat_alert')">
             <span ng-if="modifiers.no_precat_alert" 
               class="label label-success">&#x2713;</span>
@@ -149,7 +149,7 @@
           </a>
         </li>
         <li ng-if="!is_capture"><!-- nonsensical for hold capture -->
-          <a href dropdown-toggle 
+          <a href
             ng-click="toggle_mod('noop')">
             <span ng-if="modifiers.noop" 
               class="label label-success">&#x2713;</span>
@@ -159,7 +159,7 @@
           </a>
         </li>
         <li>
-          <a href dropdown-toggle 
+          <a href
             ng-click="toggle_mod('void_overdues')">
             <span ng-if="modifiers.void_overdues" 
               class="label label-success">&#x2713;</span>
@@ -169,7 +169,7 @@
           </a>
         </li>
         <li>
-          <a href dropdown-toggle 
+          <a href
             ng-click="toggle_mod('auto_print_holds_transits')">
             <span ng-if="modifiers.auto_print_holds_transits" 
               class="label label-success">&#x2713;</span>
@@ -179,7 +179,7 @@
           </a>
         </li>
         <li>
-          <a href dropdown-toggle 
+          <a href
             ng-click="toggle_mod('clear_expired')">
             <span ng-if="modifiers.clear_expired" 
               class="label label-success">&#x2713;</span>
@@ -189,7 +189,7 @@
           </a>
         </li>
         <li>
-          <a href dropdown-toggle 
+          <a href
             ng-click="toggle_mod('retarget_holds')">
             <span ng-if="modifiers.retarget_holds" 
               class="label label-success">&#x2713;</span>
@@ -199,7 +199,7 @@
           </a>
         </li>
         <li>
-          <a href dropdown-toggle 
+          <a href
             ng-click="toggle_mod('retarget_holds_all')">
             <span ng-if="modifiers.retarget_holds_all" 
               class="label label-success">&#x2713;</span>
@@ -209,7 +209,7 @@
           </a>
         </li>
         <li>
-          <a href dropdown-toggle 
+          <a href
             ng-click="toggle_mod('hold_as_transit')">
             <span ng-if="modifiers.hold_as_transit" 
               class="label label-success">&#x2713;</span>
diff --git a/Open-ILS/src/templates/staff/circ/in_house_use/index.tt2 b/Open-ILS/src/templates/staff/circ/in_house_use/index.tt2
index 2299603..7946ce5 100644
--- a/Open-ILS/src/templates/staff/circ/in_house_use/index.tt2
+++ b/Open-ILS/src/templates/staff/circ/in_house_use/index.tt2
@@ -39,12 +39,12 @@
             <span class="caret"></span>
           </button>
           <ul class="dropdown-menu">
-            <li><a href dropdown-toggle
+            <li><a href
               ng-click="args.noncat_type='barcode';bcFocus=true">
               [% l('Barcode') %]</a>
             </li>
             <li class="divider"></li>
-            <li><a href dropdown-toggle
+            <li><a href
               ng-repeat='type in nonCatTypes'
               ng-click="args.noncat_type=type.id()">{{type.name()}}</a>
             </li>
diff --git a/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2
index 945f2db..f42bfe9 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2
@@ -12,13 +12,13 @@
             <span class="caret"></span>
           </button>
           <ul class="dropdown-menu">
-            <li><a href dropdown-toggle
+            <li><a href
               ng-click="checkoutArgs.noncat_type='barcode';focusMe=true">
               [% l('Barcode') %]</a>
             </li>
             <li class="divider"></li>
             <li>
-              <a href ng-repeat='type in nonCatTypes' dropdown-toggle
+              <a href ng-repeat='type in nonCatTypes'
                ng-click="checkoutArgs.noncat_type=type.id()">{{type.name()}}</a>
             </li>
           </ul>
diff --git a/Open-ILS/src/templates/staff/share/t_autogrid.tt2 b/Open-ILS/src/templates/staff/share/t_autogrid.tt2
index 36cb85f..912b644 100644
--- a/Open-ILS/src/templates/staff/share/t_autogrid.tt2
+++ b/Open-ILS/src/templates/staff/share/t_autogrid.tt2
@@ -66,13 +66,12 @@
 
     <!-- actions drop-down menu -->
     <div class="btn-group" ng-if="actions.length" dropdown>                                                  
-      <button type="button" class="btn btn-default dropdown-toggle"
-        ng-class="{disabled : false}">
+      <button type="button" class="btn btn-default dropdown-toggle">
         [% l('Actions') %] <span class="caret"></span>                       
       </button>                                                              
       <ul class="dropdown-menu pull-right">                                  
         <li ng-repeat="action in actions" ng-class="{divider: action.divider}">
-          <a ng-if="!action.divider" href dropdown-toggle
+          <a ng-if="!action.divider" href
             ng-click="actionLauncher(action)">{{action.label}}</a>
         </li>
       </ul>

commit bf5052ff0fe997d5c6b51ef196774952a68289ee
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Dec 3 14:57:54 2014 -0500

    LP#1402797 webby: repair Hatch type=text printing
    
    When printing text, Hatch was receiving no print content due to some
    code refactoring.  Repaired.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/services/print.js b/Open-ILS/web/js/ui/default/staff/services/print.js
index bcb8aa2..fa60193 100644
--- a/Open-ILS/web/js/ui/default/staff/services/print.js
+++ b/Open-ILS/web/js/ui/default/staff/services/print.js
@@ -66,7 +66,7 @@ function($q , $window , $timeout , $http , egHatch , egAuth , egIDL , egOrg) {
 
         } else {
             // text content does not require compilation for remote printing
-            promise = $q.when();
+            promise = $q.when(args.content);
         }
 
         // TODO: link print context to template type

commit 7f6170bd1cca9fe41d7f6074e118231dda5e04e3
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Dec 3 12:48:12 2014 -0500

    LP#1402797 Avoid org tree retrieval race condition on patron app
    
    Avoid calling egOrg.ancestors() during startup, because the org unit
    tree is not guarantee to be available until startup has completed.  This
    was causing an occasional JS excpetion in the patron app pages, which
    prevented the pages from loading.
    
    The error in question:
    
     TypeError: Cannot read property 'map' of undefined
        at Object.service.get (https://host/js/ui/default/staff/services/org.js:21:25)
        at Object.service.ancestors (https://host/js/ui/default/staff/services/org.js:34:28)
        at Object.egCore.env.classLoaders.actsc (https://host/js/ui/default/staff/circ/patron/app.js:41:37)
        at https://host/js/ui/default/staff/services/env.js:77:55
        at Object.r [as forEach] (https://host/js/ui/default/staff/build/js/angular.min.js:7:290)
        at Object.service.load (https://host/js/ui/default/staff/services/env.js:76:17)
        at https://host/js/ui/default/staff/services/startup.js:64:23
        at J (https://host/js/ui/default/staff/build/js/angular.min.js:101:96)
        at https://host/js/ui/default/staff/build/js/angular.min.js:102:259
        at h.$eval (https://host/js/ui/default/staff/build/js/angular.min.js:113:32)
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index d1ebcfc..49d1e24 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -35,19 +35,7 @@ angular.module('egPatronApp', ['ngRoute', 'ui.bootstrap',
             });
         }
 
-        // local stat cats are displayed in the summary bar on each page.
-        egCore.env.classLoaders.actsc = function() {
-            return egCore.pcrud.search('actsc', 
-                {owner : egCore.org.ancestors(
-                    egCore.auth.user().ws_ou(), true)},
-                {}, {atomic : true}
-            ).then(function(cats) {
-                egCore.env.absorbList(cats, 'actsc');
-            });
-        }
-
         egCore.env.loadClasses.push('aous');
-        egCore.env.loadClasses.push('actsc');
 
         // app-globally modify the default flesh fields for 
         // fleshed user retrieval.
@@ -61,7 +49,18 @@ angular.module('egPatronApp', ['ngRoute', 'ui.bootstrap',
             ]);
         }
 
-        return egCore.startup.go()
+        return egCore.startup.go().then(function() {
+
+            // This call requires orgs to be loaded, because it
+            // calls egCore.org.ancestors(), so call it after startup
+            return egCore.pcrud.search('actsc', 
+                {owner : egCore.org.ancestors(
+                    egCore.auth.user().ws_ou(), true)},
+                {}, {atomic : true}
+            ).then(function(cats) {
+                egCore.env.absorbList(cats, 'actsc');
+            });
+        });
     }]};
 
     $routeProvider.when('/circ/patron/search', {

commit 2c7d8eb5085e283d7e0e702e41053db58e5ef251
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Dec 3 16:40:50 2014 -0500

    LP#1402797 Adjust timestamp with local timezone before truncating to the date
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
index 3f3518d..7558251 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
@@ -223,7 +223,13 @@ function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc ,
                     // Fire off the due-date updater for each circ.
                     // When all is done, close the dialog
                     $scope.ok = function(args) {
-                        var due = args.due_date.toISOString().replace(/T.*/,'');
+                        // toISOString gives us Zulu time, so
+                        // adjust for that before truncating to date
+                        var adjust_date = new Date( $scope.args.date );
+                        adjust_date.setMinutes(
+                            $scope.args.date.getMinutes() - adjust_date.getTimezoneOffset()
+                        );
+                        var due = adjust_date.toISOString().replace(/T.*/,'');
                         console.debug("applying due date of " + due);
 
                         var promises = [];

commit 49c1dbc6f06a299ecbf1780f5b3439322f5b38aa
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Dec 3 10:54:34 2014 -0500

    LP#1402797 Add usr and requestor columns to the hold pull list
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/holds/t_shelf_list.tt2 b/Open-ILS/src/templates/staff/circ/holds/t_shelf_list.tt2
index e47f713..598d86e 100644
--- a/Open-ILS/src/templates/staff/circ/holds/t_shelf_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/holds/t_shelf_list.tt2
@@ -79,6 +79,8 @@
   <eg-grid-field label="[% l('Status') %]" path='status_string'></eg-grid-field>
 
   <eg-grid-field label="[% l('Queue Position') %]" path='queue_position' hidden></eg-grid-field>
+  <eg-grid-field path='hold.usr.*' parent-idl-class="ahr" hidden></eg-grid-field>
+  <eg-grid-field path='hold.requestor.*' parent-idl-class="ahr" hidden></eg-grid-field>
   <eg-grid-field path='hold.*' parent-idl-class="ahr" hidden></eg-grid-field>
   <eg-grid-field path='copy.*' parent-idl-class="acp" hidden></eg-grid-field>
   <eg-grid-field path='volume.*' parent-idl-class="acn" hidden></eg-grid-field>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
index ee2fa79..b155085 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
@@ -6,8 +6,8 @@ angular.module('egCoreMod')
 
 .factory('egHolds',
 
-       ['$modal','$q','egCore','egUser','egConfirmDialog','egAlertDialog',
-function($modal , $q , egCore , egUser , egConfirmDialog , egAlertDialog) {
+       ['$modal','$q','egCore','egConfirmDialog','egAlertDialog',
+function($modal , $q , egCore , egConfirmDialog , egAlertDialog) {
 
     var service = {};
 
@@ -410,10 +410,10 @@ function($modal , $q , egCore , egUser , egConfirmDialog , egAlertDialog) {
         hold_data.id = hold.id();
 
         if (hold.requestor() && typeof hold.requestor() != 'object')
-            hold.requestor(egUser.get(hold.requestor()));
+            egCore.pcrud.retrieve('au',hold.requestor()).then(function(u) { hold.requestor(u) });
 
         if (hold.usr() && typeof hold.usr() != 'object')
-            hold.usr(egUser.get(hold.usr()));
+            egCore.pcrud.retrieve('au',hold.usr()).then(function(u) { hold.usr(u) });
 
         // current_copy is not always fleshed in the API
         if (hold.current_copy() && typeof hold.current_copy() != 'object')

commit 09ed139f362b41a93da82afb8457dfa623ac8374
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Dec 3 10:54:13 2014 -0500

    LP#1402797 Begin teaching grid about class hierarchies for labels
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/services/grid.js b/Open-ILS/web/js/ui/default/staff/services/grid.js
index 9598dc4..1f89a9c 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -993,37 +993,38 @@ angular.module('egGridMod',
 
             var dotpath = colSpec.path.replace(/\.?\*$/,'');
             var class_obj;
+            var idl_field;
 
             if (colSpec.parentIdlClass) {
                 class_obj = egCore.idl.classes[colSpec.parentIdlClass];
-
             } else {
-
                 class_obj = egCore.idl.classes[cols.idlClass];
-                if (!class_obj) return;
-
-                var path_parts = dotpath.split(/\./);
-
-                // find the IDL class definition for the last element in the
-                // path before the .*
-                // an empty path_parts means expand the root class
-                if (path_parts) {
-                    for (var path_idx in path_parts) {
-                        var part = path_parts[path_idx];
-                        var idl_field = class_obj.field_map[part];
-
-                        // unless we're at the end of the list, this field should
-                        // link to another class.
-                        if (idl_field && idl_field['class'] && (
-                            idl_field.datatype == 'link' || 
-                            idl_field.datatype == 'org_unit')) {
-                            class_obj = egCore.idl.classes[idl_field['class']];
-                        } else {
-                            if (path_idx < (path_parts.length - 1)) {
-                                // we ran out of classes to hop through before
-                                // we ran out of path components
-                                console.error("egGrid: invalid IDL path: " + dotpath);
-                            }
+            }
+
+            if (!class_obj) return;
+
+            console.debug('egGrid: auto dotpath is: ' + dotpath);
+            var path_parts = dotpath.split(/\./);
+
+            // find the IDL class definition for the last element in the
+            // path before the .*
+            // an empty path_parts means expand the root class
+            if (path_parts) {
+                for (var path_idx in path_parts) {
+                    var part = path_parts[path_idx];
+                    idl_field = class_obj.field_map[part];
+
+                    // unless we're at the end of the list, this field should
+                    // link to another class.
+                    if (idl_field && idl_field['class'] && (
+                        idl_field.datatype == 'link' || 
+                        idl_field.datatype == 'org_unit')) {
+                        class_obj = egCore.idl.classes[idl_field['class']];
+                    } else {
+                        if (path_idx < (path_parts.length - 1)) {
+                            // we ran out of classes to hop through before
+                            // we ran out of path components
+                            console.error("egGrid: invalid IDL path: " + dotpath);
                         }
                     }
                 }
@@ -1042,8 +1043,9 @@ angular.module('egGridMod',
 
                     var col = cols.cloneFromScope(colSpec);
                     col.path = dotpath + '.' + field.name;
+                    console.debug('egGrid: field: ' +field.name + '; parent field: ' + js2JSON(idl_field));
                     cols.add(col, false, true, 
-                        {idl_field : field, idl_class : class_obj});
+                        {idl_parent : idl_field, idl_field : field, idl_class : class_obj});
                 });
 
                 cols.columns = cols.columns.sort(
@@ -1106,7 +1108,7 @@ angular.module('egGridMod',
             // definitions.  If a match is found, back out.
             if (cols.columns.filter(function(c) {
                 return (c.path == colSpec.path) })[0]) {
-                //console.debug('skipping column ' + colSpec.path);
+                console.debug('skipping pre-existing column ' + colSpec.path);
                 return;
             }
 
@@ -1156,7 +1158,12 @@ angular.module('egGridMod',
             }
 
             if (fromExpand && idl_info.idl_class) {
-                column.idlclass = idl_info.idl_class.label || idl_info.idl_class.name;
+                column.idlclass = '';
+                if (idl_info.idl_parent) {
+                    column.idlclass = idl_info.idl_parent.label || idl_info.idl_parent.name;
+                } else {
+                    column.idlclass += idl_info.idl_class.label || idl_info.idl_class.name;
+                }
             }
         },
 
@@ -1166,9 +1173,11 @@ angular.module('egGridMod',
             var class_obj = egCore.idl.classes[cols.idlClass];
             var path_parts = dotpath.split(/\./);
 
+            var idl_parent;
             var idl_field;
             for (var path_idx in path_parts) {
                 var part = path_parts[path_idx];
+                idl_parent = idl_field;
                 idl_field = class_obj.field_map[part];
 
                 if (idl_field && idl_field['class'] && (
@@ -1182,7 +1191,8 @@ angular.module('egGridMod',
             if (!idl_field) return null;
 
             return {
-                idl_field :idl_field,
+                idl_parent: idl_parent,
+                idl_field : idl_field,
                 idl_class : class_obj
             };
         }

commit 032944674c518d3fe99b9830f2ecdbbb71d559e3
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Dec 3 10:53:35 2014 -0500

    LP#1402797 Fetch old circ when the user is not the same (API misuse)
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/circ.js b/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
index 9a0b8a7..29dec1e 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
@@ -803,6 +803,27 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
 
     service.circ_exists_dialog = function(evt, params, options) {
 
+        if (!evt.payload.old_circ) {
+            return egCore.net.request(
+                'open-ils.search',
+                'open-ils.search.asset.copy.fleshed2.find_by_barcode',
+                params.copy_barcode
+            ).then(function(resp){
+                console.log(resp);
+                if (egCore.evt.parse(resp)) {
+                    console.error(egCore.evt.parse(resp));
+                } else {
+                   evt.payload.old_circ = resp.circulations()[0];
+                   return service.circ_exists_dialog_impl( evt, params, options );
+                }
+            });
+        } else {
+            return service.circ_exists_dialog_impl( evt, params, options );
+        }
+    },
+
+    service.circ_exists_dialog_impl = function (evt, params, options) {
+
         var openCirc = evt.payload.old_circ;
         var sameUser = openCirc.usr() == params.patron_id;
         

commit c5670d423867fd13ca1e175bde954836b69e3b75
Author: Bill Erickson <berickxx at gmail.com>
Date:   Tue Dec 2 17:28:01 2014 -0500

    LP#1402797 Browser client checkout 'Done' clears current user
    
    Clicking the 'Done' button after checkout resets the patron side bar and
    action tabs to completely hide the previous patron's data.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index b51a110..d1ebcfc 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -249,6 +249,15 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
         return service.setPrimary(service.current.id(), null, true);
     }
 
+    // clear the currently focused user
+    service.clearPrimary = function() {
+        // reset with no patron
+        service.resetPatronLists();
+        service.current = null;
+        service.patron_stats = null;
+        return $q.when();
+    }
+
     // sets the primary display user, fetching data as necessary.
     service.setPrimary = function(id, user, force) {
         var user_id = id ? id : (user ? user.id() : null);
@@ -328,11 +337,10 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
             );
         } else {
 
-            // reset with no patron
-            service.resetPatronLists();
-            service.current = null;
-            service.patron_stats = null;
-            return $q.when();
+            // fetching a null user clears the primary user.
+            // NOTE: this should probably reject() and log an error, 
+            // but calling clear for backwards compat for now.
+            return service.clearPrimary();
         }
     }
 
@@ -617,7 +625,7 @@ function($scope,  $q,  $location , $filter,  egCore,  egUser,  patronSvc) {
        ['$scope','$location','egCore','egConfirmDialog','egUser','patronSvc',
 function($scope , $location , egCore , egConfirmDialog , egUser , patronSvc) {
     $scope.selectMe = true; // focus text input
-    patronSvc.setPrimary(); // clear the default user
+    patronSvc.clearPrimary(); // clear the default user
 
     // jump to the patron checkout UI
     function loadPatron(user_id) {

commit f577998f61a22c503b9c64865044d44f4d99a6dd
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Nov 26 10:48:07 2014 -0500

    LP#1402797 Remove useless options in record bucket export
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/cat/bucket/record/t_bucket_export.tt2 b/Open-ILS/src/templates/staff/cat/bucket/record/t_bucket_export.tt2
index ffc26d0..7f09aa4 100644
--- a/Open-ILS/src/templates/staff/cat/bucket/record/t_bucket_export.tt2
+++ b/Open-ILS/src/templates/staff/cat/bucket/record/t_bucket_export.tt2
@@ -12,8 +12,6 @@
         <select class="form-control" ng-model="args.format" id="export-bucket-format">
           <option value="XML">[% l('MARC XML') %]</option>
           <option value="USMARC">[% l('USMARC') %]</option>
-          <option value="UNIMARC">[% l('UNIMARC') %]</option>
-          <option value="BRE">[% l('Evergreen Record Entry') %]</option>
         </select>
       </div>
       <div class="form-group">

commit 8d4528d0c4495b7b68b699a37c5f2897015a48ff
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Nov 12 15:00:07 2014 -0500

    LP#1402797 Allow the status bar to be hidden
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/statusbar.tt2 b/Open-ILS/src/templates/staff/statusbar.tt2
index 7eef88b..47675b6 100644
--- a/Open-ILS/src/templates/staff/statusbar.tt2
+++ b/Open-ILS/src/templates/staff/statusbar.tt2
@@ -2,6 +2,8 @@
 
 <div id="status-bar" 
   class="navbar navbar-default navbar-fixed-bottom" 
+  ng-model="statusbar_hidden"
+  ng-hide="statusbar_hidden"
   role="navigation">
 
   <!-- 
@@ -28,6 +30,12 @@
           ng-class="{'status-bar-connected' : netConnected()}">
         </span>
       </li>
+      <li ng-click="statusbar_hidden ? statusbar_hidden = false : statusbar_hidden = true">
+        <span 
+          title="[% l('Collapse ... Reload to restore') %]"
+          class="glyphicon glyphicon-collapse-down">
+        </span>
+      </li>
     </ul>    
   </script>
 </div>

commit 9133c6f3fd31eb66c580d53b39810215356b6207
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed Nov 12 10:46:43 2014 -0500

    LP#1402797 Separate stock and custom penalty type models
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2 b/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
index 420c358..a656e38 100644
--- a/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
+++ b/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
@@ -23,10 +23,10 @@
           </ul>
         </div>
         <div class="col-md-4 pull-right">
-          <select class="form-control" ng-model="args.penalty">
-            <option ng-selected="args.penalty = ''" value="">[% l('Penalty Type') %]</option>
+          <select class="form-control" ng-model="args.custom_penalty">
+            <option disabled="disabled" ng-selected="args.custom_penalty = ''" value="">[% l('Penalty Type') %]</option>
             <option ng-repeat="penalty in penalties" 
-              ng-selected="args.penalty = penalty.id"
+              ng-selected="args.custom_penalty = penalty.id"
               value="{{penalty.id()}}">{{penalty.label()}}</option>
           </select>
         </div>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/circ.js b/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
index edf975a..9a0b8a7 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/services/circ.js
@@ -1440,7 +1440,11 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
                 pen.usr(user_id);
                 pen.org_unit(egCore.auth.user().ws_ou());
                 pen.note(args.note);
-                pen.standing_penalty(args.penalty);
+                if (args.custom_penalty) {
+                    pen.standing_penalty(args.custom_penalty);
+                } else {
+                    pen.standing_penalty(args.penalty);
+                }
                 pen.staff(egCore.auth.user().id());
                 pen.set_date('now');
                 return egCore.pcrud.create(pen);

commit ab2f8bd76707647800d9e860319eff10e676bf45
Author: Mike Rylander <mrylander at gmail.com>
Date:   Tue Nov 11 13:26:21 2014 -0500

    LP#1402797 Supply top-level method for uncanceling holds
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
index 77e4fb9..ee2fa79 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
@@ -449,6 +449,14 @@ function($window , $location , egCore , egHolds , egCirc) {
         return egHolds.cancel_holds(hold_ids).then(service.refresh);
     }
 
+    service.uncancel_hold = function(items) {
+        var hold_ids = items.filter(function(item) {
+            return item.hold.cancel_time();
+        }).map(function(item) {return item.hold.id()});
+
+        return egHolds.uncancel_holds(hold_ids).then(service.refresh);
+    }
+
     // jump to circ list for either 1) the targeted copy or
     // 2) the hold target copy for copy-level holds
     service.show_recent_circs = function(items) {

commit 0cdb0e5a40f5fe3c78750e193369706467754d63
Author: Mike Rylander <mrylander at gmail.com>
Date:   Tue Nov 11 13:25:55 2014 -0500

    LP#1402797 Fix boolean assumption
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index bd7cb8a..b51a110 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -394,7 +394,7 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
 
         angular.forEach(
             service.current.addresses(), 
-            function(addr) { if (!addr.valid()) fail = true }
+            function(addr) { if (addr.valid() == 'f') fail = true }
         );
 
         return $q.when(fail);

commit 354ada2cf8af416d9634a09cc81922a5ca052f30
Author: Mike Rylander <mrylander at gmail.com>
Date:   Tue Nov 11 13:25:25 2014 -0500

    LP#1402797 Sort by class, and keep columns from one class together
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/share/t_autogrid.tt2 b/Open-ILS/src/templates/staff/share/t_autogrid.tt2
index 12299c5..36cb85f 100644
--- a/Open-ILS/src/templates/staff/share/t_autogrid.tt2
+++ b/Open-ILS/src/templates/staff/share/t_autogrid.tt2
@@ -159,7 +159,7 @@
         </a></li>
         <li role="presentation" class="divider"></li>
         <li ng-repeat="col in columns">
-          <a href ng-click="toggleColumnVisibility(col)">
+          <a href title="{{col.idlclass}}" ng-click="toggleColumnVisibility(col)">
               <span ng-if="col.visible" 
                 class="label label-success">&#x2713;</span>
               <span ng-if="!col.visible" 
diff --git a/Open-ILS/web/js/ui/default/staff/services/grid.js b/Open-ILS/web/js/ui/default/staff/services/grid.js
index 772f3c6..9598dc4 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -1050,6 +1050,15 @@ angular.module('egGridMod',
                     function(a, b) {
                         if (a.explicit) return -1;
                         if (b.explicit) return 1;
+                        if (a.idlclass && b.idlclass) {
+                            return a.idlclass < b.idlclass ? -1 : 1;
+                            return a.idlclass > b.idlclass ? 1 : -1;
+                        }
+                        if (a.path && b.path) {
+                            return a.path < b.path ? -1 : 1;
+                            return a.path > b.path ? 1 : -1;
+                        }
+
                         return a.label < b.label ? -1 : 1;
                     }
                 );
@@ -1144,19 +1153,10 @@ angular.module('egGridMod',
             
             if (!column.label) {
                 column.label = idl_info.idl_field.label || column.name;
-                /*
-                // append class label to column label to better differentiate
-                // columns in the selector.
-                // Disabled for now, since it results in columns w/ really
-                // long names, making the grid unappealing when any of
-                // these colmns are selected.
-                // TODO: consider nesting the colum picker by class?
-                if (fromExpand) {
-                    var label = 
-                        idl_info.idl_class.label || idl_info.idl_class.name;
-                    column.label = label + '::' + column.label;
-                }
-                */
+            }
+
+            if (fromExpand && idl_info.idl_class) {
+                column.idlclass = idl_info.idl_class.label || idl_info.idl_class.name;
             }
         },
 

commit 843d2a2ebdfc161ea5883bb0e420dbf9bb8fff42
Author: Mike Rylander <mrylander at gmail.com>
Date:   Tue Nov 11 13:24:39 2014 -0500

    LP#1402797 Adjust the default for penalty type so it is selected
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2 b/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
index 3ddad54..420c358 100644
--- a/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
+++ b/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
@@ -24,9 +24,9 @@
         </div>
         <div class="col-md-4 pull-right">
           <select class="form-control" ng-model="args.penalty">
-            <option value="">[% l('Optional Penalty Type') %]</option>
-            <option ng-selected="args.penalty < 100"></option>
+            <option ng-selected="args.penalty = ''" value="">[% l('Penalty Type') %]</option>
             <option ng-repeat="penalty in penalties" 
+              ng-selected="args.penalty = penalty.id"
               value="{{penalty.id()}}">{{penalty.label()}}</option>
           </select>
         </div>

commit 0331e15f55c8c07a2188df66134402b746a28bb1
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 11:06:14 2014 -0400

    LP#1402797 Add invalid-address alert
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_alerts.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_alerts.tt2
index 822240c..9281362 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_alerts.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_alerts.tt2
@@ -27,6 +27,10 @@
     [% l('Patron account retrieved with an INACTIVE card.') %]
   </div>
 
+  <div class="alert alert-warning" ng-if="invalidAddresses">
+    [% l('Patron account has invalid addresses.') %]
+  </div>
+
   <!-- alert message -->
   <div class="row" ng-if="patron().alert_message()">
     <div class="col-md-12">
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
index c607e29..bd7cb8a 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js
@@ -239,6 +239,7 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
         service.patronExpired = false;
         service.patronExpiresSoon = false;
         service.retrievedWithInactive = false;
+        service.invalidAddresses = false;
     }
     service.resetPatronLists();  // initialize
 
@@ -383,6 +384,22 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
         return $q.when(false);
     }
 
+    // resolves to true if the patron account has any invalid addresses.
+    service.testInvalidAddrs = function() {
+
+        if (service.invalidAddresses)
+            return $q.when(true);
+
+        var fail = false;
+
+        angular.forEach(
+            service.current.addresses(), 
+            function(addr) { if (!addr.valid()) fail = true }
+        );
+
+        return $q.when(fail);
+    }
+
     // resolves to true if there is any aspect of the patron account
     // which should produce a message in the alerts panel
     service.checkAlerts = function() {
@@ -420,6 +437,11 @@ function($q , $timeout , $location , egCore,  egUser , $locale) {
             deferred.resolve(service.hasAlerts);
         });
 
+        service.testInvalidAddrs().then(function(bool) {
+            if (bool) service.invalidAddresses = true;
+            deferred.resolve(service.invalidAddresses);
+        });
+
         return deferred.promise;
     }
 
@@ -1184,6 +1206,7 @@ function($scope,  $routeParams , $location , egCore , patronSvc) {
         $scope.patronExpired = patronSvc.patronExpired;
         $scope.patronExpiresSoon = patronSvc.patronExpiresSoon;
         $scope.retrievedWithInactive = patronSvc.retrievedWithInactive;
+        $scope.invalidAddresses = patronSvc.invalidAddresses;
     });
 
 }])

commit d14fc8865e68d8157956aed023a4cecc68b2dc90
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 10:50:03 2014 -0400

    LP#1402797 Add Check Number input
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_bills.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_bills.tt2
index b8ab917..317bd08 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_bills.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_bills.tt2
@@ -59,6 +59,15 @@
           </div>
         </div>
         <div class="form-group">
+          <label for="check-input" class="col-md-6 control-label">
+            [% l('Check Number') %]
+          </label>
+          <div class="col-md-6">
+            <input type="number" min="1" step="any" id="check-input" 
+              ng-model="check_number" focus-me="focus_check" 
+              value="" class="form-control col-md-6 "/>
+          </div>
+        <div class="form-group">
           <label for="amount-input" class="col-md-6 control-label">
             [% l('Payment Received') %]
           </label>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js b/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js
index 5b83989..cee0f0f 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/bills.js
@@ -24,7 +24,7 @@ function($q , egCore , patronSvc) {
         .then(function(summary) {return service.summary = summary})
     }
 
-    service.applyPayment = function(type, payments, note) {
+    service.applyPayment = function(type, payments, note, check) {
         return egCore.net.request(
             'open-ils.circ',
             'open-ils.circ.money.payment',
@@ -32,6 +32,7 @@ function($q , egCore , patronSvc) {
                 userid : service.userId,
                 note : note || '', 
                 payment_type : type,
+                check_number : check,
                 payments : payments,
                 patron_credit : 0
             },
@@ -121,6 +122,7 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location,
     billSvc.userId = $routeParams.id;
 
     // set up some defaults
+    $scope.check_number = 0;
     $scope.payment_amount = 0;
     $scope.session_voided = 0;
     $scope.payment_type = 'cash_payment';
@@ -274,7 +276,7 @@ function($scope , $q , $routeParams , egCore , egConfirmDialog , $location,
     function sendPayment(note) {
         var make_payments = generatePayments();
         billSvc.applyPayment(
-            $scope.payment_type, make_payments, note)
+            $scope.payment_type, make_payments, note, $scope.check_number)
         .then(function(payment_ids) {
 
             if ($scope.receipt_on_pay) {

commit ddf43665a6ad9050599d4cc63225b3d4b48231c5
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 10:38:15 2014 -0400

    LP#1402797 Add the ability (and action) to uncancel holds
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2 b/Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2
index b21146d..13d5bf9 100644
--- a/Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2
+++ b/Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2
@@ -50,6 +50,8 @@
       label="[% l('Find Another Target') %]"></eg-grid-action>
     <eg-grid-action handler="grid_actions.cancel_hold"
       label="[% l('Cancel Hold') %]"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.uncancel_hold"
+      label="[% l('Uncancel Hold') %]"></eg-grid-action>
 
     <eg-grid-field label="[% l('Hold ID') %]" path='hold.id'></eg-grid-field>
     <eg-grid-field label="[% l('Current Copy') %]" 
diff --git a/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2 b/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
index 8cea1d1..33aee3e 100644
--- a/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/holds/t_pull_list.tt2
@@ -53,6 +53,8 @@
     label="[% l('Find Another Target') %]"></eg-grid-action>
   <eg-grid-action handler="grid_actions.cancel_hold"
     label="[% l('Cancel Hold') %]"></eg-grid-action>
+  <eg-grid-action handler="grid_actions.uncancel_hold"
+    label="[% l('Uncancel Hold') %]"></eg-grid-action>
 
   <eg-grid-field label="[% l('Hold ID') %]" path='hold.id'></eg-grid-field>
   <eg-grid-field label="[% l('Current Copy') %]" 
diff --git a/Open-ILS/src/templates/staff/circ/holds/t_shelf_list.tt2 b/Open-ILS/src/templates/staff/circ/holds/t_shelf_list.tt2
index 3700df9..e47f713 100644
--- a/Open-ILS/src/templates/staff/circ/holds/t_shelf_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/holds/t_shelf_list.tt2
@@ -50,6 +50,8 @@
     label="[% l('Find Another Target') %]"></eg-grid-action>
   <eg-grid-action handler="grid_actions.cancel_hold"
     label="[% l('Cancel Hold') %]"></eg-grid-action>
+  <eg-grid-action handler="grid_actions.uncancel_hold"
+    label="[% l('Uncancel Hold') %]"></eg-grid-action>
 
   <eg-grid-field label="[% l('Hold ID') %]" path='hold.id'></eg-grid-field>
   <eg-grid-field label="[% l('Current Copy') %]" 
diff --git a/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
index 721a417..c9bdf36 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
@@ -39,6 +39,8 @@
     label="[% l('Find Another Target') %]"></eg-grid-action>
   <eg-grid-action handler="grid_actions.cancel_hold"
     label="[% l('Cancel Hold') %]"></eg-grid-action>
+  <eg-grid-action handler="grid_actions.uncancel_hold"
+    label="[% l('Uncancel Hold') %]"></eg-grid-action>
 
   <eg-grid-field label="[% l('Hold ID') %]" path='hold.id'></eg-grid-field>
   <eg-grid-field label="[% l('Current Copy') %]" 
diff --git a/Open-ILS/src/templates/staff/circ/share/t_uncancel_hold_dialog.tt2 b/Open-ILS/src/templates/staff/circ/share/t_uncancel_hold_dialog.tt2
new file mode 100644
index 0000000..bceb1f7
--- /dev/null
+++ b/Open-ILS/src/templates/staff/circ/share/t_uncancel_hold_dialog.tt2
@@ -0,0 +1,17 @@
+<form ng-submit="ok()" role="form" class="form-horizontal">
+  <div class="modal-content">
+    <div class="modal-header">
+      <button type="button" class="close" 
+        ng-click="cancel()" aria-hidden="true">×</button>
+      <h4 class="modal-title">
+        [% l('Uncancel [_1] Hold(s)', '{{args.num_holds}}') %]
+      </h4>
+    </div>
+    <div class="modal-body"></div>
+    <div class="modal-footer">
+      <input type="submit" class="btn btn-success" value="[% l('Uncancel Hold') %]"/>
+      <button class="btn btn-warning" ng-click="cancel($event)">[% l('Exit') %]</button>
+    </div>
+  </div>
+</div>
+
diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
index a222018..77e4fb9 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
@@ -107,6 +107,49 @@ function($modal , $q , egCore , egUser , egConfirmDialog , egAlertDialog) {
         }).result;
     }
 
+    service.uncancel_holds = function(hold_ids) {
+       
+        return $modal.open({
+            templateUrl : './circ/share/t_uncancel_hold_dialog',
+            controller : 
+                ['$scope', '$modalInstance',
+                function($scope, $modalInstance) {
+                    $scope.args = {
+                        num_holds : hold_ids.length
+                    };
+                    
+                    $scope.cancel = function($event) {
+                        $modalInstance.dismiss();
+                        $event.preventDefault();
+                    }
+
+                    $scope.ok = function() {
+
+                        function uncancel_one() {
+                            var hold_id = hold_ids.pop();
+                            if (!hold_id) {
+                                $modalInstance.close();
+                                return;
+                            }
+                            egCore.net.request(
+                                'open-ils.circ', 'open-ils.circ.hold.uncancel',
+                                egCore.auth.token(), hold_id
+                            ).then(function(resp) {
+                                if (evt = egCore.evt.parse(resp)) {
+                                    console.error('unable to uncancel hold: ' 
+                                        + evt.toString());
+                                }
+                                uncancel_one();
+                            });
+                        }
+
+                        uncancel_one();
+                    }
+                }
+            ]
+        }).result;
+    }
+
     service.get_cancel_reasons = function() {
         if (egCore.env.ahrcc) return $q.when(egCore.env.ahrcc.list);
         return egCore.pcrud.retrieveAll('ahrcc', {}, {atomic : true})

commit 93c8a2e347804b89b59d7feb311cf09574122c0e
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 10:18:07 2014 -0400

    LP#1402797 Ignore the "current_copy" field, we already get that separately
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
index 6a61744..721a417 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
@@ -67,7 +67,7 @@
   <eg-grid-field label="[% l('Status') %]" path='status_string'></eg-grid-field>
 
   <eg-grid-field label="[% l('Queue Position') %]" path='queue_position' hidden></eg-grid-field>
-  <eg-grid-field path='hold.*' parent-idl-class="ahr" hidden></eg-grid-field>
+  <eg-grid-field path='hold.*' parent-idl-class="ahr" ignore="current_copy" hidden></eg-grid-field>
   <eg-grid-field path='copy.*' parent-idl-class="acp" hidden></eg-grid-field>
   <eg-grid-field path='hold.usr.*' parent-idl-class="au" hidden></eg-grid-field>
   <eg-grid-field path='hold.usr.card.*' parent-idl-class="ac" hidden></eg-grid-field>

commit 466345920c0f7fa7d3cbb2f97462cd84a05621ba
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 10:17:49 2014 -0400

    LP#1402797 Teach autogrid how to ignore fields explicitly
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/services/grid.js b/Open-ILS/web/js/ui/default/staff/services/grid.js
index 9dc5b7d..772f3c6 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -825,6 +825,7 @@ angular.module('egGridMod',
         scope : {
             name  : '@', // required; unique name
             path  : '@', // optional; flesh path
+            ignore: '@', // optional; fields to ignore when path is a wildcard
             label : '@', // optional; display label
             flex  : '@',  // optional; default flex width
             dateformat : '@', // optional: passed down to egGridValueFilter
@@ -986,6 +987,10 @@ angular.module('egGridMod',
         // position in the path.
         cols.expandPath = function(colSpec) {
 
+            var ignoreList = [];
+            if (colSpec.ignore)
+                ignoreList = colSpec.ignore.split(' ');
+
             var dotpath = colSpec.path.replace(/\.?\*$/,'');
             var class_obj;
 
@@ -1029,8 +1034,10 @@ angular.module('egGridMod',
 
                     // Only show wildcard fields where we have data to show
                     // Virtual and un-fleshed links will not have any data.
-                    if (field.virtual || (
-                        field.datatype == 'link' || field.datatype == 'org_unit'))
+                    if (field.virtual ||
+                        (field.datatype == 'link' || field.datatype == 'org_unit') ||
+                        ignoreList.indexOf(field.name) > -1
+                    )
                         return;
 
                     var col = cols.cloneFromScope(colSpec);

commit e705bbe28430a26c9da76ea0edbde5fb6484256c
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 09:57:11 2014 -0400

    LP#1402797 Add patron barcode and alias to hold lists where appropriate
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2 b/Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2
index 62af918..b21146d 100644
--- a/Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2
+++ b/Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2
@@ -59,6 +59,8 @@
       </a>
     </eg-grid-field>
 
+    <eg-grid-field label="[% l('Patron Barcode') %]">{{item.patron_barcode}}</eg-grid-field>
+    <eg-grid-field label="[% l('Patron alias') %]">{{item.patron_alias}}</eg-grid-field>
     <eg-grid-field label="[% l('Request Date') %]" path='hold.request_time'></eg-grid-field>
     <eg-grid-field label="[% l('Capture Date') %]" path='hold.capture_time'></eg-grid-field>
     <eg-grid-field label="[% l('Available Date') %]" path='hold.shelf_time'></eg-grid-field>
@@ -78,6 +80,7 @@
     <eg-grid-field label="[% l('Queue Position') %]" path='queue_position' hidden></eg-grid-field>
     <eg-grid-field path='hold.*' parent-idl-class="ahr" hidden></eg-grid-field>
     <eg-grid-field path='copy.*' parent-idl-class="acp" hidden></eg-grid-field>
+    <eg-grid-field path='hold.usr.*' parent-idl-class="acp" hidden></eg-grid-field>
     <eg-grid-field path='volume.*' parent-idl-class="acn" hidden></eg-grid-field>
     <eg-grid-field path='mvr.*' parent-idl-class="mvr" hidden></eg-grid-field>
   </eg-grid>
diff --git a/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
index df026fa..6a61744 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_holds_list.tt2
@@ -48,6 +48,8 @@
     </a>
   </eg-grid-field>
 
+  <eg-grid-field label="[% l('Patron Barcode') %]" hidden>{{item.patron_barcode}}</eg-grid-field>
+  <eg-grid-field label="[% l('Patron alias') %]" hidden>{{item.patron_alias}}</eg-grid-field>
   <eg-grid-field label="[% l('Request Date') %]" path='hold.request_time'></eg-grid-field>
   <eg-grid-field label="[% l('Capture Date') %]" path='hold.capture_time'></eg-grid-field>
   <eg-grid-field label="[% l('Available Date') %]" path='hold.shelf_time'></eg-grid-field>
@@ -67,6 +69,8 @@
   <eg-grid-field label="[% l('Queue Position') %]" path='queue_position' hidden></eg-grid-field>
   <eg-grid-field path='hold.*' parent-idl-class="ahr" hidden></eg-grid-field>
   <eg-grid-field path='copy.*' parent-idl-class="acp" hidden></eg-grid-field>
+  <eg-grid-field path='hold.usr.*' parent-idl-class="au" hidden></eg-grid-field>
+  <eg-grid-field path='hold.usr.card.*' parent-idl-class="ac" hidden></eg-grid-field>
   <eg-grid-field path='volume.*' parent-idl-class="acn" hidden></eg-grid-field>
   <eg-grid-field path='mvr.*' parent-idl-class="mvr" hidden></eg-grid-field>
 </eg-grid>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
index 161722c..a222018 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/services/holds.js
@@ -6,8 +6,8 @@ angular.module('egCoreMod')
 
 .factory('egHolds',
 
-       ['$modal','$q','egCore','egAlertDialog','egConfirmDialog','egAlertDialog',
-function($modal , $q , egCore , egAlertDialog , egConfirmDialog , egAlertDialog) {
+       ['$modal','$q','egCore','egUser','egConfirmDialog','egAlertDialog',
+function($modal , $q , egCore , egUser , egConfirmDialog , egAlertDialog) {
 
     var service = {};
 
@@ -366,6 +366,12 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog , egAlertDialog)
         hold.current_shelf_lib(egCore.org.get(hold.current_shelf_lib()));
         hold_data.id = hold.id();
 
+        if (hold.requestor() && typeof hold.requestor() != 'object')
+            hold.requestor(egUser.get(hold.requestor()));
+
+        if (hold.usr() && typeof hold.usr() != 'object')
+            hold.usr(egUser.get(hold.usr()));
+
         // current_copy is not always fleshed in the API
         if (hold.current_copy() && typeof hold.current_copy() != 'object')
             hold.current_copy(hold_data.copy);

commit 21e13fdfb07d26dce0440815817d737313ffddf9
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 09:06:53 2014 -0400

    LP#1402797 Fix "scan item for missing pieces" label to say Item instead of Patron
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/cat/item/missing_pieces.tt2 b/Open-ILS/src/templates/staff/cat/item/missing_pieces.tt2
index 2581ba7..c8751aa 100644
--- a/Open-ILS/src/templates/staff/cat/item/missing_pieces.tt2
+++ b/Open-ILS/src/templates/staff/cat/item/missing_pieces.tt2
@@ -30,15 +30,15 @@ s.CIRC_NOT_FOUND =
   <div class="input-group">
 
     <label class="input-group-addon" 
-      for="patron-lookup-barcode" >[% l('Patron Barcode') %]</label>
+      for="item-lookup-barcode" >[% l('Item Barcode') %]</label>
 
     <input 
       focus-me="selectMe" 
       select-me="selectMe"
       class="form-control barcode"
       ng-model="args.barcode" 
-      placeholder="[% l('Patron Barcode') %]"
-      id="patron-lookup-barcode" type="text"/> 
+      placeholder="[% l('Item Barcode') %]"
+      id="item-lookup-barcode" type="text"/> 
 
     <input class="btn btn-default" type="submit" value="[% l('Submit') %]"/>
   </div>

commit 428a96c5292ea4b910fc6f58f8f8ca0006090c8b
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 09:01:21 2014 -0400

    LP#1402797 Make "Checkout" the consistent spelling in the IDL
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 315b975..87a0604 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -3917,7 +3917,7 @@ SELECT  usr,
 			<field reporter:label="Circulating Item" name="target_copy" reporter:datatype="link"/>
 			<field reporter:label="Patron" name="usr" reporter:datatype="link"/>
 			<field reporter:label="Transaction Finish Date/Time" name="xact_finish" reporter:datatype="timestamp" />
-			<field reporter:label="Check Out Date/Time" name="xact_start" reporter:datatype="timestamp" />
+			<field reporter:label="Checkout Date/Time" name="xact_start" reporter:datatype="timestamp" />
 			<field reporter:label="Record Creation Date/Time" name="create_time" reporter:datatype="timestamp" />
 			<field reporter:label="Workstation" name="workstation" reporter:datatype="link"/>
 			<field reporter:label="Checkin Workstation" name="checkin_workstation" reporter:datatype="link"/>
@@ -3990,7 +3990,7 @@ SELECT  usr,
 			<field reporter:label="Circulating Item" name="target_copy" reporter:datatype="link"/>
 			<field reporter:label="Patron ZIP" name="usr_post_code" reporter:datatype="text"/>
 			<field reporter:label="Transaction Finish Date/Time" name="xact_finish" reporter:datatype="timestamp" />
-			<field reporter:label="Check Out Date/Time" name="xact_start" reporter:datatype="timestamp" />
+			<field reporter:label="Checkout Date/Time" name="xact_start" reporter:datatype="timestamp" />
 			<field reporter:label="Record Creation Date/Time" name="create_time" reporter:datatype="timestamp" />
 			<field reporter:label="Transaction Billings" name="billings" oils_persist:virtual="true" reporter:datatype="link"/>
 			<field reporter:label="Transaction Payments" name="payments" oils_persist:virtual="true" reporter:datatype="link"/>
@@ -4061,7 +4061,7 @@ SELECT  usr,
 			<field reporter:label="Circulating Item" name="target_copy" reporter:datatype="link"/>
 			<field reporter:label="Patron ZIP" name="usr_post_code" reporter:datatype="text"/>
 			<field reporter:label="Transaction Finish Date/Time" name="xact_finish" reporter:datatype="timestamp" />
-			<field reporter:label="Check Out Date/Time" name="xact_start" reporter:datatype="timestamp" />
+			<field reporter:label="Checkout Date/Time" name="xact_start" reporter:datatype="timestamp" />
 			<field reporter:label="Record Creation Date/Time" name="create_time" reporter:datatype="timestamp" />
 			<field reporter:label="Workstation" name="workstation" reporter:datatype="link"/>
 			<field reporter:label="Checkin Workstation" name="checkin_workstation" reporter:datatype="link"/>
@@ -10791,7 +10791,7 @@ SELECT  usr,
 			<field reporter:label="Circulating Item" name="target_copy" reporter:datatype="link"/>
 			<field reporter:label="Patron" name="usr" reporter:datatype="link"/>
 			<field reporter:label="Transaction Finish Date/Time" name="xact_finish" reporter:datatype="timestamp" />
-			<field reporter:label="Check Out Date/Time" name="xact_start" reporter:datatype="timestamp" />
+			<field reporter:label="Checkout Date/Time" name="xact_start" reporter:datatype="timestamp" />
 			<field reporter:label="Transaction Billings" name="billings" oils_persist:virtual="true" reporter:datatype="link"/>
 			<field reporter:label="Transaction Payments" name="payments" oils_persist:virtual="true" reporter:datatype="link"/>
 			<field reporter:label="Base Transaction" name="billable_transaction" oils_persist:virtual="true" reporter:datatype="link"/>

commit 751688cb2dca5e313faed3131b02d2f3b80ac4e6
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 08:59:02 2014 -0400

    LP#1402797 Comment out Hide/Show All in autogrid
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/share/t_autogrid.tt2 b/Open-ILS/src/templates/staff/share/t_autogrid.tt2
index 136252c..12299c5 100644
--- a/Open-ILS/src/templates/staff/share/t_autogrid.tt2
+++ b/Open-ILS/src/templates/staff/share/t_autogrid.tt2
@@ -134,6 +134,7 @@
           <span class="glyphicon glyphicon-floppy-save"></span>
           [% l('Save Columns') %]
         </a></li>
+<!--
         <li><a href ng-click="showAllColumns()">
           <span class="glyphicon glyphicon-resize-full"></span>
           [% l('Show All Columns') %]
@@ -142,6 +143,7 @@
           <span class="glyphicon glyphicon-resize-small"></span>
           [% l('Hide All Columns') %]
         </a></li>
+-->
         <li><a href ng-click="resetColumns()">
           <span class="glyphicon glyphicon-refresh"></span>
           [% l('Reset Columns') %]

commit d2c2967141402219c589ef2a17c3de5379a944c5
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Oct 30 08:57:45 2014 -0400

    LP#1402797 Add label to custom penalty dropdown
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2 b/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
index 1cd94f0..3ddad54 100644
--- a/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
+++ b/Open-ILS/src/templates/staff/circ/share/t_new_message_dialog.tt2
@@ -24,6 +24,7 @@
         </div>
         <div class="col-md-4 pull-right">
           <select class="form-control" ng-model="args.penalty">
+            <option value="">[% l('Optional Penalty Type') %]</option>
             <option ng-selected="args.penalty < 100"></option>
             <option ng-repeat="penalty in penalties" 
               value="{{penalty.id()}}">{{penalty.label()}}</option>

commit 6f7277e56ed56558483af7818f39939c10f1317c
Author: Mike Rylander <mrylander at gmail.com>
Date:   Mon Sep 22 12:03:48 2014 -0400

    LP#1402797 Push explicitly added columns to the top and keep the explicit order, then sort the rest by their labels
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/web/js/ui/default/staff/services/grid.js b/Open-ILS/web/js/ui/default/staff/services/grid.js
index 2dca409..9dc5b7d 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -1039,6 +1039,15 @@ angular.module('egGridMod',
                         {idl_field : field, idl_class : class_obj});
                 });
 
+                cols.columns = cols.columns.sort(
+                    function(a, b) {
+                        if (a.explicit) return -1;
+                        if (b.explicit) return 1;
+                        return a.label < b.label ? -1 : 1;
+                    }
+                );
+
+
             } else {
                 console.error(
                     "egGrid: wildcard path does not resolve to an object: "
@@ -1090,6 +1099,8 @@ angular.module('egGridMod',
             if (column.path && column.path.match(/\*$/)) 
                 return cols.expandPath(colSpec);
 
+            if (!fromExpand) column.explicit = true;
+
             if (!column.name) column.name = column.path;
             if (!column.path) column.path = column.name;
 

commit 434f2de78ea8fb8470b7668ef4c76bc27dfe3288
Author: Mike Rylander <mrylander at gmail.com>
Date:   Mon Sep 22 12:02:55 2014 -0400

    LP#1402797 Add catalog search to the search menu in the nav bar
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/navbar.tt2 b/Open-ILS/src/templates/staff/navbar.tt2
index 6d0e6d8..fe0695a 100644
--- a/Open-ILS/src/templates/staff/navbar.tt2
+++ b/Open-ILS/src/templates/staff/navbar.tt2
@@ -49,6 +49,12 @@
               <span>[% l('Search for Copies by Barcode') %]</span>
             </a>
           </li>
+          <li>
+            <a href="./cat/catalog/index" target="_self">
+              <span class="glyphicon glyphicon-search"></span>
+              <span>[% l('Search the Catalog') %]</span>
+            </a>
+          </li>
         </ul>
       </li>
 

commit df2c16dc63c16ee37e7beb938ae1f5eb85580ffc
Author: Mike Rylander <mrylander at gmail.com>
Date:   Mon Sep 22 12:02:33 2014 -0400

    LP#1402797 Add checkout/in workstation colums to the available set
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
index 71fc1a0..5c87466 100644
--- a/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
+++ b/Open-ILS/src/templates/staff/circ/patron/t_items_out.tt2
@@ -55,6 +55,8 @@
     </a>
   </eg-grid-field>
   <eg-grid-field label="[% l('Due Date') %]" path='due_date' dateformat='short'></eg-grid-field>
+  <eg-grid-field label="[% l('Workstation') %]" path='workstation.name'></eg-grid-field>
+  <eg-grid-field label="[% l('Checkin Workstation') %]" path='checkin_workstation.name'></eg-grid-field>
   <eg-grid-field label="[% l('Checkout / Renewal Library') %]" path='circ_lib.shortname'></eg-grid-field>
   <eg-grid-field label="[% l('Renewals Remaining') %]" path='renewal_remaining'></eg-grid-field>
   <eg-grid-field label="[% l('Fines Stopped') %]" path='stop_fines'></eg-grid-field>
diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
index fa68501..3f3518d 100644
--- a/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
+++ b/Open-ILS/web/js/ui/default/staff/circ/patron/items_out.js
@@ -81,7 +81,7 @@ function($scope,  $q,  $routeParams,  egCore , egUser,  patronSvc ,
         return egCore.pcrud.search('circ', {id : id_list},
             {   flesh : 4,
                 flesh_fields : {
-                    circ : ['target_copy'],
+                    circ : ['target_copy', 'workstation', 'checkin_workstation'],
                     acp : ['call_number'],
                     acn : ['record'],
                     bre : ['simple_record']

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/examples/fm_IDL.xml                       |   15 ++-
 Open-ILS/src/templates/staff/base_js.tt2           |    1 +
 .../staff/cat/bucket/record/t_bucket_export.tt2    |    2 -
 .../src/templates/staff/cat/catalog/t_catalog.tt2  |   10 +-
 .../src/templates/staff/cat/catalog/t_holds.tt2    |    5 +
 .../templates/staff/cat/item/missing_pieces.tt2    |    6 +-
 .../src/templates/staff/circ/checkin/t_checkin.tt2 |   21 ++--
 .../src/templates/staff/circ/holds/t_pull_list.tt2 |    2 +
 .../templates/staff/circ/holds/t_shelf_list.tt2    |    4 +
 .../templates/staff/circ/in_house_use/index.tt2    |    4 +-
 Open-ILS/src/templates/staff/circ/patron/index.tt2 |   12 +-
 .../src/templates/staff/circ/patron/t_alerts.tt2   |    4 +
 .../src/templates/staff/circ/patron/t_bills.tt2    |   15 ++-
 .../src/templates/staff/circ/patron/t_checkout.tt2 |    4 +-
 .../templates/staff/circ/patron/t_holds_list.tt2   |    8 +-
 .../templates/staff/circ/patron/t_items_out.tt2    |   34 +++++-
 .../src/templates/staff/circ/patron/t_search.tt2   |    8 +-
 .../src/templates/staff/circ/patron/t_summary.tt2  |    5 +
 .../staff/circ/share/t_new_message_dialog.tt2      |    5 +-
 .../staff/circ/share/t_uncancel_hold_dialog.tt2    |   17 +++
 Open-ILS/src/templates/staff/navbar.tt2            |    6 +
 Open-ILS/src/templates/staff/share/t_autogrid.tt2  |    9 +-
 Open-ILS/src/templates/staff/statusbar.tt2         |    8 ++
 Open-ILS/web/js/ui/default/staff/Gruntfile.js      |    1 +
 .../web/js/ui/default/staff/cat/catalog/app.js     |    2 +-
 .../web/js/ui/default/staff/circ/checkin/app.js    |    2 +
 .../web/js/ui/default/staff/circ/patron/app.js     |  129 ++++++++++++++++----
 .../web/js/ui/default/staff/circ/patron/bills.js   |   10 +-
 .../js/ui/default/staff/circ/patron/checkout.js    |   11 +-
 .../js/ui/default/staff/circ/patron/items_out.js   |   62 +++++++++-
 .../web/js/ui/default/staff/circ/services/circ.js  |   29 ++++-
 .../web/js/ui/default/staff/circ/services/holds.js |   61 +++++++++-
 .../web/js/ui/default/staff/services/coresvc.js    |    7 +-
 Open-ILS/web/js/ui/default/staff/services/date.js  |   61 +++++++++
 Open-ILS/web/js/ui/default/staff/services/grid.js  |  114 +++++++++++-------
 Open-ILS/web/js/ui/default/staff/services/print.js |    2 +-
 Open-ILS/web/js/ui/default/staff/services/ui.js    |    2 +-
 .../web/js/ui/default/staff/test/karma.conf.js     |    1 +
 .../web/js/ui/default/staff/test/unit/egDate.js    |   18 +++
 39 files changed, 581 insertions(+), 136 deletions(-)
 create mode 100644 Open-ILS/src/templates/staff/circ/share/t_uncancel_hold_dialog.tt2
 create mode 100644 Open-ILS/web/js/ui/default/staff/services/date.js
 create mode 100644 Open-ILS/web/js/ui/default/staff/test/unit/egDate.js


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list