Commit 5d05bb27 authored by Thomas Sibley's avatar Thomas Sibley
Browse files

Merge branch 'ignore-deadline-on-statuses'

parents c929225f 2e9acee6
0.06 Not released
* IgnoreOnStatuses agreement modifier
0.05_02 Wed Jun 27 15:44:36 PDT 2012
* Make sure timezone change is seen by system functions
......
Changes
etc/initialdata
etc/upgrade/0.06/content
inc/Module/AutoInstall.pm
inc/Module/Install.pm
inc/Module/Install/AutoInstall.pm
......@@ -31,6 +32,7 @@ META.yml
t/basics.t
t/business_hours.t
t/due.t
t/ignore-on-statuses.t
t/queue.t
t/starts.t
t/timezone.t
......@@ -22,7 +22,7 @@
},
{ Name => '[SLA] Require Due set', # loc
Description => 'Detect a situation when we should set Due date' , # loc
ApplicableTransTypes => 'Create,CustomField,Correspond',
ApplicableTransTypes => 'Create,CustomField,Correspond,Set,Status',
ExecModule => 'SLA_RequireDueSet',
},
);
......
our @Final = (
sub {
my $condition = RT::ScripCondition->new( RT->SystemUser );
$condition->LoadByCols( ExecModule => 'SLA_RequireDueSet' );
unless ( $condition->id ) {
$RT::Logger->error("Couldn't find condition based on SLA_RequireDueSet module. New installation?");
return 0;
}
my ($status, $msg) = $condition->SetApplicableTransTypes('Create,CustomField,Correspond,Set,Status');
unless ($status) {
$RT::Logger->error("Couldn't set ApplicableTransTypes for condition: $msg");
}
return 1;
},
);
\ No newline at end of file
......@@ -25,6 +25,10 @@ sub IsApplicable {
return 1 if $self->TicketObj->FirstCustomFieldValue('SLA');
return 0;
}
elsif ( $type eq 'Status' || ($type eq 'Set' && $self->TransactionObj->Field eq 'Status') ) {
return 1 if $self->TicketObj->FirstCustomFieldValue('SLA');
return 0;
}
return 1 if $self->IsCustomFieldChange('SLA');
return 0;
}
......
......@@ -242,7 +242,9 @@ 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.
=head2 OutOfHours (struct, no default)
=head2 Modifying Agreements
=head3 OutOfHours (struct, no default)
Out of hours modifier. Adds more real or business minutes to resolve
and/or reply options if event happens out of business hours, read also
......@@ -266,6 +268,26 @@ hours, otherwise only one.
Supporters have two additional hours in the morning to deal with bunch
of requests that came into the system during the last night.
=head3 IgnoreOnStatuses (array, no default)
Allows you to ignore a deadline when ticket has certain status. Example:
'level x' => {
KeepInLoop => { BusinessMinutes => 60, IgnoreOnStatuses => ['stalled'] },
},
In above example KeepInLoop deadline is ignored if ticket is stalled.
B<NOTE>: When a ticket goes from an ignored status to a normal status, the new
Due date is calculated from the last action (reply, SLA change, etc) which fits
the SLA type (Response, Starts, KeepInLoop, etc). This means if a ticket in
the above example flips from stalled to open without a reply, the ticket will
probably be overdue. In most cases this shouldn't be a problem since moving
out of stalled-like statuses is often the result of RT's auto-open on reply
scrip, therefore ensuring there's a new reply to calculate Due from. The
overall effect is that ignored statuses don't let the Due date drift
arbitrarily, which could wreak havoc on your SLA performance.
=head2 Configuring business hours
In the config you can set one or more work schedules. Use the following
......@@ -377,6 +399,11 @@ sub Agreement {
return undef;
}
if ( $args{'Ticket'} && $res{'IgnoreOnStatuses'} ) {
my $status = $args{'Ticket'}->Status;
return undef if grep $_ eq $status, @{$res{'IgnoreOnStatuses'}};
}
$res{'OutOfHours'} = $meta->{'OutOfHours'}{ $args{'Type'} };
$args{'Queue'} ||= $args{'Ticket'}->QueueObj if $args{'Ticket'};
......
......@@ -2,7 +2,7 @@ use strict;
use warnings;
### after: use lib qw(@RT_LIB_PATH@);
use lib qw(/opt/rt4/local/lib /opt/rt4/lib);
use lib qw(/home/tom/work/bps/rt/local/lib /home/tom/bps/rt/lib);
package RT::Extension::SLA::Test;
......
#!/usr/bin/perl
use strict;
use warnings;
use RT::Extension::SLA::Test tests => 35;
note 'check that reply to requestors dont unset due date with KeepInLoop';
{
%RT::ServiceAgreements = (
Default => '2',
Levels => {
'2' => {
KeepInLoop => { RealMinutes => 60*4, IgnoreOnStatuses => ['stalled'] },
},
},
);
my $root = RT::User->new( $RT::SystemUser );
$root->LoadByEmail('root@localhost');
ok $root->id, 'loaded root user';
# requestor creates
my $id;
my $due;
{
my $ticket = RT::Ticket->new( $root );
($id) = $ticket->Create(
Queue => 'General',
Subject => 'xxx',
Requestor => $root->id,
);
ok $id, "created ticket #$id";
is $ticket->FirstCustomFieldValue('SLA'), '2', 'default sla';
ok !$ticket->DueObj->Unix, 'no response deadline';
$due = 0;
}
# non-requestor reply
{
my $ticket = RT::Ticket->new( $RT::SystemUser );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
$ticket->Correspond( Content => 'we are working on this.' );
$ticket = RT::Ticket->new( $root );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
my $tmp = $ticket->DueObj->Unix;
ok $tmp > 0, 'Due date is set';
ok $tmp > $due, "keep in loop is 4hours when response is 2hours";
$due = $tmp;
}
# stalling ticket
{
my $ticket = RT::Ticket->new( $RT::SystemUser );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
my ($status, $msg) = $ticket->SetStatus('stalled');
ok $status, 'stalled the ticket';
$ticket->Load( $id );
ok !$ticket->DueObj->Unix, 'keep in loop deadline ignored for stalled';
}
# non-requestor reply again
{
sleep 1;
my $ticket = RT::Ticket->new( $RT::SystemUser );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
$ticket->Correspond( Content => 'we are still working on this.' );
$ticket = RT::Ticket->new( $root );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
is $ticket->Status, 'open', 'ticket was auto-opened';
my $tmp = $ticket->DueObj->Unix;
ok $tmp > 0, 'Due date is set';
ok $tmp > $due, "keep in loop sligtly moved";
$due = $tmp;
}
}
note 'Check that failing to reply to the requestors is not ignored';
{
%RT::ServiceAgreements = (
Default => '2',
Levels => {
'2' => {
Response => { RealMinutes => 60*2 },
KeepInLoop => { RealMinutes => 60*4, IgnoreOnStatuses => ['stalled'] },
},
},
);
my $root = RT::User->new( $RT::SystemUser );
$root->LoadByEmail('root@localhost');
ok $root->id, 'loaded root user';
# requestor creates
my $id;
my $due;
{
my $ticket = RT::Ticket->new( $root );
($id) = $ticket->Create(
Queue => 'General',
Subject => 'xxx',
Requestor => $root->id,
);
ok $id, "created ticket #$id";
is $ticket->FirstCustomFieldValue('SLA'), '2', 'default sla';
$due = $ticket->DueObj->Unix;
ok $due > 0, 'response deadline';
}
# stalling ticket
{
my $ticket = RT::Ticket->new( $RT::SystemUser );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
my ($status, $msg) = $ticket->SetStatus('stalled');
ok $status, 'stalled the ticket';
$ticket->Load( $id );
my $tmp = $ticket->DueObj->Unix;
ok $tmp, 'response deadline not unset';
is $tmp, $due, 'due not changed';
}
# non-requestor reply
{
sleep 1;
my $ticket = RT::Ticket->new( $RT::SystemUser );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
$ticket->Correspond( Content => 'we are still working on this.' );
$ticket = RT::Ticket->new( $root );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
is $ticket->Status, 'open', 'ticket was auto-opened';
my $tmp = $ticket->DueObj->Unix;
ok $tmp > 0, 'Due date is set';
ok $tmp > $due, "keep in loop is greater than response";
$due = $tmp;
}
# stalling ticket again
{
my $ticket = RT::Ticket->new( $RT::SystemUser );
$ticket->Load( $id );
ok $ticket->id, "loaded ticket #$id";
my ($status, $msg) = $ticket->SetStatus('stalled');
ok $status, 'stalled the ticket';
$ticket->Load( $id );
ok !$ticket->DueObj->Unix, 'keep in loop deadline unset for stalled';
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment