RT# 75322 Add ticket action Quiet Resolve
authorMitch Jackson <mitch@freeside.biz>
Thu, 30 Nov 2017 20:28:40 +0000 (20:28 +0000)
committerMitch Jackson <mitch@freeside.biz>
Thu, 30 Nov 2017 20:29:17 +0000 (20:29 +0000)
rt/etc/RT_SiteConfig.pm
rt/etc/initialdata
rt/lib/RT/Condition/StatusChangeQuietResolve.pm [new file with mode: 0644]

index d22da42..6420d11 100644 (file)
@@ -58,4 +58,193 @@ Set($MessageBoxRichTextHeight, 368);
 
 #Set(@Plugins,(qw(Extension::QuickDelete RT::FM)));
 
 
 #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;
 1;
index aa2010f..8769fed 100644 (file)
     #   ExecModule           => 'CustomFieldChange',
     #   ApplicableTransTypes => 'Any',
     #},
     #   ExecModule           => 'CustomFieldChange',
     #   ApplicableTransTypes => 'Any',
     #},
-
+    {  Name                 => 'On Resolve Allow Quiet',
+       Description          => 'Whenever a ticket is resolved, '.
+                               'except with resolve_quiet',
+       ApplicableTransTypes => 'Status',
+       ExecModule           => 'StatusChangeQuietResolve',
+    },
 );
 
 @Templates = (
 );
 
 @Templates = (
@@ -931,8 +936,12 @@ Hour:         { $SubscriptionObj->SubValue('Hour') }
        ScripCondition => 'On Owner Change',
        ScripAction    => 'Notify Owner',
        Template       => 'Transaction in HTML' },
        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",
        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 },
   },
     # 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 -*-
 );
 
 # -*- perl -*-
diff --git a/rt/lib/RT/Condition/StatusChangeQuietResolve.pm b/rt/lib/RT/Condition/StatusChangeQuietResolve.pm
new file mode 100644 (file)
index 0000000..8426141
--- /dev/null
@@ -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;