diff --git a/Dfe.Academies.Api.Infrastructure/Dfe.Academies.Infrastructure.csproj b/Dfe.Academies.Api.Infrastructure/Dfe.Academies.Infrastructure.csproj index a7cfc8198..614e0db44 100644 --- a/Dfe.Academies.Api.Infrastructure/Dfe.Academies.Infrastructure.csproj +++ b/Dfe.Academies.Api.Infrastructure/Dfe.Academies.Infrastructure.csproj @@ -21,4 +21,8 @@ + + + + diff --git a/Dfe.Academies.Api.Infrastructure/Migrations/20231218095513_Initial.Designer.cs b/Dfe.Academies.Api.Infrastructure/Migrations/20231218095513_Initial.Designer.cs new file mode 100644 index 000000000..0331cbe5c --- /dev/null +++ b/Dfe.Academies.Api.Infrastructure/Migrations/20231218095513_Initial.Designer.cs @@ -0,0 +1,768 @@ +// +using System; +using Dfe.Academies.Academisation.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Dfe.Academies.Infrastructure.Migrations +{ + [DbContext(typeof(MstrContext))] + [Migration("20231218095513_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.25") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.EducationEstablishmentTrust", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("EducationEstablishmentId") + .HasColumnType("int") + .HasColumnName("FK_EducationEstablishment"); + + b.Property("TrustId") + .HasColumnType("int") + .HasColumnName("FK_Trust"); + + b.HasKey("SK"); + + b.ToTable("EducationEstablishmentTrust", "mstr"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.Establishment", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("AddressLine1") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line1"); + + b.Property("AddressLine2") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line2"); + + b.Property("AddressLine3") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line3"); + + b.Property("AdministrativeDistrict") + .HasColumnType("nvarchar(max)") + .HasColumnName("Administrative District"); + + b.Property("BehaviourAndAttitudes") + .HasColumnType("int") + .HasColumnName("Behaviour and attitudes"); + + b.Property("CategoryOfConcern") + .HasColumnType("nvarchar(max)") + .HasColumnName("Category of concern"); + + b.Property("CloseDate") + .HasColumnType("datetime2") + .HasColumnName("CloseDate"); + + b.Property("County") + .HasColumnType("nvarchar(max)") + .HasColumnName("County"); + + b.Property("DateOfLatestShortInspection") + .HasColumnType("datetime2") + .HasColumnName("Date of latest short inspection"); + + b.Property("DidTheLatestShortInspectionConvertToAFullInspection") + .HasColumnType("nvarchar(max)") + .HasColumnName("Did the latest short inspection convert to a full inspection?"); + + b.Property("Diocese") + .HasColumnType("nvarchar(max)") + .HasColumnName("Diocese"); + + b.Property("DioceseCode") + .HasColumnType("nvarchar(max)") + .HasColumnName("Diocese(code)"); + + b.Property("EarlyYearsProvisionWhereApplicable") + .HasColumnType("int") + .HasColumnName("Early years provision (where applicable)"); + + b.Property("EffectivenessOfLeadershipAndManagement") + .HasColumnType("int") + .HasColumnName("Effectiveness of leadership and management"); + + b.Property("Email") + .HasColumnType("nvarchar(max)") + .HasColumnName("Email"); + + b.Property("EstablishmentGroupTypeId") + .HasColumnType("bigint") + .HasColumnName("FK_EstablishmentGroupType"); + + b.Property("EstablishmentName") + .HasColumnType("nvarchar(max)") + .HasColumnName("EstablishmentName"); + + b.Property("EstablishmentNumber") + .HasColumnType("int") + .HasColumnName("EstablishmentNumber"); + + b.Property("EstablishmentStatusId") + .HasColumnType("bigint") + .HasColumnName("FK_EstablishmentStatus"); + + b.Property("EstablishmentTypeId") + .HasColumnType("bigint") + .HasColumnName("FK_EstablishmentType"); + + b.Property("GORregion") + .HasColumnType("nvarchar(max)") + .HasColumnName("GORregion"); + + b.Property("GORregionCode") + .HasColumnType("nvarchar(max)") + .HasColumnName("GORregion(code)"); + + b.Property("GiasLastChangedDate") + .HasColumnType("datetime2"); + + b.Property("HeadFirstName") + .HasColumnType("nvarchar(max)") + .HasColumnName("HeadFirstName"); + + b.Property("HeadLastName") + .HasColumnType("nvarchar(max)") + .HasColumnName("HeadLastName"); + + b.Property("HeadPreferredJobTitle") + .HasColumnType("nvarchar(max)") + .HasColumnName("HeadPreferredJobTitle"); + + b.Property("HeadTitle") + .HasColumnType("nvarchar(max)") + .HasColumnName("HeadTitle"); + + b.Property("IfdPipelineSK") + .HasColumnType("bigint"); + + b.Property("InspectionEndDate") + .HasColumnType("datetime2") + .HasColumnName("Inspection end date"); + + b.Property("InspectionStartDate") + .HasColumnType("datetime2") + .HasColumnName("Inspection start date"); + + b.Property("InspectionType") + .HasColumnType("nvarchar(max)") + .HasColumnName("Inspection type"); + + b.Property("IsSafeguardingEffective") + .HasColumnType("nvarchar(max)") + .HasColumnName("Is safeguarding effective?"); + + b.Property("Latitude") + .HasColumnType("float") + .HasColumnName("Latitude"); + + b.Property("LocalAuthorityId") + .HasColumnType("bigint") + .HasColumnName("FK_LocalAuthority"); + + b.Property("Longitude") + .HasColumnType("float") + .HasColumnName("Longitude"); + + b.Property("MainPhone") + .HasColumnType("nvarchar(max)") + .HasColumnName("Main Phone"); + + b.Property("Modified") + .HasColumnType("datetime2") + .HasColumnName("Modified"); + + b.Property("ModifiedBy") + .HasColumnType("nvarchar(max)") + .HasColumnName("Modified By"); + + b.Property("NumberOfBoys") + .HasColumnType("int"); + + b.Property("NumberOfGirls") + .HasColumnType("int"); + + b.Property("NumberOfOtherSection8InspectionsSinceLastFullInspection") + .HasColumnType("int") + .HasColumnName("Number of other section 8 inspections since last full inspection"); + + b.Property("NumberOfPupils") + .HasColumnType("nvarchar(max)") + .HasColumnName("NumberOfPupils"); + + b.Property("NumberOfShortInspectionsSinceLastFullInspection") + .HasColumnType("int") + .HasColumnName("Number of short inspections since last full inspection"); + + b.Property("OfstedLastInspection") + .HasColumnType("nvarchar(max)") + .HasColumnName("OfstedLastInspection"); + + b.Property("OfstedRating") + .HasColumnType("nvarchar(max)") + .HasColumnName("OfstedRating"); + + b.Property("OpenDate") + .HasColumnType("nvarchar(max)") + .HasColumnName("OpenDate"); + + b.Property("OverallEffectiveness") + .HasColumnType("int") + .HasColumnName("Overall effectiveness"); + + b.Property("PK_CDM_ID") + .HasColumnType("bigint") + .HasColumnName("PK_CDM_ID"); + + b.Property("PK_GIAS_URN") + .HasColumnType("int") + .HasColumnName("PK_GIAS_URN"); + + b.Property("ParliamentaryConstituency") + .HasColumnType("nvarchar(max)") + .HasColumnName("Parliamentary constituency"); + + b.Property("ParliamentaryConstituencyCode") + .HasColumnType("nvarchar(max)") + .HasColumnName("ParliamentaryConstituency(code)"); + + b.Property("PercentageFSM") + .HasColumnType("nvarchar(max)") + .HasColumnName("PercentageFSM"); + + b.Property("PersonalDevelopment") + .HasColumnType("int") + .HasColumnName("Personal development"); + + b.Property("PhaseOfEducation") + .HasColumnType("nvarchar(max)") + .HasColumnName("PhaseOfEducation"); + + b.Property("PhaseOfEducationCode") + .HasColumnType("int") + .HasColumnName("PhaseOfEducation(code)"); + + b.Property("Postcode") + .HasColumnType("nvarchar(max)") + .HasColumnName("Postcode"); + + b.Property("PreviousCategoryOfConcern") + .HasColumnType("nvarchar(max)") + .HasColumnName("Previous category of concern"); + + b.Property("PreviousEarlyYearsProvisionWhereApplicable") + .HasColumnType("int") + .HasColumnName("Previous early years provision (where applicable)"); + + b.Property("PreviousFullInspectionOverallEffectiveness") + .HasColumnType("int") + .HasColumnName("Previous full inspection overall effectiveness"); + + b.Property("PreviousInspectionEndDate") + .HasColumnType("datetime2") + .HasColumnName("Previous inspection end date"); + + b.Property("PreviousInspectionStartDate") + .HasColumnType("datetime2") + .HasColumnName("Previous inspection start date"); + + b.Property("PreviousIsSafeguardingEffective") + .HasColumnType("nvarchar(max)") + .HasColumnName("Previous is safeguarding effective?"); + + b.Property("PreviousPublicationDate") + .HasColumnType("datetime2") + .HasColumnName("Previous publication date"); + + b.Property("ProjectLead") + .HasColumnType("nvarchar(max)") + .HasColumnName("Project Lead"); + + b.Property("PublicationDate") + .HasColumnType("datetime2") + .HasColumnName("Publication date"); + + b.Property("QualityOfEducation") + .HasColumnType("int") + .HasColumnName("Quality of education"); + + b.Property("ReasonEstablishmentClosed") + .HasColumnType("nvarchar(max)") + .HasColumnName("ReasonEstablishmentClosed"); + + b.Property("RegionId") + .HasColumnType("bigint") + .HasColumnName("FK_Region"); + + b.Property("ReligiousCharacter") + .HasColumnType("nvarchar(max)") + .HasColumnName("ReligiousCharacter"); + + b.Property("ReligiousCharacterCode") + .HasColumnType("nvarchar(max)") + .HasColumnName("ReligiousCharacter(code)"); + + b.Property("ReligiousEthos") + .HasColumnType("nvarchar(max)") + .HasColumnName("ReligiousEthos"); + + b.Property("RouteOfProject") + .HasColumnType("nvarchar(max)") + .HasColumnName("Route of Project"); + + b.Property("SFSOTerritory") + .HasColumnType("nvarchar(max)") + .HasColumnName("SFSO Territory"); + + b.Property("SchoolCapacity") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolCapacity"); + + b.Property("SenUnitCapacity") + .HasColumnType("int"); + + b.Property("SenUnitOnRoll") + .HasColumnType("int"); + + b.Property("ShortInspectionOverallOutcome") + .HasColumnType("nvarchar(max)") + .HasColumnName("Short inspection overall outcome"); + + b.Property("ShortInspectionPublicationDate") + .HasColumnType("datetime2") + .HasColumnName("Short inspection publication date"); + + b.Property("SixthFormProvisionWhereApplicable") + .HasColumnType("int") + .HasColumnName("Sixth form provision (where applicable)"); + + b.Property("StatutoryHighAge") + .HasColumnType("nvarchar(max)") + .HasColumnName("StatutoryHighAge"); + + b.Property("StatutoryLowAge") + .HasColumnType("nvarchar(max)") + .HasColumnName("StatutoryLowAge"); + + b.Property("TheIncomeDeprivationAffectingChildrenIndexIDACIQuintile") + .HasColumnType("int") + .HasColumnName("The income deprivation affecting children index (IDACI) quintile"); + + b.Property("Town") + .HasColumnType("nvarchar(max)") + .HasColumnName("Town"); + + b.Property("UKPRN") + .HasColumnType("nvarchar(max)") + .HasColumnName("UKPRN"); + + b.Property("URN") + .HasColumnType("int") + .HasColumnName("URN"); + + b.Property("URNAtCurrentFullInspection") + .HasColumnType("int") + .HasColumnName("URN at Current full inspection"); + + b.Property("URNAtPreviousFullInspection") + .HasColumnType("int") + .HasColumnName("URN at Previous full inspection"); + + b.Property("URNAtSection8Inspection") + .HasColumnType("int") + .HasColumnName("URN at Section 8 inspection"); + + b.Property("Website") + .HasColumnType("nvarchar(max)") + .HasColumnName("Website"); + + b.HasKey("SK"); + + b.HasIndex("EstablishmentTypeId"); + + b.HasIndex("IfdPipelineSK"); + + b.HasIndex("LocalAuthorityId"); + + b.ToTable("EducationEstablishment", "mstr"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.EstablishmentType", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("SK"); + + b.ToTable("Ref_EducationEstablishmentType", "mstr"); + + b.HasData( + new + { + SK = 224L, + Code = "35", + Name = "Free schools" + }, + new + { + SK = 228L, + Code = "18", + Name = "Further education" + }); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.IfdPipeline", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("DeliveryProcessPAN") + .HasColumnType("nvarchar(max)") + .HasColumnName("Delivery Process.PAN"); + + b.Property("DeliveryProcessPFI") + .HasColumnType("nvarchar(max)") + .HasColumnName("Delivery Process.PFI"); + + b.Property("GeneralDetailsUrn") + .HasColumnType("nvarchar(max)") + .HasColumnName("General Details.URN"); + + b.Property("ProjectTemplateInformationDeficit") + .HasColumnType("nvarchar(max)") + .HasColumnName("Project template information.Deficit?"); + + b.Property("ProjectTemplateInformationViabilityIssue") + .HasColumnType("nvarchar(max)") + .HasColumnName("Project template information.Viability issue?"); + + b.HasKey("SK"); + + b.ToTable("IfdPipeline", "mstr"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.LocalAuthority", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("SK"); + + b.ToTable("Ref_LocalAuthority", "mstr"); + + b.HasData( + new + { + SK = 1L, + Code = "202", + Name = "Barnsley" + }, + new + { + SK = 2L, + Code = "203", + Name = "Birmingham" + }, + new + { + SK = 3L, + Code = "204", + Name = "Bradford" + }); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Trust.Trust", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("AMSDTerritory") + .HasColumnType("nvarchar(max)") + .HasColumnName("AMSD Territory"); + + b.Property("AddressLine1") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line1"); + + b.Property("AddressLine2") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line2"); + + b.Property("AddressLine3") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line3"); + + b.Property("ClosedDate") + .HasColumnType("datetime2") + .HasColumnName("Closed Date"); + + b.Property("CompaniesHouseNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("Companies House Number"); + + b.Property("County") + .HasColumnType("nvarchar(max)") + .HasColumnName("County"); + + b.Property("CurrentSingleListGrouping") + .HasColumnType("nvarchar(max)") + .HasColumnName("Current Single List Grouping"); + + b.Property("DateActionPlannedFor") + .HasColumnType("datetime2") + .HasColumnName("Date Action Planned For"); + + b.Property("DateEnteredOntoSingleList") + .HasColumnType("datetime2") + .HasColumnName("Date Entered Onto Single List"); + + b.Property("DateOfGroupingDecision") + .HasColumnType("datetime2") + .HasColumnName("Date of Grouping Decision"); + + b.Property("DateOfTrustReviewMeeting") + .HasColumnType("datetime2") + .HasColumnName("Date of Trust Review Meeting"); + + b.Property("EfficiencyICFPReviewCompleted") + .HasColumnType("nvarchar(max)") + .HasColumnName("Efficiency ICFP Review Completed"); + + b.Property("EfficiencyICFPReviewOther") + .HasColumnType("nvarchar(max)") + .HasColumnName("Efficiency ICFP Review Other"); + + b.Property("ExternalGovernanceReviewDate") + .HasColumnType("datetime2") + .HasColumnName("External Governance Review Date"); + + b.Property("FollowUpLetterSent") + .HasColumnType("nvarchar(max)") + .HasColumnName("Follow Up Letter Sent"); + + b.Property("GroupID") + .HasColumnType("nvarchar(max)") + .HasColumnName("Group ID"); + + b.Property("GroupUID") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Group UID"); + + b.Property("IncorporatedOnOpenDate") + .HasColumnType("datetime2") + .HasColumnName("Incorporated on (open date)"); + + b.Property("JoinedDate") + .HasColumnType("datetime2") + .HasColumnName("Joined Date"); + + b.Property("LeadAMSDTerritory") + .HasColumnType("nvarchar(max)") + .HasColumnName("Lead AMSD Territory"); + + b.Property("LinkToWorkplaceForEfficiencyICFPReview") + .HasColumnType("nvarchar(max)") + .HasColumnName("Link To Workplace For Efficiency ICFP Review"); + + b.Property("MainPhone") + .HasColumnType("nvarchar(max)") + .HasColumnName("Main Phone"); + + b.Property("Modified") + .HasColumnType("datetime2") + .HasColumnName("Modified"); + + b.Property("ModifiedBy") + .HasColumnType("nvarchar(max)") + .HasColumnName("Modified By"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Name"); + + b.Property("NumberInTrust") + .HasColumnType("int") + .HasColumnName("Number In Trust"); + + b.Property("Postcode") + .HasColumnType("nvarchar(max)") + .HasColumnName("Postcode"); + + b.Property("PrioritisedForReview") + .HasColumnType("nvarchar(max)") + .HasColumnName("Prioritised for Review"); + + b.Property("RID") + .HasColumnType("nvarchar(max)") + .HasColumnName("RID"); + + b.Property("RegionId") + .HasColumnType("bigint") + .HasColumnName("FK_Region"); + + b.Property("Town") + .HasColumnType("nvarchar(max)") + .HasColumnName("Town"); + + b.Property("TrustBandingId") + .HasColumnType("bigint") + .HasColumnName("FK_TrustBanding"); + + b.Property("TrustPerformanceAndRiskDateOfMeeting") + .HasColumnType("datetime2") + .HasColumnName("Trust Performance And Risk Date Of Meeting"); + + b.Property("TrustReviewWriteUp") + .HasColumnType("nvarchar(max)") + .HasColumnName("Trust Review Write Up"); + + b.Property("TrustStatus") + .HasColumnType("nvarchar(max)") + .HasColumnName("Trust Status"); + + b.Property("TrustStatusId") + .HasColumnType("bigint") + .HasColumnName("FK_TrustStatus"); + + b.Property("TrustTypeId") + .HasColumnType("bigint") + .HasColumnName("FK_TrustType"); + + b.Property("UKPRN") + .HasColumnType("nvarchar(max)") + .HasColumnName("UKPRN"); + + b.Property("UPIN") + .HasColumnType("nvarchar(max)") + .HasColumnName("UPIN"); + + b.Property("WIPSummaryGoesToMinister") + .HasColumnType("nvarchar(max)") + .HasColumnName("WIP Summary Goes To Minister"); + + b.HasKey("SK"); + + b.HasIndex("TrustTypeId"); + + b.ToTable("Trust", "mstr"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Trust.TrustType", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("SK"); + + b.ToTable("Ref_TrustType", "mstr"); + + b.HasData( + new + { + SK = 30L, + Code = "06", + Name = "Multi-academy trust" + }, + new + { + SK = 32L, + Code = "10", + Name = "Single-academy trust" + }); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.Establishment", b => + { + b.HasOne("Dfe.Academies.Domain.Establishment.EstablishmentType", "EstablishmentType") + .WithMany() + .HasForeignKey("EstablishmentTypeId"); + + b.HasOne("Dfe.Academies.Domain.Establishment.IfdPipeline", "IfdPipeline") + .WithMany() + .HasForeignKey("IfdPipelineSK"); + + b.HasOne("Dfe.Academies.Domain.Establishment.LocalAuthority", "LocalAuthority") + .WithMany() + .HasForeignKey("LocalAuthorityId"); + + b.Navigation("EstablishmentType"); + + b.Navigation("IfdPipeline"); + + b.Navigation("LocalAuthority"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Trust.Trust", b => + { + b.HasOne("Dfe.Academies.Domain.Trust.TrustType", "TrustType") + .WithMany() + .HasForeignKey("TrustTypeId"); + + b.Navigation("TrustType"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Dfe.Academies.Api.Infrastructure/Migrations/20231218095513_Initial.cs b/Dfe.Academies.Api.Infrastructure/Migrations/20231218095513_Initial.cs new file mode 100644 index 000000000..4898806fb --- /dev/null +++ b/Dfe.Academies.Api.Infrastructure/Migrations/20231218095513_Initial.cs @@ -0,0 +1,360 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Dfe.Academies.Infrastructure.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "mstr"); + + migrationBuilder.CreateTable( + name: "EducationEstablishmentTrust", + schema: "mstr", + columns: table => new + { + SK = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + FK_Trust = table.Column(type: "int", nullable: false), + FK_EducationEstablishment = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EducationEstablishmentTrust", x => x.SK); + }); + + migrationBuilder.CreateTable( + name: "IfdPipeline", + schema: "mstr", + columns: table => new + { + SK = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + GeneralDetailsURN = table.Column(name: "General Details.URN", type: "nvarchar(max)", nullable: true), + DeliveryProcessPFI = table.Column(name: "Delivery Process.PFI", type: "nvarchar(max)", nullable: true), + DeliveryProcessPAN = table.Column(name: "Delivery Process.PAN", type: "nvarchar(max)", nullable: true), + ProjecttemplateinformationDeficit = table.Column(name: "Project template information.Deficit?", type: "nvarchar(max)", nullable: true), + ProjecttemplateinformationViabilityissue = table.Column(name: "Project template information.Viability issue?", type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_IfdPipeline", x => x.SK); + }); + + migrationBuilder.CreateTable( + name: "Ref_EducationEstablishmentType", + schema: "mstr", + columns: table => new + { + SK = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: true), + Code = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Ref_EducationEstablishmentType", x => x.SK); + }); + + migrationBuilder.CreateTable( + name: "Ref_LocalAuthority", + schema: "mstr", + columns: table => new + { + SK = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: true), + Code = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Ref_LocalAuthority", x => x.SK); + }); + + migrationBuilder.CreateTable( + name: "Ref_TrustType", + schema: "mstr", + columns: table => new + { + SK = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: true), + Code = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Ref_TrustType", x => x.SK); + }); + + migrationBuilder.CreateTable( + name: "EducationEstablishment", + schema: "mstr", + columns: table => new + { + SK = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + PK_GIAS_URN = table.Column(type: "int", nullable: true), + PK_CDM_ID = table.Column(type: "bigint", nullable: true), + URN = table.Column(type: "int", nullable: true), + FK_LocalAuthority = table.Column(type: "bigint", nullable: true), + FK_EstablishmentType = table.Column(type: "bigint", nullable: true), + FK_EstablishmentGroupType = table.Column(type: "bigint", nullable: true), + FK_EstablishmentStatus = table.Column(type: "bigint", nullable: true), + FK_Region = table.Column(type: "bigint", nullable: true), + EstablishmentNumber = table.Column(type: "int", nullable: true), + EstablishmentName = table.Column(type: "nvarchar(max)", nullable: true), + Latitude = table.Column(type: "float", nullable: true), + Longitude = table.Column(type: "float", nullable: true), + MainPhone = table.Column(name: "Main Phone", type: "nvarchar(max)", nullable: true), + AddressLine1 = table.Column(name: "Address Line1", type: "nvarchar(max)", nullable: true), + AddressLine2 = table.Column(name: "Address Line2", type: "nvarchar(max)", nullable: true), + AddressLine3 = table.Column(name: "Address Line3", type: "nvarchar(max)", nullable: true), + Town = table.Column(type: "nvarchar(max)", nullable: true), + County = table.Column(type: "nvarchar(max)", nullable: true), + Postcode = table.Column(type: "nvarchar(max)", nullable: true), + Email = table.Column(type: "nvarchar(max)", nullable: true), + Website = table.Column(type: "nvarchar(max)", nullable: true), + StatutoryLowAge = table.Column(type: "nvarchar(max)", nullable: true), + StatutoryHighAge = table.Column(type: "nvarchar(max)", nullable: true), + SchoolCapacity = table.Column(type: "nvarchar(max)", nullable: true), + NumberOfPupils = table.Column(type: "nvarchar(max)", nullable: true), + OfstedLastInspection = table.Column(type: "nvarchar(max)", nullable: true), + OfstedRating = table.Column(type: "nvarchar(max)", nullable: true), + OpenDate = table.Column(type: "nvarchar(max)", nullable: true), + Modified = table.Column(type: "datetime2", nullable: true), + ModifiedBy = table.Column(name: "Modified By", type: "nvarchar(max)", nullable: true), + TheincomedeprivationaffectingchildrenindexIDACIquintile = table.Column(name: "The income deprivation affecting children index (IDACI) quintile", type: "int", nullable: true), + Numberofshortinspectionssincelastfullinspection = table.Column(name: "Number of short inspections since last full inspection", type: "int", nullable: true), + Dateoflatestshortinspection = table.Column(name: "Date of latest short inspection", type: "datetime2", nullable: true), + Shortinspectionpublicationdate = table.Column(name: "Short inspection publication date", type: "datetime2", nullable: true), + Didthelatestshortinspectionconverttoafullinspection = table.Column(name: "Did the latest short inspection convert to a full inspection?", type: "nvarchar(max)", nullable: true), + Shortinspectionoveralloutcome = table.Column(name: "Short inspection overall outcome", type: "nvarchar(max)", nullable: true), + Numberofothersection8inspectionssincelastfullinspection = table.Column(name: "Number of other section 8 inspections since last full inspection", type: "int", nullable: true), + Inspectiontype = table.Column(name: "Inspection type", type: "nvarchar(max)", nullable: true), + Inspectionstartdate = table.Column(name: "Inspection start date", type: "datetime2", nullable: true), + Inspectionenddate = table.Column(name: "Inspection end date", type: "datetime2", nullable: true), + Publicationdate = table.Column(name: "Publication date", type: "datetime2", nullable: true), + Overalleffectiveness = table.Column(name: "Overall effectiveness", type: "int", nullable: true), + Categoryofconcern = table.Column(name: "Category of concern", type: "nvarchar(max)", nullable: true), + Earlyyearsprovisionwhereapplicable = table.Column(name: "Early years provision (where applicable)", type: "int", nullable: true), + Effectivenessofleadershipandmanagement = table.Column(name: "Effectiveness of leadership and management", type: "int", nullable: true), + Issafeguardingeffective = table.Column(name: "Is safeguarding effective?", type: "nvarchar(max)", nullable: true), + Previousinspectionstartdate = table.Column(name: "Previous inspection start date", type: "datetime2", nullable: true), + Previousinspectionenddate = table.Column(name: "Previous inspection end date", type: "datetime2", nullable: true), + Previouspublicationdate = table.Column(name: "Previous publication date", type: "datetime2", nullable: true), + Previousfullinspectionoveralleffectiveness = table.Column(name: "Previous full inspection overall effectiveness", type: "int", nullable: true), + Previouscategoryofconcern = table.Column(name: "Previous category of concern", type: "nvarchar(max)", nullable: true), + Previousearlyyearsprovisionwhereapplicable = table.Column(name: "Previous early years provision (where applicable)", type: "int", nullable: true), + Previousissafeguardingeffective = table.Column(name: "Previous is safeguarding effective?", type: "nvarchar(max)", nullable: true), + HeadTitle = table.Column(type: "nvarchar(max)", nullable: true), + HeadFirstName = table.Column(type: "nvarchar(max)", nullable: true), + HeadLastName = table.Column(type: "nvarchar(max)", nullable: true), + HeadPreferredJobTitle = table.Column(type: "nvarchar(max)", nullable: true), + PhaseOfEducation = table.Column(type: "nvarchar(max)", nullable: true), + PercentageFSM = table.Column(type: "nvarchar(max)", nullable: true), + UKPRN = table.Column(type: "nvarchar(max)", nullable: true), + ReligiousCharacter = table.Column(type: "nvarchar(max)", nullable: true), + ReligiousEthos = table.Column(type: "nvarchar(max)", nullable: true), + Diocese = table.Column(type: "nvarchar(max)", nullable: true), + ReasonEstablishmentClosed = table.Column(type: "nvarchar(max)", nullable: true), + CloseDate = table.Column(type: "datetime2", nullable: true), + ProjectLead = table.Column(name: "Project Lead", type: "nvarchar(max)", nullable: true), + Parliamentaryconstituency = table.Column(name: "Parliamentary constituency", type: "nvarchar(max)", nullable: true), + Qualityofeducation = table.Column(name: "Quality of education", type: "int", nullable: true), + Behaviourandattitudes = table.Column(name: "Behaviour and attitudes", type: "int", nullable: true), + Personaldevelopment = table.Column(name: "Personal development", type: "int", nullable: true), + Sixthformprovisionwhereapplicable = table.Column(name: "Sixth form provision (where applicable)", type: "int", nullable: true), + URNatCurrentfullinspection = table.Column(name: "URN at Current full inspection", type: "int", nullable: true), + URNatPreviousfullinspection = table.Column(name: "URN at Previous full inspection", type: "int", nullable: true), + URNatSection8inspection = table.Column(name: "URN at Section 8 inspection", type: "int", nullable: true), + AdministrativeDistrict = table.Column(name: "Administrative District", type: "nvarchar(max)", nullable: true), + RouteofProject = table.Column(name: "Route of Project", type: "nvarchar(max)", nullable: true), + GORregion = table.Column(type: "nvarchar(max)", nullable: true), + SFSOTerritory = table.Column(name: "SFSO Territory", type: "nvarchar(max)", nullable: true), + GiasLastChangedDate = table.Column(type: "datetime2", nullable: true), + NumberOfBoys = table.Column(type: "int", nullable: true), + NumberOfGirls = table.Column(type: "int", nullable: true), + Diocesecode = table.Column(name: "Diocese(code)", type: "nvarchar(max)", nullable: true), + GORregioncode = table.Column(name: "GORregion(code)", type: "nvarchar(max)", nullable: true), + ReligiousCharactercode = table.Column(name: "ReligiousCharacter(code)", type: "nvarchar(max)", nullable: true), + ParliamentaryConstituencycode = table.Column(name: "ParliamentaryConstituency(code)", type: "nvarchar(max)", nullable: true), + PhaseOfEducationcode = table.Column(name: "PhaseOfEducation(code)", type: "int", nullable: true), + SenUnitCapacity = table.Column(type: "int", nullable: true), + SenUnitOnRoll = table.Column(type: "int", nullable: true), + IfdPipelineSK = table.Column(type: "bigint", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EducationEstablishment", x => x.SK); + table.ForeignKey( + name: "FK_EducationEstablishment_IfdPipeline_IfdPipelineSK", + column: x => x.IfdPipelineSK, + principalSchema: "mstr", + principalTable: "IfdPipeline", + principalColumn: "SK"); + table.ForeignKey( + name: "FK_EducationEstablishment_Ref_EducationEstablishmentType_FK_EstablishmentType", + column: x => x.FK_EstablishmentType, + principalSchema: "mstr", + principalTable: "Ref_EducationEstablishmentType", + principalColumn: "SK"); + table.ForeignKey( + name: "FK_EducationEstablishment_Ref_LocalAuthority_FK_LocalAuthority", + column: x => x.FK_LocalAuthority, + principalSchema: "mstr", + principalTable: "Ref_LocalAuthority", + principalColumn: "SK"); + }); + + migrationBuilder.CreateTable( + name: "Trust", + schema: "mstr", + columns: table => new + { + SK = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + FK_TrustType = table.Column(type: "bigint", nullable: true), + FK_Region = table.Column(type: "bigint", nullable: true), + FK_TrustBanding = table.Column(type: "bigint", nullable: true), + FK_TrustStatus = table.Column(type: "bigint", nullable: true), + GroupUID = table.Column(name: "Group UID", type: "nvarchar(max)", nullable: false), + GroupID = table.Column(name: "Group ID", type: "nvarchar(max)", nullable: true), + RID = table.Column(type: "nvarchar(max)", nullable: true), + Name = table.Column(type: "nvarchar(max)", nullable: false), + CompaniesHouseNumber = table.Column(name: "Companies House Number", type: "nvarchar(max)", nullable: true), + ClosedDate = table.Column(name: "Closed Date", type: "datetime2", nullable: true), + TrustStatus = table.Column(name: "Trust Status", type: "nvarchar(max)", nullable: true), + JoinedDate = table.Column(name: "Joined Date", type: "datetime2", nullable: true), + MainPhone = table.Column(name: "Main Phone", type: "nvarchar(max)", nullable: true), + AddressLine1 = table.Column(name: "Address Line1", type: "nvarchar(max)", nullable: true), + AddressLine2 = table.Column(name: "Address Line2", type: "nvarchar(max)", nullable: true), + AddressLine3 = table.Column(name: "Address Line3", type: "nvarchar(max)", nullable: true), + Town = table.Column(type: "nvarchar(max)", nullable: true), + County = table.Column(type: "nvarchar(max)", nullable: true), + Postcode = table.Column(type: "nvarchar(max)", nullable: true), + PrioritisedforReview = table.Column(name: "Prioritised for Review", type: "nvarchar(max)", nullable: true), + CurrentSingleListGrouping = table.Column(name: "Current Single List Grouping", type: "nvarchar(max)", nullable: true), + DateofGroupingDecision = table.Column(name: "Date of Grouping Decision", type: "datetime2", nullable: true), + DateEnteredOntoSingleList = table.Column(name: "Date Entered Onto Single List", type: "datetime2", nullable: true), + TrustReviewWriteUp = table.Column(name: "Trust Review Write Up", type: "nvarchar(max)", nullable: true), + DateofTrustReviewMeeting = table.Column(name: "Date of Trust Review Meeting", type: "datetime2", nullable: true), + FollowUpLetterSent = table.Column(name: "Follow Up Letter Sent", type: "nvarchar(max)", nullable: true), + DateActionPlannedFor = table.Column(name: "Date Action Planned For", type: "datetime2", nullable: true), + WIPSummaryGoesToMinister = table.Column(name: "WIP Summary Goes To Minister", type: "nvarchar(max)", nullable: true), + ExternalGovernanceReviewDate = table.Column(name: "External Governance Review Date", type: "datetime2", nullable: true), + EfficiencyICFPReviewCompleted = table.Column(name: "Efficiency ICFP Review Completed", type: "nvarchar(max)", nullable: true), + EfficiencyICFPReviewOther = table.Column(name: "Efficiency ICFP Review Other", type: "nvarchar(max)", nullable: true), + LinkToWorkplaceForEfficiencyICFPReview = table.Column(name: "Link To Workplace For Efficiency ICFP Review", type: "nvarchar(max)", nullable: true), + NumberInTrust = table.Column(name: "Number In Trust", type: "int", nullable: true), + Modified = table.Column(type: "datetime2", nullable: true), + ModifiedBy = table.Column(name: "Modified By", type: "nvarchar(max)", nullable: true), + AMSDTerritory = table.Column(name: "AMSD Territory", type: "nvarchar(max)", nullable: true), + LeadAMSDTerritory = table.Column(name: "Lead AMSD Territory", type: "nvarchar(max)", nullable: true), + UKPRN = table.Column(type: "nvarchar(max)", nullable: true), + TrustPerformanceAndRiskDateOfMeeting = table.Column(name: "Trust Performance And Risk Date Of Meeting", type: "datetime2", nullable: true), + UPIN = table.Column(type: "nvarchar(max)", nullable: true), + Incorporatedonopendate = table.Column(name: "Incorporated on (open date)", type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Trust", x => x.SK); + table.ForeignKey( + name: "FK_Trust_Ref_TrustType_FK_TrustType", + column: x => x.FK_TrustType, + principalSchema: "mstr", + principalTable: "Ref_TrustType", + principalColumn: "SK"); + }); + + migrationBuilder.InsertData( + schema: "mstr", + table: "Ref_EducationEstablishmentType", + columns: new[] { "SK", "Code", "Name" }, + values: new object[,] + { + { 224L, "35", "Free schools" }, + { 228L, "18", "Further education" } + }); + + migrationBuilder.InsertData( + schema: "mstr", + table: "Ref_LocalAuthority", + columns: new[] { "SK", "Code", "Name" }, + values: new object[,] + { + { 1L, "202", "Barnsley" }, + { 2L, "203", "Birmingham" }, + { 3L, "204", "Bradford" } + }); + + migrationBuilder.InsertData( + schema: "mstr", + table: "Ref_TrustType", + columns: new[] { "SK", "Code", "Name" }, + values: new object[,] + { + { 30L, "06", "Multi-academy trust" }, + { 32L, "10", "Single-academy trust" } + }); + + migrationBuilder.CreateIndex( + name: "IX_EducationEstablishment_FK_EstablishmentType", + schema: "mstr", + table: "EducationEstablishment", + column: "FK_EstablishmentType"); + + migrationBuilder.CreateIndex( + name: "IX_EducationEstablishment_FK_LocalAuthority", + schema: "mstr", + table: "EducationEstablishment", + column: "FK_LocalAuthority"); + + migrationBuilder.CreateIndex( + name: "IX_EducationEstablishment_IfdPipelineSK", + schema: "mstr", + table: "EducationEstablishment", + column: "IfdPipelineSK"); + + migrationBuilder.CreateIndex( + name: "IX_Trust_FK_TrustType", + schema: "mstr", + table: "Trust", + column: "FK_TrustType"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "EducationEstablishment", + schema: "mstr"); + + migrationBuilder.DropTable( + name: "EducationEstablishmentTrust", + schema: "mstr"); + + migrationBuilder.DropTable( + name: "Trust", + schema: "mstr"); + + migrationBuilder.DropTable( + name: "IfdPipeline", + schema: "mstr"); + + migrationBuilder.DropTable( + name: "Ref_EducationEstablishmentType", + schema: "mstr"); + + migrationBuilder.DropTable( + name: "Ref_LocalAuthority", + schema: "mstr"); + + migrationBuilder.DropTable( + name: "Ref_TrustType", + schema: "mstr"); + } + } +} diff --git a/Dfe.Academies.Api.Infrastructure/Migrations/MstrContextModelSnapshot.cs b/Dfe.Academies.Api.Infrastructure/Migrations/MstrContextModelSnapshot.cs new file mode 100644 index 000000000..f969e68c6 --- /dev/null +++ b/Dfe.Academies.Api.Infrastructure/Migrations/MstrContextModelSnapshot.cs @@ -0,0 +1,766 @@ +// +using System; +using Dfe.Academies.Academisation.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Dfe.Academies.Infrastructure.Migrations +{ + [DbContext(typeof(MstrContext))] + partial class MstrContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.25") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.EducationEstablishmentTrust", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("EducationEstablishmentId") + .HasColumnType("int") + .HasColumnName("FK_EducationEstablishment"); + + b.Property("TrustId") + .HasColumnType("int") + .HasColumnName("FK_Trust"); + + b.HasKey("SK"); + + b.ToTable("EducationEstablishmentTrust", "mstr"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.Establishment", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("AddressLine1") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line1"); + + b.Property("AddressLine2") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line2"); + + b.Property("AddressLine3") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line3"); + + b.Property("AdministrativeDistrict") + .HasColumnType("nvarchar(max)") + .HasColumnName("Administrative District"); + + b.Property("BehaviourAndAttitudes") + .HasColumnType("int") + .HasColumnName("Behaviour and attitudes"); + + b.Property("CategoryOfConcern") + .HasColumnType("nvarchar(max)") + .HasColumnName("Category of concern"); + + b.Property("CloseDate") + .HasColumnType("datetime2") + .HasColumnName("CloseDate"); + + b.Property("County") + .HasColumnType("nvarchar(max)") + .HasColumnName("County"); + + b.Property("DateOfLatestShortInspection") + .HasColumnType("datetime2") + .HasColumnName("Date of latest short inspection"); + + b.Property("DidTheLatestShortInspectionConvertToAFullInspection") + .HasColumnType("nvarchar(max)") + .HasColumnName("Did the latest short inspection convert to a full inspection?"); + + b.Property("Diocese") + .HasColumnType("nvarchar(max)") + .HasColumnName("Diocese"); + + b.Property("DioceseCode") + .HasColumnType("nvarchar(max)") + .HasColumnName("Diocese(code)"); + + b.Property("EarlyYearsProvisionWhereApplicable") + .HasColumnType("int") + .HasColumnName("Early years provision (where applicable)"); + + b.Property("EffectivenessOfLeadershipAndManagement") + .HasColumnType("int") + .HasColumnName("Effectiveness of leadership and management"); + + b.Property("Email") + .HasColumnType("nvarchar(max)") + .HasColumnName("Email"); + + b.Property("EstablishmentGroupTypeId") + .HasColumnType("bigint") + .HasColumnName("FK_EstablishmentGroupType"); + + b.Property("EstablishmentName") + .HasColumnType("nvarchar(max)") + .HasColumnName("EstablishmentName"); + + b.Property("EstablishmentNumber") + .HasColumnType("int") + .HasColumnName("EstablishmentNumber"); + + b.Property("EstablishmentStatusId") + .HasColumnType("bigint") + .HasColumnName("FK_EstablishmentStatus"); + + b.Property("EstablishmentTypeId") + .HasColumnType("bigint") + .HasColumnName("FK_EstablishmentType"); + + b.Property("GORregion") + .HasColumnType("nvarchar(max)") + .HasColumnName("GORregion"); + + b.Property("GORregionCode") + .HasColumnType("nvarchar(max)") + .HasColumnName("GORregion(code)"); + + b.Property("GiasLastChangedDate") + .HasColumnType("datetime2"); + + b.Property("HeadFirstName") + .HasColumnType("nvarchar(max)") + .HasColumnName("HeadFirstName"); + + b.Property("HeadLastName") + .HasColumnType("nvarchar(max)") + .HasColumnName("HeadLastName"); + + b.Property("HeadPreferredJobTitle") + .HasColumnType("nvarchar(max)") + .HasColumnName("HeadPreferredJobTitle"); + + b.Property("HeadTitle") + .HasColumnType("nvarchar(max)") + .HasColumnName("HeadTitle"); + + b.Property("IfdPipelineSK") + .HasColumnType("bigint"); + + b.Property("InspectionEndDate") + .HasColumnType("datetime2") + .HasColumnName("Inspection end date"); + + b.Property("InspectionStartDate") + .HasColumnType("datetime2") + .HasColumnName("Inspection start date"); + + b.Property("InspectionType") + .HasColumnType("nvarchar(max)") + .HasColumnName("Inspection type"); + + b.Property("IsSafeguardingEffective") + .HasColumnType("nvarchar(max)") + .HasColumnName("Is safeguarding effective?"); + + b.Property("Latitude") + .HasColumnType("float") + .HasColumnName("Latitude"); + + b.Property("LocalAuthorityId") + .HasColumnType("bigint") + .HasColumnName("FK_LocalAuthority"); + + b.Property("Longitude") + .HasColumnType("float") + .HasColumnName("Longitude"); + + b.Property("MainPhone") + .HasColumnType("nvarchar(max)") + .HasColumnName("Main Phone"); + + b.Property("Modified") + .HasColumnType("datetime2") + .HasColumnName("Modified"); + + b.Property("ModifiedBy") + .HasColumnType("nvarchar(max)") + .HasColumnName("Modified By"); + + b.Property("NumberOfBoys") + .HasColumnType("int"); + + b.Property("NumberOfGirls") + .HasColumnType("int"); + + b.Property("NumberOfOtherSection8InspectionsSinceLastFullInspection") + .HasColumnType("int") + .HasColumnName("Number of other section 8 inspections since last full inspection"); + + b.Property("NumberOfPupils") + .HasColumnType("nvarchar(max)") + .HasColumnName("NumberOfPupils"); + + b.Property("NumberOfShortInspectionsSinceLastFullInspection") + .HasColumnType("int") + .HasColumnName("Number of short inspections since last full inspection"); + + b.Property("OfstedLastInspection") + .HasColumnType("nvarchar(max)") + .HasColumnName("OfstedLastInspection"); + + b.Property("OfstedRating") + .HasColumnType("nvarchar(max)") + .HasColumnName("OfstedRating"); + + b.Property("OpenDate") + .HasColumnType("nvarchar(max)") + .HasColumnName("OpenDate"); + + b.Property("OverallEffectiveness") + .HasColumnType("int") + .HasColumnName("Overall effectiveness"); + + b.Property("PK_CDM_ID") + .HasColumnType("bigint") + .HasColumnName("PK_CDM_ID"); + + b.Property("PK_GIAS_URN") + .HasColumnType("int") + .HasColumnName("PK_GIAS_URN"); + + b.Property("ParliamentaryConstituency") + .HasColumnType("nvarchar(max)") + .HasColumnName("Parliamentary constituency"); + + b.Property("ParliamentaryConstituencyCode") + .HasColumnType("nvarchar(max)") + .HasColumnName("ParliamentaryConstituency(code)"); + + b.Property("PercentageFSM") + .HasColumnType("nvarchar(max)") + .HasColumnName("PercentageFSM"); + + b.Property("PersonalDevelopment") + .HasColumnType("int") + .HasColumnName("Personal development"); + + b.Property("PhaseOfEducation") + .HasColumnType("nvarchar(max)") + .HasColumnName("PhaseOfEducation"); + + b.Property("PhaseOfEducationCode") + .HasColumnType("int") + .HasColumnName("PhaseOfEducation(code)"); + + b.Property("Postcode") + .HasColumnType("nvarchar(max)") + .HasColumnName("Postcode"); + + b.Property("PreviousCategoryOfConcern") + .HasColumnType("nvarchar(max)") + .HasColumnName("Previous category of concern"); + + b.Property("PreviousEarlyYearsProvisionWhereApplicable") + .HasColumnType("int") + .HasColumnName("Previous early years provision (where applicable)"); + + b.Property("PreviousFullInspectionOverallEffectiveness") + .HasColumnType("int") + .HasColumnName("Previous full inspection overall effectiveness"); + + b.Property("PreviousInspectionEndDate") + .HasColumnType("datetime2") + .HasColumnName("Previous inspection end date"); + + b.Property("PreviousInspectionStartDate") + .HasColumnType("datetime2") + .HasColumnName("Previous inspection start date"); + + b.Property("PreviousIsSafeguardingEffective") + .HasColumnType("nvarchar(max)") + .HasColumnName("Previous is safeguarding effective?"); + + b.Property("PreviousPublicationDate") + .HasColumnType("datetime2") + .HasColumnName("Previous publication date"); + + b.Property("ProjectLead") + .HasColumnType("nvarchar(max)") + .HasColumnName("Project Lead"); + + b.Property("PublicationDate") + .HasColumnType("datetime2") + .HasColumnName("Publication date"); + + b.Property("QualityOfEducation") + .HasColumnType("int") + .HasColumnName("Quality of education"); + + b.Property("ReasonEstablishmentClosed") + .HasColumnType("nvarchar(max)") + .HasColumnName("ReasonEstablishmentClosed"); + + b.Property("RegionId") + .HasColumnType("bigint") + .HasColumnName("FK_Region"); + + b.Property("ReligiousCharacter") + .HasColumnType("nvarchar(max)") + .HasColumnName("ReligiousCharacter"); + + b.Property("ReligiousCharacterCode") + .HasColumnType("nvarchar(max)") + .HasColumnName("ReligiousCharacter(code)"); + + b.Property("ReligiousEthos") + .HasColumnType("nvarchar(max)") + .HasColumnName("ReligiousEthos"); + + b.Property("RouteOfProject") + .HasColumnType("nvarchar(max)") + .HasColumnName("Route of Project"); + + b.Property("SFSOTerritory") + .HasColumnType("nvarchar(max)") + .HasColumnName("SFSO Territory"); + + b.Property("SchoolCapacity") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolCapacity"); + + b.Property("SenUnitCapacity") + .HasColumnType("int"); + + b.Property("SenUnitOnRoll") + .HasColumnType("int"); + + b.Property("ShortInspectionOverallOutcome") + .HasColumnType("nvarchar(max)") + .HasColumnName("Short inspection overall outcome"); + + b.Property("ShortInspectionPublicationDate") + .HasColumnType("datetime2") + .HasColumnName("Short inspection publication date"); + + b.Property("SixthFormProvisionWhereApplicable") + .HasColumnType("int") + .HasColumnName("Sixth form provision (where applicable)"); + + b.Property("StatutoryHighAge") + .HasColumnType("nvarchar(max)") + .HasColumnName("StatutoryHighAge"); + + b.Property("StatutoryLowAge") + .HasColumnType("nvarchar(max)") + .HasColumnName("StatutoryLowAge"); + + b.Property("TheIncomeDeprivationAffectingChildrenIndexIDACIQuintile") + .HasColumnType("int") + .HasColumnName("The income deprivation affecting children index (IDACI) quintile"); + + b.Property("Town") + .HasColumnType("nvarchar(max)") + .HasColumnName("Town"); + + b.Property("UKPRN") + .HasColumnType("nvarchar(max)") + .HasColumnName("UKPRN"); + + b.Property("URN") + .HasColumnType("int") + .HasColumnName("URN"); + + b.Property("URNAtCurrentFullInspection") + .HasColumnType("int") + .HasColumnName("URN at Current full inspection"); + + b.Property("URNAtPreviousFullInspection") + .HasColumnType("int") + .HasColumnName("URN at Previous full inspection"); + + b.Property("URNAtSection8Inspection") + .HasColumnType("int") + .HasColumnName("URN at Section 8 inspection"); + + b.Property("Website") + .HasColumnType("nvarchar(max)") + .HasColumnName("Website"); + + b.HasKey("SK"); + + b.HasIndex("EstablishmentTypeId"); + + b.HasIndex("IfdPipelineSK"); + + b.HasIndex("LocalAuthorityId"); + + b.ToTable("EducationEstablishment", "mstr"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.EstablishmentType", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("SK"); + + b.ToTable("Ref_EducationEstablishmentType", "mstr"); + + b.HasData( + new + { + SK = 224L, + Code = "35", + Name = "Free schools" + }, + new + { + SK = 228L, + Code = "18", + Name = "Further education" + }); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.IfdPipeline", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("DeliveryProcessPAN") + .HasColumnType("nvarchar(max)") + .HasColumnName("Delivery Process.PAN"); + + b.Property("DeliveryProcessPFI") + .HasColumnType("nvarchar(max)") + .HasColumnName("Delivery Process.PFI"); + + b.Property("GeneralDetailsUrn") + .HasColumnType("nvarchar(max)") + .HasColumnName("General Details.URN"); + + b.Property("ProjectTemplateInformationDeficit") + .HasColumnType("nvarchar(max)") + .HasColumnName("Project template information.Deficit?"); + + b.Property("ProjectTemplateInformationViabilityIssue") + .HasColumnType("nvarchar(max)") + .HasColumnName("Project template information.Viability issue?"); + + b.HasKey("SK"); + + b.ToTable("IfdPipeline", "mstr"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.LocalAuthority", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("SK"); + + b.ToTable("Ref_LocalAuthority", "mstr"); + + b.HasData( + new + { + SK = 1L, + Code = "202", + Name = "Barnsley" + }, + new + { + SK = 2L, + Code = "203", + Name = "Birmingham" + }, + new + { + SK = 3L, + Code = "204", + Name = "Bradford" + }); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Trust.Trust", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("AMSDTerritory") + .HasColumnType("nvarchar(max)") + .HasColumnName("AMSD Territory"); + + b.Property("AddressLine1") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line1"); + + b.Property("AddressLine2") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line2"); + + b.Property("AddressLine3") + .HasColumnType("nvarchar(max)") + .HasColumnName("Address Line3"); + + b.Property("ClosedDate") + .HasColumnType("datetime2") + .HasColumnName("Closed Date"); + + b.Property("CompaniesHouseNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("Companies House Number"); + + b.Property("County") + .HasColumnType("nvarchar(max)") + .HasColumnName("County"); + + b.Property("CurrentSingleListGrouping") + .HasColumnType("nvarchar(max)") + .HasColumnName("Current Single List Grouping"); + + b.Property("DateActionPlannedFor") + .HasColumnType("datetime2") + .HasColumnName("Date Action Planned For"); + + b.Property("DateEnteredOntoSingleList") + .HasColumnType("datetime2") + .HasColumnName("Date Entered Onto Single List"); + + b.Property("DateOfGroupingDecision") + .HasColumnType("datetime2") + .HasColumnName("Date of Grouping Decision"); + + b.Property("DateOfTrustReviewMeeting") + .HasColumnType("datetime2") + .HasColumnName("Date of Trust Review Meeting"); + + b.Property("EfficiencyICFPReviewCompleted") + .HasColumnType("nvarchar(max)") + .HasColumnName("Efficiency ICFP Review Completed"); + + b.Property("EfficiencyICFPReviewOther") + .HasColumnType("nvarchar(max)") + .HasColumnName("Efficiency ICFP Review Other"); + + b.Property("ExternalGovernanceReviewDate") + .HasColumnType("datetime2") + .HasColumnName("External Governance Review Date"); + + b.Property("FollowUpLetterSent") + .HasColumnType("nvarchar(max)") + .HasColumnName("Follow Up Letter Sent"); + + b.Property("GroupID") + .HasColumnType("nvarchar(max)") + .HasColumnName("Group ID"); + + b.Property("GroupUID") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Group UID"); + + b.Property("IncorporatedOnOpenDate") + .HasColumnType("datetime2") + .HasColumnName("Incorporated on (open date)"); + + b.Property("JoinedDate") + .HasColumnType("datetime2") + .HasColumnName("Joined Date"); + + b.Property("LeadAMSDTerritory") + .HasColumnType("nvarchar(max)") + .HasColumnName("Lead AMSD Territory"); + + b.Property("LinkToWorkplaceForEfficiencyICFPReview") + .HasColumnType("nvarchar(max)") + .HasColumnName("Link To Workplace For Efficiency ICFP Review"); + + b.Property("MainPhone") + .HasColumnType("nvarchar(max)") + .HasColumnName("Main Phone"); + + b.Property("Modified") + .HasColumnType("datetime2") + .HasColumnName("Modified"); + + b.Property("ModifiedBy") + .HasColumnType("nvarchar(max)") + .HasColumnName("Modified By"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Name"); + + b.Property("NumberInTrust") + .HasColumnType("int") + .HasColumnName("Number In Trust"); + + b.Property("Postcode") + .HasColumnType("nvarchar(max)") + .HasColumnName("Postcode"); + + b.Property("PrioritisedForReview") + .HasColumnType("nvarchar(max)") + .HasColumnName("Prioritised for Review"); + + b.Property("RID") + .HasColumnType("nvarchar(max)") + .HasColumnName("RID"); + + b.Property("RegionId") + .HasColumnType("bigint") + .HasColumnName("FK_Region"); + + b.Property("Town") + .HasColumnType("nvarchar(max)") + .HasColumnName("Town"); + + b.Property("TrustBandingId") + .HasColumnType("bigint") + .HasColumnName("FK_TrustBanding"); + + b.Property("TrustPerformanceAndRiskDateOfMeeting") + .HasColumnType("datetime2") + .HasColumnName("Trust Performance And Risk Date Of Meeting"); + + b.Property("TrustReviewWriteUp") + .HasColumnType("nvarchar(max)") + .HasColumnName("Trust Review Write Up"); + + b.Property("TrustStatus") + .HasColumnType("nvarchar(max)") + .HasColumnName("Trust Status"); + + b.Property("TrustStatusId") + .HasColumnType("bigint") + .HasColumnName("FK_TrustStatus"); + + b.Property("TrustTypeId") + .HasColumnType("bigint") + .HasColumnName("FK_TrustType"); + + b.Property("UKPRN") + .HasColumnType("nvarchar(max)") + .HasColumnName("UKPRN"); + + b.Property("UPIN") + .HasColumnType("nvarchar(max)") + .HasColumnName("UPIN"); + + b.Property("WIPSummaryGoesToMinister") + .HasColumnType("nvarchar(max)") + .HasColumnName("WIP Summary Goes To Minister"); + + b.HasKey("SK"); + + b.HasIndex("TrustTypeId"); + + b.ToTable("Trust", "mstr"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Trust.TrustType", b => + { + b.Property("SK") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("SK"), 1L, 1); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("SK"); + + b.ToTable("Ref_TrustType", "mstr"); + + b.HasData( + new + { + SK = 30L, + Code = "06", + Name = "Multi-academy trust" + }, + new + { + SK = 32L, + Code = "10", + Name = "Single-academy trust" + }); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Establishment.Establishment", b => + { + b.HasOne("Dfe.Academies.Domain.Establishment.EstablishmentType", "EstablishmentType") + .WithMany() + .HasForeignKey("EstablishmentTypeId"); + + b.HasOne("Dfe.Academies.Domain.Establishment.IfdPipeline", "IfdPipeline") + .WithMany() + .HasForeignKey("IfdPipelineSK"); + + b.HasOne("Dfe.Academies.Domain.Establishment.LocalAuthority", "LocalAuthority") + .WithMany() + .HasForeignKey("LocalAuthorityId"); + + b.Navigation("EstablishmentType"); + + b.Navigation("IfdPipeline"); + + b.Navigation("LocalAuthority"); + }); + + modelBuilder.Entity("Dfe.Academies.Domain.Trust.Trust", b => + { + b.HasOne("Dfe.Academies.Domain.Trust.TrustType", "TrustType") + .WithMany() + .HasForeignKey("TrustTypeId"); + + b.Navigation("TrustType"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Dfe.Academies.Api.Infrastructure/MstrContext.cs b/Dfe.Academies.Api.Infrastructure/MstrContext.cs index 2a6f07e07..b124374e4 100644 --- a/Dfe.Academies.Api.Infrastructure/MstrContext.cs +++ b/Dfe.Academies.Api.Infrastructure/MstrContext.cs @@ -3,13 +3,18 @@ using Dfe.Academies.Domain.Trust; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Dfe.Academies.Academisation.Data; public class MstrContext : DbContext { const string DEFAULT_SCHEMA = "mstr"; + + public MstrContext() + { + + } + public MstrContext(DbContextOptions options) : base(options) { @@ -24,6 +29,14 @@ public MstrContext(DbContextOptions options) : base(options) public DbSet IfdPipelines { get; set; } = null!; + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + optionsBuilder.UseSqlServer("Server=localhost;Database=sip;Integrated Security=true;TrustServerCertificate=True"); + } + } + protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -41,7 +54,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) private void ConfigureEstablishment(EntityTypeBuilder establishmentConfiguration) { - establishmentConfiguration.HasKey(e => e.SK).HasName("SK"); + establishmentConfiguration.HasKey(e => e.SK); establishmentConfiguration.ToTable("EducationEstablishment", DEFAULT_SCHEMA); @@ -64,11 +77,11 @@ private void ConfigureEstablishment(EntityTypeBuilder establishme establishmentConfiguration.Property(e => e.Email).HasColumnName("Email"); establishmentConfiguration.Property(e => e.EstablishmentName).HasColumnName("EstablishmentName"); establishmentConfiguration.Property(e => e.EstablishmentNumber).HasColumnName("EstablishmentNumber"); - establishmentConfiguration.Property(e => e.FK_EstablishmentGroupType).HasColumnName("FK_EstablishmentGroupType"); - establishmentConfiguration.Property(e => e.FK_EstablishmentStatus).HasColumnName("FK_EstablishmentStatus"); - establishmentConfiguration.Property(e => e.FK_EstablishmentType).HasColumnName("FK_EstablishmentType"); - establishmentConfiguration.Property(e => e.FK_LocalAuthority).HasColumnName("FK_LocalAuthority"); - establishmentConfiguration.Property(e => e.FK_Region).HasColumnName("FK_Region"); + establishmentConfiguration.Property(e => e.EstablishmentGroupTypeId).HasColumnName("FK_EstablishmentGroupType"); + establishmentConfiguration.Property(e => e.EstablishmentStatusId).HasColumnName("FK_EstablishmentStatus"); + establishmentConfiguration.Property(e => e.EstablishmentTypeId).HasColumnName("FK_EstablishmentType"); + establishmentConfiguration.Property(e => e.LocalAuthorityId).HasColumnName("FK_LocalAuthority"); + establishmentConfiguration.Property(e => e.RegionId).HasColumnName("FK_Region"); establishmentConfiguration.Property(e => e.GORregion).HasColumnName("GORregion"); establishmentConfiguration.Property(e => e.HeadFirstName).HasColumnName("HeadFirstName"); establishmentConfiguration.Property(e => e.HeadLastName).HasColumnName("HeadLastName"); @@ -135,21 +148,14 @@ private void ConfigureEstablishment(EntityTypeBuilder establishme establishmentConfiguration .HasOne(x => x.EstablishmentType) - .WithOne() - .HasForeignKey(x => x.FK_EstablishmentType) + .WithMany() + .HasForeignKey(x => x.EstablishmentTypeId) .IsRequired(false); establishmentConfiguration .HasOne(x => x.LocalAuthority) - .WithOne() - .HasForeignKey(x => x.FK_LocalAuthority) - .IsRequired(false); - - establishmentConfiguration - .HasOne(x => x.IfdPipeline) - .WithOne() - .HasForeignKey(x => x.PK_GIAS_URN) - .HasPrincipalKey(x => x.GeneralDetailsUrn) + .WithMany() + .HasForeignKey(x => x.LocalAuthorityId) .IsRequired(false); } @@ -160,14 +166,14 @@ private void ConfigureEstablishment(EntityTypeBuilder establishme void ConfigureTrust(EntityTypeBuilder trustConfiguration) { - trustConfiguration.HasKey(e => e.SK).HasName("SK"); - + trustConfiguration.HasKey(e => e.SK); + trustConfiguration.ToTable("Trust", DEFAULT_SCHEMA); - trustConfiguration.Property(e => e.TrustsTrustType).HasColumnName("FK_TrustType"); - trustConfiguration.Property(e => e.Region).HasColumnName("FK_Region"); - trustConfiguration.Property(e => e.TrustBanding).HasColumnName("FK_TrustBanding"); - trustConfiguration.Property(e => e.FK_TrustStatus).HasColumnName("FK_TrustStatus"); + trustConfiguration.Property(e => e.TrustTypeId).HasColumnName("FK_TrustType"); + trustConfiguration.Property(e => e.RegionId).HasColumnName("FK_Region"); + trustConfiguration.Property(e => e.TrustBandingId).HasColumnName("FK_TrustBanding"); + trustConfiguration.Property(e => e.TrustStatusId).HasColumnName("FK_TrustStatus"); trustConfiguration.Property(e => e.GroupUID).HasColumnName("Group UID").IsRequired(); trustConfiguration.Property(e => e.GroupID).HasColumnName("Group ID"); trustConfiguration.Property(e => e.RID).HasColumnName("RID"); @@ -207,39 +213,51 @@ void ConfigureTrust(EntityTypeBuilder trustConfiguration) trustConfiguration.Property(e => e.IncorporatedOnOpenDate).HasColumnName("Incorporated on (open date)"); trustConfiguration - .HasOne(x => x.TrustType) - .WithOne() - .HasForeignKey(x => x.TrustsTrustType) - .IsRequired(true); + .HasOne(x => x.TrustType) + .WithMany() + .HasForeignKey(x => x.TrustTypeId); } - void ConfigureTrustType(EntityTypeBuilder trustTypeConfiguration) + private void ConfigureTrustType(EntityTypeBuilder trustTypeConfiguration) { - trustTypeConfiguration.HasKey(e => e.SK).HasName("SK"); + trustTypeConfiguration.HasKey(e => e.SK); trustTypeConfiguration.ToTable("Ref_TrustType", DEFAULT_SCHEMA); + + trustTypeConfiguration.HasData(new TrustType() { SK = 30, Code = "06", Name = "Multi-academy trust" }); + trustTypeConfiguration.HasData(new TrustType() { SK = 32, Code = "10", Name = "Single-academy trust" }); } private void ConfigureEducationEstablishmentTrust(EntityTypeBuilder entityBuilder) { entityBuilder.HasKey(e => e.SK); - entityBuilder.ToTable("EducationEstablishmentTrust", DEFAULT_SCHEMA); - + entityBuilder.ToTable("EducationEstablishmentTrust", DEFAULT_SCHEMA); + + entityBuilder.Property(e => e.EducationEstablishmentId).HasColumnName("FK_EducationEstablishment"); + entityBuilder.Property(e => e.TrustId).HasColumnName("FK_Trust"); } - void ConfigureLocalAuthority(EntityTypeBuilder localAuthorityConfiguration) + + private void ConfigureLocalAuthority(EntityTypeBuilder localAuthorityConfiguration) { - localAuthorityConfiguration.HasKey(e => e.SK).HasName("SK"); + localAuthorityConfiguration.HasKey(e => e.SK); localAuthorityConfiguration.ToTable("Ref_LocalAuthority", DEFAULT_SCHEMA); + + localAuthorityConfiguration.HasData(new LocalAuthority() { SK = 1, Code = "202", Name = "Barnsley" }); + localAuthorityConfiguration.HasData(new LocalAuthority() { SK = 2, Code = "203", Name = "Birmingham" }); + localAuthorityConfiguration.HasData(new LocalAuthority() { SK = 3, Code = "204", Name = "Bradford" }); } - void ConfigureEstablishmentType(EntityTypeBuilder establishmentTypeConfiguration) + private void ConfigureEstablishmentType(EntityTypeBuilder establishmentTypeConfiguration) { - establishmentTypeConfiguration.HasKey(e => e.SK).HasName("SK"); + establishmentTypeConfiguration.HasKey(e => e.SK); establishmentTypeConfiguration.ToTable("Ref_EducationEstablishmentType", DEFAULT_SCHEMA); + + establishmentTypeConfiguration.HasData(new EstablishmentType() { SK = 224, Code = "35", Name = "Free schools" }); + establishmentTypeConfiguration.HasData(new EstablishmentType() { SK = 228, Code = "18", Name = "Further education" }); } private void ConfigureIfdPipeline(EntityTypeBuilder ifdPipelineConfiguration) { - ifdPipelineConfiguration.HasKey(e => e.SK).HasName("SK"); + ifdPipelineConfiguration.HasKey(e => e.SK); ifdPipelineConfiguration.ToTable("IfdPipeline", DEFAULT_SCHEMA); diff --git a/Dfe.Academies.Api.Infrastructure/Repositories/EstablishmentRepository.cs b/Dfe.Academies.Api.Infrastructure/Repositories/EstablishmentRepository.cs index 95e54dabd..372adf361 100644 --- a/Dfe.Academies.Api.Infrastructure/Repositories/EstablishmentRepository.cs +++ b/Dfe.Academies.Api.Infrastructure/Repositories/EstablishmentRepository.cs @@ -1,99 +1,140 @@ using Dfe.Academies.Academisation.Data; -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 { - public class EstablishmentRepository : GenericRepository, IEstablishmentRepository + public class EstablishmentRepository : IEstablishmentRepository { - public EstablishmentRepository(MstrContext context) : base(context) + private MstrContext _context; + + public EstablishmentRepository(MstrContext context) { + _context = context; } public async Task GetEstablishmentByUkprn(string ukprn, CancellationToken cancellationToken) { - var Establishment = await DefaultIncludes().SingleOrDefaultAsync(x => x.UKPRN == ukprn).ConfigureAwait(false); + var queryResult = await BaseQuery().SingleOrDefaultAsync(r => r.Establishment.UKPRN == ukprn); + + if (queryResult == null) + { + return null; + } - return Establishment; + var result = ToEstablishment(queryResult); + + return result; } + public async Task GetEstablishmentByUrn(string urn, CancellationToken cancellationToken) { - var establishment = await DefaultIncludes().SingleOrDefaultAsync(x => x.URN.ToString() == urn).ConfigureAwait(false); + var queryResult = await BaseQuery().SingleOrDefaultAsync(r => r.Establishment.URN.ToString() == urn); - return establishment; + if (queryResult == null) + { + return null; + } + + var result = ToEstablishment(queryResult); + + return result; } + public async Task> Search(string name, string ukPrn, string urn, CancellationToken cancellationToken) { - IQueryable query = DefaultIncludes().AsNoTracking(); + IQueryable query = BaseQuery(); + if (!string.IsNullOrEmpty(name)) { - query = query.Where(e => e.EstablishmentName.Contains(name)); + query = query.Where(r => r.Establishment.EstablishmentName.Contains(name)); } if (!string.IsNullOrEmpty(ukPrn)) { - query = query.Where(e => e.UKPRN == ukPrn); + query = query.Where(r => r.Establishment.UKPRN == ukPrn); } if (!string.IsNullOrEmpty(urn)) { if (int.TryParse(urn, out var urnAsNumber)) { - query = query.Where(e => e.URN == urnAsNumber); - } - } - return await query.Take(100).ToListAsync(cancellationToken); + query = query.Where(r => r.Establishment.URN == urnAsNumber); + } + } + var queryResult = await query.Take(100).ToListAsync(cancellationToken); + + var result = queryResult.Select(ToEstablishment).ToList(); + + return result; } + public async Task> GetURNsByRegion(string[] regions, CancellationToken cancellationToken) - { - return await DefaultIncludes() //Adding Explicit cast because the Domain entity has the URN as nullable + { + return await _context.Establishments .AsNoTracking() - .Where(p => regions.Contains(p!.GORregion.ToLower()) && p.URN.HasValue) + .Where(p => regions.Contains(p.GORregion) && p.URN.HasValue) .Select(e => e.URN.Value) - .ToListAsync(cancellationToken) - .ConfigureAwait(false); + .ToListAsync(cancellationToken); } + public async Task> GetByUrns(int[] urns, CancellationToken cancellationToken) { var urnsList = urns.ToList(); - return await DefaultIncludes() - .AsNoTracking() - .Where(e => urnsList.Contains((int)e.URN)) + var queryResult = await BaseQuery() + .Where(r => urnsList.Contains((int)r.Establishment.URN)) .ToListAsync(cancellationToken); + + var result = queryResult.Select(ToEstablishment).ToList(); + + return result; } public async Task> 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().AsNoTracking() - .Where(e => establishmentIds.Contains(e.SK)) - .ToListAsync(cancellationToken) - .ConfigureAwait(false); - - - return establishments; - } + { + var establishmentIds = + await _context.EducationEstablishmentTrusts + .AsNoTracking() + .Where(eet => eet.TrustId == Convert.ToInt32(trustId)) + .Select(eet => (long)eet.EducationEstablishmentId) + .ToListAsync(cancellationToken); + + var establishments = + await BaseQuery() + .Where(r => establishmentIds.Contains(r.Establishment.SK.Value)) + .ToListAsync(cancellationToken); + var result = establishments.Select(ToEstablishment).ToList(); + return result; + } - private IQueryable DefaultIncludes() + private IQueryable BaseQuery() { - var x = dbSet - .Include(x => x.EstablishmentType) - .Include(x => x.LocalAuthority) - .Include(x => x.IfdPipeline) - .AsQueryable(); + var result = + from establishment in _context.Establishments + from ifdPipeline in _context.IfdPipelines.Where(i => i.GeneralDetailsUrn == establishment.PK_GIAS_URN).DefaultIfEmpty() + from establishmentType in _context.EstablishmentTypes.Where(e => e.SK == establishment.EstablishmentTypeId).DefaultIfEmpty() + from localAuthority in _context.LocalAuthorities.Where(l => l.SK == establishment.LocalAuthorityId).DefaultIfEmpty() + select new EstablishmentQueryResult { Establishment = establishment, IfdPipeline = ifdPipeline, LocalAuthority = localAuthority, EstablishmentType = establishmentType }; - return x; + return result; } + private static Establishment ToEstablishment(EstablishmentQueryResult queryResult) + { + var result = queryResult.Establishment; + result.IfdPipeline = queryResult.IfdPipeline; + result.LocalAuthority = queryResult.LocalAuthority; + result.EstablishmentType = queryResult.EstablishmentType; + return result; + } + } + internal record EstablishmentQueryResult + { + public Establishment Establishment { get; set; } + public IfdPipeline IfdPipeline { get; set; } + public LocalAuthority LocalAuthority { get; set; } + public EstablishmentType EstablishmentType { get; set; } } } diff --git a/Dfe.Academies.Api.Infrastructure/Repositories/GenericRepository.cs b/Dfe.Academies.Api.Infrastructure/Repositories/GenericRepository.cs deleted file mode 100644 index cfb73da24..000000000 --- a/Dfe.Academies.Api.Infrastructure/Repositories/GenericRepository.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Dfe.Academies.Academisation.Domain.SeedWork; -using Microsoft.EntityFrameworkCore; - -namespace Dfe.Academies.Academisation.Data.Repositories -{ - public abstract class GenericRepository : IGenericRepository where TEntity : class - { - internal MstrContext context; - internal DbSet dbSet; - - public GenericRepository(MstrContext context) - { - this.context = context; - dbSet = context.Set(); - } - - public void Insert(TEntity obj) - { - dbSet.Add(obj); - } - - public Task> GetAll() - { - throw new NotImplementedException(); - } - - public async Task GetById(int id) - { - return await dbSet.FindAsync(id).ConfigureAwait(false); - } - - public void Delete(int id) - { - TEntity entityToDelete = dbSet.Find(id); - Delete(entityToDelete); - } - - public void Delete(TEntity entityToDelete) - { - if (context.Entry(entityToDelete).State == EntityState.Detached) - { - dbSet.Attach(entityToDelete); - } - dbSet.Remove(entityToDelete); - } - - public void Update(TEntity obj) - { - dbSet.Attach(obj); - context.Entry(obj).State = EntityState.Modified; - } - } -} diff --git a/Dfe.Academies.Api.Infrastructure/Repositories/TrustRepository.cs b/Dfe.Academies.Api.Infrastructure/Repositories/TrustRepository.cs index 0098dbc20..f85e04ff9 100644 --- a/Dfe.Academies.Api.Infrastructure/Repositories/TrustRepository.cs +++ b/Dfe.Academies.Api.Infrastructure/Repositories/TrustRepository.cs @@ -1,15 +1,16 @@ using Dfe.Academies.Academisation.Data; -using Dfe.Academies.Academisation.Data.Repositories; -using Dfe.Academies.Domain.Establishment; using Dfe.Academies.Domain.Trust; using Microsoft.EntityFrameworkCore; namespace Dfe.Academies.Infrastructure.Repositories { - public class TrustRepository : GenericRepository, ITrustRepository + public class TrustRepository : ITrustRepository { - public TrustRepository(MstrContext context) : base(context) + private MstrContext _context; + + public TrustRepository(MstrContext context) { + _context = context; } public async Task GetTrustByUkprn(string ukprn, CancellationToken cancellationToken) @@ -67,7 +68,7 @@ public async Task> GetTrustsByUkprns(string[] ukprns, CancellationTo private IQueryable DefaultIncludes() { - var x = dbSet + var x = _context.Trusts .Include(x => x.TrustType) .AsQueryable(); diff --git a/Dfe.Academies.Application.Tests/Queries/Establishment/EstablishmentQueriesTests.cs b/Dfe.Academies.Application.Tests/Queries/Establishment/EstablishmentQueriesTests.cs index 8e2da3033..86f70163f 100644 --- a/Dfe.Academies.Application.Tests/Queries/Establishment/EstablishmentQueriesTests.cs +++ b/Dfe.Academies.Application.Tests/Queries/Establishment/EstablishmentQueriesTests.cs @@ -1,5 +1,5 @@ using AutoFixture; -using Dfe.Academies.Application.Queries.Establishment; +using Dfe.Academies.Application.Establishment; using Dfe.Academies.Contracts.V4.Establishments; using Dfe.Academies.Domain.Census; using Dfe.Academies.Domain.Establishment; diff --git a/Dfe.Academies.Application.Tests/Queries/Trust/TrustQueriesTests.cs b/Dfe.Academies.Application.Tests/Queries/Trust/TrustQueriesTests.cs index 1a9fea981..7aa546978 100644 --- a/Dfe.Academies.Application.Tests/Queries/Trust/TrustQueriesTests.cs +++ b/Dfe.Academies.Application.Tests/Queries/Trust/TrustQueriesTests.cs @@ -1,12 +1,9 @@ using AutoFixture; -using Dfe.Academies.Application.Queries.Trust; +using Dfe.Academies.Application.Trust; using Dfe.Academies.Contracts.V4.Trusts; using Dfe.Academies.Domain.Trust; using FluentAssertions; using Moq; -using System; -using System.Threading.Tasks; -using Xunit; namespace Dfe.Academies.Application.Tests.Queries.Trust { diff --git a/Dfe.Academies.Application/ApplicationServiceConfigExtensions.cs b/Dfe.Academies.Application/ApplicationServiceConfigExtensions.cs index 6f48aba91..70b026482 100644 --- a/Dfe.Academies.Application/ApplicationServiceConfigExtensions.cs +++ b/Dfe.Academies.Application/ApplicationServiceConfigExtensions.cs @@ -1,6 +1,6 @@ using Dfe.Academies.Academisation.Data; -using Dfe.Academies.Application.Queries.Establishment; -using Dfe.Academies.Application.Queries.Trust; +using Dfe.Academies.Application.Establishment; +using Dfe.Academies.Application.Trust; using Dfe.Academies.Domain.Census; using Dfe.Academies.Domain.Establishment; using Dfe.Academies.Domain.Trust; diff --git a/Dfe.Academies.Application/Dfe.Academies.Application.csproj b/Dfe.Academies.Application/Dfe.Academies.Application.csproj index 8c7ed8db3..13f3ecdd5 100644 --- a/Dfe.Academies.Application/Dfe.Academies.Application.csproj +++ b/Dfe.Academies.Application/Dfe.Academies.Application.csproj @@ -15,6 +15,7 @@ + diff --git a/Dfe.Academies.Application/Builders/EstablishmentDtoBuilder.cs b/Dfe.Academies.Application/Establishment/EstablishmentDtoBuilder.cs similarity index 97% rename from Dfe.Academies.Application/Builders/EstablishmentDtoBuilder.cs rename to Dfe.Academies.Application/Establishment/EstablishmentDtoBuilder.cs index cf83004cb..c850358da 100644 --- a/Dfe.Academies.Application/Builders/EstablishmentDtoBuilder.cs +++ b/Dfe.Academies.Application/Establishment/EstablishmentDtoBuilder.cs @@ -3,8 +3,9 @@ using Dfe.Academies.Domain.Census; using System; using System.Globalization; +using Dfe.Academies.Utils.Extensions; -namespace Dfe.Academies.Application.Builders +namespace Dfe.Academies.Application.Establishment { public class EstablishmentDtoBuilder { @@ -15,7 +16,7 @@ public EstablishmentDtoBuilder WithBasicDetails(Domain.Establishment.Establishme _dto.Ukprn = establishment?.UKPRN; _dto.NoOfBoys = establishment?.NumberOfBoys.ToString(); _dto.NoOfGirls = establishment?.NumberOfGirls.ToString(); - _dto.GiasLastChangedDate = establishment?.GiasLastChangedDate?.ToString("d", new CultureInfo("en-GB")); + _dto.GiasLastChangedDate = establishment?.GiasLastChangedDate.ToResponseDate(); _dto.ReligousEthos = establishment?.ReligiousEthos; _dto.SenUnitCapacity = establishment?.SenUnitCapacity.ToString(); _dto.SenUnitOnRoll = establishment?.SenUnitOnRoll.ToString(); @@ -155,8 +156,8 @@ public EstablishmentDtoBuilder WithMISEstablishment(Domain.Establishment.Establi { _dto.MISEstablishment = new MisEstablishmentDto { - DateOfLatestSection8Inspection = establishment?.DateOfLatestShortInspection?.ToString("d", new CultureInfo("en-GB")), - InspectionEndDate = establishment?.InspectionEndDate?.ToString("d", new CultureInfo("en-GB")), + DateOfLatestSection8Inspection = establishment?.DateOfLatestShortInspection.ToResponseDate(), + InspectionEndDate = establishment?.InspectionEndDate.ToResponseDate(), OverallEffectiveness = establishment?.OverallEffectiveness?.ToString(), QualityOfEducation = establishment?.QualityOfEducation?.ToString(), BehaviourAndAttitudes = establishment?.BehaviourAndAttitudes?.ToString(), diff --git a/Dfe.Academies.Application/Queries/Establishment/EstablishmentQueries.cs b/Dfe.Academies.Application/Establishment/EstablishmentQueries.cs similarity index 68% rename from Dfe.Academies.Application/Queries/Establishment/EstablishmentQueries.cs rename to Dfe.Academies.Application/Establishment/EstablishmentQueries.cs index 4020e2142..3d35b2b34 100644 --- a/Dfe.Academies.Application/Queries/Establishment/EstablishmentQueries.cs +++ b/Dfe.Academies.Application/Establishment/EstablishmentQueries.cs @@ -1,11 +1,9 @@ using Dfe.Academies.Contracts.V4.Establishments; +using Dfe.Academies.Domain.Census; using Dfe.Academies.Domain.Establishment; - -using Dfe.Academies.Application.Builders; using Dfe.Academies.Domain.Trust; -using Dfe.Academies.Domain.Census; -namespace Dfe.Academies.Application.Queries.Establishment +namespace Dfe.Academies.Application.Establishment { public class EstablishmentQueries : IEstablishmentQueries { @@ -19,48 +17,70 @@ public EstablishmentQueries(IEstablishmentRepository establishmentRepository, IT _trustRepository = trustRepository; _censusDataRepository = censusDataRepository; } + public async Task GetByUkprn(string ukprn, CancellationToken cancellationToken) { - var establishment = await _establishmentRepository.GetEstablishmentByUkprn(ukprn, cancellationToken).ConfigureAwait(false); - var censusData = this._censusDataRepository.GetCensusDataByURN(establishment.URN.Value); + var establishment = await _establishmentRepository.GetEstablishmentByUkprn(ukprn, cancellationToken); - return establishment == null ? null : MapToEstablishmentDto(establishment, censusData); + if (establishment == null) + { + return null; + } + + return MapToEstablishmentDto(establishment); } + public async Task GetByUrn(string urn, CancellationToken cancellationToken) { - var establishment = await _establishmentRepository.GetEstablishmentByUrn(urn, cancellationToken).ConfigureAwait(false); - var censusData = this._censusDataRepository.GetCensusDataByURN(establishment.URN.Value); + var establishment = await _establishmentRepository.GetEstablishmentByUrn(urn, cancellationToken); - return establishment == null ? null : MapToEstablishmentDto(establishment, censusData); + if (establishment == null) + { + return null; + } + + return MapToEstablishmentDto(establishment); } + public async Task<(List, int)> Search(string name, string ukPrn, string urn, CancellationToken cancellationToken) { - var establishments = await _establishmentRepository.Search(name, ukPrn, urn, cancellationToken).ConfigureAwait(false); + var establishments = await _establishmentRepository.Search(name, ukPrn, urn, cancellationToken); - return (establishments.Select(x => MapToEstablishmentDto(x, _censusDataRepository.GetCensusDataByURN(x.URN.Value))).ToList(), establishments.Count); + return (establishments.Select(x => MapToEstablishmentDto(x)).ToList(), establishments.Count); } + public async Task> GetURNsByRegion(string[] regions, CancellationToken cancellationToken) { - var URNs = await _establishmentRepository.GetURNsByRegion(regions, cancellationToken).ConfigureAwait(false); + var urns = await _establishmentRepository.GetURNsByRegion(regions, cancellationToken); - return URNs; + return urns; } + public async Task> GetByTrust(string trustUkprn, CancellationToken cancellationToken) { var trust = await _trustRepository.GetTrustByUkprn(trustUkprn, cancellationToken); + + if (trust == null) + { + return new List(); + } + var establishments = await _establishmentRepository.GetByTrust(trust.SK, cancellationToken).ConfigureAwait(false); - return establishments.Select(x => MapToEstablishmentDto(x, _censusDataRepository.GetCensusDataByURN(x.URN.Value))).ToList(); + return establishments.Select(x => MapToEstablishmentDto(x)).ToList(); } + public async Task> GetByUrns(int[] Urns, CancellationToken cancellationToken) { var establishments = await _establishmentRepository.GetByUrns(Urns, cancellationToken).ConfigureAwait(false); - return (establishments.Select(x => MapToEstablishmentDto(x, _censusDataRepository.GetCensusDataByURN(x.URN.Value))).ToList()); + return establishments.Select(x => MapToEstablishmentDto(x)).ToList(); } - private static EstablishmentDto MapToEstablishmentDto(Domain.Establishment.Establishment? establishment, CensusData censusData) + private EstablishmentDto MapToEstablishmentDto(Domain.Establishment.Establishment establishment) { - return new EstablishmentDtoBuilder() + var censusData = _censusDataRepository.GetCensusDataByURN(establishment.URN.Value); + + var result = new EstablishmentDtoBuilder() .WithBasicDetails(establishment) .WithLocalAuthority(establishment) .WithDiocese(establishment) @@ -73,6 +93,8 @@ private static EstablishmentDto MapToEstablishmentDto(Domain.Establishment.Estab .WithMISEstablishment(establishment) .WithAddress(establishment) .Build(); + + return result; } } } diff --git a/Dfe.Academies.Application/Queries/Establishment/IEstablishmentQueries.cs b/Dfe.Academies.Application/Establishment/IEstablishmentQueries.cs similarity index 87% rename from Dfe.Academies.Application/Queries/Establishment/IEstablishmentQueries.cs rename to Dfe.Academies.Application/Establishment/IEstablishmentQueries.cs index 002d47769..d77d54744 100644 --- a/Dfe.Academies.Application/Queries/Establishment/IEstablishmentQueries.cs +++ b/Dfe.Academies.Application/Establishment/IEstablishmentQueries.cs @@ -1,6 +1,6 @@ using Dfe.Academies.Contracts.V4.Establishments; -namespace Dfe.Academies.Application.Queries.Establishment +namespace Dfe.Academies.Application.Establishment { public interface IEstablishmentQueries { @@ -8,7 +8,7 @@ public interface IEstablishmentQueries Task GetByUrn(string urn, CancellationToken cancellationToken); Task<(List, int)> Search(string name, string ukPrn, string urn, CancellationToken cancellationToken); Task> GetURNsByRegion(string[] regions, CancellationToken cancellationToken); - Task> GetByUrns(int[] Urns, CancellationToken cancellationToken); + Task> GetByUrns(int[] Urns, CancellationToken cancellationToken); Task> GetByTrust(string trustUkprn, CancellationToken cancellationToken); } } diff --git a/Dfe.Academies.Application/Queries/Trust/ITrustQueries.cs b/Dfe.Academies.Application/Trust/ITrustQueries.cs similarity index 93% rename from Dfe.Academies.Application/Queries/Trust/ITrustQueries.cs rename to Dfe.Academies.Application/Trust/ITrustQueries.cs index 517d93c58..6323a5776 100644 --- a/Dfe.Academies.Application/Queries/Trust/ITrustQueries.cs +++ b/Dfe.Academies.Application/Trust/ITrustQueries.cs @@ -1,6 +1,6 @@ using Dfe.Academies.Contracts.V4.Trusts; -namespace Dfe.Academies.Application.Queries.Trust +namespace Dfe.Academies.Application.Trust { public interface ITrustQueries { diff --git a/Dfe.Academies.Application/Queries/Trust/TrustQueries.cs b/Dfe.Academies.Application/Trust/TrustQueries.cs similarity index 96% rename from Dfe.Academies.Application/Queries/Trust/TrustQueries.cs rename to Dfe.Academies.Application/Trust/TrustQueries.cs index 29eefd58a..fafb0af48 100644 --- a/Dfe.Academies.Application/Queries/Trust/TrustQueries.cs +++ b/Dfe.Academies.Application/Trust/TrustQueries.cs @@ -2,7 +2,7 @@ using Dfe.Academies.Contracts.V4.Trusts; using Dfe.Academies.Domain.Trust; -namespace Dfe.Academies.Application.Queries.Trust +namespace Dfe.Academies.Application.Trust { public class TrustQueries : ITrustQueries { @@ -50,7 +50,7 @@ private static TrustDto MapToTrustDto(Domain.Trust.Trust trust) CompaniesHouseNumber = trust.CompaniesHouseNumber, ReferenceNumber = trust.GroupID, Ukprn = trust.UKPRN, - Type = new Contracts.V4.Establishments.NameAndCodeDto() { Code = trust.TrustType.Code, Name = trust.TrustType.Name }, + Type = new Contracts.V4.Establishments.NameAndCodeDto() { Code = trust.TrustType?.Code, Name = trust.TrustType?.Name }, Address = new AddressDto() { Street = trust.AddressLine1, diff --git a/Dfe.Academies.Domain/Establishment/EducationEstablishmentTrust.cs b/Dfe.Academies.Domain/Establishment/EducationEstablishmentTrust.cs index 4df672b92..f540d18f8 100644 --- a/Dfe.Academies.Domain/Establishment/EducationEstablishmentTrust.cs +++ b/Dfe.Academies.Domain/Establishment/EducationEstablishmentTrust.cs @@ -1,22 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Dfe.Academies.Domain.Establishment +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; } - public virtual Establishment Establishment { get; set; } + public int TrustId { get; set; } + public int EducationEstablishmentId { get; set; } } } diff --git a/Dfe.Academies.Domain/Establishment/Establishment.cs b/Dfe.Academies.Domain/Establishment/Establishment.cs index 9c997f916..19898d7b8 100644 --- a/Dfe.Academies.Domain/Establishment/Establishment.cs +++ b/Dfe.Academies.Domain/Establishment/Establishment.cs @@ -8,15 +8,15 @@ namespace Dfe.Academies.Domain.Establishment { public class Establishment { - public long SK { get; set; } + public long? SK { get; set; } public string? PK_GIAS_URN { get; set; } public long? PK_CDM_ID { get; set; } public int? URN { get; set; } - public long? FK_LocalAuthority { get; set; } - public long? FK_EstablishmentType { get; set; } - public long? FK_EstablishmentGroupType { get; set; } - public long? FK_EstablishmentStatus { get; set; } - public long? FK_Region { get; set; } + public long? LocalAuthorityId { get; set; } + public long? EstablishmentTypeId { get; set; } + public long? EstablishmentGroupTypeId { get; set; } + public long? EstablishmentStatusId { get; set; } + public long? RegionId { get; set; } public int? EstablishmentNumber { get; set; } public string? EstablishmentName { get; set; } public double? Latitude { get; set; } @@ -99,9 +99,9 @@ public class Establishment public int? SenUnitCapacity { get; set; } public int? SenUnitOnRoll { get; set; } - public LocalAuthority LocalAuthority { get; set; } - public EstablishmentType EstablishmentType{ get; set; } + public LocalAuthority? LocalAuthority { get; set; } + public EstablishmentType? EstablishmentType{ get; set; } - public IfdPipeline IfdPipeline { get; set; } + public IfdPipeline? IfdPipeline { get; set; } } } diff --git a/Dfe.Academies.Domain/Establishment/IEstablishmentRepository.cs b/Dfe.Academies.Domain/Establishment/IEstablishmentRepository.cs index 8c48ed4e6..72def39cf 100644 --- a/Dfe.Academies.Domain/Establishment/IEstablishmentRepository.cs +++ b/Dfe.Academies.Domain/Establishment/IEstablishmentRepository.cs @@ -1,8 +1,6 @@ -using Dfe.Academies.Academisation.Domain.SeedWork; - -namespace Dfe.Academies.Domain.Establishment +namespace Dfe.Academies.Domain.Establishment { - public interface IEstablishmentRepository : IGenericRepository + public interface IEstablishmentRepository { Task GetEstablishmentByUkprn(string ukprn, CancellationToken cancellationToken); Task GetEstablishmentByUrn(string urn, CancellationToken cancellationToken); diff --git a/Dfe.Academies.Domain/Establishment/IfdPipeline.cs b/Dfe.Academies.Domain/Establishment/IfdPipeline.cs index 7d1e36b0b..f712b67fe 100644 --- a/Dfe.Academies.Domain/Establishment/IfdPipeline.cs +++ b/Dfe.Academies.Domain/Establishment/IfdPipeline.cs @@ -5,7 +5,7 @@ namespace Dfe.Academies.Domain.Establishment { public class IfdPipeline { - public long SK { get; set; } + public long? SK { get; set; } public string? GeneralDetailsUrn { get; set; } public string? DeliveryProcessPFI { get; set; } diff --git a/Dfe.Academies.Domain/SeedWork/IGenericRepository.cs b/Dfe.Academies.Domain/SeedWork/IGenericRepository.cs deleted file mode 100644 index 36744a772..000000000 --- a/Dfe.Academies.Domain/SeedWork/IGenericRepository.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Dfe.Academies.Academisation.Domain.SeedWork -{ - public interface IGenericRepository where TEntity : class - { - void Insert(TEntity obj); - Task GetById(int id); - Task> GetAll(); - void Update(TEntity obj); - void Delete(int id); - void Delete(TEntity entityToDelete); - - } -} diff --git a/Dfe.Academies.Domain/Trust/ITrustRepository.cs b/Dfe.Academies.Domain/Trust/ITrustRepository.cs index 22206a5f6..62f2ac612 100644 --- a/Dfe.Academies.Domain/Trust/ITrustRepository.cs +++ b/Dfe.Academies.Domain/Trust/ITrustRepository.cs @@ -1,8 +1,6 @@ -using Dfe.Academies.Academisation.Domain.SeedWork; - -namespace Dfe.Academies.Domain.Trust +namespace Dfe.Academies.Domain.Trust { - public interface ITrustRepository : IGenericRepository + public interface ITrustRepository { Task GetTrustByUkprn(string ukprn, CancellationToken cancellationToken); Task GetTrustByCompaniesHouseNumber(string companiesHouseNumber, CancellationToken cancellationToken); diff --git a/Dfe.Academies.Domain/Trust/Trust.cs b/Dfe.Academies.Domain/Trust/Trust.cs index b87af4a83..d86c4ec11 100644 --- a/Dfe.Academies.Domain/Trust/Trust.cs +++ b/Dfe.Academies.Domain/Trust/Trust.cs @@ -5,10 +5,10 @@ namespace Dfe.Academies.Domain.Trust public class Trust { public long? SK { get; set; } - public long? TrustsTrustType { get; set; } - public long? Region { get; set; } - public long? TrustBanding { get; set; } - public long? FK_TrustStatus { get; set; } + public long? TrustTypeId { get; set; } + public long? RegionId { get; set; } + public long? TrustBandingId { get; set; } + public long? TrustStatusId { get; set; } public string? GroupUID { get; set; } public string? GroupID { get; set; } public string? RID { get; set; } @@ -47,6 +47,6 @@ public class Trust public string? UPIN { get; set; } public DateTime? IncorporatedOnOpenDate { get; set; } - public TrustType TrustType { get; set; } + public TrustType? TrustType { get; set; } } } diff --git a/Dfe.Academies.Utils/Dfe.Academies.Utils.csproj b/Dfe.Academies.Utils/Dfe.Academies.Utils.csproj new file mode 100644 index 000000000..27ac3865b --- /dev/null +++ b/Dfe.Academies.Utils/Dfe.Academies.Utils.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/Dfe.Academies.Utils/Extensions/DateExtensions.cs b/Dfe.Academies.Utils/Extensions/DateExtensions.cs new file mode 100644 index 000000000..b48f67ee7 --- /dev/null +++ b/Dfe.Academies.Utils/Extensions/DateExtensions.cs @@ -0,0 +1,15 @@ +using System.Globalization; + +namespace Dfe.Academies.Utils.Extensions +{ + public static class DateExtensions + { + public static string? ToResponseDate(this DateTime? date) + { + if (date == null) + return null; + + return date.Value.ToString("d", new CultureInfo("en-GB")); + } + } +} diff --git a/README.md b/README.md index 4348180bc..5b56e7d35 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,22 @@ For this reason it is not recommended anymore and instead you should setup a Nug You can connect to the MSSQL Server on port `1433`. +## API testing + +One of the problems we have is that this project doesn't control the migrations of the SIP database, that means it is really easy for the docker image to go out of date + +In the latest v4 endpoints, the decision was made to have a migration that enables us to rebuild the database for just the tables the API uses + +V2 and V3 tests will run against the docker image (legacy) + +V4 uses the migrations specified in `trams-data-api\Dfe.Academies.Api.Infrastructure/Migrations` + +Now we can easily rebuild the environment on each test run and also build an environment for testing, if we need to + +The trade off is that it might not be exactly accurate with the SIP database that is on DEV, but we can test that with some smoke tests when we deploy to dev + +Likely we might encounter some small differences very occasionally, but the benefit of being able to control a database environment, is too beneficial to worry about this + ### EntityFramework and Migrations We currently have two database contexts defined: `LegacyTramsDbContext` and `TramsDbContext`. Both database contexts manage the same database, but are used to manage different sets of tables. diff --git a/TramsDataApi.Test/DbFixture.cs b/TramsDataApi.Test/DbFixture.cs index 1b223e60f..86066364d 100644 --- a/TramsDataApi.Test/DbFixture.cs +++ b/TramsDataApi.Test/DbFixture.cs @@ -15,8 +15,8 @@ public class DbFixture : IDisposable private readonly IDbContextTransaction _legacyTransaction; private readonly IDbContextTransaction _tramsTransaction; public readonly string ConnString; - - + + public DbFixture() { var projectDir = Directory.GetCurrentDirectory(); @@ -38,10 +38,10 @@ public DbFixture() tramsContextBuilder.UseSqlServer(ConnString); _tramsDbContext = new TramsDbContext(tramsContextBuilder.Options); - + _tramsDbContext.Database.EnsureCreated(); _tramsDbContext.Database.Migrate(); - + _legacyTransaction = _legacyTramsDbContext.Database.BeginTransaction(); _tramsTransaction = _tramsDbContext.Database.BeginTransaction(); } @@ -55,7 +55,7 @@ public void Dispose() GC.SuppressFinalize(this); } } - + [CollectionDefinition("Database", DisableParallelization = true)] public class DatabaseCollection : ICollectionFixture { @@ -63,4 +63,4 @@ public class DatabaseCollection : ICollectionFixture // to be the place to apply [CollectionDefinition] and all the // ICollectionFixture<> interfaces. } -} +} \ No newline at end of file diff --git a/TramsDataApi.Test/Fixtures/ApiTestFixture.cs b/TramsDataApi.Test/Fixtures/ApiTestFixture.cs new file mode 100644 index 000000000..a5cfe350e --- /dev/null +++ b/TramsDataApi.Test/Fixtures/ApiTestFixture.cs @@ -0,0 +1,112 @@ +using Dfe.Academies.Academisation.Data; +using Dfe.Academies.Domain.Establishment; +using Dfe.Academies.Domain.Trust; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Net.Mime; +using Xunit; + +namespace TramsDataApi.Test.Fixtures +{ + public class ApiTestFixture : IDisposable + { + private readonly WebApplicationFactory _application; + + public HttpClient Client { get; init; } + + private DbContextOptions _dbContextOptions { get; init; } + + private static readonly object _lock = new(); + private static bool _isInitialised = false; + + private const string ConnectionStringKey = "ConnectionStrings:DefaultConnection"; + + public ApiTestFixture() + { + lock (_lock) + { + if (!_isInitialised) + { + string connectionString = null; + + _application = new WebApplicationFactory() + .WithWebHostBuilder(builder => + { + var configPath = Path.Combine(Directory.GetCurrentDirectory(), "integration_settings.json"); + + builder.ConfigureAppConfiguration((context, config) => + { + config.AddJsonFile(configPath) + .AddEnvironmentVariables(); + + connectionString = BuildDatabaseConnectionString(config); + + config.AddInMemoryCollection(new Dictionary + { + [ConnectionStringKey] = connectionString + }); + }); + }); + + Client = CreateHttpClient(); + + _dbContextOptions = new DbContextOptionsBuilder() + .UseSqlServer(connectionString) + .Options; + + using var context = GetMstrContext(); + context.Database.EnsureDeleted(); + context.Database.Migrate(); + _isInitialised = true; + } + } + } + + public void Dispose() + { + _application.Dispose(); + Client.Dispose(); + } + + public MstrContext GetMstrContext() => new MstrContext(_dbContextOptions); + + private HttpClient CreateHttpClient() + { + var client = _application.CreateClient(); + client.DefaultRequestHeaders.Add("ApiKey", "testing-api-key"); + client.DefaultRequestHeaders.Add("ContentType", MediaTypeNames.Application.Json); + + client.BaseAddress = new Uri("https://trams-api.com"); + + return client; + } + + private static string BuildDatabaseConnectionString(IConfigurationBuilder config) + { + var currentConfig = config.Build(); + var connection = currentConfig[ConnectionStringKey]; + var sqlBuilder = new SqlConnectionStringBuilder(connection); + sqlBuilder.InitialCatalog = "ApiTests"; + + var result = sqlBuilder.ToString(); + + return result; + } + } + + [CollectionDefinition(ApiTestCollectionName, DisableParallelization = true)] + public class ApiTestCollection : ICollectionFixture + { + public const string ApiTestCollectionName = "ApiTestCollection"; + + // This class has no code, and is never created. Its purpose is simply + // to be the place to apply [CollectionDefinition] and all the + // ICollectionFixture<> interfaces. + } +} diff --git a/TramsDataApi.Test/Helpers/DatabaseModelBuilder.cs b/TramsDataApi.Test/Helpers/DatabaseModelBuilder.cs new file mode 100644 index 000000000..cd8864790 --- /dev/null +++ b/TramsDataApi.Test/Helpers/DatabaseModelBuilder.cs @@ -0,0 +1,52 @@ +using AutoFixture; +using Dfe.Academies.Domain.Establishment; +using Dfe.Academies.Domain.Trust; + +namespace TramsDataApi.Test.Helpers +{ + public static class DatabaseModelBuilder + { + private static readonly Fixture _fixture = new Fixture(); + + public static Trust BuildTrust() + { + var result = _fixture.Create(); + result.SK = null; + result.TrustStatus = "Open"; + result.TrustTypeId = 30; + result.TrustType = null; + result.TrustStatusId = null; + result.RegionId = null; + result.TrustBandingId = null; + result.CurrentSingleListGrouping = result.CurrentSingleListGrouping.Substring(0, 19); + result.FollowUpLetterSent = result.CurrentSingleListGrouping.Substring(0, 19); + result.PrioritisedForReview = result.PrioritisedForReview.Substring(0, 19); + result.RID = result.RID.Substring(0, 10); + + return result; + } + + public static Establishment BuildEstablishment() + { + var result = _fixture.Create(); + result.SK = null; + result.IfdPipeline = null; + result.LocalAuthority = null; + result.EstablishmentType = null; + result.PK_GIAS_URN = _fixture.Create().ToString(); + result.EstablishmentTypeId = 228; + result.LocalAuthorityId = 1; + + return result; + } + + public static IfdPipeline BuildIfdPipeline() + { + var result = _fixture.Create(); + result.SK = null; + result.GeneralDetailsUrn = _fixture.Create().ToString(); + + return result; + } + } +} diff --git a/TramsDataApi.Test/Helpers/MstrContextExtensions.cs b/TramsDataApi.Test/Helpers/MstrContextExtensions.cs new file mode 100644 index 000000000..e32c003d8 --- /dev/null +++ b/TramsDataApi.Test/Helpers/MstrContextExtensions.cs @@ -0,0 +1,24 @@ +using Dfe.Academies.Academisation.Data; +using Dfe.Academies.Domain.Trust; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TramsDataApi.Test.Helpers +{ + public static class MstrContextExtensions + { + public static long GetNextTrustId(this MstrContext context) + { + var trustMaxId = context.Trusts.Max(t => t.SK); + + if (trustMaxId == null) + return 1; + + return (long)trustMaxId + 1; + } + } +} diff --git a/TramsDataApi.Test/Integration/TrustsV3IntegrationTests.cs b/TramsDataApi.Test/Integration/V3/TrustsV3IntegrationTests.cs similarity index 99% rename from TramsDataApi.Test/Integration/TrustsV3IntegrationTests.cs rename to TramsDataApi.Test/Integration/V3/TrustsV3IntegrationTests.cs index 3cdd570bd..56602d076 100644 --- a/TramsDataApi.Test/Integration/TrustsV3IntegrationTests.cs +++ b/TramsDataApi.Test/Integration/V3/TrustsV3IntegrationTests.cs @@ -13,7 +13,7 @@ using TramsDataApi.ResponseModels; using Xunit; -namespace TramsDataApi.Test.Integration +namespace TramsDataApi.Test.Integration.V3 { [Collection("Database")] public class TrustsV3IntegrationTests : IClassFixture @@ -199,7 +199,7 @@ public async Task ShouldReturnEstablishmentDataAgainstOpenTrust_WhenTrustHasAnEs var closedTrustGroup = _fixture.Build() .With(f => f.GroupUid, "1") .With(f => f.GroupId, groupID) - .With(f=> f.GroupName, TrustName) + .With(f => f.GroupName, TrustName) .With(f => f.Ukprn, TrustUKPRN) .With(f => f.GroupStatus, "Closed") .With(f => f.GroupStatusCode, "CLOSED") @@ -455,7 +455,7 @@ public async Task ShouldReturnNoResults_WhenSearchingTrusts_ByTrustThatDoesNotEx private static TrustMasterData BuildMasterTrustData(Group groupData) { var result = _fixture.Create(); - result.RID = result.RID.Substring(0,10); + result.RID = result.RID.Substring(0, 10); result.CurrentSingleListGrouping = "Auto"; result.FollowUpLetterSent = "yes"; result.PrioritisedForReview = "no"; diff --git a/TramsDataApi.Test/Integration/V4/EstablishmentV4IntegrationTests.cs b/TramsDataApi.Test/Integration/V4/EstablishmentV4IntegrationTests.cs new file mode 100644 index 000000000..ac773d3d8 --- /dev/null +++ b/TramsDataApi.Test/Integration/V4/EstablishmentV4IntegrationTests.cs @@ -0,0 +1,486 @@ +using AutoFixture; +using Dfe.Academies.Academisation.Data; +using Dfe.Academies.Contracts.V4.Establishments; +using Dfe.Academies.Domain.Establishment; +using Dfe.Academies.Domain.Trust; +using Dfe.Academies.Utils.Extensions; +using FluentAssertions; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Json; +using System.Threading.Tasks; +using TramsDataApi.Test.Fixtures; +using TramsDataApi.Test.Helpers; +using Xunit; + +namespace TramsDataApi.Test.Integration.V4 +{ + [Collection(ApiTestCollection.ApiTestCollectionName)] + public class EstablishmentV4IntegrationTests + { + private readonly HttpClient _client; + private static readonly Fixture _autoFixture = new Fixture(); + private readonly ApiTestFixture _apiFixture; + + private readonly string _apiUrlPrefix = "/v4"; + + public EstablishmentV4IntegrationTests(ApiTestFixture fixture) + { + _apiFixture = fixture; + _client = fixture.Client; + } + + [Fact] + public async Task Get_EstablishmentByUkPrn_NoEstablishmentExists_Returns_NotFound() + { + var ukPrn = _autoFixture.Create(); + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishment/{ukPrn}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.NotFound); + } + + [Fact] + public async Task Get_EstablishmentByUkPrn_EstablishmentExists_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trust = CreateDataSet(context); + var establishmentDataSet = trust.Establishments.First(); + var establishment = establishmentDataSet.Establishment; + var ifdPipeline = establishmentDataSet.IfdPipeline; + + // Matches a URN in the census + establishment.URN = 100028; + + context.Update(establishment); + context.SaveChanges(); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishment/{establishment.UKPRN}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var actual = await getEstablishmentResponse.Content.ReadFromJsonAsync(); + + AssertEstablishmentResponse(actual, establishment, ifdPipeline); + + // Check data from the census + AssertCensus(actual); + actual.Census.PercentageFsmLastSixYears.Should().Be("5.70%"); + actual.Census.PercentageEnglishAsSecondLanguage.Should().Be("52.60%"); + actual.Census.PercentageSen.Should().Be("6.30%"); + } + + [Fact] + public async Task Get_EstablishmentByUkPrn_EstablishmentHasMinimumFields_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + var establishment = new Establishment() + { + UKPRN = _autoFixture.Create(), + URN = _autoFixture.Create(), + }; + + context.Establishments.Add(establishment); + context.SaveChanges(); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishment/{establishment.UKPRN}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var actual = await getEstablishmentResponse.Content.ReadFromJsonAsync(); + actual.Ukprn.Should().Be(establishment.UKPRN); + actual.Urn.Should().Be(establishment.URN.ToString()); + } + + [Fact] + public async Task Get_EstablishmentByUrn_EstablishmentDoesNotExist_Returns_NotFound() + { + var urn = _autoFixture.Create(); + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishment/urn/{urn}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.NotFound); + } + + [Fact] + public async Task Get_EstablishmentByUrn_EstablishmentExists_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trust = CreateDataSet(context); + var establishmentDataSet = trust.Establishments.First(); + var establishment = establishmentDataSet.Establishment; + var ifdPipeline = establishmentDataSet.IfdPipeline; + + // Matches a URN in the census + establishment.URN = 100270; + + context.Update(establishment); + context.SaveChanges(); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishment/urn/{establishment.URN}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync(); + + AssertEstablishmentResponse(establishmentContent, establishment, ifdPipeline); + AssertCensus(establishmentContent); + } + + [Fact] + public async Task Get_EstablishmentListByTrust_TrustDoesNotExist_Returns_Empty() + { + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments/trust?trustUkPrn=NotExist"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Should().BeEmpty(); + } + + [Fact] + public async Task Get_EstablishmentListByTrust_TrustHasNoEstablishments_Returns_Empty() + { + using var context = _apiFixture.GetMstrContext(); + + var trust = DatabaseModelBuilder.BuildTrust(); + + context.Trusts.Add(trust); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments/trust?trustUkPrn={trust.UKPRN}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Should().BeEmpty(); + } + + [Fact] + public async Task Get_EstablishmentListByTrust_TrustExists_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustOne = CreateDataSet(context); + + // Matches URNs in the census + trustOne.Establishments.ElementAt(0).Establishment.URN = 100601; + trustOne.Establishments.ElementAt(1).Establishment.URN = 100602; + trustOne.Establishments.ElementAt(2).Establishment.URN = 100604; + + context.Establishments.UpdateRange(trustOne.Establishments.Select(x => x.Establishment)); + context.SaveChanges(); + + var trustTwo = CreateDataSet(context); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments/trust?trustUkPrn={trustOne.Trust.UKPRN}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Count.Should().Be(3); + + trustOne.Establishments.ForEach(establishmentDataSet => + { + var matchingEstablishment = establishmentContent.FirstOrDefault(x => x.Urn == establishmentDataSet.Establishment.URN.ToString()); + + AssertEstablishmentResponse(matchingEstablishment, establishmentDataSet.Establishment, establishmentDataSet.IfdPipeline); + AssertCensus(matchingEstablishment); + }); + } + + [Fact] + public async Task Get_Search_NoEstablishmentsExist_Returns_Empty() + { + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments?name=NotExist"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Should().BeEmpty(); + } + + [Fact] + public async Task Get_SearchEstablishmentsByName_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustOne = CreateDataSet(context); + var firstEstablishmentData = trustOne.Establishments.ElementAt(0); + var secondEstablishmentData = trustOne.Establishments.ElementAt(1); + firstEstablishmentData.Establishment.EstablishmentName = "West BANK queens School"; + secondEstablishmentData.Establishment.EstablishmentName = "West bank primary"; + context.Establishments.UpdateRange(trustOne.Establishments.Select(x => x.Establishment)); + context.SaveChanges(); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments?name=west bank"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Count.Should().Be(2); + + var expectedEstablishments = new List { firstEstablishmentData, secondEstablishmentData }; + + expectedEstablishments.ForEach(establishmentDataSet => + { + var matchingEstablishment = establishmentContent.FirstOrDefault(x => x.Urn == establishmentDataSet.Establishment.URN.ToString()); + + AssertEstablishmentResponse(matchingEstablishment, establishmentDataSet.Establishment, establishmentDataSet.IfdPipeline); + }); + } + + [Fact] + public async Task Get_SearchEstablishmentByUkPrn_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustOne = CreateDataSet(context); + var firstEstablishmentData = trustOne.Establishments.ElementAt(0); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments?ukPrn={firstEstablishmentData.Establishment.UKPRN}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Count.Should().Be(1); + + establishmentContent.First().Ukprn.Should().Be(firstEstablishmentData.Establishment.UKPRN.ToString()); + } + + [Fact] + public async Task Get_SearchEstablishmentByUrn_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustOne = CreateDataSet(context); + var firstEstablishmentData = trustOne.Establishments.ElementAt(0); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments?urn={firstEstablishmentData.Establishment.URN}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Count.Should().Be(1); + + establishmentContent.First().Urn.Should().Be(firstEstablishmentData.Establishment.URN.ToString()); + } + + [Fact] + public async Task Get_BulkEstablishment_NoEstablishmentsExist_Returns_Empty() + { + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments/bulk?request=123"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Should().BeEmpty(); + } + + [Fact] + public async Task Get_BulkEstablishment_EstablishmentsExist_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustOne = CreateDataSet(context); + + var establishmentOne = trustOne.Establishments.ElementAt(0); + var establishmentTwo = trustOne.Establishments.ElementAt(1); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishments/bulk?request={establishmentOne.Establishment.URN}&request={establishmentTwo.Establishment.URN}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Count.Should().Be(2); + + var expectedEstablishments = new List { establishmentOne, establishmentTwo }; + + expectedEstablishments.ForEach(establishmentDataSet => + { + var matchingEstablishment = establishmentContent.FirstOrDefault(x => x.Urn == establishmentDataSet.Establishment.URN.ToString()); + + AssertEstablishmentResponse(matchingEstablishment, establishmentDataSet.Establishment, establishmentDataSet.IfdPipeline); + }); + } + + [Fact] + public async Task Get_EstablishmentUrnsByRegion_NoEstablishmentsExist_Returns_NotFound() + { + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishment/regions?regions=123"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var establishmentContent = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + establishmentContent.Should().BeEmpty(); + } + + [Fact] + public async Task Get_EstablishmentUrnsByRegion_EstablishmentsExist_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustOne = CreateDataSet(context); + + var establishmentOne = trustOne.Establishments.ElementAt(0); + var establishmentTwo = trustOne.Establishments.ElementAt(1); + + var getEstablishmentResponse = await _client.GetAsync($"{_apiUrlPrefix}/establishment/regions?regions={establishmentOne.Establishment.GORregion}®ions={establishmentTwo.Establishment.GORregion}"); + getEstablishmentResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var actual = await getEstablishmentResponse.Content.ReadFromJsonAsync>(); + + actual.Count.Should().Be(2); + + var expectedEstablishmentUrns = new List() { establishmentOne.Establishment.URN.Value, establishmentTwo.Establishment.URN.Value }; + + actual.Should().BeEquivalentTo(expectedEstablishmentUrns); + } + + private static TrustDataSet CreateDataSet(MstrContext context) + { + var trust = DatabaseModelBuilder.BuildTrust(); + context.Add(trust); + context.SaveChanges(); + + var establishments = new List(); + + for (var idx = 0; idx < 3; idx++) + { + var establishment = DatabaseModelBuilder.BuildEstablishment(); + var ifdPipeline = DatabaseModelBuilder.BuildIfdPipeline(); + ifdPipeline.GeneralDetailsUrn = establishment.PK_GIAS_URN; + + var establishmentDataSet = new EstablishmentDataSet() + { + Establishment = establishment, + IfdPipeline = ifdPipeline + }; + + context.Establishments.Add(establishment); + context.IfdPipelines.Add(ifdPipeline); + + establishments.Add(establishmentDataSet); + } + + context.SaveChanges(); + + var trustToEstablishmentLinks = LinkTrustToEstablishments(trust, establishments.Select(d => d.Establishment).ToList()); + + context.EducationEstablishmentTrusts.AddRange(trustToEstablishmentLinks); + + context.SaveChanges(); + + var result = new TrustDataSet() + { + Trust = trust, + Establishments = establishments + }; + + return result; + } + + private static List LinkTrustToEstablishments(Trust trust, List establishments) + { + var result = new List(); + + establishments.ForEach(establishment => + { + var educationEstablishmentTrust = new EducationEstablishmentTrust() + { + TrustId = (int)trust.SK, + EducationEstablishmentId = (int)establishment.SK + }; + + result.Add(educationEstablishmentTrust); + }); + + return result; + } + + private static void AssertEstablishmentResponse(EstablishmentDto actual, Establishment expected, IfdPipeline ifdPipeline) + { + actual.Ukprn.Should().Be(expected.UKPRN); + actual.Urn.Should().Be(expected.URN.ToString()); + actual.Name.Should().Be(expected.EstablishmentName); + actual.OfstedRating.Should().Be(expected.OfstedRating); + actual.OfstedLastInspection.Should().Be(expected.OfstedLastInspection); + actual.StatutoryLowAge.Should().Be(expected.StatutoryLowAge); + actual.StatutoryHighAge.Should().Be(expected.StatutoryHighAge); + actual.SchoolCapacity.Should().Be(expected.SchoolCapacity); + actual.EstablishmentNumber.Should().Be(expected.EstablishmentNumber.ToString()); + actual.GiasLastChangedDate.Should().Be(expected.GiasLastChangedDate.ToResponseDate()); + actual.NoOfBoys.Should().Be(expected.NumberOfBoys.ToString()); + actual.NoOfGirls.Should().Be(expected.NumberOfGirls.ToString()); + actual.SenUnitCapacity.Should().Be(expected.SenUnitCapacity.ToString()); + actual.SenUnitOnRoll.Should().Be(expected.SenUnitOnRoll.ToString()); + actual.ReligousEthos.Should().Be(expected.ReligiousEthos); + actual.HeadteacherTitle.Should().Be(expected.HeadTitle); + actual.HeadteacherFirstName.Should().Be(expected.HeadFirstName); + actual.HeadteacherLastName.Should().Be(expected.HeadLastName); + actual.HeadteacherPreferredJobTitle.Should().Be(expected.HeadPreferredJobTitle); + + actual.LocalAuthorityCode.Should().Be("202"); + actual.LocalAuthorityName.Should().Be("Barnsley"); + + actual.Diocese.Code.Should().Be(expected.DioceseCode); + actual.Diocese.Name.Should().Be(expected.Diocese); + + actual.EstablishmentType.Code.Should().Be("18"); + actual.EstablishmentType.Name.Should().Be("Further education"); + + actual.Gor.Code.Should().Be(expected.GORregionCode); + actual.Gor.Name.Should().Be(expected.GORregion); + + actual.PhaseOfEducation.Code.Should().Be(expected.PhaseOfEducationCode.ToString()); + actual.PhaseOfEducation.Name.Should().Be(expected.PhaseOfEducation); + + actual.ReligiousCharacter.Code.Should().Be(expected.ReligiousCharacterCode); + actual.ReligiousCharacter.Name.Should().Be(expected.ReligiousCharacter); + + actual.ParliamentaryConstituency.Code.Should().Be(expected.ParliamentaryConstituencyCode); + actual.ParliamentaryConstituency.Name.Should().Be(expected.ParliamentaryConstituency); + + actual.Address.Street.Should().Be(expected.AddressLine1); + actual.Address.Additional.Should().Be(expected.AddressLine2); + actual.Address.Locality.Should().Be(expected.AddressLine3); + actual.Address.Town.Should().Be(expected.Town); + actual.Address.County.Should().Be(expected.County); + actual.Address.Postcode.Should().Be(expected.Postcode); + + actual.MISEstablishment.DateOfLatestSection8Inspection.Should().Be(expected.DateOfLatestShortInspection.ToResponseDate()); + actual.MISEstablishment.InspectionEndDate.Should().Be(expected.InspectionEndDate.ToResponseDate()); + actual.MISEstablishment.OverallEffectiveness.Should().Be(expected.OverallEffectiveness.ToString()); + actual.MISEstablishment.QualityOfEducation.Should().Be(expected.QualityOfEducation.ToString()); + actual.MISEstablishment.BehaviourAndAttitudes.Should().Be(expected.BehaviourAndAttitudes.ToString()); + actual.MISEstablishment.PersonalDevelopment.Should().Be(expected.PersonalDevelopment.ToString()); + actual.MISEstablishment.EffectivenessOfLeadershipAndManagement.Should().Be(expected.EffectivenessOfLeadershipAndManagement.ToString()); + actual.MISEstablishment.EarlyYearsProvision.Should().Be(expected.EarlyYearsProvisionWhereApplicable.ToString()); + actual.MISEstablishment.SixthFormProvision.Should().Be(expected.SixthFormProvisionWhereApplicable.ToString()); + actual.MISEstablishment.Weblink.Should().Be(expected.Website); + + actual.Pan.Should().Be(ifdPipeline.DeliveryProcessPAN); + actual.Pfi.Should().Be(ifdPipeline.DeliveryProcessPFI); + actual.Deficit.Should().Be(ifdPipeline.ProjectTemplateInformationDeficit); + actual.ViabilityIssue.Should().Be(ifdPipeline.ProjectTemplateInformationViabilityIssue); + + actual.Census.NumberOfPupils.Should().Be(expected.NumberOfPupils); + actual.Census.PercentageFsm.Should().Be(expected.PercentageFSM); + } + + private static void AssertCensus(EstablishmentDto actual) + { + actual.Census.PercentageFsmLastSixYears.Length.Should().BeGreaterThan(2); + actual.Census.PercentageEnglishAsSecondLanguage.Length.Should().BeGreaterThan(2); + actual.Census.PercentageSen.Length.Should().BeGreaterThan(2); + } + } + + internal record TrustDataSet + { + public Trust Trust { get; set; } + public List Establishments { get; set; } + } + + internal record EstablishmentDataSet + { + public Establishment Establishment { get; set; } + public IfdPipeline IfdPipeline { get; set; } + } +} diff --git a/TramsDataApi.Test/Integration/V4/TrustV4IntegrationTests.cs b/TramsDataApi.Test/Integration/V4/TrustV4IntegrationTests.cs new file mode 100644 index 000000000..24ea2f022 --- /dev/null +++ b/TramsDataApi.Test/Integration/V4/TrustV4IntegrationTests.cs @@ -0,0 +1,442 @@ +using AutoFixture; +using Dfe.Academies.Academisation.Data; +using Dfe.Academies.Contracts.V4; +using Dfe.Academies.Contracts.V4.Trusts; +using Dfe.Academies.Domain.Trust; +using FluentAssertions; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Json; +using System.Threading.Tasks; +using TramsDataApi.Test.Fixtures; +using TramsDataApi.Test.Helpers; +using Xunit; + +namespace TramsDataApi.Test.Integration.V4 +{ + [Collection(ApiTestCollection.ApiTestCollectionName)] + public class TrustsV4IntegrationTests + { + private readonly HttpClient _client; + private static readonly Fixture _autoFixture = new Fixture(); + private readonly ApiTestFixture _apiFixture; + + private readonly string _apiUrlPrefix = "/v4"; + + public TrustsV4IntegrationTests(ApiTestFixture fixture) + { + _apiFixture = fixture; + _client = fixture.Client; + } + + [Fact] + public async Task Get_TrustByUkPrn_AndTrustDoesNotExist_Returns_NotFound() + { + var response = await _client.GetAsync($"{_apiUrlPrefix}/trust/mockukprn"); + + response.StatusCode.Should().Be(HttpStatusCode.NotFound); + } + + [Fact] + public async Task Get_TrustByUkPrn_AndTrustExists_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustData = BuildSmallTrustSet(); + + context.Trusts.AddRange(trustData); + context.SaveChanges(); + + var selectedTrust = trustData.First(); + + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trust/{selectedTrust.UKPRN}"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var trustContent = await trustResponse.Content.ReadFromJsonAsync(); + + AssertTrustResponse(trustContent, selectedTrust); + } + + [Fact] + public async Task Get_TrustByCompaniesHouse_AndTrustDoesNotExist_Returns_NotFound() + { + var response = await _client.GetAsync($"{_apiUrlPrefix}/trust/companiesHouseNumber/mockukprn"); + + response.StatusCode.Should().Be(HttpStatusCode.NotFound); + } + + [Fact] + public async Task Get_TrustByCompaniesHouse_AndTrustExists_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustData = BuildSmallTrustSet(); + + context.Trusts.AddRange(trustData); + context.SaveChanges(); + + var selectedTrust = trustData.First(); + + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trust/companiesHouseNumber/{selectedTrust.CompaniesHouseNumber}"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var trustContent = await trustResponse.Content.ReadFromJsonAsync(); + + AssertTrustResponse(trustContent, selectedTrust); + } + + [Fact] + public async Task Get_TrustByTrustReferenceNumber_AndTrustDoesNotExist_Returns_NotFound() + { + var response = await _client.GetAsync($"{_apiUrlPrefix}/trust/trustReferenceNumber/mockukprn"); + + response.StatusCode.Should().Be(HttpStatusCode.NotFound); + } + + [Fact] + public async Task Get_TrustByTrustReferenceNumber_AndTrustExists_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustData = BuildSmallTrustSet(); + + context.Trusts.AddRange(trustData); + context.SaveChanges(); + + var selectedTrust = trustData.First(); + + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trust/trustReferenceNumber/{selectedTrust.GroupID}"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var trustContent = await trustResponse.Content.ReadFromJsonAsync(); + + AssertTrustResponse(trustContent, selectedTrust); + } + + [Fact] + public async Task Get_TrustBulk_AndTrustDoesNotExist_Returns_Empty_Ok() + { + var response = await _client.GetAsync($"{_apiUrlPrefix}/trusts/bulk?ukprns=mockukprn"); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var trusts = await response.Content.ReadFromJsonAsync>(); + + trusts.Should().HaveCount(0); + } + + [Fact] + public async Task Get_TrustBulk_AndTrustsExist_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var trustData = BuildSmallTrustSet(); + + context.Trusts.AddRange(trustData); + context.SaveChanges(); + + var firstTrust = trustData.First(); + var secondTrust = trustData.Last(); + + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trusts/bulk?ukprns={firstTrust.UKPRN}&ukprns={secondTrust.UKPRN}"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var trustContent = await trustResponse.Content.ReadFromJsonAsync>(); + + trustContent.Should().HaveCount(2); + + var actualFirstTrust = trustContent.First(t => t.Ukprn == firstTrust.UKPRN); + AssertTrustResponse(actualFirstTrust, firstTrust); + + var actualSecondTrust = trustContent.First(t => t.Ukprn == secondTrust.UKPRN); + AssertTrustResponse(actualSecondTrust, secondTrust); + } + + // This will be covered when support for searching closed trusts is added + ///// + ///// Test covers data scenario where we have two records in the group table with nearly identical information. Assumption made that primary key of Open Trusts is higher than closed record. + ///// + ///// + //[Fact] + //public async Task ShouldReturnEstablishmentDataAgainstOpenTrust_WhenTrustHasAnEstablishmentAndHasBeenOpenedAndClosedWithSameUKPRN() + //{ + // //Arrange + // string groupID = "TR02545"; + // string TrustName = "Trust A"; + // string TrustUKPRN = "123456789"; + + // var closedTrustGroup = _fixture.Build() + // .With(f => f.GroupUid, "1") + // .With(f => f.GroupId, groupID) + // .With(f => f.GroupName, TrustName) + // .With(f => f.Ukprn, TrustUKPRN) + // .With(f => f.GroupStatus, "Closed") + // .With(f => f.GroupStatusCode, "CLOSED") + // .With(f => f.GroupType, "Single-academy trust") + // .Without(p => p.CompaniesHouseNumber) + // .Create(); + + // var openTrustGroup = _fixture.Build() + // .With(f => f.GroupUid, "2") + // .With(f => f.GroupId, groupID) + // .With(f => f.GroupName, TrustName) + // .With(f => f.Ukprn, TrustUKPRN) + // .With(f => f.GroupStatus, "Open") + // .With(f => f.GroupStatusCode, "OPEN") + // .With(f => f.GroupType, "Multi-academy trust") + // .Create(); + + // _legacyDbContext.Group.AddRange(closedTrustGroup, openTrustGroup); + + + // var trustMasterData = BuildMasterTrustData(openTrustGroup); + // _legacyDbContext.TrustMasterData.Add(trustMasterData); + + // var establishmentData = _fixture.Create(); + // establishmentData.TrustsCode = openTrustGroup.GroupUid; + // _legacyDbContext.Establishment.Add(establishmentData); + + // _legacyDbContext.SaveChanges(); + + // //Act + // var httpRequestMessage = new HttpRequestMessage + // { + // Method = HttpMethod.Get, + // RequestUri = new Uri($"{_apiUrlPrefix}/trust/{trustMasterData.UKPRN}"), + // }; + + // var response = await _client.SendAsync(httpRequestMessage); + // var jsonString = await response.Content.ReadAsStringAsync(); + // var result = JsonConvert.DeserializeObject>(jsonString); + + // //Assert + // response.StatusCode.Should().Be(HttpStatusCode.OK); + // result.Data.TrustData.NumberInTrust.Should().Be(trustMasterData.NumberInTrust.ToString()); + // result.Data.GiasData.Ukprn.Should().Be(openTrustGroup.Ukprn); + + // result.Data.Establishments.Should().HaveCount(1); + // var establishment = result.Data.Establishments[0]; + // establishment.Ukprn.Should().Be(establishmentData.Ukprn); + //} + + [Fact] + public async Task Get_SearchByCriteria_Pagination_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var groupName = _autoFixture.Create(); + var trustsWithName = BuildLargeTrustSet(); + trustsWithName.ToList().ForEach(t => + { + t.Name = groupName; + context.Trusts.Add(t); + context.SaveChanges(); + }); + + var allTrustsSorted = trustsWithName.OrderBy(trust => trust.GroupUID).ToList(); + + var distinctIds = trustsWithName.Select(t => t.SK).Distinct().ToList(); + + var totalTrusts = context.Trusts.Count(); + var trustIds = context.Trusts.Select(t => t.SK).ToList(); + var missing = trustIds.Where(t => !distinctIds.Contains(t)).ToList(); + + // Page one + var pageOneTrustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trusts?groupName={groupName}&page=1&count=5"); + pageOneTrustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var pageOneTrustContent = await pageOneTrustResponse.Content.ReadFromJsonAsync>(); + + pageOneTrustContent.Data.Should().HaveCount(5); + pageOneTrustContent.Paging.RecordCount.Should().Be(20); + pageOneTrustContent.Paging.Page.Should().Be(1); + + var pageOneExpectedTrusts = allTrustsSorted.Skip(0).Take(5).Select(t => t.UKPRN).ToList(); + var pageOneActualTrusts = pageOneTrustContent.Data.Select(t => t.Ukprn).ToList(); + pageOneActualTrusts.Should().BeEquivalentTo(pageOneExpectedTrusts); + + // Page 3 + var pageThreeTrustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trusts?groupName={groupName}&page=3&count=5"); + pageThreeTrustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var pageThreeTrustContent = await pageThreeTrustResponse.Content.ReadFromJsonAsync>(); + + pageThreeTrustContent.Data.Should().HaveCount(5); + pageThreeTrustContent.Paging.RecordCount.Should().Be(20); + pageThreeTrustContent.Paging.Page.Should().Be(3); + + var pageThreeExpectedTrusts = allTrustsSorted.Skip(10).Take(5).Select(t => t.UKPRN).ToList(); + var pageThreeActualTrusts = pageThreeTrustContent.Data.Select(t => t.Ukprn).ToList(); + pageThreeActualTrusts.Should().BeEquivalentTo(pageThreeExpectedTrusts); + } + + [Theory] + [MemberData(nameof(GetSearchTrustTestSet))] + public async Task Get_SearchByCriteria_ByUniqueGroupName_Returns_Ok(string trustName, string searchString) + { + using var context = _apiFixture.GetMstrContext(); + + var trustData = BuildSmallTrustSet(); + var selectedTrust = trustData.First(); + selectedTrust.Name = trustName; + + context.Trusts.AddRange(trustData); + context.SaveChanges(); + + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trusts?groupName={searchString}"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var trustContent = await trustResponse.Content.ReadFromJsonAsync>(); + + trustContent.Data.Should().HaveCount(1); + + var trustResult = trustContent.Data.First(d => d.Ukprn == selectedTrust.UKPRN); + + AssertTrustResponse(trustResult, selectedTrust); + } + + [Theory] + [MemberData(nameof(GetSearchTrustTestSet))] + public async Task Get_SearchByCriteria_ByCompaniesHouse_Returns_Ok(string companiesHouse, string searchString) + { + using var context = _apiFixture.GetMstrContext(); + + var trustData = BuildSmallTrustSet(); + var selectedTrust = trustData.First(); + selectedTrust.CompaniesHouseNumber = companiesHouse; + + context.Trusts.AddRange(trustData); + context.SaveChanges(); + + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trusts?companiesHouseNumber={searchString}"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var trustContent = await trustResponse.Content.ReadFromJsonAsync>(); + + trustContent.Data.Should().HaveCount(1); + + var actualTrust = trustContent.Data.First(); + + actualTrust.CompaniesHouseNumber.Should().Be(selectedTrust.CompaniesHouseNumber); + } + + [Theory] + [MemberData(nameof(GetSearchTrustTestSet))] + public async Task Get_SearchByCriteria_ByUkPrn_Returns_Ok(string ukPrn, string searchString) + { + using var context = _apiFixture.GetMstrContext(); + + var trustData = BuildSmallTrustSet(); + var selectedTrust = trustData.First(); + selectedTrust.UKPRN = ukPrn; + + context.Trusts.AddRange(trustData); + context.SaveChanges(); + + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trusts?ukprn={searchString}"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var trustContent = await trustResponse.Content.ReadFromJsonAsync>(); + + trustContent.Data.Should().HaveCount(1); + + var actualTrust = trustContent.Data.First(); + + actualTrust.Ukprn.Should().Be(selectedTrust.UKPRN); + } + + [Fact] + public async Task Get_SearchByCriteria_NoTrustExists_Returns_Empty_Ok() + { + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trusts?ukprn=NotExist"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var trustContent = await trustResponse.Content.ReadFromJsonAsync>(); + + trustContent.Data.Should().HaveCount(0); + } + + [Fact] + public async Task Get_WithMinimumCriteria_Returns_Ok() + { + using var context = _apiFixture.GetMstrContext(); + + var selectedTrust = new Trust(); + + selectedTrust.UKPRN = _autoFixture.Create(); + selectedTrust.GroupUID = _autoFixture.Create(); + selectedTrust.Name = _autoFixture.Create(); + context.Trusts.Add(selectedTrust); + context.SaveChanges(); + + var trustResponse = await _client.GetAsync($"{_apiUrlPrefix}/trust/{selectedTrust.UKPRN}"); + trustResponse.StatusCode.Should().Be(HttpStatusCode.OK); + + var actual = await trustResponse.Content.ReadFromJsonAsync(); + + actual.Name.Should().Be(selectedTrust.Name); + actual.CompaniesHouseNumber.Should().BeNull(); + actual.ReferenceNumber.Should().BeNull(); + actual.Ukprn.Should().Be(selectedTrust.UKPRN); + actual.Type.Code.Should().BeNull(); + actual.Type.Name.Should().BeNull(); + actual.Address.Street.Should().BeNull(); + actual.Address.Town.Should().BeNull(); + actual.Address.Postcode.Should().BeNull(); + actual.Address.County.Should().BeNull(); + actual.Address.Additional.Should().BeNull(); + } + + private static List BuildSmallTrustSet() + { + var result = new List(); + + for (var idx = 0; idx < 3; idx++) + { + var trust = DatabaseModelBuilder.BuildTrust(); + result.Add(trust); + } + + return result; + } + + private static List BuildLargeTrustSet() + { + var result = new List(); + + for (var idx = 0; idx < 20; idx++) + { + var trust = DatabaseModelBuilder.BuildTrust(); + result.Add(trust); + } + + return result; + } + + private static void AssertTrustResponse(TrustDto actual, Trust expected) + { + actual.Name.Should().Be(expected.Name); + actual.CompaniesHouseNumber.Should().Be(expected.CompaniesHouseNumber); + actual.ReferenceNumber.Should().Be(expected.GroupID); + actual.Ukprn.Should().Be(expected.UKPRN); + actual.Type.Code.Should().Be("06"); + actual.Type.Name.Should().Be("Multi-academy trust"); + actual.Address.Street.Should().Be(expected.AddressLine1); + actual.Address.Town.Should().Be(expected.Town); + actual.Address.Postcode.Should().Be(expected.Postcode); + actual.Address.County.Should().Be(expected.County); + actual.Address.Additional.Should().Be(expected.AddressLine2); + } + + public static IEnumerable GetSearchTrustTestSet() + { + var firstValue = _autoFixture.Create(); + var secondValue = _autoFixture.Create(); + + yield return new object[] { firstValue, firstValue }; + yield return new object[] { secondValue, secondValue.Substring(0, 4) }; + } + } +} diff --git a/TramsDataApi.Test/TramsDataApi.Test.csproj b/TramsDataApi.Test/TramsDataApi.Test.csproj index cfd7e737b..2455c5286 100644 --- a/TramsDataApi.Test/TramsDataApi.Test.csproj +++ b/TramsDataApi.Test/TramsDataApi.Test.csproj @@ -37,6 +37,7 @@ + diff --git a/TramsDataApi.Test/TramsDataApiFactory.cs b/TramsDataApi.Test/TramsDataApiFactory.cs index 0f876cb3e..cc72c20a1 100644 --- a/TramsDataApi.Test/TramsDataApiFactory.cs +++ b/TramsDataApi.Test/TramsDataApiFactory.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Dfe.Academies.Academisation.Data; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.Configuration; diff --git a/TramsDataApi.sln b/TramsDataApi.sln index c4525a0e5..71c709995 100644 --- a/TramsDataApi.sln +++ b/TramsDataApi.sln @@ -20,7 +20,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dfe.Academies.Application", EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B3CDCA56-9765-4C2B-A4A4-2738C5A268EB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dfe.Academies.Application.Tests", "Dfe.Academies.Application.Tests\Dfe.Academies.Application.Tests.csproj", "{AF49D395-A01A-43E9-A643-6B2266BA62C5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dfe.Academies.Application.Tests", "Dfe.Academies.Application.Tests\Dfe.Academies.Application.Tests.csproj", "{AF49D395-A01A-43E9-A643-6B2266BA62C5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dfe.Academies.Utils", "Dfe.Academies.Utils\Dfe.Academies.Utils.csproj", "{F91012BF-C96E-499E-8C0F-B4D5235C6C3A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -52,6 +54,10 @@ Global {AF49D395-A01A-43E9-A643-6B2266BA62C5}.Debug|Any CPU.Build.0 = Debug|Any CPU {AF49D395-A01A-43E9-A643-6B2266BA62C5}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF49D395-A01A-43E9-A643-6B2266BA62C5}.Release|Any CPU.Build.0 = Release|Any CPU + {F91012BF-C96E-499E-8C0F-B4D5235C6C3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F91012BF-C96E-499E-8C0F-B4D5235C6C3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F91012BF-C96E-499E-8C0F-B4D5235C6C3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F91012BF-C96E-499E-8C0F-B4D5235C6C3A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TramsDataApi/Controllers/V4/EstablishmentsController.cs b/TramsDataApi/Controllers/V4/EstablishmentsController.cs index 0d2612042..5d4597860 100644 --- a/TramsDataApi/Controllers/V4/EstablishmentsController.cs +++ b/TramsDataApi/Controllers/V4/EstablishmentsController.cs @@ -2,7 +2,7 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Dfe.Academies.Application.Queries.Establishment; +using Dfe.Academies.Application.Establishment; using Dfe.Academies.Contracts.V4.Establishments; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; diff --git a/TramsDataApi/Controllers/V4/TrustsController.cs b/TramsDataApi/Controllers/V4/TrustsController.cs index f32d52d5c..794c69b51 100644 --- a/TramsDataApi/Controllers/V4/TrustsController.cs +++ b/TramsDataApi/Controllers/V4/TrustsController.cs @@ -2,7 +2,7 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Dfe.Academies.Application.Queries.Trust; +using Dfe.Academies.Application.Trust; using Dfe.Academies.Contracts.V4; using Dfe.Academies.Contracts.V4.Trusts; using Microsoft.AspNetCore.Mvc; diff --git a/TramsDataApi/Program.cs b/TramsDataApi/Program.cs index b3d6fb915..5e898a1b6 100644 --- a/TramsDataApi/Program.cs +++ b/TramsDataApi/Program.cs @@ -9,7 +9,6 @@ var builder = WebApplication.CreateBuilder(args); - var startup = new Startup(builder.Configuration); startup.ConfigureServices(builder.Services); @@ -19,11 +18,12 @@ var enricher = services.GetRequiredService(); loggerConfiguration - .WriteTo.ApplicationInsights(services.GetRequiredService(), TelemetryConverter.Traces) - .Enrich.FromLogContext() - .Enrich.With(enricher) - .WriteTo.Console(); - }); + .ReadFrom.Configuration(context.Configuration) + .WriteTo.ApplicationInsights(services.GetRequiredService(), TelemetryConverter.Traces) + .Enrich.FromLogContext() + .Enrich.With(enricher) + .WriteTo.Console(); +}); builder.Services.AddApplicationDependencyGroup(builder.Configuration); diff --git a/TramsDataApi/TramsDataApi.csproj b/TramsDataApi/TramsDataApi.csproj index c29e8d156..2eb570863 100644 --- a/TramsDataApi/TramsDataApi.csproj +++ b/TramsDataApi/TramsDataApi.csproj @@ -4,6 +4,12 @@ 1ce62ee2-ff0b-4f40-9066-cfbdae2e889f true + + + + + + @@ -30,7 +36,6 @@ - diff --git a/dev-docker-compose.yml b/dev-docker-compose.yml new file mode 100644 index 000000000..1ff3d0985 --- /dev/null +++ b/dev-docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.8" +services: + db: + image: ghcr.io/dfe-digital/trams-development-database:latest + env_file: .env.database + restart: always + ports: + - 1433:1433 + test-db: + image: ghcr.io/dfe-digital/trams-development-database:latest + env_file: .env.database + restart: always + ports: + - 1434:1433 \ No newline at end of file