[Bps-public-commit] RT-Extension-SLA branch, master, updated. 1.02-1-g09dd3e6

Todd Wade todd at bestpractical.com
Wed Dec 10 11:40:44 EST 2014


The branch, master has been updated
       via  09dd3e68d35d24dfb43190531a1bfd350bb5e29f (commit)
      from  6b503018d28124e6b8fe1dcb3267940430c27b27 (commit)

Summary of changes:
 README                      | 59 ++++++++++++++++++++++--------------
 lib/RT/Action/SLA_SetDue.pm | 26 +++++++++++-----
 lib/RT/Extension/SLA.pm     | 73 +++++++++++++++++++++++++--------------------
 3 files changed, 95 insertions(+), 63 deletions(-)

- Log -----------------------------------------------------------------
commit 09dd3e68d35d24dfb43190531a1bfd350bb5e29f
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Dec 8 15:18:41 2014 -0500

    Allow Response to assume only replies from Owner and AdminCCs meet SLA
    
    By default, a reply by anyone who is not a requestor unsets the due date
    for a Response SLA.  If it is common for non-requestors to reply to
    tickets, this isn't desirable.  This commit provides a way to only treat
    replies from Owners and AdminCcs as meeting a Response SLA.
    
    IsRequestorsAct is renamed to IsOutsideActor, and the documentation for
    Response SLAs is updated to clarify what is meant by an "outside actor."
    The new behavior is controlled by a new AssumeOutsideActor global SLA
    configuration option.

diff --git a/README b/README
index 4d61fa6..bd3c29b 100644
--- a/README
+++ b/README
@@ -134,30 +134,30 @@ CONFIGURATION
 
    Response
     In many companies providing support service(s) resolve time of a ticket
-    is less important than time of response to requestors from stuff
+    is less important than time of response to requestors from staff
     members.
 
-    You can use Response option to define such deadlines. When you're using
-    this option Due time "flips" when requestors and non-requestors reply to
-    a ticket. We set Due date when a ticket is created, unset when
-    non-requestor replies... until ticket is closed when ticket's Due date
-    is also unset.
+    You can use Response option to define such deadlines. The Due date is
+    set when a ticket is created, unset when a worker replies, and re-set
+    when the requestor replies again -- until the ticket is closed, when the
+    ticket's Due date is unset.
 
-    NOTE that behaviour changes when Resolve and Response options are
-    combined, read below.
+    NOTE that this behaviour changes when Resolve and Response options are
+    combined; see "Using both Resolve and Response in the same level".
 
-    As response deadlines are calculated using requestors' activity so
-    several rules applies to make things sane:
+    Note that by default, only the requestors on the ticket are considered
+    "outside actors" and thus require a Response due date; all other email
+    addresses are treated as workers of the ticket, and thus count as
+    meeting the SLA. If you'd like to invert this logic, so that the Owner
+    and AdminCcs are the only worker email addresses, and all others are
+    external, see the "AssumeOutsideActor" configuration.
 
-    *   If requestor(s) reply multiple times and are ignored then the
-        deadline is calculated using the oldest requestors' correspondence.
+    The owner is never treated as an outside actor; if they are also the
+    requestor of the ticket, it will have no SLA.
 
-    *   If a ticket has no requestor(s) then it has no response deadline.
-
-    *   If a ticket is created by non-requestor then due date is left unset.
-
-    *   If owner of a ticket is its requestor then his actions are treated
-        as non-requestors'.
+    If an outside actor replies multiple times, their later replies are
+    ignored; the deadline is awlways calculated from the oldest
+    correspondence from the outside actor.
 
    Using both Resolve and Response in the same level
     Resolve and Response can be combined. In such case due date is set
@@ -165,8 +165,8 @@ CONFIGURATION
     set'.
 
     If a ticket met its Resolve deadline then due date stops "flipping", is
-    freezed and the ticket becomes overdue. Before that moment when
-    non-requestor replies to a ticket, due date is changed to Resolve
+    freezed and the ticket becomes overdue. Before that moment when an
+    inside actor replies to a ticket, due date is changed to Resolve
     deadline instead of 'Not Set', as well this happens when a ticket is
     closed. So all the time due date is defined.
 
@@ -218,8 +218,8 @@ CONFIGURATION
         },
 
     In the above example Due is set to one hour after creation, reply of a
