Datetime Custom Fields not populating on ticket update in v4.0.6

During the modification of a ticket that implements the Datetime Mandatory custom fields, the custom field, even if populated in the ticket, is not populated in the modification, and therefore the error “Input must match [Mandatory]” is obtained.

I found a problem like mine:

But the patch indicated does not work for me, perhaps because I installed version 4.0.6. Is there a patch for “ValidateCustomFields” for version RT 4.0.6?

Looking at that patch very quickly it seems it handled the case when the value for a date custom field was not changed but there was a value.

It sounds like your bug is a little more involved since mandatory validation fails even when you change the date value.

Without digging more it’s hard to say, I know 4.0 has been end of life for some time. Did you change something recently that could have introduced this behavior? Or just started using the mandatory validation?

Hi, thanks for the quick reply, I am asking in the company if changes have been made recently, but it seems not.

If during the ticket modification, I change the date value, or I enter the previous value again, the modification takes place correctly. The problem is when leaving the field empty during the modification, but also during the reply to the ticket. It does not enter the previous value in automatic again as it does for the other custom fileds, and therefore it gives an error. This generates discontent in operators and slows down response operations.

Isn’t there a patch (for RT v4.0.6) to populate the date CFs when replying to the ticket?

Oh I was thinking the issue was different. The 4.2 patch does not apply cleanly to 4.0?

If not you could try to manually apply those code changes from the patch.

From the patch commit:

In RT 4.0, this led to silent errors on the Modify page, and did not
prevent other updates. In RT 4.2, thanks to 16ddc81, failing to enter
the current value explicitly into Date and DateTime CFs causes them to
fail to validate, and thus prevents all other updates of the page.

I would expect your RT 4.0 install to silently error, seems like your RT is behaving like the commit message says 4.2 behaves

I tried to manually insert the fix in the “ValidateCustomFields” file, but it behaves as with the original file.
I tried to replace the entire “ValidateCustomFields” file, but when I reply to the ticket I get an error from the server.
This is the “ValidateCustomFields” v4.0 file with the new fix:

