summaryrefslogtreecommitdiff
path: root/rt
diff options
context:
space:
mode:
authormark <mark>2011-08-23 21:45:51 +0000
committermark <mark>2011-08-23 21:45:51 +0000
commit4c8c18409f82d56320a80f6c94f275fa15486897 (patch)
treedeeb2cb64572fb1cd00cb55be48eaa68a69d9984 /rt
parent006b2392be94f9670eddf3d01ba89c00f9c16c05 (diff)
RT future ticket resolve, #13853
Diffstat (limited to 'rt')
-rw-r--r--rt/etc/initialdata14
-rwxr-xr-xrt/etc/schema.Pg1
-rwxr-xr-xrt/etc/schema.mysql-4.11
-rw-r--r--rt/lib/RT/Action/ScheduledResolve.pm37
-rw-r--r--rt/lib/RT/Action/SetWillResolve.pm27
-rw-r--r--rt/lib/RT/Interface/Web_Vendor.pm56
-rw-r--r--rt/lib/RT/Ticket_Vendor.pm29
-rw-r--r--rt/lib/RT/Tickets_Overlay.pm2
-rw-r--r--rt/lib/RT/Transaction_Vendor.pm35
-rwxr-xr-xrt/share/html/Elements/SelectStatus4
-rwxr-xr-xrt/share/html/Ticket/Elements/EditDates6
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowDates7
-rwxr-xr-xrt/share/html/Ticket/Update.html36
13 files changed, 252 insertions, 3 deletions
diff --git a/rt/etc/initialdata b/rt/etc/initialdata
index fc2ed2ffb..7b3f6a6bf 100644
--- a/rt/etc/initialdata
+++ b/rt/etc/initialdata
@@ -104,6 +104,16 @@
ExecModule => 'SetPriority',
Argument => '',
},
+ { Name => 'Cancel Scheduled Resolve',
+ Description => 'Set ticket not to resolve in the future',
+ ExecModule => 'SetWillResolve',
+ Argument => '',
+ },
+ { Name => 'Scheduled Resolve',
+ Description => 'Resolve ticket if its WillResolve date has passed',
+ ExecModule => 'ScheduledResolve',
+ Argument => '',
+ },
);
@ScripConditions = (
@@ -564,6 +574,10 @@ Hour: { $SubscriptionObj->SubValue('Hour') }
ScripCondition => 'On Transaction',
ScripAction => 'Extract Subject Tag',
Template => 'Blank' },
+ { Description => 'On Correspond, cancel future resolve',
+ ScripCondition => 'On Correspond',
+ ScripAction => 'Cancel Scheduled Resolve',
+ Template => 'Blank' },
);
@ACL = (
diff --git a/rt/etc/schema.Pg b/rt/etc/schema.Pg
index e3006d073..32c5e872d 100755
--- a/rt/etc/schema.Pg
+++ b/rt/etc/schema.Pg
@@ -404,6 +404,7 @@ CREATE TABLE Tickets (
Due TIMESTAMP NULL ,
Resolved TIMESTAMP NULL ,
+ WillResolve TIMESTAMP NULL ,
LastUpdatedBy integer NOT NULL DEFAULT 0 ,
LastUpdated TIMESTAMP NULL ,
diff --git a/rt/etc/schema.mysql-4.1 b/rt/etc/schema.mysql-4.1
index 173570219..edd3deda7 100755
--- a/rt/etc/schema.mysql-4.1
+++ b/rt/etc/schema.mysql-4.1
@@ -289,6 +289,7 @@ CREATE TABLE Tickets (
Due DATETIME NULL ,
Resolved DATETIME NULL ,
+ WillResolve DATETIME NULL ,
LastUpdatedBy integer NOT NULL DEFAULT 0 ,
LastUpdated DATETIME NULL ,
diff --git a/rt/lib/RT/Action/ScheduledResolve.pm b/rt/lib/RT/Action/ScheduledResolve.pm
new file mode 100644
index 000000000..6b323cb6f
--- /dev/null
+++ b/rt/lib/RT/Action/ScheduledResolve.pm
@@ -0,0 +1,37 @@
+package RT::Action::ScheduledResolve;
+
+use strict;
+use warnings;
+
+use base qw(RT::Action);
+
+=head1 DESCRIPTION
+
+If the ticket's WillResolve date is in the past, set its status to resolved.
+
+=cut
+
+sub Prepare {
+ my $self = shift;
+
+ return undef if grep { $self->TicketObj->Status eq $_ } (
+ 'resolved',
+ 'rejected',
+ 'deleted'
+ ); # don't resolve from any of these states.
+ my $time = $self->TicketObj->WillResolveObj->Unix;
+ return ( $time > 0 and $time < time() );
+}
+
+sub Commit {
+ my $self = shift;
+
+ my $never = RT::Date->new($self->CurrentUser);
+ $never->Unix(-1);
+ $self->TicketObj->SetWillResolve($never->ISO);
+ $self->TicketObj->SetStatus('resolved');
+}
+
+RT::Base->_ImportOverlays();
+
+1;
diff --git a/rt/lib/RT/Action/SetWillResolve.pm b/rt/lib/RT/Action/SetWillResolve.pm
new file mode 100644
index 000000000..807b3c64c
--- /dev/null
+++ b/rt/lib/RT/Action/SetWillResolve.pm
@@ -0,0 +1,27 @@
+package RT::Action::SetWillResolve;
+use base 'RT::Action';
+
+use strict;
+
+sub Describe {
+ my $self = shift;
+ return (ref $self ." will set a ticket's future resolve date to the argument.");
+}
+
+sub Prepare {
+ return 1;
+}
+
+sub Commit {
+ my $self = shift;
+ my $DateObj = RT::Date->new( $self->CurrentUser );
+ $DateObj->Set(
+ Format => 'unknown',
+ Value => $self->Argument,
+ );
+ $self->TicketObj->SetWillResolve( $DateObj->ISO );
+}
+
+RT::Base->_ImportOverlays();
+
+1;
diff --git a/rt/lib/RT/Interface/Web_Vendor.pm b/rt/lib/RT/Interface/Web_Vendor.pm
index c79222be5..27c647f18 100644
--- a/rt/lib/RT/Interface/Web_Vendor.pm
+++ b/rt/lib/RT/Interface/Web_Vendor.pm
@@ -255,8 +255,62 @@ sub ProcessTicketBasics {
push( @results, $msg );
}
- # }}}
+ return (@results);
+}
+
+=head2 ProcessTicketDates (TicketObj => RT::Ticket, ARGSRef => {})
+
+Process updates to the Starts, Started, Told, Resolved, and WillResolve
+fields.
+
+=cut
+sub ProcessTicketDates {
+ my %args = (
+ TicketObj => undef,
+ ARGSRef => undef,
+ @_
+ );
+
+ my $Ticket = $args{'TicketObj'};
+ my $ARGSRef = $args{'ARGSRef'};
+
+ my (@results);
+
+ # {{{ Set date fields
+ my @date_fields = qw(
+ Told
+ Resolved
+ Starts
+ Started
+ Due
+ WillResolve
+ );
+
+ #Run through each field in this list. update the value if apropriate
+ foreach my $field (@date_fields) {
+ next unless exists $ARGSRef->{ $field . '_Date' };
+ next if $ARGSRef->{ $field . '_Date' } eq '';
+
+ my ( $code, $msg );
+
+ my $DateObj = RT::Date->new( $session{'CurrentUser'} );
+ $DateObj->Set(
+ Format => 'unknown',
+ Value => $ARGSRef->{ $field . '_Date' }
+ );
+
+ my $obj = $field . "Obj";
+ if ( ( defined $DateObj->Unix )
+ and ( $DateObj->Unix != $Ticket->$obj()->Unix() ) )
+ {
+ my $method = "Set$field";
+ my ( $code, $msg ) = $Ticket->$method( $DateObj->ISO );
+ push @results, "$msg";
+ }
+ }
+
+ # }}}
return (@results);
}
diff --git a/rt/lib/RT/Ticket_Vendor.pm b/rt/lib/RT/Ticket_Vendor.pm
index 2039f3e2d..9fa24a2a8 100644
--- a/rt/lib/RT/Ticket_Vendor.pm
+++ b/rt/lib/RT/Ticket_Vendor.pm
@@ -33,4 +33,33 @@ sub MissingRequiredFields {
return @results;
}
+# Declare the 'WillResolve' field
+sub _VendorAccessible {
+ {
+ WillResolve =>
+ {read => 1, write => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''},
+ },
+};
+
+sub WillResolveObj {
+ my $self = shift;
+
+ my $time = new RT::Date( $self->CurrentUser );
+
+ if ( my $willresolve = $self->WillResolve ) {
+ $time->Set( Format => 'sql', Value => $willresolve );
+ }
+ else {
+ $time->Set( Format => 'unix', Value => -1 );
+ }
+
+ return $time;
+}
+
+sub WillResolveAsString {
+ my $self = shift;
+ return $self->WillResolveObj->AsString();
+}
+
+
1;
diff --git a/rt/lib/RT/Tickets_Overlay.pm b/rt/lib/RT/Tickets_Overlay.pm
index 876f1084e..f6df5530d 100644
--- a/rt/lib/RT/Tickets_Overlay.pm
+++ b/rt/lib/RT/Tickets_Overlay.pm
@@ -145,9 +145,11 @@ our %FIELD_METADATA = (
WatcherGroup => [ 'MEMBERSHIPFIELD', ], #loc_left_pair
HasAttribute => [ 'HASATTRIBUTE', 1 ],
HasNoAttribute => [ 'HASATTRIBUTE', 0 ],
+ #freeside
Agentnum => [ 'FREESIDEFIELD', ],
Classnum => [ 'FREESIDEFIELD', ],
Tagnum => [ 'FREESIDEFIELD', 'cust_tag' ],
+ WillResolve => [ 'DATE' => 'WillResolve', ], #loc_left_pair
);
our %SEARCHABLE_SUBFIELDS = (
diff --git a/rt/lib/RT/Transaction_Vendor.pm b/rt/lib/RT/Transaction_Vendor.pm
new file mode 100644
index 000000000..caeb3f72c
--- /dev/null
+++ b/rt/lib/RT/Transaction_Vendor.pm
@@ -0,0 +1,35 @@
+package RT::Transaction;
+use strict;
+use vars qw(%_BriefDescriptions);
+
+$_BriefDescriptions{'Set'} = sub {
+ my $self = shift;
+ if ( $self->Field eq 'Password' ) {
+ return $self->loc('Password changed');
+ }
+ elsif ( $self->Field eq 'Queue' ) {
+ my $q1 = new RT::Queue( $self->CurrentUser );
+ $q1->Load( $self->OldValue );
+ my $q2 = new RT::Queue( $self->CurrentUser );
+ $q2->Load( $self->NewValue );
+ return $self->loc("[_1] changed from [_2] to [_3]",
+ $self->loc($self->Field) , $q1->Name , $q2->Name);
+ }
+
+ # Write the date/time change at local time:
+ elsif ($self->Field =~ /Due|Starts|Started|Told|WillResolve/) {
+ my $t1 = new RT::Date($self->CurrentUser);
+ $t1->Set(Format => 'ISO', Value => $self->NewValue);
+ my $t2 = new RT::Date($self->CurrentUser);
+ $t2->Set(Format => 'ISO', Value => $self->OldValue);
+ return $self->loc( "[_1] changed from [_2] to [_3]", $self->loc($self->Field), $t2->AsString, $t1->AsString );
+ }
+ else {
+ return $self->loc( "[_1] changed from [_2] to [_3]",
+ $self->loc($self->Field),
+ ($self->OldValue? "'".$self->OldValue ."'" : $self->loc("(no value)")) , "'". $self->NewValue."'" );
+ }
+};
+
+1;
+
diff --git a/rt/share/html/Elements/SelectStatus b/rt/share/html/Elements/SelectStatus
index 7aa7aa528..5718a2a9d 100755
--- a/rt/share/html/Elements/SelectStatus
+++ b/rt/share/html/Elements/SelectStatus
@@ -45,7 +45,8 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<select name="<%$Name%>">
+% my $onchange_attr = $onchange ? " onchange=\"$onchange\"" : '';
+<select id="<%$Name%>" name="<%$Name%>"<% $onchange_attr |n%>>
%if ($DefaultValue) {
<option value=""<% !$Default && qq[ selected="selected"] |n %>><%$DefaultLabel%></option>
%}
@@ -64,4 +65,5 @@ $Default => ''
$SkipDeleted => 0
$DefaultValue => 1
$DefaultLabel => "-"
+$onchange => ''
</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/EditDates b/rt/share/html/Ticket/Elements/EditDates
index bfa3a3049..371f6e31e 100755
--- a/rt/share/html/Ticket/Elements/EditDates
+++ b/rt/share/html/Ticket/Elements/EditDates
@@ -70,6 +70,12 @@
<& /Elements/SelectDate, menu_prefix => 'Due', current => 0 &> (<% $TicketObj->DueObj->AsString %>)
</td>
</tr>
+ <tr>
+ <td class="label"><&|/l&>Close After</&>:</td>
+ <td class="entry">
+ <& /Elements/SelectDate, menu_prefix => 'WillResolve', current => 0 &> (<% $TicketObj->WillResolveObj->AsString %>)
+ </td>
+ </tr>
% $m->callback( %ARGS, CallbackName => 'EndOfList', Ticket => $TicketObj );
</table>
<%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowDates b/rt/share/html/Ticket/Elements/ShowDates
index 1a79628a9..fc0146194 100755
--- a/rt/share/html/Ticket/Elements/ShowDates
+++ b/rt/share/html/Ticket/Elements/ShowDates
@@ -75,6 +75,13 @@
<td class="label date resolved"><&|/l&>Closed</&>:</td>
<td class="value date resolved"><% $Ticket->ResolvedObj->AsString %></td>
</tr>
+% my $willresolve = $Ticket->WillResolveObj;
+% if ( $willresolve && $willresolve->Unix > 0 ) {
+ <tr>
+ <td class="label date willresolve"><&|/l&>Will Resolve</&>:</td>
+ <td class="value date willresolve"><% $willresolve->AsString %></td>
+ </tr>
+% } # else don't display either of them
<tr>
<td class="label date updated"><&|/l&>Updated</&>:</td>
% my $UpdatedString = $Ticket->LastUpdated ? loc("[_1] by [_2]", $Ticket->LastUpdatedAsString, $m->scomp('/Elements/ShowUser', User => $Ticket->LastUpdatedByObj)) : loc("Never");
diff --git a/rt/share/html/Ticket/Update.html b/rt/share/html/Ticket/Update.html
index 62db0d1c3..7c28cc30d 100755
--- a/rt/share/html/Ticket/Update.html
+++ b/rt/share/html/Ticket/Update.html
@@ -67,7 +67,29 @@
<tr><td valign="baseline" class="label"><&|/l&>Status</&>:</td>
<td valign="baseline">
-<& /Elements/SelectStatus, Name=>"Status", DefaultLabel => loc("[_1] (Unchanged)", loc($TicketObj->Status)), Default => $ARGS{'Status'} || ($TicketObj->Status eq $DefaultStatus ? undef : $DefaultStatus)&>
+<script type="text/javascript">
+function changeStatus() {
+ var Status_select = document.getElementById('Status');
+ var x = Status_select.options[Status_select.selectedIndex].value;
+ var text = document.getElementById('WillResolve_Date');
+ var button = document.getElementById('WillResolve_Date_date_button');
+ if (x == 'resolved' || x == 'rejected' || x == 'deleted') {
+ text.disabled = true;
+ button.style.display = 'none';
+ }
+ else {
+ text.disabled = false;
+ button.style.display = 'inline';
+ }
+}
+</script>
+<& /Elements/SelectStatus,
+ Name=>"Status",
+ DefaultLabel => loc("[_1] (Unchanged)", loc($TicketObj->Status)),
+ Default => $ARGS{'Status'}
+ || ($TicketObj->Status eq $DefaultStatus ? undef : $DefaultStatus,
+ onchange => 'changeStatus()'
+)&>
<span class="label"><&|/l&>Owner</&>:</span>
<& /Elements/SelectOwner,
Name => "Owner",
@@ -76,6 +98,18 @@
DefaultLabel => loc("[_1] (Unchanged)", $m->scomp('/Elements/ShowUser', User => $TicketObj->OwnerObj)),
Default => $ARGS{'Owner'}
&>
+<span class="label"><&|/l&>Close this Ticket on</&>:</span>
+<& /Elements/SelectDate,
+ menu_prefix => 'WillResolve',
+ current => 0,
+ ShowTime => 0,
+&>
+% if ( $TicketObj->WillResolve ) {
+<span class="label"> (<% $TicketObj->WillResolveObj->AsString %>)</span>
+% }
+<script type="text/javascript">
+changeStatus();
+</script>
</td>
<td rowspan=4 valign="top">
<table style="float:right;">