1 package OpenILS::Application::Trigger;
2 use strict; use warnings;
3 use OpenILS::Application;
4 use base qw/OpenILS::Application/;
6 use OpenSRF::EX qw/:try/;
8 use OpenSRF::AppSession;
9 use OpenSRF::Utils::SettingsClient;
10 use OpenSRF::Utils::Logger qw/:level/;
11 use OpenSRF::Utils qw/:datetime/;
14 use DateTime::Format::ISO8601;
16 use OpenILS::Utils::Fieldmapper;
17 use OpenILS::Utils::CStoreEditor q/:funcs/;
18 use OpenILS::Application::Trigger::Event;
19 use OpenILS::Application::Trigger::EventGroup;
22 my $log = 'OpenSRF::Utils::Logger';
27 sub create_events_for_object {
34 my $ident = $target->Identity;
35 my $ident_value = $target->$ident();
37 my $editor = new_editor(xact=>1);
39 my $hooks = $editor->search_action_trigger_hook(
41 core_type => $target->json_hint
45 my %hook_hash = map { ($_->key, $_) } @$hooks;
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 ],
56 for my $def ( @$defs ) {
58 my $date = DateTime->now;
60 if ($hook_hash{$def->hook}->passive eq 'f') {
62 if (my $dfield = $def->delay_field) {
63 if ($target->$dfield()) {
64 $date = DateTime::Format::ISO8601->new->parse_datetime( clense_ISO8601($target->$dfield) );
70 $date->add( seconds => interval_to_seconds($def->delay) );
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' ) );
78 $editor->create_action_trigger_event( $event );
80 $client->respond( $event->id );
87 __PACKAGE__->register_method(
88 api_name => 'open-ils.trigger.event.autocreate',
89 method => 'create_events_for_object',
96 sub fire_single_event {
101 my $e = OpenILS::Application::Trigger::Event->new($event_id);
103 if ($e->validate->valid) {
109 reacted => $e->reacted,
110 cleanedup => $e->cleanedup,
114 __PACKAGE__->register_method(
115 api_name => 'open-ils.trigger.event.fire',
116 method => 'fire_single_event',
121 sub fire_event_group {
126 my $e = OpenILS::Application::Trigger::EventGroup->new(@$events);
128 if ($e->validate->valid) {
134 reacted => $e->reacted,
135 cleanedup => $e->cleanedup,
139 __PACKAGE__->register_method(
140 api_name => 'open-ils.trigger.event_group.fire',
141 method => 'fire_event_group',
150 my $editor = new_editor();
152 return $editor->search_action_trigger_event([
153 { state => 'pending', run_time => {'<' => 'now'} },
157 __PACKAGE__->register_method(
158 api_name => 'open-ils.trigger.event.find_pending',
159 method => 'pending_events',
168 my ($events) = $self->method_lookup('open-ils.trigger.event.find_pending')->run();
170 my %groups = ( '*' => [] );
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) {
177 # split the grouping link steps
178 my @steps = split '.', $group;
180 # find the grouping object
181 my $node = $event->target;
182 $node = $node->$_() for ( @steps );
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();
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;
192 # it's a non-grouped event
193 push @{ $groups{'*'} }, $e;
200 __PACKAGE__->register_method(
201 api_name => 'open-ils.trigger.event.find_pending_by_group',
202 method => 'grouped_events',
210 my ($groups) = $self->method_lookup('open-ils.trigger.event.find_pending_by_group')->run();
212 for my $def ( %$groups ) {
214 for my $event ( @{ $$groups{'*'} } ) {
217 ->method_lookup('open-ils.trigger.event.fire')
222 my $defgroup = $$groups{$def};
223 for my $ident ( keys %$defgroup ) {
226 ->method_lookup('open-ils.trigger.event_group.fire')
227 ->run($$defgroup{$ident})
235 __PACKAGE__->register_method(
236 api_name => 'open-ils.trigger.event.run_all_pending',
237 method => 'run_all_events',