Skip to content
This repository was archived by the owner on Oct 3, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .vs/TakeMyTime.NETCore/DesignTimeBuild/.dtbcache
Binary file not shown.
Binary file modified .vs/TakeMyTime.NETCore/v16/.suo
Binary file not shown.
21 changes: 21 additions & 0 deletions TakeMyTime.DAL.Tests/TakeMyTime.DAL.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TakeMyTime.DAL\TakeMyTime.DAL.csproj" />
<ProjectReference Include="..\TakeMyTime.Models\TakeMyTime.Models.csproj" />
</ItemGroup>

</Project>
106 changes: 106 additions & 0 deletions TakeMyTime.DAL.Tests/WeekdayProductivityManagerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using TakeMyTime.Models.Models;

namespace TakeMyTime.DAL.Tests
{
[TestClass]
public class WeekdayProductivityManagerTests
{
private WeekdayProductivityManager manager;

[TestInitialize]
public void Initialize()
{
this.manager = new WeekdayProductivityManager();
}

private Entry[] GenerateEntries()
{
return new Entry[]
{
new Entry
{
DurationAsTicks = TimeSpan.FromHours(1).Ticks,
Started = new DateTime(2020, 3, 16)
},
new Entry
{
DurationAsTicks = TimeSpan.FromHours(1).Ticks,
Started = new DateTime(2020, 3, 17)
},
new Entry
{
DurationAsTicks = TimeSpan.FromHours(1).Ticks,
Started = new DateTime(2020, 3, 10)
},
new Entry
{
DurationAsTicks = TimeSpan.FromHours(1).Ticks,
Started = new DateTime(2020, 3, 18)
},
new Entry
{
DurationAsTicks = TimeSpan.FromHours(1).Ticks,
Started = new DateTime(2020, 3, 19)
},
new Entry
{
DurationAsTicks = TimeSpan.FromHours(1).Ticks,
Started = new DateTime(2020, 3, 20)
}
};
}

[TestMethod]
public void TestDayWithoutEntries()
{
// ARRANGE
var entries = this.GenerateEntries();

// ACT
foreach (var entry in entries)
{
this.manager.ProcessEntry(entry);
}
var result = this.manager.GetResults();

// ASSERT
double expectedTotalResultMonday = 0;
double expectedAverageHoursMonday = 0;
double expectedShareMonday = 0;

Assert.AreNotEqual(expectedTotalResultMonday, result.Single(r => r.Day == DayOfWeek.Monday).TotalHours);
Assert.AreNotEqual(expectedAverageHoursMonday, result.Single(r => r.Day == DayOfWeek.Monday).AverageHours);
Assert.AreNotEqual(expectedShareMonday, result.Single(r => r.Day == DayOfWeek.Monday).Value);
}

[TestMethod]
public void TestDayWithEntries()
{
// ARRANGE
var entries = this.GenerateEntries();

// ACT
foreach (var entry in entries)
{
this.manager.ProcessEntry(entry);
}
var result = this.manager.GetResults();

// ASSERT
double expectedTotalResultTuesday = 2;
double expectedAverageHoursTuesday = 1;
double expectedShareTuesday = 33; // 100 / 6 = 16,7 => 16,7 x 2 ~ 33
double expectedShareWednesday = 17;

Assert.AreEqual(expectedTotalResultTuesday, result.Single(r => r.Day == DayOfWeek.Tuesday).TotalHours);
Assert.AreEqual(expectedAverageHoursTuesday, result.Single(r => r.Day == DayOfWeek.Tuesday).AverageHours);
double roundedResultOfTuesdayShares = result.Where(r => r.Day == DayOfWeek.Tuesday).Sum(d => Math.Round(d.Value * 100));
Assert.AreEqual(expectedShareTuesday, roundedResultOfTuesdayShares);
double roundedResultOfWednesdayShares = Math.Round(result.Single(r => r.Day == DayOfWeek.Wednesday).Value * 100, 1);
Assert.AreEqual(expectedShareWednesday, roundedResultOfWednesdayShares);
}
}
}
4 changes: 2 additions & 2 deletions TakeMyTime.DAL/Repositories/StatisticsRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public IEnumerable<ProductivityViewModel> GetProjectProductiveDays(int project_i
var entries = this.context.Entries
.Where(e => e.Project_Id == project_id);

foreach (var entry in entries)
foreach (var entry in entries.Where(e => e.DurationAsTicks.HasValue))
{
results.Add(new ProductivityViewModel { X = entry.Date, Y = new TimeSpan(entry.DurationAsTicks.Value) });
}
Expand All @@ -106,7 +106,7 @@ public IEnumerable<MostProductiveWeekDaysViewModel> GetMostProductiveDays()
.Include(e => e.Project)
.Where(e => e.Project.ProjectStatus == EnumDefinition.ProjectStatus.Active)
.ToList();
var weekdayManager = new WeekdayProductivityManager(entries.Count());
var weekdayManager = new WeekdayProductivityManager();

foreach (var entry in entries)
{
Expand Down
106 changes: 80 additions & 26 deletions TakeMyTime.DAL/WeekdayProductivityManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,107 +8,161 @@ namespace TakeMyTime.DAL
{
public class WeekdayProductivityManager
{
public WeekdayProductivityManager(int totalEntryCount)
public WeekdayProductivityManager()
{
this.TotalEntryCount = totalEntryCount;
}

public void ProcessEntry(Entry entry)
{
if(CanProcessEntries)
var durationAsHours = entry.DurationAsTicks.HasValue ? TimeSpan.FromTicks(entry.DurationAsTicks.Value).TotalHours : 0;
if(durationAsHours > 0)
{
TotalWorkingHours += durationAsHours;
var date = entry.Started.HasValue ? entry.Started.Value.DayOfWeek : entry.Date.DayOfWeek;
switch (date)
{
case DayOfWeek.Monday:
MondayTotalWorkingHours += durationAsHours;
MondayEntryCount++;
this.MondayValueShare = Math.Round((double)MondayEntryCount / (double)TotalEntryCount, 2);
this.MondayAverageWorkingHours = Math.Round(MondayTotalWorkingHours / MondayEntryCount, 2);

break;
case DayOfWeek.Tuesday:
TuesdayTotalWorkingHours += durationAsHours;
TuesdayEntryCount++;
this.TuesdayValueShare = Math.Round((double)TuesdayEntryCount / (double)TotalEntryCount, 2);
this.TuesdayAverageWorkingHours = Math.Round(TuesdayTotalWorkingHours / TuesdayEntryCount, 2);

break;
case DayOfWeek.Wednesday:
WednesdayTotalWorkingHours += durationAsHours;
WednesdayEntryCount++;
this.WednesdayValueShare = Math.Round((double)WednesdayEntryCount / (double)TotalEntryCount, 2);
this.WednesdayAverageWorkingHours = Math.Round(WednesdayTotalWorkingHours / WednesdayEntryCount, 2);

break;
case DayOfWeek.Thursday:
ThursdayTotalWorkingHours += durationAsHours;
ThursdayEntryCount++;
this.ThursdayValueShare = Math.Round((double)ThursdayEntryCount / (double)TotalEntryCount, 2);
this.ThursdayAverageWorkingHours = Math.Round(ThursdayTotalWorkingHours / ThursdayEntryCount, 2);

break;
case DayOfWeek.Friday:
FridayTotalWorkingHours += durationAsHours;
FridayEntryCount++;
this.FridayValueShare = Math.Round((double)FridayEntryCount / (double)TotalEntryCount, 2);
this.FridayAverageWorkingHours = Math.Round(FridayTotalWorkingHours / FridayEntryCount, 2);

break;
case DayOfWeek.Saturday:
SaturdayTotalWorkingHours += durationAsHours;
SaturdayEntryCount++;
this.SaturdayValueShare = Math.Round((double)SaturdayEntryCount / (double)TotalEntryCount, 2);
this.SaturdayAverageWorkingHours = Math.Round(SaturdayTotalWorkingHours / SaturdayEntryCount, 2);

break;
case DayOfWeek.Sunday:
SundayTotalWorkingHours += durationAsHours;
SundayEntryCount++;
this.SundayValueShare = Math.Round((double)SundayEntryCount / (double)TotalEntryCount, 2);
this.SundayAverageWorkingHours = Math.Round(SundayTotalWorkingHours / SundayEntryCount, 2);
break;
};

CalculateShares();
}
}

private void CalculateShares()
{
this.MondayValueShare = Math.Round(MondayTotalWorkingHours / TotalWorkingHours, 2);
this.TuesdayValueShare = Math.Round(TuesdayTotalWorkingHours / TotalWorkingHours, 2);
this.WednesdayValueShare = Math.Round(WednesdayTotalWorkingHours / TotalWorkingHours, 2);
this.ThursdayValueShare = Math.Round(ThursdayTotalWorkingHours / TotalWorkingHours, 2);
this.FridayValueShare = Math.Round(FridayTotalWorkingHours / TotalWorkingHours, 2);
this.SaturdayValueShare = Math.Round(SaturdayTotalWorkingHours / TotalWorkingHours, 2);
this.SundayValueShare = Math.Round(SundayTotalWorkingHours / TotalWorkingHours, 2);
}

public IEnumerable<MostProductiveWeekDaysViewModel> GetResults()
{
return new List<MostProductiveWeekDaysViewModel>
{
new MostProductiveWeekDaysViewModel
{
Day = DayOfWeek.Monday,
Value = MondayValueShare
Value = MondayValueShare,
AverageHours = MondayAverageWorkingHours,
TotalHours = MondayTotalWorkingHours
},
new MostProductiveWeekDaysViewModel
{
Day = DayOfWeek.Tuesday,
Value = TuesdayValueShare
Value = TuesdayValueShare,
AverageHours = TuesdayAverageWorkingHours,
TotalHours = TuesdayTotalWorkingHours
},
new MostProductiveWeekDaysViewModel
{
Day = DayOfWeek.Wednesday,
Value = WednesdayValueShare
Value = WednesdayValueShare,
AverageHours = WednesdayAverageWorkingHours,
TotalHours = WednesdayTotalWorkingHours
},
new MostProductiveWeekDaysViewModel
{
Day = DayOfWeek.Thursday,
Value = ThursdayValueShare
Value = ThursdayValueShare,
AverageHours = ThursdayAverageWorkingHours,
TotalHours = ThursdayTotalWorkingHours
},
new MostProductiveWeekDaysViewModel
{
Day = DayOfWeek.Friday,
Value = FridayValueShare
Value = FridayValueShare,
AverageHours = FridayAverageWorkingHours,
TotalHours = FridayTotalWorkingHours
},
new MostProductiveWeekDaysViewModel
{
Day = DayOfWeek.Saturday,
Value = SaturdayValueShare
Value = SaturdayValueShare,
AverageHours = SaturdayAverageWorkingHours,
TotalHours = SaturdayTotalWorkingHours
},
new MostProductiveWeekDaysViewModel
{
Day = DayOfWeek.Sunday,
Value = SundayValueShare
Value = SundayValueShare,
AverageHours = SundayAverageWorkingHours,
TotalHours = SundayTotalWorkingHours
},
};
}

public int TotalEntryCount { get; private set; }
public int MondayEntryCount { get; private set; }
public double TotalWorkingHours { get; private set; }
public double MondayTotalWorkingHours { get; private set; }
public double MondayValueShare { get; private set; }
public int TuesdayEntryCount { get; private set; }
public double MondayAverageWorkingHours { get; private set; }
public double MondayEntryCount { get; set; }
public double TuesdayTotalWorkingHours { get; private set; }
public double TuesdayValueShare { get; private set; }
public int WednesdayEntryCount { get; private set; }
public double TuesdayAverageWorkingHours { get; private set; }
public double TuesdayEntryCount { get; set; }
public double WednesdayTotalWorkingHours { get; private set; }
public double WednesdayValueShare { get; private set; }
public int ThursdayEntryCount { get; private set; }
public double WednesdayAverageWorkingHours { get; private set; }
public double WednesdayEntryCount { get; set; }
public double ThursdayTotalWorkingHours { get; private set; }
public double ThursdayValueShare { get; private set; }
public int FridayEntryCount { get; private set; }
public double ThursdayAverageWorkingHours { get; private set; }
public double ThursdayEntryCount { get; set; }
public double FridayTotalWorkingHours { get; private set; }
public double FridayValueShare { get; private set; }
public int SaturdayEntryCount { get; private set; }
public double FridayAverageWorkingHours { get; private set; }
public double FridayEntryCount { get; set; }
public double SaturdayTotalWorkingHours { get; private set; }
public double SaturdayValueShare { get; private set; }
public int SundayEntryCount { get; private set; }
public double SaturdayAverageWorkingHours { get; private set; }
public double SaturdayEntryCount { get; set; }
public double SundayTotalWorkingHours { get; private set; }
public double SundayValueShare { get; private set; }
public bool CanProcessEntries { get => this.TotalEntryCount > 0; }
public double SundayAverageWorkingHours { get; private set; }
public double SundayEntryCount { get; set; }
}
}
2 changes: 2 additions & 0 deletions TakeMyTime.Models/Models/MostProductiveWeekDaysViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ public class MostProductiveWeekDaysViewModel
{
public DayOfWeek Day { get; set; }
public double Value { get; set; }
public double AverageHours { get; set; }
public double TotalHours { get; set; }
}
}
6 changes: 6 additions & 0 deletions TakeMyTime.NETCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TakeMyTime.BLL.Tests", "Tak
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TakeMyTime.Tests.Common", "TakeMyTime.Tests.Common\TakeMyTime.Tests.Common.csproj", "{D7D6ABCF-39A8-4C17-BF63-F29F11F496BC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakeMyTime.DAL.Tests", "TakeMyTime.DAL.Tests\TakeMyTime.DAL.Tests.csproj", "{E778405A-42E7-4F78-BE0F-EB025BDDD2CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -57,6 +59,10 @@ Global
{D7D6ABCF-39A8-4C17-BF63-F29F11F496BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7D6ABCF-39A8-4C17-BF63-F29F11F496BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7D6ABCF-39A8-4C17-BF63-F29F11F496BC}.Release|Any CPU.Build.0 = Release|Any CPU
{E778405A-42E7-4F78-BE0F-EB025BDDD2CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E778405A-42E7-4F78-BE0F-EB025BDDD2CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E778405A-42E7-4F78-BE0F-EB025BDDD2CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E778405A-42E7-4F78-BE0F-EB025BDDD2CB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
4 changes: 3 additions & 1 deletion TakeMyTime.WPF/Statistics/Dashboard.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ private string[] ResolveWeekdayNames(IEnumerable<MostProductiveWeekDaysViewModel
var labels = new List<string>();
foreach (var vm in viewModels)
{
labels.Add(ResourceStringManager.GetResourceByKey(vm.Day.ToString()));
string formattedAvgHours = string.Format("{0}(Ø {1:0.00}h){2}(Total: {3:0.00}h)", System.Environment.NewLine,
vm.AverageHours, System.Environment.NewLine, vm.TotalHours);
labels.Add(ResourceStringManager.GetResourceByKey(vm.Day.ToString()) + formattedAvgHours);
}

return labels.ToArray();
Expand Down
Loading