Skip to content

Commit

Permalink
Merge pull request #410 from DFE-Digital/feature/get-establishment-by…
Browse files Browse the repository at this point in the history
…-trust

Get Establishment by Trust Repository method
  • Loading branch information
dneed-nimble authored Nov 9, 2023
2 parents 7ec08ef + 95c1783 commit 61c6674
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 26 deletions.
9 changes: 8 additions & 1 deletion Dfe.Academies.Api.Infrastructure/MstrContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public MstrContext(DbContextOptions<MstrContext> options) : base(options)
public DbSet<TrustType> TrustTypes { get; set; } = null!;
public DbSet<Establishment> Establishments { get; set; } = null!;
public DbSet<EstablishmentType> EstablishmentTypes { get; set; } = null!;
public DbSet<EducationEstablishmentTrust> EducationEstablishmentTrusts { get; set; } = null!;
public DbSet<LocalAuthority> LocalAuthorities { get; set; } = null!;

public DbSet<IfdPipeline> IfdPipelines { get; set; } = null!;
Expand All @@ -31,6 +32,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)

modelBuilder.Entity<Establishment>(ConfigureEstablishment);
modelBuilder.Entity<EstablishmentType>(ConfigureEstablishmentType);
modelBuilder.Entity<EducationEstablishmentTrust>(ConfigureEducationEstablishmentTrust);
modelBuilder.Entity<LocalAuthority>(ConfigureLocalAuthority);
modelBuilder.Entity<IfdPipeline>(ConfigureIfdPipeline);

Expand Down Expand Up @@ -211,7 +213,12 @@ void ConfigureTrustType(EntityTypeBuilder<TrustType> trustTypeConfiguration)

trustTypeConfiguration.ToTable("Ref_TrustType", DEFAULT_SCHEMA);
}

private void ConfigureEducationEstablishmentTrust(EntityTypeBuilder<EducationEstablishmentTrust> entityBuilder)
{
entityBuilder.HasKey(e => e.SK);
entityBuilder.ToTable("EducationEstablishmentTrust", DEFAULT_SCHEMA);

}
void ConfigureLocalAuthority(EntityTypeBuilder<LocalAuthority> localAuthorityConfiguration)
{
localAuthorityConfiguration.HasKey(e => e.SK).HasName("SK");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Dfe.Academies.Academisation.Data.Repositories;
using Dfe.Academies.Domain.Establishment;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel;
using static System.Net.Mime.MediaTypeNames;

namespace Dfe.Academies.Infrastructure.Repositories
Expand All @@ -26,23 +27,23 @@ public EstablishmentRepository(MstrContext context) : base(context)
}
public async Task<List<Establishment>> Search(string name, string ukPrn, string urn, CancellationToken cancellationToken)
{
IQueryable<Establishment> query = DefaultIncludes();

query = !string.IsNullOrEmpty(name)
? query.Where(establishment => establishment.EstablishmentName.Contains(name))
: query;

query = !string.IsNullOrEmpty(ukPrn)
? query.Where(establishment => establishment.UKPRN.Contains(ukPrn))
: query;

query = !string.IsNullOrEmpty(urn)
? query.Where(establishment => establishment.URN.ToString().Contains(urn))
: query;

return await query.OrderBy(establishment => establishment.SK)
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
IQueryable<Establishment> query = DefaultIncludes().AsNoTracking();
if (!string.IsNullOrEmpty(name))
{
query = query.Where(e => e.EstablishmentName.Contains(name));
}
if (!string.IsNullOrEmpty(ukPrn))
{
query = query.Where(e => e.UKPRN == ukPrn);
}
if (!string.IsNullOrEmpty(urn))
{
if (int.TryParse(urn, out var urnAsNumber))
{
query = query.Where(e => e.URN == urnAsNumber);
}
}
return await query.ToListAsync(cancellationToken);
}
public async Task<IEnumerable<int>> GetURNsByRegion(string[] regions, CancellationToken cancellationToken)
{
Expand All @@ -62,6 +63,25 @@ public async Task<List<Establishment>> GetByUrns(int[] urns, CancellationToken c
.ToListAsync(cancellationToken);
}

public async Task<List<Establishment>> GetByTrust(long? trustId, CancellationToken cancellationToken)
{
var establishmentIds = await context.EducationEstablishmentTrusts
.Where(eet => eet.FK_Trust == Convert.ToInt32(trustId))
.Select(eet => (long)eet.FK_EducationEstablishment)
.ToListAsync(cancellationToken)
.ConfigureAwait(false);

var establishments = await DefaultIncludes()
.Where(e => establishmentIds.Contains(e.SK))
.ToListAsync(cancellationToken)
.ConfigureAwait(false);


return establishments;
}



private IQueryable<Establishment> DefaultIncludes()
{
var x = dbSet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public TrustRepository(MstrContext context) : base(context)

return trust;
}
public async Task<Trust?> GetTrustByCompaniesHouseNumber(string companiesHouseNumber, CancellationToken cancellationToken)
{
var trust = await dbSet
.Include(x => x.TrustType)
.SingleOrDefaultAsync(x => x.CompaniesHouseNumber == companiesHouseNumber).ConfigureAwait(false);

return trust;
}

public async Task<List<Trust>> GetTrustsByUkprns(string[] ukprns, CancellationToken cancellationToken)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ public async Task GetByUkprn_WhenEstablishmentReturnedFromRepo_EstablishmentDtoI
// Arrange
var establishment = _fixture.Create<Domain.Establishment.Establishment?>();
var mockRepo = new Mock<IEstablishmentRepository>();
var mockTrustRepo = new Mock<ITrustRepository>();

string ukprn = "1010101";
mockRepo.Setup(x => x.GetEstablishmentByUkprn(It.Is<string>(v => v == ukprn), It.IsAny<CancellationToken>())).Returns(Task.FromResult(establishment));

var establishmentQueries = new EstablishmentQueries(
mockRepo.Object);
mockRepo.Object, mockTrustRepo.Object);

