1 package OpenILS::Application::Penalty;
2 use strict; use warnings;
5 use OpenSRF::EX qw(:try);
6 use OpenSRF::Utils::Cache;
7 use OpenSRF::Utils qw/:datetime/;
8 use OpenILS::Utils::ScriptRunner;
9 use OpenSRF::Utils::SettingsClient;
10 use OpenILS::Application::AppUtils;
11 use OpenSRF::Utils::Logger qw(:logger);
12 use base 'OpenSRF::Application';
14 my $U = "OpenILS::Application::AppUtils";
19 my %groups; # - user groups
21 my $fatal_key = 'result.fatalEvents';
22 my $info_key = 'result.infoEvents';
25 # --------------------------------------------------------------
26 # Loads the config info
27 # --------------------------------------------------------------
30 my $conf = OpenSRF::Utils::SettingsClient->new;
31 my @pfx = ( "apps", "open-ils.penalty","app_settings" );
32 $path = $conf->config_value( @pfx, 'script_path');
33 $script = $conf->config_value( @pfx, 'patron_penalty' );
35 if(!($path and $script)) {
36 $logger->error("penalty: server config missing script and/or script path");
40 $logger->info("penalty: Loading patron penalty script $script with path $path");
44 # --------------------------------------------------------------
45 # Builds the script runner and shoves data into the script
47 # --------------------------------------------------------------
51 my $patron = $args{patron};
52 my $patron_summary = $args{patron_summary};
54 my $pgroup = find_profile($patron);
55 $patron->profile( $pgroup );
58 $runner->refresh_context if $runner;
61 $runner = OpenILS::Utils::ScriptRunner->new unless $runner;
62 $runner->add_path( $_ );
65 $runner->insert( 'environment.patron', $patron, 1);
66 $runner->insert( $fatal_key, [] );
67 $runner->insert( $info_key, [] );
68 $runner->insert( 'environment.patronItemsOut', $patron_summary->[0] );
69 $runner->insert( 'environment.patronFines', $patron_summary->[1] );
79 my $groups = $U->storagereq(
80 'open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic');
81 %groups = map { $_->id => $_ } @$groups;
84 return $groups{$patron->profile};
89 __PACKAGE__->register_method (
90 method => 'patron_penalty',
91 api_name => 'open-ils.penalty.patron_penalty.calculate',
93 Calculates the patron's standing penalties
94 @param args An object of named params including:
95 patronid The id of the patron
96 update True if this call should update the database
97 background True if this call should return immediately,
98 then go on to process the penalties. This flag
99 works only in conjunction with the 'update' flag.
100 @return An object with keys 'fatal_penalties' and
101 'info_penalties' who are themeselves arrays of 0 or
102 more penalties. Returns event on error.
106 # --------------------------------------------------------------
109 # - background : modifier to 'update' which says to return
110 # immediately then continue processing. If this flag is set
111 # then the caller will get no penalty info and will never
112 # know for sure if the call even succeeded.
113 # --------------------------------------------------------------
115 my( $self, $conn, $args ) = @_;
119 $conn->respond_complete(1) if $$args{background};
121 if( $patron = $$args{patron} ) { # - unfless if necessary
122 $patron->home_ou( $patron->home_ou->id ) if ref($patron->home_ou);
123 $patron->profile( $patron->profile->id ) if ref($patron->profile);
126 ( $patron, $evt ) = $U->fetch_user($$args{patronid});
130 # - fetch the circulation summary info for the user
131 my $summary = $U->fetch_patron_circ_summary($patron->id);
133 # - build the script runner
134 my $runner = build_runner(
136 patron_summary => $summary
139 # - Load up the script and run it
140 $runner->add_path($path);
141 $runner->run($script) or
142 throw OpenSRF::EX::ERROR ("Patron Penalty Script Died: $@");
144 # array items are returned as a comma-separated list of strings
145 my @fatals = split( /,/, $runner->retrieve($fatal_key) );
146 my @infos = split( /,/, $runner->retrieve($info_key) );
147 my $all = [ @fatals, @infos ];
149 $logger->info("penalty: script returned fatal events [@fatals] and info events [@infos]");
151 $conn->respond_complete(
152 { fatal_penalties => \@fatals, info_penalties => \@infos });
154 # - update the penalty info in the db if necessary
155 $evt = update_patron_penalties(
157 penalties => $all ) if $$args{update};
159 # - The caller won't know it failed, so log it
160 $logger->error("penalty: Error updating the patron ".
161 "penalties in the database: ".Dumper($evt)) if $evt;
166 # --------------------------------------------------------------
167 # Removes existing penalties for the patron that are not passed
168 # into this function. Creates new penalty entries for the
169 # provided penalties that don't already exist;
170 # --------------------------------------------------------------
171 sub update_patron_penalties {
174 my $patron = $args{patron};
175 my $penalties = $args{penalties};
177 my $session = $U->start_db_session();
179 # - fetch the current penalties
180 my $existing = $session->request(
181 'open-ils.storage.direct.actor.'.
182 'user_standing_penalty.search.usr.atomic', $patron->id )->gather(1);
185 my $patronid = $patron->id;
187 # If an existing penalty is not in the newly generated
188 # list of penalties, remove it from the DB
189 for my $e (@$existing) {
190 if( ! grep { $_ eq $e->penalty_type } @$penalties ) {
192 $logger->activity("penalty: removing user penalty ".
193 $e->penalty_type . " from user $patronid");
195 my $s = $session->request(
196 'open-ils.storage.direct.actor.user_standing_penalty.delete', $e->id )->gather(1);
197 return $U->DB_UPDATE_FAILED($e) unless defined($s);
201 # Add penalties that previously didn't exist
202 for my $p (@$penalties) {
203 if( ! grep { $_->penalty_type eq $p } @$existing ) {
205 $logger->activity("penalty: adding user penalty $p to user $patronid");
207 my $newp = Fieldmapper::actor::user_standing_penalty->new;
208 $newp->penalty_type( $p );
209 $newp->usr( $patronid );
211 my $s = $session->request(
212 'open-ils.storage.direct.actor.user_standing_penalty.create', $newp )->gather(1);
213 return $U->DB_UPDATE_FAILED($p) unless $s;
217 $U->commit_db_session($session);