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