Mailing List Archive

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

- Log -----------------------------------------------------------------
commit 71f5c468664a230a7e81582f5460e0b1d1ae3830
Author: sunnavy <sunnavy@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@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@localhost' },
+ { Subject => 't2', Status => 'new', "RT::CustomRole-$cr_id" => 'root@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;

-----------------------------------------------------------------------
_______________________________________________
rt-commit mailing list
rt-commit@lists.bestpractical.com
http://lists.bestpractical.com/cgi-bin/mailman/listinfo/rt-commit