[Rt-commit] rt branch, 4.6/custom-date-ranges, updated. rt-4.4.4-84-g3d8b51dd5

? sunnavy sunnavy at bestpractical.com
Tue Jun 4 17:55:02 EDT 2019


The branch, 4.6/custom-date-ranges has been updated
       via  3d8b51dd5ce6de049e45e6c6807b00a7393fd883 (commit)
       via  35e26f47d80423748a6a7d45766070f5d8c31284 (commit)
      from  b6822facbfe6f51da0154432d13e58a67ef83c9e (commit)

Summary of changes:
 etc/RT_Config.pm.in        |  5 ++++-
 lib/RT/Record.pm           | 46 ++++++++++++++++++++++++++++++++++++++++------
 t/api/custom-date-ranges.t | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 7 deletions(-)

- Log -----------------------------------------------------------------
commit 35e26f47d80423748a6a7d45766070f5d8c31284
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Jun 5 05:39:03 2019 +0800

    Add business time support for custom date range

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 09e3f6874..2a8d0288f 100644
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1026,7 +1026,10 @@ Set C<%CustomDateRanges> to a nested structure similar to the following:
         'RT::Ticket' => {
             'Resolution Time' => 'Resolved - Created',
 
-            'Downtime' => 'CF.Recovered - CF.{First Alert}',
+            'Downtime' => {
+                value => 'CF.Recovered - CF.{First Alert}',
+                business_time => 1,
+            },
 
             'Time To Beta' => {
                 value => 'CF.Beta - now',
diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm
index ebbc5346d..eca8c12cd 100644
--- a/lib/RT/Record.pm
+++ b/lib/RT/Record.pm
@@ -2459,10 +2459,12 @@ sub _DateForCustomDateRangeField {
     return $date;
 }
 
-# parses "field - field" and returns a four-element list containing the end
+# parses "field - field" and returns a five-element list containing the end
 # date field name, the operator (right now always "-" for subtraction), the
-# start date field name, and either a custom duration formatter coderef or
-# undef. returns the empty list if there's an error
+# start date field name, either a custom duration formatter coderef or undef,
+# and a boolean to indicate if it should calculate duration as business time
+# or not. returns the empty list if there's an error
+
 sub _ParseCustomDateRangeSpec {
     my $self = shift;
     my $name = shift;
@@ -2470,10 +2472,12 @@ sub _ParseCustomDateRangeSpec {
 
     my $calculation;
     my $format;
+    my $business_time;
 
     if (ref($spec)) {
         $calculation = $spec->{value};
         $format = $spec->{format};
+        $business_time = $spec->{business_time};
     }
     else {
         $calculation = $spec;
@@ -2515,7 +2519,7 @@ sub _ParseCustomDateRangeSpec {
 
     my ($end, $op, $start) = @matches;
 
-    return ($end, $op, $start, $format);
+    return ($end, $op, $start, $format, $business_time);
 }
 
 =head2 CustomDateRange name, spec
@@ -2531,7 +2535,7 @@ sub CustomDateRange {
     my $name = shift;
     my $spec = shift;
 
-    my ($end, $op, $start, $format) = $self->_ParseCustomDateRangeSpec($name, $spec);
+    my ($end, $op, $start, $format, $business_time) = $self->_ParseCustomDateRangeSpec($name, $spec);
 
     # parse failed; render no value
     return unless $start && $end;
@@ -2545,7 +2549,37 @@ sub CustomDateRange {
 
     my $duration;
     if ($op eq '-') {
-        $duration = $end_dt->Diff($start_dt);
+        if ( $business_time && !$self->QueueObj->SLADisabled && $self->SLA ) {
+            my $config    = RT->Config->Get('ServiceAgreements');
+            my $agreement = $config->{Levels}{ $self->SLA };
+            my $timezone
+                = $config->{QueueDefault}{ $self->QueueObj->Name }{Timezone}
+                || $agreement->{Timezone}
+                || RT->Config->Get('Timezone');
+
+            {
+                local $ENV{'TZ'} = $ENV{'TZ'};
+                if ( $timezone ne ( $ENV{'TZ'} || '' ) ) {
+                    $ENV{'TZ'} = $timezone;
+                    require POSIX;
+                    POSIX::tzset();
+                }
+
+                my $bhours = RT::SLA->BusinessHours( $agreement->{BusinessHours} || 'Default' );
+                $duration = $bhours->between(
+                    $start_dt->Unix <= $end_dt->Unix
+                    ? ( $start_dt->Unix, $end_dt->Unix )
+                    : ( $end_dt->Unix, $start_dt->Unix )
+                );
+                $duration *= -1 if $start_dt->Unix > $end_dt->Unix;
+            }
+
+            if ( $timezone ne ( $ENV{'TZ'} || '' ) ) {
+                POSIX::tzset();
+            }
+        }
+
+        $duration //= $end_dt->Diff($start_dt);
     }
     else {
         RT->Logger->error("Unexpected operator in CustomDateRanges '$name' spec '$spec'. Got '$op', expected '-'.");

commit 3d8b51dd5ce6de049e45e6c6807b00a7393fd883
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Jun 5 05:39:19 2019 +0800

    Test business time for custom date range

diff --git a/t/api/custom-date-ranges.t b/t/api/custom-date-ranges.t
index 3ced5ae50..498ec80ce 100644
--- a/t/api/custom-date-ranges.t
+++ b/t/api/custom-date-ranges.t
@@ -54,3 +54,37 @@ is($t->CustomDateRange(test => {
     },
 }), '496800/1450202400/1449705600/1', 'format');
 
+diag 'test business time' if $ENV{'TEST_VERBOSE'};
+{
+    RT->Config->Set(
+        ServiceAgreements => (
+            Default => '2h',
+            Levels  => { '2h' => { Response => 2 * 60, Timezone => 'UTC' }, },
+        )
+    );
+    RT->Config->Set(
+        ServiceBusinessHours => (
+            'Default' => {
+                1 => { Name => 'Monday',    Start => '9:00', End => '18:00' },
+                2 => { Name => 'Tuesday',   Start => '9:00', End => '18:00' },
+                3 => { Name => 'Wednesday', Start => '9:00', End => '18:00' },
+                4 => { Name => 'Thursday',  Start => '9:00', End => '18:00' },
+                5 => { Name => 'Friday',    Start => '9:00', End => '18:00' },
+            },
+        )
+    );
+
+    ok( $t->QueueObj->SetSLADisabled(0), 'Enabled SLA' );
+    ok( $t->SetSLA('2h'), 'Set sla to 2h' );
+
+    # from 2015-12-10 00:00:00 to 2015-12-15 18:00:00, there are 4 work days
+    is( $t->CustomDateRange(
+            test => {
+                value         => 'Resolved - Created',
+                business_time => 1,
+            }
+        ),
+        '36 hours',
+        'Business time of Resolved - Created'
+      );
+}

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


More information about the rt-commit mailing list