--- /dev/null
+[%
+ WRAPPER "staff/t_base.tt2";
+ ctx.page_title = l("Check In");
+ ctx.page_app = "egCheckinApp";
+ ctx.page_ctrl = "CheckinCtrl";
+%]
+
+[% BLOCK APP_JS %]
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/list.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/user.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/checkin/app.js"></script>
+[% END %]
+
+<style>
+ /* MOVE ME */
+ .pad-horiz {padding : 0px 10px 0px 10px; }
+ .pad-vert {padding : 20px 0px 10px 0px;}
+ #patron-checkin-barcode { width: 18em; }
+</style>
+
+<!-- checkin form -->
+<div class="row pad-vert">
+ <div class="col-lg-10">
+ <div class="pad-horiz">
+ <form ng-submit="checkin(checkinArgs)">
+ <input focus-me="focusMe" ng-model="checkinArgs.copy_barcode"
+ id="patron-checkin-barcode" type="text"/>
+ <span class="pad-horiz"></span>
+ <input type="submit" value="[% l('Submit') %]"/>
+ </form>
+ </div>
+ </div>
+ <div class="col-lg-2 text-right">
+ <div class="btn-group text-left">
+ [% INCLUDE 'staff/parts/column_picker.tt2' listname='checkins' %]
+ </div>
+ </div>
+</div>
+
+[% INCLUDE 'staff/circ/checkin/t_checkin_table.tt2' %]
+
+
+[% END %]
--- /dev/null
+
+[%
+# checkin table columns
+COLUMNS = [
+{label => l('Barcode'), name => 'copy_barcode' display => 1},
+{label => l('Circ ID'), name => 'payload.circ.id', display => 1},
+{label => l('Due Date'), name => 'payload.circ.due_date' display => 1},
+# once we are handling all response types, we probably don't need to show
+# Response. Or, at least, make it more friendly / localizable
+{label => l('Response'), name => 'textcode', display => 1},
+{label => l('Title'), name => 'payload.record.title', display => 1},
+{label => l('Author'), name => 'payload.record.author', display => 1},
+{label => l('Call Number'),name => 'payload.copy.call_number.label', display => 1},
+{label => l('Alert Msg'), name => 'payload.copy.alert_message' display => 1},
+]
+%]
+
+<!-- tell JS about our columns so they can be dynamically managed -->
+<div ng-init="
+checkins.setColumns([
+[%- FOR col IN COLUMNS %]
+{label:'[% col.label %]',name:'[% col.name %]'[% IF col.display %],display:true[% END %]}[% IF !loop.last; ','; END -%]
+[% END %]
+])">
+</div>
+
+<div class="row">
+ <div class="col-lg-12">
+ <table class="table table-hover table-condensed table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th ng-repeat="col in checkins.allColumns"
+ ng-show="checkins.displayColumns[col.name]">
+ {{col.label}}
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="checkin in checkins.items | reverse track by $index">
+ <td>{{checkins.count() - $index}}</td>
+ <td ng-repeat="col in checkins.allColumns"
+ ng-show="checkins.displayColumns[col.name]">
+ {{checkins.fieldValue(checkin, col.name)}}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
For icons, see http://getbootstrap.com/components/#glyphicons
-->
-<div class="navbar navbar-default navbar-static-top"
+<div id="top-navbar" class="navbar navbar-default navbar-static-top"
role="navigation" ng-controller="NavCtrl">
<!-- navbar-header here needed for supporting angular-ui-bootstrap -->
[% l('Patron Search') %]
</a>
</li>
+ <li>
+ <a href="./circ/checkin/index" target="_self">
+ <span class="glyphicon glyphicon-save"></span>
+ [% l('Check In') %]
+ </a>
+ </li>
<li class="divider"></li>
<li class="dropdown-header">Sub Menu Test</li>
<li><a href="javascript:;">Test Item</a></li>
data-toggle="dropdown"></a>
<ul class="dropdown-menu">
<li class="disabled"><a href="" ng-click="" target="_self">
+ <span class="glyphicon glyphicon-random"></span>
[% l('Change Operator') %]</a></li>
- <li><a href="./login" ng-click="logout()"
- target="_self">[% l('Log Out') %]</a></li>
+ <li>
+ <a href="./login" ng-click="logout()" target="_self">
+ <span class="glyphicon glyphicon-log-out"></span>
+ [% l('Log Out') %]
+ </a>
+ </li>
</ul>
</li>
</ul>
+<style>
+ /* TODO: move me */
+ #splash-nav .panel-body div {
+ padding-bottom: 10px;
+ }
+</style>
+
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
</div>
</div>
<br/>
- <div class="row">
+ <div class="row" id="splash-nav">
<div class="col-lg-4">
<div class="panel panel-success">
</div>
<div class="panel-body">
<div>
- <img src="/xul/server/skin/media/images/portal/forward.png"/>
- <a target="_self" href="./circ/patron/search">[% l('Check Out') %]</a>
+ <img src="/xul/server/skin/media/images/portal/retreivepatron.png"/>
+ <a target="_self" href="./circ/patron/search">[% l('Find Patrons') %]</a>
+ </div>
+ <div>
+ <img src="/xul/server/skin/media/images/portal/back.png"/>
+ <a target="_self" href="./circ/checkin/index">[% l('Check In Items') %]</a>
</div>
</div>
</div>
--- /dev/null
+angular.module('egCheckinApp', ['ngRoute', 'ui.bootstrap',
+ 'egCoreMod', 'egUiMod', 'egListMod', 'egUserMod'])
+
+.config(function($routeProvider, $locationProvider) {
+ $locationProvider.html5Mode(true);
+ // no routes needed
+})
+
+/**
+ * checkin service
+ */
+.factory('checkinSvc',
+ ['$q','egList','egNet','egAuth','egUser','egEnv','egOrg','egList',
+function($q, egList, egNet, egAuth, egUser, egEnv, egOrg, egList) {
+
+ var service = {};
+ service.checkins = egList.create();
+ return service;
+}])
+
+/**
+ * Manages checkin
+ * */
+.controller('CheckinCtrl',
+ ['$scope','egStartup','checkinSvc','egNet','egAuth',
+function($scope, egStartup, checkinSvc, egNet, egAuth) {
+
+ // run egStartup here since it's not handled via resolver
+ egStartup.go().then(
+ function() {
+ // handle post-startup business
+ }
+ );
+
+ $scope.focusMe = true;
+ $scope.checkins = checkinSvc.checkins;
+
+ $scope.checkin = function(args) {
+ performCheckin(angular.copy(args));
+ args.copy_barcode = ''; // reset UI
+ }
+
+ function performCheckin(args, override) {
+ var method = 'open-ils.circ.checkin';
+ if (override) method += '.override';
+
+ egNet.request('open-ils.circ', method, egAuth.token(), args)
+ .then(function(evt) {
+
+ if (!evt) {
+ console.error('no checkin response received');
+ return;
+ }
+
+ if (angular.isArray(evt)) evt = evt[0];
+ evt.id = checkinSvc.checkins.count();
+ evt.copy_barcode = args.copy_barcode;
+ handleCheckinResponse(evt, args, override);
+ });
+ }
+
+ function handleCheckinResponse(evt, args, override) {
+
+ switch (evt.textcode) {
+ case 'SUCCESS':
+ case 'ROUTE_ITEM':
+ case 'ASSET_COPY_NOT_FOUND':
+ checkinSvc.checkins.items.push(evt);
+ break;
+ default:
+ console.warn('unhandled checkin response : ' + evt.textcode);
+ console.debug('checkin: ' + js2JSON(evt));
+ // push it on the list so the user can at least see
+ // something happened.
+ $scope.checkins.items.push(evt);
+ }
+ }
+}])
+
// TODO: $inject array
function(egAuth, egUser, egNet, egEnv, egPCRUD, egStartup, egOrg) {
- // load needed org unit settings and munge the data into
- // key/value pairs for ease of use.
+ // fetch the org settings we care about during egStartup
+ // and toss them into egEnv as egEnv.aous[name] = value.
egEnv.classLoaders.aous = function() {
- return egNet.request(
- 'open-ils.actor',
- 'open-ils.actor.ou_setting.ancestor_default.batch',
- egAuth.user().ws_ou(),
- ['circ.obscure_dob'],
- egAuth.token()
- ).then(function(blob) {
- var settings = {};
- angular.forEach(blob, function(val, key) {
- if (val) { settings[key] = val.value }
- });
- egEnv.aous = settings;
- });
+ return egOrg.settings(['circ.obscure_dob'])
+ .then(function(settings) { egEnv.aous = settings });
}
egEnv.loadClasses.push('aous');
*/
angular.module('egCoreMod')
-.factory('egOrg', ['egEnv', 'egAuth', 'egPCRUD',
-function(egEnv, egAuth, egPCRUD) {
+.factory('egOrg',
+ ['$q','egEnv','egAuth','egNet',
+function($q, egEnv, egAuth, egNet) {
var service = {};
return list;
}
+ // returns a promise, resolved with a hash of setting name =>
+ // setting value for the selected org unit. Org unit defaults to
+ // auth workstation org unit.
+ service.settings = function(names, ou_id) {
+ var deferred = $q.defer();
+ ou_id = ou_id || egAuth.user().ws_ou();
+ egNet.request(
+ 'open-ils.actor',
+ 'open-ils.actor.ou_setting.ancestor_default.batch',
+ ou_id, names, egAuth.token()
+ ).then(function(blob) {
+ var settings = {};
+ angular.forEach(blob, function(val, key) {
+ // val is either null or a structure containing
+ // the value
+ if (val) { settings[key] = val.value }
+ });
+ deferred.resolve(settings);
+ });
+ return deferred.promise;
+ }
+
+
return service;
}]);