[Rt-commit] rt branch, 4.4/total-time-worked, created. rt-4.4.1-310-ge8295fe

Dave Goehrig dave at bestpractical.com
Tue Mar 14 14:59:24 EDT 2017


The branch, 4.4/total-time-worked has been created
        at  e8295fe801abe6bdd4e8db26ee18c0144a66fcf2 (commit)

- Log -----------------------------------------------------------------
commit e8295fe801abe6bdd4e8db26ee18c0144a66fcf2
Author: Dave Goehrig <dave at bestpractical.com>
Date:   Thu Feb 23 11:51:47 2017 -0500

    adding total time worked
    
    This adds a new recursive total time worked function to Ticket.pm
    and adds a COLUMN_MAP entry so that it can be displayed in reports.
    
    The code is optional and requires setting a $DisplayTotalTimeWorked
    in RT_SiteConfig.pm.  Also before creating tickets using this one needs
    to disable the  'On TimeWorked Change Update Parent TimeWorked' scrip
    which mutates the value of time worked on the parent tickets.
    
    It should be noted running this on an existing database will report
    invalid results for all tickets where that scrip was active as it will
    double count all of the child time worked in the parent tickets.

diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index f2581de..01e4791 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -1411,8 +1411,37 @@ sub TimeEstimatedAsString {
     return $self->_DurationAsString( $self->TimeEstimated );
 }
 
+=head2 TotalTimeWorked
 
+Returns the amount of time worked on this ticket and all child tickets
 
+=cut
+
+sub TotalTimeWorked {
+    my $self = shift;
+    my $seen = shift || {};
+    my $time = $self->TimeWorked;
+    my $links = $self->Members;
+    LINK: while (my $link = $links->Next) {
+        my $obj = $link->BaseObj;
+        next LINK unless $obj && UNIVERSAL::isa($obj,'RT::Ticket');
+        next LINK if $seen->{$obj->Id};
+        $seen->{ $obj->Id } = 1;
+        $time += $obj->TotalTimeWorked($seen);
+    }
+    return $time;
+}
+
+=head2 TotalTimeWorkedAsString
+
+Returns the amount of time worked on this ticket and all its children as a formatted duration string
+
+=cut
+
+sub TotalTimeWorkedAsString {
+    my $self = shift;
+    return $self->_DurationAsString( $self->TotalTimeWorked );
+}
 
 =head2 Comment
 
diff --git a/share/html/Elements/RT__Ticket/ColumnMap b/share/html/Elements/RT__Ticket/ColumnMap
index 2db1149..089ccea 100644
--- a/share/html/Elements/RT__Ticket/ColumnMap
+++ b/share/html/Elements/RT__Ticket/ColumnMap
@@ -342,6 +342,16 @@ unless (RT->Config->Get('Crypt')->{'Enable'}) {
     $COLUMN_MAP->{KeyRequestors} = $GenericMap->{Requestors};
 }
 
+if(RT->Config->Get('DisplayTotalTimeWorked')) {
+  $COLUMN_MAP->{TotalTimeWorked} = {
+        attribute => 'TotalTimeWorked',
+        title => 'Total Time Worked',
+        value => sub {
+            return $_[0]->TotalTimeWorkedAsString;
+        },
+    }
+}
+
 $m->callback( GenericMap => $GenericMap, COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 );
 return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr );
 </%init>
diff --git a/share/html/Search/Elements/BuildFormatString b/share/html/Search/Elements/BuildFormatString
index 1bf71b1..4bea321 100644
--- a/share/html/Search/Elements/BuildFormatString
+++ b/share/html/Search/Elements/BuildFormatString
@@ -101,6 +101,9 @@ my @fields = qw(
     NBSP
 ); # loc_qw
 
