Skip to content

Commit

Permalink
Merge pull request #515 from DFE-Digital/overview-performance
Browse files Browse the repository at this point in the history
Overview Page re-architected to use services
  • Loading branch information
dneed-nimble authored Sep 26, 2024
2 parents ca3380a + 0caf6ad commit a550133
Show file tree
Hide file tree
Showing 28 changed files with 1,041 additions and 627 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Contacts pages will now have relevant data for SATs, using the URN as an alternative to the trust UID
- All Trust contacts now have the internal data that pertains to their email addresses, where present in our unpublished GIAS data.

### Changed

- Ofsted data now uses inspection start date as inspection date
- Reduced the load time of the Trust overview page

## [Release-7][release-7] (production-2024-09-23.3213)

### Added
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System.Globalization;
using DfE.FindInformationAcademiesTrusts.Data.AcademiesDb.Contexts;
using DfE.FindInformationAcademiesTrusts.Data.AcademiesDb.Extensions;
using DfE.FindInformationAcademiesTrusts.Data.Repositories.Academy;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Globalization;

namespace DfE.FindInformationAcademiesTrusts.Data.AcademiesDb.Repositories;

Expand Down Expand Up @@ -57,8 +57,8 @@ private async Task<Dictionary<string, OfstedRatings>> GetOfstedRatings(int[] urn
var ofstedRatings =
await academiesDbContext.MisEstablishments
.Where(me => urns.Contains(me.Urn!.Value))
.Select(me => new OfstedRatings(me.Urn!.Value, me.OverallEffectiveness, me.InspectionEndDate,
me.PreviousFullInspectionOverallEffectiveness, me.PreviousInspectionEndDate))
.Select(me => new OfstedRatings(me.Urn!.Value, me.OverallEffectiveness, me.InspectionStartDate,
me.PreviousFullInspectionOverallEffectiveness, me.PreviousInspectionStartDate))
.ToListAsync();

// Look in MisFurtherEducationEstablishments for academies not found in MisEstablishments
Expand Down Expand Up @@ -133,32 +133,75 @@ public async Task<int> GetNumberOfAcademiesInTrustAsync(string uid)
.FirstOrDefaultAsync();
}

public async Task<AcademyOverview[]> GetAcademiesInTrustOverviewAsync(string uid)
{
var academiesData = await academiesDbContext.GiasGroupLinks
.Where(gl => gl.GroupUid == uid)
.Join(
academiesDbContext.GiasEstablishments,
gl => gl.Urn!,
e => e.Urn.ToString(),
(gl, e) => new
{
Urn = e.Urn.ToString(),
LocalAuthority = e.LaName,
NumberOfPupils = e.NumberOfPupils.ParseAsNullableInt(),
SchoolCapacity = e.SchoolCapacity.ParseAsNullableInt()
})
.ToListAsync();

// Get URNs as ints
var urns = academiesData.Select(a => int.Parse(a.Urn)).ToArray();

// Fetch Ofsted ratings
var ofstedRatingsDict = await GetOfstedRatings(urns);

var academiesOverview = academiesData.Select(a =>
{
var currentOfstedRating = OfstedRatingScore.None;
if (ofstedRatingsDict.TryGetValue(a.Urn, out var ofstedRatings))
{
currentOfstedRating = ofstedRatings.Current?.OfstedRatingScore ?? OfstedRatingScore.None;
}

return new AcademyOverview(
a.Urn,
a.LocalAuthority ?? string.Empty,
a.NumberOfPupils,
a.SchoolCapacity,
currentOfstedRating
);
}).ToArray();

return academiesOverview;
}

private sealed record OfstedRatings(int Urn, OfstedRating Current, OfstedRating Previous)
{
public OfstedRatings(int urn, int? currentOverallEffectiveness, string? currentInspectionEndDate,
string? previousOverallEffectiveness, string? previousInspectionEndDate) :
public OfstedRatings(int urn, int? currentOverallEffectiveness, string? currentInspectionDate,
string? previousOverallEffectiveness, string? previousInspectionDate) :
this(urn,
currentOverallEffectiveness,
currentInspectionEndDate,
currentInspectionDate,
previousOverallEffectiveness is null ? null : int.Parse(previousOverallEffectiveness),
previousInspectionEndDate)
previousInspectionDate)
{
}

