</div>
</div>
-<div ng-if="already_checked_in" class="col-md-6 alert alert-danger">
- [% l('[_1] was already checked in.', '{{already_checked_in}}') %]
+<div ng-if="alert" class="col-md-6 alert alert-danger">
+ <span ng-if="alert.already_checked_in">
+ [% l('[_1] was already checked in.', '{{alert.already_checked_in}}') %]
+ </span>
+ <span ng-if="alert.item_never_circed">
+ [% l('Item [_1] has never circulated.', '{{alert.item_never_circed}}') %]
+ </span>
</div>
<hr/>
grid-controls="gridControls"
persist-key="circ.checkin">
+
+ <eg-grid-action
+ handler="fetchLastCircPatron"
+ label="[% l('Retrieve Last Patron Who Circulated Item') %]">
+ </eg-grid-action>
+
<eg-grid-field label="[% l('Alert Msg') %]"
path="acp.alert_message"></eg-grid-field>
<eg-grid-field label="[% l('Start') %]"
path='circ.xact_start'></eg-grid-field>
- <eg-grid-field label="[% l('Title') %]"
- path="title"></eg-grid-field>
+ <eg-grid-field label="[% l('Title') %]" path="title">
+ <a target="_self" href="[% ctx.base_path %]/opac/record/{{record.doc_id()}}">
+ {{item.title}}
+ </a>
+ </eg-grid-field>
<eg-grid-field label="[% l('Due Date') %]"
path='circ.due_date' hidden></eg-grid-field>
session will auto-override this event[% END %]</i>
<br/><br/>
<input type="submit" class="btn btn-primary"
- value="[% l('Force Checkout?') %]"/>
+ value="[% l('Force Action?') %]"/>
<button class="btn btn-warning"
ng-click="cancel($event)">[% l('Cancel') %]</button>
</div>
</button>
<!-- actions drop-down menu -->
- <div class="btn-group" ng-if="actions.length"
- is-open="gridActionsIsOpen" dropdown>
+ <div class="btn-group" ng-if="actions.length" dropdown>
<button type="button" class="btn btn-default dropdown-toggle"
ng-class="{disabled : false}">
[% l('Actions') %] <span class="caret"></span>
</button>
<ul class="dropdown-menu pull-right">
<li ng-class="{disabled : false}" ng-repeat="action in actions">
- <a href ng-click="actionLauncher(action)">{{action.label}}</a>
+ <a href dropdown-toggle
+ ng-click="actionLauncher(action)">{{action.label}}</a>
</li>
</ul>
</div>
var copy = res.copy;
itemSvc.copy = copy;
- if (copyId && copyId != copy.id()) {
- // if a new barcode is scanned in the detail view,
- // update the url to match the ID of the new copy
- $location.path('/cat/item/' + copy.id() + '/' + $scope.tab);
- deferred.reject(); // avoid propagation of data fetch calls
- return;
- }
- copyId = copy.id();
$scope.copy = copy;
$scope.recordId = copy.call_number().record().id();
$scope.summaryRecord = itemSvc.copy.call_number().record();
function(field) { copy[field](Boolean(copy[field]() == 't')) }
);
+ // finally, if this is a different copy, redirect.
+ // Note that we flesh first since the copy we just
+ // fetched will be used after the redirect.
+ if (copyId && copyId != copy.id()) {
+ // if a new barcode is scanned in the detail view,
+ // update the url to match the ID of the new copy
+ $location.path('/cat/item/' + copy.id() + '/' + $scope.tab);
+ deferred.reject(); // avoid propagation of data fetch calls
+ return;
+ }
+ copyId = copy.id();
+
deferred.resolve();
});
* Manages checkin
*/
.controller('CheckinCtrl',
- ['$scope','$q','egCore','checkinSvc','egGridDataProvider','egCirc',
-function($scope , $q , egCore , checkinSvc , egGridDataProvider , egCirc) {
+ ['$scope','$q','$window','$location','egCore','checkinSvc','egGridDataProvider','egCirc',
+function($scope , $q , $window , $location , egCore , checkinSvc , egGridDataProvider , egCirc) {
var suppress_popups = false;
var today = new Date();
var compiled = compile_checkin_args(args);
args.copy_barcode = ''; // reset UI for next scan
$scope.focusMe = true;
+ delete $scope.alert;
var params = compiled.params;
var options = compiled.options;
if (!params.copy_barcode) return;
if (seen_barcodes[params.copy_barcode]) {
- $scope.already_checked_in = params.copy_barcode;
+ $scope.alert = {already_checked_in : params.copy_barcode};
return;
}
seen_barcodes[params.copy_barcode] = true;
- delete $scope.already_checked_in;
+ delete $scope.alert;
var row_item = {
index : checkinSvc.checkins.length,
});
}
+
+ // --- context menu actions
+ //
+ $scope.fetchLastCircPatron = function(items) {
+ var checkin = items[0];
+ if (!checkin || !checkin.acp) return;
+
+ egCore.pcrud.search('circ',
+ {target_copy : checkin.acp.id()},
+ {order_by : {circ : 'xact_start desc' }, limit : 1}
+ ).then(function(circ) {
+
+ if (circ) {
+ // jump to the patron UI (separate app)
+ $window.location.href = $location
+ .path('/circ/patron/' + circ.usr() + '/checkout')
+ .absUrl();
+ return;
+ }
+
+ $scope.alert = {item_never_circed : checkin.acp.barcode()};
+ });
+ }
+
}])
case 'COPY_ALERT_MESSAGE':
return service.copy_alert_dialog(evt, params, options, 'checkout');
default:
- return service.override_dialog(evt, params, options);
+ return service.override_dialog(evt, params, options, 'checkin');
}
}
case 'COPY_ALERT_MESSAGE':
return service.copy_alert_dialog(evt, params, options, 'checkin');
default:
- return service.override_dialog(evt, params, options);
+ return service.override_dialog(evt, params, options, 'checkin');
}
}
// opens a dialog asking the user if they would like to override
// the returned event.
- service.override_dialog = function(evt, params, options) {
+ service.override_dialog = function(evt, params, options, action) {
return $modal.open({
templateUrl: './circ/share/t_event_override_dialog',
controller:
}]
}).result.then(
function() {
+ options.override = true;
+
+ if (action == 'checkin') {
+ return service.checkin(params, options);
+ }
+
+ // checkout/renew support override-after-first
if (service.checkout_auto_override_after_first.indexOf(evt.textcode) > -1)
service.auto_override_checkout_events[evt.textcode] = true;
- options.override = true;
+
return service.checkout(params, options);
}
);
return service.handle_overridable_checkin_event(evt, params, options);
switch (evt.textcode) {
+
case 'SUCCESS':
case 'NO_CHANGE':
- if (copy.status().id() == 8 // on holds shelf
- && hold
- && hold.pickup_lib() == egCore.auth.user().ws_ou()) {
- // inform user if the item is on the local holds shelf
-
- return service.route_dialog(
- './circ/share/t_hold_shelf_dialog',
- evt, params, options
- ).then(function() { return final_resp });
-
- } else {
-
- // see if the copy location is configured to alert
- return service.handle_checkin_loc_alert(evt, params, options)
- .then(function() {return final_resp});
+ switch(Number(copy.status().id())) {
+
+ case 0: /* AVAILABLE */
+ case 4: /* MISSING */
+ case 7: /* RESHELVING */
+
+ // see if the copy location requires an alert
+ return service.handle_checkin_loc_alert(evt, params, options)
+ .then(function() {return final_resp});
+
+ case 8: /* ON HOLDS SHELF */
+
+
+ if (hold) {
+
+ if (hold.pickup_lib() == egCore.auth.user().ws_ou()) {
+ // inform user if the item is on the local holds shelf
+
+ return service.route_dialog(
+ './circ/share/t_hold_shelf_dialog',
+ evt, params, options
+ ).then(function() { return final_resp });
+
+ } else {
+ // normally, if the hold was on the shelf at a
+ // different location, it would be put into
+ // transit, resulting in a ROUTE_ITEM event.
+ return $q.when(final_resp);
+ }
+ } else {
+
+ console.error('checkin: item on holds shelf, '
+ + 'but hold info not returned from checkin');
+ return $q.when(final_resp);
+ }
+
+ case 11: /* CATALOGING */
+ return $q.when(final_resp);
+
+ case 15: /* ON_RESERVATION_SHELF */
+ // TODO: show booking reservation dialog
+ return $q.when(final_resp);
+
+ default:
+ console.error('Unhandled checkin copy status: '
+ + copy.status().id() + ' : ' + copy.status().name());
+ return $q.when(final_resp);
}
case 'ROUTE_ITEM':
// fires the action handler function for a context action
$scope.actionLauncher = function(action) {
- $scope.gridActionsIsOpen = false;
-
if (!action.handler) {
console.error(
'No handler specified for "' + action.label + '"');