diff --git a/Keas.Core/Domain/Person.cs b/Keas.Core/Domain/Person.cs index 4bcf4f072..adccf5a8e 100644 --- a/Keas.Core/Domain/Person.cs +++ b/Keas.Core/Domain/Person.cs @@ -40,7 +40,17 @@ public string Name { get { return FirstName + " " + LastName; } - } + } + + [StringLength(256)] + [Display(Name = "Name")] + public string NameV2 + { + get + { + return $"{LastName}, {FirstName}"; + } + } [Required] [StringLength(256)] diff --git a/Keas.Mvc/Controllers/GroupController.cs b/Keas.Mvc/Controllers/GroupController.cs index 42addac0e..b557cadf3 100644 --- a/Keas.Mvc/Controllers/GroupController.cs +++ b/Keas.Mvc/Controllers/GroupController.cs @@ -157,6 +157,20 @@ public async Task IncompleteDocumentsReport(int id) return View(model); } + public async Task CompletedDocumentsReport(int id, DateTime? start = null, DateTime? end = null) + { + var group = await GetGroup(id); + + if (group == null) + { + ErrorMessage = "Group not found or no access to Group"; + return RedirectToAction("NoAccess", "Home"); + } + + var model = await _reportService.CompletedDocuments(group, start, end); + return View(model); + } + public async Task PeopleLeavingWithAssets(int id) { var group = await GetGroup(id); diff --git a/Keas.Mvc/Models/ReportModels/CompletedDocsReportModel.cs b/Keas.Mvc/Models/ReportModels/CompletedDocsReportModel.cs index a10aec6ed..04b9dec7e 100644 --- a/Keas.Mvc/Models/ReportModels/CompletedDocsReportModel.cs +++ b/Keas.Mvc/Models/ReportModels/CompletedDocsReportModel.cs @@ -16,6 +16,23 @@ public class CompletedDocsReportModel [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] [Display(Name = "End Created Date")] public DateTime End { get; set; } - public List Docs {get;set;} + + public Group Group { get; set; } + + public CompletedDocsReportModelItem[] Items { get; set; } + } + + public class CompletedDocsReportModelItem + { + public string PersonName { get; set; } + public string DocName { get; set; } + [DisplayFormat(DataFormatString = "{0:d}")] + public DateTime CreatedAt { get; set; } + [DisplayFormat(DataFormatString = "{0:d}")] + public DateTime? CompletedAt { get; set; } + public string TeamSlug { get; set; } + public string TeamName { get; set; } + public string DetailsLink { get; set; } + } } diff --git a/Keas.Mvc/Services/ReportService.cs b/Keas.Mvc/Services/ReportService.cs index 4a41cb90d..07b04fef1 100644 --- a/Keas.Mvc/Services/ReportService.cs +++ b/Keas.Mvc/Services/ReportService.cs @@ -39,6 +39,7 @@ public interface IReportService Task> InactiveSpaces(string teamSlug); //Not sure if this one can be done with a group Task CompletedDocuments(Team team, string teamSlug, DateTime? start, DateTime? end); + Task CompletedDocuments(Group group, DateTime? start = null, DateTime? end = null); } @@ -412,9 +413,52 @@ public async Task CompletedDocuments(Team team, string end = end.Value.FromPacificTime().Date; } - var docs = await _context.Documents.AsNoTracking().Include(a => a.Person).Where(a => a.TeamId == team.Id && a.Active && a.Person.Active && a.CreatedAt >= start && a.CreatedAt <= end && a.Status == "Completed").ToListAsync(); - var model = new CompletedDocsReportModel { Start = start.Value.ToPacificTime().Date, End = end.Value.ToPacificTime().Date, Docs = docs }; + var model = new CompletedDocsReportModel + { + Start = start.Value.ToPacificTime().Date, + End = end.Value.ToPacificTime().Date, + Items = await _context.Documents.AsNoTracking() + .Include(a => a.Person) + .Where(a => a.TeamId == team.Id && a.Active && a.Person.Active && a.CreatedAt >= start && a.CreatedAt <= end && a.Status == "Completed") + .Select(CompletedDocsProjection()) + .ToArrayAsync() + }; + + return model; + } + + public async Task CompletedDocuments(Group group, DateTime? start = null, DateTime? end = null) + { + if (!start.HasValue) + { + start = DateTime.UtcNow.AddDays(-30).Date; + } + else + { + start = start.Value.FromPacificTime().Date; + } + if (!end.HasValue) + { + end = DateTime.UtcNow.AddDays(1).Date; + } + else + { + end = end.Value.FromPacificTime().Date; + } + + + var model = new CompletedDocsReportModel + { + Group = group, + Start = start.Value.ToPacificTime().Date, + End = end.Value.ToPacificTime().Date, + Items = await _context.Documents.AsNoTracking() + .Include(a => a.Team).Include(a => a.Person) + .Where(a => a.Team.Groups.Any(g => g.GroupId == group.Id) && a.Active && a.Person.Active && a.CreatedAt >= start && a.CreatedAt <= end && a.Status == "Completed") + .Select(CompletedDocsProjection()) + .ToArrayAsync() + }; return model; } @@ -652,5 +696,19 @@ public Expression> ExpiringWorkstatio DetailsLink = $"/{a.Team.Slug}/spaces/details/{a.SpaceId}", //This is really only needed for the non group one? }; } + + public Expression> CompletedDocsProjection() + { + return a => new CompletedDocsReportModelItem + { + PersonName = a.Person.NameV2, + DocName = a.Name, + CreatedAt = a.CreatedAt.ToPacificTime(), + CompletedAt = a.CompletedAt.ToPacificTime(), + TeamSlug = a.Team.Slug, + TeamName = a.Team.Name, + DetailsLink = $"/{a.Team.Slug}/people/details/{a.PersonId}", + }; + } } } diff --git a/Keas.Mvc/Views/Group/CompletedDocumentsReport.cshtml b/Keas.Mvc/Views/Group/CompletedDocumentsReport.cshtml new file mode 100644 index 000000000..07a77289f --- /dev/null +++ b/Keas.Mvc/Views/Group/CompletedDocumentsReport.cshtml @@ -0,0 +1,107 @@ +@model Keas.Mvc.Models.ReportModels.CompletedDocsReportModel + +@{ + ViewData["Title"] = "Completed Documents"; +} + +Back to Group Home + +
+
+
+

