Click here to Skip to main content
15,884,739 members
Articles / Desktop Programming / Windows Forms

Reputationator - CP Narcissists Rejoice! Part 1 of 4

Rate me:
Please Sign up or sign in to vote.
4.93/5 (35 votes)
30 Aug 2011CPOL22 min read 58.6K   882   41  
Keep more detailed track of your Codeproject reputation points.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;

namespace ReputationLib
{
	public class DisplayCategories : List<RepCategory> 
	{
		public RepCategory Category { get; set; }
	}

	public class RepItemCollection : List<RepItem>
	{
		private const int MAX_DAYS = 365;

		private int UserID = Globals.UserID;

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Constructor
		/// </summary>
		public RepItemCollection()
		{
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Retrieves existing data from the database.
		/// </summary>
		/// <param name="query"></param>
		/// <returns></returns>
		public bool GetData()
		{
			if (Globals.UserID <= 0)
			{
				throw new Exception("Codeproject UserID not specified.");
			}
			if (string.IsNullOrEmpty(Globals.ConnectionString))
			{
				throw new Exception("Connection string not specified.");
			}

			bool          result  = false;
			SqlConnection conn    = null;
			SqlCommand    cmd     = null;
			SqlDataReader reader  = null;
			DataTable     data    = new DataTable();
			DateTime      thePast = DateTime.Now.AddYears(-1);
			try
			{
				conn            = new SqlConnection(Globals.ConnectionString);
				cmd             = new SqlCommand("GetData", conn);
				cmd.CommandType = System.Data.CommandType.StoredProcedure;
				cmd.Parameters.AddWithValue("@user", Globals.UserID);
				cmd.Parameters.AddWithValue("@date", thePast);
				conn.Open();
				reader          = cmd.ExecuteReader();
				if (reader != null && reader.HasRows)
				{
					data.Load(reader);
					PopulateList(data);
					result = true;
				}
			}
			catch (Exception ex)
			{
				if (ex != null) {}
			}
			finally
			{
				if (conn != null)
				{
					conn.Close();
				}
			}
			return result;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Adds or updates a record to the list. This is so that the user can scrape manually 
		/// multiple times during the day and still update the database with the most recent 
		/// values.
		/// </summary>
		/// <param name="cat"></param>
		/// <param name="date"></param>
		/// <param name="user"></param>
		/// <param name="points"></param>
		public void AddOrUpdate(RepCategory cat, DateTime date, int user, int points)
		{
			int change = 0;
			List<RepItem> items = null;
			// We're looking for an item with the current category ID, for the user, on the 
			// specified date. We should have only one
			items = (from item in this
					 where (item.Category == cat && item.CPUserID == user)
					 select item).ToList();
			RepItem lastItem = null;
			if (items.Count > 0)
			{
				lastItem = (from item in items
							where (item.Category == cat && item.CPUserID == user && item.TimeScraped.Date == date.Date)
							select item).LastOrDefault();
			}

			// 16Aug2011 - jms - updating/adding from a manual scraping event was 
			// incorrectly adding a new item. to the collection (the database update 
			// was happening correctly).

			// if we found no matching items, we add a new one 
			if (lastItem == null)
			{
				if (items.Count > 0)
				{
					lastItem = (from item in items
								where (item.Category == cat && item.CPUserID == user)
								select item).LastOrDefault();
					if (lastItem != null)
					{
						change = points - lastItem.Value;
					}
				}
				this.Add(new RepItem() 
				{
					Category    = cat,
					CPUserID    = user,
					TimeScraped = date,
					Value       = points,
					ChangeValue = change
				});
			}
			else
			// otherwise we decide how to modify the item we found
			{
				// set its value
				lastItem.Value   = points;
				if (items.Count > 1)
				{
					// set the changed value
					RepItem prevItem = items[items.Count - 2];
					change = points - prevItem.Value;
				}
				lastItem.ChangeValue = change;
			}

		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Updates the database with the most recently scraped data
		/// </summary>
		public void UpdateDatabase(int mode = 0)
		{
			RemoveExpiredData();

			SqlConnection conn        = null;
			SqlCommand    cmd         = null;
			string        query       = "";
			int           records     = 0;
			DateTime      now         = DateTime.Now.Date;

			// get all of todays records
			List<RepItem> items;
			int total = 0;
			switch (mode)
			{
				default : // just the most recent data (mode 0)
					items = (from item in this
							 where item.TimeScraped == now && item.CPUserID == Globals.UserID
							 select item).ToList();
					// sum the categories (except the RepCategory.Total)
					total = items.Sum(item => (item.Category != RepCategory.Total) ? item.Value : 0);
					break;

				case 1 : // db1 Total adjustment
					items = (from item in this
							 where item.Category == RepCategory.Total && item.CPUserID == Globals.UserID
							 select item).ToList();
					break;
			}

			foreach(RepItem item in items)
			{
				// In mode 0, we only have the most recently scraped data, so we need 
				// to adjust our total to account for the caching issue on 
				// Codeproject.
				if (mode == 0 && item.Category == RepCategory.Total)
				{
				    item.Value = total;
				}
				query = "AddOrUpdate";
				try
				{
					if (conn == null)
					{
						conn = new SqlConnection(Globals.ConnectionString);
					}
					if (cmd == null)
					{
						cmd             = new SqlCommand(query, conn);
						cmd.CommandType = System.Data.CommandType.StoredProcedure;
						cmd.Parameters.Add("@user",     SqlDbType.Int);
						cmd.Parameters.Add("@date",     SqlDbType.DateTime);
						cmd.Parameters.Add("@category", SqlDbType.Int);
						cmd.Parameters.Add("@points",   SqlDbType.Int);
					}
					cmd.CommandText = query;
					cmd.Parameters["@user"].Value     = item.CPUserID;
					cmd.Parameters["@date"].Value     = item.TimeScraped;
					cmd.Parameters["@category"].Value = (int)(item.Category);
					cmd.Parameters["@points"].Value   = item.Value;
					if (conn.State == System.Data.ConnectionState.Closed)
					{
						conn.Open();
					}
					records = cmd.ExecuteNonQuery();
					if (records != 1)
					{
					    throw new Exception("Insert did not succeed");
					}				}
				catch (Exception ex)
				{
					if (ex != null) {}
				}
			}
			if (conn != null && conn.State == System.Data.ConnectionState.Open)
			{
				conn.Close();
			}
		}


		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Populates the colection with rata retrieved from the database.
		/// </summary>
		/// <param name="data"></param>
		private void PopulateList(DataTable data)
		{
			foreach (DataRow row in data.Rows)
			{
				int value = Convert.ToInt32(row["PointValue"]);
				RepItem item = new RepItem()
				{
					Category    = Globals.IntToEnum (Convert.ToInt32(row["Category"]), RepCategory.Unknown),
					TimeScraped = Convert.ToDateTime(row["ScrapeDate"]),
					Value       = value,
					CPUserID    = Convert.ToInt32   (row["CPUserID"]),
					ChangeValue = 0
				};
				this.Add(item);
			}
			// add missing days
			FillDataHoles();

			// If true, the repcollection class will adjust all values for category Total 
			// to the actual sum of the sub-categories. This will account for CodeProject 
			// caching issues  discovered on 19Aug2011. The only way this can be true is 
			// if the user runs the app with the "/db1" parameter. This only needs to be 
			// done one time.
			if (Globals.AdjustExistingDbTotals)
			{
				NormalizeTotalCategory();
				Globals.AdjustExistingDbTotals = false;
			}

			// calculate the amount changed for each item from the previous day
			CalcChangedValues();
		}

		//--------------------------------------------------------------------------------------
		// I found that sometimes, the sub-ategories don't add up to the actual toital reported 
		// on CodeProject.  Even when I was checking it by hand by adding up what was currently 
		// on the web site, the total showed 20 points more than the sum of the categories. This 
		// is probably a caching problem on the part of CodeProject, so I had to write this 
		// method to account for it.  Once confirmed, I decided that I would simply check the 
		// sum just before I add it to the database.
		/// <summary>
		/// Ensures the the Total category item is actully the sum of all of the sub-categories.
		/// </summary>
		public void NormalizeTotalCategory()
		{
			int adjusted = 0;
			if (this.Count > 0)
			{
				DateTime startDate = this.First().TimeScraped;
				DateTime endDate   = this.Last().TimeScraped;

				List<RepItem> list = null;
				do
				{
					if (startDate.Date == endDate.Date)
					{
						int x = 0;
						x++;
					}
					list = (from item in this 
							where item.TimeScraped.Date == startDate.Date && item.CPUserID == Globals.UserID && item.Category != RepCategory.Total 
							select item).ToList();
					if (list.Count > 0)
					{
						RepItem totalItem = (from item in this 
											 where item.TimeScraped.Date == startDate.Date && item.CPUserID == Globals.UserID && item.Category == RepCategory.Total 
											 select item).FirstOrDefault();
						if (totalItem != null)
						{
							int total = list.Sum((item) => item.Value);
							if (total != totalItem.Value)
							{
								adjusted++;
							}
							totalItem.Value = total;
						}
					}
					startDate = startDate.AddDays(1);
				} while (startDate.Date <= endDate.Date);
			}
			// if we adjusted any totals, update the database with a mode of 1 to save just 
			// those adjusted totals
			if (adjusted > 0)
			{
				UpdateDatabase(1);
			}
		}

		//--------------------------------------------------------------------------------------
		public void CalcChangedValues()
		{
			foreach(RepCategory cat in Enum.GetValues(typeof(RepCategory)))
			{
				if (cat != RepCategory.Unknown)
				{
					List<RepItem> list = (from item in this 
										  where item.Category == cat
										  select item).ToList();
					for (int i = 1; i < list.Count; i++)
					{
						if (i == list.Count - 1)
						{
							int x = 5;
							x++;
						}
						list[i].ChangeValue = list[i].Value - list[i-1].Value;
					}
				}
			}
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Fills in missing data by interpolating a value for a missing date.
		/// </summary>
		private void FillDataHoles()
		{
			bool needSorting = false;
			foreach(RepCategory cat in Enum.GetValues(typeof(RepCategory)))
			{
				if (cat != RepCategory.Unknown)
				{
					List<RepItem> list = (from item in this 
										  where item.Category == cat
										  select item).ToList();
					if (list.Count > 1)
					{
						for (int i = 1; i < list.Count; i++)
						{
							if (i == 19)
							{
							}
							RepItem currItem = list[i];
							RepItem prevItem = list[i-1];
							TimeSpan span = currItem.TimeScraped.Date - prevItem.TimeScraped.Date;
							if (span.Days > 1)
							{
								needSorting = true;
								int value = prevItem.Value + (int)(Math.Ceiling((double)(currItem.Value - prevItem.Value) / 2));
								this.Add(new RepItem(){ Category    = cat,
														TimeScraped = currItem.TimeScraped.AddDays(-1),
														CPUserID    = currItem.CPUserID,
														Value       = value,
														ChangeValue = 0 });
							}
						}
					}
				}
			}
			if (needSorting)
			{
				this.Sort(new GenericComparer<RepItem>(new string[]{"TimeScraped", "Category"}, GenericSortOrder.Ascending));
			}
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Removes data that's more than a year old from the collection (but leaves the data 
		/// in the database if you want to retrieve it later with code that *you* add.
		/// </summary>
		private void RemoveExpiredData()
		{
			// get todays date just one time
			DateTime now = DateTime.Now.Date;
			// find all rcords that need to be deleted
			var x = (from item in this
					 where TimeSpan.FromTicks(now.Ticks - item.TimeScraped.Ticks).Days > MAX_DAYS
					 select item);
			// Delete the items. NOTE: this only deletes them from the list in memory, NOT 
			// the database itself.
			foreach(RepItem item in x)
			{
				this.Remove(item);
			}
		}

		#region "Getxxxx"
		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Retrieves all repitem objects that are between the specified dates (inclusive) 
		/// and that are of the appropriate category.
		/// </summary>
		/// <param name="dateStart"></param>
		/// <param name="dateEnd"></param>
		/// <param name="categories"></param>
		/// <returns></returns>
		private List<RepItem> GetItemsByDateAndCategory(DateTime dateStart, DateTime dateEnd, DisplayCategories categories)
		{
			// Retrieve the items that have a category that exists in the list of specified 
			// categories 
			List<RepItem> list = (from item in this 
								  from cat in categories
								  where (item.Category == cat && item.TimeScraped.Between(dateStart, dateEnd, true))
								  select item).ToList();
			return list;
		}


		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the highest value in all of the items in the collection that are of the 
		/// specified category
		/// </summary>
		/// <param name="list"></param>
		/// <returns></returns>
		public int GetHighestDailyValue(List<RepItem> list)
		{
			int value = list.Max((item) => item.Value);
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the highest value in all of the items in the collection between the 
		/// specified dates
		/// </summary>
		/// <returns></returns>
		public int GetHighestDailyValue(DateTime dateStart, DateTime dateEnd, DisplayCategories categories)
		{
			int value = 0;
			foreach (int i in Enum.GetValues(typeof(RepCategory)))
			{
				RepCategory category = Globals.IntToEnum(i, RepCategory.Unknown);
				if (category == RepCategory.Unknown)
				{
					continue;
				}
				List<RepItem> list = GetItemsByDateAndCategory(dateStart, dateEnd, categories);
				if (list != null)
				{
					value = GetHighestDailyValue(list);
				}
			}
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the highest value in all of the items in the collection
		/// </summary>
		/// <returns></returns>
		public int GetHighestDailyValue(DisplayCategories categories)
		{
			DateTime dateStart = new DateTime(0).Date;
			DateTime dateEnd = DateTime.Now.Date;
			return GetHighestDailyValue(dateStart, dateEnd, categories);
		}

		//--------------------------------------------------------------------------------------
		public int GetLowestDailyValue(List<RepItem> list)
		{
			int value = list.Min((item) => item.Value);
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the highest value in all of the items
		/// </summary>
		/// <returns></returns>
		public int GetLowestDailyValue(DateTime dateStart, DateTime dateEnd, DisplayCategories categories)
		{
			int value = 0;
			foreach (int i in Enum.GetValues(typeof(RepCategory)))
			{
				RepCategory category = Globals.IntToEnum(i, RepCategory.Unknown);
				if (category == RepCategory.Unknown)
				{
					continue;
				}
				List<RepItem> list = GetItemsByDateAndCategory(dateStart, dateEnd, categories);
				if (list != null)
				{
					value = GetLowestDailyValue(list);
				}
			}
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the highest value in all of the items
		/// </summary>
		/// <returns></returns>
		public int GetLowestDailyValue(DisplayCategories categories)
		{
			DateTime dateStart = new DateTime(0).Date;
			DateTime dateEnd   = new DateTime(0).Date;
			return GetLowestDailyValue(dateStart, dateEnd, categories);
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the lowest value in all of the items in the collection that are of the 
		/// specified category
		/// </summary>
		/// <param name="list"></param>
		/// <returns></returns>
		public int GetHighestDailyChangeValue(List<RepItem> list)
		{
			int value = list.Max((item) => item.ChangeValue);
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the highest value in all of the items in the collection between the 
		/// specified dates
		/// </summary>
		/// <returns></returns>
		public int GetHighestDailyChangeValue(DateTime dateStart, DateTime dateEnd, DisplayCategories categories)
		{
			int value = 0;
			foreach (int i in Enum.GetValues(typeof(RepCategory)))
			{
				RepCategory category = Globals.IntToEnum(i, RepCategory.Unknown);
				if (category == RepCategory.Unknown)
				{
					continue;
				}
				List<RepItem> list = GetItemsByDateAndCategory(dateStart, dateEnd, categories);
				if (list != null)
				{
					value = GetHighestDailyChangeValue(list);
				}
			}
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the highest value in all of the items in the collection
		/// </summary>
		/// <returns></returns>
		public int GetHighestDailyChangeValue(DisplayCategories categories)
		{
			DateTime dateStart = new DateTime(0).Date;
			DateTime dateEnd = DateTime.Now.Date;
			return GetHighestDailyChangeValue(dateStart, dateEnd, categories);
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the lowest changed value in all of the items
		/// </summary>
		/// <param name="list"></param>
		/// <returns></returns>
		public int GetLowestDailyChangeValue(List<RepItem> list)
		{
			int value = list.Min((item) => item.ChangeValue);
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the lowest changed value in all of the items
		/// </summary>
		/// <returns></returns>
		public int GetLowestDailyChangeValue(DateTime dateStart, DateTime dateEnd, DisplayCategories categories)
		{
			int value = 0;
			foreach (int i in Enum.GetValues(typeof(RepCategory)))
			{
				RepCategory category = Globals.IntToEnum(i, RepCategory.Unknown);
				if (category == RepCategory.Unknown)
				{
					continue;
				}
				List<RepItem> list = GetItemsByDateAndCategory(dateStart, dateEnd, categories);
				if (list != null)
				{
					value = GetLowestDailyChangeValue(list);
				}
			}
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Calculates the lowest changed value in all of the items
		/// </summary>
		/// <returns></returns>
		public int GetLowestDailyChangeValue(DisplayCategories categories)
		{
			DateTime dateStart = new DateTime(0).Date;
			DateTime dateEnd   = new DateTime(0).Date;
			return GetLowestDailyChangeValue(dateStart, dateEnd, categories);
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Get the most recent points value for the specified category
		/// </summary>
		/// <param name="category"></param>
		/// <returns></returns>
		public int GetLatestPointValue(RepCategory category)
		{
			int value = 0;
			var repItem = (from item in this
						  where item.Category == category
						  select item).LastOrDefault();
			if (repItem != null)
			{
				value = repItem.Value;
			}
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the daily average points earned for the specified category
		/// </summary>
		/// <param name="category"></param>
		/// <returns></returns>
		public int GetDailyAverage(RepCategory category)
		{
			int           value       = 0;
			double        total       = 0;
			DateTime      now         = DateTime.Now.Date;
			DateTime      periodStart = now.AddDays(-((int)RepPeriod.Year));
			List<RepItem> list        = (from item in this
										 where item.Category == category && item.TimeScraped.Between(periodStart, now, true)
										 select item).ToList();
			foreach (RepItem item in list)
			{
				total += item.ChangeValue;
			}
			value = (int)(Math.Ceiling(total / list.Count));
			return value;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Determines the start date based on the specified reputation period.
		/// </summary>
		/// <param name="period"></param>
		/// <returns></returns>
		public DateTime GetPeriodStart(RepPeriod period)
		{
			DateTime periodStart = DateTime.Now.Date;
			switch (period)
			{
			    // for the entire week, starting on the first day of the week
			    case RepPeriod.Week : 
			        periodStart = periodStart.WeekStartDate();
			        break;
			    // for the current month, beginning on the 1st
			    case RepPeriod.Month :
			        periodStart = periodStart.AddDays(-(periodStart.Day - 1));
			        break;
			    // for the current year, starting on 01 Jan
			    case RepPeriod.Year :
			        periodStart = periodStart.AddDays(-(periodStart.DayOfYear - 1));
			        break;
			}
			return periodStart;
		}

		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the total points for the specified fiscal period.
		/// </summary>
		/// <param name="period"></param>
		/// <param name="category"></param>
		/// <returns></returns>
		public int GetCurrentPeriodPoints(RepPeriod period, RepCategory category)
		{
			int value            = 0;
			DateTime now         = DateTime.Now.Date;
			DateTime periodStart = GetPeriodStart(period);
			List<RepItem> list   = (from item in this
									where item.Category == category && item.TimeScraped.Between(periodStart, now, true)
									select item).ToList();
			foreach (RepItem item in list)
			{
				value += item.ChangeValue;
			}
			return value;
		}
	
		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the total points for the specified fiscal period.
		/// </summary>
		/// <param name="period"></param>
		/// <param name="category"></param>
		/// <returns></returns>
		public void GetCurrentPeriodPoints(RepPeriod period, RepCategory category, out int value, out int projected)
		{
			value     = 0;
			projected = 0;

			DateTime now         = DateTime.Now.Date;
			DateTime periodStart = GetPeriodStart(period);
			value                = GetCurrentPeriodPoints(period, category);
			int avg              = GetDailyAverage(RepCategory.Total);
			projected            = value;
			TimeSpan span        = now - periodStart;

			if (span.Days <= (int)period)
			{
				int daysLeft = (int)period - span.Days;
				projected = value + (daysLeft * avg);
			}
		}
	
		//--------------------------------------------------------------------------------------
		/// <summary>
		/// Gets the points for the last specified period (regardles of period starting 
		/// date). A week is 7 days, a month is 30, and a year is 365. No attempts are 
		/// made to account for leap years or months that don't have 30 days in them.
		/// </summary>
		/// <param name="period"></param>
		/// <param name="category"></param>
		/// <returns></returns>
		public int GetLastPeriodPoints(RepPeriod period, RepCategory category)
		{
			int value = 0;
			DateTime now = DateTime.Now.Date;
			DateTime periodStart = DateTime.Now.Date.AddDays(-((int)period));
			List<RepItem> list = (from item in this
								  where item.Category == category && item.TimeScraped.Between(periodStart, now, true)
								  select item).ToList();
			foreach (RepItem item in list)
			{
				value += item.ChangeValue;
			}
			return value;
		}
		#endregion "Getxxxx"

		/// <summary>
		/// Use this method to artificially populate the reputation scores - useful if you 
		/// want to see how the program reacts with various amounts of data.
		/// </summary>
		/// <param name="startDate"></param>
		/// <param name="user"></param>
		public void TestFill(DateTime startDate, int user)
		{
			Random random = new Random(DateTime.Now.Millisecond);
			random.Next(1, 1000);
			Clear();
			int[] points = new int[]{0,0,0,0,0,0,0,0,0};
			DateTime now = DateTime.Now.Date;
			TimeSpan span = now - startDate.Date;
			int minRandom = 0;
			int maxRandom = 1000;
			int total     = 0;

			for (int i = 0; i < span.TotalDays; i++)
			{
				total = 0;
				foreach (int j in Enum.GetValues(typeof(RepCategory)))
				{
					RepCategory category = Globals.IntToEnum(j, RepCategory.Unknown);
					if (j > 0)
					{
						switch (category)
						{
							case RepCategory.Author :
								minRandom = 10;
								maxRandom = 100;
								break;
							case RepCategory.Authority:
								minRandom = 200;
								maxRandom = 600;
								break;
							case RepCategory.Debator:
								minRandom = 100;
								maxRandom = 500;
								break;
							case RepCategory.Editor:
								minRandom = 0;
								maxRandom = 25;
								break;
							case RepCategory.Enquirer:
								minRandom = 0;
								maxRandom = 1;
								break;
							case RepCategory.Organiser:
								minRandom = 0;
								maxRandom = 125;
								break;
							case RepCategory.Participant:
								minRandom = 1;
								maxRandom = 25;
								break;
							case RepCategory.Total :
								minRandom = 0;
								maxRandom = 0;
								break;
						}
						if (category != RepCategory.Total)
						{
							points[j] += random.Next(minRandom, maxRandom);
							total += points[j];
						}
						else
						{
							points[j] = total;
						}
						AddOrUpdate(category, startDate, user, points[j]);
					}
				}
				startDate = startDate.AddDays(1);

			}

			CalcChangedValues();

			int totalPoints = GetLatestPointValue(RepCategory.Total);
		}
	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Paddedwall Software
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions