From ac0a14ec365b8c9257746e084dc21d319d52e991 Mon Sep 17 00:00:00 2001 From: plockwood Date: Mon, 15 Jan 2024 12:08:43 +0000 Subject: [PATCH 1/8] progress --- .../Dfe.PrepareConversions.Data.Tests.csproj | 2 +- .../Dfe.PrepareConversions.Data.csproj | 2 +- .../KeyStagePerformance.cs | 3 + .../KeyStagePerformanceResponse.cs | 4 +- .../Services/KeyStagePerformanceService.cs | 2 +- ...onversions.DocumentGeneration.Tests.csproj | 2 +- ...epareConversions.DocumentGeneration.csproj | 2 +- .../Dfe.PrepareConversions.Redirector.csproj | 2 +- .../Dfe.PrepareConversions.Tests.csproj | 2 +- .../Dfe.PrepareConversions.csproj | 2 +- .../Dfe.PrepareConversions/Models/Links.cs | 3 + .../EducationalAttendance/default.cshtml | 67 +++++++++++++++++++ .../Pages/NewProject/SearchTrust.cshtml.cs | 4 +- .../Pages/TaskList/Index.cshtml | 11 ++- .../Pages/TaskList/Index.cshtml.cs | 1 + .../EducationalAttendance.cshtml | 39 +++++++++++ .../TaskList/PreviewProjectTemplate.cshtml.cs | 1 + .../EducationalAttendanceViewComponent.cs | 46 +++++++++++++ .../EducationalAttendanceViewModel.cs | 21 ++++++ .../ViewModels/TaskListViewModel.cs | 1 + 20 files changed, 205 insertions(+), 12 deletions(-) create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendance.cshtml create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/ViewComponents/EducationalAttendanceViewComponent.cs create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/EducationalAttendanceViewModel.cs diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data.Tests/Dfe.PrepareConversions.Data.Tests.csproj b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data.Tests/Dfe.PrepareConversions.Data.Tests.csproj index 731900e01..698fb4d83 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data.Tests/Dfe.PrepareConversions.Data.Tests.csproj +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data.Tests/Dfe.PrepareConversions.Data.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Dfe.PrepareConversions.Data.csproj b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Dfe.PrepareConversions.Data.csproj index 0c9513d16..daac5427d 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Dfe.PrepareConversions.Data.csproj +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Dfe.PrepareConversions.Data.csproj @@ -11,7 +11,7 @@ - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/KeyStagePerformance/KeyStagePerformance.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/KeyStagePerformance/KeyStagePerformance.cs index 758534b80..bc4a4d86c 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/KeyStagePerformance/KeyStagePerformance.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/KeyStagePerformance/KeyStagePerformance.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using Dfe.Academies.Contracts.V1.EducationalPerformance; namespace Dfe.PrepareConversions.Data.Models.KeyStagePerformance; @@ -8,7 +9,9 @@ public class KeyStagePerformance public IEnumerable KeyStage2 { get; set; } public IEnumerable KeyStage4 { get; set; } public IEnumerable KeyStage5 { get; set; } + public IEnumerable SchoolAbsenceData { get; set; } + public bool HasSchoolAbsenceData => SchoolAbsenceData?.Any() ?? false; public bool HasKeyStage2PerformanceTables => KeyStage2?.Any(HasKeyStage2Performance) ?? false; public bool HasKeyStage4PerformanceTables => KeyStage4?.Any(HasKeyStage4Performance) ?? false; public bool HasKeyStage5PerformanceTables => KeyStage5?.Any(HasKeyStage5Performance) ?? false; diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/KeyStagePerformance/KeyStagePerformanceResponse.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/KeyStagePerformance/KeyStagePerformanceResponse.cs index 2f7880860..bb9c040c3 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/KeyStagePerformance/KeyStagePerformanceResponse.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/KeyStagePerformance/KeyStagePerformanceResponse.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Dfe.Academies.Contracts.V1.EducationalPerformance; +using System.Collections.Generic; namespace Dfe.PrepareConversions.Data.Models.KeyStagePerformance; @@ -8,4 +9,5 @@ public class KeyStagePerformanceResponse public IEnumerable KeyStage2 { get; set; } public IEnumerable KeyStage4 { get; set; } public IEnumerable KeyStage5 { get; set; } + public IEnumerable absenceData { get; set; } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/KeyStagePerformanceService.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/KeyStagePerformanceService.cs index c22097dbd..b5070dae8 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/KeyStagePerformanceService.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/KeyStagePerformanceService.cs @@ -30,7 +30,7 @@ public async Task GetKeyStagePerformance(string urn) return new KeyStagePerformance { - KeyStage2 = keyStagePerformanceResponse.KeyStage2, KeyStage4 = keyStagePerformanceResponse.KeyStage4, KeyStage5 = keyStagePerformanceResponse.KeyStage5 + KeyStage2 = keyStagePerformanceResponse.KeyStage2, KeyStage4 = keyStagePerformanceResponse.KeyStage4, KeyStage5 = keyStagePerformanceResponse.KeyStage5, SchoolAbsenceData = keyStagePerformanceResponse.absenceData }; } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.DocumentGeneration.Tests/Dfe.PrepareConversions.DocumentGeneration.Tests.csproj b/Dfe.PrepareConversions/Dfe.PrepareConversions.DocumentGeneration.Tests/Dfe.PrepareConversions.DocumentGeneration.Tests.csproj index db5f11e07..35329471b 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.DocumentGeneration.Tests/Dfe.PrepareConversions.DocumentGeneration.Tests.csproj +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.DocumentGeneration.Tests/Dfe.PrepareConversions.DocumentGeneration.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.DocumentGeneration/Dfe.PrepareConversions.DocumentGeneration.csproj b/Dfe.PrepareConversions/Dfe.PrepareConversions.DocumentGeneration/Dfe.PrepareConversions.DocumentGeneration.csproj index 56964c851..5c6b2a734 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.DocumentGeneration/Dfe.PrepareConversions.DocumentGeneration.csproj +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.DocumentGeneration/Dfe.PrepareConversions.DocumentGeneration.csproj @@ -10,7 +10,7 @@ - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Redirector/Dfe.PrepareConversions.Redirector.csproj b/Dfe.PrepareConversions/Dfe.PrepareConversions.Redirector/Dfe.PrepareConversions.Redirector.csproj index 09375b475..78c2fba1d 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Redirector/Dfe.PrepareConversions.Redirector.csproj +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Redirector/Dfe.PrepareConversions.Redirector.csproj @@ -9,7 +9,7 @@ - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Dfe.PrepareConversions.Tests.csproj b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Dfe.PrepareConversions.Tests.csproj index da8519812..d695d4263 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Dfe.PrepareConversions.Tests.csproj +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Dfe.PrepareConversions.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Dfe.PrepareConversions.csproj b/Dfe.PrepareConversions/Dfe.PrepareConversions/Dfe.PrepareConversions.csproj index 53326243c..d92d5fd85 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Dfe.PrepareConversions.csproj +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Dfe.PrepareConversions.csproj @@ -35,7 +35,7 @@ - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs index 9518a15f8..a8f76e572 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs @@ -180,6 +180,9 @@ public static class KeyStagePerformanceSection public static readonly LinkItem KeyStage5PerformanceTablesAdditionalInformation = AddLinkItem(page: "/TaskList/KeyStagePerformance/KeyStage5PerformanceTablesAdditionalInformation"); + + public static readonly LinkItem EducationalAttendance = + AddLinkItem(page: "/TaskList/KeyStagePerformance/EducationalAttendance"); } public static class Decision diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml new file mode 100644 index 000000000..e69bffbe8 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml @@ -0,0 +1,67 @@ +@using Dfe.PrepareConversions.Utils +@using Dfe.PrepareConversions.TagHelpers +@model IEnumerable +
+ + + + + + + + @foreach (var vm in Model) + { + + } + + + + + + + @{ + var index = 0; + + @foreach (var vm in Model) + { + + index++; + } + } + + +
+

Overall Absence

+

Percentage of mornings or afternoons recorded as an absence from school for any reason, across the full academic year.

+
@vm.Year
@ViewData["SchoolName"]@vm.OverallAbsence
+ + + + + + + @foreach (var vm in Model) + { + + } + + + + + + + @{ + index = 0; + @foreach (var vm in Model) + { + + index++; + } + } + + +
+

Persistent absence of 10% or more

+

The percentage of pupils missing 10% or more of the mornings or afternoons they could attend..