CancellationToken cancellationToken = default(global::System.Threading.CancellationToken);

Expand All @@ -51,11 +53,12 @@ public async Task GetByUrn_WhenEstablishmentReturnedFromRepo_EstablishmentDtoIsR
// Arrange
var establishment = _fixture.Create<Domain.Establishment.Establishment?>();
var mockRepo = new Mock<IEstablishmentRepository>();
var mockTrustRepo = new Mock<ITrustRepository>();
string urn = "1010101";
mockRepo.Setup(x => x.GetEstablishmentByUrn(It.Is<string>(v => v == urn), It.IsAny<CancellationToken>())).Returns(Task.FromResult(establishment));

var establishmentQueries = new EstablishmentQueries(
mockRepo.Object);
mockRepo.Object, mockTrustRepo.Object);

CancellationToken cancellationToken = default(global::System.Threading.CancellationToken);

Expand All @@ -75,13 +78,14 @@ public async Task Search_WhenEstablishmentsReturnedFromRepo_EstablishmentDtoList
// Arrange
var establishments = _fixture.Create<List<Domain.Establishment.Establishment>>();
var mockRepo = new Mock<IEstablishmentRepository>();
var mockTrustRepo = new Mock<ITrustRepository>();
string urn = "1010101";
string name = "Test name";
string ukPrn = "Test UkPrn";
mockRepo.Setup(x => x.Search(It.Is<string>(v => v == name), It.Is<string>(v => v == ukPrn), It.Is<string>(v => v == urn), It.IsAny<CancellationToken>())).Returns(Task.FromResult(establishments));

var establishmentQueries = new EstablishmentQueries(
mockRepo.Object);
mockRepo.Object, mockTrustRepo.Object);

CancellationToken cancellationToken = default(global::System.Threading.CancellationToken);

Expand All @@ -107,10 +111,11 @@ public async Task GetURNsByRegion_WhenEstablishmentUrnsReturnedFromRepo_IEnumebr
string[] regions = _fixture.Create<string[]>();
var establishmentUrns = _fixture.Create<List<int>>().AsEnumerable();
var mockRepo = new Mock<IEstablishmentRepository>();
var mockTrustRepo = new Mock<ITrustRepository>();
mockRepo.Setup(x => x.GetURNsByRegion(It.Is<string[]>(v => v == regions), It.IsAny<CancellationToken>())).Returns(Task.FromResult(establishmentUrns));

var establishmentQueries = new EstablishmentQueries(
mockRepo.Object);
mockRepo.Object, mockTrustRepo.Object);
CancellationToken cancellationToken = default(global::System.Threading.CancellationToken);

// Act
Expand All @@ -131,10 +136,11 @@ public async Task GetByUrns_WhenEstablishmentsReturnedFromRepo_ListOfEstablishme
int[] Urns = _fixture.Create<int[]>();
var establishments = _fixture.Create<List<Domain.Establishment.Establishment>>();
var mockRepo = new Mock<IEstablishmentRepository>();
var mockTrustRepo = new Mock<ITrustRepository>();
mockRepo.Setup(x => x.GetByUrns(It.Is<int[]>(v => v == Urns), It.IsAny<CancellationToken>())).Returns(Task.FromResult(establishments));

