From 85c816f83f14bde9e0c13de21ad98993b37d6e6c Mon Sep 17 00:00:00 2001 From: Elijah Aremu <45821029+elielijah321@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:22:29 +0000 Subject: [PATCH] withdrawn status for conversions --- .../AdvisoryBoardDecision.cs | 13 +++ .../AdvisoryBoardDecisions.cs | 3 +- .../AdvisoryBoardWithdrawnReason.cs | 14 +++ .../AdvisoryBoardWithdrawnReasonDetails.cs | 17 +++ .../Extensions/AdvisoryBoardExtensions.cs | 21 ++++ .../Dfe.PrepareConversions/Models/Links.cs | 1 + .../RecordDecisionPreview/default.cshtml | 18 +++ .../TaskList/Decision/DecisionDate.cshtml.cs | 1 + .../Pages/TaskList/Decision/Summary.cshtml | 24 ++++ .../TaskList/Decision/WhoDecided.cshtml.cs | 1 + .../TaskList/Decision/WhyWithdrawn.cshtml | 65 +++++++++++ .../TaskList/Decision/WhyWithdrawn.cshtml.cs | 108 ++++++++++++++++++ 12 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardWithdrawnReason.cs create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardWithdrawnReasonDetails.cs create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhyWithdrawn.cshtml create mode 100644 Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhyWithdrawn.cshtml.cs diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardDecision.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardDecision.cs index 9feae7c1c..99c887ae8 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardDecision.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardDecision.cs @@ -19,6 +19,8 @@ public AdvisoryBoardDecision() public string ApprovedConditionsDetails { get; set; } public List DeclinedReasons { get; set; } public List DeferredReasons { get; set; } + public List WithdrawnReasons { get; set; } + public DateTime? AdvisoryBoardDecisionDate { get; set; } public DecisionMadeBy? DecisionMadeBy { get; set; } @@ -34,6 +36,7 @@ public AdvisoryBoardDecisions? Decision { DeclinedReasons = new List(); DeferredReasons = new List(); + WithdrawnReasons = new List(); } if (value == AdvisoryBoardDecisions.Declined) @@ -41,6 +44,7 @@ public AdvisoryBoardDecisions? Decision ApprovedConditionsSet = null; ApprovedConditionsDetails = null; DeferredReasons = new List(); + WithdrawnReasons = new List(); } if (value == AdvisoryBoardDecisions.Deferred) @@ -48,6 +52,15 @@ public AdvisoryBoardDecisions? Decision ApprovedConditionsSet = null; ApprovedConditionsDetails = null; DeclinedReasons = new List(); + WithdrawnReasons = new List(); + } + + if (value == AdvisoryBoardDecisions.Withdrawn) + { + ApprovedConditionsSet = null; + ApprovedConditionsDetails = null; + DeclinedReasons = new List(); + DeferredReasons = new List(); } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardDecisions.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardDecisions.cs index dace8e44e..c83319bdd 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardDecisions.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardDecisions.cs @@ -4,5 +4,6 @@ public enum AdvisoryBoardDecisions { Approved = 0, Declined = 1, - Deferred = 2 + Deferred = 2, + Withdrawn = 3 } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardWithdrawnReason.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardWithdrawnReason.cs new file mode 100644 index 000000000..bd1628aa7 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardWithdrawnReason.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Dfe.PrepareConversions.Data.Models.AdvisoryBoardDecision; + +public enum AdvisoryBoardWithdrawnReason +{ + [Description("Additional information needed")] + AdditionalInformationNeeded = 0, + + [Description("Awaiting next ofsted report")] + AwaitingNextOfstedReport = 1, + [Description("Performance concerns")] PerformanceConcerns = 2, + [Description("Other")] Other = 3 +} diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardWithdrawnReasonDetails.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardWithdrawnReasonDetails.cs new file mode 100644 index 000000000..6b32eded6 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Models/AdvisoryBoardDecision/AdvisoryBoardWithdrawnReasonDetails.cs @@ -0,0 +1,17 @@ +namespace Dfe.PrepareConversions.Data.Models.AdvisoryBoardDecision; + +public class AdvisoryBoardWithdrawnReasonDetails +{ + public AdvisoryBoardWithdrawnReasonDetails() + { + } + + public AdvisoryBoardWithdrawnReasonDetails(AdvisoryBoardWithdrawnReason reason, string details) + { + Reason = reason; + Details = details; + } + + public AdvisoryBoardWithdrawnReason Reason { get; set; } + public string Details { get; set; } +} diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Extensions/AdvisoryBoardExtensions.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Extensions/AdvisoryBoardExtensions.cs index 5a6bd06ca..08b2e1ca1 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Extensions/AdvisoryBoardExtensions.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Extensions/AdvisoryBoardExtensions.cs @@ -24,8 +24,29 @@ public static List AddReasonIfValid(this Lis return reasons; } + public static List AddReasonIfValid(this List reasons, + bool isChecked, + AdvisoryBoardWithdrawnReason reason, + string detail, + ModelStateDictionary modelState) + { + if (isChecked && string.IsNullOrWhiteSpace(detail)) + { + modelState.AddModelError($"{reason}Details", $"Enter a reason for selecting {reason.ToDescription()}"); + } + + if (isChecked) reasons.Add(new AdvisoryBoardWithdrawnReasonDetails(reason, detail)); + + return reasons; + } + public static AdvisoryBoardDeferredReasonDetails GetReason(this List reasons, AdvisoryBoardDeferredReason reason) { return reasons.FirstOrDefault(r => r.Reason == reason); } + + public static AdvisoryBoardWithdrawnReasonDetails GetReason(this List reasons, AdvisoryBoardWithdrawnReason reason) + { + return reasons.FirstOrDefault(r => r.Reason == reason); + } } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs index 56c941a18..e83ca51d1 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Models/Links.cs @@ -204,6 +204,7 @@ public static class Decision public static readonly LinkItem AnyConditions = AddLinkItem(backText: "Back", page: "/TaskList/Decision/AnyConditions"); public static readonly LinkItem DecisionDate = AddLinkItem(backText: "Back", page: "/TaskList/Decision/DecisionDate"); public static readonly LinkItem WhyDeferred = AddLinkItem(backText: "Back", page: "/TaskList/Decision/WhyDeferred"); + public static readonly LinkItem WhyWithdrawn = AddLinkItem(backText: "Back", page: "/TaskList/Decision/WhyWithdrawn"); public static readonly LinkItem Summary = AddLinkItem(backText: "Back", page: "/TaskList/Decision/Summary"); public static readonly LinkItem SubMenuRecordADecision = AddLinkItem(backText: "Back", page: "/TaskList/Decision/RecordADecision"); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/RecordDecisionPreview/default.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/RecordDecisionPreview/default.cshtml index e92f5c679..4ddf6e237 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/RecordDecisionPreview/default.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Components/RecordDecisionPreview/default.cshtml @@ -20,6 +20,7 @@ { AdvisoryBoardDecisions.Approved => "govuk-tag--green", AdvisoryBoardDecisions.Deferred => "govuk-tag--orange", + AdvisoryBoardDecisions.Withdrawn => "govuk-tag--purple", _ => "govuk-tag--red" }; } @@ -88,6 +89,23 @@ } + @if (Model.Decision.Decision == AdvisoryBoardDecisions.Withdrawn) + { +
+
+ Why was this project withdrawn +
+
+ + @foreach (AdvisoryBoardWithdrawnReasonDetails reason in Model.Decision.WithdrawnReasons) + { +
@reason.Reason.ToDescription():
+
@reason.Details
+ } +
+
+ } + @if (Model.Decision.Decision == AdvisoryBoardDecisions.Approved) { var conditionsSet = Model.Decision.ApprovedConditionsSet.HasValue && Model.Decision.ApprovedConditionsSet.Value; diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/DecisionDate.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/DecisionDate.cshtml.cs index 68e1bb64e..1ee6310c6 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/DecisionDate.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/DecisionDate.cshtml.cs @@ -55,6 +55,7 @@ public LinkItem GetPageForBackLink(int id) { Decision: AdvisoryBoardDecisions.Approved } => Links.Decision.AnyConditions, { Decision: AdvisoryBoardDecisions.Declined } => Links.Decision.DeclineReason, { Decision: AdvisoryBoardDecisions.Deferred } => Links.Decision.WhyDeferred, + { Decision: AdvisoryBoardDecisions.Withdrawn } => Links.Decision.WhyWithdrawn, _ => throw new Exception("Unexpected decision state") }; } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/Summary.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/Summary.cshtml index d16706319..a939c8b65 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/Summary.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/Summary.cshtml @@ -30,6 +30,7 @@ { AdvisoryBoardDecisions.Approved => "govuk-tag--green", AdvisoryBoardDecisions.Deferred => "govuk-tag--orange", + AdvisoryBoardDecisions.Withdrawn => "govuk-tag--purple", _ => "govuk-tag--red" }; } @@ -117,6 +118,29 @@ } + @if (Model.Decision.Decision == AdvisoryBoardDecisions.Withdrawn) + { +
+
+ Why was this project withdrawn +
+
+ + @foreach (AdvisoryBoardWithdrawnReasonDetails reason in Model.Decision.WithdrawnReasons) + { +
@reason.Reason.ToDescription():
+
@reason.Details
+ } + +
+
+ + Changewithdrawn-reason + +
+
+ } + @if (Model.Decision.Decision == AdvisoryBoardDecisions.Approved) { var conditionsSet = Model.Decision.ApprovedConditionsSet.GetValueOrDefault(); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhoDecided.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhoDecided.cshtml.cs index ba2f99e75..20deec12c 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhoDecided.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhoDecided.cshtml.cs @@ -62,6 +62,7 @@ public IActionResult OnPost(int id) AdvisoryBoardDecisions.Approved => RedirectToPage(Links.Decision.AnyConditions.Page, LinkParameters), AdvisoryBoardDecisions.Declined => RedirectToPage(Links.Decision.DeclineReason.Page, LinkParameters), AdvisoryBoardDecisions.Deferred => RedirectToPage(Links.Decision.WhyDeferred.Page, LinkParameters), + AdvisoryBoardDecisions.Withdrawn => RedirectToPage(Links.Decision.WhyWithdrawn.Page, LinkParameters), _ => RedirectToPage(Links.Decision.AnyConditions.Page, LinkParameters) }; } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhyWithdrawn.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhyWithdrawn.cshtml new file mode 100644 index 000000000..59d855020 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhyWithdrawn.cshtml @@ -0,0 +1,65 @@ +@page "/task-list/{id:int}/decision/why-withdrawn" +@using Dfe.PrepareConversions.Data.Models.AdvisoryBoardDecision +@using Dfe.Academisation.ExtensionMethods +@using Dfe.PrepareConversions.Extensions +@model Dfe.PrepareConversions.Pages.TaskList.Decision.WhyWithdrawnModel +@{ + ViewData["Title"] = $"Why project was {Model.DecisionText}"; + Layout = "_Layout"; +} + +@section BeforeMain +{ + + +} + +@Model.SchoolName +