+
@vm.Year
@ViewData["SchoolName"]@vm.PersistentAbsence
+
\ No newline at end of file diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/NewProject/SearchTrust.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/NewProject/SearchTrust.cshtml.cs index 154769f14..a9433c479 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/NewProject/SearchTrust.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/NewProject/SearchTrust.cshtml.cs @@ -91,7 +91,7 @@ public async Task OnPost(string urn) return Page(); } - string ukprn = searchSplit[1]; + string ukprn = searchSplit[searchSplit.Length -1]; TrustDtoResponse trusts = await _trustsRepository.SearchTrusts(ukprn); @@ -121,6 +121,6 @@ private static string HighlightSearchMatch(string input, string toReplace, Trust private static string[] SplitOnBrackets(string input) { - return input.Split(new[] { '(', ')' }, 3, StringSplitOptions.None); + return input.Split(new[] { '(', ')' }, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml index 99b6ad03f..c103af7b7 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml @@ -167,7 +167,16 @@ } - + @if (Model.TaskList.HasAbsenceData) + { +
  • + + + Educational Attendance + + +
  • + } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml.cs index e6143736d..052e15fdb 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml.cs @@ -59,6 +59,7 @@ public override async Task OnGetAsync(int id) TaskList.HasKeyStage2PerformanceTables = keyStagePerformance.HasKeyStage2PerformanceTables; TaskList.HasKeyStage4PerformanceTables = keyStagePerformance.HasKeyStage4PerformanceTables; TaskList.HasKeyStage5PerformanceTables = keyStagePerformance.HasKeyStage5PerformanceTables; + TaskList.HasAbsenceData = keyStagePerformance.HasSchoolAbsenceData; } return Page(); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendance.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendance.cshtml new file mode 100644 index 000000000..f0c43fac0 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendance.cshtml @@ -0,0 +1,39 @@ +@page "/task-list/{id:int}/EducationalAttendance" +@using Dfe.PrepareConversions.TagHelpers +@model Dfe.PrepareConversions.Pages.BaseAcademyConversionProjectPageModel +@{ + ViewData["Title"] = "Educational Attendance"; +} + +@section BeforeMain +{ + +} + +
    +
    + @Model.Project.SchoolName +

    Educational Attendance

    +

    + These performance tables will automatically go into your project template. +

    +

    + Source of data: Find and compare school performance (opens in new tab) +

    +
    + There is no 2019 to 2020 absence data because of the pandemic. 2020 to 2021 data is limited. +
    +
    +
    + @await Component.InvokeAsync("EducationalAttendance") +
    + +
    +
    + +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml.cs index c98cb0c4d..e194d02a4 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml.cs @@ -50,6 +50,7 @@ private async Task SetKeyStagePerformancePageData(ProjectViewModel project) TaskList.HasKeyStage2PerformanceTables = keyStagePerformance.HasKeyStage2PerformanceTables; TaskList.HasKeyStage4PerformanceTables = keyStagePerformance.HasKeyStage4PerformanceTables; TaskList.HasKeyStage5PerformanceTables = keyStagePerformance.HasKeyStage5PerformanceTables; + TaskList.HasAbsenceData = keyStagePerformance.HasSchoolAbsenceData; } public override async Task OnPostAsync(int id) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewComponents/EducationalAttendanceViewComponent.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewComponents/EducationalAttendanceViewComponent.cs new file mode 100644 index 000000000..a586ee34c --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewComponents/EducationalAttendanceViewComponent.cs @@ -0,0 +1,46 @@ +using Dfe.PrepareConversions.Data; +using Dfe.PrepareConversions.Data.Models; +using Dfe.PrepareConversions.Data.Models.KeyStagePerformance; +using Dfe.PrepareConversions.Data.Services; +using Dfe.PrepareConversions.ViewModels; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Dfe.PrepareConversions.ViewComponents; + +public class EducationalAttendanceViewComponent : ViewComponent +{ + private readonly KeyStagePerformanceService _keyStagePerformanceService; + private readonly IAcademyConversionProjectRepository _repository; + + public EducationalAttendanceViewComponent( + KeyStagePerformanceService keyStagePerformanceService, + IAcademyConversionProjectRepository repository) + { + _keyStagePerformanceService = keyStagePerformanceService; + _repository = repository; + } + + public async Task InvokeAsync() + { + int id = int.Parse(ViewContext.RouteData.Values["id"]?.ToString() ?? string.Empty); + + ApiResponse response = await _repository.GetProjectById(id); + if (!response.Success) + { + throw new InvalidOperationException(); + } + + AcademyConversionProject project = response.Body; + ViewData["SchoolName"] = project.SchoolName; + ViewData["LocalAuthority"] = project.LocalAuthority; + KeyStagePerformance keyStagePerformance = await _keyStagePerformanceService.GetKeyStagePerformance(project.Urn.ToString()); + + IOrderedEnumerable viewModel = keyStagePerformance.SchoolAbsenceData.Select(EducationalAttendanceViewModel.Build) + .OrderByDescending(ks => ks.Year); + + return View(viewModel); + } +} diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/EducationalAttendanceViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/EducationalAttendanceViewModel.cs new file mode 100644 index 000000000..ba040cceb --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/EducationalAttendanceViewModel.cs @@ -0,0 +1,21 @@ +using Dfe.Academies.Contracts.V1.EducationalPerformance; + + +namespace Dfe.PrepareConversions.ViewModels; + +public class EducationalAttendanceViewModel +{ + public string Year { get; set; } + public string OverallAbsence { get; set; } + public string PersistentAbsence { get; set; } + + public static EducationalAttendanceViewModel Build(SchoolAbsenceDataDto dto) + { + return new EducationalAttendanceViewModel + { + Year = dto.Year, + OverallAbsence = dto.OverallAbsence, + PersistentAbsence = dto.PersistentAbsence, + }; + } +} diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/TaskListViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/TaskListViewModel.cs index 2b1ca5b60..5d2825c13 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/TaskListViewModel.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/TaskListViewModel.cs @@ -17,6 +17,7 @@ public class TaskListViewModel public bool HasKeyStage2PerformanceTables { get; set; } public bool HasKeyStage4PerformanceTables { get; set; } public bool HasKeyStage5PerformanceTables { get; set; } + public bool HasAbsenceData { get; set; } public static TaskListViewModel Build(ProjectViewModel project) { From b47958108e9ede5b6b84849a768e5ba729d76aeb Mon Sep 17 00:00:00 2001 From: plockwood Date: Mon, 15 Jan 2024 16:09:29 +0000 Subject: [PATCH 2/8] new view model --- .../PerformanceDataViewModel.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs new file mode 100644 index 000000000..b0433973c --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs @@ -0,0 +1,38 @@ +using Dfe.PrepareConversions.Data.Services; +using Dfe.PrepareConversions.Models; +using Dfe.PrepareConversions.Services; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; + +namespace Dfe.PrepareConversions.Pages.TaskList.KeyStagePerformance +{ + public class PerformanceDataViewModel: BaseAcademyConversionProjectPageModel + { + private readonly ErrorService _errorService; + + public PerformanceDataViewModel(IAcademyConversionProjectRepository repository, ErrorService errorService) : base(repository) + { + _errorService = errorService; + } + + public override async Task OnPostAsync(int id) + { + if (YesChecked is true && string.IsNullOrWhiteSpace(ExternalApplicationFormUrl)) + { + ModelState.AddModelError(nameof(ExternalApplicationFormUrl), "You must enter valid link for the schools application form"); + } + + if (ModelState.IsValid) + { + + await _repository.SetProjectExternalApplicationForm(id, YesChecked.Value, YesChecked is true ? ExternalApplicationFormUrl : default); + + + return RedirectToPage(Links.ExternalApplicationForm.Index.Page, new { id }); + } + + _errorService.AddErrors(ModelState.Keys, ModelState); + return await base.OnGetAsync(id); + } + } +} From 889a5a2e9d44bb77f156101920c0fe39795e5359 Mon Sep 17 00:00:00 2001 From: plockwood Date: Tue, 16 Jan 2024 14:09:52 +0000 Subject: [PATCH 3/8] Work for additional info on the absence data --- .../Features/ApiClient.cs | 5 ++ .../Features/IApiClient.cs | 1 + .../Features/PathFor.cs | 1 + .../Models/SetPerformanceDataModel.cs | 30 +++++++ .../AcademyConversionProjectRepository.cs | 6 ++ .../IAcademyConversionProjectRepository.cs | 1 + .../PerformanceDataViewModel.cs | 83 +++++++++++++++++-- 7 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/SetPerformanceDataModel.cs diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs index 4f2e5cd26..bb39ea9e3 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs @@ -96,4 +96,9 @@ public async Task GetAllProjectsV2Async(AcademyConversionSe { return await AcademisationClient.PostAsync(PathFor.GetAllProjectsV2, JsonContent.Create(searchModel)); } + + public Task SetPerformanceData(int id, SetPerformanceDataModel setPerformanceDataModel) + { + return await AcademisationClient.PutAsync(string.Format(PathFor.SetExternalApplicationForm, id), JsonContent.Create(setPerformanceDataModel)); + } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/IApiClient.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/IApiClient.cs index f0b3f5327..81fa9b436 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/IApiClient.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/IApiClient.cs @@ -17,4 +17,5 @@ public interface IApiClient Task SetProjectExternalApplicationForm(int id, bool externalApplicationFormSaved, string externalApplicationFormUrl); Task SetSchoolOverview(int id, SetSchoolOverviewModel updatedSchoolOverview); + Task SetPerformanceData(int id, SetPerformanceDataModel setPerformanceDataModel); } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/PathFor.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/PathFor.cs index 4070206eb..3278b9a55 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/PathFor.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/PathFor.cs @@ -18,6 +18,7 @@ public PathFor(IFeatureManager features) public static string GetFilterParameters => "/legacy/projects/status"; public static string AddProjectNote => "/legacy/project/{0}/notes"; public static string SetExternalApplicationForm => "/conversion-project/{0}/setExternalApplicationForm"; + public static string SetPerformanceData => "/conversion-project/{0}/SetPerformanceData"; public static string SetSchoolOverview => "/conversion-project/{0}/SetSchoolOverview"; public static string GetAllProjectsV2 => "/conversion-project/projects"; diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/SetPerformanceDataModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/SetPerformanceDataModel.cs new file mode 100644 index 000000000..8707d6ed6 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/SetPerformanceDataModel.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dfe.PrepareConversions.Data.Models +{ + public class SetPerformanceDataModel + { + public SetPerformanceDataModel(int id, + string? keyStage2PerformanceAdditionalInformation, + string? keyStage4PerformanceAdditionalInformation, + string? keyStage5PerformanceAdditionalInformation, + string? educationalAttendanceAdditionalInformation) + { + Id = id; + KeyStage2PerformanceAdditionalInformation = keyStage2PerformanceAdditionalInformation; + KeyStage4PerformanceAdditionalInformation = keyStage4PerformanceAdditionalInformation; + KeyStage5PerformanceAdditionalInformation = keyStage5PerformanceAdditionalInformation; + EducationalAttendanceAdditionalInformation = educationalAttendanceAdditionalInformation; + } + + public int Id { get; set; } + public string? KeyStage2PerformanceAdditionalInformation { get; set; } + public string? KeyStage4PerformanceAdditionalInformation { get; set; } + public string? KeyStage5PerformanceAdditionalInformation { get; set; } + public string? EducationalAttendanceAdditionalInformation { get; set; } + } +} diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs index 678027f19..4f1b4ca4a 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs @@ -238,6 +238,12 @@ public async Task SetProjectExternalApplicationForm(int id, bool externalApplica HttpResponseMessage result = await _apiClient.SetProjectExternalApplicationForm(id, externalApplicationFormSaved, externalApplicationFormUrl); if (result.IsSuccessStatusCode is false) throw new ApiResponseException($"Request to Api failed | StatusCode - {result.StatusCode}"); } + + public async Task SetProjectExternalApplicationForm(int id, SetPerformanceDataModel setPerformanceDataModel) + { + HttpResponseMessage result = await _apiClient.SetProjectExternalApplicationForm(id, setPerformanceDataModel); + if (result.IsSuccessStatusCode is false) throw new ApiResponseException($"Request to Api failed | StatusCode - {result.StatusCode}"); + } public async Task SetSchoolOverview(int id, SetSchoolOverviewModel updatedSchoolOverview) { HttpResponseMessage result = await _apiClient.SetSchoolOverview(id, updatedSchoolOverview); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/IAcademyConversionProjectRepository.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/IAcademyConversionProjectRepository.cs index aec6ab943..f2ce71618 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/IAcademyConversionProjectRepository.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/IAcademyConversionProjectRepository.cs @@ -43,6 +43,7 @@ Task>>> GetAllPro Task CreateProject(CreateNewProject newProject); Task SetProjectExternalApplicationForm(int id, bool externalApplicationFormSaved, string externalApplicationFormUrl); Task SetSchoolOverview(int id, SetSchoolOverviewModel updatedSchoolOverview); + Task SetPerformanceData(int id, SetPerformanceDataModel setPerformanceDataModel); Task> GetFilterParameters(); Task> AddProjectNote(int id, AddProjectNote addProjectNote); } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs index b0433973c..edb6f583c 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs @@ -1,7 +1,11 @@ -using Dfe.PrepareConversions.Data.Services; +using Dfe.PrepareConversions.Data.Models; +using Dfe.PrepareConversions.Data; +using Dfe.PrepareConversions.Data.Services; using Dfe.PrepareConversions.Models; using Dfe.PrepareConversions.Services; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; +using System; using System.Threading.Tasks; namespace Dfe.PrepareConversions.Pages.TaskList.KeyStagePerformance @@ -15,12 +19,23 @@ public PerformanceDataViewModel(IAcademyConversionProjectRepository repository, _errorService = errorService; } + [BindProperty] + public SetPerformanceDataModel Model { get; set; } + + public bool ShowError => _errorService.HasErrors(); + + public string SuccessPage + { + get => TempData["SuccessPage"].ToString(); + set => TempData["SuccessPage"] = value; + } + public override async Task OnPostAsync(int id) { - if (YesChecked is true && string.IsNullOrWhiteSpace(ExternalApplicationFormUrl)) - { - ModelState.AddModelError(nameof(ExternalApplicationFormUrl), "You must enter valid link for the schools application form"); - } + //if (YesChecked is true && string.IsNullOrWhiteSpace(ExternalApplicationFormUrl)) + //{ + // ModelState.AddModelError(nameof(ExternalApplicationFormUrl), "You must enter valid link for the schools application form"); + //} if (ModelState.IsValid) { @@ -33,6 +48,64 @@ public override async Task OnPostAsync(int id) _errorService.AddErrors(ModelState.Keys, ModelState); return await base.OnGetAsync(id); + + + bool schoolAndTrustInformationSectionComplete = AcademyConversionProject.SchoolAndTrustInformationSectionComplete != null && + AcademyConversionProject.SchoolAndTrustInformationSectionComplete.Value; + if (schoolAndTrustInformationSectionComplete && !Project.HeadTeacherBoardDate.HasValue) + { + _errorService.AddError( + $"/task-list/{id}/confirm-school-trust-information-project-dates/advisory-board-date?return=%2FTaskList%2FSchoolAndTrustInformation/ConfirmSchoolAndTrustInformation&fragment=advisory-board-date", + "Set an Advisory board date before you generate your project template"); + } + + if (AcademyConversionProject.LocalAuthorityInformationTemplateSentDate.HasValue && + AcademyConversionProject.LocalAuthorityInformationTemplateReturnedDate.HasValue && + AcademyConversionProject.LocalAuthorityInformationTemplateSentDate > AcademyConversionProject.LocalAuthorityInformationTemplateReturnedDate) + { + _errorService.AddError("returnedDateBeforeSentDateError", "The returned template date be must on or after sent date"); + } + + if (AcademyConversionProject.EndOfCurrentFinancialYear.HasValue && + AcademyConversionProject.EndOfNextFinancialYear.HasValue && + AcademyConversionProject.EndOfCurrentFinancialYear != DateTime.MinValue && + AcademyConversionProject.EndOfNextFinancialYear != DateTime.MinValue && + AcademyConversionProject.EndOfCurrentFinancialYear.Value.AddYears(1).AddDays(-1) > AcademyConversionProject.EndOfNextFinancialYear) + { + _errorService.AddError( + $"/task-list/{id}/confirm-school-budget-information/update-school-budget-information?return=%2FTaskList%2FSchoolBudgetInformation/ConfirmSchoolBudgetInformation&fragment=financial-year", + "The next financial year cannot be before or within a year of the current financial year"); + } + + _errorService.AddErrors(Request.Form.Keys, ModelState); + if (_errorService.HasErrors()) + { + RePopDatePickerModelsAfterValidationFail(); + return Page(); + } + + ApiResponse response = await _repository.UpdateProject(id, Build()); + + if (!response.Success) + { + _errorService.AddApiError(); + return Page(); + } + + (string returnPage, string fragment) = GetReturnPageAndFragment(); + if (!string.IsNullOrWhiteSpace(returnPage)) + { + return RedirectToPage(returnPage, null, new { id }, fragment); + } + + return RedirectToPage(SuccessPage, new { id }); + } + + private (string, string) GetReturnPageAndFragment() + { + Request.Query.TryGetValue("return", out StringValues returnQuery); + Request.Query.TryGetValue("fragment", out StringValues fragmentQuery); + return (returnQuery, fragmentQuery); } } } From 56e41f1c8992edba443387483388db22200414f4 Mon Sep 17 00:00:00 2001 From: plockwood Date: Fri, 19 Jan 2024 16:24:14 +0000 Subject: [PATCH 4/8] Performance data for educational attendance additional info fixes and change to move to new endpoint for all performance data --- .../Features/ApiClient.cs | 4 +- .../Models/AcademyConversionProject.cs | 1 + .../AcademyConversionProjectRepository.cs | 4 +- .../Dfe.PrepareConversions/Models/Links.cs | 3 + .../DownloadProjectTemplate.cshtml.cs | 2 +- .../Pages/TaskList/Index.cshtml.cs | 2 +- .../EducationalAttendance.cshtml | 2 +- ...onalAttendanceAdditionalInformation.cshtml | 44 +++++++++ ...formanceTablesAdditionalInformation.cshtml | 4 +- ...formanceTablesAdditionalInformation.cshtml | 4 +- ...formanceTablesAdditionalInformation.cshtml | 4 +- .../PerformanceDataViewModel.cs | 98 ++++++++++--------- .../TaskList/PreviewProjectTemplate.cshtml.cs | 2 +- ...emyConversionProjectItemsCacheDecorator.cs | 5 + .../ViewModels/ProjectViewModel.cs | 2 + 15 files changed, 123 insertions(+), 58 deletions(-) create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendanceAdditionalInformation.cshtml diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs index bb39ea9e3..595c22c81 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs @@ -97,8 +97,8 @@ public async Task GetAllProjectsV2Async(AcademyConversionSe return await AcademisationClient.PostAsync(PathFor.GetAllProjectsV2, JsonContent.Create(searchModel)); } - public Task SetPerformanceData(int id, SetPerformanceDataModel setPerformanceDataModel) + public async Task SetPerformanceData(int id, SetPerformanceDataModel setPerformanceDataModel) { - return await AcademisationClient.PutAsync(string.Format(PathFor.SetExternalApplicationForm, id), JsonContent.Create(setPerformanceDataModel)); + return await AcademisationClient.PutAsync(string.Format(PathFor.SetPerformanceData, id), JsonContent.Create(setPerformanceDataModel)); } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AcademyConversionProject.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AcademyConversionProject.cs index 9290efa85..5b3f18d75 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AcademyConversionProject.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AcademyConversionProject.cs @@ -117,6 +117,7 @@ public class AcademyConversionProject public string KeyStage2PerformanceAdditionalInformation { get; set; } public string KeyStage4PerformanceAdditionalInformation { get; set; } public string KeyStage5PerformanceAdditionalInformation { get; set; } + public string EducationalAttendanceAdditionalInformation { get; set; } // assigned user public User AssignedUser { get; set; } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs index 4f1b4ca4a..26f64dc7d 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs @@ -239,9 +239,9 @@ public async Task SetProjectExternalApplicationForm(int id, bool externalApplica if (result.IsSuccessStatusCode is false) throw new ApiResponseException($"Request to Api failed | StatusCode - {result.StatusCode}"); } - public async Task SetProjectExternalApplicationForm(int id, SetPerformanceDataModel setPerformanceDataModel) + public async Task SetPerformanceData(int id, SetPerformanceDataModel setPerformanceDataModel) { - HttpResponseMessage result = await _apiClient.SetProjectExternalApplicationForm(id, setPerformanceDataModel); + HttpResponseMessage result = await _apiClient.SetPerformanceData(id, setPerformanceDataModel); if (result.IsSuccessStatusCode is false) throw new ApiResponseException($"Request to Api failed | StatusCode - {result.StatusCode}"); } public async Task SetSchoolOverview(int id, SetSchoolOverviewModel updatedSchoolOverview) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs index 6dbdf2e71..539b8a558 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs @@ -183,6 +183,9 @@ public static class KeyStagePerformanceSection public static readonly LinkItem EducationalAttendance = AddLinkItem(page: "/TaskList/KeyStagePerformance/EducationalAttendance"); + + public static readonly LinkItem EducationalAttendanceAdditionalInformation = + AddLinkItem(page: "/TaskList/KeyStagePerformance/EducationalAttendanceAdditionalInformation"); } public static class Decision diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/DownloadProjectTemplate.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/DownloadProjectTemplate.cshtml.cs index 151826c66..23d8e1edc 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/DownloadProjectTemplate.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/DownloadProjectTemplate.cshtml.cs @@ -62,7 +62,7 @@ public async Task OnGetHtbTemplateAsync(int id) SchoolPerformance schoolPerformance = await _schoolPerformanceService.GetSchoolPerformanceByUrn(project.Urn.ToString()); Data.Models.SchoolOverview schoolOverview = await _schoolOverviewService.GetSchoolOverviewByUrn(project.Urn.ToString()); - KeyStagePerformance keyStagePerformance = await _keyStagePerformanceService.GetKeyStagePerformance(project.Urn.ToString()); + Data.Models.KeyStagePerformance.KeyStagePerformance keyStagePerformance = await _keyStagePerformanceService.GetKeyStagePerformance(project.Urn.ToString()); var DocumentGenerator = new DocumentGenerator(); HtbTemplate document = DocumentGenerator.GenerateDocument(response, schoolPerformance, schoolOverview, keyStagePerformance, project, out byte[] documentByteArray); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml.cs index 052e15fdb..e3cff293a 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml.cs @@ -51,7 +51,7 @@ public override async Task OnGetAsync(int id) "Set an Advisory board date before you generate your project template"); } - KeyStagePerformance keyStagePerformance = await _keyStagePerformanceService.GetKeyStagePerformance(Project?.SchoolURN); + Data.Models.KeyStagePerformance.KeyStagePerformance keyStagePerformance = await _keyStagePerformanceService.GetKeyStagePerformance(Project?.SchoolURN); // 16 plus = 6, All-through = 7, Middle deemed primary = 3, Middle deemed secondary = 5, Not applicable = 0, Nursery = 1, Primary = 2, Secondary = 4 if (Project != null) TaskList = TaskListViewModel.Build(Project); if (TaskList != null) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendance.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendance.cshtml index f0c43fac0..486ac38b3 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendance.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendance.cshtml @@ -30,7 +30,7 @@
    - +
    diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendanceAdditionalInformation.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendanceAdditionalInformation.cshtml new file mode 100644 index 000000000..a80a61d35 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/EducationalAttendanceAdditionalInformation.cshtml @@ -0,0 +1,44 @@ +@page "/task-list/{id:int}/EducationalAttendance/additional-information" +@using Dfe.PrepareConversions.TagHelpers +@model Dfe.PrepareConversions.Pages.TaskList.KeyStagePerformance.PerformanceDataViewModel +@{ + Model.SuccessPage = Links.KeyStagePerformanceSection.EducationalAttendance.Page; + ViewData["Title"] = "Educational Attendance additional information"; +} + +@section BeforeMain +{ + +} + +@if (Model.ShowError) +{ + +} + +
    +
    + @Model.Project.SchoolName +

    Educational Attendance

    +

    + These performance tables will automatically go into your project template. +

    +

    + Source of data: Find and compare school performance (opens in new tab) +

    +
    + There is no 2019 to 2020 absence data because of the pandemic. 2020 to 2021 data is limited. +
    +
    +
    + @await Component.InvokeAsync("EducationalAttendance") +
    + + + + + + +
    \ No newline at end of file diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage2PerformanceTablesAdditionalInformation.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage2PerformanceTablesAdditionalInformation.cshtml index 4d6862c65..8f633e7a7 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage2PerformanceTablesAdditionalInformation.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage2PerformanceTablesAdditionalInformation.cshtml @@ -1,6 +1,6 @@ @page "/task-list/{id:int}/key-stage-2-performance-tables/additional-information" @using Dfe.PrepareConversions.TagHelpers -@model Dfe.PrepareConversions.Pages.UpdateAcademyConversionProjectPageModel +@model Dfe.PrepareConversions.Pages.TaskList.KeyStagePerformance.PerformanceDataViewModel @{ Model.SuccessPage = Links.KeyStagePerformanceSection.KeyStage2PerformanceTables.Page; ViewData["Title"] = "Key stage 2 performance tables additional information"; @@ -32,7 +32,7 @@
    - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage4PerformanceTablesAdditionalInformation.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage4PerformanceTablesAdditionalInformation.cshtml index 2c6969315..6a009ef50 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage4PerformanceTablesAdditionalInformation.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage4PerformanceTablesAdditionalInformation.cshtml @@ -1,6 +1,6 @@ @page "/task-list/{id:int}/key-stage-4-performance-tables/additional-information" @using Dfe.PrepareConversions.TagHelpers -@model Dfe.PrepareConversions.Pages.UpdateAcademyConversionProjectPageModel +@model Dfe.PrepareConversions.Pages.TaskList.KeyStagePerformance.PerformanceDataViewModel @{ Model.SuccessPage = Links.KeyStagePerformanceSection.KeyStage4PerformanceTables.Page; ViewData["Title"] = "Key stage 4 performance tables additional information"; @@ -31,7 +31,7 @@
    - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage5PerformanceTablesAdditionalInformation.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage5PerformanceTablesAdditionalInformation.cshtml index 7442dd068..f081d4cd6 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage5PerformanceTablesAdditionalInformation.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/KeyStage5PerformanceTablesAdditionalInformation.cshtml @@ -1,6 +1,6 @@ @page "/task-list/{id:int}/key-stage-5-performance-tables/additional-information" @using Dfe.PrepareConversions.TagHelpers -@model Dfe.PrepareConversions.Pages.UpdateAcademyConversionProjectPageModel +@model Dfe.PrepareConversions.Pages.TaskList.KeyStagePerformance.PerformanceDataViewModel @{ Model.SuccessPage = Links.KeyStagePerformanceSection.KeyStage5PerformanceTables.Page; ViewData["Title"] = "Key stage 5 performance tables additional information"; @@ -32,7 +32,7 @@ - + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs index edb6f583c..11fb1a1c4 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Primitives; using System; using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; namespace Dfe.PrepareConversions.Pages.TaskList.KeyStagePerformance { @@ -19,8 +20,22 @@ public PerformanceDataViewModel(IAcademyConversionProjectRepository repository, _errorService = errorService; } - [BindProperty] - public SetPerformanceDataModel Model { get; set; } + // key stage performance tables + [BindProperty(Name = "key-stage-2-additional-information")] + [DisplayFormat(ConvertEmptyStringToNull = false)] + public string KeyStage2PerformanceAdditionalInformation { get; set; } + + [BindProperty(Name = "key-stage-4-additional-information")] + [DisplayFormat(ConvertEmptyStringToNull = false)] + public string KeyStage4PerformanceAdditionalInformation { get; set; } + + [BindProperty(Name = "key-stage-5-additional-information")] + [DisplayFormat(ConvertEmptyStringToNull = false)] + public string KeyStage5PerformanceAdditionalInformation { get; set; } + + [BindProperty(Name = "educational-attendance-additional-information")] + [DisplayFormat(ConvertEmptyStringToNull = false)] + public string EducationalAttendanceAdditionalInformation { get; set; } public bool ShowError => _errorService.HasErrors(); @@ -30,8 +45,22 @@ public string SuccessPage set => TempData["SuccessPage"] = value; } + public override async Task OnGetAsync(int id) + { + await base.OnGetAsync(id); + + KeyStage2PerformanceAdditionalInformation = Project.KeyStage2PerformanceAdditionalInformation; + KeyStage4PerformanceAdditionalInformation = Project.KeyStage4PerformanceAdditionalInformation; + KeyStage5PerformanceAdditionalInformation = Project.KeyStage5PerformanceAdditionalInformation; + EducationalAttendanceAdditionalInformation = Project.EducationalAttendanceAdditionalInformation; + + return Page(); + } + public override async Task OnPostAsync(int id) { + await SetProject(id); + //if (YesChecked is true && string.IsNullOrWhiteSpace(ExternalApplicationFormUrl)) //{ // ModelState.AddModelError(nameof(ExternalApplicationFormUrl), "You must enter valid link for the schools application form"); @@ -39,66 +68,47 @@ public override async Task OnPostAsync(int id) if (ModelState.IsValid) { + SetExistingValuesIfNotChanged(); - await _repository.SetProjectExternalApplicationForm(id, YesChecked.Value, YesChecked is true ? ExternalApplicationFormUrl : default); + await _repository.SetPerformanceData(id, new SetPerformanceDataModel(id, + KeyStage2PerformanceAdditionalInformation, + KeyStage4PerformanceAdditionalInformation, + KeyStage5PerformanceAdditionalInformation, + EducationalAttendanceAdditionalInformation)); + (string returnPage, string fragment) = GetReturnPageAndFragment(); + if (!string.IsNullOrWhiteSpace(returnPage)) + { + return RedirectToPage(returnPage, null, new { id }, fragment); + } - return RedirectToPage(Links.ExternalApplicationForm.Index.Page, new { id }); + return RedirectToPage(SuccessPage, new { id }); } _errorService.AddErrors(ModelState.Keys, ModelState); return await base.OnGetAsync(id); + } - - bool schoolAndTrustInformationSectionComplete = AcademyConversionProject.SchoolAndTrustInformationSectionComplete != null && - AcademyConversionProject.SchoolAndTrustInformationSectionComplete.Value; - if (schoolAndTrustInformationSectionComplete && !Project.HeadTeacherBoardDate.HasValue) - { - _errorService.AddError( - $"/task-list/{id}/confirm-school-trust-information-project-dates/advisory-board-date?return=%2FTaskList%2FSchoolAndTrustInformation/ConfirmSchoolAndTrustInformation&fragment=advisory-board-date", - "Set an Advisory board date before you generate your project template"); - } - - if (AcademyConversionProject.LocalAuthorityInformationTemplateSentDate.HasValue && - AcademyConversionProject.LocalAuthorityInformationTemplateReturnedDate.HasValue && - AcademyConversionProject.LocalAuthorityInformationTemplateSentDate > AcademyConversionProject.LocalAuthorityInformationTemplateReturnedDate) - { - _errorService.AddError("returnedDateBeforeSentDateError", "The returned template date be must on or after sent date"); - } - - if (AcademyConversionProject.EndOfCurrentFinancialYear.HasValue && - AcademyConversionProject.EndOfNextFinancialYear.HasValue && - AcademyConversionProject.EndOfCurrentFinancialYear != DateTime.MinValue && - AcademyConversionProject.EndOfNextFinancialYear != DateTime.MinValue && - AcademyConversionProject.EndOfCurrentFinancialYear.Value.AddYears(1).AddDays(-1) > AcademyConversionProject.EndOfNextFinancialYear) - { - _errorService.AddError( - $"/task-list/{id}/confirm-school-budget-information/update-school-budget-information?return=%2FTaskList%2FSchoolBudgetInformation/ConfirmSchoolBudgetInformation&fragment=financial-year", - "The next financial year cannot be before or within a year of the current financial year"); + private void SetExistingValuesIfNotChanged() + { + if (KeyStage2PerformanceAdditionalInformation is null) { + KeyStage2PerformanceAdditionalInformation = Project.KeyStage2PerformanceAdditionalInformation; } - _errorService.AddErrors(Request.Form.Keys, ModelState); - if (_errorService.HasErrors()) + if (KeyStage4PerformanceAdditionalInformation is null) { - RePopDatePickerModelsAfterValidationFail(); - return Page(); + KeyStage4PerformanceAdditionalInformation = Project.KeyStage4PerformanceAdditionalInformation; } - ApiResponse response = await _repository.UpdateProject(id, Build()); - - if (!response.Success) + if (KeyStage5PerformanceAdditionalInformation is null) { - _errorService.AddApiError(); - return Page(); + KeyStage5PerformanceAdditionalInformation = Project.KeyStage5PerformanceAdditionalInformation; } - (string returnPage, string fragment) = GetReturnPageAndFragment(); - if (!string.IsNullOrWhiteSpace(returnPage)) + if (EducationalAttendanceAdditionalInformation is null) { - return RedirectToPage(returnPage, null, new { id }, fragment); + EducationalAttendanceAdditionalInformation = Project.EducationalAttendanceAdditionalInformation; } - - return RedirectToPage(SuccessPage, new { id }); } private (string, string) GetReturnPageAndFragment() diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml.cs index e194d02a4..7adface64 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml.cs @@ -42,7 +42,7 @@ public override async Task OnGetAsync(int id) private async Task SetKeyStagePerformancePageData(ProjectViewModel project) { - KeyStagePerformance keyStagePerformance = + Data.Models.KeyStagePerformance.KeyStagePerformance keyStagePerformance = await _keyStagePerformanceService.GetKeyStagePerformance(project.SchoolURN); // 16 plus = 6, All-through = 7, Middle deemed primary = 3, Middle deemed secondary = 5, Not applicable = 0, Nursery = 1, Primary = 2, Secondary = 4 diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/AcademyConversionProjectItemsCacheDecorator.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/AcademyConversionProjectItemsCacheDecorator.cs index 916d64f02..ea6fbc62e 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/AcademyConversionProjectItemsCacheDecorator.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/AcademyConversionProjectItemsCacheDecorator.cs @@ -95,4 +95,9 @@ public async Task SetSchoolOverview(int id, SetSchoolOverviewModel updatedSchool { await _innerRepository.SetSchoolOverview(id, updatedSchoolOverview); } + + public async Task SetPerformanceData(int id, SetPerformanceDataModel setPerformanceDataModel) + { + await _innerRepository.SetPerformanceData(id, setPerformanceDataModel); + } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs index 96f8b84de..a8ca6ecab 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs @@ -108,6 +108,7 @@ public ProjectViewModel(AcademyConversionProject project) KeyStage2PerformanceAdditionalInformation = project.KeyStage2PerformanceAdditionalInformation; KeyStage4PerformanceAdditionalInformation = project.KeyStage4PerformanceAdditionalInformation; KeyStage5PerformanceAdditionalInformation = project.KeyStage5PerformanceAdditionalInformation; + EducationalAttendanceAdditionalInformation = project.EducationalAttendanceAdditionalInformation; AssignedUser = project.AssignedUser; @@ -222,6 +223,7 @@ public ProjectViewModel(AcademyConversionProject project) public string KeyStage2PerformanceAdditionalInformation { get; set; } public string KeyStage4PerformanceAdditionalInformation { get; set; } public string KeyStage5PerformanceAdditionalInformation { get; set; } + public string EducationalAttendanceAdditionalInformation { get; set; } public User AssignedUser { get; set; } From ed9c93152fc2cf0fc96dd62cce8c601fd84f4429 Mon Sep 17 00:00:00 2001 From: plockwood Date: Mon, 22 Jan 2024 15:20:52 +0000 Subject: [PATCH 5/8] Show Attendance data for SEN and PRU only and only show last 3 years of attendance data --- .../Models/AcademyConversionProject.cs | 1 + .../EducationalAttendance/default.cshtml | 36 +++++++++---------- .../Pages/TaskList/Index.cshtml | 2 +- .../ViewModels/ProjectViewModel.cs | 5 +++ 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AcademyConversionProject.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AcademyConversionProject.cs index 5b3f18d75..ae0fb4e5d 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AcademyConversionProject.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AcademyConversionProject.cs @@ -10,6 +10,7 @@ public class AcademyConversionProject public DateTime CreatedOn { get; set; } public string SchoolName { get; set; } public string SchoolPhase { get; set; } + public string SchoolType { get; set; } public string LocalAuthority { get; set; } public string ApplicationReferenceNumber { get; set; } public string ProjectStatus { get; set; } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml index e69bffbe8..689f9ae15 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml @@ -2,7 +2,9 @@ @using Dfe.PrepareConversions.TagHelpers @model IEnumerable
    - + @{ + var educationalAttendanceViewModels = Model.OrderByDescending(x => x.Year).ToList(); + } - @foreach (var vm in Model) + + @for (int i = 0; i < 3; i++) { + var vm = educationalAttendanceViewModels[i]; + } @@ -22,14 +27,10 @@ - @{ - var index = 0; - - @foreach (var vm in Model) - { - - index++; - } + @for (int i = 0; i < 3; i++) + { + var vm = educationalAttendanceViewModels[i]; + } @@ -43,8 +44,10 @@ - @foreach (var vm in Model) + @for (int i = 0; i < 3; i++) { + var vm = educationalAttendanceViewModels[i]; + } @@ -53,13 +56,10 @@ - @{ - index = 0; - @foreach (var vm in Model) - { - - index++; - } + @for (int i = 0; i < 3; i++) + { + var vm = educationalAttendanceViewModels[i]; + } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml index c103af7b7..a9bbc0dbd 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Index.cshtml @@ -167,7 +167,7 @@ } - @if (Model.TaskList.HasAbsenceData) + @if (Model.TaskList.HasAbsenceData && (Model.Project.IsPRU || Model.Project.IsSEN)) {
  • diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs index a8ca6ecab..4e57f7f36 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs @@ -20,6 +20,7 @@ public ProjectViewModel(AcademyConversionProject project) ApplicationReceivedDate = project.ApplicationReceivedDate.ToDateString(); AssignedDate = project.AssignedDate.ToDateString(); SchoolPhase = project.SchoolPhase; + SchoolType = project.SchoolType; HeadTeacherBoardDate = project.HeadTeacherBoardDate; LocalAuthorityInformationTemplateSentDate = project.LocalAuthorityInformationTemplateSentDate; @@ -125,6 +126,10 @@ public ProjectViewModel(AcademyConversionProject project) public string ApplicationReceivedDate { get; } public string AssignedDate { get; } public string SchoolPhase { get; } + public string SchoolType { get; } + + public bool IsPRU { get { return SchoolType.ToLower() == "pupil referal unit"; } } + public bool IsSEN { get { return SchoolType.ToLower().Contains("special"); } } public DateTime? HeadTeacherBoardDate { get; set; } public DateTime? LocalAuthorityInformationTemplateSentDate { get; set; } From 0e91eaee93f76d1189eb01d3d9ef7b28ea09c434 Mon Sep 17 00:00:00 2001 From: plockwood Date: Mon, 22 Jan 2024 16:26:10 +0000 Subject: [PATCH 6/8] Added attendance data to project preview and project document --- .../Models/HtbTemplate.cs | 6 ++ .../EducationalAttendance/default.cshtml | 4 +- .../TaskList/PreviewProjectTemplate.cshtml | 18 ++++ .../Resources/htb-template.docx | Bin 25014 -> 25106 bytes .../DocumentGenerator/DocumentGenerator.cs | 2 + .../EducationalAttendanceGenerator.cs | 86 ++++++++++++++++++ 6 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/Services/DocumentGenerator/EducationalAttendanceGenerator.cs diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/HtbTemplate.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/HtbTemplate.cs index 7a833d12d..66c4111ff 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/HtbTemplate.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/HtbTemplate.cs @@ -217,6 +217,7 @@ public class HtbTemplate public IEnumerable KeyStage2 { get; set; } public KeyStage4PerformanceTableViewModel KeyStage4 { get; set; } public IEnumerable KeyStage5 { get; set; } + public IEnumerable EducationalAttendance { get; set; } public static HtbTemplate Build(AcademyConversionProject project, SchoolPerformance schoolPerformance, @@ -312,6 +313,11 @@ public static HtbTemplate Build(AcademyConversionProject project, htbTemplate.KeyStage5 = keyStagePerformance.KeyStage5.Select(KeyStage5PerformanceTableViewModel.Build).OrderByDescending(ks => ks.Year); } + if (keyStagePerformance.HasSchoolAbsenceData) + { + htbTemplate.EducationalAttendance = keyStagePerformance.SchoolAbsenceData.Select(EducationalAttendanceViewModel.Build).OrderByDescending(ks => ks.Year); + } + return htbTemplate; } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml index 689f9ae15..7b60a9606 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/EducationalAttendance/default.cshtml @@ -8,7 +8,7 @@
  • @@ -12,8 +14,11 @@
    @vm.Year
    @ViewData["SchoolName"]@vm.OverallAbsence@vm.OverallAbsence
    @vm.Year
    @ViewData["SchoolName"]@vm.PersistentAbsence@vm.PersistentAbsence
    @@ -39,7 +39,7 @@
    -

    Overall Absence

    +

    Overall absence

    Percentage of mornings or afternoons recorded as an absence from school for any reason, across the full academic year.

    diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml index c4bfa2b5c..ad1761c91 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/PreviewProjectTemplate.cshtml @@ -207,6 +207,24 @@ } + +@if (Model.TaskList.HasAbsenceData && (Model.Project.IsSEN || Model.Project.IsPRU)) +{ +

    Educational Attendance

    +
    +
    +

    + Educational Attendance details +

    +
    +
    + @await Component.InvokeAsync("EducationalAttendance") +
    + +
    +
    +
    +}

    diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Resources/htb-template.docx b/Dfe.PrepareConversions/Dfe.PrepareConversions/Resources/htb-template.docx index bf96f663508bd99873ffcba218916900366c5088..81d88fbf391496cd73a3650327094f2fdf1177f1 100644 GIT binary patch delta 8205 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 W7;a-piO6jP547Y#6*T$B_P+oIlv%I< delta 8082 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 diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/DocumentGenerator/DocumentGenerator.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/DocumentGenerator/DocumentGenerator.cs index 30d366e07..eb53a16c4 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/DocumentGenerator/DocumentGenerator.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/DocumentGenerator/DocumentGenerator.cs @@ -13,6 +13,7 @@ using static Dfe.PrepareConversions.Services.DocumentGenerator.SchoolAndTrustInformationAndProjectDatesGenerator; using static Dfe.PrepareConversions.Services.DocumentGenerator.SchoolOverviewGenerator; using static Dfe.PrepareConversions.Services.DocumentGenerator.OfstedInformationGenerator; +using static Dfe.PrepareConversions.Services.DocumentGenerator.EducationalAttendanceGenerator; using static Dfe.PrepareConversions.Services.DocumentGenerator.KeyStage2Generator; using static Dfe.PrepareConversions.Services.DocumentGenerator.KeyStage4Generator; using static Dfe.PrepareConversions.Services.DocumentGenerator.KeyStage5Generator; @@ -45,6 +46,7 @@ public HtbTemplate GenerateDocument(ApiResponse respon AddKeyStage2Information(documentBuilder, document, project); AddKeyStage4Information(documentBuilder, document, project); AddKeyStage5Information(documentBuilder, document, project); + AddEducationalAttendanceInformation(documentBuilder, document, project); documentByteArray = documentBuilder.Build(); return document; } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/DocumentGenerator/EducationalAttendanceGenerator.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/DocumentGenerator/EducationalAttendanceGenerator.cs new file mode 100644 index 000000000..cdf8e7808 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/DocumentGenerator/EducationalAttendanceGenerator.cs @@ -0,0 +1,86 @@ +using Dfe.PrepareConversions.Data.Models; +using Dfe.PrepareConversions.DocumentGeneration.Elements; +using Dfe.PrepareConversions.DocumentGeneration.Interfaces; +using Dfe.PrepareConversions.Models; +using Dfe.PrepareConversions.Utils; +using Dfe.PrepareConversions.ViewModels; +using System.Collections.Generic; +using static Dfe.PrepareConversions.Utils.KeyStageDataStatusHelper; +using static Dfe.PrepareConversions.Services.DocumentGenerator.DocumentGenerator; +using DocumentFormat.OpenXml.EMMA; +using System.Linq; +using System.Reflection.Metadata.Ecma335; + +namespace Dfe.PrepareConversions.Services.DocumentGenerator; + +public static class EducationalAttendanceGenerator +{ + public static void AddEducationalAttendanceInformation(IDocumentBuilder documentBuilder, HtbTemplate document, AcademyConversionProject project) + { + if (document.EducationalAttendance == null || !project.SchoolType.ToLower().Contains("special")) + { + documentBuilder.ReplacePlaceholderWithContent("EducationalAttendanceData", builder => builder.AddParagraph("")); + return; + } + + documentBuilder.ReplacePlaceholderWithContent("EducationalAttendanceData", builder => + { + builder.AddHeading("Educational Attendance", HeadingLevel.One); + builder.AddHeading($"Overall absence", HeadingLevel.Two); + + var educationalAttendanceViewModels = document.EducationalAttendance.OrderByDescending(x => x.Year).ToList(); + var table = new List(); + + var textElements = new List() { new TextElement("") { Bold = true } }; + + for (int i = 0; i < 3; i++) + { + var vm = educationalAttendanceViewModels[i]; + + textElements.Add(new TextElement(vm.Year) { Bold = true }); + } + + table.Add(textElements.ToArray()); + textElements = new List() { new TextElement($"{project.SchoolName}") { Bold = true }, }; + + for (int i = 0; i < 3; i++) + { + var vm = educationalAttendanceViewModels[i]; + + textElements.Add(new TextElement(vm.OverallAbsence) { Bold = true }); + } + table.Add(textElements.ToArray()); + builder.AddTable(table); + + ///******************/// + table = new List(); + textElements = new List() { new TextElement("") { Bold = true }, }; + builder.AddHeading($"Persistent absence of 10% or more", HeadingLevel.Two); + + for (int i = 0; i < 3; i++) + { + var vm = educationalAttendanceViewModels[i]; + + textElements.Add(new TextElement(vm.Year) { Bold = true }); + } + + table.Add(textElements.ToArray()); + textElements = new List() { new TextElement($"{project.SchoolName}") { Bold = true }, }; + + for (int i = 0; i < 3; i++) + { + var vm = educationalAttendanceViewModels[i]; + + textElements.Add(new TextElement(vm.PersistentAbsence) { Bold = true }); + } + table.Add(textElements.ToArray()); + builder.AddTable(table); + + builder.AddParagraph(""); + builder.AddTable(new List + { + new[] { new TextElement("Additional information") { Bold = true }, new TextElement(project.EducationalAttendanceAdditionalInformation) } + }); + }); + } +} \ No newline at end of file From 0c7fe92371d0bcb6a0d051157c174a9ac915c57c Mon Sep 17 00:00:00 2001 From: plockwood Date: Thu, 25 Jan 2024 10:20:06 +0000 Subject: [PATCH 7/8] merge fixes --- .../Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs index 2a85ae59e..cb829d498 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/ViewModels/ProjectViewModel.cs @@ -142,7 +142,6 @@ public ProjectViewModel(AcademyConversionProject project) public bool IsPRU { get { return SchoolType.ToLower() == "pupil referal unit"; } } public bool IsSEN { get { return SchoolType.ToLower().Contains("special"); } } public DateTime? HeadTeacherBoardDate { get; set; } - public string SchoolType { get; set; } public DateTime? LocalAuthorityInformationTemplateSentDate { get; set; } public DateTime? LocalAuthorityInformationTemplateReturnedDate { get; set; } @@ -256,5 +255,4 @@ public ProjectViewModel(AcademyConversionProject project) protected override string TypeAndRouteValue => AcademyTypeAndRoute; public override bool IsExternalSchoolApplication => string.IsNullOrEmpty(this.ApplicationReferenceNumber); - public bool IsPRU => SchoolType.ToLower().Equals("pupil referral unit"); } From c4ec479ddc3c16f7868f37beac449902e85e0eaf Mon Sep 17 00:00:00 2001 From: plockwood Date: Thu, 25 Jan 2024 16:04:20 +0000 Subject: [PATCH 8/8] Fixed AngleSharp tests --- .../Pages/BaseIntegrationTests.MockData.cs | 16 +++++++++ ...ceAdditionalInformationIntegrationTests.cs | 6 +--- ...ceAdditionalInformationIntegrationTests.cs | 6 +--- ...ceAdditionalInformationIntegrationTests.cs | 6 +--- .../PreviewHTBIntegrationTests.cs | 18 ++-------- .../Pages/NewProject/SearchTrust.cshtml.cs | 3 ++ .../PerformanceDataViewModel.cs | 35 ++++++++++++------- 7 files changed, 47 insertions(+), 43 deletions(-) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/BaseIntegrationTests.MockData.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/BaseIntegrationTests.MockData.cs index 2fd9a230b..bd434f0bd 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/BaseIntegrationTests.MockData.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/BaseIntegrationTests.MockData.cs @@ -148,6 +148,22 @@ public ProjectNote AddPostProjectNote(int id, AddProjectNote request) return response; } + public SetPerformanceDataModel AddPutPerformanceData(AcademyConversionProject project) + { + SetPerformanceDataModel request = _fixture + .Build() + .OmitAutoProperties() + .With(x => x.Id, project.Id) + .With(x => x.KeyStage2PerformanceAdditionalInformation, project.KeyStage2PerformanceAdditionalInformation) + .With(x => x.KeyStage4PerformanceAdditionalInformation, project.KeyStage4PerformanceAdditionalInformation) + .With(x => x.KeyStage5PerformanceAdditionalInformation, project.KeyStage5PerformanceAdditionalInformation) + .With(x => x.EducationalAttendanceAdditionalInformation, project.EducationalAttendanceAdditionalInformation) + .Create(); + + _factory.AddPutWithJsonRequest(string.Format(PathFor.SetPerformanceData, project.Id), request, project); + return request; + } + public UpdateAcademyConversionProject AddPatchProjectMany(AcademyConversionProject project, Func, IPostprocessComposer> postProcess) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage2PerformanceAdditionalInformationIntegrationTests.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage2PerformanceAdditionalInformationIntegrationTests.cs index a257830cf..5e4686988 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage2PerformanceAdditionalInformationIntegrationTests.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage2PerformanceAdditionalInformationIntegrationTests.cs @@ -18,11 +18,7 @@ public async Task Should_navigate_to_and_update_additional_information() { AcademyConversionProject project = AddGetProject(); AddGetKeyStagePerformance(project.Urn.Value); - UpdateAcademyConversionProject request = AddPatchConfiguredProject(project, x => - { - x.KeyStage2PerformanceAdditionalInformation = _fixture.Create(); - x.Urn = project.Urn; - }); + SetPerformanceDataModel request = AddPutPerformanceData(project); await OpenAndConfirmPathAsync($"/task-list/{project.Id}/key-stage-2-performance-tables"); await NavigateAsync("Change", 0); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage4PerformanceAdditionalInformationIntegrationTests.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage4PerformanceAdditionalInformationIntegrationTests.cs index d881e9fa6..1de7aaf5b 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage4PerformanceAdditionalInformationIntegrationTests.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage4PerformanceAdditionalInformationIntegrationTests.cs @@ -18,11 +18,7 @@ public async Task Should_navigate_to_and_update_additional_information() { AcademyConversionProject project = AddGetProject(); AddGetKeyStagePerformance(project.Urn.Value); - UpdateAcademyConversionProject request = AddPatchConfiguredProject(project, x => - { - x.KeyStage4PerformanceAdditionalInformation = _fixture.Create(); - x.Urn = project.Urn; - }); + SetPerformanceDataModel request = AddPutPerformanceData(project); await OpenAndConfirmPathAsync($"/task-list/{project.Id}/key-stage-4-performance-tables"); await NavigateAsync("Change", 0); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage5PerformanceAdditionalInformationIntegrationTests.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage5PerformanceAdditionalInformationIntegrationTests.cs index 3faf189c8..e029bb2c5 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage5PerformanceAdditionalInformationIntegrationTests.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/KeyStagePerformance/KeyStage5PerformanceAdditionalInformationIntegrationTests.cs @@ -18,11 +18,7 @@ public async Task Should_navigate_to_and_update_additional_information() { AcademyConversionProject project = AddGetProject(); AddGetKeyStagePerformance(project.Urn.Value); - UpdateAcademyConversionProject request = AddPatchConfiguredProject(project, x => - { - x.KeyStage5PerformanceAdditionalInformation = _fixture.Create(); - x.Urn = project.Urn; - }); + SetPerformanceDataModel request = AddPutPerformanceData(project); await OpenAndConfirmPathAsync($"/task-list/{project.Id}/key-stage-5-performance-tables"); await NavigateAsync("Change", 0); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/PreviewHTBTemplate/PreviewHTBIntegrationTests.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/PreviewHTBTemplate/PreviewHTBIntegrationTests.cs index 9ddbaaeb8..1b418ac52 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/PreviewHTBTemplate/PreviewHTBIntegrationTests.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Tests/Pages/TaskList/PreviewHTBTemplate/PreviewHTBIntegrationTests.cs @@ -387,11 +387,7 @@ public async Task Should_update_KS2_additional_information_and_navigate_back_to_ AcademyConversionProject project = AddGetProject(); AddGetKeyStagePerformance(project.Urn.Value); - UpdateAcademyConversionProject request = AddPatchConfiguredProject(project, x => - { - x.KeyStage2PerformanceAdditionalInformation = _fixture.Create(); - x.Urn = project.Urn; - }); + SetPerformanceDataModel request = AddPutPerformanceData(project); await OpenAndConfirmPathAsync($"/task-list/{project.Id}/preview-project-template"); @@ -450,11 +446,7 @@ public async Task Should_update_KS4_additional_information_and_navigate_back_to_ AcademyConversionProject project = AddGetProject(); AddGetKeyStagePerformance(project.Urn.Value); - UpdateAcademyConversionProject request = AddPatchConfiguredProject(project, x => - { - x.KeyStage4PerformanceAdditionalInformation = _fixture.Create(); - x.Urn = project.Urn; - }); + SetPerformanceDataModel request = AddPutPerformanceData(project); await OpenAndConfirmPathAsync($"/task-list/{project.Id}/preview-project-template"); @@ -516,11 +508,7 @@ public async Task Should_update_KS5_additional_information_and_navigate_back_to_ AcademyConversionProject project = AddGetProject(); AddGetKeyStagePerformance(project.Urn.Value); - UpdateAcademyConversionProject request = AddPatchConfiguredProject(project, x => - { - x.KeyStage5PerformanceAdditionalInformation = _fixture.Create(); - x.Urn = project.Urn; - }); + SetPerformanceDataModel request = AddPutPerformanceData(project); await OpenAndConfirmPathAsync($"/task-list/{project.Id}/preview-project-template"); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/NewProject/SearchTrust.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/NewProject/SearchTrust.cshtml.cs index a9433c479..6068e57d6 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/NewProject/SearchTrust.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/NewProject/SearchTrust.cshtml.cs @@ -121,6 +121,9 @@ private static string HighlightSearchMatch(string input, string toReplace, Trust private static string[] SplitOnBrackets(string input) { + // return array containing one empty string if input string is null or empty + if (string.IsNullOrWhiteSpace(input)) return new string[1] { string.Empty }; + return input.Split(new[] { '(', ')' }, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs index 11fb1a1c4..9ae2b698a 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/KeyStagePerformance/PerformanceDataViewModel.cs @@ -8,10 +8,12 @@ using System; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; +using Dfe.PrepareConversions.Data.Exceptions; +using DocumentFormat.OpenXml.Spreadsheet; namespace Dfe.PrepareConversions.Pages.TaskList.KeyStagePerformance { - public class PerformanceDataViewModel: BaseAcademyConversionProjectPageModel + public class PerformanceDataViewModel : BaseAcademyConversionProjectPageModel { private readonly ErrorService _errorService; @@ -61,37 +63,44 @@ public override async Task OnPostAsync(int id) { await SetProject(id); - //if (YesChecked is true && string.IsNullOrWhiteSpace(ExternalApplicationFormUrl)) - //{ - // ModelState.AddModelError(nameof(ExternalApplicationFormUrl), "You must enter valid link for the schools application form"); - //} - if (ModelState.IsValid) { SetExistingValuesIfNotChanged(); - await _repository.SetPerformanceData(id, new SetPerformanceDataModel(id, + try + { + await _repository.SetPerformanceData(id, new SetPerformanceDataModel(id, KeyStage2PerformanceAdditionalInformation, KeyStage4PerformanceAdditionalInformation, KeyStage5PerformanceAdditionalInformation, EducationalAttendanceAdditionalInformation)); - (string returnPage, string fragment) = GetReturnPageAndFragment(); - if (!string.IsNullOrWhiteSpace(returnPage)) + (string returnPage, string fragment) = GetReturnPageAndFragment(); + if (!string.IsNullOrWhiteSpace(returnPage)) + { + return RedirectToPage(returnPage, null, new { id }, fragment); + } + + return RedirectToPage(SuccessPage, new { id }); + + } + catch (ApiResponseException ex) { - return RedirectToPage(returnPage, null, new { id }, fragment); + + _errorService.AddApiError(); + return Page(); } - return RedirectToPage(SuccessPage, new { id }); } _errorService.AddErrors(ModelState.Keys, ModelState); - return await base.OnGetAsync(id); + return Page(); } private void SetExistingValuesIfNotChanged() { - if (KeyStage2PerformanceAdditionalInformation is null) { + if (KeyStage2PerformanceAdditionalInformation is null) + { KeyStage2PerformanceAdditionalInformation = Project.KeyStage2PerformanceAdditionalInformation; }

    Persistent absence of 10% or more

    -

    The percentage of pupils missing 10% or more of the mornings or afternoons they could attend..

    +

    The percentage of pupils missing 10% or more of the mornings or afternoons they could attend.