add a validator (for stacking) to optionally check the age of an event target
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Trigger / Validator.pm
1 package OpenILS::Application::Trigger::Validator;
2 use strict; use warnings;
3 use DateTime;
4 use DateTime::Format::ISO8601;
5 use OpenSRF::Utils qw/:datetime/;
6 use OpenSRF::Utils::Logger qw/:logger/;
7 use OpenILS::Const qw/:const/;
8 sub fourty_two { return 42 }
9 sub NOOP_True { return 1 }
10 sub NOOP_False { return 0 }
11
12 sub CircIsOpen {
13     my $self = shift;
14     my $env = shift;
15
16     return 0 if (defined($env->{target}->checkin_time));
17     return 0 if ($env->{params}->{max_delay_age} && !$self->MaxPassiveDelayAge($env));
18
19     if ($env->{params}->{min_target_age}) {
20         $env->{params}->{target_age_field} = 'xact_start';
21         return 0 if (!$self->MinPassiveTargetAge($env));
22     }
23
24     return 1;
25 }
26
27 sub MaxPassiveDelayAge {
28     my $self = shift;
29     my $env = shift;
30     my $target = $env->{target};
31     my $delay_field = $env->{event}->event_def->delay_field;
32
33     my $delay_field_ts = DateTime::Format::ISO8601->new->parse_datetime(clense_ISO8601($target->$delay_field()));
34
35     # the cutoff date is the target timestamp + the delay + the max_delay_age
36     # This is also true for negative delays. For example:
37     #    due_date + "-3 days" + "1 day" == -2 days old.
38     $delay_field_ts
39         ->add( seconds => interval_to_seconds( $env->{event}->event_def->delay ) )
40         ->add( seconds => interval_to_seconds( $env->{params}->{max_delay_age} ) );
41
42     return 1 if $delay_field_ts > DateTime->now;
43     return 0;
44 }
45
46 sub MinPassiveTargetAge {
47     my $self = shift;
48     my $env = shift;
49     my $target = $env->{target};
50     my $delay_field = $env->{params}->{target_age_field} || $env->{event}->event_def->delay_field;
51
52     my $delay_field_ts = DateTime::Format::ISO8601->new->parse_datetime(clense_ISO8601($target->$delay_field()));
53
54     # to get the minimum time that the target must have aged to, add the min age to the delay field
55     $delay_field_ts->add( seconds => interval_to_seconds( $env->{params}->{min_target_age} ) );
56
57     return 1 if $delay_field_ts <= DateTime->now;
58     return 0;
59 }
60
61 sub CircIsOverdue {
62     my $self = shift;
63     my $env = shift;
64     my $circ = $env->{target};
65
66     return 0 if $circ->checkin_time;
67     return 0 if $circ->stop_fines and not $circ->stop_fines =~ /MAXFINES|LONGOVERDUE/;
68     return 0 if ($env->{params}->{max_delay_age} && !$self->MaxPassiveDelayAge($env));
69
70     if ($env->{params}->{min_target_age}) {
71         $env->{params}->{target_age_field} = 'xact_start';
72         return 0 if (!$self->MinPassiveTargetAge($env));
73     }
74
75     my $due_date = DateTime::Format::ISO8601->new->parse_datetime(clense_ISO8601($circ->due_date));
76     return 0 if $due_date > DateTime->now;
77
78     return 1;
79 }
80
81 sub HoldIsAvailable {
82     my $self = shift;
83     my $env = shift;
84
85     my $hold = $env->{target};
86
87     return 1 if 
88         !$hold->cancel_time and
89         $hold->capture_time and 
90         $hold->current_copy and
91         $hold->current_copy->status == OILS_COPY_STATUS_ON_HOLDS_SHELF;
92
93     return 0;
94 }
95
96 1;