[Rt-commit] rt branch, 4.4-trunk, updated. rt-4.4.1-355-g934b6f4

Shawn Moore shawn at bestpractical.com
Wed May 31 14:21:43 EDT 2017


The branch, 4.4-trunk has been updated
       via  934b6f47fa0d5265a1c6618e2479f1d5a7085ccf (commit)
       via  055a4f9dc9ba5050d8db56ff03f2f84e036313a4 (commit)
      from  ecd07082d28053b3cbe578070b4c1b6a6d358573 (commit)

Summary of changes:
 lib/RT/Ticket.pm                             |  30 +++++
 share/html/Elements/RT__Ticket/ColumnMap     |  10 ++
 share/html/Search/Elements/BuildFormatString |   4 +
 share/html/Ticket/Elements/ShowBasics        |   7 +
 t/api/total-time-worked.t                    | 183 +++++++++++++++++++++++++++
 5 files changed, 234 insertions(+)
 create mode 100644 t/api/total-time-worked.t

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

    Add Total Time Worked feature
    
    This adds a new recursive TotalTimeWorked method to RT::Ticket
    and adds a COLUMN_MAP entry so that it can be displayed in searches.
    
    The feature is optional and requires setting $DisplayTotalTimeWorked
    in RT_SiteConfig.pm.
    
    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 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. This is why the feature is opt in.

diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index f2581de..2224122 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -1411,8 +1411,38 @@ 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..711de89 100644
--- a/share/html/Search/Elements/BuildFormatString
+++ b/share/html/Search/Elements/BuildFormatString
@@ -101,6 +101,10 @@ 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..3724abf
--- /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;

commit 934b6f47fa0d5265a1c6618e2479f1d5a7085ccf
Merge: ecd0708 055a4f9
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed May 31 18:21:35 2017 +0000

    Merge branch '4.4/total-time-worked' into 4.4-trunk


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


More information about the rt-commit mailing list