Skip to content

Commit

Permalink
Merge pull request #992 from DFE-Digital/feature/156275-withdrawn-dec…
Browse files Browse the repository at this point in the history
…ision-option

withdrawn status for conversions
  • Loading branch information
elielijah321 authored Feb 20, 2024
2 parents d7bdd8b + e52b7a5 commit 80aa7ab
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public AdvisoryBoardDecision()
public string ApprovedConditionsDetails { get; set; }
public List<AdvisoryBoardDeclinedReasonDetails> DeclinedReasons { get; set; }
public List<AdvisoryBoardDeferredReasonDetails> DeferredReasons { get; set; }
public List<AdvisoryBoardWithdrawnReasonDetails> WithdrawnReasons { get; set; }

public DateTime? AdvisoryBoardDecisionDate { get; set; }
public DecisionMadeBy? DecisionMadeBy { get; set; }

Expand All @@ -34,20 +36,31 @@ public AdvisoryBoardDecisions? Decision
{
DeclinedReasons = new List<AdvisoryBoardDeclinedReasonDetails>();
DeferredReasons = new List<AdvisoryBoardDeferredReasonDetails>();
WithdrawnReasons = new List<AdvisoryBoardWithdrawnReasonDetails>();
}

if (value == AdvisoryBoardDecisions.Declined)
{
ApprovedConditionsSet = null;
ApprovedConditionsDetails = null;
DeferredReasons = new List<AdvisoryBoardDeferredReasonDetails>();
WithdrawnReasons = new List<AdvisoryBoardWithdrawnReasonDetails>();
}

if (value == AdvisoryBoardDecisions.Deferred)
{
ApprovedConditionsSet = null;
ApprovedConditionsDetails = null;
DeclinedReasons = new List<AdvisoryBoardDeclinedReasonDetails>();
WithdrawnReasons = new List<AdvisoryBoardWithdrawnReasonDetails>();
}

if (value == AdvisoryBoardDecisions.Withdrawn)
{
ApprovedConditionsSet = null;
ApprovedConditionsDetails = null;
DeclinedReasons = new List<AdvisoryBoardDeclinedReasonDetails>();
DeferredReasons = new List<AdvisoryBoardDeferredReasonDetails>();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public enum AdvisoryBoardDecisions
{
Approved = 0,
Declined = 1,
Deferred = 2
Deferred = 2,
Withdrawn = 3
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,29 @@ public static List<AdvisoryBoardDeferredReasonDetails> AddReasonIfValid(this Lis
return reasons;
}

public static List<AdvisoryBoardWithdrawnReasonDetails> AddReasonIfValid(this List<AdvisoryBoardWithdrawnReasonDetails> 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<AdvisoryBoardDeferredReasonDetails> reasons, AdvisoryBoardDeferredReason reason)
{
return reasons.FirstOrDefault(r => r.Reason == reason);
}

public static AdvisoryBoardWithdrawnReasonDetails GetReason(this List<AdvisoryBoardWithdrawnReasonDetails> reasons, AdvisoryBoardWithdrawnReason reason)
{
return reasons.FirstOrDefault(r => r.Reason == reason);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,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");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
{
AdvisoryBoardDecisions.Approved => "govuk-tag--green",
AdvisoryBoardDecisions.Deferred => "govuk-tag--orange",
AdvisoryBoardDecisions.Withdrawn => "govuk-tag--purple",
_ => "govuk-tag--red"
};
}
Expand Down Expand Up @@ -88,6 +89,23 @@
</div>
}

@if (Model.Decision.Decision == AdvisoryBoardDecisions.Withdrawn)
{
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key">
Why was this project withdrawn
</dt>
<dd class="govuk-summary-list__value" id="withdrawn-reasons">

@foreach (AdvisoryBoardWithdrawnReasonDetails reason in Model.Decision.WithdrawnReasons)
{
<div>@reason.Reason.ToDescription():</div>
<div class="govuk-!-margin-bottom-2">@reason.Details</div>
}
</dd>
</div>
}

@if (Model.Decision.Decision == AdvisoryBoardDecisions.Approved)
{
var conditionsSet = Model.Decision.ApprovedConditionsSet.HasValue && Model.Decision.ApprovedConditionsSet.Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
{
AdvisoryBoardDecisions.Approved => "govuk-tag--green",
AdvisoryBoardDecisions.Deferred => "govuk-tag--orange",
AdvisoryBoardDecisions.Withdrawn => "govuk-tag--purple",
_ => "govuk-tag--red"
};
}
Expand Down Expand Up @@ -117,6 +118,29 @@
</div>
}

