[Rt-commit] r4302 - in RT-Extension-ActivityReports: . html html/Callbacks html/Callbacks/ActivityReports html/Callbacks/ActivityReports/NoAuth html/Callbacks/ActivityReports/NoAuth/webrt.css html/Tools html/Tools/Elements lib lib/RT lib/RT/Extension

alexmv at bestpractical.com alexmv at bestpractical.com
Tue Dec 13 13:57:41 EST 2005


Author: alexmv
Date: Tue Dec 13 13:57:40 2005
New Revision: 4302

Added:
   RT-Extension-ActivityReports/MANIFEST
   RT-Extension-ActivityReports/Makefile.PL
   RT-Extension-ActivityReports/html/
   RT-Extension-ActivityReports/html/Callbacks/
   RT-Extension-ActivityReports/html/Callbacks/ActivityReports/
   RT-Extension-ActivityReports/html/Callbacks/ActivityReports/NoAuth/
   RT-Extension-ActivityReports/html/Callbacks/ActivityReports/NoAuth/webrt.css/
   RT-Extension-ActivityReports/html/Callbacks/ActivityReports/NoAuth/webrt.css/Default
   RT-Extension-ActivityReports/html/Tools/
   RT-Extension-ActivityReports/html/Tools/ActivityDetail.html
   RT-Extension-ActivityReports/html/Tools/ActivitySummary.html
   RT-Extension-ActivityReports/html/Tools/Elements/
   RT-Extension-ActivityReports/html/Tools/Elements/MiniPlot
   RT-Extension-ActivityReports/html/Tools/ResolutionStatistics.html
   RT-Extension-ActivityReports/lib/
   RT-Extension-ActivityReports/lib/RT/
   RT-Extension-ActivityReports/lib/RT/Extension/
   RT-Extension-ActivityReports/lib/RT/Extension/ActivityReports.pm
Modified:
   RT-Extension-ActivityReports/   (props changed)
Log:
 r7708 at zoq-fot-pik:  chmrr | 2005-12-13 13:57:03 -0500
  * Three kinds of reports sketched out; they still need style, query help


Added: RT-Extension-ActivityReports/MANIFEST
==============================================================================
--- (empty file)
+++ RT-Extension-ActivityReports/MANIFEST	Tue Dec 13 13:57:40 2005
@@ -0,0 +1,18 @@
+html/Callbacks/ActivityReports/NoAuth/webrt.css/Default
+html/Tools/ActivityDetail.html
+html/Tools/ActivitySummary.html
+html/Tools/Elements/MiniPlot
+html/Tools/ResolutionStatistics.html
+inc/Module/Install.pm
+inc/Module/Install/Base.pm
+inc/Module/Install/Can.pm
+inc/Module/Install/Fetch.pm
+inc/Module/Install/Makefile.pm
+inc/Module/Install/Metadata.pm
+inc/Module/Install/RTx.pm
+inc/Module/Install/Win32.pm
+inc/Module/Install/WriteAll.pm
+lib/RT/Extension/ActivityReports.pm
+Makefile.PL
+MANIFEST			This list of files
+META.yml

Added: RT-Extension-ActivityReports/Makefile.PL
==============================================================================
--- (empty file)
+++ RT-Extension-ActivityReports/Makefile.PL	Tue Dec 13 13:57:40 2005
@@ -0,0 +1,6 @@
+use inc::Module::Install;
+
+RTx('RT-Extension-ActivityReports');
+license('perl');
+author('Alex Vandiver <alexmv at bestpractical.com>');
+&WriteAll;

