summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitch Jackson <mitch@freeside.biz>2017-11-30 20:28:40 +0000
committerMitch Jackson <mitch@freeside.biz>2017-11-30 20:29:17 +0000
commit603d84b691c7496bb2ec1cddc549fcc7b80e3e38 (patch)
treedfdd12903f6f52b781a46e72ac1016793f8915b6
parent1f24086e325f98eb92b0bc0f6aa60119d3c0340f (diff)
RT# 75322 Add ticket action Quiet Resolve
-rw-r--r--rt/etc/RT_SiteConfig.pm189
-rw-r--r--rt/etc/initialdata19
-rw-r--r--rt/lib/RT/Condition/StatusChangeQuietResolve.pm48
3 files changed, 253 insertions, 3 deletions
diff --git a/rt/etc/RT_SiteConfig.pm b/rt/etc/RT_SiteConfig.pm
index d22da42a1..6420d11ef 100644
--- a/rt/etc/RT_SiteConfig.pm
+++ b/rt/etc/RT_SiteConfig.pm
@@ -58,4 +58,193 @@ Set($MessageBoxRichTextHeight, 368);
#Set(@Plugins,(qw(Extension::QuickDelete RT::FM)));
+
+# Define default lifecycle to include resolved_quiet status workflow
+Set(%Lifecycles,
+ default => {
+ initial => [qw(new)], # loc_qw
+ active => [qw(open stalled)], # loc_qw
+ inactive => [qw(resolved resolved_quiet rejected deleted)], # loc_qw
+
+ defaults => {
+ on_create => 'new',
+ on_merge => 'resolved',
+ approved => 'open',
+ denied => 'rejected',
+ reminder_on_open => 'open',
+ reminder_on_resolve => 'resolved',
+ },
+
+ transitions => {
+ "" => [qw(new open resolved)],
+
+ # from => [ to list ],
+ new => [qw(open stalled resolved resolved_quiet rejected deleted)],
+ open => [qw(new stalled resolved resolved_quiet rejected deleted)],
+ stalled => [qw(new open rejected resolved resolved_quiet deleted)],
+ resolved => [qw(new open stalled rejected deleted)],
+ resolved_quiet => [qw(resolved)],
+ rejected => [qw(new open stalled resolved resolved_quiet deleted)],
+ deleted => [qw(new open stalled rejected resolved resolved_quiet)],
+ },
+
+ rights => {
+ '* -> deleted' => 'DeleteTicket',
+ '* -> *' => 'ModifyTicket',
+ },
+ actions => [
+ 'new -> open' => { label => 'Open It', update => 'Respond' },
+ 'new -> resolved' => { label => 'Resolve', update => 'Comment' },
+ 'new -> resolved_quiet' => { label => 'Quiet Resolve', update => 'Comment' },
+ 'new -> rejected' => { label => 'Reject', update => 'Respond' },
+ 'new -> deleted' => { label => 'Delete', },
+ 'open -> stalled' => { label => 'Stall', update => 'Comment' },
+ 'open -> resolved' => { label => 'Resolve', update => 'Comment' },
+ 'open -> resolved_quiet' => { label => 'Quiet Resolve', update => 'Comment' },
+ 'open -> rejected' => { label => 'Reject', update => 'Respond' },
+ 'stalled -> open' => { label => 'Open It', },
+ 'resolved -> open' => { label => 'Re-open', update => 'Comment' },
+ 'rejected -> open' => { label => 'Re-open', update => 'Comment' },
+ 'deleted -> open' => { label => 'Undelete', },
+ ],
+ },
+# don't change lifecyle of the approvals, they are not capable to deal with
+# custom statuses
+ approvals => {
+ initial => [ 'new' ],
+ active => [ 'open', 'stalled' ],
+ inactive => [ 'resolved', 'rejected', 'deleted' ],
+
+ defaults => {
+ on_create => 'new',
+ on_merge => 'resolved',
+ reminder_on_open => 'open',
+ reminder_on_resolve => 'resolved',
+ },
+
+ transitions => {
+ '' => [qw(new open resolved)],
+
+ # from => [ to list ],
+ new => [qw(open stalled resolved rejected deleted)],
+ open => [qw(new stalled resolved rejected deleted)],
+ stalled => [qw(new open rejected resolved deleted)],
+ resolved => [qw(new open stalled rejected deleted)],
+ rejected => [qw(new open stalled resolved deleted)],
+ deleted => [qw(new open stalled rejected resolved)],
+ },
+ rights => {
+ '* -> deleted' => 'DeleteTicket',
+ '* -> rejected' => 'ModifyTicket',
+ '* -> *' => 'ModifyTicket',
+ },
+ actions => [
+ 'new -> open' => { label => 'Open It', update => 'Respond' },
+ 'new -> resolved' => { label => 'Resolve', update => 'Comment' },
+ 'new -> rejected' => { label => 'Reject', update => 'Respond' },
+ 'new -> deleted' => { label => 'Delete', },
+ 'open -> stalled' => { label => 'Stall', update => 'Comment' },
+ 'open -> resolved' => { label => 'Resolve', update => 'Comment' },
+ 'open -> rejected' => { label => 'Reject', update => 'Respond' },
+ 'stalled -> open' => { label => 'Open It', },
+ 'resolved -> open' => { label => 'Re-open', update => 'Comment' },
+ 'rejected -> open' => { label => 'Re-open', update => 'Comment' },
+ 'deleted -> open' => { label => 'Undelete', },
+ ],
+ },
+);
+
+# Lifecycle 'default' from RT_Config.pm
+# Customer may set the lifecycle on their ticket queue as 'hide_resolve_quiet'
+# to suppress the 'resolve_quiet' ticket status
+Set(%Lifecycles,
+ hide_resolve_quiet => {
+ initial => [qw(new)], # loc_qw
+ active => [qw(open stalled)], # loc_qw
+ inactive => [qw(resolved rejected deleted)], # loc_qw
+
+ defaults => {
+ on_create => 'new',
+ on_merge => 'resolved',
+ approved => 'open',
+ denied => 'rejected',
+ reminder_on_open => 'open',
+ reminder_on_resolve => 'resolved',
+ },
+
+ transitions => {
+ "" => [qw(new open resolved)],
+
+ # from => [ to list ],
+ new => [qw( open stalled resolved rejected deleted)],
+ open => [qw(new stalled resolved rejected deleted)],
+ stalled => [qw(new open rejected resolved deleted)],
+ resolved => [qw(new open stalled rejected deleted)],
+ rejected => [qw(new open stalled resolved deleted)],
+ deleted => [qw(new open stalled rejected resolved )],
+ },
+ rights => {
+ '* -> deleted' => 'DeleteTicket',
+ '* -> *' => 'ModifyTicket',
+ },
+ actions => [
+ 'new -> open' => { label => 'Open It', update => 'Respond' }, # loc{label}
+ 'new -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label}
+ 'new -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label}
+ 'new -> deleted' => { label => 'Delete', }, # loc{label}
+ 'open -> stalled' => { label => 'Stall', update => 'Comment' }, # loc{label}
+ 'open -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label}
+ 'open -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label}
+ 'stalled -> open' => { label => 'Open It', }, # loc{label}
+ 'resolved -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label}
+ 'rejected -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label}
+ 'deleted -> open' => { label => 'Undelete', }, # loc{label}
+ ],
+ },
+# don't change lifecyle of the approvals, they are not capable to deal with
+# custom statuses
+ approvals => {
+ initial => [ 'new' ],
+ active => [ 'open', 'stalled' ],
+ inactive => [ 'resolved', 'rejected', 'deleted' ],
+
+ defaults => {
+ on_create => 'new',
+ on_merge => 'resolved',
+ reminder_on_open => 'open',
+ reminder_on_resolve => 'resolved',
+ },
+
+ transitions => {
+ '' => [qw(new open resolved)],
+
+ # from => [ to list ],
+ new => [qw(open stalled resolved rejected deleted)],
+ open => [qw(new stalled resolved rejected deleted)],
+ stalled => [qw(new open rejected resolved deleted)],
+ resolved => [qw(new open stalled rejected deleted)],
+ rejected => [qw(new open stalled resolved deleted)],
+ deleted => [qw(new open stalled rejected resolved)],
+ },
+ rights => {
+ '* -> deleted' => 'DeleteTicket',
+ '* -> rejected' => 'ModifyTicket',
+ '* -> *' => 'ModifyTicket',
+ },
+ actions => [
+ 'new -> open' => { label => 'Open It', update => 'Respond' }, # loc{label}
+ 'new -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label}
+ 'new -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label}
+ 'new -> deleted' => { label => 'Delete', }, # loc{label}
+ 'open -> stalled' => { label => 'Stall', update => 'Comment' }, # loc{label}
+ 'open -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label}
+ 'open -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label}
+ 'stalled -> open' => { label => 'Open It', }, # loc{label}
+ 'resolved -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label}
+ 'rejected -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label}
+ 'deleted -> open' => { label => 'Undelete', }, # loc{label}
+ ],
+ },
+);
+
1;
diff --git a/rt/etc/initialdata b/rt/etc/initialdata
index aa2010fd1..8769fed8b 100644
--- a/rt/etc/initialdata
+++ b/rt/etc/initialdata
@@ -254,7 +254,12 @@
# ExecModule => 'CustomFieldChange',
# ApplicableTransTypes => 'Any',
#},
-
+ { Name => 'On Resolve Allow Quiet',
+ Description => 'Whenever a ticket is resolved, '.
+ 'except with resolve_quiet',
+ ApplicableTransTypes => 'Status',
+ ExecModule => 'StatusChangeQuietResolve',
+ },
);
@Templates = (
@@ -931,8 +936,12 @@ Hour: { $SubscriptionObj->SubValue('Hour') }
ScripCondition => 'On Owner Change',
ScripAction => 'Notify Owner',
Template => 'Transaction in HTML' },
- { Description => 'On Resolve Notify Requestors',
- ScripCondition => 'On Resolve',
+# { Description => 'On Resolve Notify Requestors',
+# ScripCondition => 'On Resolve',
+# ScripAction => 'Notify Requestors',
+# Template => 'Resolved in HTML' },
+ { Description => 'On Resolve Notify Requestors, Allow Quiet Resolve',
+ ScripCondition => 'On Resolve Allow Quiet',
ScripAction => 'Notify Requestors',
Template => 'Resolved in HTML' },
{ Description => "On transaction, add any tags in the transaction's subject to the ticket's subject",
@@ -1068,6 +1077,10 @@ Hour: { $SubscriptionObj->SubValue('Hour') }
# superseded by "notify owner and adminccs"
'notify adminccs' => { 'transaction' => 1 },
},
+ 'on resolve' => {
+ # superseded by "On Resolve Notify Requestors, Allow Quiet Resolve"
+ 'notify requestors' => { 'resolved in html' => 1 },
+ },
);
# -*- perl -*-
diff --git a/rt/lib/RT/Condition/StatusChangeQuietResolve.pm b/rt/lib/RT/Condition/StatusChangeQuietResolve.pm
new file mode 100644
index 000000000..842614182
--- /dev/null
+++ b/rt/lib/RT/Condition/StatusChangeQuietResolve.pm
@@ -0,0 +1,48 @@
+package RT::Condition::StatusChangeQuietResolve;
+use base 'RT::Condition';
+use strict;
+use warnings;
+
+=head2 DESCRIPTION
+
+This condition allows for muting of resolution notifications when
+combined with the ticket status 'resolved_quiet'
+
+If status has been updated as 'resolved_quiet', this condition
+will block notification, and update ticket status to 'resolved'
+
+If status has been updated as 'resolved', this condition
+will block notification only if the previous ticket status
+had been 'resolved_quiet'
+
+=cut
+
+sub IsApplicable {
+ my $self = shift;
+ my $txn = $self->TransactionObj;
+ my ($type, $field) = ($txn->Type, $txn->Field);
+
+ return 0
+ unless $type eq 'Status'
+ || ($type eq 'Set' && $field eq 'Status');
+
+ return 0
+ unless $txn->NewValue eq 'resolved'
+ || $txn->NewValue eq 'resolved_quiet';
+
+ my $ticket = $self->TicketObj;
+
+ if ($txn->NewValue eq 'resolved_quiet') {
+ $ticket->SetStatus('resolved');
+ return 0;
+ }
+ elsif ($txn->NewValue eq 'resolved' && $txn->OldValue eq 'resolved_quiet') {
+ return 0;
+ }
+
+ return 1;
+}
+
+RT::Base->_ImportOverlays();
+
+1;