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::Application::Circ::ScriptBuilder;
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");
45 __PACKAGE__->register_method (
46 method => 'patron_penalty',
47 api_name => 'open-ils.penalty.patron_penalty.calculate',
49 Calculates the patron's standing penalties
50 @param args An object of named params including:
51 patronid The id of the patron
52 update True if this call should update the database
53 background True if this call should return immediately,
54 then go on to process the penalties. This flag
55 works only in conjunction with the 'update' flag.
56 @return An object with keys 'fatal_penalties' and
57 'info_penalties' who are themeselves arrays of 0 or
58 more penalties. Returns event on error.
62 # --------------------------------------------------------------
65 # - background : modifier to 'update' which says to return
66 # immediately then continue processing. If this flag is set
67 # then the caller will get no penalty info and will never
68 # know for sure if the call even succeeded.
69 # --------------------------------------------------------------
71 my( $self, $conn, $args ) = @_;
75 $conn->respond_complete(1) if $$args{background};
77 return { fatal_penalties => [], info_penalties => [] }
78 unless ($args->{patron} || $args->{patronid});
80 $args->{patron_id} = $args->{patronid};
81 $args->{fetch_patron_circ_info} = 1;
82 my $runner = OpenILS::Application::Circ::ScriptBuilder->build($args);
84 # - Load up the script and run it
85 $runner->add_path($path);
87 $runner->load($script);
88 my $result = $runner->run or throw OpenSRF::EX::ERROR ("Patron Penalty Script Died: $@");
90 my @fatals = @{$result->{fatalEvents}};
91 my @infos = @{$result->{infoEvents}};
92 my $all = [ @fatals, @infos ];
94 $logger->info("penalty: script returned fatal events [@fatals] and info events [@infos]");
96 $conn->respond_complete(
97 { fatal_penalties => \@fatals, info_penalties => \@infos });
99 # - update the penalty info in the db if necessary
100 $logger->debug("update penalty settings = " . $$args{update});
102 $evt = update_patron_penalties(
103 patron => $args->{patron},
104 penalties => $all ) if $$args{update};
106 # - The caller won't know it failed, so log it
107 $logger->error("penalty: Error updating the patron ".
108 "penalties in the database: ".Dumper($evt)) if $evt;
113 # --------------------------------------------------------------
114 # Removes existing penalties for the patron that are not passed
115 # into this function. Creates new penalty entries for the
116 # provided penalties that don't already exist;
117 # --------------------------------------------------------------
118 sub update_patron_penalties {
121 my $patron = $args{patron};
122 my $penalties = $args{penalties};
123 my $pid = $patron->id;
125 $logger->debug("updating penalties for patron $pid => @$penalties");
127 my $session = $U->start_db_session();
129 # - fetch the current penalties
130 my $existing = $session->request(
131 'open-ils.storage.direct.actor.'.
132 'user_standing_penalty.search.usr.atomic', $pid )->gather(1);
135 push( @types, $_->penalty_type ) for @$existing;
136 $logger->info("penalty: user has existing penalties [@types]");
140 # If an existing penalty is not in the newly generated
141 # list of penalties, remove it from the DB
142 for my $e (@$existing) {
143 if( ! grep { $_ eq $e->penalty_type } @$penalties ) {
145 $logger->activity("penalty: removing user penalty ".
146 $e->penalty_type . " from user $pid");
148 my $s = $session->request(
149 'open-ils.storage.direct.actor.user_standing_penalty.delete', $e->id )->gather(1);
150 return $U->DB_UPDATE_FAILED($e) unless defined($s);
154 # Add penalties that previously didn't exist
155 for my $p (@$penalties) {
156 if( ! grep { $_->penalty_type eq $p } @$existing ) {
158 $logger->activity("penalty: adding user penalty $p to user $pid");
160 my $newp = Fieldmapper::actor::user_standing_penalty->new;
161 $newp->penalty_type( $p );
164 my $s = $session->request(
165 'open-ils.storage.direct.actor.user_standing_penalty.create', $newp )->gather(1);
166 return $U->DB_UPDATE_FAILED($p) unless $s;
170 $U->commit_db_session($session);