+# Total time worked is an optional ColumnMap enabled for rolling up child timeworked
+push @fields, 'TotalTimeWorked' if (RT->Config->Get('DisplayTotalTimeWorked'));
+
 my $CustomFields = RT::CustomFields->new( $session{'CurrentUser'});
 foreach my $id (keys %queues) {
     # Gotta load up the $queue object, since queues get stored by name now.
diff --git a/share/html/Ticket/Elements/ShowBasics b/share/html/Ticket/Elements/ShowBasics
index 0a06f02..94e3814 100644
--- a/share/html/Ticket/Elements/ShowBasics
+++ b/share/html/Ticket/Elements/ShowBasics
@@ -74,6 +74,13 @@
     <td class="value"><& ShowTime, minutes => $Ticket->TimeWorked &></td>
   </tr>
 % }
+% my $totalTimeWorked = 0;
+% if (RT->Config->Get('DisplayTotalTimeWorked') && ($totalTimeWorked = $Ticket->TotalTimeWorked)) {
+  <tr class="total time worked sum">
+    <td class="label"><&|/l&>Total Time Worked</&>:</td>
+    <td class="value"><& ShowTime, minutes => $totalTimeWorked &></td>
+  </tr>
+% }
 % if ( keys %$time_worked ) {
 <tr class="time worked by-user">
   <td class="label"><&|/l&>Users</&>:</td>
diff --git a/t/api/total-time-worked.t b/t/api/total-time-worked.t
new file mode 100644
index 0000000..c0a3efa
--- /dev/null
+++ b/t/api/total-time-worked.t
@@ -0,0 +1,183 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test tests => undef;
+
+my $scrip = RT::Scrip->new(RT->SystemUser);
+$scrip->LoadByCols(Description => 'On TimeWorked Change Update Parent TimeWorked');
+$scrip->SetDisabled(1);
+
+
+diag("Test tickets total time worked");
+{
+    my $parent = RT::Ticket->new(RT->SystemUser);
+    my ($ok1,$msg1) = $parent->Create(
+        Queue => 'general',
+        Subject => 'total time worked test parent',
+    );
+    ok($ok1,"Created parent ticket $msg1");
+
+    my $child = RT::Ticket->new(RT->SystemUser);
+    my ($ok2,$msg2) = $child->Create(
+        Queue => 'general',
+        Subject => 'total time worked test child',
+    );
+    ok($ok2,"Created child ticket $msg2");
+
+    my $grandchild = RT::Ticket->new(RT->SystemUser);
+    my ($ok3,$msg3) = $grandchild->Create(
+        Queue => 'general',
+        Subject => 'total time worked test child child',
+    );
+    ok($ok3,"Created grandchild ticket $msg3");
+
+    my ($ok4,$msg4) = $parent->AddLink(
+        Type => 'MemberOf',
+        Base => $child->id,
+    );
+    ok($ok4,"Created parent -> child link $msg4");
+
+    my ($ok5,$msg5) = $child->AddLink(
+        Type => 'MemberOf',
+        Base => $grandchild->id,
+    );
+    ok($ok5,"Created child -> grandchild link $msg5");
+
+    my $grandchild2 = RT::Ticket->new(RT->SystemUser);
+    my ($ok6,$msg6) = $grandchild2->Create(
+        Queue => 'general',
+        Subject => 'total time worked test other child child',
+    );
+    ok($ok6,"Create second grandchild $msg6");
+
+    my ($ok7,$msg7) = $child->AddLink(
+        Type => 'MemberOf',
+        Base => $grandchild2->id,
+    );
+    ok($ok7,"Create child -> second grandchild link $msg7");
+
+    $parent->SetTimeWorked(10);
+    $child->SetTimeWorked(20);
+    $grandchild->SetTimeWorked(40);
+    $grandchild2->SetTimeWorked(50);
+
+    is $grandchild2->TimeWorked, 50, 'check other child child time worked';
+    is $grandchild->TimeWorked, 40, 'check child child time worked';
+    is $child->TimeWorked, 20, 'check child time worked';
+    is $parent->TimeWorked, 10, 'check parent time worked';
+
+    is $parent->TotalTimeWorked, 120, 'check parent total time worked';
+    is $child->TotalTimeWorked, 110, 'check child total time worked';
+    is $grandchild->TotalTimeWorked, 40, 'check child child total time worked';
+    is $grandchild2->TotalTimeWorked, 50, 'check other child child total time worked';
+
+    is $parent->TotalTimeWorkedAsString, '2 hours (120 minutes)', 'check parent total time worked as string';
+    is $grandchild->TotalTimeWorkedAsString, '40 minutes', 'check child child total time workd as string';
+}
+
+diag("Test multiple inheritance total time worked");
+{
+    my $parent = RT::Ticket->new(RT->SystemUser);
+    my ($ok1,$msg1) = $parent->Create(
+        Queue => 'general',
+        Subject => 'total time worked test parent',
+    );
+    ok $ok1, "created parent ticket $msg1";
+
+    my $child = RT::Ticket->new(RT->SystemUser);
+    my ($ok2,$msg2) = $child->Create(
+        Queue => 'general',
+        Subject => 'total time worked test child',
+    );
+    ok $ok2, "created child ticket $msg2";
+
+    my $grandchild = RT::Ticket->new(RT->SystemUser);
+    my ($ok3,$msg3) = $grandchild->Create(
+        Queue => 'general',
+        Subject => 'total time worked test child child, and test child',
+    );
+    ok $ok3, "created grandchild ticket $msg3";
+
+    $parent->SetTimeWorked(10);
+    $child->SetTimeWorked(20);
+    $grandchild->SetTimeWorked(40);
+
+    my ($ok4,$msg4) = $parent->AddLink(
+        Type => 'MemberOf',
+        Base => $child->id,
+    );
+    ok $ok4, "Create parent -> child link $msg4";
+
+    my ($ok5,$msg5) = $child->AddLink(
+        Type => 'MemberOf',
+        Base => $grandchild->id,
+    );
+    ok $ok5, "Create child -> grandchild link $msg5";
+
+     my ($ok6,$msg6) = $parent->AddLink(
+        Type => 'MemberOf',
+        Base => $grandchild->id,
+    );
+    ok $ok6, "Created parent -> grandchild link $msg6";
+
+    is $parent->TotalTimeWorked, 70, 'check parent total time worked';
+    is $child->TotalTimeWorked, 60, 'check child total time worked';
+    is $grandchild->TotalTimeWorked, 40, 'check child child total time worked';
+
+}
+
+diag("Test inheritance total time worked");
+{
+    my @warnings;
+    
+    my $parent = RT::Ticket->new(RT->SystemUser);
+    my ($ok1,$msg1) = $parent->Create(
+        Queue => 'general',
+        Subject => 'total time worked test parent',
+    );
+    ok $ok1, "created parent ticket $msg1";
+
+    my $child = RT::Ticket->new(RT->SystemUser);
+    my ($ok2,$msg2) = $child->Create(
+        Queue => 'general',
+        Subject => 'total time worked test child',
+    );
+    ok $ok2, "created child ticket $msg2";
+
+    {
+        local $SIG{__WARN__} = sub {
+            push @warnings, @_;
+        };
+
+        my ($ok3,$msg3) = $parent->AddLink(
+            Type => 'MemberOf',
+            Base => $child->id,
+        );
+        ok $ok3, "Created parent -> child link $msg3";
+        my ($ok4,$msg4) = $parent->AddLink(
+            Type => 'MemberOf',
+            Base => 'http://bestpractical.com',
+        );
+        ok $ok4, "Create parent -> url link $msg4";
+
+        my ($ok5,$msg5) = $child->AddLink(
+            Type => 'MemberOf',
+            Base => 'http://docs.bestpractical.com/',
+        );
+        ok $ok5, "Created child -> url link $msg5";
+
+    }
+
+    $parent->SetTimeWorked(10);
+    $child->SetTimeWorked(20);
+
+    is $parent->TotalTimeWorked, 30, 'check parent total time worked';
+    is $child->TotalTimeWorked, 20, 'check child total time worked';
+
+   TODO: {
+       local $TODO = "this warns because of the unrelated I#31399";
+       is(@warnings, 0, "no warnings");
+   }
+}
+
+done_testing;

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


More information about the rt-commit mailing list