Skip to content
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
79 changes: 51 additions & 28 deletions LearningHub.Nhs.WebUI/Controllers/ReportsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public async Task<IActionResult> CreateReportDateSelection()
var reportCreation = await this.multiPageFormService.GetMultiPageFormData<DatabricksRequestModel>(MultiPageFormDataFeature.AddCustomWebForm("ReportWizardCWF"), this.TempData);
var dateVM = new ReportCreationDateSelection();
dateVM.TimePeriod = reportCreation.TimePeriod;
if (reportCreation.StartDate.HasValue)
if (reportCreation.StartDate.HasValue && reportCreation.TimePeriod == "Custom")
{
dateVM.StartDay = reportCreation.StartDate.HasValue ? reportCreation.StartDate.GetValueOrDefault().Day : 0;
dateVM.StartMonth = reportCreation.StartDate.HasValue ? reportCreation.StartDate.GetValueOrDefault().Month : 0;
Expand All @@ -189,33 +189,11 @@ public async Task<IActionResult> CreateReportDateSelection()
dateVM.EndMonth = reportCreation.EndDate.HasValue ? reportCreation.EndDate.GetValueOrDefault().Month : 0;
dateVM.EndYear = reportCreation.EndDate.HasValue ? reportCreation.EndDate.GetValueOrDefault().Year : 0;
}
else
{
var result = await this.reportService.GetCourseCompletionReport(new DatabricksRequestModel
{
StartDate = reportCreation.StartDate,
EndDate = reportCreation.EndDate,
TimePeriod = reportCreation.TimePeriod,
Courses = reportCreation.Courses,
ReportHistoryId = reportCreation.ReportHistoryId,
Take = 1,
Skip = 1,
});

if (result != null)
{
var validDate = DateTime.TryParse(result.MinValidDate, out DateTime startDate);
dateVM.DataStart = validDate ? startDate : null;
dateVM.HintText = validDate
? $"For example, {startDate.Day} {startDate.Month} {startDate.Year}"
: $"For example, {DateTime.Now.Day} {DateTime.Now.Month} {DateTime.Now.Year}";
}
else
{
dateVM.DataStart = null;
dateVM.HintText = $"For example, {DateTime.Now.Day} {DateTime.Now.Month} {DateTime.Now.Year}";
}
}

var minDate = await this.GetMinDate();

dateVM.DataStart = minDate.DataStart;
dateVM.HintText = minDate.HintText;

return this.View(dateVM);
}
Expand All @@ -235,8 +213,20 @@ public async Task<IActionResult> CreateReportSummary(ReportCreationDateSelection
var reportCreation = await this.multiPageFormService.GetMultiPageFormData<DatabricksRequestModel>(MultiPageFormDataFeature.AddCustomWebForm("ReportWizardCWF"), this.TempData);
reportCreation.TimePeriod = reportCreationDate.TimePeriod;

if (reportCreation.TimePeriod == null)
{
var minDate = await this.GetMinDate();
reportCreationDate.DataStart = minDate.DataStart;
reportCreationDate.HintText = minDate.HintText;
this.ModelState.AddModelError("TimePeriod", CommonValidationErrorMessages.ReportingPeriodRequired);
return this.View("CreateReportDateSelection", reportCreationDate);
}

if (!this.ModelState.IsValid)
{
var minDate = await this.GetMinDate();
reportCreationDate.DataStart = minDate.DataStart;
reportCreationDate.HintText = minDate.HintText;
return this.View("CreateReportDateSelection", reportCreationDate);
}

Expand Down Expand Up @@ -433,5 +423,38 @@ private async Task<List<KeyValuePair<string, string>>> GetCoursesAsync()

return courses;
}