public OfstedRatings(int urn, int? currentOverallEffectiveness, string? currentInspectionEndDate,
int? previousOverallEffectiveness, string? previousInspectionEndDate)
public OfstedRatings(int urn, int? currentOverallEffectiveness, string? currentInspectionDate,
int? previousOverallEffectiveness, string? previousInspectionDate)
: this(urn,
currentOverallEffectiveness == null
? OfstedRating.None
: new OfstedRating(
(OfstedRatingScore)currentOverallEffectiveness.Value,
currentInspectionEndDate.ParseAsNullableDate()
currentInspectionDate.ParseAsNullableDate()
),
previousOverallEffectiveness == null
? OfstedRating.None
: new OfstedRating(
(OfstedRatingScore)previousOverallEffectiveness,
previousInspectionEndDate.ParseAsNullableDate()
previousInspectionDate.ParseAsNullableDate()
)
)
{
Expand Down
2 changes: 1 addition & 1 deletion DfE.FindInformationAcademiesTrusts.Data/OfstedRating.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace DfE.FindInformationAcademiesTrusts.Data;

public record OfstedRating(OfstedRatingScore OfstedRatingScore, DateTime? InspectionEndDate)
public record OfstedRating(OfstedRatingScore OfstedRatingScore, DateTime? InspectionDate)
{
public static readonly OfstedRating None = new(OfstedRatingScore.None, null);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace DfE.FindInformationAcademiesTrusts.Data.Repositories.Academy;

public record AcademyOverview(
string Urn,
string LocalAuthority,
int? NumberOfPupils,
int? SchoolCapacity,
OfstedRatingScore CurrentOfstedRating
);
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface IAcademyRepository
Task<AcademyOfsted[]> GetAcademiesInTrustOfstedAsync(string uid);
Task<AcademyPupilNumbers[]> GetAcademiesInTrustPupilNumbersAsync(string uid);
Task<AcademyFreeSchoolMeals[]> GetAcademiesInTrustFreeSchoolMealsAsync(string uid);
Task<AcademyOverview[]> GetAcademiesInTrustOverviewAsync(string uid);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using DfE.FindInformationAcademiesTrusts.Data;

namespace DfE.FindInformationAcademiesTrusts.Extensions;

public static class OfstedRatingScoreExtensions
{
public static int ToDataSortValue(this OfstedRatingScore rating)
{
return rating switch
{
OfstedRatingScore.Outstanding => 1,
OfstedRatingScore.Good => 2,
OfstedRatingScore.RequiresImprovement => 3,
OfstedRatingScore.Inadequate => 4,
OfstedRatingScore.None => 5,
_ => -1
};
}

public static string ToDisplayString(this OfstedRatingScore rating)
{
return rating switch
{
OfstedRatingScore.Outstanding => "Outstanding",
OfstedRatingScore.Good => "Good",
OfstedRatingScore.RequiresImprovement => "Requires improvement",
OfstedRatingScore.Inadequate => "Inadequate",
OfstedRatingScore.None => "Not yet inspected",
_ => "Unknown"
};
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using DfE.FindInformationAcademiesTrusts.Data;
using DfE.FindInformationAcademiesTrusts.Services;
using DfE.FindInformationAcademiesTrusts.Services.Academy;
using DfE.FindInformationAcademiesTrusts.Services.DataSource;
using DfE.FindInformationAcademiesTrusts.Services.Trust;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -10,6 +11,7 @@ public abstract class AcademiesPageModel(
ITrustProvider trustProvider,
IDataSourceService dataSourceService,
ITrustService trustService,
IAcademyService academyService,
IExportService exportService,
ILogger<AcademiesPageModel> logger,
IDateTimeProvider dateTimeProvider
Expand All @@ -22,6 +24,7 @@ public virtual async Task<IActionResult> OnGetExportAsync(string uid)
{
TrustSummaryServiceModel? trustSummary = await TrustService.GetTrustSummaryAsync(uid);
Trust? allAcademiesDetails = await TrustProvider.GetTrustByUidAsync(uid);
AcademyOfstedServiceModel[] ofstedRatings = await academyService.GetAcademiesInTrustOfstedAsync(uid);

if (trustSummary == null || allAcademiesDetails == null)
{
Expand All @@ -31,7 +34,7 @@ public virtual async Task<IActionResult> OnGetExportAsync(string uid)
// Sanitize the trust name to remove any illegal characters
string sanitizedTrustName = string.Concat(allAcademiesDetails.Name.Where(c => !Path.GetInvalidFileNameChars().Contains(c)));

var fileContents = ExportService.ExportAcademiesToSpreadsheetUsingProvider(allAcademiesDetails, trustSummary);
var fileContents = ExportService.ExportAcademiesToSpreadsheetUsingProvider(allAcademiesDetails, trustSummary, ofstedRatings);
string fileName = $"{sanitizedTrustName}-{DateTimeProvider.Now:yyyy-MM-dd}.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class AcademiesDetailsModel : AcademiesPageModel
public AcademiesDetailsModel(ITrustProvider trustProvider, IDataSourceService dataSourceService,
IOtherServicesLinkBuilder linkBuilder, ILogger<AcademiesDetailsModel> logger,
ITrustService trustService, IAcademyService academyService, IExportService exportService, IDateTimeProvider dateTimeProvider) : base(trustProvider,
dataSourceService, trustService, exportService, logger, dateTimeProvider)
dataSourceService, trustService, academyService, exportService, logger, dateTimeProvider)
{
PageTitle = "Academies details";
TabName = "Details";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class FreeSchoolMealsModel : AcademiesPageModel
public FreeSchoolMealsModel(ITrustProvider trustProvider, IDataSourceService dataSourceService,
ILogger<FreeSchoolMealsModel> logger, ITrustService trustService, IAcademyService academyService,
IExportService exportService, IDateTimeProvider dateTimeProvider) :
base(trustProvider, dataSourceService, trustService, exportService, logger, dateTimeProvider)
base(trustProvider, dataSourceService, trustService, academyService, exportService, logger, dateTimeProvider)
{
PageTitle = "Academies free school meals";
TabName = "Free school meals";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class OfstedRatingsModel : AcademiesPageModel

public OfstedRatingsModel(ITrustProvider trustProvider, IDataSourceService dataSourceService,
ILogger<OfstedRatingsModel> logger, ITrustService trustService, IAcademyService academyService, IExportService exportService, IDateTimeProvider dateTimeProvider) : base(
trustProvider, dataSourceService, trustService, exportService, logger, dateTimeProvider)
trustProvider, dataSourceService, trustService, academyService, exportService, logger, dateTimeProvider)
{
PageTitle = "Academies Ofsted ratings";
TabName = "Ofsted ratings";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class PupilNumbersModel : AcademiesPageModel

public PupilNumbersModel(ITrustProvider trustProvider, IDataSourceService dataSourceService,
ILogger<PupilNumbersModel> logger, ITrustService trustService, IAcademyService academyService, IExportService exportService, IDateTimeProvider dateTimeProvider)
: base(trustProvider, dataSourceService, trustService, exportService, logger, dateTimeProvider)
: base(trustProvider, dataSourceService, trustService, academyService, exportService, logger, dateTimeProvider)
{
AcademyService = academyService;
PageTitle = "Academies pupil numbers";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<td class="govuk-body govuk-table__cell" data-sort-value="@Model.OfstedRatingSortValue" data-testid="@Model.IdPrefix-ofsted-rating">
<span class="govuk-!-font-weight-bold">@Model.OfstedRatingDescription</span>
<span>
@if (Model.OfstedRating.InspectionEndDate is not null)
@if (Model.OfstedRating.InspectionDate is not null)
{
<br/>
@Model.OfstedRating.InspectionEndDate.Value.ToString(StringFormatConstants.ViewDate)
@Model.OfstedRating.InspectionDate.Value.ToString(StringFormatConstants.ViewDate)
<br/>
<strong class="@Model.TagClasses govuk-!-margin-top-2 govuk-!-margin-bottom-1">
@Model.TagText
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class OfstedRatingCellModel

public string? IdPrefix { get; set; }

public bool IsAfterJoining => OfstedRating.InspectionEndDate >= AcademyJoinedDate;
public bool IsAfterJoining => OfstedRating.InspectionDate >= AcademyJoinedDate;

public string? OfstedRatingDescription => OfstedRating.OfstedRatingScore switch
{
Expand Down
46 changes: 21 additions & 25 deletions DfE.FindInformationAcademiesTrusts/Pages/Trusts/Overview.cshtml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@page
@using DfE.FindInformationAcademiesTrusts.Data
@using DfE.FindInformationAcademiesTrusts.Extensions
@model OverviewModel

@{
Expand All @@ -9,21 +10,24 @@
<section>
<div class="govuk-!-margin-top-9 govuk-!-margin-bottom-1">
<div class="govuk-grid-row">
<!-- Trust Summary Section -->
<div class="govuk-grid-column-one-half">
<section class="govuk-summary-card" data-testid="trust-summary">
<div class="govuk-summary-card__title-wrapper">
<h2 class="govuk-summary-card__title" id="trust-information">Trust summary</h2>
</div>
<div class="govuk-summary-card__content">
<dl class="govuk-summary-list">
<!-- Total Academies -->
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key govuk-!-width-one-half">
Total academies
</dt>
<dd class="govuk-summary-list__value" data-testid="total-academies">
@Model.NumberOfAcademiesInTrust
@Model.TotalAcademies
</dd>
</div>
<!-- Academies in Each Local Authority -->
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key govuk-!-width-one-half">
Academies in each local authority
Expand All @@ -35,31 +39,34 @@
}
</dd>
</div>
<!-- Pupil Numbers -->
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key govuk-!-width-one-half">
Pupil numbers
</dt>
<dd class="govuk-summary-list__value" data-testid="number-of-pupils">
@($"{Model.TotalPupilNumbersInTrust:n0}")
@($"{Model.TotalPupilNumbers:n0}")
</dd>
</div>
<!-- Pupil Capacity and Percentage Full -->
<div class="govuk-summary-list__row">
<dt class="govuk-summary-list__key govuk-!-width-one-half">
Pupil capacity <br>(% full)
</dt>
<dd class="govuk-summary-list__value" data-testid="pupil-capacity">
@($"{Model.TotalPupilCapacityInTrust:n0}")
@if (Model.TotalPercentageCapacityInTrust is not null)
@($"{Model.TotalCapacity:n0}")
@if (Model.PercentageFull is not null)
{
<br>
@($"({Model.TotalPercentageCapacityInTrust}%)")
@($"({Model.PercentageFull}%)")
}
</dd>
</div>
</dl>
</div>
</section>
</div>
<!-- Ofsted Ratings Section -->
<div class="govuk-grid-column-one-half">
<section class="govuk-summary-card" data-testid="ofsted-ratings">
<div class="govuk-summary-card__title-wrapper">
Expand All @@ -74,26 +81,15 @@
</tr>
</thead>
<tbody class="govuk-table__body">
<tr class="govuk-table__row">
<td class="govuk-body govuk-table__cell" data-sort-value="1">Outstanding</td>
<td class="govuk-body govuk-table__cell govuk-table__cell--numeric" data-testid="ofsted-rating-outstanding">@Model.GetNumberOfAcademiesWithOfstedRating(OfstedRatingScore.Outstanding)</td>
</tr>
<tr class="govuk-table__row">
<td class="govuk-body govuk-table__cell" data-sort-value="2">Good</td>
<td class="govuk-body govuk-table__cell govuk-table__cell--numeric" data-testid="ofsted-rating-good">@Model.GetNumberOfAcademiesWithOfstedRating(OfstedRatingScore.Good)</td>
</tr>
<tr class="govuk-table__row">
<td class="govuk-body govuk-table__cell" data-sort-value="3">Requires improvement</td>
<td class="govuk-body govuk-table__cell govuk-table__cell--numeric" data-testid="ofsted-rating-requires-improvement">@Model.GetNumberOfAcademiesWithOfstedRating(OfstedRatingScore.RequiresImprovement)</td>
</tr>
<tr class="govuk-table__row">
<td class="govuk-body govuk-table__cell" data-sort-value="4">Inadequate</td>
<td class="govuk-body govuk-table__cell govuk-table__cell--numeric" data-testid="ofsted-rating-inadequate">@Model.GetNumberOfAcademiesWithOfstedRating(OfstedRatingScore.Inadequate)</td>
</tr>
<tr class="govuk-table__row">
<td class="govuk-body govuk-table__cell" data-sort-value="5">Not yet inspected</td>
<td class="govuk-body govuk-table__cell govuk-table__cell--numeric" data-testid="ofsted-rating-not-inspected-yet">@Model.GetNumberOfAcademiesWithOfstedRating(OfstedRatingScore.None)</td>
</tr>
@foreach (var rating in Enum.GetValues(typeof(OfstedRatingScore)).Cast<OfstedRatingScore>())
{
<tr class="govuk-table__row">
<td class="govuk-body govuk-table__cell" data-sort-value="@rating.ToDataSortValue()">@rating.ToDisplayString()</td>
<td class="govuk-body govuk-table__cell govuk-table__cell--numeric" data-test-id="[email protected]()">
@Model.GetNumberOfAcademiesWithOfstedRating(rating)
</td>
</tr>
}
</tbody>
</table>
</div>
Expand Down
Loading

0 comments on commit a550133

Please sign in to comment.