-    non-requestor moves Due date two hours forward, requestors' replies move
-    Due date to one hour and resolve deadine is 24 hours.
+    inside actor moves Due date two hours forward, outside actors' replies
+    move Due date to one hour and resolve deadine is 24 hours.
 
   Modifying Agreements
    OutOfHours (struct, no default)
@@ -315,6 +315,18 @@ CONFIGURATION
             ...
         };
 
+  AssumeOutsideActor
+    When using a Response configuration, the due date is unset when anyone
+    who is not a requestor replies. If it is common for non-requestors to
+    reply to tickets, and this should *not* satisfy the SLA, you may wish to
+    set AssumeOutsideActor. This causes the extension to assume that the
+    Response SLA has only been met when the owner or AdminCc reply.
+
+        %RT::ServiceAgreements = (
+            AssumeOutsideActor => 1,
+            ...
+        };
+
   Access control
     You can totally hide SLA custom field from users and use per queue
     defaults, just revoke SeeCustomField and ModifyCustomField.
@@ -334,6 +346,9 @@ TODO
           something else). So people would be able to handle tickets in the right
           order using Due dates.
 
+        * [not implemented] tests for AssumeOutsideActor - need tests for all of the
+          conditionals in RT::Action::SLA_SetDue::IsOutsideActor
+
         * [not implemented] WebUI
 
 DESIGN
