Support numeric fields in reports

beta
Vitaliy Filippov 2018-05-30 16:26:36 +03:00
parent bf83ef7a98
commit 0191669861
5 changed files with 49 additions and 28 deletions

View File

@ -131,6 +131,23 @@ sub _get_names
} }
} }
sub get_measures
{
my $cols = Bugzilla::Search->REPORT_COLUMNS();
my $descs = {
count => '',
times => '',
};
for my $f (keys %$cols)
{
if ($cols->{$f}->{numeric})
{
$descs->{$f} = $cols->{$f}->{title};
}
}
return $descs;
}
sub execute sub execute
{ {
my $class = shift; my $class = shift;
@ -206,24 +223,34 @@ sub execute
} }
} }
my $measures = { my $measure_alias = {
etime => 'estimated_time', etime => 'estimated_time',
rtime => 'remaining_time', rtime => 'remaining_time',
wtime => 'interval_time', wtime => 'interval_time',
count => '_count',
}; };
my $measures = {
count => 'count',
};
my $old_columns = { %{Bugzilla::Search->COLUMNS($runner)} };
# Trick Bugzilla::Search: replace report columns SQL + add '_count' column # Trick Bugzilla::Search: replace report columns SQL + add '_count' column
# FIXME: Remove usage of global variable COLUMNS in search generation code # FIXME: Remove usage of global variable COLUMNS in search generation code
my %old_columns = %{Bugzilla::Search->COLUMNS($runner)}; %{Bugzilla::Search->COLUMNS($runner)} = (%{Bugzilla::Search->COLUMNS($runner)}, %{Bugzilla::Search->REPORT_COLUMNS($runner)});
%{Bugzilla::Search->COLUMNS($runner)} = (%{Bugzilla::Search->COLUMNS($runner)}, %{Bugzilla::Search->REPORT_COLUMNS}); Bugzilla::Search->COLUMNS($runner)->{count}->{name} = '1';
Bugzilla::Search->COLUMNS($runner)->{_count}->{name} = '1'; my $columns = Bugzilla::Search->COLUMNS($runner);
for my $column (keys %$columns)
{
if ($columns->{$column}->{numeric})
{
$measures->{$column} = $column;
}
}
my $measure = $ARGS->{measure} || ''; my $measure = $ARGS->{measure} || '';
$measure = $measure_alias->{$measure} || $measure;
# Check that $measure is available (+ etime/rtime/wtime is usable only in table mode)
if ($measure eq 'times' ? !$is_table : !$measures->{$measure}) if ($measure eq 'times' ? !$is_table : !$measures->{$measure})
{ {
$measure = 'count'; $measure = 'count';
} }
# If the user has no access to the measured column, reset it to 'count' # If the user has no access to the measured column, reset it to 'count'
if (!Bugzilla::Search->COLUMNS($runner)->{$measure eq 'times' ? 'remaining_time' : $measures->{$measure}}) if (!Bugzilla::Search->COLUMNS($runner)->{$measure eq 'times' ? 'remaining_time' : $measures->{$measure}})
{ {
@ -234,7 +261,7 @@ sub execute
my %a; my %a;
my @group_by = grep { !($a{$_}++) } values %$field; my @group_by = grep { !($a{$_}++) } values %$field;
my @axis_fields = @group_by; my @axis_fields = @group_by;
for ($measure eq 'times' ? qw(etime rtime wtime) : $measure) for ($measure eq 'times' ? qw(estimated_time remaining_time interval_time) : $measure)
{ {
push @axis_fields, $measures->{$_} unless $a{$measures->{$_}}; push @axis_fields, $measures->{$_} unless $a{$measures->{$_}};
} }
@ -251,7 +278,7 @@ sub execute
($field->{x} || "''")." x, ". ($field->{x} || "''")." x, ".
($field->{y} || "''")." y, ". ($field->{y} || "''")." y, ".
($field->{z} || "''")." z, ". ($field->{z} || "''")." z, ".
join(', ', map { "SUM($measures->{$_}) $_" } $measure eq 'times' ? qw(etime rtime wtime) : $measure). join(', ', map { "SUM($measures->{$_}) $_" } ($measure eq 'times' ? qw(etime rtime wtime) : $measure)).
" FROM ($query) _report_table GROUP BY ".join(", ", @group_by); " FROM ($query) _report_table GROUP BY ".join(", ", @group_by);
$::SIG{TERM} = 'DEFAULT'; $::SIG{TERM} = 'DEFAULT';
@ -264,11 +291,9 @@ sub execute
my %data; my %data;
my %names; my %names;
# Read the bug data and count the bugs for each possible value of row, column # Read the bug data and count the bugs for each possible value of row, column and table.
# and table.
# #
# We detect a numerical field, and sort appropriately, if all the values are # We detect a numerical field, and sort appropriately, if all the values are numeric.
# numeric.
my %isnumeric; my %isnumeric;
foreach my $group (@$results) foreach my $group (@$results)
@ -369,7 +394,7 @@ sub execute
$vars->{cumulate} = $ARGS->{cumulate} ? 1 : 0; $vars->{cumulate} = $ARGS->{cumulate} ? 1 : 0;
$vars->{x_labels_vertical} = $ARGS->{x_labels_vertical} ? 1 : 0; $vars->{x_labels_vertical} = $ARGS->{x_labels_vertical} ? 1 : 0;
%{Bugzilla::Search->COLUMNS($runner)} = %old_columns; %{Bugzilla::Search->COLUMNS($runner)} = %$old_columns;
return $vars; return $vars;
} }