private async Task<ReportCreationDateSelection> GetMinDate()
{
var dateVM = new ReportCreationDateSelection();
var reportCreation = await this.multiPageFormService.GetMultiPageFormData<DatabricksRequestModel>(MultiPageFormDataFeature.AddCustomWebForm("ReportWizardCWF"), this.TempData);

var result = await this.reportService.GetCourseCompletionReport(new DatabricksRequestModel
{
StartDate = null,
EndDate = null,
TimePeriod = reportCreation.TimePeriod,
Courses = reportCreation.Courses,
ReportHistoryId = 0,
Take = 1,
Skip = 1,
});

if (result != null)
{
var validDate = DateTime.TryParse(result.MinValidDate, out DateTime startDate);
dateVM.DataStart = validDate ? startDate : null;
dateVM.HintText = validDate
? $"For example, {startDate.Day} {startDate.Month} {startDate.Year}"
: $"For example, {DateTime.Now.Day} {DateTime.Now.Month} {DateTime.Now.Year}";
}
else
{
dateVM.DataStart = null;
dateVM.HintText = $"For example, {DateTime.Now.Day} {DateTime.Now.Month} {DateTime.Now.Year}";
}

return dateVM;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -269,5 +269,10 @@ public static class CommonValidationErrorMessages
/// Course Required.
/// </summary>
public const string CourseRequired = "Select a course";

/// <summary>
/// Course Required.
/// </summary>
public const string ReportingPeriodRequired = "Select a reporting period";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,10 @@ public class DynamicCheckboxItemViewModel
/// Gets or sets a value indicating whether gets or sets a selected.
/// </summary>
public bool Selected { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the option is exclusive.
/// </summary>
public bool Exclusive { get; set; } = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public List<DynamicCheckboxItemViewModel> BuildCourses(List<KeyValuePair<string,
Value = r.Key.ToString(),
Label = UtilityHelper.ConvertToSentenceCase(r.Value),
}).ToList();
this.AllCources.Insert(0, new DynamicCheckboxItemViewModel { Value = "all", Label = "All courses", });
this.AllCources.Insert(0, new DynamicCheckboxItemViewModel { Value = "all", Label = "All courses", Exclusive = true });
return this.AllCources;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,18 @@ private void ValidateStartDateIsAfterDataStart(List<ValidationResult> startDateV
{
startDateValidationResults.Add(
new ValidationResult(
"Enter a start date after the start of data in the platform", new[] { nameof(this.StartDay), }));
$"No data is available for the selected date range. Select a date after {this.DataStart.Value.Day} {this.DataStart.Value.Month} {this.DataStart.Value.Year}", new[] { nameof(this.StartDay), }));
startDateValidationResults.Add(
new ValidationResult(
string.Empty,
new[] { nameof(this.StartMonth), nameof(this.StartYear), }));
}

