BritainKnights/Scripts/Engines/Reports/Objects/Staffing/StaffHistory.cs

406 lines
No EOL
11 KiB
C#

using System;
using System.IO;
using System.Xml;
using System.Collections;
namespace Server.Engines.Reports
{
public class StaffHistory : PersistableObject
{
#region Type Identification
public static readonly PersistableType ThisTypeID = new PersistableType( "stfhst", new ConstructCallback( Construct ) );
private static PersistableObject Construct()
{
return new StaffHistory();
}
public override PersistableType TypeID{ get{ return ThisTypeID; } }
#endregion
private PageInfoCollection m_Pages;
private QueueStatusCollection m_QueueStats;
private Hashtable m_UserInfo;
private Hashtable m_StaffInfo;
public PageInfoCollection Pages{ get{ return m_Pages; } set{ m_Pages = value; } }
public QueueStatusCollection QueueStats{ get{ return m_QueueStats; } set{ m_QueueStats = value; } }
public Hashtable UserInfo{ get{ return m_UserInfo; } set{ m_UserInfo = value; } }
public Hashtable StaffInfo{ get{ return m_StaffInfo; } set{ m_StaffInfo = value; } }
public void AddPage( PageInfo info )
{
lock ( SaveLock )
m_Pages.Add( info );
info.History = this;
}
public StaffHistory()
{
m_Pages = new PageInfoCollection();
m_QueueStats = new QueueStatusCollection();
m_UserInfo = new Hashtable( StringComparer.OrdinalIgnoreCase );
m_StaffInfo = new Hashtable( StringComparer.OrdinalIgnoreCase );
}
public StaffInfo GetStaffInfo( string account )
{
lock ( RenderLock )
{
if ( account == null || account.Length == 0 )
return null;
StaffInfo info = m_StaffInfo[account] as StaffInfo;
if ( info == null )
m_StaffInfo[account] = info = new StaffInfo( account );
return info;
}
}
public UserInfo GetUserInfo( string account )
{
if ( account == null || account.Length == 0 )
return null;
UserInfo info = m_UserInfo[account] as UserInfo;
if ( info == null )
m_UserInfo[account] = info = new UserInfo( account );
return info;
}
public static readonly object RenderLock = new object();
public static readonly object SaveLock = new object();
public void Save()
{
lock ( SaveLock )
{
string path = Path.Combine( Core.BaseDirectory, "staffHistory.xml" );
PersistanceWriter pw = new XmlPersistanceWriter( path, "Staff" );
pw.WriteDocument( this );
pw.Close();
}
}
public void Load()
{
string path = Path.Combine( Core.BaseDirectory, "staffHistory.xml" );
if ( !File.Exists( path ) )
return;
PersistanceReader pr = new XmlPersistanceReader( path, "Staff" );
pr.ReadDocument( this );
pr.Close();
}
public override void SerializeChildren( PersistanceWriter op )
{
for ( int i = 0; i < m_Pages.Count; ++i )
m_Pages[i].Serialize( op );
for ( int i = 0; i < m_QueueStats.Count; ++i )
m_QueueStats[i].Serialize( op );
}
public override void DeserializeChildren( PersistanceReader ip )
{
DateTime min = DateTime.Now - TimeSpan.FromDays( 8.0 );
while ( ip.HasChild )
{
PersistableObject obj = ip.GetChild();
if ( obj is PageInfo )
{
PageInfo pageInfo = obj as PageInfo;
pageInfo.UpdateResolver();
if ( pageInfo.TimeSent >= min || pageInfo.TimeResolved >= min )
{
m_Pages.Add( pageInfo );
pageInfo.History = this;
}
else
{
pageInfo.Sender = null;
pageInfo.Resolver = null;
}
}
else if ( obj is QueueStatus )
{
QueueStatus queueStatus = obj as QueueStatus;
if ( queueStatus.TimeStamp >= min )
m_QueueStats.Add( queueStatus );
}
}
}
public StaffInfo[] GetStaff()
{
StaffInfo[] staff = new StaffInfo[m_StaffInfo.Count];
int index = 0;
foreach ( StaffInfo staffInfo in m_StaffInfo.Values )
staff[index++] = staffInfo;
return staff;
}
public void Render( ObjectCollection objects )
{
lock ( RenderLock )
{
objects.Add( GraphQueueStatus() );
StaffInfo[] staff = GetStaff();
BaseInfo.SortRange = TimeSpan.FromDays( 7.0 );
Array.Sort( staff );
objects.Add( GraphHourlyPages( m_Pages, PageResolution.None, "New pages by hour", "graph_new_pages_hr" ) );
objects.Add( GraphHourlyPages( m_Pages, PageResolution.Handled, "Handled pages by hour", "graph_handled_pages_hr" ) );
objects.Add( GraphHourlyPages( m_Pages, PageResolution.Deleted, "Deleted pages by hour", "graph_deleted_pages_hr" ) );
objects.Add( GraphHourlyPages( m_Pages, PageResolution.Canceled, "Canceled pages by hour", "graph_canceled_pages_hr" ) );
objects.Add( GraphHourlyPages( m_Pages, PageResolution.Logged, "Logged-out pages by hour", "graph_logged_pages_hr" ) );
BaseInfo.SortRange = TimeSpan.FromDays( 1.0 );
Array.Sort( staff );
objects.Add( ReportTotalPages( staff, TimeSpan.FromDays( 1.0 ), "1 Day" ) );
objects.AddRange( (PersistableObject[])ChartTotalPages( staff, TimeSpan.FromDays( 1.0 ), "1 Day", "graph_daily_pages" ) );
BaseInfo.SortRange = TimeSpan.FromDays( 7.0 );
Array.Sort( staff );
objects.Add( ReportTotalPages( staff, TimeSpan.FromDays( 7.0 ), "1 Week" ) );
objects.AddRange( (PersistableObject[])ChartTotalPages( staff, TimeSpan.FromDays( 7.0 ), "1 Week", "graph_weekly_pages" ) );
BaseInfo.SortRange = TimeSpan.FromDays( 30.0 );
Array.Sort( staff );
objects.Add( ReportTotalPages( staff, TimeSpan.FromDays( 30.0 ), "1 Month" ) );
objects.AddRange( (PersistableObject[])ChartTotalPages( staff, TimeSpan.FromDays( 30.0 ), "1 Month", "graph_monthly_pages" ) );
for ( int i = 0; i < staff.Length; ++i )
objects.Add( GraphHourlyPages( staff[i] ) );
}
}
public static int GetPageCount( StaffInfo staff, DateTime min, DateTime max )
{
return GetPageCount( staff.Pages, PageResolution.Handled, min, max );
}
public static int GetPageCount( PageInfoCollection pages, PageResolution res, DateTime min, DateTime max )
{
int count = 0;
for ( int i = 0; i < pages.Count; ++i )
{
if ( res != PageResolution.None && pages[i].Resolution != res )
continue;
DateTime ts = pages[i].TimeResolved;
if ( ts >= min && ts < max )
++count;
}
return count;
}
private BarGraph GraphQueueStatus()
{
int[] totals = new int[24];
int[] counts = new int[24];
DateTime max = DateTime.Now;
DateTime min = max - TimeSpan.FromDays( 7.0 );
for ( int i = 0; i < m_QueueStats.Count; ++i )
{
DateTime ts = m_QueueStats[i].TimeStamp;
if ( ts >= min && ts < max )
{
DateTime date = ts.Date;
TimeSpan time = ts.TimeOfDay;
int hour = time.Hours;
totals[hour] += m_QueueStats[i].Count;
counts[hour]++;
}
}
BarGraph barGraph = new BarGraph( "Average pages in queue", "graph_pagequeue_avg", 10, "Time", "Pages", BarGraphRenderMode.Lines );
barGraph.FontSize = 6;
for ( int i = 7; i <= totals.Length+7; ++i )
{
int val;
if ( counts[i%totals.Length] == 0 )
val = 0;
else
val = (totals[i%totals.Length] + (counts[i%totals.Length] / 2)) / counts[i%totals.Length];
int realHours = i%totals.Length;
int hours;
if ( realHours == 0 )
hours = 12;
else if ( realHours > 12 )
hours = realHours - 12;
else
hours = realHours;
barGraph.Items.Add( hours + (realHours >= 12 ? " PM" : " AM"), val );
}
return barGraph;
}
private BarGraph GraphHourlyPages( StaffInfo staff )
{
return GraphHourlyPages( staff.Pages, PageResolution.Handled, "Average pages handled by " + staff.Display, "graphs_" + staff.Account.ToLower() + "_avg" );
}
private BarGraph GraphHourlyPages( PageInfoCollection pages, PageResolution res, string title, string fname )
{
int[] totals = new int[24];
int[] counts = new int[24];
DateTime[] dates = new DateTime[24];
DateTime max = DateTime.Now;
DateTime min = max - TimeSpan.FromDays( 7.0 );
bool sentStamp = ( res == PageResolution.None );
for ( int i = 0; i < pages.Count; ++i )
{
if ( res != PageResolution.None && pages[i].Resolution != res )
continue;
DateTime ts = ( sentStamp ? pages[i].TimeSent : pages[i].TimeResolved );
if ( ts >= min && ts < max )
{
DateTime date = ts.Date;
TimeSpan time = ts.TimeOfDay;
int hour = time.Hours;
totals[hour]++;
if ( dates[hour] != date )
{
counts[hour]++;
dates[hour] = date;
}
}
}
BarGraph barGraph = new BarGraph( title, fname, 10, "Time", "Pages", BarGraphRenderMode.Lines );
barGraph.FontSize = 6;
for ( int i = 7; i <= totals.Length+7; ++i )
{
int val;
if ( counts[i%totals.Length] == 0 )
val = 0;
else
val = (totals[i%totals.Length] + (counts[i%totals.Length] / 2)) / counts[i%totals.Length];
int realHours = i%totals.Length;
int hours;
if ( realHours == 0 )
hours = 12;
else if ( realHours > 12 )
hours = realHours - 12;
else
hours = realHours;
barGraph.Items.Add( hours + (realHours >= 12 ? " PM" : " AM"), val );
}
return barGraph;
}
private Report ReportTotalPages( StaffInfo[] staff, TimeSpan ts, string title )
{
DateTime max = DateTime.Now;
DateTime min = max - ts;
Report report = new Report( title + " Staff Report", "400" );
report.Columns.Add( "65%", "left", "Staff Name" );
report.Columns.Add( "35%", "center", "Page Count" );
for ( int i = 0; i < staff.Length; ++i )
report.Items.Add( staff[i].Display, GetPageCount( staff[i], min, max ) );
return report;
}
private PieChart[] ChartTotalPages( StaffInfo[] staff, TimeSpan ts, string title, string fname )
{
DateTime max = DateTime.Now;
DateTime min = max - ts;
PieChart staffChart = new PieChart( title + " Staff Chart", fname + "_staff", true );
int other = 0;
for ( int i = 0; i < staff.Length; ++i )
{
int count = GetPageCount( staff[i], min, max );
if ( i < 12 && count > 0 )
staffChart.Items.Add( staff[i].Display, count );
else
other += count;
}
if ( other > 0 )
staffChart.Items.Add( "Other", other );
PieChart resChart = new PieChart( title + " Resolutions", fname + "_resol", true );
int countTotal = GetPageCount( m_Pages, PageResolution.None, min, max );
int countHandled = GetPageCount( m_Pages, PageResolution.Handled, min, max );
int countDeleted = GetPageCount( m_Pages, PageResolution.Deleted, min, max );
int countCanceled = GetPageCount( m_Pages, PageResolution.Canceled, min, max );
int countLogged = GetPageCount( m_Pages, PageResolution.Logged, min, max );
int countUnres = countTotal - ( countHandled + countDeleted + countCanceled + countLogged );
resChart.Items.Add( "Handled", countHandled );
resChart.Items.Add( "Deleted", countDeleted );
resChart.Items.Add( "Canceled", countCanceled );
resChart.Items.Add( "Logged Out", countLogged );
resChart.Items.Add( "Unresolved", countUnres );
return new PieChart[]{ staffChart, resChart };
}
}
}