1 package OpenILS::Utils::PermitHold;
2 use strict; use warnings;
5 use OpenSRF::Utils::SettingsClient;
6 use OpenILS::Utils::ScriptRunner;
7 use OpenILS::Application::AppUtils;
8 use DateTime::Format::ISO8601;
9 use OpenILS::Application::Circ::ScriptBuilder;
10 use OpenSRF::Utils::Logger qw(:logger);
12 my $U = "OpenILS::Application::AppUtils";
14 my $script; # - the permit script
15 my $script_libs; # - extra script libs
17 # mental note: open-ils.storage.biblio.record_entry.ranged_tree
20 # params within a hash are: copy, patron,
21 # requestor, request_lib, title, title_descriptor
22 sub permit_copy_hold {
27 patron_id => $$params{patron_id},
28 patron => $$params{patron},
29 copy => $$params{copy},
30 requestor => $$params{requestor},
31 title => $$params{title},
32 volume => $$params{volume},
33 flesh_age_protect => 1,
35 requestLib => $$params{request_lib},
36 pickupLib => $$params{pickup_lib},
40 my $runner = OpenILS::Application::Circ::ScriptBuilder->build($ctx);
42 if( $ctx->{_events} ) {
43 push( @allevents, $_) for @{$ctx->{_events}};
45 # --------------------------------------------------------------
46 # If scriptbuilder returned any events, then the script context
47 # is undefined and should not be used
48 # --------------------------------------------------------------
52 # check the various holdable flags
53 push( @allevents, OpenILS::Event->new('ITEM_NOT_HOLDABLE') )
54 unless $U->is_true($ctx->{copy}->holdable);
56 push( @allevents, OpenILS::Event->new('ITEM_NOT_HOLDABLE') )
57 unless $U->is_true($ctx->{copy}->location->holdable);
59 push( @allevents, OpenILS::Event->new('ITEM_NOT_HOLDABLE') )
60 unless $U->is_true($ctx->{copy}->status->holdable);
62 my $evt = check_age_protect($ctx->{patron}, $ctx->{copy});
63 push( @allevents, $evt ) if $evt;
65 $logger->debug("Running permit_copy_hold on copy " . $$params{copy}->id);
67 load_scripts($runner);
68 my $result = $runner->run or
69 throw OpenSRF::EX::ERROR ("Hold Copy Permit Script Died: $@");
71 # --------------------------------------------------------------
72 # Extract and uniquify the event list
73 # --------------------------------------------------------------
74 my $events = $result->{events};
75 my $pid = ($params->{patron}) ? $params->{patron}->id : $params->{patron_id};
76 $logger->debug("circ_permit_hold for user $pid returned events: [@$events]");
78 push( @allevents, OpenILS::Event->new($_)) for @$events;
81 my %hash = map { ($_->{ilsevent} => $_) } @allevents;
82 @allevents = values %hash;
86 return \@allevents if $$params{show_event_list};
87 return 1 unless @allevents;
96 my $conf = OpenSRF::Utils::SettingsClient->new;
97 my @pfx = ( "apps", "open-ils.circ","app_settings" );
98 my $libs = $conf->config_value(@pfx, 'script_path');
99 $script = $conf->config_value(@pfx, 'scripts', 'circ_permit_hold');
100 $script_libs = (ref($libs)) ? $libs : [$libs];
103 $runner->add_path($_) for(@$script_libs);
104 $runner->load($script);
108 sub check_age_protect {
109 my( $patron, $copy ) = @_;
111 return undef unless $copy->age_protect;
113 my $prox = $U->storagereq(
114 'open-ils.storage.asset.copy.proximity',
115 $copy->id, $patron->home_ou->id );
117 # If this copy is within the appropriate proximity,
118 # age protect does not apply
119 return undef if $prox <= $copy->age_protect->prox;
121 # How many seconds old does the copy have to be to escape age protection
122 my $interval = OpenSRF::Utils::interval_to_seconds($copy->age_protect->age);
123 my $start_date = time - $interval;
125 # Now, now many seconds old is this copy
126 my $dparser = DateTime::Format::ISO8601->new;
127 my $create_date = $dparser->parse_datetime(
128 OpenSRF::Utils::clense_ISO8601($copy->create_date));
129 my $age = $create_date->epoch;
131 $logger->debug("age_protect create_date = $create_date : age=$age, start_date=$start_date");
133 unless( $start_date < $age ) {
134 $logger->info("age_protect prevents copy from having a hold placed on it: ".$copy->id);
135 return OpenILS::Event->new('ITEM_AGE_PROTECTED', copy => $copy->id );