From 8719fe859d8645935514c78abc15173455ea7ba2 Mon Sep 17 00:00:00 2001 From: Jeremy Smith Date: Tue, 14 Jun 2016 13:39:01 -0700 Subject: [PATCH 1/4] Allow getting entries since a specific date --- src/Nagger.Data/Local/LocalTimeRepository.cs | 38 +++++++++++++++++++ src/Nagger.Interfaces/ILocalTimeRepository.cs | 2 + 2 files changed, 40 insertions(+) diff --git a/src/Nagger.Data/Local/LocalTimeRepository.cs b/src/Nagger.Data/Local/LocalTimeRepository.cs index 1448f38..dfa2861 100644 --- a/src/Nagger.Data/Local/LocalTimeRepository.cs +++ b/src/Nagger.Data/Local/LocalTimeRepository.cs @@ -106,6 +106,44 @@ public IEnumerable GetUnsyncedEntries(bool getInternal = false) return entries; } + public IEnumerable GetTimeEntriesSince(DateTime time, bool getInternal = false) + { + var entries = new List(); + using (var cnn = GetConnection()) + using (var cmd = cnn.CreateCommand()) + { + var cmdText = "SELECT * FROM TimeEntries WHERE TimeRecorded >= @time"; + if (!getInternal) cmdText += " AND Internal = 0"; + cmd.CommandText = cmdText; + + cmd.Prepare(); + cmd.Parameters.AddWithValue("@time", time); + + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + var timeEntry = new TimeEntry + { + TimeRecorded = + DateTime.SpecifyKind(reader.GetDateTime(reader.GetOrdinal("TimeRecorded")), + DateTimeKind.Local), + Comment = reader.Get("Comment"), + Id = reader.Get("Id"), + Task = _localTaskRepository.GetTaskById(reader.Get("TaskId")), + Synced = reader.Get("Synced"), + MinutesSpent = reader.Get("MinutesSpent"), + Internal = reader.Get("Internal"), + Project = _localProjectRepository.GetProjectById(reader.Get("ProjectId")) + }; + + entries.Add(timeEntry); + } + } + } + return entries; + } + public IEnumerable GetRecentlyRecordedTaskIds(int limit) { var ids = new List(); diff --git a/src/Nagger.Interfaces/ILocalTimeRepository.cs b/src/Nagger.Interfaces/ILocalTimeRepository.cs index 8f92305..bd00f17 100644 --- a/src/Nagger.Interfaces/ILocalTimeRepository.cs +++ b/src/Nagger.Interfaces/ILocalTimeRepository.cs @@ -1,5 +1,6 @@ namespace Nagger.Interfaces { + using System; using System.Collections.Generic; using Models; @@ -13,6 +14,7 @@ public interface ILocalTimeRepository TimeEntry GetLastTimeEntry(bool getInternal = false); IEnumerable GetUnsyncedEntries(bool getInternal = false); + IEnumerable GetTimeEntriesSince(DateTime time, bool getInternal = false); IEnumerable GetRecentlyRecordedTaskIds(int limit); IEnumerable GetRecentlyRecordedCommentsForTaskId(int limit, string taskId); } From 42e3881f1d6a3c6c53c9ecb8c447458f1701c51c Mon Sep 17 00:00:00 2001 From: Jeremy Smith Date: Tue, 14 Jun 2016 13:39:15 -0700 Subject: [PATCH 2/4] Add in helpful datetime extensions --- src/Nagger.Extensions/DateTimeExtensions.cs | 18 ++++++++++++++++++ src/Nagger.Extensions/Nagger.Extensions.csproj | 1 + 2 files changed, 19 insertions(+) create mode 100644 src/Nagger.Extensions/DateTimeExtensions.cs diff --git a/src/Nagger.Extensions/DateTimeExtensions.cs b/src/Nagger.Extensions/DateTimeExtensions.cs new file mode 100644 index 0000000..3e16dd4 --- /dev/null +++ b/src/Nagger.Extensions/DateTimeExtensions.cs @@ -0,0 +1,18 @@ +namespace Nagger.Extensions +{ + using System; + + public static class DateTimeExtensions + { + // see http://stackoverflow.com/a/38064/296889 + public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek) + { + var diff = dt.DayOfWeek - startOfWeek; + if (diff < 0) + { + diff += 7; + } + return dt.AddDays(-1 * diff).Date; + } + } +} diff --git a/src/Nagger.Extensions/Nagger.Extensions.csproj b/src/Nagger.Extensions/Nagger.Extensions.csproj index b42a7ed..747475c 100644 --- a/src/Nagger.Extensions/Nagger.Extensions.csproj +++ b/src/Nagger.Extensions/Nagger.Extensions.csproj @@ -40,6 +40,7 @@ + From 8b49f0dafdb3de2e6ee30d2391096aa662823881 Mon Sep 17 00:00:00 2001 From: Jeremy Smith Date: Tue, 14 Jun 2016 13:39:30 -0700 Subject: [PATCH 3/4] Generate the time report --- src/Nagger.Interfaces/ITimeService.cs | 2 ++ src/Nagger.Services/CommandService.cs | 4 ++++ src/Nagger.Services/TimeService.cs | 31 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/src/Nagger.Interfaces/ITimeService.cs b/src/Nagger.Interfaces/ITimeService.cs index b1ce423..6464c1f 100644 --- a/src/Nagger.Interfaces/ITimeService.cs +++ b/src/Nagger.Interfaces/ITimeService.cs @@ -20,5 +20,7 @@ public interface ITimeService int IntervalsSinceLastRecord(bool justToday = true); IEnumerable GetRecentlyRecordedTaskIds(int limit); IEnumerable GetRecentlyRecordedCommentsForTask(int limit, Task task); + + string GetTimeReport(); } } \ No newline at end of file diff --git a/src/Nagger.Services/CommandService.cs b/src/Nagger.Services/CommandService.cs index 23dd617..9d2e3c3 100644 --- a/src/Nagger.Services/CommandService.cs +++ b/src/Nagger.Services/CommandService.cs @@ -22,6 +22,10 @@ public void ExecuteCommands(string[] args) _timeService.DailyTimeOperations(true); _outputService.ShowInformation("Push Has been run."); break; + case "-report": + var report = _timeService.GetTimeReport(); + _outputService.ShowInformation(report); + break; } } } diff --git a/src/Nagger.Services/TimeService.cs b/src/Nagger.Services/TimeService.cs index c0ddc10..adb9e4d 100644 --- a/src/Nagger.Services/TimeService.cs +++ b/src/Nagger.Services/TimeService.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; + using System.Text; using Extensions; using Interfaces; using Models; @@ -104,6 +105,36 @@ public IEnumerable GetRecentlyRecordedCommentsForTask(int limit, Task ta { return task?.Id == null ? new List() : _localTimeRepository.GetRecentlyRecordedCommentsForTaskId(limit, task.Id); } + public string GetTimeReport() + { + SquashTime(); + + var workThisWeek = GetSpanOfWorkSince(DayOfWeek.Sunday); + var workToday = GetSpanOfWorkSince(DateTime.Today.DayOfWeek); + + var hoursThisWeek = workThisWeek.Hours; + var minutesThisWeek = workThisWeek.Minutes; + + var hoursToday = workToday.Hours; + var minutesToday = workToday.Minutes; + + var builder = new StringBuilder(); + builder.AppendLine("---This Week---"); + builder.AppendFormat("{0} hours and {1} minutes", hoursThisWeek, minutesThisWeek); + builder.AppendLine(); + builder.AppendLine("---Today---"); + builder.AppendFormat("{0} hours and {1} minutes", hoursToday, minutesToday); + + return builder.ToString(); + } + + TimeSpan GetSpanOfWorkSince(DayOfWeek dayOfWeek) + { + var weekStart = DateTime.Now.StartOfWeek(dayOfWeek); + var entries = _localTimeRepository.GetTimeEntriesSince(weekStart); + + return TimeSpan.FromMinutes(entries.Sum(entry => entry.MinutesSpent)); + } public void DailyTimeOperations(bool force = false) { From 0f66f361cb3dadb768bed8c7c4581f72bbb1ef47 Mon Sep 17 00:00:00 2001 From: Jeremy Smith Date: Tue, 14 Jun 2016 13:40:59 -0700 Subject: [PATCH 4/4] Resharper Cleanup --- src/Nagger.Data/Local/LocalTimeRepository.cs | 7 +++--- src/Nagger.Extensions/DateTimeExtensions.cs | 4 ++-- src/Nagger.Interfaces/ILocalTimeRepository.cs | 2 +- src/Nagger.Services/TimeService.cs | 23 +++++++++++-------- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/Nagger.Data/Local/LocalTimeRepository.cs b/src/Nagger.Data/Local/LocalTimeRepository.cs index dfa2861..929c17a 100644 --- a/src/Nagger.Data/Local/LocalTimeRepository.cs +++ b/src/Nagger.Data/Local/LocalTimeRepository.cs @@ -8,10 +8,11 @@ public class LocalTimeRepository : LocalBaseRepository, ILocalTimeRepository { - readonly ILocalTaskRepository _localTaskRepository; readonly ILocalProjectRepository _localProjectRepository; + readonly ILocalTaskRepository _localTaskRepository; - public LocalTimeRepository(ILocalTaskRepository localTaskRepository, ILocalProjectRepository localProjectRepository) + public LocalTimeRepository(ILocalTaskRepository localTaskRepository, + ILocalProjectRepository localProjectRepository) { _localTaskRepository = localTaskRepository; _localProjectRepository = localProjectRepository; @@ -46,7 +47,7 @@ public TimeEntry GetLastTimeEntry(bool getInternal = false) { var internalWhere = (getInternal) ? "" : "WHERE Internal = 0"; - cmd.CommandText = "SELECT * FROM TimeEntries "+internalWhere+" ORDER BY Id DESC LIMIT 1"; + cmd.CommandText = "SELECT * FROM TimeEntries " + internalWhere + " ORDER BY Id DESC LIMIT 1"; using (var reader = cmd.ExecuteReader()) { diff --git a/src/Nagger.Extensions/DateTimeExtensions.cs b/src/Nagger.Extensions/DateTimeExtensions.cs index 3e16dd4..fa146f0 100644 --- a/src/Nagger.Extensions/DateTimeExtensions.cs +++ b/src/Nagger.Extensions/DateTimeExtensions.cs @@ -12,7 +12,7 @@ public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek) { diff += 7; } - return dt.AddDays(-1 * diff).Date; + return dt.AddDays(-1*diff).Date; } } -} +} \ No newline at end of file diff --git a/src/Nagger.Interfaces/ILocalTimeRepository.cs b/src/Nagger.Interfaces/ILocalTimeRepository.cs index bd00f17..a2045b7 100644 --- a/src/Nagger.Interfaces/ILocalTimeRepository.cs +++ b/src/Nagger.Interfaces/ILocalTimeRepository.cs @@ -18,4 +18,4 @@ public interface ILocalTimeRepository IEnumerable GetRecentlyRecordedTaskIds(int limit); IEnumerable GetRecentlyRecordedCommentsForTaskId(int limit, string taskId); } -} +} \ No newline at end of file diff --git a/src/Nagger.Services/TimeService.cs b/src/Nagger.Services/TimeService.cs index adb9e4d..c07fe54 100644 --- a/src/Nagger.Services/TimeService.cs +++ b/src/Nagger.Services/TimeService.cs @@ -11,9 +11,9 @@ public class TimeService : ITimeService { readonly ILocalTimeRepository _localTimeRepository; + readonly IProjectService _projectService; readonly IRemoteTimeRepository _remoteTimeRepository; readonly ISettingsService _settingsService; - readonly IProjectService _projectService; public TimeService(ILocalTimeRepository localTimeRepository, IRemoteTimeRepository remoteTimeRepository, ISettingsService settingsService, IProjectService projectService) @@ -103,8 +103,11 @@ public IEnumerable GetRecentlyRecordedTaskIds(int limit) public IEnumerable GetRecentlyRecordedCommentsForTask(int limit, Task task) { - return task?.Id == null ? new List() : _localTimeRepository.GetRecentlyRecordedCommentsForTaskId(limit, task.Id); + return task?.Id == null + ? new List() + : _localTimeRepository.GetRecentlyRecordedCommentsForTaskId(limit, task.Id); } + public string GetTimeReport() { SquashTime(); @@ -128,14 +131,6 @@ public string GetTimeReport() return builder.ToString(); } - TimeSpan GetSpanOfWorkSince(DayOfWeek dayOfWeek) - { - var weekStart = DateTime.Now.StartOfWeek(dayOfWeek); - var entries = _localTimeRepository.GetTimeEntriesSince(weekStart); - - return TimeSpan.FromMinutes(entries.Sum(entry => entry.MinutesSpent)); - } - public void DailyTimeOperations(bool force = false) { var lastSquash = _settingsService.GetSetting("LastSquashDate"); @@ -242,6 +237,14 @@ public void SquashTime() RecordMarker(unsyncedEntries.Last().TimeRecorded); } + TimeSpan GetSpanOfWorkSince(DayOfWeek dayOfWeek) + { + var weekStart = DateTime.Now.StartOfWeek(dayOfWeek); + var entries = _localTimeRepository.GetTimeEntriesSince(weekStart); + + return TimeSpan.FromMinutes(entries.Sum(entry => entry.MinutesSpent)); + } + static bool EntriesAreForSameWork(TimeEntry firstEntry, TimeEntry secondEntry) { // entries are considered for the same work if they have the same task and if they have the same comment