rolling back xact created by scriptbuilder
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Utils / PermitHold.pm
1 package OpenILS::Utils::PermitHold;
2 use strict; use warnings;
3 use Data::Dumper;
4 use OpenSRF::Utils;
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);
11 use OpenILS::Event;
12 my $U   = "OpenILS::Application::AppUtils";
13
14 my $script;                     # - the permit script
15 my $script_libs;        # - extra script libs
16
17 # mental note:  open-ils.storage.biblio.record_entry.ranged_tree
18
19
20 # params within a hash are: copy, patron, 
21 # requestor, request_lib, title, title_descriptor
22 sub permit_copy_hold {
23         my $params      = shift;
24         my @allevents;
25
26         my $ctx = {
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,
34                 _direct => {
35                         requestLib      => $$params{request_lib},
36                         pickupLib       => $$params{pickup_lib},
37                 }
38         };
39
40         my $runner = OpenILS::Application::Circ::ScriptBuilder->build($ctx);
41
42         if( $ctx->{_events} ) {
43                 push( @allevents, $_) for @{$ctx->{_events}};
44
45                 # --------------------------------------------------------------
46                 # If scriptbuilder returned any events, then the script context
47                 # is undefined and should not be used
48                 # --------------------------------------------------------------
49
50         } else {
51
52                 # check the various holdable flags
53                 push( @allevents, OpenILS::Event->new('ITEM_NOT_HOLDABLE') )
54                         unless $U->is_true($ctx->{copy}->holdable);
55         
56                 push( @allevents, OpenILS::Event->new('ITEM_NOT_HOLDABLE') )
57                         unless $U->is_true($ctx->{copy}->location->holdable);
58         
59                 push( @allevents, OpenILS::Event->new('ITEM_NOT_HOLDABLE') )
60                         unless $U->is_true($ctx->{copy}->status->holdable);
61         
62                 my $evt = check_age_protect($ctx->{patron}, $ctx->{copy});
63                 push( @allevents, $evt ) if $evt;
64         
65                 $logger->debug("Running permit_copy_hold on copy " . $$params{copy}->id);
66         
67                 load_scripts($runner);
68                 my $result = $runner->run or 
69                         throw OpenSRF::EX::ERROR ("Hold Copy Permit Script Died: $@");
70
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]");
77         
78                 push( @allevents, OpenILS::Event->new($_)) for @$events;
79         }
80
81         my %hash = map { ($_->{ilsevent} => $_) } @allevents;
82         @allevents = values %hash;
83
84         $ctx->{editor}->rollback if $ctx->{editor};
85
86         $runner->cleanup;
87
88         return \@allevents if $$params{show_event_list};
89         return 1 unless @allevents;
90         return 0;
91 }
92
93
94 sub load_scripts {
95         my $runner = shift;
96
97         if(!$script) {
98                 my $conf = OpenSRF::Utils::SettingsClient->new;
99                 my @pfx = ( "apps", "open-ils.circ","app_settings" );
100                 my $libs        = $conf->config_value(@pfx, 'script_path');
101                 $script = $conf->config_value(@pfx, 'scripts', 'circ_permit_hold');
102                 $script_libs = (ref($libs)) ? $libs : [$libs];
103         }
104
105         $runner->add_path($_) for(@$script_libs);
106         $runner->load($script);
107 }
108
109
110 sub check_age_protect {
111         my( $patron, $copy ) = @_;
112
113         return undef unless $copy->age_protect;
114
115         my $prox = $U->storagereq(
116                 'open-ils.storage.asset.copy.proximity', 
117                 $copy->id, $patron->home_ou->id );
118
119         # If this copy is within the appropriate proximity, 
120         # age protect does not apply
121         return undef if $prox <= $copy->age_protect->prox;
122
123         # How many seconds old does the copy have to be to escape age protection
124         my $interval = OpenSRF::Utils::interval_to_seconds($copy->age_protect->age);
125         my $start_date = time - $interval;
126
127         # Now, now many seconds old is this copy
128         my $dparser = DateTime::Format::ISO8601->new;
129         my $create_date = $dparser->parse_datetime(
130                 OpenSRF::Utils::clense_ISO8601($copy->create_date));
131         my $age = $create_date->epoch;
132
133         $logger->debug("age_protect create_date = $create_date : age=$age, start_date=$start_date");
134
135         unless( $start_date < $age ) {
136                 $logger->info("age_protect prevents copy from having a hold placed on it: ".$copy->id);
137                 return OpenILS::Event->new('ITEM_AGE_PROTECTED', copy => $copy->id );
138         }
139
140         return undef;
141 }
142
143
144
145
146
147
148
149 23;