@if (Model.Decision.Decision == AdvisoryBoardDecisions.Withdrawn)
{
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key">
Why was this project withdrawn
</dt>
<dd class="govuk-summary-list__value" id="withdrawn-reasons">

@foreach (AdvisoryBoardWithdrawnReasonDetails reason in Model.Decision.WithdrawnReasons)
{
<div>@reason.Reason.ToDescription():</div>
<div class="govuk-!-margin-bottom-2">@reason.Details</div>
}

</dd>
<dd class="govuk-summary-list__actions">
<a class="govuk-link" asp-page="@Links.Decision.WhyWithdrawn.Page" asp-route-id="@Model.Id" asp-route-obl="true" id="change-withdrawn-btn">
Change<span class="govuk-visually-hidden">withdrawn-reason</span>
</a>
</dd>
</div>
}

@if (Model.Decision.Decision == AdvisoryBoardDecisions.Approved)
{
var conditionsSet = Model.Decision.ApprovedConditionsSet.GetValueOrDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
<partial name="_BackLink" model="@Model.BackLinkModel"/>
<partial name="_ErrorSummary"/>
}

<span id="selection-span" class="govuk-caption-l">@Model.SchoolName</span>
<h1 class="govuk-heading-l">Why was this project withdrawn?</h1>

<form method="post">
<div class="govuk-form-group">
<fieldset class="govuk-fieldset">
<legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
</legend>
<div class="govuk-checkboxes @ModelState.GetErrorStyleClass()" data-module="govuk-checkboxes" id="WasReasonGiven">

<input type="hidden" asp-for="@Model.WasReasonGiven"/>

@{
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);
}
</div>
</fieldset>
</div>

<button class="govuk-button" data-module="govuk-button" id="submit-btn">
Continue
</button>
</form>

@{
void CheckBoxAndLabel(AdvisoryBoardWithdrawnReason withdrawnReason, bool isChecked, string details)
{
<div class="govuk-checkboxes__item" id="@(withdrawnReason)Details">
<input class="govuk-checkboxes__input" id="@withdrawnReason.ToString().ToLower()-checkbox" name="@(withdrawnReason)IsChecked" type="checkbox"
data-aria-controls="conditional-@withdrawnReason" value="true" @(isChecked ? "checked" : "")>
<label class="govuk-label govuk-checkboxes__label" for="@withdrawnReason.ToString().ToLower()-checkbox">
@withdrawnReason.ToDescription()
</label>
</div>
<div class="govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden" id="conditional-@withdrawnReason">
<div class="govuk-form-group">
<label class="govuk-label" for="@withdrawnReason.ToString().ToLower()-txtarea">
Give reasons
</label>
<textarea class="govuk-textarea govuk-!-width-three-quarters" id="@withdrawnReason.ToString().ToLower()-txtarea"
name="@(withdrawnReason)Details" rows="5" aria-describedby="more-detail-hint">@details</textarea>
</div>

</div>
}
}
Original file line number Diff line number Diff line change
@@ -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<AdvisoryBoardWithdrawnReasonDetails> 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<AdvisoryBoardWithdrawnReasonDetails> 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;
}
}

0 comments on commit 80aa7ab

Please sign in to comment.