Group: @Model.Group.Name

+

Completed Documents

+
+
+
+ +
+ +
+
+
+

Filters

+
+ + + + + + +
+ +
+
+
+
+ +
+ +
+
+ + + + + + + + + + + + + + @foreach (var item in Model.Items) + { + + + + + + + + + } + +
+ Person + + Doc Name + + Created + + Completed + + Team + + Link +
@item.PersonName@item.DocName@Html.DisplayFor(a => item.CreatedAt)@Html.DisplayFor(a => item.CompletedAt)@item.TeamName + Details +
+
+
+ +@section Styles { + @await Html.PartialAsync("_ReportStylePartial") +} +@section Scripts { + @{ + await Html.RenderPartialAsync("_ImportJS"); + } + + +} diff --git a/Keas.Mvc/Views/Group/Index.cshtml b/Keas.Mvc/Views/Group/Index.cshtml index 9e2192096..504499e8f 100644 --- a/Keas.Mvc/Views/Group/Index.cshtml +++ b/Keas.Mvc/Views/Group/Index.cshtml @@ -48,11 +48,14 @@
-

Incomplete Documents Reports

+

Documents Reports

diff --git a/Keas.Mvc/Views/Report/CompletedDocuments.cshtml b/Keas.Mvc/Views/Report/CompletedDocuments.cshtml index 244a88dc2..c9801b587 100644 --- a/Keas.Mvc/Views/Report/CompletedDocuments.cshtml +++ b/Keas.Mvc/Views/Report/CompletedDocuments.cshtml @@ -56,19 +56,15 @@ - @foreach (var item in Model.Docs) + @foreach (var item in Model.Items) { - @Html.DisplayFor(a=> item.Person.LastName), @Html.DisplayFor(a => item.Person.FirstName) - @Html.DisplayFor(a=> item.Name) + @item.PersonName + @item.DocName + @Html.DisplayFor(a => item.CreatedAt) + @Html.DisplayFor(a => item.CompletedAt) - @item.CreatedAt.ToPacificTime().ToString("d") - - - @(item.CompletedAt.HasValue ? item.CompletedAt.Value.ToPacificTime().ToString("d") : null) - - - Details + Details } diff --git a/Test/TestsDatabase/PersonTests.cs b/Test/TestsDatabase/PersonTests.cs index 86f12b341..ddaaacee4 100644 --- a/Test/TestsDatabase/PersonTests.cs +++ b/Test/TestsDatabase/PersonTests.cs @@ -72,6 +72,11 @@ public void TestDatabaseFieldAttributes() "[System.ComponentModel.DataAnnotations.DisplayAttribute(Name = \"Name\")]", "[System.ComponentModel.DataAnnotations.StringLengthAttribute((Int32)256)]", })); + expectedFields.Add(new NameAndType("NameV2", "System.String", new List + { + "[System.ComponentModel.DataAnnotations.DisplayAttribute(Name = \"Name\")]", + "[System.ComponentModel.DataAnnotations.StringLengthAttribute((Int32)256)]", + })); expectedFields.Add(new NameAndType("Notes", "System.String", new List { "[System.ComponentModel.DataAnnotations.DataTypeAttribute((System.ComponentModel.DataAnnotations.DataType)9)]",