]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Trigger.pm
add strict/warnings all around to ease debugging
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Trigger.pm
1 package OpenILS::Application::Trigger;
2 use strict; use warnings;
3 use OpenILS::Application;
4 use base qw/OpenILS::Application/;
5
6 use OpenSRF::EX qw/:try/;
7
8 use OpenSRF::AppSession;
9 use OpenSRF::Utils::SettingsClient;
10 use OpenSRF::Utils::Logger qw/:level/;
11 use OpenSRF::Utils qw/:datetime/;
12
13 use DateTime;
14 use DateTime::Format::ISO8601;
15
16 use OpenILS::Utils::Fieldmapper;
17 use OpenILS::Utils::CStoreEditor q/:funcs/;
18 use OpenILS::Application::Trigger::Event;
19 use OpenILS::Application::Trigger::EventGroup;
20
21
22 my $log = 'OpenSRF::Utils::Logger';
23
24 sub initialize {}
25 sub child_init {}
26
27 sub create_events_for_object {
28     my $self = shift;
29     my $client = shift;
30     my $key = shift;
31     my $target = shift;
32     my $location = shift;
33
34     my $ident = $target->Identity;
35     my $ident_value = $target->$ident();
36
37     my $editor = new_editor(xact=>1);
38
39     my $hooks = $editor->search_action_trigger_hook(
40         { key       => $key,
41           core_type => $target->json_hint
42         }
43     );
44
45     my %hook_hash = map { ($_->key, $_) } @$hooks;
46
47     my $orgs = $editor->json_query({ from => [ 'actor.org_unit_ancestors' => $location ] });
48     my $defs = $editor->search_action_trigger_event_definition([
49         { hook   => [ keys %hook_hash ],
50           owner  => [ map { $_->{id} } @$orgs  ],
51           active => 't'
52         },
53         { idlist => 1 }
54     ]);
55
56     for my $def ( @$defs ) {
57
58         my $date = DateTime->now;
59
60         if ($hook_hash{$def->hook}->passive eq 'f') {
61
62             if (my $dfield = $def->delay_field) {
63                 if ($target->$dfield()) {
64                     $date = DateTime::Format::ISO8601->new->parse_datetime( clense_ISO8601($target->$dfield) );
65                 } else {
66                     next;
67                 }
68             }
69
70             $date->add( seconds => interval_to_seconds($def->delay) );
71         }
72
73         my $event = Fieldmapper::action_trigger::event->new();
74         $event->target( $ident_value );
75         $event->event_def( $def->id );
76         $event->run_time( $date->strftime( '%F %T%z' ) );
77
78         $editor->create_action_trigger_event( $event );
79
80         $client->respond( $event->id );
81     }
82
83     $editor->commit;
84
85     return undef;
86 }
87 __PACKAGE__->register_method(
88     api_name => 'open-ils.trigger.event.autocreate',
89     method   => 'create_events_for_object',
90     api_level=> 1,
91     stream   => 1,
92     argc     => 3
93 );
94
95
96 sub fire_single_event {
97     my $self = shift;
98     my $client = shift;
99     my $event_id = shift;
100
101     my $e = OpenILS::Application::Trigger::Event->new($event_id);
102
103     if ($e->validate->valid) {
104         $e->react->cleanup;
105     }
106
107     return {
108         valid     => $e->valid,
109         reacted   => $e->reacted,
110         cleanedup => $e->cleanedup,
111         event     => $e->event
112     };
113 }
114 __PACKAGE__->register_method(
115     api_name => 'open-ils.trigger.event.fire',
116     method   => 'fire_single_event',
117     api_level=> 1,
118     argc     => 1
119 );
120
121 sub fire_event_group {
122     my $self = shift;
123     my $client = shift;
124     my $events = shift;
125
126     my $e = OpenILS::Application::Trigger::EventGroup->new(@$events);
127
128     if ($e->validate->valid) {
129         $e->react->cleanup;
130     }
131
132     return {
133         valid     => $e->valid,
134         reacted   => $e->reacted,
135         cleanedup => $e->cleanedup,
136         events    => $e->events
137     };
138 }
139 __PACKAGE__->register_method(
140     api_name => 'open-ils.trigger.event_group.fire',
141     method   => 'fire_event_group',
142     api_level=> 1,
143     argc     => 1
144 );
145
146 sub pending_events {
147     my $self = shift;
148     my $client = shift;
149
150     my $editor = new_editor();
151
152     return $editor->search_action_trigger_event([
153         { state => 'pending', run_time => {'<' => 'now'} },
154         { idlist=> 1 }
155     ]);
156 }
157 __PACKAGE__->register_method(
158     api_name => 'open-ils.trigger.event.find_pending',
159     method   => 'pending_events',
160     api_level=> 1
161 );
162
163
164 sub grouped_events {
165     my $self = shift;
166     my $client = shift;
167
168     my ($events) = $self->method_lookup('open-ils.trigger.event.find_pending')->run();
169
170     my %groups = ( '*' => [] );
171
172     for my $e_id ( @$events ) {
173         my $e = OpenILS::Application::Trigger::Event->new($e_id);
174         if ($e->validate->valid) {
175             if (my $group = $event->event->event_def->group_field) {
176
177                 # split the grouping link steps
178                 my @steps = split '.', $group;
179
180                 # find the grouping object
181                 my $node = $event->target;
182                 $node = $node->$_() for ( @steps );
183
184                 # get the pkey value for the grouping object on this event
185                 my $node_ident = $node->Identity;
186                 my $ident_value = $node->$node_ident();
187
188                 # push this event onto the event+grouping_pkey_value stack
189                 $groups{$e->event->event_def->id}{$ident_value} ||= [];
190                 push @{ $groups{$e->event->event_def->id}{$ident_value} }, $e;
191             } else {
192                 # it's a non-grouped event
193                 push @{ $groups{'*'} }, $e;
194             }
195         }
196     }
197
198     return \%groups;
199 }
200 __PACKAGE__->register_method(
201     api_name => 'open-ils.trigger.event.find_pending_by_group',
202     method   => 'grouped_events',
203     api_level=> 1
204 );
205
206 sub run_all_events {
207     my $self = shift;
208     my $client = shift;
209
210     my ($groups) = $self->method_lookup('open-ils.trigger.event.find_pending_by_group')->run();
211
212     for my $def ( %$groups ) {
213         if ($def eq '*') {
214             for my $event ( @{ $$groups{'*'} } ) {
215                 $client->respond(
216                     $self
217                         ->method_lookup('open-ils.trigger.event.fire')
218                         ->run($event)
219                 );
220             }
221         } else {
222             my $defgroup = $$groups{$def};
223             for my $ident ( keys %$defgroup ) {
224                 $client->respond(
225                     $self
226                         ->method_lookup('open-ils.trigger.event_group.fire')
227                         ->run($$defgroup{$ident})
228                 );
229             }
230         }
231     }
232                 
233             
234 }
235 __PACKAGE__->register_method(
236     api_name => 'open-ils.trigger.event.run_all_pending',
237     method   => 'run_all_events',
238     api_level=> 1
239 );
240
241
242 1;