public DateTime CalculateLowerCutoffTime(Goal goal, decimal oldCurrentLevel, DateTime previousDoneItTime) { var hourdecr = GoalProcessor.GetHourlyDecreaseRate(goal); var lowerCutoff = goal.GetLowerCutoff(); var hours = (oldCurrentLevel - lowerCutoff) / hourdecr; return previousDoneItTime.AddHours(Math.Abs(Convert.ToDouble(hours))); }
public void it_should_calculate_correct_hours_left_to_zero() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { Amount = 7, IntervalType = IntervalType.Weekly }; // Week goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 7.01M, Date = now.AddDays(-7) } }; var vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.OnTrack, vm.Status); goal.DoneIts = new List<DoneIt>(){ new DoneIt() { Amount = 6.99M, Date = now.AddDays(-7) }}; vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.Behind, vm.Status); // Hour goal = new Goal() { Amount = 24, IntervalType = IntervalType.Dayly }; goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 24.01M, Date = now.AddDays(-1) } }; vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.OnTrack, vm.Status); goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 23.99M, Date = now.AddDays(-1) } }; vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.Behind, vm.Status); // Month goal = new Goal() { Amount = 3, IntervalType = IntervalType.Monthly }; goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 3.01M, Date = now.AddDays(-30) } }; vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.OnTrack, vm.Status); goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 2.99M, Date = now.AddDays(-30) } }; vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.Behind, vm.Status); }
public void it_should_build_a_flat_zero_line_if_no_donits() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { IntervalType = IntervalType.Weekly }; var vm= target.ProcessGoal(goal); Assert.AreEqual(vm.Graph.Points.Count, 2); }
public void it_should_set_value_of_first_point_to_the_amount_the_first_doneit() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { Amount = 7, IntervalType = IntervalType.Weekly }; goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 10, Date = now.AddDays(-2) } }; var vm = target.ProcessGoal(goal); Assert.AreEqual(10, vm.Graph.Points.Where(p => p.Time == now.AddDays(-2).AddSeconds(1)).FirstOrDefault().Amount); }
public ActionResult Create(Goal goal) { goal.UserName = User.Identity.Name; if (ModelState.IsValid) { db.Goals.Add(goal); db.SaveChanges(); return RedirectToAction("Index"); } return View(goal); }
public void it_should_calcualte_cutofftime_correct() { var now = DateTime.Now; var firstDoneit = new DateTime(2012, 5, 27); var target = new GoalProcessor(now); var goal = new Goal() { Amount = 1, IntervalType = IntervalType.Dayly }; var calculated = target.CalculateLowerCutoffTime(goal, 1, firstDoneit); AssertTimesAreAlmostEqual(firstDoneit.AddDays(3), calculated); calculated = target.CalculateLowerCutoffTime(goal, 0, now); AssertTimesAreAlmostEqual(now.AddDays(2), calculated); calculated = target.CalculateLowerCutoffTime(goal, 1M, now.AddDays(-10)); AssertTimesAreAlmostEqual(now.AddDays(-7), calculated); }
public void it_should_increase_hours_left_when_adding_a_new_doneit() { var now = DateTime.Now; var target = new GoalProcessor(now); // Week var goal = new Goal() { Amount = 7, IntervalType = IntervalType.Weekly }; goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 3.01M, Date = now.AddDays(-7) } }; goal.DoneIts.Add(new DoneIt() { Amount = 3, Date = now.AddDays(-4) } ); goal.DoneIts.Add(new DoneIt() { Amount = 1, Date = now.AddDays(-1) }); var vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.OnTrack, vm.Status); goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 2.9M, Date = now.AddDays(-7) } }; goal.DoneIts.Add(new DoneIt() { Amount = 3, Date = now.AddDays(-4) }); goal.DoneIts.Add(new DoneIt() { Amount = 1, Date = now.AddDays(-1) }); vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.Behind, vm.Status); }
public static decimal GetHourlyDecreaseRate(Goal goal) { decimal perHour = 0; switch (goal.IntervalType) { case IntervalType.Dayly: perHour = (decimal)goal.Amount / 24; break; case IntervalType.Weekly: // Number per hour perHour = (decimal)goal.Amount / (7 * 24); break; case IntervalType.Monthly: perHour = (decimal)goal.Amount / (30 * 24); break; default: new NotSupportedException(); break; } return perHour; }
public void it_should_show_a_stright_line_when_in_cutoff() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { Amount = 7, IntervalType = IntervalType.Weekly }; // Simple one entry // -28,7 // -21,0 // -14,-7 // -7, -14 // -6, -14 (cutoff) // 0, -14 (cutoff) goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 7, Date = now.AddDays(-28) } , new DoneIt() { Amount = 0, Date = now.AddDays(-21) } , new DoneIt() { Amount = 0, Date = now.AddDays(-14) } , new DoneIt() { Amount = 0, Date = now.AddDays(-7) } , }; var vm = target.ProcessGoal(goal); // 1: 7 AssertPointOnGraph(vm, 0, 0, now.AddDays(-28)); AssertPointOnGraph(vm, 1, 7, now.AddDays(-28)); // 2: 0 AssertPointOnGraph(vm, 2, 0, now.AddDays(-21)); AssertPointOnGraph(vm, 3, 0, now.AddDays(-21)); // 3: 0 AssertPointOnGraph(vm, 4, -7, now.AddDays(-14)); AssertPointOnGraph(vm, 5, -7, now.AddDays(-14)); // 4: 0 AssertPointOnGraph(vm, 6, -14, now.AddDays(-7)); AssertPointOnGraph(vm, 7, -14, now.AddDays(-7)); // Cutoff AssertPointOnGraph(vm, 8, -14, now.AddDays(-7)); // Cutoff AssertPointOnGraph(vm, 9, -14, now.AddDays(-7)); // Final AssertPointOnGraph(vm, 10, -14, now.AddDays(0)); }
public static DateTime GetDateOfLastOrFirstGraphPoint(bool isFirst, Goal goal, DateTime now) { if (isFirst) { return now.AddMonths(-4); } return now; var a = isFirst ? -1 : 1; if (goal.EvaluationType == GoalEvaluation.Countinious) { switch (goal.IntervalType) { case IntervalType.Dayly: return now.AddDays(2*a); case IntervalType.Weekly: return now.AddDays(7*a); case IntervalType.Monthly: return now.AddMonths(1*a); default: throw new ApplicationException("Unknown Intervaltype"); } } else { if (isFirst) { return goal.StartDate.HasValue ? goal.StartDate.Value : now.AddDays(-10); } else { return goal.EndDate.HasValue ? goal.EndDate.Value : now.AddDays(10); } } }
public static GraphViewModel CreateEmptyGraph(Goal goal, DateTime now) { var vm = new GraphViewModel(); if (goal.EvaluationType == GoalEvaluation.Countinious) { var p1 = new GraphPoint { Amount = 0 }; var p2 = new GraphPoint { Amount = 0 }; switch (goal.IntervalType) { case IntervalType.Dayly: p1.Time = now.AddDays(-2); p2.Time = now.AddDays(2); break; case IntervalType.Weekly: p1.Time = now.AddDays(-14); p2.Time = now.AddDays(7); break; case IntervalType.Monthly: p1.Time = now.AddMonths(-2); p2.Time = now.AddMonths(1); break; default: break; } vm.Points = new List<GraphPoint> { p1, p2 }; } else { var p1 = new GraphPoint { Amount = 0, Time=goal.StartDate.HasValue?goal.StartDate.Value:now }; var p2 = new GraphPoint { Amount = 0 , Time=goal.EndDate.HasValue?goal.EndDate.Value:now}; vm.Points = new List<GraphPoint> { p1, p2 }; } return vm; }
public void it_should_never_go_below_a_configurable_threshold() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { Amount = 7, IntervalType = IntervalType.Weekly }; // Hour goal = new Goal() { Amount = 24, IntervalType = IntervalType.Dayly }; goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 24.01M, Date = now.AddDays(-1) } }; var vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.OnTrack, vm.Status); Assert.IsTrue(Math.Abs(vm.CurrentLevel - 0) < 0.1M); goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 23.99M, Date = now.AddDays(-1) } }; vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.Behind, vm.Status); Assert.IsTrue(Math.Abs(vm.CurrentLevel - 0) < 0.1M); goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 24.01M, Date = now.AddDays(-2) } }; vm = target.ProcessGoal(goal); Assert.IsTrue(Math.Abs(vm.CurrentLevel - -24) < 0.1M); // Hour limited by threshold (2*) goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 24.01M, Date = now.AddDays(-4) } }; vm = target.ProcessGoal(goal); Assert.IsTrue(Math.Abs(vm.CurrentLevel - -48) < 0.1M); }
public GoalViewModel ProcessGoal(Goal goal) { var vm = new GoalViewModel(); vm.Status = GoalStatus.NotStarted; vm.Goal = goal; vm.Graph = new GraphViewModel();// gp.ProcessGraph(goal); //var timeFirstPoint = GraphProcessor.GetDateOfLastOrFirstGraphPoint(true, goal, _now); decimal currentLevel = 0; DateTime? previousDoneItTime = null; decimal perHour = GetHourlyDecreaseRate(goal); var cutoffLevel = goal.GetLowerCutoff(); if (goal.DoneIts.Count > 0) { decimal oldCurrentLevel=0; foreach (var done in goal.DoneIts.OrderBy(d => d.Date)) { oldCurrentLevel = currentLevel; if (previousDoneItTime == null) { // First doneit starts counting currentLevel = done.Amount; vm.Graph.AddPoint(done, oldCurrentLevel, currentLevel); } else { // Calculate current level var dif = (done.Date - (DateTime)previousDoneItTime).TotalHours; oldCurrentLevel = currentLevel - (perHour * Convert.ToDecimal(dif)); if (oldCurrentLevel < cutoffLevel) { // Add extra point at lower threshold var cutoffTime = CalculateLowerCutoffTime(goal, currentLevel, previousDoneItTime.Value); vm.Graph.Points.Add(new GraphPoint { Time = cutoffTime, Amount = 0, y = cutoffLevel }); oldCurrentLevel = cutoffLevel; } currentLevel = oldCurrentLevel + done.Amount; vm.Graph.AddPoint(done, oldCurrentLevel, currentLevel); } previousDoneItTime = done.Date; } // Calculate current level var diff = (_now - (DateTime)previousDoneItTime).TotalHours; currentLevel -= (perHour * Convert.ToDecimal(diff)); // Check for cutoff if (currentLevel < cutoffLevel) { // Add extra point at lower threshold var cutoffTime = CalculateLowerCutoffTime(goal, oldCurrentLevel, previousDoneItTime.Value); vm.Graph.Points.Add(new GraphPoint { Time = cutoffTime, Amount = 0, y = cutoffLevel }); currentLevel = cutoffLevel; vm.Cutoff = CutoffStatus.Active; } // Add current level vm.Graph.Points.Add(new GraphPoint { Time = _now, Amount = 0, y = currentLevel }); vm.Status = currentLevel < 0 ? GoalStatus.Behind : GoalStatus.OnTrack; vm.AtZero = TimeSpan.FromHours(Convert.ToDouble(currentLevel / perHour)); vm.CurrentLevel = currentLevel; } else { vm.Graph = GraphProcessor.CreateEmptyGraph(goal, _now); } var graph = vm.Graph; var first = graph.Points.OrderBy(x => x.Time).First().Time; var last = graph.Points.OrderBy(x => x.Time).Last().Time; var totalSecs = ((last - first).TotalSeconds); if (totalSecs > 0) { foreach (var point in graph.Points) { point.x = Convert.ToDecimal((point.Time - first).TotalSeconds / totalSecs); } } //GraphProcessor.CalculateXPositions(out vm); return vm; }
public void when_no_doneits_it_should_show_status_not_started() { var target = new GoalProcessor(); var goal = new Goal() { Amount = 7, IntervalType = IntervalType.Weekly }; var now = DateTime.Now; var vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.NotStarted, vm.Status); //goal.DoneIts.Add(new DoneIt() { Amount = 1, Date = now.a }
public void when_first_doneit_it_should_start_counting_down() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { Amount = 7, IntervalType = IntervalType.Weekly }; goal.DoneIts.Add(new DoneIt() { Amount = 1, Date = now }); var vm = target.ProcessGoal(goal); Assert.AreEqual(GoalStatus.OnTrack, vm.Status); }
public void it_should_show_a_stright_line_when_in_cutoff2() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { Amount = 1, IntervalType = IntervalType.Dayly }; // Simple one entry // -8,1 goal.DoneIts = new List<DoneIt>() { new DoneIt() { Amount = 1, Date = now.AddDays(-10) } , }; var vm = target.ProcessGoal(goal); // Start 0,1 AssertPointOnGraph(vm, 0, 0, now.AddDays(-10)); AssertPointOnGraph(vm, 1, 1, now.AddDays(-10)); // AssertPointOnGraph(vm, 2, -2, now.AddDays(-8)); AssertPointOnGraph(vm, 3, -2, now); }
public GraphViewModel ProcessGraph(Goal goal) { decimal currentLevel = 0; DateTime? previousDoneItTime = null; decimal perHour = GoalProcessor.GetHourlyDecreaseRate(goal); var gvm = GraphProcessor.CreateEmptyGraph(goal,_now); if (goal.DoneIts.Count > 0) { foreach (var done in goal.DoneIts.OrderBy(d => d.Date)) { if (previousDoneItTime == null) { previousDoneItTime = done.Date; currentLevel = done.Amount; } else { currentLevel += done.Amount; } gvm.Points.Add(new GraphPoint { Amount = done.Amount, Time = done.Date }); } var diff = (_now - (DateTime)previousDoneItTime).TotalHours; currentLevel -= (perHour * Convert.ToDecimal(diff)); //vm.Status = currentLevel < 0 ? GoalStatus.Behind : GoalStatus.OnTrack; //vm.AtZero = TimeSpan.FromHours(Convert.ToDouble(currentLevel / perHour)); //vm.CurrentLevel = currentLevel; } return gvm; }
public ActionResult Edit(Goal goal) { goal.UserName = User.Identity.Name; if (ModelState.IsValid) { db.Entry(goal).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(goal); }
public void it_should_start_one_interval_before_and_end_one_interval_after_if_interval() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { EvaluationType = GoalEvaluation.Countinious, IntervalType = IntervalType.Weekly }; var vm = target.ProcessGoal(goal); Assert.AreEqual(vm.Graph.Points[0].Time, now.AddDays(-14)); Assert.AreEqual(vm.Graph.Points[1].Time, now.AddDays(7)); Assert.AreEqual(0, vm.Graph.Points[0].Amount); Assert.AreEqual(0, vm.Graph.Points[1].Amount); goal = new Goal() { EvaluationType = GoalEvaluation.Countinious, IntervalType = IntervalType.Monthly }; vm = target.ProcessGoal(goal); Assert.AreEqual(vm.Graph.Points[0].Time, now.AddMonths(-2)); Assert.AreEqual(vm.Graph.Points[1].Time, now.AddMonths(1)); goal = new Goal() { EvaluationType = GoalEvaluation.Countinious, IntervalType = IntervalType.Dayly }; vm = target.ProcessGoal(goal); Assert.AreEqual(vm.Graph.Points[0].Time, now.AddDays(-2)); Assert.AreEqual(vm.Graph.Points[1].Time, now.AddDays(2)); }
public void it_should_start_and_end_on_specified_dates_if_timelimited() { var now = DateTime.Now; var target = new GoalProcessor(now); var goal = new Goal() { EvaluationType = GoalEvaluation.Timelimited }; var vm = target.ProcessGoal(goal); Assert.AreEqual(0, vm.Graph.Points[0].Amount); Assert.AreEqual(0, vm.Graph.Points[1].Amount); goal = new Goal() { EvaluationType = GoalEvaluation.Timelimited, StartDate = now.AddDays(-10), EndDate = now.AddDays(10) }; vm = target.ProcessGoal(goal); Assert.AreEqual(vm.Graph.Points[0].Time, now.AddDays(-10)); Assert.AreEqual(vm.Graph.Points[1].Time, now.AddDays(10)); }