var establishmentQueries = new EstablishmentQueries(
mockRepo.Object);
mockRepo.Object, mockTrustRepo.Object);
CancellationToken cancellationToken = default(global::System.Threading.CancellationToken);
// Act
var result = await establishmentQueries.GetByUrns(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
using System.Threading;
using System;
using Dfe.Academies.Application.Builders;
using Dfe.Academies.Domain.Trust;

namespace Dfe.Academies.Application.Queries.Establishment
{
public class EstablishmentQueries : IEstablishmentQueries
{
private readonly IEstablishmentRepository _establishmentRepository;
private readonly ITrustRepository _trustRepository;

public EstablishmentQueries(IEstablishmentRepository establishmentRepository)
public EstablishmentQueries(IEstablishmentRepository establishmentRepository, ITrustRepository trustRepository)
{
_establishmentRepository = establishmentRepository;
_trustRepository = trustRepository;
}
public async Task<EstablishmentDto?> GetByUkprn(string ukprn, CancellationToken cancellationToken)
{
Expand All @@ -37,6 +40,12 @@ public async Task<IEnumerable<int>> GetURNsByRegion(string[] regions, Cancellati

return URNs;
}
public async Task<List<EstablishmentDto>> GetByTrust(string trustUkprn, CancellationToken cancellationToken)
{
var trust = await _trustRepository.GetTrustByUkprn(trustUkprn, cancellationToken);
var establishments = await _establishmentRepository.GetByTrust(trust.SK, cancellationToken).ConfigureAwait(false);
return establishments.Select(MapToEstablishmentDto).ToList();
}
public async Task<List<EstablishmentDto>> GetByUrns(int[] Urns, CancellationToken cancellationToken)
{
var establishments = await _establishmentRepository.GetByUrns(Urns, cancellationToken).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface IEstablishmentQueries
Task<EstablishmentDto?> GetByUrn(string urn, CancellationToken cancellationToken);
Task<(List<EstablishmentDto>, int)> Search(string name, string ukPrn, string urn, CancellationToken cancellationToken);
Task<IEnumerable<int>> GetURNsByRegion(string[] regions, CancellationToken cancellationToken);
Task<List<EstablishmentDto>> GetByUrns(int[] Urns, CancellationToken cancellationToken);
Task<List<EstablishmentDto>> GetByUrns(int[] Urns, CancellationToken cancellationToken);
Task<List<EstablishmentDto>> GetByTrust(string trustUkprn, CancellationToken cancellationToken);
}
}
1 change: 1 addition & 0 deletions Dfe.Academies.Application/Queries/Trust/ITrustQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Dfe.Academies.Application.Queries.Trust
public interface ITrustQueries
{
Task<TrustDto?> GetByUkprn(string ukprn, CancellationToken cancellationToken);
Task<TrustDto?> GetByCompaniesHouseNumber(string companiesHouseNumber, CancellationToken cancellationToken);
Task<List<TrustDto>> GetByUkprns(string[] ukprns, CancellationToken cancellationToken);
Task<(List<TrustDto>, int)> Search(int page, int count, string name, string ukPrn, string companiesHouseNumber, CancellationToken cancellationToken);
}
Expand Down
5 changes: 5 additions & 0 deletions Dfe.Academies.Application/Queries/Trust/TrustQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public TrustQueries(ITrustRepository trustRepository)
var trust = await _trustRepository.GetTrustByUkprn(ukprn, cancellationToken).ConfigureAwait(false);
return trust == null ? null : MapToTrustDto(trust);
}
public async Task<TrustDto?> GetByCompaniesHouseNumber(string companiesHouseNumber, CancellationToken cancellationToken)
{
var trust = await _trustRepository.GetTrustByCompaniesHouseNumber(companiesHouseNumber, cancellationToken).ConfigureAwait(false);
return trust == null ? null : MapToTrustDto(trust);
}

public async Task<(List<TrustDto>, int)> Search(int page, int count, string name, string ukPrn, string companiesHouseNumber, CancellationToken cancellationToken)
{
Expand Down
22 changes: 22 additions & 0 deletions Dfe.Academies.Domain/Establishment/EducationEstablishmentTrust.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dfe.Academies.Domain.Establishment
{
public class EducationEstablishmentTrust
{
public int SK { get; set; }

// Foreign keys
public int FK_Trust { get; set; }
public int FK_EducationEstablishment { get; set; }

// Navigation properties
public virtual Trust.Trust Trust { get; set; }

Check warning on line 18 in Dfe.Academies.Domain/Establishment/EducationEstablishmentTrust.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Non-nullable property 'Trust' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public virtual Establishment Establishment { get; set; }

Check warning on line 19 in Dfe.Academies.Domain/Establishment/EducationEstablishmentTrust.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Non-nullable property 'Establishment' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ public interface IEstablishmentRepository : IGenericRepository<Establishment>
Task<Establishment?> GetEstablishmentByUrn(string urn, CancellationToken cancellationToken);
Task<List<Establishment>> Search(string name, string ukPrn,
string urn, CancellationToken cancellationToken);
Task<IEnumerable<int>> GetURNsByRegion(string[] regions, CancellationToken cancellationToken);
Task<IEnumerable<int>> GetURNsByRegion(string[] regions, CancellationToken cancellationToken);
Task<List<Establishment>> GetByTrust(long? trustId, CancellationToken cancellationToken);
Task<List<Establishment>> GetByUrns(int[] Urns, CancellationToken cancellationToken);
}
}
1 change: 1 addition & 0 deletions Dfe.Academies.Domain/Trust/ITrustRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Dfe.Academies.Domain.Trust
public interface ITrustRepository : IGenericRepository<Trust>
{
Task<Trust?> GetTrustByUkprn(string ukprn, CancellationToken cancellationToken);
Task<Trust?> GetTrustByCompaniesHouseNumber(string companiesHouseNumber, CancellationToken cancellationToken);
Task<List<Trust>> GetTrustsByUkprns(string[] ukprns, CancellationToken cancellationToken);
Task<List<Trust>> Search(int page, int count, string name, string ukPrn,
string companiesHouseNumber, CancellationToken cancellationToken);
Expand Down
28 changes: 28 additions & 0 deletions TramsDataApi/Controllers/V4/EstablishmentsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,33 @@ public async Task<ActionResult<List<EstablishmentDto>>> GetByUrns([FromQuery] in
var response = new List<EstablishmentDto>(establishments);
return Ok(response);
}
/// <summary>
/// Retrieves a list of establishments by their Trust UK Provider Reference Number (UKPRN) identifier.
/// </summary>
/// <param name="trustUkprn">Contains the Trust UK Provider Reference Number (UKPRN) identifier of the establishments.</param>
/// /// <param name="cancellationToken"></param>
/// <returns>List of establishments or NotFound if none are available.</returns>
[HttpGet]
[Route("establishments/trust")]
[SwaggerOperation(Summary = "Get Establishments by Trust", Description = "Returns a list of establishments specified by Trust UKPRN.")]
[SwaggerResponse(200, "Successfully found and returned the establishments.")]
[SwaggerResponse(404, "Establishments with specified Trust UKPRN not found.")]
public async Task<ActionResult<List<EstablishmentDto>>> GetByTrust([FromQuery] string trustUkprn, CancellationToken cancellationToken)
{
var commaSeparatedRequestTrust = string.Join(",", trustUkprn);
_logger.LogInformation($"Attemping to get establishments by Trust UKPRN : {commaSeparatedRequestTrust}");

var establishments = await _establishmentQueries.GetByTrust(trustUkprn, cancellationToken).ConfigureAwait(false);

if (establishments == null)
{
_logger.LogInformation($"No establishment was found with the requested Trust UKPRN : {commaSeparatedRequestTrust}");
return NotFound();
}

_logger.LogInformation($"Returning Establishments for Trust with specific UKPRN : {commaSeparatedRequestTrust}");
var response = new List<EstablishmentDto>(establishments);
return Ok(response);
}
}
}
26 changes: 26 additions & 0 deletions TramsDataApi/Controllers/V4/TrustsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,32 @@ public async Task<ActionResult<TrustDto>> GetTrustByUkprn(string ukprn, Cancella
_logger.LogDebug(JsonSerializer.Serialize(trust));
return Ok(trust);
}
/// <summary>
/// Retrieves a Trust by its Companies House Number.
/// </summary>
/// <param name="companiesHouseNumber">The Companies House Number identifier.</param>
/// <param name="cancellationToken"></param>
/// <returns>A Trust or NotFound if not available.</returns>
[HttpGet]
[Route("trust/{companiesHouseNumber}")]
[SwaggerOperation(Summary = "Retrieve Trust by Companies House Number", Description = "Returns a Trust identified by Companies House Number.")]
[SwaggerResponse(200, "Successfully found and returned the Trust.")]
[SwaggerResponse(404, "Trust with specified Companies House Number not found.")]
public async Task<ActionResult<TrustDto>> GetTrustByCompaniesHouseNumber(string companiesHouseNumber, CancellationToken cancellationToken)
{
_logger.LogInformation($"Attempting to get trust by Companies House Number {companiesHouseNumber}");
var trust = await _trustQueries.GetByCompaniesHouseNumber(companiesHouseNumber, cancellationToken).ConfigureAwait(false);

if (trust == null)
{
_logger.LogInformation($"No trust found for Companies House Number {companiesHouseNumber}");
return NotFound();
}

_logger.LogInformation($"Returning trust found by Companies House Number {companiesHouseNumber}");
_logger.LogDebug(JsonSerializer.Serialize(trust));
return Ok(trust);
}

/// <summary>
/// Searches for Trusts based on query parameters.
Expand Down

0 comments on commit 61c6674

Please sign in to comment.