Added: RT-Extension-ActivityReports/html/Callbacks/ActivityReports/NoAuth/webrt.css/Default
==============================================================================
--- (empty file)
+++ RT-Extension-ActivityReports/html/Callbacks/ActivityReports/NoAuth/webrt.css/Default	Tue Dec 13 13:57:40 2005
@@ -0,0 +1,42 @@
+table.miniplot {
+    width: 100%;
+    border-collapse: collapse;
+}
+table.miniplot td {
+    margin: 0;
+    padding: 0;
+    border-bottom: 1px solid black;
+}
+table.miniplot .graph {
+    margin-left: auto;
+    margin-right: auto;
+    position: relative;
+    width: 60px;
+}
+table.miniplot .graph ul { 
+    height: 100px; 
+    margin: 0;
+    padding: 0;
+}
+table.miniplot .graph ul li {  
+    list-style: none;
+    position: absolute; 
+    bottom: 0px; 
+    padding: 0 !important; 
+    margin: 0 !important; 
+    border-bottom: none;
+}
+table.miniplot .graph ul li .data {
+    display: none;
+}
+
+.miniplot .demoblock { margin: 0 10px; padding: 0 30px; }
+
+.miniplot .c1 { border: 2px solid #990000; background: #ff0000; }
+.miniplot .c2 { border: 2px solid #996600; background: #ff9900; }
+.miniplot .c3 { border: 2px solid #009900; background: #00ff00; }
+.miniplot .c4 { border: 2px solid #009999; background: #00ffff; }
+.miniplot .c5 { border: 2px solid #000099; background: #0000ff; }
+.miniplot .c6 { border: 2px solid #990099; background: #ff00ff; }
+graph .c5 { border: 2px solid #000099; background: #0000ff; }
+.graph .c6 { border: 2px solid #990099; background: #ff00ff; }

Added: RT-Extension-ActivityReports/html/Tools/ActivityDetail.html
==============================================================================
--- (empty file)
+++ RT-Extension-ActivityReports/html/Tools/ActivityDetail.html	Tue Dec 13 13:57:40 2005
@@ -0,0 +1,87 @@
+<& /Elements/Header, Title => loc("Activity detail") &>
+<& Elements/Tabs,
+    current_tab => "Tools/ActivityDetail.html",
+    Title => loc("Activity detail") &>
+
+<& Elements/MiniPlot, data => \%counts &>
+
+<table style="width: 100%">
+<tr>
+<th>Queue</th><th>Activity</th><th>Date</th><th>Time</th><th>Ticket #</th><th>User</th><th>Short description</th>
+</tr>
+% for my $item (@items) {
+<tr>
+<td><% $item->{queue} %></td>
+<td><% $item->{status} %></td>
+<td><% $item->{date} %></td>
+<td><% $item->{time} %></td>
+<td><% $item->{id} %></td>
+<td><% $item->{actor} %></td>
+<td><% $item->{notes} %></td>
+</tr>
+% }
+</table>
+
+<form action="ActivityDetail.html" method="POST" enctype="multipart/form-data">
+<textarea name="query"><% $query %></textarea>
+<& /Elements/Submit, Name => 'LimitReport', Label => loc('Limit') &>
+</form>
+<%args>
+$query => 'id > 0'
+$start => "'2005/01/01'"
+$end   => "'2006/01/01'"
+</%args>
+<%init>
+
+
+my $summary_tickets = RT::Tickets->new($session{'CurrentUser'});
+$summary_tickets->FromSQL($query . " AND ( Updated >= $start AND Updated <= $end)");
+my %counts;
+while (my $ticket = $summary_tickets->Next) {
+    my $txns = $ticket->Transactions;
+    $txns->Limit(FIELD => 'Created', OPERATOR => '>=', VALUE => $start);
+    $txns->Limit(FIELD => 'Created', OPERATOR => '<=', VALUE => $end);
+    # I think they really don't just want status changes
+    $txns->Limit(FIELD => 'Type', VALUE => 'Status', ENTRYAGGREGATOR => 'OR');
+    $txns->Limit(FIELD => 'Type', VALUE => 'Create');
+
+    while (my $txn = $txns->Next){
+        my $date = substr($txn->Created, 0, 10);
+        # we don't have data on the status of a new ticket, default to 'new'
+        $counts{$date}{$txn->NewValue || 'new'}++;
+    }
+}
+
+
+my $tickets = RT::Tickets->new($session{'CurrentUser'});
+$tickets->FromSQL($query);
+my @items;
+while (my $ticket = $tickets->Next) {
+    my $txns = $ticket->Transactions;
+    $txns->Limit(FIELD => 'Created', OPERATOR => '>=', VALUE => $start);
+    $txns->Limit(FIELD => 'Created', OPERATOR => '<=', VALUE => $end);
+    # I think they really don't just want status changes
+    $txns->Limit(FIELD => 'Type', VALUE => 'Status', ENTRYAGGREGATOR => 'OR');
+    $txns->Limit(FIELD => 'Type', VALUE => 'Create');
+
+    while (my $txn = $txns->Next) {
+        push @items, { queue => $txn->TicketObj->QueueObj->Name,
+                       id => $txn->TicketObj->id,
+                       date => (split ' ', $txn->CreatedObj->ISO)[0],
+                       time => (split ' ', $txn->CreatedObj->ISO)[1],
+                       status => $txn->NewValue || 'new',
+                       actor => $txn->CreatorObj->Name,
+                       notes => (substr($txn->Content, 0, 60) ||  $txn->BriefDescription)
+                     };
+    }
+}
+
+ at items = sort {
+           $a->{queue}    cmp $b->{'queue'}
+        || $a->{'status'} cmp $b->{'status'}
+        || $a->{'id'}     <=> $b->{'id'}
+        || $a->{'actor'}  cmp $b->{'actor'}
+        || $a->{'notes'}  <=> $b->{'notes'}
+} @items;
+
+</%init>
\ No newline at end of file

Added: RT-Extension-ActivityReports/html/Tools/ActivitySummary.html
==============================================================================
--- (empty file)
+++ RT-Extension-ActivityReports/html/Tools/ActivitySummary.html	Tue Dec 13 13:57:40 2005
@@ -0,0 +1,66 @@
+<& /Elements/Header, Title => loc("Activity summary") &>
+<& Elements/Tabs,
+    current_tab => "Tools/ActivitySummary.html",
+    Title => loc("Activity summary") &>
+
+<& Elements/MiniPlot, data => \%queues &>
+
+<table style="width: 100%">
+<tr>
+<th>Queue</th>
+% for my $status (sort keys %status) {
+<th><% $status %></th>
+% }
+<th>Total</th>
+</tr>
+% for my $queue (sort keys %queues) {
+<th><% $queue %></th>
+% for my $status (sort keys %status) {
+<td><% $queues{$queue}{$status} || 0 %>
+% }
+<td><% $total{$queue} %></td>
+</tr>
+% }
+<tr>
+<th>Grand Total</th>
+% for my $status (sort keys %status) {
+<td><% $status{$status} %></td>
+% }
+<td><% $total %></td>
+</table>
+
+<form action="ActivitySummary.html" method="POST" enctype="multipart/form-data">
+<textarea name="query"><% $query %></textarea>
+<& /Elements/Submit, Name => 'LimitReport', Label => loc('Limit') &>
+</form>
+<%args>
+$query => 'id > 0'
+$start => "'2005/01/01'"
+$end   => "'2006/01/01'"
+</%args>
+<%init>
+
+my $tickets = RT::Tickets->new($session{'CurrentUser'});
+$tickets->FromSQL($query . " AND ( Updated >= $start AND Updated <= $end)");
+
+my %queues;
+my %status;
+my %total;
+my $total;
+while (my $ticket = $tickets->Next) {
+    my $txns = $ticket->Transactions;
+    $txns->Limit(FIELD => 'Created', OPERATOR => '>=', VALUE => $start);
+    $txns->Limit(FIELD => 'Created', OPERATOR => '<=', VALUE => $end);
+    $txns->Limit(FIELD => 'Type', VALUE => 'Status', ENTRYAGGREGATOR => 'OR');
+    $txns->Limit(FIELD => 'Type', VALUE => 'Create');
+
+    while (my $txn = $txns->Next) {
+        $queues{$txn->TicketObj->QueueObj->Name}{$txn->NewValue || 'new'}++;   
+        $status{$txn->NewValue || 'new'}++;
+        $total{$txn->TicketObj->QueueObj->Name}++;
+        $total++;
+    }
+}
+
+
+</%init>
\ No newline at end of file

Added: RT-Extension-ActivityReports/html/Tools/Elements/MiniPlot
==============================================================================
--- (empty file)
+++ RT-Extension-ActivityReports/html/Tools/Elements/MiniPlot	Tue Dec 13 13:57:40 2005
@@ -0,0 +1,57 @@
+<table class="miniplot"><tr>
+% for my $major (@major) {
+<td><div class="graph">
+    <ul>
+% my $i = 0;
+% for my $minor (@minor) {
+%   my $percent = int( 100 * ($data->{$major}{$minor} || 0) / $max );
+        <li class="c<% ($i % 6) + 1%>" style="width: <% $barwidth %>%; 
+                                              left: <% $baroffset + $each * $i %>%;
+                                              height: <% $percent %>%;"><div class="data"><% $minor %>: <% $percent %>%</div></li>
+% $i++;
+% }
+    </ul>
+</div></td>
+% }
+</tr><tr>
+% for my $major (@major) {
+<th><% $major %></th>
+% }
+</tr>
+</table>
+
+<table class="miniplot"><tr>
+% my $i = 0;
+% for my $minor (@minor) {
+<th><span class="demoblock c<% ($i++ % 6) + 1 %>"></span> <% $minor %></th>
+% }
+</tr>
+</table>
+
+<%args>
+$data
+$major => undef
+$minor => undef
+</%args>
+<%init>
+
+my $max = 0;
+
+my %minor;
+for my $major (keys %{$data}) {
+    for (keys %{$data->{$major}}) {
+        $minor{$_}++;
+        $max = $data->{$major}{$_} if $data->{$major}{$_} > $max;
+    }
+}
+
+my @major = $major ? @{$major} : sort keys %{$data};
+my @minor = $minor ? @{$minor} : sort keys %minor;
+
+return unless @minor and @major;
+
+my $each      = int( (100 / @minor) );
+my $barwidth  = int( (100 / @minor) * (3/4) );
+my $baroffset = int( (100 / @minor) * (1/8) );
+
+</%init>
\ No newline at end of file

Added: RT-Extension-ActivityReports/html/Tools/ResolutionStatistics.html
==============================================================================
--- (empty file)
+++ RT-Extension-ActivityReports/html/Tools/ResolutionStatistics.html	Tue Dec 13 13:57:40 2005
@@ -0,0 +1,100 @@
+<& /Elements/Header, Title => loc("Resolution statistics") &>
+<& Elements/Tabs,
+    current_tab => "Tools/ResolutionStatistics.html",
+    Title => loc("Activity detail") &>
+
+<& Elements/MiniPlot,
+   data => \%plot,
+   major => ['Date range','Last 30 days','Last 60 days','Last 90 days','Ever'],
+   minor => [(sort keys %queues), "Average"]
+ &>
+
+<table style="width: 100%">
+<tr>
+<td></td><th colspan="4">Number of tickets closed / Average resolution time per ticket</th>
+</tr>
+<tr>
+<th>Queue</th>
+<th>Date range</th>
+<th>Last 30 days</th>
+<th>Last 60 days</th>
+<th>Last 90 days</th>
+<th>Ever</th>
+</tr>
+% for my $queue (sort keys %queues) {
+<tr>
+<th><% $queue %></th>
+% for my $period ('Date range','Last 30 days','Last 60 days','Last 90 days','Ever') {
+<td><% scalar @{$closed{$period}{$queue}} %> / <% $average_resolve_times{$period}{$queue} %></td>
+% }
+</tr>
+% }
+<tr>
+<th>Ticket average</th>
+% for my $period ('Date range','Last 30 days','Last 60 days','Last 90 days','Ever') {
+<td><% $average_resolve_times{$period}{_all_count} %> / <% $average_resolve_times{$period}{_all} %></td>
+% }
+</tr>
+</table>
+
+<form action="ResolutionStatistics.html" method="POST" enctype="multipart/form-data">
+<textarea name="query"><% $query %></textarea>
+<& /Elements/Submit, Name => 'LimitReport', Label => loc('Limit') &>
+</form>
+
+<%args>
+$query => 'id > 0'
+$start => "'2005/01/01'"
+$end   => "'2006/01/01'"
+</%args>
+<%init>
+
+my $in_30_days = RT::Date->new($session{'CurrentUser'});
+$in_30_days->Set(Format => 'Unix', Value => ( time - (86400*30)));
+my $in_60_days = RT::Date->new($session{'CurrentUser'});
+$in_60_days->Set(Format => 'Unix', Value => ( time - (86400*60)));
+my $in_90_days = RT::Date->new($session{'CurrentUser'});
+$in_90_days->Set(Format => 'Unix', Value => ( time - (86400*90)));
+
+my %queries;
+$queries{'Date range'}   = "(Resolved >= $start AND Resolved <= $end)";
+$queries{'Last 30 days'} = "(Resolved >= '".$in_30_days->ISO."')";
+$queries{'Last 60 days'} = "(Resolved >= '".$in_60_days->ISO."')";
+$queries{'Last 90 days'} = "(Resolved >= '".$in_90_days->ISO."')";
+$queries{'Ever'}         = "(Status = 'resolved' OR Status = 'rejected')";
+
+
+my %closed;
+my %queues;
+foreach my $period (keys %queries) {
+    my $tix = RT::Tickets->new($session{'CurrentUser'});
+    $tix->FromSQL($query . " AND " .$queries{$period});
+
+    while (my $ticket = $tix->Next) {
+        push @{ $closed{$period}{$ticket->QueueObj->Name}}, $ticket;
+        $queues{$ticket->QueueObj->Name}++;
+    }
+}
+
+my %restimes;
+my %average_resolve_times;
+my %plot;
+use Time::Duration;
+foreach my $period ( keys %closed ) {
+    foreach my $queue ( keys %{$closed{$period}} ) {
+        foreach my $ticket (@{$closed{$period}{$queue}} ) {
+            push @{$restimes{$period}{$queue}}, ( $ticket->ResolvedObj->Unix - $ticket->CreatedObj->Unix);
+        }
+
+        my $total_time = 0;
+        $total_time+= $_ for @{$restimes{$period}{$queue}};
+        $average_resolve_times{$period}{'_all_time'} += $total_time;
+        $average_resolve_times{$period}{'_all_count'} += @{$restimes{$period}{$queue}};
+        $plot{$period}{$queue} = $total_time / @{$restimes{$period}{$queue}};
+        $average_resolve_times{$period}{$queue} = Time::Duration::concise(Time::Duration::duration($plot{$period}{$queue}));
+    }
+    $plot{$period}{Average} = $average_resolve_times{$period}{'_all_time'} / $average_resolve_times{$period}{'_all_count'};
+    $average_resolve_times{$period}{'_all'}  = Time::Duration::concise(Time::Duration::duration($plot{$period}{Average}));
+}
+
+</%init>
\ No newline at end of file

Added: RT-Extension-ActivityReports/lib/RT/Extension/ActivityReports.pm
==============================================================================
--- (empty file)
+++ RT-Extension-ActivityReports/lib/RT/Extension/ActivityReports.pm	Tue Dec 13 13:57:40 2005
@@ -0,0 +1,3 @@
+package RT::Extension::ActivityReports;
+
+our $VERSION = '0.1';


More information about the Rt-commit mailing list