if (startDate.Date > DateTime.Now.Date)
{
startDateValidationResults.Add(
new ValidationResult(
"The start date cannot be in the future", new[] { nameof(this.StartDay), }));
startDateValidationResults.Add(
new ValidationResult(
string.Empty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@
return [{ text: 'Action required', className: 'fa-solid fa-triangle-exclamation text-warning pt-1' }];
case NotificationType.AccessRequest:
return [{ text: 'Access request', className: 'fa-solid fa-lock text-dark pt-1' }];
case NotificationType.ReportProcessed:
return [{ text: 'Report', className: 'fa-solid fa-circle-check text-success pt-1' }];
default:
return [{ text: 'unknown', className: '' }];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export enum NotificationType {
UserPermission = 6,
PublishFailed = 7,
AccessRequest = 8,
ReportProcessed = 9,
}

export enum NotificationPriority {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public IViewComponentResult Invoke(
Value = cb.Value,
Label = cb.Label,
HintText = cb.HintText,
Exclusive = cb.Exclusive,
Selected = selectedList.Contains(cb.Value),
}).ToList(),
};
Expand Down
35 changes: 22 additions & 13 deletions LearningHub.Nhs.WebUI/Views/Reports/CourseCompletionReport.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@model LearningHub.Nhs.WebUI.Models.Report.CourseCompletionViewModel

@{
ViewData["Title"] = "Course completion report";
ViewData["Title"] = "Course progress report";
var returnUrl = $"{Context.Request.Path}{Context.Request.QueryString}";


Expand Down Expand Up @@ -38,19 +38,27 @@
<a href="/Reports">Reports</a>
</div>

<h1 class="nhsuk-heading-xl"> Course completion report</h1>
<h1 class="nhsuk-heading-xl"> Course progress report</h1>
<dl class="nhsuk-summary-list nhsuk-u-reading-width">
<div class="nhsuk-summary-list__row">
<dt class="nhsuk-summary-list__key">
Course@(distinctCourses.Count() > 1 ? "s" : "")
</dt>
<dd class="nhsuk-summary-list__value">
<ul>
@foreach (var entry in distinctCourses)
{
<li>@entry</li>
}
</ul>
@if (distinctCourses.Count() > 1)
{
<ul>
@foreach (var entry in distinctCourses)
{
<li>@entry</li>
}
</ul>
}
else
{
<p>@distinctCourses.FirstOrDefault()</p>
}


</dd>

Expand Down Expand Up @@ -97,15 +105,16 @@
{
<h2 class="nhsuk-heading-m">Displaying @startRow–@endRow of @Model.TotalCount filtered row@(Model.TotalCount > 1 ? "s" : "")</h2>

<p class="nhsuk-u-secondary-text-color nhsuk-u-reading-width">
Request to download this report in a spreadsheet (.xls) format.You will be notified
when the report is ready.
</p>

@if (Model.ReportHistoryModel != null && Model.ReportHistoryModel.DownloadRequest == null)
{
<p class="nhsuk-u-secondary-text-color nhsuk-u-reading-width">
Request to download this report in a spreadsheet (.xls) format.You will be notified
when the report is ready.
</p>
<form method="post" asp-controller="Reports" asp-action="QueueReportDownload">
<input type="hidden" name="reportHistoryId" value="@Model.ReportHistoryId" />
<button class="nhsuk-button nhsuk-button--reverse nhsuk-button--with-border" type="submit">Request report as spreadsheet</button>
<button class="nhsuk-button nhsuk-button--reverse nhsuk-button--with-border" type="submit">Request report</button>
</form>
}
else if (Model.ReportHistoryModel != null && Model.ReportHistoryModel.DownloadRequest == true && Model.ReportHistoryModel.ReportStatusId == ((int)Status.Pending))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,45 +27,42 @@
<div class="nhsuk-hint">
Create a course completion report
</div>

<h1 class="nhsuk-heading-xl">
Reporting Period
Reporting period
</h1>
<div class="nhsuk-u-padding-bottom-9">

@if (errorHasOccurred)
{
<vc:error-summary order-of-property-names="@(new[] { nameof(Model.TimePeriod) })" />
}

<form asp-controller="Reports" asp-action="CreateReportSummary" method="post">
@Html.HiddenFor(x=>x.HintText)
@Html.HiddenFor(x =>x.DataStart)
<div class="nhsuk-form-group">
<div class="nhsuk-form-group @(errorHasOccurred ? "nhsuk-form-group--error" : "")">
<fieldset class="nhsuk-fieldset">
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
<h1 class="nhsuk-fieldset__heading">
</h1>
</legend>
<div class="nhsuk-hint">
For the last:
</div>

<div class="nhsuk-radios" data-module="nhsuk-radios">
@foreach (var (radio, index) in Model.PopulateDateRange().Select((r, i) => (r, i)))
{
var radioId = $"TimePeriod-{index}";
var radioId = index == 0 ? "TimePeriod" : $"TimePeriod-{index}";
@if (radio.Value != "Custom")
{

<div class="nhsuk-radios__item">
<input class="nhsuk-radios__input"
id="@radioId"
asp-for="TimePeriod"
name="TimePeriod"
type="radio"
value="@radio.Value"
aria-describedby="@(!string.IsNullOrEmpty(radio.HintText) ? $"{radio.Value}-item-hint" : string.Empty)"
data-val-required="Select a time period"
data-val="true"
@(radio.Value == Model.TimePeriod ? "checked" : string.Empty) />
data-val="false" />
<label class="nhsuk-label nhsuk-radios__label" for="@radioId">
@radio.Label
</label>
Expand All @@ -92,7 +89,7 @@
<div class="date-range-container">
<div class="date-range-item">
<div class="nhsuk-form-group nhsuk-date-inline">
<label class="nhsuk-label nhsuk-label--strong nhsuk-u-padding-top-5" for="StartDate">From</label>
<label class="nhsuk-label nhsuk-label--strong nhsuk-u-font-weight-bold nhsuk-u-padding-top-5" for="StartDate">From</label>
<vc:date-input id="StartDate"
label=""
day-id="StartDay"
Expand All @@ -104,7 +101,7 @@
</div>
<div class="date-range-item">
<div class="nhsuk-form-group nhsuk-date-inline">
<label class="nhsuk-label nhsuk-label--strong nhsuk-u-padding-top-5" for="EndDate">To</label>
<label class="nhsuk-label nhsuk-label--strong nhsuk-u-font-weight-bold nhsuk-u-padding-top-5" for="EndDate">To</label>
<vc:date-input id="EndDate"
label=""
day-id="EndDay"
Expand All @@ -129,7 +126,7 @@
</div>
<div class="nhsuk-u-padding-top-7 nhsuk-u-padding-bottom-7">

<button class="nhsuk-button" type="submit">Continue</button>
<button class="nhsuk-button" type="submit">Submit</button>
</div>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@model DynamicCheckboxesViewModel
@{
var propertyName = ViewData["PropertyName"]?.ToString() ?? "SelectedValues";
var exclusiveGroup = $"{propertyName}-list";
}

<div class="nhsuk-form-group @(Model.Required && !Model.SelectedValues.Any() ? "nhsuk-form-group--error" : "")">
Expand All @@ -17,14 +18,16 @@
@for (int i = 0; i < Model.Checkboxes.Count; i++)
{
var checkbox = Model.Checkboxes[i];
var inputId = $"{propertyName}_{i}";
var inputId = i == 0 ? propertyName : $"{propertyName}_{i}";

<div class="nhsuk-checkboxes__item">
<input class="nhsuk-checkboxes__input"
id="@inputId"
name="@propertyName"
type="checkbox"
value="@checkbox.Value"
@(checkbox.Exclusive ? "data-checkbox-exclusive" : null)
data-checkbox-exclusive-group="@exclusiveGroup"
@(checkbox.Selected ? "checked" : null) />

<label class="nhsuk-label nhsuk-checkboxes__label" for="@inputId">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ public async Task<int> CreateReportNotificationAsync(int userId, string reportNa

var message = learningHubConfig.Notifications.Report.Replace("[ReportName]", reportName).Replace("[ReportContent]", reportContent);

message = message.Replace("[ReportSection]", $"{this.learningHubConfig.BaseUrl.TrimEnd('/')}/{this.learningHubConfig.ReportUrl.TrimStart('/')}");


var notification = await this.CreateAsync(userId, this.UserSpecificNotification(
title, message, NotificationTypeEnum.ReportProcessed, NotificationPriorityEnum.General));
Expand Down
Loading
Loading