From: Dan Pearl Date: Tue, 24 Jan 2017 18:59:01 +0000 (-0500) Subject: LP##1661688 - Want easy way to clear a hold when picked up by other patron. X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=3e081d1ee518cbfa3b53b1d261aa773831ecd365;p=working%2FEvergreen.git LP##1661688 - Want easy way to clear a hold when picked up by other patron. This common action was handled previously as 1) item is scanned - The system detects that this items is for a different patron, and an error message is displayed. 2) Force Override was selected - If the librarian had the appropriate privileges, the Force Override could allow the checkout to occur. 3) librarian cancels original hold - This independent operation would be needed to cancel the original hold, otherwise the hold would be targeted again. This feature provides the option to cancel the hold in step #2. An error message will be displayed as before, but within that message will be a checkbox to allow cancelling of the original hold which, if checked, will mean that step #3 will be automatically done. The checked/non-checked state of the checkbox is initialized with an organizational unit setting. The default is false (to preserve default prior behavior). Note: This change only affects the "web client". TO TEST THIS A. Before the Patch Hold an item for patron "A". Attempt to check it out for patron "B". Observe the choices to Force Override (to allow the checkout) or to cancel. Do a Force Override and observe that the original hold is still active. B. After the Patch Repeat the above scenario, and observe the (blank) checkbox. Perform the Force Override and observe that the original hold is still active. Repeat the scenario, except this time check the checkbox. Observe after the checheckout is done that original hold is gone. Adjust the organizational setting (see the Release Notes) to change the default appearance of the checkbox. For completeness, you can verify that if you cancel out the message pop-up that the checkout is cancelled and and that the hold status is unchanged, regardless of the state of the checkbox. Signed-off-by: Dan Pearl Signed-off-by: Jason Stephenson Signed-off-by: Kathy Lussier Signed-off-by: Galen Charlton --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm index 8dbfcc2145..f516381930 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm @@ -1119,7 +1119,12 @@ sub check_captured_holds { cancel_time => undef, fulfillment_time => undef }, - { limit => 1 } + { limit => 1, + flesh => 2, + flesh_fields => { ahr => ['usr'], + au => ['family_name', 'first_given_name'] + } + } ] )->[0]; @@ -1130,7 +1135,17 @@ sub check_captured_holds { $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)); } diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql index ab4468d084..43bf6aed32 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -16729,6 +16729,29 @@ INSERT INTO config.org_unit_setting_type 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', diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.hold_checkout.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.hold_checkout.sql new file mode 100644 index 0000000000..1541b3bd7e --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.hold_checkout.sql @@ -0,0 +1,29 @@ +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; + diff --git a/Open-ILS/src/templates/staff/circ/share/t_event_override_dialog.tt2 b/Open-ILS/src/templates/staff/circ/share/t_event_override_dialog.tt2 index 730814548a..0adeb115cc 100644 --- a/Open-ILS/src/templates/staff/circ/share/t_event_override_dialog.tt2 +++ b/Open-ILS/src/templates/staff/circ/share/t_event_override_dialog.tt2 @@ -13,6 +13,14 @@
{{copy_barcode}}
{{evt.desc}} +
+ [% l('for ') %] {{patronName}}. +
+ +
+ +
diff --git a/Open-ILS/web/js/ui/default/staff/circ/services/circ.js b/Open-ILS/web/js/ui/default/staff/circ/services/circ.js index f749b9292d..3bf866cde2 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/services/circ.js +++ b/Open-ILS/web/js/ui/default/staff/circ/services/circ.js @@ -27,9 +27,12 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog, egAddCopyAl '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; @@ -732,12 +735,53 @@ function($uibModal , $q , egCore , egAlertDialog , egConfirmDialog, egAddCopyAl ['$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(); diff --git a/docs/RELEASE_NOTES_NEXT/Circulation/alternate_patron_hold_pickup.adoc b/docs/RELEASE_NOTES_NEXT/Circulation/alternate_patron_hold_pickup.adoc new file mode 100644 index 0000000000..d3ef60edfb --- /dev/null +++ b/docs/RELEASE_NOTES_NEXT/Circulation/alternate_patron_hold_pickup.adoc @@ -0,0 +1,20 @@ +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.