[Rt-commit] rt branch, 4.4/chart-group-by-custom-roles, created. rt-4.4.4-126-g15be5bba0e

? sunnavy sunnavy at bestpractical.com
Wed Jul 22 15:10:30 EDT 2020


The branch, 4.4/chart-group-by-custom-roles has been created
        at  15be5bba0e5978073e4ebeaaf21ae72d0c5d1a1e (commit)

- Log -----------------------------------------------------------------
commit 71f5c468664a230a7e81582f5460e0b1d1ae3830
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jul 23 02:12:35 2020 +0800

    Add grouping by custom roles for ticket search charts

diff --git a/lib/RT/Report/Tickets.pm b/lib/RT/Report/Tickets.pm
index 01e9b72d3c..254b3f6ecb 100644
--- a/lib/RT/Report/Tickets.pm
+++ b/lib/RT/Report/Tickets.pm
@@ -86,6 +86,7 @@ our @GROUPINGS = (
     Cc            => 'Watcher',         #loc_left_pair
     AdminCc       => 'Watcher',         #loc_left_pair
     Watcher       => 'Watcher',         #loc_left_pair
+    CustomRole    => 'Watcher',
 
     Created       => 'Date',            #loc_left_pair
     Starts        => 'Date',            #loc_left_pair
@@ -126,13 +127,62 @@ our %GROUPINGS_META = (
         Function => 'GenerateUserFunction',
     },
     Watcher => {
-        SubFields => [grep RT::User->_Accessible($_, "public"), qw(
-            Name RealName NickName
-            EmailAddress
-            Organization
-            Lang City Country Timezone
-        )],
+        SubFields => sub {
+            my $self = shift;
+            my $args = shift;
+
+            my @fields = grep RT::User->_Accessible( $_, "public" ),
+                qw( Name RealName NickName EmailAddress Organization Lang City Country Timezone);
+
+            my @res;
+            if ( $args->{key} =~ /^CustomRole/ ) {
+                my $queues = $args->{'Queues'};
+                if ( !$queues && $args->{'Query'} ) {
+                    require RT::Interface::Web::QueryBuilder::Tree;
+                    my $tree = RT::Interface::Web::QueryBuilder::Tree->new('AND');
+                    $tree->ParseSQL( Query => $args->{'Query'}, CurrentUser => $self->CurrentUser );
+                    $queues = $args->{'Queues'} = $tree->GetReferencedQueues( CurrentUser => $self->CurrentUser );
+                }
+                return () unless $queues;
+
+                my $crs = RT::CustomRoles->new( $self->CurrentUser );
+                for my $id ( keys %$queues ) {
+                    my $queue = RT::Queue->new( $self->CurrentUser );
+                    $queue->Load($id);
+                    next unless $queue->id;
+
+                    $crs->LimitToObjectId( $queue->id );
+                }
+                while ( my $cr = $crs->Next ) {
+                    for my $field (@fields) {
+                        push @res, [ $cr->Name, $field ], "CustomRole.{" . $cr->id . "}.$field";
+                    }
+                }
+            }
+            else {
+                for my $field (@fields) {
+                    push @res, [ $args->{key}, $field ], "$args->{key}.$field";
+                }
+            }
+            return @res;
+        },
         Function => 'GenerateWatcherFunction',
+        Label    => sub {
+            my $self = shift;
+            my %args = (@_);
+
+            my $key;
+            if ( $args{KEY} =~ /^CustomRole\.\{(\d+)\}/ ) {
+                my $id = $1;
+                my $cr = RT::CustomRole->new( $self->CurrentUser );
+                $cr->Load($id);
+                $key = $cr->Name;
+            }
+            else {
+                $key = $args{KEY};
+            }
+            return join ' ', $key, $args{SUBKEY};
+        },
     },
     Date => {
         SubFields => [qw(
@@ -392,7 +442,7 @@ sub Groupings {
             push @fields, map { ([$field, $_], "$field.$_") } @{ $meta->{'SubFields'} };
         }
         elsif ( my $code = $self->FindImplementationCode( $meta->{'SubFields'} ) ) {
-            push @fields, $code->( $self, \%args );
+            push @fields, $code->( $self, { %args, key => $field } );
         }
         else {
             $RT::Logger->error(
@@ -409,10 +459,10 @@ sub IsValidGrouping {
     my %args = (@_);
     return 0 unless $args{'GroupBy'};
 
-    my ($key, $subkey) = split /\./, $args{'GroupBy'}, 2;
+    my ($key, $subkey) = split /(?<!CustomRole)\./, $args{'GroupBy'}, 2;
 
     %GROUPINGS = @GROUPINGS unless keys %GROUPINGS;
-    my $type = $GROUPINGS{$key};
+    my $type = $self->_GroupingType( $key );
     return 0 unless $type;
     return 1 unless $subkey;
 
@@ -424,7 +474,7 @@ sub IsValidGrouping {
         return 1 if grep $_ eq $subkey, @{ $meta->{'SubFields'} };
     }
     elsif ( my $code = $self->FindImplementationCode( $meta->{'SubFields'}, 'silent' ) ) {
-        return 1 if grep $_ eq "$key.$subkey", $code->( $self, \%args );
+        return 1 if grep $_ eq "$key.$subkey", $code->( $self, { %args, key => $key } );
     }
     return 0;
 }
@@ -524,10 +574,10 @@ sub SetupGroupings {
             RT->Logger->error("'$e' is not a valid grouping for reports; skipping");
             next;
         }
-        my ($key, $subkey) = split /\./, $e, 2;
+        my ($key, $subkey) = split /(?<!CustomRole)\./, $e, 2;
         $e = { $self->_FieldToFunction( KEY => $key, SUBKEY => $subkey ) };
         $e->{'TYPE'} = 'grouping';
-        $e->{'INFO'} = $GROUPINGS{ $key };
+        $e->{'INFO'} = $self->_GroupingType($key);
         $e->{'META'} = $GROUPINGS_META{ $e->{'INFO'} };
         $e->{'POSITION'} = $i++;
         push @group_by, $e;
@@ -631,7 +681,7 @@ sub _FieldToFunction {
 
     $args{'FIELD'} ||= $args{'KEY'};
 
-    my $meta = $GROUPINGS_META{ $GROUPINGS{ $args{'KEY'} } };
+    my $meta = $GROUPINGS_META{ $self->_GroupingType( $args{'KEY'} ) };
     return ('FUNCTION' => 'NULL') unless $meta;
 
     return %args unless $meta->{'Function'};
@@ -861,6 +911,7 @@ sub GenerateWatcherFunction {
 
     my $type = $args{'FIELD'};
     $type = '' if $type eq 'Watcher';
+    $type =~ s!^CustomRole\.\{(\d+)\}!RT::CustomRole-$1!g;
 
     my $column = $args{'SUBKEY'} || 'Name';
 
@@ -1110,6 +1161,14 @@ sub FormatTable {
     return thead => \@head, tbody => \@body, tfoot => \@footer;
 }
 
+sub _GroupingType {
+    my $self = shift;
+    my $key  = shift or return;
+    # keys for custom roles are like "CustomRole.{1}"
+    $key = 'CustomRole' if $key =~ /^CustomRole/;
+    return $GROUPINGS{$key};
+}
+
 RT::Base->_ImportOverlays();
 
 1;

commit 15be5bba0e5978073e4ebeaaf21ae72d0c5d1a1e
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jul 23 02:31:55 2020 +0800

    Add tests for grouping by custom roles in ticket search charts

diff --git a/t/charts/group-by-cr.t b/t/charts/group-by-cr.t
new file mode 100644
index 0000000000..cda29a2ad7
--- /dev/null
+++ b/t/charts/group-by-cr.t
@@ -0,0 +1,80 @@
+use strict;
+use warnings;
+
+use RT::Test tests => undef;
+use RT::Ticket;
+
+my $q = RT::Test->load_or_create_queue( Name => 'General' );
+ok $q && $q->id, 'loaded or created queue';
+my $queue = $q->Name;
+
+my $cr = RT::CustomRole->new( RT->SystemUser );
+my ( $id, $msg ) = $cr->Create( Name => 'Test', Queue => $q->id );
+ok $id, $msg;
+ok( $cr->AddToObject( ObjectId => $q->id ) );
+my $cr_id = $cr->id;
+
+my @tickets = RT::Test->create_tickets(
+    {},
+    { Subject => 't1', Status => 'new', "RT::CustomRole-$cr_id" => 'root at localhost' },
+    { Subject => 't2', Status => 'new', "RT::CustomRole-$cr_id" => 'root at localhost' },
+    { Subject => 't3', Status => 'new' },
+);
+
+use_ok 'RT::Report::Tickets';
+
+{
+    my $report  = RT::Report::Tickets->new( RT->SystemUser );
+    my %columns = $report->SetupGroupings(
+        Query    => 'Queue = ' . $q->id,
+        GroupBy  => ["CustomRole.{$cr_id}.Name"],
+        Function => ['COUNT'],
+    );
+    $report->SortEntries;
+
+    my @colors   = RT->Config->Get("ChartColors");
+    my $expected = {
+        'thead' => [
+            {   'cells' => [
+                    { 'value'   => 'Test Name', 'type'  => 'head' },
+                    { 'rowspan' => 1,           'value' => 'Ticket count', 'type' => 'head', 'color' => $colors[0] },
+                ],
+            }
+        ],
+        'tfoot' => [
+            {   'cells' =>
+                    [ { 'colspan' => 1, 'value' => 'Total', 'type' => 'label' }, { 'value' => 3, 'type' => 'value' }, ],
+                'even' => 1,
+            }
+        ],
+        'tbody' => [
+            {   'cells' => [
+                    {   'type'  => 'label',
+                        'value' => '(no value)'
+                    },
+                    {   'query' => '(CustomRole.{1}.Name IS NULL)',
+                        'type'  => 'value',
+                        'value' => '1'
+                    }
+                ],
+                'even' => 1
+            },
+            {   'cells' => [
+                    {   'type'  => 'label',
+                        'value' => 'root'
+                    },
+                    {   'value' => '2',
+                        'query' => '(CustomRole.{1}.Name = \'root\')',
+                        'type'  => 'value'
+                    }
+                ],
+                'even' => 0
+            },
+        ],
+    };
+
+    my %table = $report->FormatTable(%columns);
+    is_deeply( \%table, $expected, "basic table" );
+}
+
+done_testing;

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


More information about the rt-commit mailing list