Why was this project withdrawn?

+ +
+
+
+ + +
+ + + + @{ + CheckBoxAndLabel(AdvisoryBoardWithdrawnReason.AdditionalInformationNeeded, Model.AdditionalInformationNeededIsChecked, Model.AdditionalInformationNeededDetails); + CheckBoxAndLabel(AdvisoryBoardWithdrawnReason.AwaitingNextOfstedReport, Model.AwaitingNextOfstedReportIsChecked, Model.AwaitingNextOfstedReportDetails); + CheckBoxAndLabel(AdvisoryBoardWithdrawnReason.PerformanceConcerns, Model.PerformanceConcernsIsChecked, Model.PerformanceConcernsDetails); + CheckBoxAndLabel(AdvisoryBoardWithdrawnReason.Other, Model.OtherIsChecked, Model.OtherDetails); + } +
+
+
+ + +
+ +@{ + void CheckBoxAndLabel(AdvisoryBoardWithdrawnReason withdrawnReason, bool isChecked, string details) + { +
+ + +
+
+
+ + +
+ +
+ } +} \ No newline at end of file diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhyWithdrawn.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhyWithdrawn.cshtml.cs new file mode 100644 index 000000000..0e13e2f24 --- /dev/null +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/TaskList/Decision/WhyWithdrawn.cshtml.cs @@ -0,0 +1,108 @@ +using Dfe.Academisation.ExtensionMethods; +using Dfe.PrepareConversions.Data.Models.AdvisoryBoardDecision; +using Dfe.PrepareConversions.Data.Services; +using Dfe.PrepareConversions.Extensions; +using Dfe.PrepareConversions.Models; +using Dfe.PrepareConversions.Pages.TaskList.Decision.Models; +using Dfe.PrepareConversions.Services; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; + +namespace Dfe.PrepareConversions.Pages.TaskList.Decision; + +public class WhyWithdrawnModel : DecisionBaseModel +{ + private readonly ErrorService _errorService; + + public WhyWithdrawnModel(IAcademyConversionProjectRepository repository, + ISession session, + ErrorService errorService + ) + : base(repository, session) + { + _errorService = errorService; + } + + [BindProperty] + public string AdditionalInformationNeededDetails { get; set; } + + [BindProperty] + public bool AdditionalInformationNeededIsChecked { get; set; } + + [BindProperty] + public string AwaitingNextOfstedReportDetails { get; set; } + + [BindProperty] + public bool AwaitingNextOfstedReportIsChecked { get; set; } + + [BindProperty] + public string PerformanceConcernsDetails { get; set; } + + [BindProperty] + public bool PerformanceConcernsIsChecked { get; set; } + + [BindProperty] + public string OtherDetails { get; set; } + + [BindProperty] + public bool OtherIsChecked { get; set; } + + [BindProperty] + public bool WasReasonGiven => AdditionalInformationNeededIsChecked || AwaitingNextOfstedReportIsChecked || PerformanceConcernsIsChecked || OtherIsChecked; + + public string DecisionText { get; set; } + + public IActionResult OnGet(int id) + { + SetBackLinkModel(Links.Decision.WhoDecided, id); + + AdvisoryBoardDecision decision = GetDecisionFromSession(id); + DecisionText = decision.Decision.ToDescription().ToLowerInvariant(); + + List reasons = decision.WithdrawnReasons; + SetReasonsModel(reasons); + + return Page(); + } + + public IActionResult OnPost(int id) + { + AdvisoryBoardDecision decision = GetDecisionFromSession(id); + + decision.WithdrawnReasons.Clear(); + decision.WithdrawnReasons + .AddReasonIfValid(AdditionalInformationNeededIsChecked, AdvisoryBoardWithdrawnReason.AdditionalInformationNeeded, AdditionalInformationNeededDetails, ModelState) + .AddReasonIfValid(AwaitingNextOfstedReportIsChecked, AdvisoryBoardWithdrawnReason.AwaitingNextOfstedReport, AwaitingNextOfstedReportDetails, ModelState) + .AddReasonIfValid(PerformanceConcernsIsChecked, AdvisoryBoardWithdrawnReason.PerformanceConcerns, PerformanceConcernsDetails, ModelState) + .AddReasonIfValid(OtherIsChecked, AdvisoryBoardWithdrawnReason.Other, OtherDetails, ModelState); + + SetDecisionInSession(id, decision); + + if (!WasReasonGiven) ModelState.AddModelError("WasReasonGiven", "Select at least one reason"); + + _errorService.AddErrors(ModelState.Keys, ModelState); + if (_errorService.HasErrors()) return OnGet(id); + + return RedirectToPage(Links.Decision.DecisionDate.Page, LinkParameters); + } + + private void SetReasonsModel(List reasons) + { + AdvisoryBoardWithdrawnReasonDetails additionalInfo = reasons.GetReason(AdvisoryBoardWithdrawnReason.AdditionalInformationNeeded); + AdditionalInformationNeededIsChecked = additionalInfo != null; + AdditionalInformationNeededDetails = additionalInfo?.Details; + + AdvisoryBoardWithdrawnReasonDetails ofsted = reasons.GetReason(AdvisoryBoardWithdrawnReason.AwaitingNextOfstedReport); + AwaitingNextOfstedReportIsChecked = ofsted != null; + AwaitingNextOfstedReportDetails = ofsted?.Details; + + AdvisoryBoardWithdrawnReasonDetails perf = reasons.GetReason(AdvisoryBoardWithdrawnReason.PerformanceConcerns); + PerformanceConcernsIsChecked = perf != null; + PerformanceConcernsDetails = perf?.Details; + + AdvisoryBoardWithdrawnReasonDetails other = reasons.GetReason(AdvisoryBoardWithdrawnReason.Other); + OtherIsChecked = other != null; + OtherDetails = other?.Details; + } +}