%# BEGIN BPS TAGGED BLOCK {{{
%#
%# COPYRIGHT:
%#
%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
%#                                          <sales@bestpractical.com>
%#
%# (Except where explicitly superseded by other copyright notices)
%#
%#
%# LICENSE:
%#
%# This work is made available to you under the terms of Version 2 of
%# the GNU General Public License. A copy of that license should have
%# been provided with this software, but in any event can be snarfed
%# from www.gnu.org.
%#
%# This work is distributed in the hope that it will be useful, but
%# WITHOUT ANY WARRANTY; without even the implied warranty of
%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
%# General Public License for more details.
%#
%# You should have received a copy of the GNU General Public License
%# along with this program; if not, write to the Free Software
%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
%# 02110-1301 or visit their web page on the internet at
%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
%#
%#
%# CONTRIBUTION SUBMISSION POLICY:
%#
%# (The following paragraph is not intended to limit the rights granted
%# to you to modify and distribute this software under the terms of
%# the GNU General Public License and is only of importance to you if
%# you choose to contribute your changes and enhancements to the
%# community by submitting them to Best Practical Solutions, LLC.)
%#
%# By intentionally submitting any modifications, corrections or
%# derivatives to this work, or any other work intended for use with
%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
%# you are the copyright holder for those contributions and you grant
%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
%# royalty-free, perpetual, license to use, copy, create derivative
%# works based on those contributions, and sublicense and distribute
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
<%INIT>
my ($valid, @res) = (1, ());
$CustomFields->GotoFirstItem;
while ( my $CF = $CustomFields->Next ) {
    my $field = $NamePrefix . $CF->Id . "-Value";

    my $value;
    if ($ARGSRef->{"${field}s-Magic"} and exists $ARGSRef->{"${field}s"}) {
        $value = $ARGSRef->{"${field}s"};

        # We only validate Single Combos -- multis can never be user input
        next if ref $value;
    }
    else {
        $value = $ARGSRef->{$field};
    }
    $m->notes(('Field-' . $CF->Id) => $value);

    my @values = ();

    if ( $CF->Type =~ /^Date(?:Time)?$/) {
        @values = grep {
            my $DateObj = RT::Date->new ( $session{'CurrentUser'} );
            $DateObj->Set(
                Format => 'unknown',
                Value => $_,
                ($CF->Type eq "Date" ? (Timezone => 'utc') : ())
            );
            $DateObj->IsSet
        } @values;
    }

    if ( ref $value eq 'ARRAY' ) {
        @values = @$value;
    } elsif ( $CF->Type =~ /text/i ) {
        @values = ($value);
    } else {
        @values = split /\r*\n/, ( defined $value ? $value : '');
    }
    @values = grep $_ ne '',
        map {
            s/\r+\n/\n/g;
            s/^\s+//;
            s/\s+$//;
            $_;
        }
        grep defined, @values;
    @values = ('') unless @values;

    for my $value( @values ) {
        if ($value) {
            if ( $CF->Type eq 'IPAddress' ) {
                use Regexp::Common qw(RE_net_IPv4);
                my $ip = RT::ObjectCustomFieldValue->ParseIP( $value );
                unless ( $ip ) {
                    my $msg =
                      loc( "Input can not be parsed as an IP address" );
                    $m->notes( ( 'InvalidField-' . $CF->Id ) => $msg );
                    push @res, $msg;
                    $valid = 0;
                }
            }
            elsif ( $CF->Type eq 'IPAddressRange' ) {
                my ( $start_ip, $end_ip ) =
                  RT::ObjectCustomFieldValue->ParseIPRange($value);
                unless ( $start_ip && $end_ip ) {
                    my $msg =
                      loc( "Input can not be parsed as an IP address range" );
                    $m->notes( ( 'InvalidField-' . $CF->Id ) => $msg );
                    push @res, $msg;
                    $valid = 0;
                }
            }
        }

        next if $CF->MatchPattern($value);

        my $msg = loc("Input must match [_1]", $CF->FriendlyPattern);
        $m->notes( ('InvalidField-' . $CF->Id) => $msg );
        push @res, $msg;
        $valid = 0;
    }
}
$m->notes('ValidFields', $valid);
return wantarray? ($valid, @res): $valid;
</%INIT>
<%ARGS>
$CustomFields
$ARGSRef
$NamePrefix => "Object-RT::Ticket--CustomField-"
</%ARGS>

Without testing the manual changes I can’t verify if they are correct, did you delete your mason cache and restart your web server after making the change?

Yes, i have “CentOS release 5.8” + “Apache/2.2.3” so i make:

  1. rm -Rf /usr/local/rt4/var/mason_data/obj/*
  2. service httpd restart

Any idea why the patch:

    if ( $CF->Type =~ /^Date(?:Time)?$/) {
    @values = grep {
        my $DateObj = RT::Date->new ( $session{'CurrentUser'} );
        $DateObj->Set(
            Format => 'unknown',
            Value => $_,
            ($CF->Type eq "Date" ? (Timezone => 'utc') : ())
        );
        $DateObj->IsSet
    } @values;
}

not working on RT 4.0.6?

Where is that code from? It doesn’t seem to be from the patch that the original patch that was linked in the other forum thread? It looked like this:

@@ -74,6 +74,14 @@ while ( my $CF = $CustomFields->Next ) {
         CustomField => $CF,
         Value       => $submitted->{Values} || $submitted->{Value} || $submitted->{Upload},
     );
+    if ($CF->Type =~ /^Date(?:Time)?$/) {
+        if (not @values) {
+            my $values = $Object->CustomFieldValues($CF->Id);
+            while (my $ocfv = $values->Next) {
+                push @values, $ocfv->Content;
+            }
+        }
+    }
     push @values, '' unless @values;
 
     for my $value( @values ) {