diff --git a/lib/RT/Action/SLA_SetDue.pm b/lib/RT/Action/SLA_SetDue.pm
index 06bf646..4f3ed30 100644
--- a/lib/RT/Action/SLA_SetDue.pm
+++ b/lib/RT/Action/SLA_SetDue.pm
@@ -37,16 +37,16 @@ sub Commit {
     my $txn = $self->TransactionObj;
     my $level = $ticket->FirstCustomFieldValue('SLA');
 
-    my ($last_reply, $is_requestor) = $self->LastEffectiveAct;
+    my ($last_reply, $is_outside) = $self->LastEffectiveAct;
     $RT::Logger->debug(
-        'Last effective '. ($is_requestor? '':'non-') .'requestors\' reply'
+        'Last effective '. ($is_outside? '':'non-') .'outside actors\' reply'
         .' to ticket #'. $ticket->id .' is txn #'. $last_reply->id
     );
 
     my $response_due = $self->Due(
         Ticket => $ticket,
         Level => $level,
-        Type => $is_requestor? 'Response': 'KeepInLoop',
+        Type => $is_outside? 'Response' : 'KeepInLoop',
         Time => $last_reply->CreatedObj->Unix,
     );
 
@@ -65,16 +65,26 @@ sub Commit {
     return $self->SetDateField( Due => $due );
 }
 
-sub IsRequestorsAct {
+sub IsOutsideActor {
     my $self = shift;
     my $txn = shift || $self->TransactionObj;
 
     my $actor = $txn->CreatorObj->PrincipalObj;
 
-    # owner is always treated as non-requestor
+    # owner is always treated as inside actor
     return 0 if $actor->id == $self->TicketObj->Owner;
 
-    return $self->TicketObj->Requestors->HasMemberRecursively( $actor )? 1 : 0;
+    if ( $RT::ServiceAgreements{'AssumeOutsideActor'} ) {
+        # All non-admincc users are outside actors
+        return 0 if $self->TicketObj          ->AdminCc->HasMemberRecursively( $actor )
+                 or $self->TicketObj->QueueObj->AdminCc->HasMemberRecursively( $actor );
+
+        return 1;
+    } else {
+        # Only requestors are outside actors
+        return 1 if $self->TicketObj->Requestors->HasMemberRecursively( $actor );
+        return 0;
+    }
 }
 
 sub LastEffectiveAct {
@@ -90,13 +100,13 @@ sub LastEffectiveAct {
 
     my $res;
     while ( my $txn = $txns->Next ) {
-        unless ( $self->IsRequestorsAct( $txn ) ) {
+        unless ( $self->IsOutsideActor( $txn ) ) {
             last if $res;
             return ($txn);
         }
         $res = $txn;
     }
-    return ($res, 'requestor');
+    return ($res, 1);
 }
 
 1;
diff --git a/lib/RT/Extension/SLA.pm b/lib/RT/Extension/SLA.pm
index 3354202..94f4423 100644
--- a/lib/RT/Extension/SLA.pm
+++ b/lib/RT/Extension/SLA.pm
@@ -167,43 +167,33 @@ Example:
 
 =head3 Response
 
-In many companies providing support service(s) resolve time
-of a ticket is less important than time of response to requestors
-from stuff members.
+In many companies providing support service(s) resolve time of a ticket
+is less important than time of response to requestors from staff
+members.
 
-You can use Response option to define such deadlines. When you're
-using this option Due time "flips" when requestors and non-requestors
-reply to a ticket. We set Due date when a ticket is created, unset
-when non-requestor replies... until ticket is closed when ticket's
-Due date is also unset.
+You can use Response option to define such deadlines.  The Due date is
+set when a ticket is created, unset when a worker replies, and re-set
+when the requestor replies again -- until the ticket is closed, when the
+ticket's Due date is unset.
 
-B<NOTE> that behaviour changes when Resolve and Response options
-are combined, read L<below|/"Using both Resolve and Response in the same level">.
+B<NOTE> that this behaviour changes when Resolve and Response options
+are combined; see L</"Using both Resolve and Response in the same
+level">.
 
-As response deadlines are calculated using requestors' activity
-so several rules applies to make things sane:
+Note that by default, only the requestors on the ticket are considered
+"outside actors" and thus require a Response due date; all other email
+addresses are treated as workers of the ticket, and thus count as
+meeting the SLA.  If you'd like to invert this logic, so that the Owner
+and AdminCcs are the only worker email addresses, and all others are
+external, see the L</AssumeOutsideActor> configuration.
 
-=over 4
+The owner is never treated as an outside actor; if they are also the
+requestor of the ticket, it will have no SLA.
 
-=item *
+If an outside actor replies multiple times, their later replies are
+ignored; the deadline is awlways calculated from the oldest
+correspondence from the outside actor.
 
-If requestor(s) reply multiple times and are ignored then the deadline
-is calculated using the oldest requestors' correspondence.
-
-=item *
-
-If a ticket has no requestor(s) then it has no response deadline.
-
-=item *
-
-If a ticket is created by non-requestor then due date is left unset.
-
-=item *
-
-If owner of a ticket is its requestor then his actions are treated
-as non-requestors'.
-
-=back
 
 =head3 Using both Resolve and Response in the same level
 
@@ -213,7 +203,7 @@ according to the earliest of two deadlines and never is dropped to
 
 If a ticket met its Resolve deadline then due date stops "flipping",
 is freezed and the ticket becomes overdue. Before that moment when
-non-requestor replies to a ticket, due date is changed to Resolve
+an inside actor replies to a ticket, due date is changed to Resolve
 deadline instead of 'Not Set', as well this happens when a ticket
 is closed. So all the time due date is defined.
 
@@ -267,7 +257,7 @@ every few hours. KeepInLoop option can be used to achieve this.
     },
 
 In the above example Due is set to one hour after creation, reply
-of a non-requestor moves Due date two hours forward, requestors'
+of a inside actor moves Due date two hours forward, outside actors'
 replies move Due date to one hour and resolve deadine is 24 hours.
 
 =head2 Modifying Agreements
@@ -368,6 +358,20 @@ In the config you can set per queue defaults, using:
         ...
     };
 
+=head2 AssumeOutsideActor
+
+When using a L<Response|/"Resolve and Response (interval, no defaults)">
+configuration, the due date is unset when anyone who is not a requestor
+replies.  If it is common for non-requestors to reply to tickets, and
+this should I<not> satisfy the SLA, you may wish to set
+C<AssumeOutsideActor>.  This causes the extension to assume that the
+Response SLA has only been met when the owner or AdminCc reply.
+
+    %RT::ServiceAgreements = (
+        AssumeOutsideActor => 1,
+        ...
+    };
+
 =head2 Access control
 
 You can totally hide SLA custom field from users and use per queue
@@ -552,6 +556,9 @@ sub GetDefaultServiceLevel {
       something else). So people would be able to handle tickets in the right
       order using Due dates.
 
+    * [not implemented] tests for AssumeOutsideActor - need tests for all of the
+      conditionals in RT::Action::SLA_SetDue::IsOutsideActor
+
     * [not implemented] WebUI
 
 =head1 DESIGN

-----------------------------------------------------------------------


More information about the Bps-public-commit mailing list