'[% ctx.media_prefix %]/js/ui/default/staff/build/css/ngToast-animations.min.css',
'[% ctx.media_prefix %]/js/ui/default/staff/build/css/tree-control.css',
'[% ctx.media_prefix %]/js/ui/default/staff/build/css/tree-control-attribute.css',
+ '[% ctx.media_prefix %]/js/ui/default/staff/build/css/tablesort.css',
'[% ctx.base_path %]/staff/css/print.css',
'[% ctx.base_path %]/staff/css/cat.css',
'[% ctx.base_path %]/staff/css/style.css',
'[% ctx.media_prefix %]/js/ui/default/staff/build/js/angular-tree-control.js',
'[% ctx.media_prefix %]/js/ui/default/staff/build/js/iframeResizer.min.js',
'[% ctx.media_prefix %]/js/ui/default/staff/build/js/ng-order-object-by.js',
+ '[% ctx.media_prefix %]/js/ui/default/staff/build/js/angular-tablesort.js',
'[% ctx.media_prefix %]/js/ui/default/staff/build/js/lovefield.min.js',
'[% ctx.media_prefix %]/js/ui/default/staff/build/fonts/glyphicons-halflings-regular.woff',
'[% ctx.media_prefix %]/js/dojo/opensrf/JSON_v1.js',
s.PATRON_NOT_FOUND = "[% l('Patron not found') %]";
s.PATRON_BLOCKED = "[% l('Patron blocked') %]";
s.BAD_BARCODE = "[% l('Bad item barcode') %]";
+ s.BAD_PATRON_BARCODE = "[% l('Bad patron barcode') %]";
s.ITEM_NOT_FOUND = "[% l('Item not found') %]";
+ s.CONFIRM_CLEAR_PENDING = "[% l('Clear pending transactions') %]";
+ s.CONFIRM_CLEAR_PENDING_BODY = "[% l('Are you certain you want to clear these pending offline transactions? This action is not reversable, and they cannot be recovered after clearing!') %]";
}]);
</script>
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-4">
+ [% l('Due Date:') %]
+ </div>
+ <div class="col-md-4">
+ <eg-date-input id="co_duedate" ng-model="shared.due_date"></eg-date-input>
+ </div>
+ <div class="col-md-3">
+ <select class="form-control" ng-model="shared.due_date_offset" ng-change="resetDueDate()">
+ <option value="">[% l('No Offset') %]</option>
+ <option value="3">[% l('Today + 3 days') %]</option>
+ <option value="7">[% l('Today + 7 days') %]</option>
+ <option value="14">[% l('Today + 14 days') %]</option>
+ <option value="30">[% l('Today + 30 days') %]</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="row pad-vert">
+ <div class="col-md-1"></div>
+ <div class="col-md-4">
[% l('Patron barcode:') %]
</div>
<div class="col-md-7">
</div>
<div class="row pad-vert">
- <div class="col-md-1"></div>
- <div class="col-md-4">
- [% l('Due Date:') %]
+ <div class="col-md-2">
+ <button class="btn btn-warning" ng-click="clear('checkout')">[% l('Clear') %]</button>
</div>
<div class="col-md-4">
- <eg-date-input id="co_duedate" ng-model="shared.due_date"></eg-date-input>
- </div>
- <div class="col-md-3">
- <select class="form-control" ng-model="shared.due_date_offset" ng-change="resetDueDate()">
- <option value="">[% l('No Offset') %]</option>
- <option value="3">[% l('3 days') %]</option>
- <option value="7">[% l('7 days') %]</option>
- <option value="14">[% l('14 days') %]</option>
- <option value="30">[% l('30 days') %]</option>
- </select>
- </div>
- </div>
-
- <div class="row pad-vert">
- <div class="col-md-6">
- <button class="btn btn-warning" ng-click="clear('checkout')">[% l('Clear') %]</button>
+ <input id="do_check_co" type="checkbox" ng-model="strict_barcode" ng-click="changeCheck()"></input>
+ <label for="do_check_co">[% l('Strict Barcode') %]</label>
</div>
<div class="col-md-6">
<input id="do_print_co" type="checkbox" ng-model="do_print" ng-click="changePrint()"></input>
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-4">
- [% l('Patron barcode:') %]
+ [% l('Due Date:') %]
</div>
- <div class="col-md-7">
- <input class="form-control" type="text" ng-model="renew.patron_barcode" next-on-enter="re_barcode"/>
+ <div class="col-md-4">
+ <eg-date-input ng-model="shared.due_date"></eg-date-input>
+ </div>
+ <div class="col-md-3">
+ <select class="form-control" ng-model="shared.due_date_offset" ng-change="resetDueDate()">
+ <option value="">[% l('No Offset') %]</option>
+ <option value="3">[% l('Today + 3 days') %]</option>
+ <option value="7">[% l('Today + 7 days') %]</option>
+ <option value="14">[% l('Today + 14 days') %]</option>
+ <option value="30">[% l('Today + 30 days') %]</option>
+ </select>
</div>
</div>
<div class="row pad-vert">
<div class="col-md-1"></div>
<div class="col-md-4">
- [% l('Item Barcode:') %]
+ [% l('Patron barcode:') %]
</div>
<div class="col-md-7">
- <input class="form-control" type="text" ng-model="renew.barcode" id="re_barcode" eg-enter="!notEnough('renew') && add('renew')"/>
+ <input class="form-control" type="text" ng-model="renew.patron_barcode" next-on-enter="re_barcode"/>
</div>
</div>
<div class="row pad-vert">
<div class="col-md-1"></div>
<div class="col-md-4">
- [% l('Due Date:') %]
- </div>
- <div class="col-md-4">
- <eg-date-input ng-model="shared.due_date"></eg-date-input>
+ [% l('Item Barcode:') %]
</div>
- <div class="col-md-3">
- <select class="form-control" ng-model="shared.due_date_offset" ng-change="resetDueDate()">
- <option value="">[% l('No Offset') %]</option>
- <option value="3">[% l('3 days') %]</option>
- <option value="7">[% l('7 days') %]</option>
- <option value="14">[% l('14 days') %]</option>
- <option value="30">[% l('30 days') %]</option>
- </select>
+ <div class="col-md-7">
+ <input class="form-control" type="text" ng-model="renew.barcode" id="re_barcode" eg-enter="!notEnough('renew') && add('renew')"/>
</div>
</div>
<div class="row pad-vert">
- <div class="col-md-6">
+ <div class="col-md-2">
<button class="btn btn-warning" ng-click="clear('renew')">[% l('Clear') %]</button>
</div>
+ <div class="col-md-4">
+ <input id="do_check_r" type="checkbox" ng-model="strict_barcode" ng-click="changeCheck()"></input>
+ <label for="do_check_r">[% l('Strict Barcode') %]</label>
+ </div>
<div class="col-md-6">
<input id="do_print_r" type="checkbox" ng-model="do_print" ng-click="changePrint()"></input>
<label for="do_print_r">[% l('Print receipt') %]</label>
<!-- left-hand side -->
<div class="col-md-6 container" style="border-right:solid 1px;">
- <div class="row pad-vert">
+ <div class="row">
<div class="col-md-1"></div>
<div class="col-md-5">
[% l('Use count:') %]
</div>
</div>
- <div class="row">
+ <div class="row pad-vert">
<div class="col-md-1"></div>
<div class="col-md-5">
[% l('Item Barcode:') %]
</div>
<div class="row pad-vert">
- <div class="col-md-6">
+ <div class="col-md-2">
<button class="btn btn-warning" ng-click="clear('in_house_use')">[% l('Clear') %]</button>
</div>
+ <div class="col-md-4">
+ <input id="do_check_ihu" type="checkbox" ng-model="strict_barcode" ng-click="changeCheck()"></input>
+ <label for="do_check_ihu">[% l('Strict Barcode') %]</label>
+ </div>
<div class="col-md-6">
<input id="do_print_ihu" type="checkbox" ng-model="do_print" ng-click="changePrint()"></input>
<label for="do_print_ihu">[% l('Print receipt') %]</label>
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-5">
- [% l('Item Barcode:') %]
+ [% l('Checkin Date:') %]
</div>
<div class="col-md-6">
- <input class="form-control" type="text" ng-model="checkin.barcode" eg-enter="!notEnough('checkin') && add('checkin')"/>
+ <eg-date-input ng-model="checkin.backdate"></eg-date-input>
</div>
</div>
<div class="row pad-vert">
<div class="col-md-1"></div>
<div class="col-md-5">
- [% l('Checkin Date:') %]
+ [% l('Item Barcode:') %]
</div>
<div class="col-md-6">
- <eg-date-input ng-model="checkin.backdate"></eg-date-input>
+ <input class="form-control" type="text" ng-model="checkin.barcode" eg-enter="!notEnough('checkin') && add('checkin')"/>
</div>
</div>
<div class="row pad-vert">
- <div class="col-md-6">
+ <div class="col-md-2">
<button class="btn btn-warning" ng-click="clear('checkin')">[% l('Clear') %]</button>
</div>
+ <div class="col-md-4">
+ <input id="do_check_ci" type="checkbox" ng-model="strict_barcode" ng-click="changeCheck()"></input>
+ <label for="do_check_ci">[% l('Strict Barcode') %]</label>
+ </div>
<div class="col-md-6">
<input id="do_print_ci" type="checkbox" ng-model="do_print" ng-click="changePrint()"></input>
<label for="do_print_ci">[% l('Print receipt') %]</label>
</div>
<div class="row">
<div class="col-md-12">
- <table class="table">
+ <table class="table" ts-wrapper>
<thead>
<tr>
- <th>[% l('Description') %]</th>
- <th>[% l('Date Created') %]</th>
+ <th ts-criteria="org">[% l('Organization') %]</th>
+ <th ts-criteria="creator">[% l('Created By') %]</th>
+ <th ts-criteria="description">[% l('Description') %]</th>
+ <th ts-criteria="create_time|parseInt" ts-default="descending">[% l('Date Created') %]</th>
<th>[% l('Upload Count') %]</th>
<th>[% l('Transactions Processed') %]</th>
- <th>[% l('Date Completed') %]</th>
+ <th ts-criteria="end_time|parseInt">[% l('Date Completed') %]</th>
<th></th>
</tr>
</thead>
<tbody>
- <tr
+ <tr ts-repeat
ng-repeat="ses in sessions track by $index"
ng-click="setSession(ses, $index)"
ng-class="{'bg-info':current_session_index==$index}"
>
+ <td>{{ses.org}}</td>
+ <td>{{ses.creator}}</td>
<td>{{ses.description}}</td>
<td>{{createDate(ses.create_time, true) | date:'short'}}</td>
<td>{{ses.total}}</td>
ng-disabled="!logged_in || (!xact.command.patron_barcode && xact.command.user.card.barcode)"
ng-click="retrievePatron(xact.command.patron_barcode)">[% l('Patron') %]</button>
<button
- class="btn btn-info btn-xs"
+ class="btn btn-info btn-xs hidden"
ng-disabled="!logged_in"
ng-click="retrieveDetails(xact)">[% l('Details') %]</button>
</td>
<!-- offline page app -->
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/file.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/offline.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/build/js/angular-tablesort.js"></script>
<script>
angular.module('egCoreMod').run(['egStrings', function(s) {
s.REG_ADDR_TYPE = "[% l('Mailing') %]";
}]);
</script>
<link rel="stylesheet" href="[% ctx.base_path %]/staff/css/circ.css" />
+<link rel="stylesheet" href="[% ctx.media_prefix %]/js/ui/default/staff/build/css/tablesort.css" />
[% END %]
<div ng-view></div>
'node_modules/iframe-resizer/js/iframeResizer.map',
'node_modules/iframe-resizer/js/iframeResizer.contentWindow.min.js',
'node_modules/angular-order-object-by/src/ng-order-object-by.js',
+ 'node_modules/angular-tablesort/js/angular-tablesort.js',
'node_modules/lovefield/dist/lovefield.min.js',
'node_modules/lovefield/dist/lovefield.min.js.map'
]
'node_modules/ngtoast/dist/ngToast-animations.min.css',
'node_modules/angular-tree-control/css/tree-control.css',
'node_modules/angular-tree-control/css/tree-control-attribute.css',
+ 'node_modules/angular-tablesort/tablesort.css',
]
}]
},
lf.isOffline = true;
-angular.module('egOffline', ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'ngToast'])
+angular.module('egOffline', ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'ngToast', 'tableSort'])
.config(
['$routeProvider','$locationProvider','$compileProvider',
}
return $q.reject();
}).then(function() {
+ var creator_list = [$q.when()];
angular.forEach($scope.sessions, function (s) {
s.total = 0;
+ s.org = egCore.org.get(s.org).shortname();
+ creator_list.push(egCore.pcrud.retrieve('au',s.creator).then(function(u) {
+ s.creator = u.family_name();
+ }));
angular.forEach(s.scripts, function(sc) {
s.total += sc.count;
});
});
+
+ return $q.all(creator_list);
});
}
}
).then(function(res) {
if (res.data.ilsevent == "0") {
- return $scope.clear_pending().then(function() {
+ return $scope.clear_pending(true).then(function() {
return $scope.refreshSessions();
});
} else {
])
.controller('OfflineCtrl',
- ['$q','$scope','$location','$window','egCore','egLovefield','$routeParams','$timeout','$http','ngToast',
- function($q , $scope , $location , $window , egCore , egLovefield , $routeParams , $timeout , $http , ngToast) {
+ ['$q','$scope','$location','$window','egCore','egLovefield','$routeParams','$timeout','$http','ngToast','egConfirmDialog',
+ function($q , $scope , $location , $window , egCore , egLovefield , $routeParams , $timeout , $http , ngToast , egConfirmDialog) {
$scope.active_tab = $routeParams.tab || 'checkout';
$scope.blocked_patron = null;
})[0].name;
}
+ $scope.changeCheck = function () {
+ $scope.strict_barcode = !$scope.strict_barcode;
+ $scope.do_check_changed = true;
+ egCore.hatch.setItem('eg.offline.strict_barcode', $scope.strict_barcode)
+ }
+
$scope.changePrint = function () {
$scope.do_print = !$scope.do_print;
$scope.do_print_changed = true;
+ egCore.hatch.setItem('eg.offline.print_receipt', $scope.do_print)
}
$scope.logged_in = egCore.auth.token() ? true : false;
if (!$scope.logged_in && $routeParams.tab == 'session')
$scope.active_tab = 'checkout';
+ egCore.hatch.getItem('eg.offline.print_receipt')
+ .then(function(setting) {
+ $scope.do_print = setting;
+ if (setting !== undefined) $scope.do_print_changed = true;
+ });
+
+ egCore.hatch.getItem('eg.offline.strict_barcode')
+ .then(function(setting) {
+ $scope.strict_barcode = setting;
+ if (setting !== undefined) $scope.do_check_changed = true;
+ });
+
egCore.hatch.getItem('eg.workstation.all')
.then(function(all) {
if (all && all.length) {
});
}
- $scope.clear_pending = function () {
- return egLovefield.destroyPendingOfflineXacts().then(function () {
- return $scope.retrieve_pending();
+ $scope.clear_pending = function (skip_confirm) {
+ if (skip_confirm) {
+ return egLovefield.destroyPendingOfflineXacts().then(function () {
+ return $scope.retrieve_pending();
+ });
+ }
+ return egConfirmDialog.open(
+ egCore.strings.CONFIRM_CLEAR_PENDING,
+ egCore.strings.CONFIRM_CLEAR_PENDING_BODY,
+ {}
+ ).result.then(function() {
+ return egLovefield.destroyPendingOfflineXacts().then(function () {
+ return $scope.retrieve_pending();
+ });
});
+
}
$scope.retrieve_pending();
$scope.$watch('active_tab', function (n,o) {
+ if (n != o && !$scope.do_check_changed && n != 'checkout') $scope.strict_barcode = false;
+ if (n != o && !$scope.do_check_changed && n == 'checkout') $scope.strict_barcode = true;
if (n != o && !$scope.do_print_changed && n != 'checkout') $scope.do_print = false;
if (n != o && !$scope.do_print_changed && n == 'checkout') $scope.do_print = true;
if (n != o && n == 'session') $scope.retrieve_pending();
$scope.resetDueDate = function (xtype) {
$scope.shared.due_date = new Date();
+ $scope.shared.due_date.setDate($scope.shared.due_date.getDate() + parseInt($scope.shared.due_date_offset));
}
$scope.notEnough = function (xtype) {
var pbarcode = $scope[xtype].patron_barcode;
var backdate = $scope[xtype].backdate;
+ if ($scope.strict_barcode && pbarcode) {
+ if (!check_barcode(pbarcode)) {
+ $scope.bad_barcode = xtype;
+ ngToast.warning(egCore.strings.BAD_PATRON_BARCODE);
+ egCore.audio.play('warning.offline.bad_barcode');
+ return;
+ }
+ }
+
if ($scope.strict_barcode && $scope[xtype].barcode) {
if (!check_barcode($scope[xtype].barcode)) {
$scope.bad_barcode = xtype;
var now = new Date().getTime();
now = now / 1000;
- if ($scope.shared.due_date_offset) {
- var due = parseInt(now * 1000);
- due += parseInt($scope.shared.due_date_offset) * 86400000;
- $scope.shared.due_date = new Date(due);
- }
-
if ($scope[xtype].noncat_type) $scope[xtype].noncat = 1;
if ($scope.shared.due_date && (xtype == 'checkout' || xtype == 'renew')) {
"angular-mocks": "~1.5.0",
"angular-route": "~1.5.0",
"angular-tree-control": "~0.2.28",
+ "angular-tablesort": "^1.4.1",
"angular-order-object-by": "rxfork/ngOrderObjectBy#npm",
"lovefield": "*",
"bootstrap": "~3.3.6",