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 authtoken The login session key
95 @params args An object of named params including:
96 patronid The id of the patron
97 update True if this call should update the database
98 background True if this call should return immediately,
99 then go on to process the penalties. This flag
100 works only in conjunction with the 'update' flag.
101 @return An object with keys 'fatal_penalties' and
102 'info_penalties' who are themeselves arrays of 0 or
103 more penalties. Returns event on error.
107 # --------------------------------------------------------------
110 # - background : modifier to 'update' which says to return
111 # immediately then continue processing. If this flag is set
112 # then the caller will get no penalty info and will never
113 # know for sure if the call even succeeded.
114 # --------------------------------------------------------------
116 my( $self, $conn, $authtoken, $args ) = @_;
118 my( $requestor, $patron, $evt );
120 $conn->respond_complete(1) if $$args{background};
122 $patron = $$args{patron};
125 $logger->info("penalty: ".JSON->perl2JSON($patron));
126 $logger->info("penalty: ".$patron->profile);
127 $logger->info("penalty: ".$patron->usrname);
130 ( $patron, $evt ) = $U->fetch_user($$args{patronid});
134 ( $requestor, $evt ) = $U->checkses($authtoken);
137 $evt = $U->check_perms( $requestor->id, $patron->home_ou, 'VIEW_USER');
140 # - fetch the circulation summary info for the user
141 my $summary = $U->fetch_patron_circ_summary($patron->id);
143 # - build the script runner
144 my $runner = build_runner(
146 patron_summary => $summary
149 # - Load up the script and run it
150 $runner->add_path($path);
151 $runner->load($script);
152 $runner->run or throw OpenSRF::EX::ERROR ("Patron Penalty Script Died: $@");
154 # array items are returned as a comma-separated list of strings
155 my @fatals = split( /,/, $runner->retrieve($fatal_key) );
156 my @infos = split( /,/, $runner->retrieve($info_key) );
157 my $all = [ @fatals, @infos ];
159 $logger->info("penalty: script returned fatal events [@fatals] and info events [@infos]");
161 $conn->respond_complete(
162 { fatal_penalties => \@fatals, info_penalties => \@infos });
164 # - update the penalty info in the db if necessary
165 $evt = update_patron_penalties(
168 requestor => $requestor ) if $$args{update};
170 # - The caller won't know it failed, so log it
171 $logger->error("penalty: Error updating the patron ".
172 "penalties in the database: ".Dumper($evt)) if $evt;
177 # --------------------------------------------------------------
178 # Removes existing penalties for the patron that are not passed
179 # into this function. Creates new penalty entries for the
180 # provided penalties that don't already exist;
181 # --------------------------------------------------------------
182 sub update_patron_penalties {
185 my $patron = $args{patron};
186 my $penalties = $args{penalties};
187 my $requestor = $args{requestor};
189 my $session = $U->start_db_session();
191 # - fetch the current penalties
192 my $existing = $session->request(
193 'open-ils.storage.direct.actor.'.
194 'user_standing_penalty.search.usr.atomic', $patron->id )->gather(1);
197 my $reqid = $requestor->id;
198 my $patronid = $patron->id;
200 # If an existing penalty is not in the newly generated
201 # list of penalties, remove it from the DB
202 for my $e (@$existing) {
203 if( ! grep { $_ eq $e->penalty_type } @$penalties ) {
205 $logger->activity("user $reqid removing user penalty ".
206 $e->penalty_type . " from user $patronid");
208 my $s = $session->request(
209 'open-ils.storage.direct.actor.user_standing_penalty.delete', $e->id )->gather(1);
210 return $U->DB_UPDATE_FAILED($e) unless defined($s);
214 # Add penalties that previously didn't exist
215 for my $p (@$penalties) {
216 if( ! grep { $_->penalty_type eq $p } @$existing ) {
218 $logger->activity("user $reqid adding user penalty $p to user $patronid");
220 my $newp = Fieldmapper::actor::user_standing_penalty->new;
221 $newp->penalty_type( $p );
222 $newp->usr( $patronid );
224 my $s = $session->request(
225 'open-ils.storage.direct.actor.user_standing_penalty.create', $newp )->gather(1);
226 return $U->DB_UPDATE_FAILED($p) unless $s;
230 $U->commit_db_session($session);