cancel_time => undef,
fulfillment_time => undef
},
- { limit => 1 }
+ { limit => 1,
+ flesh => 2,
+ flesh_fields => { ahr => ['usr'],
+ au => ['family_name', 'first_given_name']
+ }
+ }
]
)->[0];
$logger->info("circulator: this copy is needed by a different patron to fulfill a hold");
- $self->push_events(OpenILS::Event->new('ITEM_ON_HOLDS_SHELF'));
+ my $payload;
+ my $holdau = $hold->usr;
+
+ if ($holdau) {
+ $payload->{patron_name} = $holdau->first_given_name . ' ' . $holdau->family_name;
+ } else {
+ $payload->{patron_name} = "???";
+ }
+ $payload->{hold_id} = $hold->id;
+ $self->push_events(OpenILS::Event->new('ITEM_ON_HOLDS_SHELF',
+ payload => $payload));
}
INSERT INTO config.org_unit_setting_type
( name, grp, label, description, datatype )
VALUES
+ ('circ.clear_hold_on_checkout',
+ 'circ',
+ oils_i18n_gettext('circ.clear_hold_on_checkout',
+ 'Clear hold when other patron checks out item',
+ 'coust', 'label'),
+ oils_i18n_gettext('circ.clear_hold_on_checkout',
+ 'When patron A checks out item on hold for patron B, ' ||
+ 'automatically clear the hold for patron B. This is ' ||
+ 'desirable when checking out item for family members',
+ 'coust', 'description'),
+ 'bool');
+
+INSERT INTO actor.org_unit_setting (
+ org_unit, name, value
+) VALUES (
+ (SELECT id FROM actor.org_unit WHERE parent_ou IS NULL),
+ 'circ.clear_hold_on_checkout',
+ 'false'
+);
+
+INSERT INTO config.org_unit_setting_type
+( name, grp, label, description, datatype )
+VALUES
('circ.patron_search.diacritic_insensitive',
'circ',
oils_i18n_gettext('circ.patron_search.diacritic_insensitive',
--- /dev/null
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+INSERT INTO config.org_unit_setting_type
+( name, grp, label, description, datatype )
+VALUES
+ ('circ.clear_hold_on_checkout',
+ 'circ',
+ oils_i18n_gettext('circ.clear_hold_on_checkout',
+ 'Clear hold when other patron checks out item',
+ 'coust', 'label'),
+ oils_i18n_gettext('circ.clear_hold_on_checkout',
+ 'When patron A checks out item on hold for patron B, ' ||
+ 'automatically clear the hold for patron B. This is ' ||
+ 'desirable when checking out item for family members',
+ 'coust', 'description'),
+ 'bool');
+
+INSERT INTO actor.org_unit_setting (
+ org_unit, name, value
+) VALUES (
+ (SELECT id FROM actor.org_unit WHERE parent_ou IS NULL),
+ 'circ.clear_hold_on_checkout',
+ 'false'
+);
+
+COMMIT;
+
<div class="panel-body">
<div ng-if="copy_barcode" class="strong-text-2">{{copy_barcode}}</div>
{{evt.desc}}
+ <div ng-if="evt.textcode == 'ITEM_ON_HOLDS_SHELF'">
+ [% l('for ') %] {{patronName}}.
+ <div>
+ <label><input type="checkbox" ng-model="formdata.clearHold"/>
+ [% l('Cancel this hold upon checkout?') %]</label>
+ </div>
+
+ </div>
</div>
</div>
</div>
'ui.staff.require_initials.patron_standing_penalty',
'ui.admin.work_log.max_entries',
'ui.admin.patron_log.max_entries',
- 'circ.staff_client.do_not_auto_attempt_print'
+ 'circ.staff_client.do_not_auto_attempt_print',
+ 'circ.clear_hold_on_checkout'
]).then(function(set) {
service.require_initials = Boolean(set['ui.staff.require_initials.patron_standing_penalty']);
+ service.clearHold = Boolean(set['circ.clear_hold_on_checkout']);
+
if (angular.isArray(set['circ.staff_client.do_not_auto_attempt_print'])) {
if (set['circ.staff_client.do_not_auto_attempt_print'].indexOf('Hold Slip') > 1)
service.never_auto_print['hold_shelf_slip'] = true;
['$scope', '$uibModalInstance',
function($scope, $uibModalInstance) {
$scope.events = evt;
+
+ // Find the event, if any, that is for ITEM_ON_HOLDS_SHELF
+ // and grab the patron name of the owner.
+ $scope.holdEvent = evt.filter(
+ function(e) {
+ return e.textcode === 'ITEM_ON_HOLDS_SHELF'
+ }
+ );
+
+ if ($scope.holdEvent) {
+ // Ensure we have a scalar here
+ if (angular.isArray($scope.holdEvent)) {
+ $scope.holdEvent = $scope.holdEvent[0];
+ }
+
+ $scope.patronName = $scope.holdEvent.payload.patron_name;
+ $scope.holdID = $scope.holdEvent.payload.hold_id;
+ }
+
$scope.auto_override =
evt.filter(function(e){
return service.checkout_auto_override_after_first.indexOf(evt.textcode) > -1;
}).length > 0;
$scope.copy_barcode = params.copy_barcode; // may be null
- $scope.ok = function() { $uibModalInstance.close() }
+
+ // Implementation note: Why not use a primitive here? It
+ // doesn't work. See:
+ // http://stackoverflow.com/questions/18642371/checkbox-not-binding-to-scope-in-angularjs
+ $scope.formdata = {clearHold : service.clearHold};
+
+ $scope.ok = function() {
+ $uibModalInstance.close();
+
+ // Handle the cancellation of the assciated hold here
+ if ($scope.formdata.clearHold && $scope.holdID) {
+ $scope.args = {
+ cancel_reason : 5,
+ note: 'Item checked out by other patron'
+ };
+ egCore.net.request(
+ 'open-ils.circ', 'open-ils.circ.hold.cancel',
+ egCore.auth.token(), $scope.holdID,
+ $scope.args.cancel_reason,
+ $scope.args.note);
+ }
+ }
+
$scope.cancel = function ($event) {
$uibModalInstance.dismiss();
$event.preventDefault();
--- /dev/null
+Alternate Patron Hold Pickup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+This feature adds a bit of convenience to a common task: checking out
+an item on hold to another patron (typically a family member or helper).
+
+When you checkout the item, you will get a pop-up window with warnings associated
+with this item. The "ITEM_ON_HOLDS_SHELF" message is now expanded to
+
+ * Let you know the name of the person who had placed the hold.
+ * Give you the option (in the form of a checkbox) of cancelling the
+ hold placed by the above-named patron. (Checked = Cancel the hold;
+ Uncheked = Leave the hold in place)
+
+The initial value of the checkbox is derived from the circ.clear_hold_on_checkout
+organizational setting. This is found under Administration -- Server Administration -- Org Unit Setting Types
+
+If the operator has CANCEL_HOLD privilege, then if the checkbox is checked and the checkout is allowed to proceed,
+the hold will be cancelled with a note that the item was checked out to another patrron.
+
+This feature is available in the browser-based staff client.