I've been testing some code for the situation where an item gets "stuck"
circulating at a non-owning library. A number of people at the recent
hackfest expressed interest in various ways to get an item to fill holds
at it's home library depending on some setting, so I thought others
might be interested, and wondered if anyone else was working on this.
The idea is to compare a library setting, which is a time interval such
as '6 weeks', to the time interval since the item was checked in at its
home library. If the library setting has been exceeded, the system will
search for holds relative to the item's home library rather than the
current check in library. In effect, the item will go home if holds
exist there, if not the item may at least start moving toward its home
library depending on what other holds exist and the layout of the
library system.
The code adds one storage call to compare the library setting(pulled via
item circ_lib), and if the setting is exceeded, calls the existing
nearest_hold sub
with the item circ_lib rather than check in lib. You'll need to add an
UPDATE_ORG_UNIT_SETTING.circ.hold_go_home permission if you want to try
it out. The diff is against svn rel_1_6_0.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
Signed-off-by:
Doug Kyle
[email protected]
Index: src/perlmods/OpenILS/Const.pm
===================================================================
--- src/perlmods/OpenILS/Const.pm (revision 16362)
+++ src/perlmods/OpenILS/Const.pm (working copy)
@@ -77,6 +77,7 @@
econst OILS_SETTING_ORG_BOUNCED_EMAIL => 'org.bounced_emails';
econst OILS_SETTING_CHARGE_LOST_ON_ZERO => 'circ.charge_lost_on_zero';
econst OILS_SETTING_VOID_OVERDUE_ON_LOST => 'circ.void_overdue_on_lost';
+econst OILS_SETTING_HOLD_GO_HOME => 'circ.hold_go_home';
econst OILS_SETTING_HOLD_SOFT_STALL => 'circ.hold_stalling.soft';
econst OILS_SETTING_HOLD_HARD_STALL => 'circ.hold_stalling.hard';
econst OILS_SETTING_HOLD_SOFT_BOUNDARY => 'circ.hold_boundary.soft';
Index: src/perlmods/OpenILS/Application/Circ/Holds.pm
===================================================================
--- src/perlmods/OpenILS/Application/Circ/Holds.pm (revision 16362)
+++ src/perlmods/OpenILS/Application/Circ/Holds.pm (working copy)
@@ -1571,14 +1571,31 @@
my $hold_stall_interval = $U->ou_ancestor_setting_value($user->ws_ou, OILS_SETTING_HOLD_SOFT_STALL);
+ my $hold_go_home_interval = $U->ou_ancestor_setting_value($copy->circ_lib->id, OILS_SETTING_HOLD_GO_HOME) || 0; #doug
+ my $homer;
+ if ($hold_go_home_interval) {
+ $homer = $U->storagereq(
+ "open-ils.storage.action.hold_go_home_interval_test",
+ $hold_go_home_interval, $copy->id, $copy->circ_lib->id );
+ }
+
$logger->info("circulator: searching for best hold at org ".$user->ws_ou.
" and copy $bc with a hold stalling interval of ". ($hold_stall_interval || "(none)"));
# search for what should be the best holds for this copy to fulfill
- my $best_holds = $U->storagereq(
- "open-ils.storage.action.hold_request.nearest_hold.atomic",
- $user->ws_ou, $copy->id, 10, $hold_stall_interval );
+ my $best_holds;
+ if ($homer) {
+ $best_holds = $U->storagereq(
+ "open-ils.storage.action.hold_request.nearest_hold.atomic",
+ $copy->circ_lib->id, $copy->id, 10, $hold_stall_interval );
+ } else {
+ $best_holds = $U->storagereq(
+ "open-ils.storage.action.hold_request.nearest_hold.atomic",
+ $user->ws_ou, $copy->id, 10, $hold_stall_interval );
+ }
+
unless(@$best_holds) {
if( my $hold = $$old_holds[0] ) {
Index: src/perlmods/OpenILS/Application/Storage/Publisher/action.pm
===================================================================
--- src/perlmods/OpenILS/Application/Storage/Publisher/action.pm (revision 16362)
+++ src/perlmods/OpenILS/Application/Storage/Publisher/action.pm (working copy)
@@ -296,6 +296,30 @@
method => 'nearest_hold',
);
+sub hold_go_home_interval_test {
+ my $self = shift;
+ my $client = shift;
+ my $interval = shift;
+ my $cp = shift;
+ my $circ_lib = shift;
+ my $test = action::hold_request->db_Main->selectcol_arrayref(<<" SQL", {}, $interval, $cp, $circ_lib);
+ SELECT MAX(checkin_time) < NOW() - INTERVAL ?
+ FROM action.circulation
+ WHERE target_copy = ?
+ AND checkin_lib = ?
+ SQL
+ $client->respond( $test->[0] );
+ return undef;
+
+}
+__PACKAGE__->register_method(
+ api_name => 'open-ils.storage.action.hold_go_home_interval_test',
+ api_level => 1,
+ stream => 1,
+ method => 'hold_go_home_interval_test',
+);
+
+
sub next_resp_group_id {
my $self = shift;
my $client = shift;
Index: xul/staff_client/server/admin/org_unit_settings.xhtml
===================================================================
--- xul/staff_client/server/admin/org_unit_settings.xhtml (revision 16362)
+++ xul/staff_client/server/admin/org_unit_settings.xhtml (working copy)
@@ -81,6 +81,10 @@
label : '&staff.server.admin.org_settings.circ.hold_boundary.soft;',
type : 'number'
},
+ 'circ.hold_go_home' : {
+ label : '&staff.server.admin.org_settings.circ.hold_go_home;',
+ desc : '&staff.server.admin.org_settings.circ.hold_go_home.desc;',
+ },
'opac.barcode_regex' : {
label : '&staff.server.admin.org_settings.opac.barcode_regex;',
desc : '&staff.server.admin.org_settings.opac.barcode_regex.desc;'
Index: web/opac/locale/en-US/lang.dtd
===================================================================
--- web/opac/locale/en-US/lang.dtd (revision 16362)
+++ web/opac/locale/en-US/lang.dtd (working copy)
@@ -1590,6 +1590,8 @@
<!ENTITY staff.server.admin.org_settings.circ.hold_stalling.soft.desc 'How long to wait before allowing remote items to be opportunisticaly captured for a hold. Example "5 days"'>
<!ENTITY staff.server.admin.org_settings.circ.hold_boundary.hard "Holds: Hard boundary">
<!ENTITY staff.server.admin.org_settings.circ.hold_boundary.soft "Holds: Soft boundary">
+<!ENTITY staff.server.admin.org_settings.circ.hold_go_home "Holds: Go Home Interval">
+<!ENTITY staff.server.admin.org_settings.circ.hold_go_home.desc "Capture hold nearest to item circ_lib.">
<!ENTITY staff.server.admin.org_settings.opac.barcode_regex "Patron barcode format">
<!ENTITY staff.server.admin.org_settings.opac.barcode_regex.desc 'Regular expression defining the patron barcode format'>
<!ENTITY staff.server.admin.org_settings.global.password_regex "Password format">