#!perl

package RT::Condition::CustomFieldSetTo;
use 5.10.1;
use strict;
use warnings;

use Scalar::Util qw(looks_like_number);
use List::MoreUtils qw(any); 

use base qw(RT::Condition);


=pod

=head1 NAME

RT::Condition::CustomFieldSetTo

=head1 DESCRIPTION

An RT condition that tests whether a named custom field is set to a given
value. The custom field name and target value is set by the condition argument.

=head1 ARGUMENTS

C<RT::Action::CustomFieldSetTo> requires a condition argument, so
you must provide copies of it in RT's scripconditions table with appropriate
arguments.

The argument takes the form of a comma-separated series of values. The first
value is the custom field name; following values are the values of the custom
field that will be accepted as matching the condition.

If no list of values is provided for the custom field, the condition triggers
whenever the custom field value changes in a transaction, irrespective of the
value.

=cut

sub IsApplicable {
    my $self = shift;

    $RT::Logger->debug("RT::Condition::CustomFieldSetTo invoked with " . $self->Argument . " on ticket " . $self->TicketObj . " txid " . $self->TransactionObj->Id);
    # If the transaction isn't on a numeric field we know it isn't a custom field
    # and can just return:
    my $field = $self->TransactionObj->Field;
    return 0 unless (looks_like_number($field));
    
    # If no custom field is supplied, return
    die("RT::Condition::CustomFieldSetTo invoked without arguments, cannot act")
        unless $self->Argument;

    my ($cfname, @cfvalues) = split(',', $self->Argument);
    
    # Get the custom field ID.
    my $sla_cf = RT::CustomField->new( $RT::SystemUser );
    my ($result, $msg) = $sla_cf->LoadByNameAndQueue( Name => $cfname, Queue => $self->TicketObj->Queue );
    if (!$result) {
        die("No custom field named '$cfname': $msg");
    }
    
    # If the transaction is against the named custom field, see if it matches one of the
    # listed values.
    my $ret;
    if ($field eq $sla_cf->Id) {
        # Get the new CF value:
        my $new_cfv = RT::ObjectCustomFieldValue->new( $RT::SystemUser );
        ($result, $msg) = $new_cfv->Load($self->TransactionObj->NewReference);
        die("Couldn't load CF value: $msg") if (!$result);
        # ... and attempt to match it. 
        if (@cfvalues) {
            # Found cf value in expected list
            $ret = any { $_ eq $new_cfv->Content } @cfvalues;
        } else {
            # No CF values specified, assume any change of this CF matches.
            $ret = 1;
        }
    } else {
        # It's a different CF, doesn't apply
        $ret = 0;
    }
    $RT::Logger->debug("RT::Condition::CustomFieldSetTo for " . $self->Argument . " on tx " . $self->TransactionObj->Id . " returning " . $ret);
    return $ret;
}

1;

