]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Penalty.pm
moved penalty server to cstore since it is called a lot - speed
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Penalty.pm
1 package OpenILS::Application::Penalty;
2 use strict; use warnings;
3 use DateTime;
4 use Data::Dumper;
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 OpenILS::Utils::CStoreEditor qw/:funcs/;
13 use base 'OpenSRF::Application';
14
15 my $U = "OpenILS::Application::AppUtils";
16 my $script;
17 my $path;
18 my $libs;
19 my $runner;
20 my %groups; # - user groups
21
22 my $fatal_key = 'result.fatalEvents';
23 my $info_key = 'result.infoEvents';
24
25
26 # --------------------------------------------------------------
27 # Loads the config info
28 # --------------------------------------------------------------
29 sub initialize {
30
31         my $conf = OpenSRF::Utils::SettingsClient->new;
32         my @pfx  = ( "apps", "open-ils.penalty","app_settings" );
33         $path           = $conf->config_value( @pfx, 'script_path');
34         $script = $conf->config_value( @pfx, 'patron_penalty' );
35
36         if(!($path and $script)) {
37                 $logger->error("penalty:  server config missing script and/or script path");
38                 return 0;
39         }
40
41         $logger->info("penalty: Loading patron penalty script $script with path $path");
42 }
43
44
45
46 __PACKAGE__->register_method (
47         method   => 'patron_penalty',
48         api_name         => 'open-ils.penalty.patron_penalty.calculate',
49         signature => q/
50                 Calculates the patron's standing penalties
51                 @param args An object of named params including:
52                         patronid The id of the patron
53                         update True if this call should update the database
54                         background True if this call should return immediately,
55                                 then go on to process the penalties.  This flag
56                                 works only in conjunction with the 'update' flag.
57                 @return An object with keys 'fatal_penalties' and 
58                 'info_penalties' who are themeselves arrays of 0 or 
59                 more penalties.  Returns event on error.
60         /
61 );
62
63 # --------------------------------------------------------------
64 # modes: 
65 #  - update 
66 #  - background : modifier to 'update' which says to return 
67 #               immediately then continue processing.  If this flag is set
68 #               then the caller will get no penalty info and will never 
69 #               know for sure if the call even succeeded. 
70 # --------------------------------------------------------------
71 sub patron_penalty {
72         my( $self, $conn, $args ) = @_;
73         
74         my( $patron, $evt );
75
76         $conn->respond_complete(1) if $$args{background};
77
78         return { fatal_penalties => [], info_penalties => [] }
79                 unless ($args->{patron} || $args->{patronid});
80
81         $args->{patron_id} = $args->{patronid};
82         $args->{fetch_patron_circ_info} = 1;
83         my $runner = OpenILS::Application::Circ::ScriptBuilder->build($args);
84
85         # - Load up the script and run it
86         $runner->add_path($path);
87
88         $runner->load($script);
89         my $result = $runner->run or throw OpenSRF::EX::ERROR ("Patron Penalty Script Died: $@");
90
91         my @fatals = @{$result->{fatalEvents}};
92         my @infos = @{$result->{infoEvents}};
93         my $all = [ @fatals, @infos ];
94
95         $logger->info("penalty: script returned fatal events [@fatals] and info events [@infos]");
96
97         $conn->respond_complete(
98                 { fatal_penalties => \@fatals, info_penalties => \@infos });
99
100         # - update the penalty info in the db if necessary
101         $logger->debug("update penalty settings = " . $$args{update});
102
103         $evt = update_patron_penalties( 
104                 patron    => $args->{patron}, 
105                 penalties => $all ) if $$args{update};
106
107         # - The caller won't know it failed, so log it
108         $logger->error("penalty: Error updating the patron ".
109                 "penalties in the database: ".Dumper($evt)) if $evt;
110
111         return undef;
112 }
113
114 # --------------------------------------------------------------
115 # Removes existing penalties for the patron that are not passed 
116 # into this function.  Creates new penalty entries for the 
117 # provided penalties that don't already exist;
118 # --------------------------------------------------------------
119 sub update_patron_penalties {
120
121         my %args      = @_;
122         my $patron    = $args{patron};
123         my $penalties = $args{penalties};
124         my $pid = $patron->id;
125
126
127         $logger->debug("updating penalties for patron $pid => @$penalties");
128         my $editor = new_editor(xact =>1);
129
130
131         # - fetch the current penalties
132         my $existing = $editor->search_actor_user_standing_penalty({usr=>$pid});
133
134         my @types;
135         push( @types, $_->penalty_type ) for @$existing;
136         $logger->info("penalty: user has existing penalties [@types]");
137
138         my @deleted;
139
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 ) {
144
145                         $logger->activity("penalty: removing user penalty ".
146                                 $e->penalty_type . " from user $pid");
147
148                         $editor->delete_actor_user_standing_penalty($e)
149                                 or return $editor->event;
150                 }
151         }
152
153         # Add penalties that previously didn't exist
154         for my $p (@$penalties) {
155                 if( ! grep { $_->penalty_type eq $p } @$existing ) {
156
157                         $logger->activity("penalty: adding user penalty $p to user $pid");
158
159                         my $newp = Fieldmapper::actor::user_standing_penalty->new;
160                         $newp->penalty_type( $p );
161                         $newp->usr( $pid );
162
163                         $editor->create_actor_user_standing_penalty($newp)
164                                 or return $editor->event;
165                 }
166         }
167         
168         $editor->commit;
169         return undef;
170 }
171
172
173
174
175
176 1;