View File

@ -464,7 +464,7 @@ sub STATIC_COLUMNS
qa_contact_short => { title => 'QA Contact Login' }, qa_contact_short => { title => 'QA Contact Login' },
# FIXME save aggregated work_time in bugs table and search on it # FIXME save aggregated work_time in bugs table and search on it
work_time => { name => $actual_time, numeric => 1 }, work_time => { name => $actual_time, numeric => 1 },
interval_time => { name => $actual_time, title => 'Period Worktime', noreports => 1, numeric => 1 }, interval_time => { name => $actual_time, title => 'Period Worktime', numeric => 1 },
percentage_complete => { percentage_complete => {
name => "(CASE WHEN $actual_time + bugs.remaining_time = 0.0 THEN 0.0" . name => "(CASE WHEN $actual_time + bugs.remaining_time = 0.0 THEN 0.0" .
" ELSE 100 * ($actual_time / ($actual_time + bugs.remaining_time)) END)", " ELSE 100 * ($actual_time / ($actual_time + bugs.remaining_time)) END)",

View File

@ -51,7 +51,8 @@ my $dbh = Bugzilla->switch_to_shadow_db();
my $action = $ARGS->{action} || 'menu'; my $action = $ARGS->{action} || 'menu';
my $token = $ARGS->{token}; my $token = $ARGS->{token};
if ($action eq "menu") $vars->{measure_descs} = Bugzilla::Report->get_measures();
if ($action eq 'menu')
{ {
# No need to do any searching in this case, so bail out early. # No need to do any searching in this case, so bail out early.
$template->process("reports/menu.html.tmpl", $vars) $template->process("reports/menu.html.tmpl", $vars)
@ -111,7 +112,7 @@ $vars->{report_columns} = Bugzilla::Search->REPORT_COLUMNS();
my $formatparam = $ARGS->{format}; my $formatparam = $ARGS->{format};
if ($action eq "wrap") if ($action eq 'wrap')
{ {
# So which template are we using? If action is "wrap", we will be using # So which template are we using? If action is "wrap", we will be using
# no format (it gets passed through to be the format of the actual data), # no format (it gets passed through to be the format of the actual data),

View File

@ -112,7 +112,7 @@ END; %]
<a href="[% urlbase %]&amp; <a href="[% urlbase %]&amp;
[% PROCESS value_url value=row field=row_field %]&amp; [% PROCESS value_url value=row field=row_field %]&amp;
[% PROCESS value_url value=col field=col_field %]"> [% PROCESS value_url value=col field=col_field %]">
[% data.$tbl.$col.$row.$m %]</a> [% data.$tbl.$col.$row.$m | format("%.01f") %]</a>
[% END %] [% END %]
</td> </td>
[% END %] [% END %]
@ -124,7 +124,7 @@ END; %]
<a href="[% urlbase %]&amp; <a href="[% urlbase %]&amp;
[% PROCESS value_url value=row field=row_field %] [% PROCESS value_url value=row field=row_field %]
[% "&amp;$col_vals" IF col_vals %]"> [% "&amp;$col_vals" IF col_vals %]">
[% row_total.$m %]</a> [% row_total.$m | format("%.01f") %]</a>
[% grand_total.$m = grand_total.$m + row_total.$m %] [% grand_total.$m = grand_total.$m + row_total.$m %]
</td> </td>
[% END %] [% END %]
@ -142,7 +142,7 @@ END; %]
<a href="[% urlbase %]&amp; <a href="[% urlbase %]&amp;
[% PROCESS value_url value=col field=col_field %] [% PROCESS value_url value=col field=col_field %]
[% "&amp;$row_vals" IF row_vals %]"> [% "&amp;$row_vals" IF row_vals %]">
[% col_totals.$col_n.$m %]</a> [% col_totals.$col_n.$m | format("%.01f") %]</a>
</td> </td>
[% END %] [% END %]
[% col_n = col_n + 1 %] [% col_n = col_n + 1 %]
@ -153,7 +153,7 @@ END; %]
<strong> <strong>
<a href="[% urlbase %] <a href="[% urlbase %]
[% "&amp;$row_vals" IF row_vals %] [% "&amp;$row_vals" IF row_vals %]
[% "&amp;$col_vals" IF col_vals %]">[% grand_total.$m %]</a> [% "&amp;$col_vals" IF col_vals %]">[% grand_total.$m | format("%.01f") %]</a>
</strong> </strong>
</td> </td>
[% END %] [% END %]

View File

@ -139,13 +139,8 @@
Show: Show:
</th> </th>
<td> <td>
[% measure_descs = { [% measure_descs.times = 'Estimated/Actual/Remaining' %]
rtime => 'Remaining time' [% measure_descs.count = "Number of $terms.bugs" %]
etime => 'Estimated time'
wtime => 'Actual time'
times => 'Estimated/Actual/Remaining'
count => "Number of $terms.bugs"
} %]
<select name="measure" style="width: 100%; border: 0; margin-top: 2px"> <select name="measure" style="width: 100%; border: 0; margin-top: 2px">
[% FOR m = measure_descs.keys.sort %] [% FOR m = measure_descs.keys.sort %]
<option value="[% m %]"[% IF measure == m %] selected="selected"[% END %]>[% measure_descs.$m %]</option> <option value="[% m %]"[% IF measure == m %] selected="selected"[% END %]>[% measure_descs.$m %]</option>