<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package OpenILS::Application::Trigger::EventGroup;
use strict; use warnings;
use OpenILS::Application::Trigger::Event;
use base 'OpenILS::Application::Trigger::Event';
use OpenSRF::EX qw/:try/;

use OpenSRF::Utils::Logger qw/:level/;

use OpenILS::Utils::Fieldmapper;
use OpenILS::Utils::CStoreEditor q/:funcs/;
use OpenILS::Application::Trigger::ModRunner;

my $log = 'OpenSRF::Utils::Logger';

sub new {
    my $class = shift;
    my @ids = @_;
    $class = ref($class) || $class;

    my $editor = new_editor(xact=&gt;1);

    my $self = bless {
        environment =&gt; {},
        events      =&gt; [
            map {
                ref($_) ?
                    do { $_-&gt;standalone(0); $_-&gt;editor($editor); $_ } :
                    OpenILS::Application::Trigger::Event-&gt;new($_, $editor)
            } @ids
        ],
        ids         =&gt; \@ids,
        editor      =&gt; $editor
    } =&gt; $class;


    $self-&gt;editor-&gt;xact_commit; # flush out those updates
    $self-&gt;editor-&gt;xact_begin;

    return $self;
}

sub react {
    my $self = shift;

    return $self if (defined $self-&gt;reacted);

    if ($self-&gt;valid) {
        $self-&gt;update_state( 'reacting') || die 'Unable to update event group state';
        $self-&gt;build_environment;

        try {
            $self-&gt;reacted(
                OpenILS::Application::Trigger::ModRunner::Reactor
                    -&gt;new( $self-&gt;event-&gt;event_def-&gt;reactor, $self-&gt;environment )
                    -&gt;run
                    -&gt;final_result
            );
        } otherwise {
            $log-&gt;error( shift() );
            $self-&gt;update_state( 'error' ) || die 'Unable to update event group state';
        };

        if (defined $self-&gt;reacted) {
            $self-&gt;update_state( 'reacted' ) || die 'Unable to update event group state';
        } else {
            $self-&gt;update_state( 'error' ) || die 'Unable to update event group state';
        }
    } else {
        $self-&gt;{reacted} = undef;
    }
    return $self;
}

sub validate {
    my $self = shift;

    return $self if (defined $self-&gt;valid);

    $self-&gt;update_state( 'validating') || die 'Unable to update event group state';
    $self-&gt;editor-&gt;xact_begin;

    my @valid_events;
    try {
        for my $event ( @{ $self-&gt;events } ) {
            $event-&gt;validate;
            push @valid_events, $event if ($event-&gt;valid);
        }
        $self-&gt;valid(1) if (@valid_events);
        $self-&gt;{events} = \@valid_events;
        $self-&gt;{ids} = [ map { $_-&gt;id } @valid_events ];
        $self-&gt;editor-&gt;xact_commit;
    } otherwise {
        $log-&gt;error( shift() );
        $self-&gt;editor-&gt;xact_rollback;
        $self-&gt;update_state( 'error' ) || die 'Unable to update event group state';
    };

    return $self;
}
 
sub cleanedup {
    my $self = shift;
    return undef unless (ref $self);

    my $c = shift;
    $self-&gt;{cleanedup} = $c if (defined $c);
    return $self-&gt;{cleanedup};
}

sub reacted {
    my $self = shift;
    return undef unless (ref $self);

    my $r = shift;
    $self-&gt;{reacted} = $r if (defined $r);
    return $self-&gt;{reacted};
}

sub valid {
    my $self = shift;
    return undef unless (ref $self);

    my $v = shift;
    $self-&gt;{valid} = $v if (defined $v);
    return $self-&gt;{valid};
}

sub event {
    my $self = shift;
    return undef unless (ref $self);

    return $self-&gt;{events}[0]-&gt;event;
}

sub events {
    my $self = shift;
    return undef unless (ref $self);

    return $self-&gt;{events};
}

sub ids {
    my $self = shift;
    return undef unless (ref $self);

    return $self-&gt;{ids};
}

sub environment {
    my $self = shift;
    return undef unless (ref $self);

    my $e = shift;
    $self-&gt;{environment} = $e if (defined $e);
    return $self-&gt;{environment};
}

sub editor {
    my $self = shift;
    return undef unless (ref $self);

    my $e = shift;
    $self-&gt;{editor} = $e if (defined $e);
    return $self-&gt;{editor};
}

sub unfind {
    my $self = shift;
    return undef unless (ref $self);

    die 'Cannot unfind a reacted event group' if (defined $self-&gt;reacted);

    $self-&gt;update_state( 'pending' ) || die 'Unable to update event group state';
    $self-&gt;{events} = undef;
    return $self;
}

sub update_state {
    my $self = shift;
    return undef unless ($self &amp;&amp; ref $self);

    my $state = shift;
    return undef unless ($state);

    my $fields = shift;

    $self-&gt;editor-&gt;xact_begin || return undef;

    my @oks;
    my $ok;
    my $last_updated;
    for my $event ( @{ $self-&gt;events } ) {
        my $e = $self-&gt;editor-&gt;retrieve_action_trigger_event( $event-&gt;id );
        $e-&gt;start_time( 'now' ) unless $e-&gt;start_time;
        $e-&gt;update_time( 'now' );
        $e-&gt;update_process( $$ );
        $e-&gt;state( $state );

        $e-&gt;clear_start_time() if ($e-&gt;state eq 'pending');

        if ($fields &amp;&amp; ref($fields)) {
            $e-&gt;$_($$fields{$_}) for (keys %$fields);
        }

        my $ok = $self-&gt;editor-&gt;update_action_trigger_event( $e );
        if ($ok) {
            push @oks, $ok;
            $last_updated = $e-&gt;id;
        }
    }

    if (scalar(@oks) &lt; scalar(@{ $self-&gt;ids })) {
        $self-&gt;editor-&gt;xact_rollback;
        return undef;
    } else {
        $ok = $self-&gt;editor-&gt;xact_commit;
    }

    my $updated = $self-&gt;editor-&gt;retrieve_action_trigger_event($last_updated);
    if ($ok) {
        for my $event ( @{ $self-&gt;events } ) {
            my $e = $event-&gt;event;
            $e-&gt;start_time( $updated-&gt;start_time );
            $e-&gt;update_time( $updated-&gt;update_time );
            $e-&gt;update_process( $updated-&gt;update_process );
            $e-&gt;state( $updated-&gt;state );
        }
    }

    return $ok || undef;
}

sub build_environment {
    my $self = shift;
    my $env = $self-&gt;environment;

    $$env{EventProcessor} = $self;
    $$env{target} = [];
    $$env{event} = [];
    for my $e ( @{ $self-&gt;events } ) {
        for my $env_part ( keys %{ $e-&gt;environment } ) {
            next if ($env_part eq 'EventProcessor');
            if ($env_part eq 'target') {
                push @{ $$env{target} }, $e-&gt;environment-&gt;{target};
            } elsif ($env_part eq 'event') {
                push @{ $$env{event} }, $e-&gt;environment-&gt;{event};
            } else {
                $$env{$env_part} = $e-&gt;environment-&gt;{$env_part};
            }
        }
    }

    return $self;
}

1;
</pre></body></html>