<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/curbside/services/core.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/curbside/app.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/curbside/directives/to_be_staged_manager.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/curbside/directives/staged_manager.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/curbside/directives/arrived_manager.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/curbside/directives/delivered_manager.js"></script>
<script>
angular.module('egCoreMod').run(['egStrings', function(s) {
s.SUCCESS_CURBSIDE_MARK_STAGED = "[% l('Marked curbside appointment {{slot_id}} as staged') %]";
s.NOTFOUND_CURBSIDE_MARK_STAGED = "[% l('Could not find curbside appointment {{slot_id}} to mark as staged') %]";
s.FAILED_CURBSIDE_MARK_STAGED = "[% l('Failed to mark curbside appointment {{slot_id}} as staged: {{evt_code}}') %]";
+ s.SUCCESS_CURBSIDE_MARK_ARRIVED = "[% l('Marked curbside appointment {{slot_id}} as patron arrived') %]";
+ s.NOTFOUND_CURBSIDE_MARK_ARRIVED = "[% l('Could not find curbside appointment {{slot_id}} to mark as patron arrived') %]";
+ s.FAILED_CURBSIDE_MARK_ARRIVED = "[% l('Failed to mark curbside appointment {{slot_id}} as patron arrived: {{evt_code}}') %]";
+ s.SUCCESS_CURBSIDE_MARK_DELIVERED = "[% l('Marked curbside appointment {{slot_id}} as delivered') %]";
+ s.NOTFOUND_CURBSIDE_MARK_DELIVERED = "[% l('Could not find curbside appointment {{slot_id}} to mark as delivered') %]";
+ s.FAILED_CURBSIDE_MARK_DELIVERED = "[% l('Failed to mark curbside appointment {{slot_id}} as delivered: {{evt_code}}') %]";
}]);
</script>
[% END %]
--- /dev/null
+<div>
+ <div ng-style="{visibility : refreshNeeded ? 'visible' : 'hidden'}" class="alert alert-warning">
+ [% l('Updates to the list of appointments whose patron has arrived are available. Please refresh.') %]
+ </div>
+ <eg-grid
+ id-field="slot_id"
+ features="-sort,-multisort,-picker,-multiselect"
+ items-provider="gridDataProvider"
+ grid-controls="gridControls"
+ dateformat="{{$root.egDateAndTimeFormat}}">
+
+ <eg-grid-menu-item handler="refresh_arrived" standalone="true"
+ label="[% l('Refresh List')%]"></eg-grid-menu-item>
+
+ <eg-grid-field label="[% l('Pickup Date/Time') %]" path="slot.slot" datatype="timestamp"></eg-grid-field>
+ <eg-grid-field label="[% l('Patron') %]" path="slot.patron">
+ <a href="./circ/patron/{{item.slot.patron().id()}}/holds" target="_blank">
+ {{item.slot.patron().family_name()}} / {{item.slot.patron().card().barcode()}}
+ <span class="glyphicon glyphicon-new-window"></span>
+ </a>
+ </eg-grid-field>
+ <eg-grid-field label="[% l('Appointment ID') %]" path="slot.id"></eg-grid-field>
+ <eg-grid-field label="[% l('Action') %]" handlers="gridCellHandlers" compiled>
+ <button class="btn btn-sm btn-primary"
+ ng-disabled="col.handlers.wasHandled(item['slot_id'])"
+ ng-click="col.handlers.mark_delivered(item['slot_id'])">
+ [% l('Mark As Items Delivered') %]
+ </button>
+ </eg-grid-field>
+ </eg-grid>
+</div>
--- /dev/null
+<div>
+ <div ng-style="{visibility : refreshNeeded ? 'visible' : 'hidden'}" class="alert alert-warning">
+ [% l('Updates to the list of appointments whose items were delivered are available. Please refresh.') %]
+ </div>
+ <eg-grid
+ id-field="id"
+ features="-sort,-multisort,-picker,-multiselect"
+ items-provider="gridDataProvider"
+ grid-controls="gridControls"
+ dateformat="{{$root.egDateAndTimeFormat}}">
+
+ <eg-grid-menu-item handler="refresh_delivered" standalone="true"
+ label="[% l('Refresh List')%]"></eg-grid-menu-item>
+
+ <eg-grid-field label="[% l('Pickup Date/Time') %]" path="slot" datatype="timestamp"></eg-grid-field>
+ <eg-grid-field label="[% l('Patron') %]" path="patron">
+ <a href="./circ/patron/{{item.patron().id()}}/holds" target="_blank">
+ {{item.patron().family_name()}} / {{item.patron().card().barcode()}}
+ <span class="glyphicon glyphicon-new-window"></span>
+ </a>
+ </eg-grid-field>
+ <eg-grid-field label="[% l('Appointment ID') %]" path="id"></eg-grid-field>
+ </eg-grid>
+</div>
</uib-tab>
<uib-tab index="'staged'" heading="[% l('Staged And Ready') %]">
<div class="container-fluid">
- XXX
+ <eg-curbside-staged-manager ng-if="active_tab === 'staged'"></eg-curbside-staged-manager>
</div>
</uib-tab>
<uib-tab index="'arrived'" heading="[% l('Patron Is Outside') %]">
<div class="container-fluid">
- XXX
+ <eg-curbside-arrived-manager ng-if="active_tab === 'arrived'"></eg-curbside-arrived-manager>
</div>
</uib-tab>
<uib-tab index="'delivered'" heading="[% l('Delivered Today') %]">
<div class="container-fluid">
- XXX
+ <eg-curbside-delivered-manager ng-if="active_tab === 'delivered'"></eg-curbside-delivered-manager>
</div>
</uib-tab>
<uib-tab index="'schedule'" heading="[% l('Schedule Pickup') %]">
--- /dev/null
+<div>
+ <div ng-style="{visibility : refreshNeeded ? 'visible' : 'hidden'}" class="alert alert-warning">
+ [% l('Updates to the list of staged and ready appointments are available. Please refresh.') %]
+ </div>
+ <eg-grid
+ id-field="slot_id"
+ features="-sort,-multisort,-picker,-multiselect"
+ items-provider="gridDataProvider"
+ grid-controls="gridControls"
+ dateformat="{{$root.egDateAndTimeFormat}}">
+
+ <eg-grid-menu-item handler="refresh_staged" standalone="true"
+ label="[% l('Refresh List')%]"></eg-grid-menu-item>
+
+ <eg-grid-field label="[% l('Pickup Date/Time') %]" path="slot.slot" datatype="timestamp"></eg-grid-field>
+ <eg-grid-field label="[% l('Patron') %]" path="slot.patron">
+ <a href="./circ/patron/{{item.slot.patron().id()}}/holds" target="_blank">
+ {{item.slot.patron().family_name()}} / {{item.slot.patron().card().barcode()}}
+ <span class="glyphicon glyphicon-new-window"></span>
+ </a>
+ </eg-grid-field>
+ <eg-grid-field label="[% l('Appointment ID') %]" path="slot.id"></eg-grid-field>
+ <eg-grid-field label="[% l('Action') %]" handlers="gridCellHandlers" compiled>
+ <button class="btn btn-sm btn-primary"
+ ng-disabled="col.handlers.wasHandled(item['slot_id'])"
+ ng-click="col.handlers.mark_arrived(item['slot_id'])">
+ [% l('Mark As Patron Arrived') %]
+ </button>
+ <button class="btn btn-sm btn-primary"
+ ng-disabled="col.handlers.wasHandled(item['slot_id'])"
+ ng-click="col.handlers.mark_delivered(item['slot_id'])">
+ [% l('Mark As Patron Arrived and Items Delivered') %]
+ </button>
+ </eg-grid-field>
+ </eg-grid>
+</div>
--- /dev/null
+angular.module('egCurbsideAppDep')
+
+.directive('egCurbsideArrivedManager', function() {
+ return {
+ transclude: true,
+ restrict: 'E',
+ scope: { },
+ templateUrl: './circ/curbside/t_arrived_manager',
+ controller:
+ ['$scope','$q','egCurbsideCoreSvc','egCore','egGridDataProvider',
+ '$uibModal','$timeout','$location','egConfirmDialog','ngToast','$interval',
+function($scope , $q , egCurbsideCoreSvc , egCore , egGridDataProvider ,
+ $uibModal , $timeout , $location , egConfirmDialog , ngToast , $interval) {
+
+ $scope.gridControls = {};
+
+ $scope.wasHandled = {};
+ $scope.refreshNeeded = false;
+
+ latestTime = undefined;
+ var checkRefresh = undefined;
+ function startRefreshCheck() {
+ if (!angular.isDefined(checkRefresh)) {
+ checkRefresh = $interval(function() {
+ egCurbsideCoreSvc.get_latest_arrived().then(function(latest) {
+ if (angular.isDefined(latest)) {
+ if (angular.isDefined(latestTime) && latestTime != latest) {
+ $scope.refreshNeeded = true;
+ stopRefreshCheck();
+ }
+ latestTime = latest;
+ }
+ });
+ }, 15000);
+ }
+ }
+ function stopRefreshCheck() {
+ if (angular.isDefined(checkRefresh)) {
+ $interval.cancel(checkRefresh);
+ checkRefresh = undefined;
+ }
+ }
+ this.$onInit = function() {
+ startRefreshCheck();
+ }
+ this.$onDestroy = function() {
+ stopRefreshCheck();
+ }
+
+ $scope.gridDataProvider = egGridDataProvider.instance({
+ get : function(offset, count) {
+ $scope.wasHandled = {};
+ $scope.refreshNeeded = false;
+ startRefreshCheck();
+ return egCurbsideCoreSvc.get_arrived(offset, count);
+ }
+ });
+
+ $scope.refresh_arrived = function() {
+ $scope.gridControls.refresh();
+ }
+
+ $scope.gridCellHandlers = { };
+ $scope.gridCellHandlers.mark_delivered = function(id) {
+ egCurbsideCoreSvc.mark_delivered(id).then(function(resp) {
+ if (evt = egCore.evt.parse(resp)) {
+ ngToast.danger(egCore.strings.$replace(
+ egCore.strings.FAILED_CURBSIDE_MARK_DELIVERED,
+ { slot_id : id, evt_code : evt.code }
+ ));
+ return;
+ }
+ if (!angular.isDefined(resp)) {
+ ngToast.warning(egCore.strings.$replace(
+ egCore.strings.NOTFOUND_CURBSIDE_MARK_DELIVERED,
+ { slot_id : id }
+ ));
+ return;
+ }
+ ngToast.success(egCore.strings.$replace(
+ egCore.strings.SUCCESS_CURBSIDE_MARK_DELIVERED,
+ { slot_id : id }
+ ));
+ $scope.wasHandled[id] = true;
+ $timeout(function() { $scope.refresh_arrived() }, 500);
+ });
+ }
+ $scope.gridCellHandlers.wasHandled = function(id) {
+ return $scope.wasHandled[id];
+ }
+
+}]}});
--- /dev/null
+angular.module('egCurbsideAppDep')
+
+.directive('egCurbsideDeliveredManager', function() {
+ return {
+ transclude: true,
+ restrict: 'E',
+ scope: { },
+ templateUrl: './circ/curbside/t_delivered_manager',
+ controller:
+ ['$scope','$q','egCurbsideCoreSvc','egCore','egGridDataProvider',
+ '$uibModal','$timeout','$location','egConfirmDialog','ngToast','$interval',
+function($scope , $q , egCurbsideCoreSvc , egCore , egGridDataProvider ,
+ $uibModal , $timeout , $location , egConfirmDialog , ngToast , $interval) {
+
+ $scope.gridControls = {};
+
+ $scope.refreshNeeded = false;
+
+ latestTime = undefined;
+ var checkRefresh = undefined;
+ function startRefreshCheck() {
+ if (!angular.isDefined(checkRefresh)) {
+ checkRefresh = $interval(function() {
+ egCurbsideCoreSvc.get_latest_delivered().then(function(latest) {
+ if (angular.isDefined(latest)) {
+ if (angular.isDefined(latestTime) && latestTime != latest) {
+ $scope.refreshNeeded = true;
+ stopRefreshCheck();
+ }
+ latestTime = latest;
+ }
+ });
+ }, 15000);
+ }
+ }
+ function stopRefreshCheck() {
+ if (angular.isDefined(checkRefresh)) {
+ $interval.cancel(checkRefresh);
+ checkRefresh = undefined;
+ }
+ }
+ this.$onInit = function() {
+ startRefreshCheck();
+ }
+ this.$onDestroy = function() {
+ stopRefreshCheck();
+ }
+
+ $scope.gridDataProvider = egGridDataProvider.instance({
+ get : function(offset, count) {
+ $scope.refreshNeeded = false;
+ startRefreshCheck();
+ return egCurbsideCoreSvc.get_delivered(offset, count);
+ }
+ });
+
+ $scope.refresh_delivered = function() {
+ $scope.gridControls.refresh();
+ }
+
+ $scope.gridCellHandlers = { };
+
+}]}});
--- /dev/null
+angular.module('egCurbsideAppDep')
+
+.directive('egCurbsideStagedManager', function() {
+ return {
+ transclude: true,
+ restrict: 'E',
+ scope: { },
+ templateUrl: './circ/curbside/t_staged_manager',
+ controller:
+ ['$scope','$q','egCurbsideCoreSvc','egCore','egGridDataProvider',
+ '$uibModal','$timeout','$location','egConfirmDialog','ngToast','$interval',
+function($scope , $q , egCurbsideCoreSvc , egCore , egGridDataProvider ,
+ $uibModal , $timeout , $location , egConfirmDialog , ngToast , $interval) {
+
+ $scope.gridControls = {};
+
+ $scope.wasHandled = {};
+ $scope.refreshNeeded = false;
+
+ latestTime = undefined;
+ var checkRefresh = undefined;
+ function startRefreshCheck() {
+ if (!angular.isDefined(checkRefresh)) {
+ checkRefresh = $interval(function() {
+ egCurbsideCoreSvc.get_latest_staged().then(function(latest) {
+ if (angular.isDefined(latest)) {
+ if (angular.isDefined(latestTime) && latestTime != latest) {
+ $scope.refreshNeeded = true;
+ stopRefreshCheck();
+ }
+ latestTime = latest;
+ }
+ });
+ }, 15000);
+ }
+ }
+ function stopRefreshCheck() {
+ if (angular.isDefined(checkRefresh)) {
+ $interval.cancel(checkRefresh);
+ checkRefresh = undefined;
+ }
+ }
+ this.$onInit = function() {
+ startRefreshCheck();
+ }
+ this.$onDestroy = function() {
+ stopRefreshCheck();
+ }
+
+ $scope.gridDataProvider = egGridDataProvider.instance({
+ get : function(offset, count) {
+ $scope.wasHandled = {};
+ $scope.refreshNeeded = false;
+ startRefreshCheck();
+ return egCurbsideCoreSvc.get_staged(offset, count);
+ }
+ });
+
+ $scope.refresh_staged = function() {
+ $scope.gridControls.refresh();
+ }
+
+ $scope.gridCellHandlers = { };
+ $scope.gridCellHandlers.mark_arrived = function(id) {
+ egCurbsideCoreSvc.mark_arrived(id).then(function(resp) {
+ if (evt = egCore.evt.parse(resp)) {
+ ngToast.danger(egCore.strings.$replace(
+ egCore.strings.FAILED_CURBSIDE_MARK_ARRIVED,
+ { slot_id : id, evt_code : evt.code }
+ ));
+ return;
+ }
+ if (!angular.isDefined(resp)) {
+ ngToast.warning(egCore.strings.$replace(
+ egCore.strings.NOTFOUND_CURBSIDE_MARK_ARRIVED,
+ { slot_id : id }
+ ));
+ return;
+ }
+ ngToast.success(egCore.strings.$replace(
+ egCore.strings.SUCCESS_CURBSIDE_MARK_ARRIVED,
+ { slot_id : id }
+ ));
+ $scope.wasHandled[id] = true;
+ $timeout(function() { $scope.refresh_staged() }, 500);
+ });
+ }
+ $scope.gridCellHandlers.wasHandled = function(id) {
+ return $scope.wasHandled[id];
+ }
+
+}]}});
});
}
+ service.get_staged = function(offset, count) {
+ return egCore.net.request(
+ 'open-ils.curbside',
+ 'open-ils.curbside.fetch_staged',
+ egCore.auth.token(),
+ egCore.auth.user().ws_ou(),
+ count, // yep, count first
+ offset
+ );
+ };
+ service.get_latest_staged = function() {
+ return egCore.net.request(
+ 'open-ils.curbside',
+ 'open-ils.curbside.fetch_staged.latest',
+ egCore.auth.token()
+ ).then(function(resp) {
+ if (evt = egCore.evt.parse(resp)) {
+ return undefined;
+ } else {
+ return resp;
+ }
+ });
+ }
+
+ service.get_arrived = function(offset, count) {
+ return egCore.net.request(
+ 'open-ils.curbside',
+ 'open-ils.curbside.fetch_arrived',
+ egCore.auth.token(),
+ egCore.auth.user().ws_ou(),
+ count, // yep, count first
+ offset
+ );
+ };
+ service.get_latest_arrived = function() {
+ return egCore.net.request(
+ 'open-ils.curbside',
+ 'open-ils.curbside.fetch_arrived.latest',
+ egCore.auth.token()
+ ).then(function(resp) {
+ if (evt = egCore.evt.parse(resp)) {
+ return undefined;
+ } else {
+ return resp;
+ }
+ });
+ }
+
+ service.get_delivered = function(offset, count) {
+ return egCore.net.request(
+ 'open-ils.curbside',
+ 'open-ils.curbside.fetch_delivered',
+ egCore.auth.token(),
+ egCore.auth.user().ws_ou(),
+ count, // yep, count first
+ offset
+ );
+ };
+ service.get_latest_delivered = function() {
+ return egCore.net.request(
+ 'open-ils.curbside',
+ 'open-ils.curbside.fetch_delivered.latest',
+ egCore.auth.token()
+ ).then(function(resp) {
+ if (evt = egCore.evt.parse(resp)) {
+ return undefined;
+ } else {
+ return resp;
+ }
+ });
+ }
+
service.mark_staged = function(slot_id) {
return egCore.net.request(
'open-ils.curbside',
slot_id
);
}
+ service.mark_arrived = function(slot_id) {
+ return egCore.net.request(
+ 'open-ils.curbside',
+ 'open-ils.curbside.mark_arrived',
+ egCore.auth.token(),
+ slot_id
+ );
+ }
+ service.mark_delivered = function(slot_id) {
+ return egCore.net.request(
+ 'open-ils.curbside',
+ 'open-ils.curbside.mark_delivered',
+ egCore.auth.token(),
+ slot_id
+ );
+ }
+
return service;
}])