[Rt-commit] rt branch, 4.4/sla, repushed
? sunnavy
sunnavy at bestpractical.com
Sun Aug 2 15:17:57 EDT 2015
The branch 4.4/sla was deleted and repushed:
was acbe9d8cd3be526fd644a6e5e40979bb91e5ee74
now 8bfb984257cd45a4ef9811a4ba10607b4e3b570a
1: e19d40d ! 1: c0b308e import sla extension
@@ -500,16 +500,6 @@
+ .' to ticket #'. $ticket->id .' is txn #'. $last_reply->id
+ );
+
-+ my $meta =
-+ $RT::ServiceAgreements{ 'Levels' }{ $level }
-+ ? $RT::ServiceAgreements{ 'Levels' }{ $level }{ $is_outside ? 'Response' : 'KeepInLoop' }
-+ : undef;
-+ if ( $meta && $meta->{IgnoreOnStatuses} && $meta->{RecalculateDueOnIgnoredStatusChange} ) {
-+ my $last_ignored_status_txn = $self->LastIgnoredStatusAct(@{$meta->{IgnoreOnStatuses}});
-+ $last_reply = $last_ignored_status_txn
-+ if $last_ignored_status_txn && $last_reply->Created lt $last_ignored_status_txn->Created;
-+ }
-+
+ my $response_due = $self->Due(
+ Ticket => $ticket,
+ Level => $level,
@@ -574,19 +564,6 @@
+ $res = $txn;
+ }
+ return ($res, 1);
-+}
-+
-+sub LastIgnoredStatusAct {
-+ my $self = shift;
-+ my @statuses = @_;
-+ my $txns = $self->TicketObj->Transactions;
-+ $txns->Limit( FIELD => 'FIELD', VALUE => 'Status' );
-+ $txns->Limit( FIELD => 'OldValue', OPERATOR => 'IN', VALUE => \@statuses );
-+ $txns->OrderByCols(
-+ { FIELD => 'Created', ORDER => 'DESC' },
-+ { FIELD => 'id', ORDER => 'DESC' },
-+ );
-+ return $txns->First;
+}
+
+1;
@@ -1366,18 +1343,16 @@
+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.
-+The option C<RecalculateDueOnIgnoredStatusChange> could get around the
-+"probably be overdue" issue by considering the last ignored status date too.
-+e.g.
-+
-+ 'level x' => {
-+ KeepInLoop => {
-+ BusinessMinutes => 60,
-+ RecalculateDueOnIgnoredStatusChange => 1,
-+ IgnoreOnStatuses => ['stalled'],
++C<ExcludeTimeOnIgnoredStatuses> option could get around the "probably be
++overdue" issue by excluding the time spent on ignored statuses.
++
++ 'level x' => {
++ KeepInLoop => {
++ BusinessMinutes => 60,
++ ExcludeTimeOnIgnoredStatuses => 1,
++ IgnoreOnStatuses => ['stalled'],
++ },
+ },
-+ },
-+
+
+=head2 Configuring business hours
+
@@ -1553,6 +1528,52 @@
+ foreach ( qw(RealMinutes BusinessMinutes) ) {
+ next unless my $mod = $agreement->{'OutOfHours'}{ $_ };
+ ($agreement->{ $_ } ||= 0) += $mod;
++ }
++ }
++
++ if ( $args{ Ticket }
++ && $agreement->{ IgnoreOnStatuses }
++ && $agreement->{ ExcludeTimeOnIgnoredStatuses } )
++ {
++ my $txns = RT::Transactions->new( RT->SystemUser );
++ $txns->LimitToTicket($args{Ticket}->id);
++ $txns->Limit(
++ FIELD => 'Field',
++ VALUE => 'Status',
++ );
++ my $date = RT::Date->new( RT->SystemUser );
++ $date->Set( Value => $args{ Time } );
++ $txns->Limit(
++ FIELD => 'Created',
++ OPERATOR => '>=',
++ VALUE => $date->ISO( Timezone => 'UTC' ),
++ );
++
++ my $last_time = $args{ Time };
++ while ( my $txn = $txns->Next ) {
++ if ( grep( { $txn->OldValue eq $_ } @{ $agreement->{ IgnoreOnStatuses } } ) ) {
++ if ( !grep( { $txn->NewValue eq $_ } @{ $agreement->{ IgnoreOnStatuses } } ) ) {
++ if ( defined $agreement->{ 'BusinessMinutes' } ) {
++
++ # re-init $bhours to make sure we don't have a cached start/end,
++ # so the time here is not outside the calculated business hours
++
++ my $bhours = $self->BusinessHours( $agreement->{ 'BusinessHours' } );
++ my $time = $bhours->between( $last_time, $txn->CreatedObj->Unix );
++ if ( $time > 0 ) {
++ $res = $bhours->add_seconds( $res, $time );
++ }
++ }
++ else {
++ my $time = $txn->CreatedObj->Unix - $last_time;
++ $res += $time;
++ }
++ $last_time = $txn->CreatedObj->Unix;
++ }
++ }
++ else {
++ $last_time = $txn->CreatedObj->Unix;
++ }
+ }
+ }
+
2: 0b4a9d1 < -: ------- make cf "SLA" configurable and don't create it by default
-: ------- > 2: 25a0ac4 use SLA column in Tickets table instead
-: ------- > 3: 6e30149 allow to disable SLA for some queues
3: 93d4f6f ! 4: f1cd8c1 update doc/config and move it to RT_Config.pm
@@ -1,24 +1,22 @@
Author: sunnavy <sunnavy at bestpractical.com>
- migrate ServiceAgreements/BusinessHours and doc to standard config
+ update doc/config and move it to RT_Config.pm
diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@
-
- Set( $SLACustomField, 'SLA' );
-
+ },
+ );
+
++=head1 SLA
+
++=over 4
++
+=item C<%ServiceAgreements>
+
-+It's possible to define different set of levels for different
-+queues. You can create several CFs with the same name and
-+different set of values. But if you move tickets between
-+queues a lot then it's going to be a problem and it's preferred
-+to use B<ONE> SLA custom field.
-+
+There is no WebUI in the current version. Almost everything is controlled in
-+the RT's config C<%ServiceAgreements> and C<%ServiceBusinessHours>. For example:
++the C<%ServiceAgreements> and C<%ServiceBusinessHours>. For example:
+
+ Set( %ServiceAgreements = (
+ Default => '4h',
@@ -29,7 +27,7 @@
+ '2h' => { Resolve => { RealMinutes => 60*2 } },
+ '4h' => { Resolve => { RealMinutes => 60*4 } },
+ },
-+ );
++ ));
+
+In this example I<Incident> is the name of the queue, and I<2h> is the name of
+the SLA which will be applied to this queue by default.
@@ -201,11 +199,11 @@
+ KeepInLoop => { RealMinutes => 60*2 }, # two hours
+ Resolve => { RealMinutes => 60*24 }, # 24 real hours
+ },
-+
+
+In the above example Due is set to one hour after creation, reply
+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.
-+
+
+=item Modifying Agreements
+
+=over 4
@@ -253,14 +251,13 @@
+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.
-+The option C<RecalculateDueOnIgnoredStatusChange> could get around the
-+"probably be overdue" issue by considering the last ignored status date too.
-+e.g.
++C<ExcludeTimeOnIgnoredStatuses> option could get around the "probably be
++overdue" issue by excluding the time spent on ignored statuses, e.g.
+
+ 'level x' => {
+ KeepInLoop => {
+ BusinessMinutes => 60,
-+ RecalculateDueOnIgnoredStatusChange => 1,
++ ExcludeTimeOnIgnoredStatuses => 1,
+ IgnoreOnStatuses => ['stalled'],
+ },
+ },
@@ -278,7 +275,7 @@
+ ...
+ },
+ ...
-+ );
++ ));
+
+=item AssumeOutsideActor
+
@@ -346,46 +343,10 @@
+
+Set( %ServiceBusinessHours, );
+
-+=item Access control
-+
-+You can totally hide SLA custom field from users and use per queue
-+defaults, just revoke SeeCustomField and ModifyCustomField.
-+
-+If you want people to see the current service level ticket is assigned
-+to then grant SeeCustomField right.
-+
-+You may want to allow customers or managers to escalate their tickets.
-+Just grant them ModifyCustomField right.
-+
-+=cut
-+
- =back
++=back
=head1 Administrative interface
-
-diff --git a/lib/RT/Action/SLA_SetDue.pm b/lib/RT/Action/SLA_SetDue.pm
---- a/lib/RT/Action/SLA_SetDue.pm
-+++ b/lib/RT/Action/SLA_SetDue.pm
-@@
- );
-
- my $meta =
-- $RT::ServiceAgreements{ 'Levels' }{ $level }
-- ? $RT::ServiceAgreements{ 'Levels' }{ $level }{ $is_outside ? 'Response' : 'KeepInLoop' }
-+ RT->Config->Get('ServiceAgreements') && RT->Config->Get('ServiceAgreements')->{ 'Levels' }{ $level }
-+ ? RT->Config->Get('ServiceAgreements')->{ 'Levels' }{ $level }{ $is_outside ? 'Response' : 'KeepInLoop' }
- : undef;
- if ( $meta && $meta->{IgnoreOnStatuses} && $meta->{RecalculateDueOnIgnoredStatusChange} ) {
- my $last_ignored_status_txn = $self->LastIgnoredStatusAct(@{$meta->{IgnoreOnStatuses}});
-@@
- # owner is always treated as inside actor
- return 0 if $actor->id == $self->TicketObj->Owner;
-
-- if ( $RT::ServiceAgreements{'AssumeOutsideActor'} ) {
-+ if ( RT->Config->Get('ServiceAgreements')->{'AssumeOutsideActor'} ) {
- # All non-admincc users are outside actors
- return 0 if $self->TicketObj ->AdminCc->HasMemberRecursively( $actor )
- or $self->TicketObj->QueueObj->AdminCc->HasMemberRecursively( $actor );
+
diff --git a/lib/RT/SLA.pm b/lib/RT/SLA.pm
--- a/lib/RT/SLA.pm
@@ -397,9 +358,9 @@
-=head1 CONFIGURATION
-
-Service level agreements of tickets is controlled by an SLA custom field (CF).
--You need to create/apply it and specify it in config like:
--
-- Set($SLACustomField, 'SLA');
+-This field is created during C<make initdb> step (above) and applied globally.
+-This CF MUST be of C<select one value> type. Values of the CF define the
+-service levels.
-
-It's possible to define different set of levels for different
-queues. You can create several CFs with the same name and
@@ -636,18 +597,16 @@
-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.
--The option C<RecalculateDueOnIgnoredStatusChange> could get around the
--"probably be overdue" issue by considering the last ignored status date too.
--e.g.
--
-- 'level x' => {
-- KeepInLoop => {
-- BusinessMinutes => 60,
-- RecalculateDueOnIgnoredStatusChange => 1,
-- IgnoreOnStatuses => ['stalled'],
-- },
-- },
--
+-C<ExcludeTimeOnIgnoredStatuses> option could get around the "probably be
+-overdue" issue by excluding the time spent on ignored statuses.
+-
+- 'level x' => {
+- KeepInLoop => {
+- BusinessMinutes => 60,
+- ExcludeTimeOnIgnoredStatuses => 1,
+- IgnoreOnStatuses => ['stalled'],
+- },
+- },
-
-=head2 Configuring business hours
-
@@ -715,65 +674,7 @@
- ...
- };
-
--=head2 Access control
--
--You can totally hide SLA custom field from users and use per queue
--defaults, just revoke SeeCustomField and ModifyCustomField.
--
--If you want people to see the current service level ticket is assigned
--to then grant SeeCustomField right.
--
--You may want to allow customers or managers to escalate thier tickets.
--Just grant them ModifyCustomField right.
--
=cut
sub BusinessHours {
-@@
-
- require Business::Hours;
- my $res = new Business::Hours;
-- $res->business_hours( %{ $RT::ServiceBusinessHours{ $name } } )
-- if $RT::ServiceBusinessHours{ $name };
-+ $res->business_hours( %{ RT->Config->Get('ServiceBusinessHours')->{ $name } } )
-+ if RT->Config->Get('ServiceBusinessHours') && RT->Config->Get('ServiceBusinessHours')->{ $name };
- return $res;
- }
-
-@@
- @_
- );
-
-- my $meta = $RT::ServiceAgreements{'Levels'}{ $args{'Level'} };
-+ my $meta = RT->Config->Get('ServiceAgreements') ? RT->Config->Get('ServiceAgreements')->{'Levels'}{ $args{'Level'} } : undef;
- return undef unless $meta;
-
- if ( exists $meta->{'StartImmediately'} || !defined $meta->{'Starts'} ) {
-@@
- $res{'OutOfHours'} = $meta->{'OutOfHours'}{ $args{'Type'} };
-
- $args{'Queue'} ||= $args{'Ticket'}->QueueObj if $args{'Ticket'};
-- if ( $args{'Queue'} && ref $RT::ServiceAgreements{'QueueDefault'}{ $args{'Queue'}->Name } ) {
-- $res{'Timezone'} = $RT::ServiceAgreements{'QueueDefault'}{ $args{'Queue'}->Name }{'Timezone'};
-+ if ( $args{'Queue'} && ref RT->Config->Get('ServiceAgreements')->{'QueueDefault'}{ $args{'Queue'}->Name } ) {
-+ $res{'Timezone'} = RT->Config->Get('ServiceAgreements')->{'QueueDefault'}{ $args{'Queue'}->Name }{'Timezone'};
- }
- $res{'Timezone'} ||= $meta->{'Timezone'} || $RT::Timezone;
-
-@@
- if ( $args{'Queue'} ) {
- return $args{'Queue'}->SLA if $args{'Queue'}->SLA;
-
-- if ( my $info = $RT::ServiceAgreements{'QueueDefault'}{ $args{'Queue'}->Name } ) {
-+ if ( my $info = RT->Config->Get('ServiceAgreements')->{'QueueDefault'}{ $args{'Queue'}->Name } ) {
- return $info unless ref $info;
-- return $info->{'Level'} || $RT::ServiceAgreements{'Default'};
-+ return $info->{'Level'} || RT->Config->Get('ServiceAgreements')->{'Default'};
- }
- }
-- return $RT::ServiceAgreements{'Default'};
-+ return RT->Config->Get('ServiceAgreements')->{'Default'};
- }
-
- RT::Base->_ImportOverlays();
4: bd668ad < -: ------- in case users are upgrading with SLA extension installed already
5: acbe9d8 < -: ------- upgrading note for core sla
-: ------- > 5: 8be9a47 upgrade-sla script to migrate SLA values from custom fields
-: ------- > 6: 6eaad04 upgrading note for core sla
-: ------- > 7: 8bfb984 fix uninitialized warnings to make tests happy
More information about the rt-commit
mailing list