1 package OpenILS::Application::Trigger;
2 use OpenILS::Application;
3 use base qw/OpenILS::Application/;
5 use OpenSRF::EX qw/:try/;
7 use OpenSRF::AppSession;
8 use OpenSRF::Utils::SettingsClient;
9 use OpenSRF::Utils::Logger qw/:level/;
10 use OpenSRF::Utils qw/:datetime/;
13 use DateTime::Format::ISO8601;
15 use OpenILS::Utils::Fieldmapper;
16 use OpenILS::Utils::CStoreEditor q/:funcs/;
17 use OpenILS::Application::Trigger::Event;
18 use OpenILS::Application::Trigger::EventGroup;
21 my $log = 'OpenSRF::Utils::Logger';
26 sub create_events_for_object {
33 my $ident = $target->Identity;
34 my $ident_value = $target->$ident();
36 my $editor = new_editor(xact=>1);
38 my $hooks = $editor->search_action_trigger_hook(
40 core_type => $target->json_hint
44 my %hook_hash = map { ($_->id, $_) } @$hooks;
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 ],
55 for my $def ( @$defs ) {
57 my $date = DateTime->now;
59 if ($hook_hash{$def->hook}->passive eq 'f') {
61 if (my $dfield = $def->delay_field) {
62 if ($target->$dfield()) {
63 $date = DateTime::Format::ISO8601->new->parse_datetime( clense_ISO8601($target->$dfield) );
69 $date->add( seconds => interval_to_seconds($def->delay) );
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( '%G %T%z' ) );
77 $event = $editor->create_action_trigger_event( $event );
79 $client->respond( $event->id );
86 __PACKAGE__->register_method(
87 api_name => 'open-ils.trigger.event.autocreate',
88 method => 'create_events_for_object',
95 sub fire_single_event {
100 my $e = OpenILS::Application::Trigger::Event->new($event_id);
102 if ($e->validate->valid) {
108 reacted => $e->reacted,
109 cleanedup => $e->cleanedup,
113 __PACKAGE__->register_method(
114 api_name => 'open-ils.trigger.event.fire',
115 method => 'fire_single_event',
120 sub fire_event_group {
125 my $e = OpenILS::Application::Trigger::EventGroup->new(@$events);
127 if ($e->validate->valid) {
133 reacted => $e->reacted,
134 cleanedup => $e->cleanedup,
138 __PACKAGE__->register_method(
139 api_name => 'open-ils.trigger.event_group.fire',
140 method => 'fire_event_group',
149 my $editor = new_editor();
151 return $editor->search_action_trigger_event([
152 { state => 'pending', run_time => {'<' => 'now'} },
156 __PACKAGE__->register_method(
157 api_name => 'open-ils.trigger.event.find_pending',
158 method => 'pending_events',
167 my ($events) = $self->method_lookup('open-ils.trigger.event.find_pending')->run();
169 my %groups = ( '*' => [] );
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) {
176 # split the grouping link steps
177 my @steps = split '.', $group;
179 # find the grouping object
180 my $node = $event->target;
181 $node = $node->$_() for ( @steps );
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();
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;
191 # it's a non-grouped event
192 push @{ $groups{'*'} }, $e;
199 __PACKAGE__->register_method(
200 api_name => 'open-ils.trigger.event.find_pending_by_group',
201 method => 'grouped_events',
209 my ($groups) = $self->method_lookup('open-ils.trigger.event.find_pending_by_group')->run();
211 for my $def ( %$groups ) {
213 for my $event ( @{ $$groups{'*'} } ) {
216 ->method_lookup('open-ils.trigger.event.fire')
221 my $defgroup = $$groups{$def};
222 for my $ident ( keys %$defgroup ) {
225 ->method_lookup('open-ils.trigger.event_group.fire')
226 ->run($$defgroup{$ident})
234 __PACKAGE__->register_method(
235 api_name => 'open-ils.trigger.event.run_all_pending',
236 method => 'run_all_events',