diff --git a/Dfe.Academies.Academisation.Data/AcademisationContext.cs b/Dfe.Academies.Academisation.Data/AcademisationContext.cs index ebc9e2832..4d6fe53ac 100644 --- a/Dfe.Academies.Academisation.Data/AcademisationContext.cs +++ b/Dfe.Academies.Academisation.Data/AcademisationContext.cs @@ -26,7 +26,7 @@ namespace Dfe.Academies.Academisation.Data; public class AcademisationContext(DbContextOptions options, IMediator mediator) : DbContext(options), IUnitOfWork { - const string DEFAULT_SCHEMA = "academisation"; + public const string DEFAULT_SCHEMA = "academisation"; const string Assigned_User_Id = "AssignedUserId"; const string Assigned_User_Email_Address = "AssignedUserEmailAddress"; const string Assigned_User_Full_Name = "AssignedUserFullName"; @@ -248,6 +248,14 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(ConfigureCompleteTransmissionLog); + if (this.Database.ProviderName != "Microsoft.EntityFrameworkCore.Sqlite") + { + // Trust refernce number sequence + modelBuilder.HasSequence("TrustReferenceNumberSeq", schema: DEFAULT_SCHEMA) + .StartsAt(1) + .IncrementsBy(1); + } + base.OnModelCreating(modelBuilder); } diff --git a/Dfe.Academies.Academisation.Data/Migrations/20241023142123_add-complete-sent-date-to-project.Designer.cs b/Dfe.Academies.Academisation.Data/Migrations/20241023142123_add-complete-sent-date-to-project.Designer.cs new file mode 100644 index 000000000..cf0f0a076 --- /dev/null +++ b/Dfe.Academies.Academisation.Data/Migrations/20241023142123_add-complete-sent-date-to-project.Designer.cs @@ -0,0 +1,2357 @@ +// +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.Academisation.Data.Migrations +{ + [DbContext(typeof(AcademisationContext))] + [Migration("20241023142123_add-complete-sent-date-to-project")] + partial class addcompletesentdatetoproject + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationReference") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("nvarchar(max)") + .HasComputedColumnSql("'A2B_' + CAST([Id] AS NVARCHAR(255))", true); + + b.Property("ApplicationStatus") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ApplicationSubmittedDate") + .HasColumnType("datetime2"); + + b.Property("ApplicationType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("FormTrustId") + .HasColumnType("int"); + + b.Property("JoinTrustId") + .HasColumnType("int"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("FormTrustId") + .IsUnique() + .HasFilter("[FormTrustId] IS NOT NULL"); + + b.HasIndex("JoinTrustId") + .IsUnique() + .HasFilter("[JoinTrustId] IS NOT NULL"); + + b.ToTable("ConversionApplication", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Contributor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConversionApplicationId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ConversionApplicationId"); + + b.ToTable("ConversionApplicationContributor", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Lease", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationSchoolId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsSchoolLeaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("InterestRate") + .HasColumnType("decimal(18,2)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LeaseTerm") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentsToDate") + .HasColumnType("decimal(18,2)"); + + b.Property("Purpose") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RepaymentAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("ResponsibleForAssets") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ValueOfAssets") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationSchoolId"); + + b.ToTable("ApplicationSchoolLease", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Loan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationSchoolId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsSchoolLoanId") + .HasColumnType("uniqueidentifier"); + + b.Property("InterestRate") + .HasColumnType("decimal(18,2)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Purpose") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Schedule") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationSchoolId"); + + b.ToTable("ApplicationSchoolLoan", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConversionApplicationId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DioceseFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("DioceseName") + .HasColumnType("nvarchar(max)"); + + b.Property("DynamicsApplyingSchoolId") + .HasColumnType("uniqueidentifier"); + + b.Property("ExemptionEndDate") + .HasColumnType("datetimeoffset"); + + b.Property("FoundationConsentFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("FoundationTrustOrBodyName") + .HasColumnType("nvarchar(max)"); + + b.Property("FurtherInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("HasLeases") + .HasColumnType("bit"); + + b.Property("HasLoans") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LocalAuthorityClosurePlanDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("LocalAuthorityReorganisationDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("MainFeederSchools") + .HasColumnType("nvarchar(max)"); + + b.Property("OfstedInspectionDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("PartOfFederation") + .HasColumnType("bit"); + + b.Property("ProtectedCharacteristics") + .HasColumnType("int"); + + b.Property("ResolutionConsentFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("Safeguarding") + .HasColumnType("bit"); + + b.Property("TrustBenefitDetails") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ConversionApplicationId"); + + b.ToTable("ApplicationSchool", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("ApplicationFormTrust", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.JoinTrust", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChangesToLaGovernance") + .HasColumnType("bit"); + + b.Property("ChangesToLaGovernanceExplained") + .HasColumnType("nvarchar(max)"); + + b.Property("ChangesToTrust") + .HasColumnType("int"); + + b.Property("ChangesToTrustExplained") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("TrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UKPRN") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ApplicationJoinTrust", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationFormTrustId") + .HasColumnType("int"); + + b.Property("Biography") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DateOfBirth") + .HasColumnType("datetime2"); + + b.Property("DynamicsKeyPersonId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationFormTrustId"); + + b.ToTable("ApplicationFormTrustKeyPerson", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPersonRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationFormTrustKeyPersonRoleId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Role") + .HasColumnType("int"); + + b.Property("TimeInRole") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationFormTrustKeyPersonRoleId"); + + b.ToTable("ApplicationFormTrustKeyPersonRole", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.CompleteTransmissionLog.CompleteTransmissionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompleteProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConversionProjectId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("IsSuccess") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Response") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransferProjectId") + .HasColumnType("int"); + + b.Property("TransferringAcademyId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CompleteTransmissionLog", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("ConversionAdvisoryBoardDecision", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDAORevokedReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("AdvisoryBoardDecisionDAORevokedReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeclinedReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("ConversionAdvisoryBoardDecisionDeclinedReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeferredReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("ConversionAdvisoryBoardDecisionDeferredReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardWithdrawnReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("AdvisoryBoardDecisionWithdrawnReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Author") + .HasColumnType("nvarchar(max)"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("Note") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectNotes", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.FormAMatProjectAggregate.FormAMatProject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ProposedTrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReferenceNumber") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FormAMatProject", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.OpeningDateHistoryAggregate.OpeningDateHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChangedAt") + .HasColumnType("datetime2"); + + b.Property("ChangedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("EntityId") + .HasColumnType("int"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("NewDate") + .HasColumnType("datetime2"); + + b.Property("OldDate") + .HasColumnType("datetime2"); + + b.Property("ReasonsChanged") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("OpeningDateHistories", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationSharePointId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOn") + .HasColumnType("datetime2") + .HasColumnName("CreatedOn"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("FormAMatProjectId") + .HasColumnType("int") + .HasColumnName("FormAMatProjectId"); + + b.Property("IsReadOnly") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ProjectGroupId") + .HasColumnType("int"); + + b.Property("ProjectSentToCompleteDate") + .HasColumnType("datetime2"); + + b.Property("SchoolSharePointId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Project", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.SchoolImprovementPlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArrangedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ArrangedByOther") + .HasColumnType("nvarchar(max)"); + + b.Property("ConfidenceLevel") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("ExpectedEndDate") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ExpectedEndDateOther") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("PlanComments") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ProvidedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("SchoolImprovementPlans", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate.ProjectGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ReferenceNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("TrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ProjectGroups", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.IntendedTransferBenefit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("SelectedBenefit") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransferProjectId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TransferProjectId"); + + b.ToTable("IntendedTransferBenefit", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 10003000L); + + b.Property("AnyRisks") + .HasColumnType("bit"); + + b.Property("AssignedUserEmailAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("AssignedUserFullName") + .HasColumnType("nvarchar(max)"); + + b.Property("AssignedUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Author") + .HasColumnType("nvarchar(max)"); + + b.Property("BenefitsSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("ComplexLandAndBuildingFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("ComplexLandAndBuildingShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DiocesanConsent") + .HasColumnType("nvarchar(max)"); + + b.Property("EqualitiesImpactAssessmentConsidered") + .HasColumnType("bit"); + + b.Property("FeatureSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("FinanceAndDebtFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("FinanceAndDebtShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("HasHtbDate") + .HasColumnType("bit"); + + b.Property("HasTargetDateForTransfer") + .HasColumnType("bit"); + + b.Property("HasTransferFirstDiscussedDate") + .HasColumnType("bit"); + + b.Property("HighProfileFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("HighProfileShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("HtbDate") + .HasColumnType("datetime2"); + + b.Property("IncomingTrustAgreement") + .HasColumnType("nvarchar(max)"); + + b.Property("IsFormAMat") + .HasColumnType("bit"); + + b.Property("IsReadOnly") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LegalRequirementsSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("OtherBenefitValue") + .HasColumnType("nvarchar(max)"); + + b.Property("OtherRisksFurtherSpecification") + .HasMaxLength(20000) + .HasColumnType("nvarchar(max)"); + + b.Property("OtherRisksShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("OtherTransferTypeDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustConsent") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustName") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PreviousAdvisoryBoardDate") + .HasColumnType("datetime2"); + + b.Property("ProjectGroupId") + .HasColumnType("int"); + + b.Property("ProjectRationale") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectReference") + .HasColumnType("nvarchar(max)"); + + b.Property("RationaleSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("RddOrEsfaIntervention") + .HasColumnType("bit"); + + b.Property("RddOrEsfaInterventionDetail") + .HasColumnType("nvarchar(max)"); + + b.Property("Recommendation") + .HasColumnType("nvarchar(max)"); + + b.Property("SpecificReasonsForTransfer") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasColumnType("nvarchar(max)"); + + b.Property("TargetDateForTransfer") + .HasColumnType("datetime2"); + + b.Property("TransferDatesSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("TransferFirstDiscussed") + .HasColumnType("datetime2"); + + b.Property("TrustSponsorRationale") + .HasColumnType("nvarchar(max)"); + + b.Property("TypeOfTransfer") + .HasColumnType("nvarchar(max)"); + + b.Property("Urn") + .HasColumnType("int"); + + b.Property("WhoInitiatedTheTransfer") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("TransferProject", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferringAcademy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DistanceFromAcademyToTrustHq") + .HasColumnType("nvarchar(max)"); + + b.Property("DistanceFromAcademyToTrustHqDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("FinancialDeficit") + .HasColumnType("nvarchar(max)"); + + b.Property("IncomingTrustName") + .HasColumnType("nvarchar(max)"); + + b.Property("IncomingTrustUkprn") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage2PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage4PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage5PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("LatestOfstedReportAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("LocalAuthority") + .HasColumnType("nvarchar(max)"); + + b.Property("MPNameAndParty") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingAcademyUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PFIScheme") + .HasColumnType("nvarchar(max)"); + + b.Property("PFISchemeDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectSentToComplete") + .HasColumnType("bit"); + + b.Property("PublishedAdmissionNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PupilNumbersAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("Region") + .HasColumnType("nvarchar(max)"); + + b.Property("TransferProjectId") + .HasColumnType("int"); + + b.Property("ViabilityIssues") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TransferProjectId"); + + b.ToTable("TransferringAcademy", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", "FormTrust") + .WithOne() + .HasForeignKey("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", "FormTrustId"); + + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.JoinTrust", "JoinTrust") + .WithOne() + .HasForeignKey("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", "JoinTrustId"); + + b.Navigation("FormTrust"); + + b.Navigation("JoinTrust"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Contributor", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", null) + .WithMany("Contributors") + .HasForeignKey("ConversionApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.ContributorDetails", "Details", b1 => + { + b1.Property("ContributorId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("EmailAddress"); + + b1.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("FirstName"); + + b1.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("LastName"); + + b1.Property("OtherRoleName") + .HasColumnType("nvarchar(max)") + .HasColumnName("OtherRoleName"); + + b1.Property("Role") + .HasColumnType("int") + .HasColumnName("Role"); + + b1.HasKey("ContributorId"); + + b1.ToTable("ConversionApplicationContributor", "academisation"); + + b1.WithOwner() + .HasForeignKey("ContributorId"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Lease", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", null) + .WithMany("Leases") + .HasForeignKey("ApplicationSchoolId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Loan", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", null) + .WithMany("Loans") + .HasForeignKey("ApplicationSchoolId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", null) + .WithMany("Schools") + .HasForeignKey("ConversionApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.SchoolDetails", "Details", b1 => + { + b1.Property("SchoolId") + .HasColumnType("int"); + + b1.Property("ApplicationJoinTrustReason") + .HasColumnType("nvarchar(max)") + .HasColumnName("JoinTrustReason"); + + b1.Property("ApproverContactEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApproverContactEmail"); + + b1.Property("ApproverContactName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApproverContactName"); + + b1.Property("CapacityAssumptions") + .HasColumnType("nvarchar(max)") + .HasColumnName("CapacityAssumptions"); + + b1.Property("CapacityPublishedAdmissionsNumber") + .HasColumnType("int") + .HasColumnName("CapacityPublishedAdmissionsNumber"); + + b1.Property("ConfirmPaySupportGrantToSchool") + .HasColumnType("bit") + .HasColumnName("ConfirmPaySupportGrantToSchool"); + + b1.Property("ContactChairEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactChairEmail"); + + b1.Property("ContactChairName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactChairName"); + + b1.Property("ContactHeadEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactHeadEmail"); + + b1.Property("ContactHeadName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactHeadName"); + + b1.Property("ContactRole") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactRole"); + + b1.Property("ConversionChangeNamePlanned") + .HasColumnType("bit") + .HasColumnName("ConversionChangeNamePlanned"); + + b1.Property("ConversionTargetDate") + .HasColumnType("datetime2") + .HasColumnName("ConversionTargetDate"); + + b1.Property("ConversionTargetDateExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionTargetDateExplained"); + + b1.Property("ConversionTargetDateSpecified") + .HasColumnType("bit") + .HasColumnName("ConversionTargetDateSpecified"); + + b1.Property("DeclarationBodyAgree") + .HasColumnType("bit") + .HasColumnName("DeclarationBodyAgree"); + + b1.Property("DeclarationIAmTheChairOrHeadteacher") + .HasColumnType("bit") + .HasColumnName("DeclarationIAmTheChairOrHeadteacher"); + + b1.Property("DeclarationSignedByName") + .HasColumnType("nvarchar(max)") + .HasColumnName("DeclarationSignedByName"); + + b1.Property("FinanceOngoingInvestigations") + .HasColumnType("bit") + .HasColumnName("FinanceOngoingInvestigations"); + + b1.Property("FinancialInvestigationsExplain") + .HasColumnType("nvarchar(max)") + .HasColumnName("FinancialInvestigationsExplain"); + + b1.Property("FinancialInvestigationsTrustAware") + .HasColumnType("bit") + .HasColumnName("FinancialInvestigationsTrustAware"); + + b1.Property("MainContactOtherEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherEmail"); + + b1.Property("MainContactOtherName") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherName"); + + b1.Property("MainContactOtherRole") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherRole"); + + b1.Property("ProjectedPupilNumbersYear1") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear1"); + + b1.Property("ProjectedPupilNumbersYear2") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear2"); + + b1.Property("ProjectedPupilNumbersYear3") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear3"); + + b1.Property("ProposedNewSchoolName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ProposedNewSchoolName"); + + b1.Property("SchoolConversionReasonsForJoining") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolConversionReasonsForJoining"); + + b1.Property("SchoolHasConsultedStakeholders") + .HasColumnType("bit") + .HasColumnName("SchoolHasConsultedStakeholders"); + + b1.Property("SchoolName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolName"); + + b1.Property("SchoolPlanToConsultStakeholders") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPlanToConsultStakeholders"); + + b1.Property("SchoolSupportGrantFundsPaidTo") + .HasColumnType("int") + .HasColumnName("SupportGrantFundsPaidTo"); + + b1.Property("Urn") + .HasColumnType("int") + .HasColumnName("Urn"); + + b1.HasKey("SchoolId"); + + b1.ToTable("ApplicationSchool", "academisation"); + + b1.WithOwner() + .HasForeignKey("SchoolId"); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.LandAndBuildings", "LandAndBuildings", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("FacilitiesShared") + .HasColumnType("bit") + .HasColumnName("FacilitiesShared"); + + b2.Property("FacilitiesSharedExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("FacilitiesSharedExplained"); + + b2.Property("Grants") + .HasColumnType("bit") + .HasColumnName("Grants"); + + b2.Property("GrantsAwardingBodies") + .HasColumnType("nvarchar(max)") + .HasColumnName("GrantsAwardingBodies"); + + b2.Property("OwnerExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("OwnerExplained"); + + b2.Property("PartOfBuildingSchoolsForFutureProgramme") + .HasColumnType("bit") + .HasColumnName("PartOfBuildingSchoolsForFutureProgramme"); + + b2.Property("PartOfPfiScheme") + .HasColumnType("bit") + .HasColumnName("PartOfPfiScheme"); + + b2.Property("PartOfPfiSchemeType") + .HasColumnType("nvarchar(max)") + .HasColumnName("PartOfPfiSchemeType"); + + b2.Property("PartOfPrioritySchoolsBuildingProgramme") + .HasColumnType("bit") + .HasColumnName("PartOfPrioritySchoolsBuildingProgramme"); + + b2.Property("WorksPlanned") + .HasColumnType("bit") + .HasColumnName("WorksPlanned"); + + b2.Property("WorksPlannedDate") + .HasColumnType("datetime2") + .HasColumnName("WorksPlannedDate"); + + b2.Property("WorksPlannedExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("WorksPlannedExplained"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "CurrentFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("CurrentFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("CurrentFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("CurrentFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("CurrentFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "NextFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("NextFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("NextFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("NextFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("NextFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("NextFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "PreviousFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("PreviousFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("PreviousFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("PreviousFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("PreviousFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.Navigation("CurrentFinancialYear"); + + b1.Navigation("LandAndBuildings"); + + b1.Navigation("NextFinancialYear"); + + b1.Navigation("PreviousFinancialYear"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FormTrustDetails", "TrustDetails", b1 => + { + b1.Property("FormTrustId") + .HasColumnType("int"); + + b1.Property("FormTrustGrowthPlansYesNo") + .HasColumnType("bit") + .HasColumnName("FormTrustGrowthPlansYesNo"); + + b1.Property("FormTrustImprovementApprovedSponsor") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementApprovedSponsor"); + + b1.Property("FormTrustImprovementStrategy") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementStrategy"); + + b1.Property("FormTrustImprovementSupport") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementSupport"); + + b1.Property("FormTrustOpeningDate") + .HasColumnType("datetime2") + .HasColumnName("FormTrustOpeningDate"); + + b1.Property("FormTrustPlanForGrowth") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustPlanForGrowth"); + + b1.Property("FormTrustPlansForNoGrowth") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustPlansForNoGrowth"); + + b1.Property("FormTrustProposedNameOfTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustProposedNameOfTrust"); + + b1.Property("FormTrustReasonApprovaltoConvertasSAT") + .HasColumnType("bit") + .HasColumnName("FormTrustReasonApprovaltoConvertasSAT"); + + b1.Property("FormTrustReasonApprovedPerson") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonApprovedPerson"); + + b1.Property("FormTrustReasonForming") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonForming"); + + b1.Property("FormTrustReasonFreedom") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonFreedom"); + + b1.Property("FormTrustReasonGeoAreas") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonGeoAreas"); + + b1.Property("FormTrustReasonImproveTeaching") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonImproveTeaching"); + + b1.Property("FormTrustReasonVision") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonVision"); + + b1.Property("TrustApproverEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustApproverEmail"); + + b1.Property("TrustApproverName") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustApproverName"); + + b1.HasKey("FormTrustId"); + + b1.ToTable("ApplicationFormTrust", "academisation"); + + b1.WithOwner() + .HasForeignKey("FormTrustId"); + }); + + b.Navigation("TrustDetails") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", null) + .WithMany("KeyPeople") + .HasForeignKey("ApplicationFormTrustId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPersonRole", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", null) + .WithMany("Roles") + .HasForeignKey("ApplicationFormTrustKeyPersonRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDecisionDetails", "AdvisoryBoardDecisionDetails", b1 => + { + b1.Property("ConversionAdvisoryBoardDecisionId") + .HasColumnType("int"); + + b1.Property("AcademyOrderDate") + .HasColumnType("datetime2") + .HasColumnName("AcademyOrderDate"); + + b1.Property("AdvisoryBoardDecisionDate") + .HasColumnType("datetime2") + .HasColumnName("AdvisoryBoardDecisionDate"); + + b1.Property("ApprovedConditionsDetails") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApprovedConditionsDetails"); + + b1.Property("ApprovedConditionsSet") + .HasColumnType("bit") + .HasColumnName("ApprovedConditionsSet"); + + b1.Property("ConversionProjectId") + .HasColumnType("int") + .HasColumnName("ConversionProjectId"); + + b1.Property("Decision") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Decision"); + + b1.Property("DecisionMadeBy") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("DecisionMadeBy"); + + b1.Property("DecisionMakerName") + .HasColumnType("nvarchar(max)") + .HasColumnName("DecisionMakerName"); + + b1.Property("TransferProjectId") + .HasColumnType("int") + .HasColumnName("TransferProjectId"); + + b1.HasKey("ConversionAdvisoryBoardDecisionId"); + + b1.ToTable("ConversionAdvisoryBoardDecision", "academisation"); + + b1.WithOwner() + .HasForeignKey("ConversionAdvisoryBoardDecisionId"); + }); + + b.Navigation("AdvisoryBoardDecisionDetails") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDAORevokedReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DaoRevokedReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeclinedReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DeclinedReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeferredReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DeferredReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardWithdrawnReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("WithdrawnReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectNote", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", null) + .WithMany("Notes") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.FormAMatProjectAggregate.FormAMatProject", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b1 => + { + b1.Property("FormAMatProjectId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b1.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b1.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b1.HasKey("FormAMatProjectId"); + + b1.ToTable("FormAMatProject", "academisation"); + + b1.WithOwner() + .HasForeignKey("FormAMatProjectId"); + }); + + b.Navigation("AssignedUser"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectDetails", "Details", b1 => + { + b1.Property("ProjectId") + .HasColumnType("int"); + + b1.Property("AcademyTypeAndRoute") + .HasColumnType("nvarchar(max)") + .HasColumnName("AcademyTypeAndRoute"); + + b1.Property("ActualPupilNumbers") + .HasColumnType("int") + .HasColumnName("ActualPupilNumbers"); + + b1.Property("AgeRange") + .HasColumnType("nvarchar(max)") + .HasColumnName("AgeRange"); + + b1.Property("AnnexBFormReceived") + .HasColumnType("bit") + .HasColumnName("AnnexBFormReceived"); + + b1.Property("AnnexBFormUrl") + .HasColumnType("nvarchar(max)") + .HasColumnName("AnnexBFormUrl"); + + b1.Property("ApplicationReceivedDate") + .HasColumnType("datetime2") + .HasColumnName("ApplicationReceivedDate"); + + b1.Property("ApplicationReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApplicationReferenceNumber"); + + b1.Property("AssignedDate") + .HasColumnType("datetime2") + .HasColumnName("AssignedDate"); + + b1.Property("Author") + .HasColumnType("nvarchar(max)") + .HasColumnName("Author"); + + b1.Property("BaselineDate") + .HasColumnType("datetime2") + .HasColumnName("BaselineDate"); + + b1.Property("Capacity") + .HasColumnType("int") + .HasColumnName("Capacity"); + + b1.Property("CapitalCarryForwardAtEndMarchCurrentYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("CapitalCarryForwardAtEndMarchCurrentYear"); + + b1.Property("CapitalCarryForwardAtEndMarchNextYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("CapitalCarryForwardAtEndMarchNextYear"); + + b1.Property("ClearedBy") + .HasColumnType("nvarchar(max)") + .HasColumnName("ClearedBy"); + + b1.Property("Consultation") + .HasColumnType("nvarchar(max)") + .HasColumnName("Consultation"); + + b1.Property("ConversionSupportGrantAmount") + .HasColumnType("decimal(18,2)") + .HasColumnName("ConversionSupportGrantAmount"); + + b1.Property("ConversionSupportGrantAmountChanged") + .HasColumnType("bit") + .HasColumnName("ConversionSupportGrantAmountChanged"); + + b1.Property("ConversionSupportGrantChangeReason") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantChangeReason"); + + b1.Property("ConversionSupportGrantEnvironmentalImprovementGrant") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantEnvironmentalImprovementGrant"); + + b1.Property("ConversionSupportGrantNumberOfSites") + .HasColumnType("nvarchar(max)"); + + b1.Property("ConversionSupportGrantType") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantType"); + + b1.Property("DaoPackSentDate") + .HasColumnType("datetime2") + .HasColumnName("DaoPackSentDate"); + + b1.Property("DiocesanConsent") + .HasColumnType("nvarchar(max)") + .HasColumnName("DiocesanConsent"); + + b1.Property("DiocesanTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("DiocesanTrust"); + + b1.Property("DistanceFromSchoolToTrustHeadquarters") + .HasColumnType("decimal(18,2)") + .HasColumnName("DistanceFromSchoolToTrustHeadquarters"); + + b1.Property("DistanceFromSchoolToTrustHeadquartersAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("DistanceFromSchoolToTrustHeadquartersAdditionalInformation"); + + b1.Property("EducationalAttendanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b1.Property("EndOfCurrentFinancialYear") + .HasColumnType("datetime2") + .HasColumnName("EndOfCurrentFinancialYear"); + + b1.Property("EndOfNextFinancialYear") + .HasColumnType("datetime2") + .HasColumnName("EndOfNextFinancialYear"); + + b1.Property("ExternalApplicationFormSaved") + .HasColumnType("bit") + .HasColumnName("ExternalApplicationFormSaved"); + + b1.Property("ExternalApplicationFormUrl") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExternalApplicationFormUrl"); + + b1.Property("FinancialDeficit") + .HasColumnType("nvarchar(max)") + .HasColumnName("FinancialDeficit"); + + b1.Property("Form7Received") + .HasColumnType("nvarchar(max)") + .HasColumnName("Form7Received"); + + b1.Property("Form7ReceivedDate") + .HasColumnType("datetime2") + .HasColumnName("Form7ReceivedDate"); + + b1.Property("FoundationConsent") + .HasColumnType("nvarchar(max)") + .HasColumnName("FoundationConsent"); + + b1.Property("GoverningBodyResolution") + .HasColumnType("nvarchar(max)") + .HasColumnName("GoverningBodyResolution"); + + b1.Property("HeadTeacherBoardDate") + .HasColumnType("datetime2") + .HasColumnName("HeadTeacherBoardDate"); + + b1.Property("IfdPipelineId") + .HasColumnType("int") + .HasColumnName("IfdPipelineId"); + + b1.Property("IsFormAMat") + .HasColumnType("bit") + .HasColumnName("IsFormAMat"); + + b1.Property("KeyStage2PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage2PerformanceAdditionalInformation"); + + b1.Property("KeyStage4PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage4PerformanceAdditionalInformation"); + + b1.Property("KeyStage5PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage5PerformanceAdditionalInformation"); + + b1.Property("LegalRequirementsSectionComplete") + .HasColumnType("bit") + .HasColumnName("LegalRequirementsSectionComplete"); + + b1.Property("LocalAuthority") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthority"); + + b1.Property("LocalAuthorityInformationTemplateComments") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthorityInformationTemplateComments"); + + b1.Property("LocalAuthorityInformationTemplateLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthorityInformationTemplateLink"); + + b1.Property("LocalAuthorityInformationTemplateReturnedDate") + .HasColumnType("datetime2") + .HasColumnName("LocalAuthorityInformationTemplateReturnedDate"); + + b1.Property("LocalAuthorityInformationTemplateSectionComplete") + .HasColumnType("bit") + .HasColumnName("LocalAuthorityInformationTemplateSectionComplete"); + + b1.Property("LocalAuthorityInformationTemplateSentDate") + .HasColumnType("datetime2") + .HasColumnName("LocalAuthorityInformationTemplateSentDate"); + + b1.Property("MemberOfParliamentNameAndParty") + .HasColumnType("nvarchar(max)") + .HasColumnName("MemberOfParliamentNameAndParty"); + + b1.Property("NameOfTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("NameOfTrust"); + + b1.Property("NumberOfAlternativeProvisionPlaces") + .HasColumnType("int"); + + b1.Property("NumberOfFundedResidentialPlaces") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfMedicalPlaces") + .HasColumnType("int"); + + b1.Property("NumberOfPlacesFundedFor") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfPost16Places") + .HasColumnType("int"); + + b1.Property("NumberOfResidentialPlaces") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfSENUnitPlaces") + .HasColumnType("int"); + + b1.Property("PartOfPfiScheme") + .HasColumnType("nvarchar(max)") + .HasColumnName("PartOfPfiScheme"); + + b1.Property("PercentageFreeSchoolMeals") + .HasColumnType("decimal(18,2)") + .HasColumnName("PercentageFreeSchoolMeals"); + + b1.Property("PercentageOfGoodOrOutstandingSchoolsInTheDiocesanTrust") + .HasColumnType("decimal(18,2)") + .HasColumnName("PercentageOfGoodOrOutstandingSchoolsInTheDiocesanTrust"); + + b1.Property("PfiSchemeDetails") + .HasColumnType("nvarchar(max)") + .HasColumnName("PfiSchemeDetails"); + + b1.Property("PreviousHeadTeacherBoardDate") + .HasColumnType("datetime2") + .HasColumnName("PreviousHeadTeacherBoardDate"); + + b1.Property("PreviousHeadTeacherBoardDateQuestion") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousHeadTeacherBoardDateQuestion"); + + b1.Property("PreviousHeadTeacherBoardLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousHeadTeacherBoardLink"); + + b1.Property("ProjectDatesSectionComplete") + .HasColumnType("bit") + .HasColumnName("ProjectDatesSectionComplete"); + + b1.Property("ProjectStatus") + .HasColumnType("nvarchar(max)") + .HasColumnName("ProjectStatus"); + + b1.Property("ProjectedRevenueBalanceAtEndMarchNextYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("ProjectedRevenueBalanceAtEndMarchNextYear"); + + b1.Property("ProposedConversionDate") + .HasColumnType("datetime2") + .HasColumnName("ProposedAcademyOpeningDate"); + + b1.Property("PublishedAdmissionNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("PublishedAdmissionNumber"); + + b1.Property("PupilsAttendingGroupMedicalAndHealthNeeds") + .HasColumnType("bit"); + + b1.Property("PupilsAttendingGroupPermanentlyExcluded") + .HasColumnType("bit"); + + b1.Property("PupilsAttendingGroupTeenageMums") + .HasColumnType("bit"); + + b1.Property("RationaleForProject") + .HasColumnType("nvarchar(max)") + .HasColumnName("RationaleForProject"); + + b1.Property("RationaleForTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("RationaleForTrust"); + + b1.Property("RationaleSectionComplete") + .HasColumnType("bit") + .HasColumnName("RationaleSectionComplete"); + + b1.Property("RecommendationForProject") + .HasColumnType("nvarchar(max)") + .HasColumnName("RecommendationForProject"); + + b1.Property("Region") + .HasColumnType("nvarchar(max)") + .HasColumnName("Region"); + + b1.Property("RevenueCarryForwardAtEndMarchCurrentYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("RevenueCarryForwardAtEndMarchCurrentYear"); + + b1.Property("RisksAndIssues") + .HasColumnType("nvarchar(max)") + .HasColumnName("RisksAndIssues"); + + b1.Property("RisksAndIssuesSectionComplete") + .HasColumnType("bit") + .HasColumnName("RisksAndIssuesSectionComplete"); + + b1.Property("SchoolAndTrustInformationSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolAndTrustInformationSectionComplete"); + + b1.Property("SchoolBudgetInformationAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolBudgetInformationAdditionalInformation"); + + b1.Property("SchoolBudgetInformationSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolBudgetInformationSectionComplete"); + + b1.Property("SchoolName") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolName"); + + b1.Property("SchoolOverviewSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolOverviewSectionComplete"); + + b1.Property("SchoolPerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPerformanceAdditionalInformation"); + + b1.Property("SchoolPhase") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPhase"); + + b1.Property("SchoolPupilForecastsAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPupilForecastsAdditionalInformation"); + + b1.Property("SchoolType") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolType"); + + b1.Property("SponsorName") + .HasColumnType("nvarchar(max)") + .HasColumnName("SponsorName"); + + b1.Property("SponsorReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("SponsorReferenceNumber"); + + b1.Property("TrustReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustReferenceNumber"); + + b1.Property("TrustUkprn") + .HasColumnType("int"); + + b1.Property("Urn") + .HasColumnType("int") + .HasColumnName("Urn"); + + b1.Property("Version") + .HasColumnType("nvarchar(max)") + .HasColumnName("Version"); + + b1.Property("ViabilityIssues") + .HasColumnType("nvarchar(max)") + .HasColumnName("ViabilityIssues"); + + b1.Property("YearOneProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearOneProjectedCapacity"); + + b1.Property("YearOneProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearOneProjectedPupilNumbers"); + + b1.Property("YearThreeProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearThreeProjectedCapacity"); + + b1.Property("YearThreeProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearThreeProjectedPupilNumbers"); + + b1.Property("YearTwoProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearTwoProjectedCapacity"); + + b1.Property("YearTwoProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearTwoProjectedPupilNumbers"); + + b1.HasKey("ProjectId"); + + b1.ToTable("Project", "academisation"); + + b1.WithOwner() + .HasForeignKey("ProjectId"); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b2 => + { + b2.Property("ProjectDetailsProjectId") + .HasColumnType("int"); + + b2.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b2.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b2.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b2.HasKey("ProjectDetailsProjectId"); + + b2.ToTable("Project", "academisation"); + + b2.WithOwner() + .HasForeignKey("ProjectDetailsProjectId"); + }); + + b1.Navigation("AssignedUser"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.SchoolImprovementPlan", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", null) + .WithMany("SchoolImprovementPlans") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate.ProjectGroup", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b1 => + { + b1.Property("ProjectGroupId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b1.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b1.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b1.HasKey("ProjectGroupId"); + + b1.ToTable("ProjectGroups", "academisation"); + + b1.WithOwner() + .HasForeignKey("ProjectGroupId"); + }); + + b.Navigation("AssignedUser"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.IntendedTransferBenefit", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", null) + .WithMany("IntendedTransferBenefits") + .HasForeignKey("TransferProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferringAcademy", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", null) + .WithMany("TransferringAcademies") + .HasForeignKey("TransferProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.Navigation("Contributors"); + + b.Navigation("Schools"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.Navigation("Leases"); + + b.Navigation("Loans"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.Navigation("KeyPeople"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.Navigation("DaoRevokedReasons"); + + b.Navigation("DeclinedReasons"); + + b.Navigation("DeferredReasons"); + + b.Navigation("WithdrawnReasons"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.Navigation("Notes"); + + b.Navigation("SchoolImprovementPlans"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", b => + { + b.Navigation("IntendedTransferBenefits"); + + b.Navigation("TransferringAcademies"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Dfe.Academies.Academisation.Data/Migrations/20241023142123_add-complete-sent-date-to-project.cs b/Dfe.Academies.Academisation.Data/Migrations/20241023142123_add-complete-sent-date-to-project.cs new file mode 100644 index 000000000..7a8999664 --- /dev/null +++ b/Dfe.Academies.Academisation.Data/Migrations/20241023142123_add-complete-sent-date-to-project.cs @@ -0,0 +1,44 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Dfe.Academies.Academisation.Data.Migrations +{ + /// + public partial class addcompletesentdatetoproject : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ProjectSentToComplete", + schema: "academisation", + table: "Project"); + + migrationBuilder.AddColumn( + name: "ProjectSentToCompleteDate", + schema: "academisation", + table: "Project", + type: "datetime2", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ProjectSentToCompleteDate", + schema: "academisation", + table: "Project"); + + migrationBuilder.AddColumn( + name: "ProjectSentToComplete", + schema: "academisation", + table: "Project", + type: "bit", + nullable: false, + defaultValue: false); + } + } +} diff --git a/Dfe.Academies.Academisation.Data/Migrations/20241023151338_add-trust-reference-number-seq.Designer.cs b/Dfe.Academies.Academisation.Data/Migrations/20241023151338_add-trust-reference-number-seq.Designer.cs new file mode 100644 index 000000000..17b469c7e --- /dev/null +++ b/Dfe.Academies.Academisation.Data/Migrations/20241023151338_add-trust-reference-number-seq.Designer.cs @@ -0,0 +1,2359 @@ +// +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.Academisation.Data.Migrations +{ + [DbContext(typeof(AcademisationContext))] + [Migration("20241023151338_add-trust-reference-number-seq")] + partial class addtrustreferencenumberseq + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.HasSequence("TrustReferenceNumberSeq", "academisation"); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationReference") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("nvarchar(max)") + .HasComputedColumnSql("'A2B_' + CAST([Id] AS NVARCHAR(255))", true); + + b.Property("ApplicationStatus") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ApplicationSubmittedDate") + .HasColumnType("datetime2"); + + b.Property("ApplicationType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("FormTrustId") + .HasColumnType("int"); + + b.Property("JoinTrustId") + .HasColumnType("int"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("FormTrustId") + .IsUnique() + .HasFilter("[FormTrustId] IS NOT NULL"); + + b.HasIndex("JoinTrustId") + .IsUnique() + .HasFilter("[JoinTrustId] IS NOT NULL"); + + b.ToTable("ConversionApplication", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Contributor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConversionApplicationId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ConversionApplicationId"); + + b.ToTable("ConversionApplicationContributor", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Lease", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationSchoolId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsSchoolLeaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("InterestRate") + .HasColumnType("decimal(18,2)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LeaseTerm") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentsToDate") + .HasColumnType("decimal(18,2)"); + + b.Property("Purpose") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RepaymentAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("ResponsibleForAssets") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ValueOfAssets") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationSchoolId"); + + b.ToTable("ApplicationSchoolLease", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Loan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationSchoolId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsSchoolLoanId") + .HasColumnType("uniqueidentifier"); + + b.Property("InterestRate") + .HasColumnType("decimal(18,2)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Purpose") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Schedule") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationSchoolId"); + + b.ToTable("ApplicationSchoolLoan", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConversionApplicationId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DioceseFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("DioceseName") + .HasColumnType("nvarchar(max)"); + + b.Property("DynamicsApplyingSchoolId") + .HasColumnType("uniqueidentifier"); + + b.Property("ExemptionEndDate") + .HasColumnType("datetimeoffset"); + + b.Property("FoundationConsentFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("FoundationTrustOrBodyName") + .HasColumnType("nvarchar(max)"); + + b.Property("FurtherInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("HasLeases") + .HasColumnType("bit"); + + b.Property("HasLoans") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LocalAuthorityClosurePlanDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("LocalAuthorityReorganisationDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("MainFeederSchools") + .HasColumnType("nvarchar(max)"); + + b.Property("OfstedInspectionDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("PartOfFederation") + .HasColumnType("bit"); + + b.Property("ProtectedCharacteristics") + .HasColumnType("int"); + + b.Property("ResolutionConsentFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("Safeguarding") + .HasColumnType("bit"); + + b.Property("TrustBenefitDetails") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ConversionApplicationId"); + + b.ToTable("ApplicationSchool", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("ApplicationFormTrust", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.JoinTrust", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChangesToLaGovernance") + .HasColumnType("bit"); + + b.Property("ChangesToLaGovernanceExplained") + .HasColumnType("nvarchar(max)"); + + b.Property("ChangesToTrust") + .HasColumnType("int"); + + b.Property("ChangesToTrustExplained") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("TrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UKPRN") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ApplicationJoinTrust", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationFormTrustId") + .HasColumnType("int"); + + b.Property("Biography") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DateOfBirth") + .HasColumnType("datetime2"); + + b.Property("DynamicsKeyPersonId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationFormTrustId"); + + b.ToTable("ApplicationFormTrustKeyPerson", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPersonRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationFormTrustKeyPersonRoleId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Role") + .HasColumnType("int"); + + b.Property("TimeInRole") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationFormTrustKeyPersonRoleId"); + + b.ToTable("ApplicationFormTrustKeyPersonRole", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.CompleteTransmissionLog.CompleteTransmissionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompleteProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConversionProjectId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("IsSuccess") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Response") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransferProjectId") + .HasColumnType("int"); + + b.Property("TransferringAcademyId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CompleteTransmissionLog", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("ConversionAdvisoryBoardDecision", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDAORevokedReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("AdvisoryBoardDecisionDAORevokedReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeclinedReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("ConversionAdvisoryBoardDecisionDeclinedReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeferredReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("ConversionAdvisoryBoardDecisionDeferredReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardWithdrawnReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("AdvisoryBoardDecisionWithdrawnReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Author") + .HasColumnType("nvarchar(max)"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("Note") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectNotes", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.FormAMatProjectAggregate.FormAMatProject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ProposedTrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReferenceNumber") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FormAMatProject", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.OpeningDateHistoryAggregate.OpeningDateHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChangedAt") + .HasColumnType("datetime2"); + + b.Property("ChangedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("EntityId") + .HasColumnType("int"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("NewDate") + .HasColumnType("datetime2"); + + b.Property("OldDate") + .HasColumnType("datetime2"); + + b.Property("ReasonsChanged") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("OpeningDateHistories", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationSharePointId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOn") + .HasColumnType("datetime2") + .HasColumnName("CreatedOn"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("FormAMatProjectId") + .HasColumnType("int") + .HasColumnName("FormAMatProjectId"); + + b.Property("IsReadOnly") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ProjectGroupId") + .HasColumnType("int"); + + b.Property("ProjectSentToCompleteDate") + .HasColumnType("datetime2"); + + b.Property("SchoolSharePointId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Project", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.SchoolImprovementPlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArrangedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ArrangedByOther") + .HasColumnType("nvarchar(max)"); + + b.Property("ConfidenceLevel") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("ExpectedEndDate") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ExpectedEndDateOther") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("PlanComments") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ProvidedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("SchoolImprovementPlans", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate.ProjectGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ReferenceNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("TrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ProjectGroups", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.IntendedTransferBenefit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("SelectedBenefit") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransferProjectId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TransferProjectId"); + + b.ToTable("IntendedTransferBenefit", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 10003000L); + + b.Property("AnyRisks") + .HasColumnType("bit"); + + b.Property("AssignedUserEmailAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("AssignedUserFullName") + .HasColumnType("nvarchar(max)"); + + b.Property("AssignedUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Author") + .HasColumnType("nvarchar(max)"); + + b.Property("BenefitsSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("ComplexLandAndBuildingFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("ComplexLandAndBuildingShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DiocesanConsent") + .HasColumnType("nvarchar(max)"); + + b.Property("EqualitiesImpactAssessmentConsidered") + .HasColumnType("bit"); + + b.Property("FeatureSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("FinanceAndDebtFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("FinanceAndDebtShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("HasHtbDate") + .HasColumnType("bit"); + + b.Property("HasTargetDateForTransfer") + .HasColumnType("bit"); + + b.Property("HasTransferFirstDiscussedDate") + .HasColumnType("bit"); + + b.Property("HighProfileFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("HighProfileShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("HtbDate") + .HasColumnType("datetime2"); + + b.Property("IncomingTrustAgreement") + .HasColumnType("nvarchar(max)"); + + b.Property("IsFormAMat") + .HasColumnType("bit"); + + b.Property("IsReadOnly") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LegalRequirementsSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("OtherBenefitValue") + .HasColumnType("nvarchar(max)"); + + b.Property("OtherRisksFurtherSpecification") + .HasMaxLength(20000) + .HasColumnType("nvarchar(max)"); + + b.Property("OtherRisksShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("OtherTransferTypeDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustConsent") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustName") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PreviousAdvisoryBoardDate") + .HasColumnType("datetime2"); + + b.Property("ProjectGroupId") + .HasColumnType("int"); + + b.Property("ProjectRationale") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectReference") + .HasColumnType("nvarchar(max)"); + + b.Property("RationaleSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("RddOrEsfaIntervention") + .HasColumnType("bit"); + + b.Property("RddOrEsfaInterventionDetail") + .HasColumnType("nvarchar(max)"); + + b.Property("Recommendation") + .HasColumnType("nvarchar(max)"); + + b.Property("SpecificReasonsForTransfer") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasColumnType("nvarchar(max)"); + + b.Property("TargetDateForTransfer") + .HasColumnType("datetime2"); + + b.Property("TransferDatesSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("TransferFirstDiscussed") + .HasColumnType("datetime2"); + + b.Property("TrustSponsorRationale") + .HasColumnType("nvarchar(max)"); + + b.Property("TypeOfTransfer") + .HasColumnType("nvarchar(max)"); + + b.Property("Urn") + .HasColumnType("int"); + + b.Property("WhoInitiatedTheTransfer") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("TransferProject", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferringAcademy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DistanceFromAcademyToTrustHq") + .HasColumnType("nvarchar(max)"); + + b.Property("DistanceFromAcademyToTrustHqDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("FinancialDeficit") + .HasColumnType("nvarchar(max)"); + + b.Property("IncomingTrustName") + .HasColumnType("nvarchar(max)"); + + b.Property("IncomingTrustUkprn") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage2PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage4PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage5PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("LatestOfstedReportAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("LocalAuthority") + .HasColumnType("nvarchar(max)"); + + b.Property("MPNameAndParty") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingAcademyUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PFIScheme") + .HasColumnType("nvarchar(max)"); + + b.Property("PFISchemeDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectSentToComplete") + .HasColumnType("bit"); + + b.Property("PublishedAdmissionNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PupilNumbersAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("Region") + .HasColumnType("nvarchar(max)"); + + b.Property("TransferProjectId") + .HasColumnType("int"); + + b.Property("ViabilityIssues") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TransferProjectId"); + + b.ToTable("TransferringAcademy", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", "FormTrust") + .WithOne() + .HasForeignKey("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", "FormTrustId"); + + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.JoinTrust", "JoinTrust") + .WithOne() + .HasForeignKey("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", "JoinTrustId"); + + b.Navigation("FormTrust"); + + b.Navigation("JoinTrust"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Contributor", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", null) + .WithMany("Contributors") + .HasForeignKey("ConversionApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.ContributorDetails", "Details", b1 => + { + b1.Property("ContributorId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("EmailAddress"); + + b1.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("FirstName"); + + b1.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("LastName"); + + b1.Property("OtherRoleName") + .HasColumnType("nvarchar(max)") + .HasColumnName("OtherRoleName"); + + b1.Property("Role") + .HasColumnType("int") + .HasColumnName("Role"); + + b1.HasKey("ContributorId"); + + b1.ToTable("ConversionApplicationContributor", "academisation"); + + b1.WithOwner() + .HasForeignKey("ContributorId"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Lease", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", null) + .WithMany("Leases") + .HasForeignKey("ApplicationSchoolId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Loan", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", null) + .WithMany("Loans") + .HasForeignKey("ApplicationSchoolId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", null) + .WithMany("Schools") + .HasForeignKey("ConversionApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.SchoolDetails", "Details", b1 => + { + b1.Property("SchoolId") + .HasColumnType("int"); + + b1.Property("ApplicationJoinTrustReason") + .HasColumnType("nvarchar(max)") + .HasColumnName("JoinTrustReason"); + + b1.Property("ApproverContactEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApproverContactEmail"); + + b1.Property("ApproverContactName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApproverContactName"); + + b1.Property("CapacityAssumptions") + .HasColumnType("nvarchar(max)") + .HasColumnName("CapacityAssumptions"); + + b1.Property("CapacityPublishedAdmissionsNumber") + .HasColumnType("int") + .HasColumnName("CapacityPublishedAdmissionsNumber"); + + b1.Property("ConfirmPaySupportGrantToSchool") + .HasColumnType("bit") + .HasColumnName("ConfirmPaySupportGrantToSchool"); + + b1.Property("ContactChairEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactChairEmail"); + + b1.Property("ContactChairName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactChairName"); + + b1.Property("ContactHeadEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactHeadEmail"); + + b1.Property("ContactHeadName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactHeadName"); + + b1.Property("ContactRole") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactRole"); + + b1.Property("ConversionChangeNamePlanned") + .HasColumnType("bit") + .HasColumnName("ConversionChangeNamePlanned"); + + b1.Property("ConversionTargetDate") + .HasColumnType("datetime2") + .HasColumnName("ConversionTargetDate"); + + b1.Property("ConversionTargetDateExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionTargetDateExplained"); + + b1.Property("ConversionTargetDateSpecified") + .HasColumnType("bit") + .HasColumnName("ConversionTargetDateSpecified"); + + b1.Property("DeclarationBodyAgree") + .HasColumnType("bit") + .HasColumnName("DeclarationBodyAgree"); + + b1.Property("DeclarationIAmTheChairOrHeadteacher") + .HasColumnType("bit") + .HasColumnName("DeclarationIAmTheChairOrHeadteacher"); + + b1.Property("DeclarationSignedByName") + .HasColumnType("nvarchar(max)") + .HasColumnName("DeclarationSignedByName"); + + b1.Property("FinanceOngoingInvestigations") + .HasColumnType("bit") + .HasColumnName("FinanceOngoingInvestigations"); + + b1.Property("FinancialInvestigationsExplain") + .HasColumnType("nvarchar(max)") + .HasColumnName("FinancialInvestigationsExplain"); + + b1.Property("FinancialInvestigationsTrustAware") + .HasColumnType("bit") + .HasColumnName("FinancialInvestigationsTrustAware"); + + b1.Property("MainContactOtherEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherEmail"); + + b1.Property("MainContactOtherName") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherName"); + + b1.Property("MainContactOtherRole") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherRole"); + + b1.Property("ProjectedPupilNumbersYear1") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear1"); + + b1.Property("ProjectedPupilNumbersYear2") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear2"); + + b1.Property("ProjectedPupilNumbersYear3") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear3"); + + b1.Property("ProposedNewSchoolName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ProposedNewSchoolName"); + + b1.Property("SchoolConversionReasonsForJoining") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolConversionReasonsForJoining"); + + b1.Property("SchoolHasConsultedStakeholders") + .HasColumnType("bit") + .HasColumnName("SchoolHasConsultedStakeholders"); + + b1.Property("SchoolName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolName"); + + b1.Property("SchoolPlanToConsultStakeholders") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPlanToConsultStakeholders"); + + b1.Property("SchoolSupportGrantFundsPaidTo") + .HasColumnType("int") + .HasColumnName("SupportGrantFundsPaidTo"); + + b1.Property("Urn") + .HasColumnType("int") + .HasColumnName("Urn"); + + b1.HasKey("SchoolId"); + + b1.ToTable("ApplicationSchool", "academisation"); + + b1.WithOwner() + .HasForeignKey("SchoolId"); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.LandAndBuildings", "LandAndBuildings", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("FacilitiesShared") + .HasColumnType("bit") + .HasColumnName("FacilitiesShared"); + + b2.Property("FacilitiesSharedExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("FacilitiesSharedExplained"); + + b2.Property("Grants") + .HasColumnType("bit") + .HasColumnName("Grants"); + + b2.Property("GrantsAwardingBodies") + .HasColumnType("nvarchar(max)") + .HasColumnName("GrantsAwardingBodies"); + + b2.Property("OwnerExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("OwnerExplained"); + + b2.Property("PartOfBuildingSchoolsForFutureProgramme") + .HasColumnType("bit") + .HasColumnName("PartOfBuildingSchoolsForFutureProgramme"); + + b2.Property("PartOfPfiScheme") + .HasColumnType("bit") + .HasColumnName("PartOfPfiScheme"); + + b2.Property("PartOfPfiSchemeType") + .HasColumnType("nvarchar(max)") + .HasColumnName("PartOfPfiSchemeType"); + + b2.Property("PartOfPrioritySchoolsBuildingProgramme") + .HasColumnType("bit") + .HasColumnName("PartOfPrioritySchoolsBuildingProgramme"); + + b2.Property("WorksPlanned") + .HasColumnType("bit") + .HasColumnName("WorksPlanned"); + + b2.Property("WorksPlannedDate") + .HasColumnType("datetime2") + .HasColumnName("WorksPlannedDate"); + + b2.Property("WorksPlannedExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("WorksPlannedExplained"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "CurrentFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("CurrentFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("CurrentFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("CurrentFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("CurrentFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "NextFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("NextFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("NextFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("NextFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("NextFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("NextFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "PreviousFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("PreviousFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("PreviousFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("PreviousFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("PreviousFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.Navigation("CurrentFinancialYear"); + + b1.Navigation("LandAndBuildings"); + + b1.Navigation("NextFinancialYear"); + + b1.Navigation("PreviousFinancialYear"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FormTrustDetails", "TrustDetails", b1 => + { + b1.Property("FormTrustId") + .HasColumnType("int"); + + b1.Property("FormTrustGrowthPlansYesNo") + .HasColumnType("bit") + .HasColumnName("FormTrustGrowthPlansYesNo"); + + b1.Property("FormTrustImprovementApprovedSponsor") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementApprovedSponsor"); + + b1.Property("FormTrustImprovementStrategy") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementStrategy"); + + b1.Property("FormTrustImprovementSupport") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementSupport"); + + b1.Property("FormTrustOpeningDate") + .HasColumnType("datetime2") + .HasColumnName("FormTrustOpeningDate"); + + b1.Property("FormTrustPlanForGrowth") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustPlanForGrowth"); + + b1.Property("FormTrustPlansForNoGrowth") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustPlansForNoGrowth"); + + b1.Property("FormTrustProposedNameOfTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustProposedNameOfTrust"); + + b1.Property("FormTrustReasonApprovaltoConvertasSAT") + .HasColumnType("bit") + .HasColumnName("FormTrustReasonApprovaltoConvertasSAT"); + + b1.Property("FormTrustReasonApprovedPerson") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonApprovedPerson"); + + b1.Property("FormTrustReasonForming") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonForming"); + + b1.Property("FormTrustReasonFreedom") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonFreedom"); + + b1.Property("FormTrustReasonGeoAreas") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonGeoAreas"); + + b1.Property("FormTrustReasonImproveTeaching") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonImproveTeaching"); + + b1.Property("FormTrustReasonVision") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonVision"); + + b1.Property("TrustApproverEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustApproverEmail"); + + b1.Property("TrustApproverName") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustApproverName"); + + b1.HasKey("FormTrustId"); + + b1.ToTable("ApplicationFormTrust", "academisation"); + + b1.WithOwner() + .HasForeignKey("FormTrustId"); + }); + + b.Navigation("TrustDetails") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", null) + .WithMany("KeyPeople") + .HasForeignKey("ApplicationFormTrustId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPersonRole", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", null) + .WithMany("Roles") + .HasForeignKey("ApplicationFormTrustKeyPersonRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDecisionDetails", "AdvisoryBoardDecisionDetails", b1 => + { + b1.Property("ConversionAdvisoryBoardDecisionId") + .HasColumnType("int"); + + b1.Property("AcademyOrderDate") + .HasColumnType("datetime2") + .HasColumnName("AcademyOrderDate"); + + b1.Property("AdvisoryBoardDecisionDate") + .HasColumnType("datetime2") + .HasColumnName("AdvisoryBoardDecisionDate"); + + b1.Property("ApprovedConditionsDetails") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApprovedConditionsDetails"); + + b1.Property("ApprovedConditionsSet") + .HasColumnType("bit") + .HasColumnName("ApprovedConditionsSet"); + + b1.Property("ConversionProjectId") + .HasColumnType("int") + .HasColumnName("ConversionProjectId"); + + b1.Property("Decision") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Decision"); + + b1.Property("DecisionMadeBy") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("DecisionMadeBy"); + + b1.Property("DecisionMakerName") + .HasColumnType("nvarchar(max)") + .HasColumnName("DecisionMakerName"); + + b1.Property("TransferProjectId") + .HasColumnType("int") + .HasColumnName("TransferProjectId"); + + b1.HasKey("ConversionAdvisoryBoardDecisionId"); + + b1.ToTable("ConversionAdvisoryBoardDecision", "academisation"); + + b1.WithOwner() + .HasForeignKey("ConversionAdvisoryBoardDecisionId"); + }); + + b.Navigation("AdvisoryBoardDecisionDetails") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDAORevokedReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DaoRevokedReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeclinedReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DeclinedReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeferredReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DeferredReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardWithdrawnReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("WithdrawnReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectNote", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", null) + .WithMany("Notes") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.FormAMatProjectAggregate.FormAMatProject", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b1 => + { + b1.Property("FormAMatProjectId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b1.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b1.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b1.HasKey("FormAMatProjectId"); + + b1.ToTable("FormAMatProject", "academisation"); + + b1.WithOwner() + .HasForeignKey("FormAMatProjectId"); + }); + + b.Navigation("AssignedUser"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectDetails", "Details", b1 => + { + b1.Property("ProjectId") + .HasColumnType("int"); + + b1.Property("AcademyTypeAndRoute") + .HasColumnType("nvarchar(max)") + .HasColumnName("AcademyTypeAndRoute"); + + b1.Property("ActualPupilNumbers") + .HasColumnType("int") + .HasColumnName("ActualPupilNumbers"); + + b1.Property("AgeRange") + .HasColumnType("nvarchar(max)") + .HasColumnName("AgeRange"); + + b1.Property("AnnexBFormReceived") + .HasColumnType("bit") + .HasColumnName("AnnexBFormReceived"); + + b1.Property("AnnexBFormUrl") + .HasColumnType("nvarchar(max)") + .HasColumnName("AnnexBFormUrl"); + + b1.Property("ApplicationReceivedDate") + .HasColumnType("datetime2") + .HasColumnName("ApplicationReceivedDate"); + + b1.Property("ApplicationReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApplicationReferenceNumber"); + + b1.Property("AssignedDate") + .HasColumnType("datetime2") + .HasColumnName("AssignedDate"); + + b1.Property("Author") + .HasColumnType("nvarchar(max)") + .HasColumnName("Author"); + + b1.Property("BaselineDate") + .HasColumnType("datetime2") + .HasColumnName("BaselineDate"); + + b1.Property("Capacity") + .HasColumnType("int") + .HasColumnName("Capacity"); + + b1.Property("CapitalCarryForwardAtEndMarchCurrentYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("CapitalCarryForwardAtEndMarchCurrentYear"); + + b1.Property("CapitalCarryForwardAtEndMarchNextYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("CapitalCarryForwardAtEndMarchNextYear"); + + b1.Property("ClearedBy") + .HasColumnType("nvarchar(max)") + .HasColumnName("ClearedBy"); + + b1.Property("Consultation") + .HasColumnType("nvarchar(max)") + .HasColumnName("Consultation"); + + b1.Property("ConversionSupportGrantAmount") + .HasColumnType("decimal(18,2)") + .HasColumnName("ConversionSupportGrantAmount"); + + b1.Property("ConversionSupportGrantAmountChanged") + .HasColumnType("bit") + .HasColumnName("ConversionSupportGrantAmountChanged"); + + b1.Property("ConversionSupportGrantChangeReason") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantChangeReason"); + + b1.Property("ConversionSupportGrantEnvironmentalImprovementGrant") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantEnvironmentalImprovementGrant"); + + b1.Property("ConversionSupportGrantNumberOfSites") + .HasColumnType("nvarchar(max)"); + + b1.Property("ConversionSupportGrantType") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantType"); + + b1.Property("DaoPackSentDate") + .HasColumnType("datetime2") + .HasColumnName("DaoPackSentDate"); + + b1.Property("DiocesanConsent") + .HasColumnType("nvarchar(max)") + .HasColumnName("DiocesanConsent"); + + b1.Property("DiocesanTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("DiocesanTrust"); + + b1.Property("DistanceFromSchoolToTrustHeadquarters") + .HasColumnType("decimal(18,2)") + .HasColumnName("DistanceFromSchoolToTrustHeadquarters"); + + b1.Property("DistanceFromSchoolToTrustHeadquartersAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("DistanceFromSchoolToTrustHeadquartersAdditionalInformation"); + + b1.Property("EducationalAttendanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b1.Property("EndOfCurrentFinancialYear") + .HasColumnType("datetime2") + .HasColumnName("EndOfCurrentFinancialYear"); + + b1.Property("EndOfNextFinancialYear") + .HasColumnType("datetime2") + .HasColumnName("EndOfNextFinancialYear"); + + b1.Property("ExternalApplicationFormSaved") + .HasColumnType("bit") + .HasColumnName("ExternalApplicationFormSaved"); + + b1.Property("ExternalApplicationFormUrl") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExternalApplicationFormUrl"); + + b1.Property("FinancialDeficit") + .HasColumnType("nvarchar(max)") + .HasColumnName("FinancialDeficit"); + + b1.Property("Form7Received") + .HasColumnType("nvarchar(max)") + .HasColumnName("Form7Received"); + + b1.Property("Form7ReceivedDate") + .HasColumnType("datetime2") + .HasColumnName("Form7ReceivedDate"); + + b1.Property("FoundationConsent") + .HasColumnType("nvarchar(max)") + .HasColumnName("FoundationConsent"); + + b1.Property("GoverningBodyResolution") + .HasColumnType("nvarchar(max)") + .HasColumnName("GoverningBodyResolution"); + + b1.Property("HeadTeacherBoardDate") + .HasColumnType("datetime2") + .HasColumnName("HeadTeacherBoardDate"); + + b1.Property("IfdPipelineId") + .HasColumnType("int") + .HasColumnName("IfdPipelineId"); + + b1.Property("IsFormAMat") + .HasColumnType("bit") + .HasColumnName("IsFormAMat"); + + b1.Property("KeyStage2PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage2PerformanceAdditionalInformation"); + + b1.Property("KeyStage4PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage4PerformanceAdditionalInformation"); + + b1.Property("KeyStage5PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage5PerformanceAdditionalInformation"); + + b1.Property("LegalRequirementsSectionComplete") + .HasColumnType("bit") + .HasColumnName("LegalRequirementsSectionComplete"); + + b1.Property("LocalAuthority") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthority"); + + b1.Property("LocalAuthorityInformationTemplateComments") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthorityInformationTemplateComments"); + + b1.Property("LocalAuthorityInformationTemplateLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthorityInformationTemplateLink"); + + b1.Property("LocalAuthorityInformationTemplateReturnedDate") + .HasColumnType("datetime2") + .HasColumnName("LocalAuthorityInformationTemplateReturnedDate"); + + b1.Property("LocalAuthorityInformationTemplateSectionComplete") + .HasColumnType("bit") + .HasColumnName("LocalAuthorityInformationTemplateSectionComplete"); + + b1.Property("LocalAuthorityInformationTemplateSentDate") + .HasColumnType("datetime2") + .HasColumnName("LocalAuthorityInformationTemplateSentDate"); + + b1.Property("MemberOfParliamentNameAndParty") + .HasColumnType("nvarchar(max)") + .HasColumnName("MemberOfParliamentNameAndParty"); + + b1.Property("NameOfTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("NameOfTrust"); + + b1.Property("NumberOfAlternativeProvisionPlaces") + .HasColumnType("int"); + + b1.Property("NumberOfFundedResidentialPlaces") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfMedicalPlaces") + .HasColumnType("int"); + + b1.Property("NumberOfPlacesFundedFor") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfPost16Places") + .HasColumnType("int"); + + b1.Property("NumberOfResidentialPlaces") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfSENUnitPlaces") + .HasColumnType("int"); + + b1.Property("PartOfPfiScheme") + .HasColumnType("nvarchar(max)") + .HasColumnName("PartOfPfiScheme"); + + b1.Property("PercentageFreeSchoolMeals") + .HasColumnType("decimal(18,2)") + .HasColumnName("PercentageFreeSchoolMeals"); + + b1.Property("PercentageOfGoodOrOutstandingSchoolsInTheDiocesanTrust") + .HasColumnType("decimal(18,2)") + .HasColumnName("PercentageOfGoodOrOutstandingSchoolsInTheDiocesanTrust"); + + b1.Property("PfiSchemeDetails") + .HasColumnType("nvarchar(max)") + .HasColumnName("PfiSchemeDetails"); + + b1.Property("PreviousHeadTeacherBoardDate") + .HasColumnType("datetime2") + .HasColumnName("PreviousHeadTeacherBoardDate"); + + b1.Property("PreviousHeadTeacherBoardDateQuestion") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousHeadTeacherBoardDateQuestion"); + + b1.Property("PreviousHeadTeacherBoardLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousHeadTeacherBoardLink"); + + b1.Property("ProjectDatesSectionComplete") + .HasColumnType("bit") + .HasColumnName("ProjectDatesSectionComplete"); + + b1.Property("ProjectStatus") + .HasColumnType("nvarchar(max)") + .HasColumnName("ProjectStatus"); + + b1.Property("ProjectedRevenueBalanceAtEndMarchNextYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("ProjectedRevenueBalanceAtEndMarchNextYear"); + + b1.Property("ProposedConversionDate") + .HasColumnType("datetime2") + .HasColumnName("ProposedAcademyOpeningDate"); + + b1.Property("PublishedAdmissionNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("PublishedAdmissionNumber"); + + b1.Property("PupilsAttendingGroupMedicalAndHealthNeeds") + .HasColumnType("bit"); + + b1.Property("PupilsAttendingGroupPermanentlyExcluded") + .HasColumnType("bit"); + + b1.Property("PupilsAttendingGroupTeenageMums") + .HasColumnType("bit"); + + b1.Property("RationaleForProject") + .HasColumnType("nvarchar(max)") + .HasColumnName("RationaleForProject"); + + b1.Property("RationaleForTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("RationaleForTrust"); + + b1.Property("RationaleSectionComplete") + .HasColumnType("bit") + .HasColumnName("RationaleSectionComplete"); + + b1.Property("RecommendationForProject") + .HasColumnType("nvarchar(max)") + .HasColumnName("RecommendationForProject"); + + b1.Property("Region") + .HasColumnType("nvarchar(max)") + .HasColumnName("Region"); + + b1.Property("RevenueCarryForwardAtEndMarchCurrentYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("RevenueCarryForwardAtEndMarchCurrentYear"); + + b1.Property("RisksAndIssues") + .HasColumnType("nvarchar(max)") + .HasColumnName("RisksAndIssues"); + + b1.Property("RisksAndIssuesSectionComplete") + .HasColumnType("bit") + .HasColumnName("RisksAndIssuesSectionComplete"); + + b1.Property("SchoolAndTrustInformationSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolAndTrustInformationSectionComplete"); + + b1.Property("SchoolBudgetInformationAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolBudgetInformationAdditionalInformation"); + + b1.Property("SchoolBudgetInformationSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolBudgetInformationSectionComplete"); + + b1.Property("SchoolName") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolName"); + + b1.Property("SchoolOverviewSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolOverviewSectionComplete"); + + b1.Property("SchoolPerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPerformanceAdditionalInformation"); + + b1.Property("SchoolPhase") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPhase"); + + b1.Property("SchoolPupilForecastsAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPupilForecastsAdditionalInformation"); + + b1.Property("SchoolType") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolType"); + + b1.Property("SponsorName") + .HasColumnType("nvarchar(max)") + .HasColumnName("SponsorName"); + + b1.Property("SponsorReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("SponsorReferenceNumber"); + + b1.Property("TrustReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustReferenceNumber"); + + b1.Property("TrustUkprn") + .HasColumnType("int"); + + b1.Property("Urn") + .HasColumnType("int") + .HasColumnName("Urn"); + + b1.Property("Version") + .HasColumnType("nvarchar(max)") + .HasColumnName("Version"); + + b1.Property("ViabilityIssues") + .HasColumnType("nvarchar(max)") + .HasColumnName("ViabilityIssues"); + + b1.Property("YearOneProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearOneProjectedCapacity"); + + b1.Property("YearOneProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearOneProjectedPupilNumbers"); + + b1.Property("YearThreeProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearThreeProjectedCapacity"); + + b1.Property("YearThreeProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearThreeProjectedPupilNumbers"); + + b1.Property("YearTwoProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearTwoProjectedCapacity"); + + b1.Property("YearTwoProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearTwoProjectedPupilNumbers"); + + b1.HasKey("ProjectId"); + + b1.ToTable("Project", "academisation"); + + b1.WithOwner() + .HasForeignKey("ProjectId"); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b2 => + { + b2.Property("ProjectDetailsProjectId") + .HasColumnType("int"); + + b2.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b2.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b2.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b2.HasKey("ProjectDetailsProjectId"); + + b2.ToTable("Project", "academisation"); + + b2.WithOwner() + .HasForeignKey("ProjectDetailsProjectId"); + }); + + b1.Navigation("AssignedUser"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.SchoolImprovementPlan", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", null) + .WithMany("SchoolImprovementPlans") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate.ProjectGroup", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b1 => + { + b1.Property("ProjectGroupId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b1.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b1.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b1.HasKey("ProjectGroupId"); + + b1.ToTable("ProjectGroups", "academisation"); + + b1.WithOwner() + .HasForeignKey("ProjectGroupId"); + }); + + b.Navigation("AssignedUser"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.IntendedTransferBenefit", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", null) + .WithMany("IntendedTransferBenefits") + .HasForeignKey("TransferProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferringAcademy", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", null) + .WithMany("TransferringAcademies") + .HasForeignKey("TransferProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.Navigation("Contributors"); + + b.Navigation("Schools"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.Navigation("Leases"); + + b.Navigation("Loans"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.Navigation("KeyPeople"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.Navigation("DaoRevokedReasons"); + + b.Navigation("DeclinedReasons"); + + b.Navigation("DeferredReasons"); + + b.Navigation("WithdrawnReasons"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.Navigation("Notes"); + + b.Navigation("SchoolImprovementPlans"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", b => + { + b.Navigation("IntendedTransferBenefits"); + + b.Navigation("TransferringAcademies"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Dfe.Academies.Academisation.Data/Migrations/20241023151338_add-trust-reference-number-seq.cs b/Dfe.Academies.Academisation.Data/Migrations/20241023151338_add-trust-reference-number-seq.cs new file mode 100644 index 000000000..9657fbac8 --- /dev/null +++ b/Dfe.Academies.Academisation.Data/Migrations/20241023151338_add-trust-reference-number-seq.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Dfe.Academies.Academisation.Data.Migrations +{ + /// + public partial class addtrustreferencenumberseq : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateSequence( + name: "TrustReferenceNumberSeq", + schema: "academisation"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropSequence( + name: "TrustReferenceNumberSeq", + schema: "academisation"); + } + } +} diff --git a/Dfe.Academies.Academisation.Data/Migrations/AcademisationContextModelSnapshot.cs b/Dfe.Academies.Academisation.Data/Migrations/AcademisationContextModelSnapshot.cs index 3e2183996..bc37d319e 100644 --- a/Dfe.Academies.Academisation.Data/Migrations/AcademisationContextModelSnapshot.cs +++ b/Dfe.Academies.Academisation.Data/Migrations/AcademisationContextModelSnapshot.cs @@ -22,6 +22,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + modelBuilder.HasSequence("TrustReferenceNumberSeq", "academisation"); + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => { b.Property("Id") @@ -732,8 +734,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("ProjectGroupId") .HasColumnType("int"); - b.Property("ProjectSentToComplete") - .HasColumnType("bit"); + b.Property("ProjectSentToCompleteDate") + .HasColumnType("datetime2"); b.Property("SchoolSharePointId") .HasColumnType("uniqueidentifier"); diff --git a/Dfe.Academies.Academisation.Data/Repositories/ConversionProjectRepository.cs b/Dfe.Academies.Academisation.Data/Repositories/ConversionProjectRepository.cs index 7832c6045..833cf3e86 100644 --- a/Dfe.Academies.Academisation.Data/Repositories/ConversionProjectRepository.cs +++ b/Dfe.Academies.Academisation.Data/Repositories/ConversionProjectRepository.cs @@ -1,12 +1,11 @@  using System.Globalization; -using System.Net.Http.Headers; using Dfe.Academies.Academisation.Domain.ApplicationAggregate; using Dfe.Academies.Academisation.Domain.ProjectAggregate; using Dfe.Academies.Academisation.Domain.SeedWork; using Dfe.Academies.Academisation.IDomain.ProjectAggregate; +using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Internal; namespace Dfe.Academies.Academisation.Data.Repositories { @@ -345,9 +344,39 @@ public async Task SetProjectReadOnly(int id, bool isReadOnly, CancellationToken public async Task> GetProjectsToSendToCompleteAsync(CancellationToken cancellationToken) { - return await this.dbSet.Where(proj => !proj.ProjectSentToComplete && + return await this.dbSet.Where(proj => !proj.ProjectSentToCompleteDate.HasValue && !proj.FormAMatProjectId.HasValue && proj.IsReadOnly).ToListAsync(cancellationToken); } + + public async Task> GetFormAMatProjectsToSendToCompleteAsync(CancellationToken cancellationToken) + { + return await this.dbSet.Where(proj => !proj.ProjectSentToCompleteDate.HasValue && + proj.FormAMatProjectId.HasValue && + proj.IsReadOnly).ToListAsync(cancellationToken); + } + + public async Task CreateFormAMatProject(IProject project) + { + string? trustReferenceNumber; + + // This has been written to allow the integration tests to run as they use sqlite + if (context.Database.ProviderName == "Microsoft.EntityFrameworkCore.Sqlite") + { + trustReferenceNumber = $"TR{project.Id:D5}"; ; + } + else + { + var p = new SqlParameter("@result", System.Data.SqlDbType.Int); + p.Direction = System.Data.ParameterDirection.Output; + + await context.Database.ExecuteSqlRawAsync($"set @result = NEXT VALUE FOR {AcademisationContext.DEFAULT_SCHEMA}.TrustReferenceNumberSeq", p); + trustReferenceNumber = $"TR{(int)p.Value:D5}"; + } + + project.SetIncomingTrust(trustReferenceNumber, project.Details.NameOfTrust); + + Insert(project as Project); + } } } diff --git a/Dfe.Academies.Academisation.Data/Repositories/TransferProjectRepository.cs b/Dfe.Academies.Academisation.Data/Repositories/TransferProjectRepository.cs index 7a8a8c401..2c4952e86 100644 --- a/Dfe.Academies.Academisation.Data/Repositories/TransferProjectRepository.cs +++ b/Dfe.Academies.Academisation.Data/Repositories/TransferProjectRepository.cs @@ -137,5 +137,12 @@ public async Task> GetProjectsToSendToCompleteAsyn return await projects.Where(y => y.IsFormAMat != true).ToListAsync(cancellationToken); } + + public async Task> GetFormAMatProjectsToSendToCompleteAsync(CancellationToken cancellationToken) + { + var projects = this.dbSet.Include(y => y.TransferringAcademies).Where(proj => proj.TransferringAcademies.Any(x => !x.ProjectSentToComplete) && proj.IsReadOnly); + + return await projects.Where(y => y.IsFormAMat == true).ToListAsync(cancellationToken); + } } } diff --git a/Dfe.Academies.Academisation.Domain/ProjectAggregate/IConversionProjectRepository.cs b/Dfe.Academies.Academisation.Domain/ProjectAggregate/IConversionProjectRepository.cs index 5314bee00..827b366a5 100644 --- a/Dfe.Academies.Academisation.Domain/ProjectAggregate/IConversionProjectRepository.cs +++ b/Dfe.Academies.Academisation.Domain/ProjectAggregate/IConversionProjectRepository.cs @@ -29,4 +29,7 @@ public interface IConversionProjectRepository : IRepository, IGenericRe Task> GetConversionProjectsByProjectGroupIdAsync(int? projectGroupId, CancellationToken cancellationToken = default); Task> GetProjectsByIdsAsync(IEnumerable projectIds, CancellationToken cancellationToken); Task> GetProjectsToSendToCompleteAsync(CancellationToken cancellationToken); + Task> GetFormAMatProjectsToSendToCompleteAsync(CancellationToken cancellationToken); + + Task CreateFormAMatProject(IProject project); } diff --git a/Dfe.Academies.Academisation.Domain/ProjectAggregate/Project.cs b/Dfe.Academies.Academisation.Domain/ProjectAggregate/Project.cs index ed4cc2bb3..ca2017f7d 100644 --- a/Dfe.Academies.Academisation.Domain/ProjectAggregate/Project.cs +++ b/Dfe.Academies.Academisation.Domain/ProjectAggregate/Project.cs @@ -48,7 +48,7 @@ public Project(int id, ProjectDetails projectDetails, DateTime? createdOn = null public ProjectDetails Details { get; private set; } - public bool ProjectSentToComplete { get; private set; } = false; + public DateTime? ProjectSentToCompleteDate { get; private set; } = null; public bool IsReadOnly { get; set; } = false; @@ -565,9 +565,9 @@ public void SetDeletedAt() DeletedAt = DateTime.UtcNow; } - public void SetProjectSentToComplete() + public void SetProjectSentToCompleteDate(DateTime dateSent) { - ProjectSentToComplete = true; + ProjectSentToCompleteDate = dateSent; } public void SetIsReadOnly(bool isReadOnly) { diff --git a/Dfe.Academies.Academisation.Domain/TransferProjectAggregate/ITransferProjectRepository.cs b/Dfe.Academies.Academisation.Domain/TransferProjectAggregate/ITransferProjectRepository.cs index 0099ab9a1..eff92379b 100644 --- a/Dfe.Academies.Academisation.Domain/TransferProjectAggregate/ITransferProjectRepository.cs +++ b/Dfe.Academies.Academisation.Domain/TransferProjectAggregate/ITransferProjectRepository.cs @@ -14,5 +14,6 @@ public interface ITransferProjectRepository : IRepository, IGen Task> GetProjectsByProjectGroupIdAsync(int? projectGroupId, CancellationToken cancellationToken); Task> GetProjectsToSendToCompleteAsync(CancellationToken cancellationToken); + Task> GetFormAMatProjectsToSendToCompleteAsync(CancellationToken cancellationToken); } } diff --git a/Dfe.Academies.Academisation.Domain/TransferProjectAggregate/TransferringAcademy.cs b/Dfe.Academies.Academisation.Domain/TransferProjectAggregate/TransferringAcademy.cs index d7d9a4548..a8e70a405 100644 --- a/Dfe.Academies.Academisation.Domain/TransferProjectAggregate/TransferringAcademy.cs +++ b/Dfe.Academies.Academisation.Domain/TransferProjectAggregate/TransferringAcademy.cs @@ -82,5 +82,9 @@ public void SetProjectSentToComplete() { ProjectSentToComplete = true; } + + public static TransferringAcademy Create(int transferProjectId, string? incomingTrustUkprn, string? incomingTrustName, string outgoingAcademyUkprn, string? region, string? localAuthority) { + return new TransferringAcademy(incomingTrustUkprn, incomingTrustName, outgoingAcademyUkprn, region, localAuthority) { TransferProjectId = transferProjectId }; + } } } diff --git a/Dfe.Academies.Academisation.IDomain/ProjectAggregate/IProject.cs b/Dfe.Academies.Academisation.IDomain/ProjectAggregate/IProject.cs index 8652631c2..78c3821ec 100644 --- a/Dfe.Academies.Academisation.IDomain/ProjectAggregate/IProject.cs +++ b/Dfe.Academies.Academisation.IDomain/ProjectAggregate/IProject.cs @@ -13,7 +13,7 @@ public interface IProject public Guid? ApplicationSharePointId { get; } public int? FormAMatProjectId { get; } public int? ProjectGroupId { get; } - public bool ProjectSentToComplete { get; } + public DateTime? ProjectSentToCompleteDate { get; } public bool IsReadOnly { get; } DateTime CreatedOn { get; } DateTime LastModifiedOn { get; } @@ -64,7 +64,7 @@ void AddSchoolImprovementPlan(List arrangedBy, void UpdateSchoolImprovementPlan(int id, List arrangedBy, string? arrangedByOther, string providedBy, DateTime startDate, SchoolImprovementPlanExpectedEndDate expectedEndDate, DateTime? expectedEndDateOther, SchoolImprovementPlanConfidenceLevel confidenceLevel, string? planComments); public void SetProjectDates(DateTime? advisoryBoardDate, DateTime? previousAdvisoryBoard, DateTime? proposedConversionDate, bool? projectDatesSectionComplete, List? reasonsChanged, string? changedBy); - void SetProjectSentToComplete(); + void SetProjectSentToCompleteDate(DateTime dateSent); } diff --git a/Dfe.Academies.Academisation.IService/ServiceModels/Complete/CompleteConversionProjectServiceModel.cs b/Dfe.Academies.Academisation.IService/ServiceModels/Complete/CompleteConversionProjectServiceModel.cs new file mode 100644 index 000000000..f1041c803 --- /dev/null +++ b/Dfe.Academies.Academisation.IService/ServiceModels/Complete/CompleteConversionProjectServiceModel.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices.JavaScript; +using System.Text; +using System.Threading.Tasks; + +namespace Dfe.Academies.Academisation.IService.ServiceModels.Complete +{ + public record CompleteConversionProjectServiceModel( + int urn, + string? advisory_board_date, + string? advisory_board_conditions, + string? provisional_conversion_date, + bool directive_academy_order, + string? created_by_email, + string? created_by_first_name, + string? created_by_last_name, + int? prepare_id, + string? group_id, + int? incoming_trust_ukprn); + + public record CompleteFormAMatConversionProjectServiceModel( + int urn, + string? advisory_board_date, + string? advisory_board_conditions, + string? provisional_conversion_date, + bool directive_academy_order, + string? created_by_email, + string? created_by_first_name, + string? created_by_last_name, + int? prepare_id, + string? group_id, + string new_trust_reference_number, + string new_trust_name); + + public record CompleteTransferProjectServiceModel( + int urn, + string? advisory_board_date, + string? advisory_board_conditions, + string? provisional_transfer_date, + bool? inadequate_ofsted, + bool? financial_safeguarding_governance_issues, + bool? outgoing_trust_to_close, + string? created_by_email, + string? created_by_first_name, + string? created_by_last_name, + int? prepare_id, + string? group_id, + int? incoming_trust_ukprn, + int? outgoing_trust_ukprn); + + public record CompleteFormAMatTransferProjectServiceModel( + int urn, + string? advisory_board_date, + string? advisory_board_conditions, + string? provisional_transfer_date, + bool? inadequate_ofsted, + bool? financial_safeguarding_governance_issues, + int? outgoing_trust_ukprn, + bool? outgoing_trust_to_close, + string? created_by_email, + string? created_by_first_name, + string? created_by_last_name, + int? prepare_id, + string? group_id, + string new_trust_reference_number, + string new_trust_name + ); + +} diff --git a/Dfe.Academies.Academisation.IService/ServiceModels/Complete/CompleteProjectsServiceModel.cs b/Dfe.Academies.Academisation.IService/ServiceModels/Complete/CompleteProjectsServiceModel.cs deleted file mode 100644 index 375ed9773..000000000 --- a/Dfe.Academies.Academisation.IService/ServiceModels/Complete/CompleteProjectsServiceModel.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices.JavaScript; -using System.Text; -using System.Threading.Tasks; - -namespace Dfe.Academies.Academisation.IService.ServiceModels.Complete -{ - public record CompleteProjectsServiceModel( - int urn, - string? advisory_board_date, - string? advisory_board_conditions, - string? provisional_conversion_date, - bool directive_academy_order, - string? created_by_email, - string? created_by_first_name, - string? created_by_last_name, - int? prepare_id, - string? group_id, - int? incoming_trust_ukprn); - - public record TransfersCompleteProjectsServiceModel( - int urn, - string? advisory_board_date, - string? advisory_board_conditions, - string? provisional_transfer_date, - bool? inadequate_ofsted, - bool? financial_safeguarding_governance_issues, - bool? outgoing_trust_to_close, - string? created_by_email, - string? created_by_first_name, - string? created_by_last_name, - int? prepare_id, - string? group_id, - int? incoming_trust_ukprn, - int? outgoing_trust_ukprn); - -} diff --git a/Dfe.Academies.Academisation.IService/ServiceModels/Legacy/ProjectAggregate/ConversionProjectServiceModel.cs b/Dfe.Academies.Academisation.IService/ServiceModels/Legacy/ProjectAggregate/ConversionProjectServiceModel.cs index 140d067f4..cfd98c20b 100644 --- a/Dfe.Academies.Academisation.IService/ServiceModels/Legacy/ProjectAggregate/ConversionProjectServiceModel.cs +++ b/Dfe.Academies.Academisation.IService/ServiceModels/Legacy/ProjectAggregate/ConversionProjectServiceModel.cs @@ -125,6 +125,10 @@ public ConversionProjectServiceModel(int id, int urn) public DateTime? ProposedConversionDate { get; set; } public bool? ProjectDatesSectionComplete { get; set; } public bool IsReadOnly { get; set; } + + public DateTime? ProjectSentToCompleteDate { get; set; } + + public bool Equals(ConversionProjectServiceModel? other) { @@ -252,7 +256,8 @@ public bool Equals(ConversionProjectServiceModel? other) string.Equals(ExternalApplicationFormUrl, other.ExternalApplicationFormUrl, StringComparison.InvariantCultureIgnoreCase) && ExternalApplicationFormSaved == other.ExternalApplicationFormSaved && - IsReadOnly == other.IsReadOnly; + IsReadOnly == other.IsReadOnly && + ProjectSentToCompleteDate == other.ProjectSentToCompleteDate; } public override bool Equals(object? obj) @@ -368,6 +373,7 @@ public override int GetHashCode() hashCode.Add(ExternalApplicationFormUrl, StringComparer.InvariantCultureIgnoreCase); hashCode.Add(ExternalApplicationFormSaved); hashCode.Add(IsReadOnly); + hashCode.Add(ProjectSentToCompleteDate); return hashCode.ToHashCode(); } } diff --git a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandlerTests.cs b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandlerTests.cs new file mode 100644 index 000000000..b018e355b --- /dev/null +++ b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandlerTests.cs @@ -0,0 +1,215 @@ +using AutoFixture; +using AutoFixture.AutoMoq; +using Dfe.Academies.Academisation.Core; +using Dfe.Academies.Academisation.Core.Utils; +using Dfe.Academies.Academisation.Data.Http; +using Dfe.Academies.Academisation.Domain.ApplicationAggregate; +using Dfe.Academies.Academisation.Domain.CompleteTransmissionLog; +using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; +using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IService.ServiceModels.Complete; +using Dfe.Academies.Academisation.Service.Commands.CompleteProject; +using Dfe.Academisation.CorrelationIdMiddleware; +using Microsoft.Extensions.Logging; +using Moq; +using System.Net; +using Xunit; +using Dfe.Academies.Academisation.IDomain.ProjectAggregate; +using Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate; +using Newtonsoft.Json; +using Moq.Protected; +using Dfe.Academies.Academisation.Domain.Core.ProjectAggregate; +using Dfe.Academies.Academisation.Service.Factories; +using Polly; +using Dfe.Academies.Academisation.Domain.SeedWork; +namespace Dfe.Academies.Academisation.Service.UnitTest.Commands.CompleteProject +{ + public class CreateCompleteConversionProjectsCommandHandlerTests + { + private MockRepository mockRepository; + private Fixture _fixture = new Fixture(); + + private Mock _mockConversionProjectRepository; + private Mock _mockAdvisoryBoardDecisionRepository; + private Mock _mockProjectGroupRepository; + private Mock _mockCompleteTransmissionLogRepository; + private Mock _mockCompleteApiClientFactory; + private Mock _mockDateTimeProvider; + private Mock _mockPollyPolicyFactory; + private CorrelationContext _correlationContext; + private Mock> _mockLogger; + private CreateCompleteConversionProjectsCommandHandler _handler; + + public CreateCompleteConversionProjectsCommandHandlerTests() + { + this.mockRepository = new MockRepository(MockBehavior.Default); + _fixture.Customize(new AutoMoqCustomization() { ConfigureMembers = true }); + + this._mockConversionProjectRepository = this.mockRepository.Create(); + this._mockAdvisoryBoardDecisionRepository = this.mockRepository.Create(); + this._mockProjectGroupRepository = this.mockRepository.Create(); + this._mockCompleteTransmissionLogRepository = this.mockRepository.Create(); + this._mockCompleteApiClientFactory = this.mockRepository.Create(); + this._mockDateTimeProvider = this.mockRepository.Create(); + this._mockPollyPolicyFactory = this.mockRepository.Create(); + this._correlationContext = new CorrelationContext(); + _correlationContext.SetContext(Guid.NewGuid()); + this._mockLogger = this.mockRepository.Create>(); + } + + private CreateCompleteConversionProjectsCommandHandler CreateCreateCompleteConversionProjectsCommandHandler() + { + return new CreateCompleteConversionProjectsCommandHandler( + this._mockConversionProjectRepository.Object, + this._mockAdvisoryBoardDecisionRepository.Object, + this._mockProjectGroupRepository.Object, + this._mockCompleteTransmissionLogRepository.Object, + this._mockCompleteApiClientFactory.Object, + this._mockDateTimeProvider.Object, + this._correlationContext, + this._mockPollyPolicyFactory.Object, + this._mockLogger.Object); + } + + public static Mock CreateHttpMessageHandlerMock(HttpStatusCode code, object content) + { + var handlerMock = new Mock(); + handlerMock.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .ReturnsAsync(() => { + return new HttpResponseMessage(code) + { + Content = new StringContent(JsonConvert.SerializeObject(content)) + }; + }); + return handlerMock; + } + + [Fact] + public async Task Handle_NoConversionProjectsFound_ReturnsNotFoundCommandResult() + { + // Arrange + var command = _fixture.Create(); + _mockConversionProjectRepository.Setup(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync((IEnumerable)null); + + var mockClient = new Mock(); + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.Is(x => x == _correlationContext))) + .Returns(mockClient.Object); + + _handler = CreateCreateCompleteConversionProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + + // Assert + Assert.IsType(result); + // Verifying that the logger was called for the "No projects found" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("No conversion projects found.")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Once); + + // Verifying that the GetProjectsToSendToCompleteAsync was called once + _mockConversionProjectRepository.Verify(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + [Fact] + public async Task Handle_ConversionProjectsExist_SuccessfulResponse_ReturnsCommandSuccessResult() + { + // Arrange + _fixture.Customize(x => x.With(x => x.AssignedUser, new User(Guid.NewGuid(), "TestFirst TestLast", "test@test.com"))); + + var command = _fixture.Create(); + var conversionProjects = _fixture.CreateMany().ToList(); + var advisoryDecision = _fixture.Create(); + var successResponse = _fixture.Create(); + var projectGroup = _fixture.Create(); + var mockContext = new Mock(); + + _mockConversionProjectRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + _mockCompleteTransmissionLogRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + + _mockConversionProjectRepository.Setup(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync(conversionProjects); + _mockAdvisoryBoardDecisionRepository.Setup(repo => repo.GetConversionProjectDecsion(It.IsAny())) + .ReturnsAsync(advisoryDecision); + _mockProjectGroupRepository.Setup(repo => repo.GetById(It.IsAny())) + .ReturnsAsync(projectGroup); + _mockPollyPolicyFactory.Setup(pol => pol.GetCompleteHttpClientRetryPolicy(It.IsAny())) + .Returns(Policy.NoOpAsync()); + + var handlerMock = CreateHttpMessageHandlerMock(HttpStatusCode.Created, successResponse); + var httpClient = new HttpClient(handlerMock.Object) { BaseAddress = new Uri("http://localhost")}; + + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.IsAny())) + .Returns(httpClient); + + _handler = CreateCreateCompleteConversionProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + // Assert + Assert.IsType(result); + + // Verifying that the logger was called for the "Success sending conversion" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("Success sending conversion project to complete with project urn")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Exactly(conversionProjects.Count)); + } + [Fact] + public async Task Handle_ConversionProjectsExist_ErrorResponse_ReturnsCommandSuccessResult() + { + // Arrange + _fixture.Customize(x => x.With(x => x.AssignedUser, new User(Guid.NewGuid(), "TestFirst TestLast", "test@test.com"))); + + var command = _fixture.Create(); + var conversionProjects = _fixture.CreateMany().ToList(); + var advisoryDecision = _fixture.Create(); + var errorResponse = _fixture.Create(); + var projectGroup = _fixture.Create(); + var mockContext = new Mock(); + + _mockConversionProjectRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + _mockCompleteTransmissionLogRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + + _mockConversionProjectRepository.Setup(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync(conversionProjects); + _mockAdvisoryBoardDecisionRepository.Setup(repo => repo.GetConversionProjectDecsion(It.IsAny())) + .ReturnsAsync(advisoryDecision); + _mockProjectGroupRepository.Setup(repo => repo.GetById(It.IsAny())) + .ReturnsAsync(projectGroup); + _mockPollyPolicyFactory.Setup(pol => pol.GetCompleteHttpClientRetryPolicy(It.IsAny())) + .Returns(Policy.NoOpAsync()); + + var handlerMock = CreateHttpMessageHandlerMock(HttpStatusCode.BadRequest, errorResponse); + var httpClient = new HttpClient(handlerMock.Object) { BaseAddress = new Uri("http://localhost") }; + + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.IsAny())) + .Returns(httpClient); + + _handler = CreateCreateCompleteConversionProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + // Assert + Assert.IsType(result); + + // Verifying that the logger was called for the "Success sending conversion" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("Error sending conversion project to complete with project urn")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Exactly(conversionProjects.Count)); + } + } +} + diff --git a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandlerTests.cs b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandlerTests.cs new file mode 100644 index 000000000..a3f117778 --- /dev/null +++ b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandlerTests.cs @@ -0,0 +1,218 @@ +using AutoFixture.AutoMoq; +using AutoFixture; +using Dfe.Academies.Academisation.Core; +using Dfe.Academies.Academisation.Core.Utils; +using Dfe.Academies.Academisation.Data.Http; +using Dfe.Academies.Academisation.Domain.ApplicationAggregate; +using Dfe.Academies.Academisation.Domain.CompleteTransmissionLog; +using Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate; +using Dfe.Academies.Academisation.Domain.Core.ProjectAggregate; +using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; +using Dfe.Academies.Academisation.Domain.SeedWork; +using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IDomain.ProjectAggregate; +using Dfe.Academies.Academisation.IService.ServiceModels.Complete; +using Dfe.Academies.Academisation.Service.Commands.CompleteProject; +using Dfe.Academies.Academisation.Service.Factories; +using Dfe.Academisation.CorrelationIdMiddleware; +using Microsoft.Extensions.Logging; +using Moq; +using Moq.Protected; +using Newtonsoft.Json; +using Polly; +using System.Net; +using Xunit; + +namespace Dfe.Academies.Academisation.Service.UnitTest.Commands.CompleteProject +{ + public class CreateCompleteFormAMatConversionProjectsCommandHandlerTests + { + private MockRepository mockRepository; + private Fixture _fixture = new Fixture(); + + private Mock _mockConversionProjectRepository; + private Mock _mockAdvisoryBoardDecisionRepository; + private Mock _mockProjectGroupRepository; + private Mock _mockCompleteTransmissionLogRepository; + private Mock _mockCompleteApiClientFactory; + private Mock _mockDateTimeProvider; + private Mock _mockPollyPolicyFactory; + private CorrelationContext _correlationContext; + private Mock> _mockLogger; + private CreateCompleteFormAMatConversionProjectsCommandHandler _handler; + + public CreateCompleteFormAMatConversionProjectsCommandHandlerTests() + { + this.mockRepository = new MockRepository(MockBehavior.Default); + _fixture.Customize(new AutoMoqCustomization() { ConfigureMembers = true }); + + this._mockConversionProjectRepository = this.mockRepository.Create(); + this._mockAdvisoryBoardDecisionRepository = this.mockRepository.Create(); + this._mockProjectGroupRepository = this.mockRepository.Create(); + this._mockCompleteTransmissionLogRepository = this.mockRepository.Create(); + this._mockCompleteApiClientFactory = this.mockRepository.Create(); + this._mockDateTimeProvider = this.mockRepository.Create(); + this._mockPollyPolicyFactory = this.mockRepository.Create(); + this._correlationContext = new CorrelationContext(); + _correlationContext.SetContext(Guid.NewGuid()); + this._mockLogger = this.mockRepository.Create>(); + } + + private CreateCompleteFormAMatConversionProjectsCommandHandler CreateCreateCompleteFormAMatConversionProjectsCommandHandler() + { + return new CreateCompleteFormAMatConversionProjectsCommandHandler( + this._mockConversionProjectRepository.Object, + this._mockAdvisoryBoardDecisionRepository.Object, + this._mockProjectGroupRepository.Object, + this._mockCompleteTransmissionLogRepository.Object, + this._mockCompleteApiClientFactory.Object, + this._mockDateTimeProvider.Object, + this._correlationContext, + this._mockPollyPolicyFactory.Object, + this._mockLogger.Object); + } + + public static Mock CreateHttpMessageHandlerMock(HttpStatusCode code, object content) + { + var handlerMock = new Mock(); + handlerMock.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .ReturnsAsync(() => { + return new HttpResponseMessage(code) + { + Content = new StringContent(JsonConvert.SerializeObject(content)) + }; + }); + return handlerMock; + } + + [Fact] + public async Task Handle_NoConversionProjectsFound_ReturnsNotFoundCommandResult() + { + // Arrange + var command = _fixture.Create(); + _mockConversionProjectRepository.Setup(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync((IEnumerable)null); + + var mockClient = new Mock(); + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.Is(x => x == _correlationContext))) + .Returns(mockClient.Object); + + _handler = CreateCreateCompleteFormAMatConversionProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + + // Assert + Assert.IsType(result); + // Verifying that the logger was called for the "No projects found" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("No conversion projects found.")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Once); + + // Verifying that the GetProjectsToSendToCompleteAsync was called once + _mockConversionProjectRepository.Verify(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + [Fact] + public async Task Handle_ConversionProjectsExist_SuccessfulResponse_ReturnsCommandSuccessResult() + { + // Arrange + _fixture.Customize(x => x.With(x => x.AssignedUser, new User(Guid.NewGuid(), "TestFirst TestLast", "test@test.com"))); + + var command = _fixture.Create(); + var conversionProjects = _fixture.CreateMany().ToList(); + var advisoryDecision = _fixture.Create(); + var successResponse = _fixture.Create(); + var projectGroup = _fixture.Create(); + var mockContext = new Mock(); + + _mockConversionProjectRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + _mockCompleteTransmissionLogRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + + _mockConversionProjectRepository.Setup(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync(conversionProjects); + _mockAdvisoryBoardDecisionRepository.Setup(repo => repo.GetConversionProjectDecsion(It.IsAny())) + .ReturnsAsync(advisoryDecision); + _mockProjectGroupRepository.Setup(repo => repo.GetById(It.IsAny())) + .ReturnsAsync(projectGroup); + _mockPollyPolicyFactory.Setup(pol => pol.GetCompleteHttpClientRetryPolicy(It.IsAny())) + .Returns(Policy.NoOpAsync()); + + var handlerMock = CreateHttpMessageHandlerMock(HttpStatusCode.Created, successResponse); + var httpClient = new HttpClient(handlerMock.Object) { BaseAddress = new Uri("http://localhost") }; + + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.IsAny())) + .Returns(httpClient); + + _handler = CreateCreateCompleteFormAMatConversionProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + // Assert + Assert.IsType(result); + + // Verifying that the logger was called for the "Success sending conversion" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("Success sending conversion project to complete with project urn")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Exactly(conversionProjects.Count)); + _mockConversionProjectRepository.Verify(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + [Fact] + public async Task Handle_ConversionProjectsExist_ErrorResponse_ReturnsCommandSuccessResult() + { + // Arrange + _fixture.Customize(x => x.With(x => x.AssignedUser, new User(Guid.NewGuid(), "TestFirst TestLast", "test@test.com"))); + + var command = _fixture.Create(); + var conversionProjects = _fixture.CreateMany().ToList(); + var advisoryDecision = _fixture.Create(); + var errorResponse = _fixture.Create(); + var projectGroup = _fixture.Create(); + var mockContext = new Mock(); + + _mockConversionProjectRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + _mockCompleteTransmissionLogRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + + _mockConversionProjectRepository.Setup(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync(conversionProjects); + _mockAdvisoryBoardDecisionRepository.Setup(repo => repo.GetConversionProjectDecsion(It.IsAny())) + .ReturnsAsync(advisoryDecision); + _mockProjectGroupRepository.Setup(repo => repo.GetById(It.IsAny())) + .ReturnsAsync(projectGroup); + _mockPollyPolicyFactory.Setup(pol => pol.GetCompleteHttpClientRetryPolicy(It.IsAny())) + .Returns(Policy.NoOpAsync()); + + var handlerMock = CreateHttpMessageHandlerMock(HttpStatusCode.BadRequest, errorResponse); + var httpClient = new HttpClient(handlerMock.Object) { BaseAddress = new Uri("http://localhost") }; + + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.IsAny())) + .Returns(httpClient); + + _handler = CreateCreateCompleteFormAMatConversionProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + // Assert + Assert.IsType(result); + + // Verifying that the logger was called for the "Success sending conversion" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("Error sending conversion project to complete with project urn")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Exactly(conversionProjects.Count)); + _mockConversionProjectRepository.Verify(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + } +} + diff --git a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandlerTests.cs b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandlerTests.cs new file mode 100644 index 000000000..a173bb69f --- /dev/null +++ b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandlerTests.cs @@ -0,0 +1,281 @@ +using AutoFixture; +using AutoFixture.AutoMoq; +using AutoFixture.Kernel; +using Dfe.Academies.Academisation.Core; +using Dfe.Academies.Academisation.Core.Utils; +using Dfe.Academies.Academisation.Data.Http; +using Dfe.Academies.Academisation.Domain.CompleteTransmissionLog; +using Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate; +using Dfe.Academies.Academisation.Domain.Core.ProjectAggregate; +using Dfe.Academies.Academisation.Domain.ProjectAggregate; +using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; +using Dfe.Academies.Academisation.Domain.SeedWork; +using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IDomain.ProjectAggregate; +using Dfe.Academies.Academisation.IDomain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IService.Query; +using Dfe.Academies.Academisation.IService.ServiceModels.Complete; +using Dfe.Academies.Academisation.Service.Commands.CompleteProject; +using Dfe.Academies.Academisation.Service.Factories; +using Dfe.Academies.Contracts.V4.Establishments; +using Dfe.Academisation.CorrelationIdMiddleware; +using Microsoft.Extensions.Logging; +using Moq; +using Moq.Protected; +using Newtonsoft.Json; +using Polly; +using System.Net; +using System.Reflection; +using Xunit; + +namespace Dfe.Academies.Academisation.Service.UnitTest.Commands.CompleteProject +{ + public class CreateCompleteFormAMatTransferProjectsCommandHandlerTests + { + private MockRepository mockRepository; + private Fixture _fixture = new Fixture(); + + private Mock _mockTransferProjectRepository; + private Mock _mockAdvisoryBoardDecisionRepository; + private Mock _mockAcademiesQueryService; + private Mock _mockProjectGroupRepository; + private Mock _mockCompleteTransmissionLogRepository; + private Mock _mockCompleteApiClientFactory; + private Mock _mockDateTimeProvider; + private ICorrelationContext _correlationContext; + private Mock _mockPollyPolicyFactory; + private Mock> _mockLogger; + private CreateCompleteFormAMatTransferProjectsCommandHandler _handler; + + public CreateCompleteFormAMatTransferProjectsCommandHandlerTests() + { + this.mockRepository = new MockRepository(MockBehavior.Default); + + this._mockTransferProjectRepository = this.mockRepository.Create(); + this._mockAdvisoryBoardDecisionRepository = this.mockRepository.Create(); + this._mockAcademiesQueryService = this.mockRepository.Create(); + this._mockProjectGroupRepository = this.mockRepository.Create(); + this._mockCompleteTransmissionLogRepository = this.mockRepository.Create(); + this._mockCompleteApiClientFactory = this.mockRepository.Create(); + this._mockDateTimeProvider = this.mockRepository.Create(); + this._mockPollyPolicyFactory = this.mockRepository.Create(); + this._mockLogger = this.mockRepository.Create>(); + + this._correlationContext = new CorrelationContext(); + _correlationContext.SetContext(Guid.NewGuid()); + + _fixture.Customize(new AutoMoqCustomization()); + } + + private CreateCompleteFormAMatTransferProjectsCommandHandler CreateCreateCompleteFormAMatTransferProjectsCommandHandler() + { + return new CreateCompleteFormAMatTransferProjectsCommandHandler( + this._mockTransferProjectRepository.Object, + this._mockAdvisoryBoardDecisionRepository.Object, + this._mockAcademiesQueryService.Object, + this._mockProjectGroupRepository.Object, + this._mockCompleteTransmissionLogRepository.Object, + this._mockCompleteApiClientFactory.Object, + this._mockDateTimeProvider.Object, + this._correlationContext, + this._mockPollyPolicyFactory.Object, + this._mockLogger.Object); + } + + public static Mock CreateHttpMessageHandlerMock(HttpStatusCode code, object content) + { + var handlerMock = new Mock(); + handlerMock.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .ReturnsAsync(() => + { + return new HttpResponseMessage(code) + { + Content = new StringContent(JsonConvert.SerializeObject(content)) + }; + }); + return handlerMock; + } + + [Fact] + public async Task Handle_NoConversionProjectsFound_ReturnsNotFoundCommandResult() + { + // Arrange + var command = _fixture.Create(); + _mockTransferProjectRepository.Setup(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync((IEnumerable)null); + + var mockClient = new Mock(); + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.Is(x => x == _correlationContext))) + .Returns(mockClient.Object); + + _handler = CreateCreateCompleteFormAMatTransferProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + + // Assert + Assert.IsType(result); + // Verifying that the logger was called for the "No transfer projects found" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("No transfer projects found.")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Once); + + // Verifying that the GetFormAMatProjectsToSendToCompleteAsync was called once + _mockTransferProjectRepository.Verify(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + [Fact] + public async Task Handle_ConversionProjectsExist_SuccessfulResponse_ReturnsCommandSuccessResult() + { + // Arrange + var command = _fixture.Create(); + var transferProjects = _fixture.CreateMany().ToList(); + var establishments = new List(); + + foreach (var transferProject in transferProjects) + { + Mock.Get(transferProject).Setup(x => x.Id).Returns(_fixture.Create()); + Mock.Get(transferProject).Setup(x => x.SpecificReasonsForTransfer).Returns(new List { "Forced" }); + Mock.Get(transferProject).Setup(x => x.AssignedUserEmailAddress).Returns("test@test.com"); + Mock.Get(transferProject).Setup(x => x.AssignedUserFullName).Returns("TestFirst TestLast"); + Mock.Get(transferProject).Setup(x => x.AssignedUserId).Returns(Guid.NewGuid()); + Mock.Get(transferProject).Setup(x => x.OutgoingTrustUkprn).Returns("111111"); + Mock.Get(transferProject).Setup(x => x.HtbDate).Returns(DateTime.Now); + Mock.Get(transferProject).Setup(x => x.TargetDateForTransfer).Returns(DateTime.Now); + + var transferringAcademies = _fixture.CreateMany().ToList(); + + foreach (var academy in transferringAcademies) { + Mock.Get(academy).Setup(x => x.TransferProjectId).Returns(transferProject.Id); + Mock.Get(academy).Setup(x => x.OutgoingAcademyUkprn).Returns(_fixture.Create()); + Mock.Get(academy).Setup(x => x.IncomingTrustName).Returns(_fixture.Create()); + establishments.Add(new EstablishmentDto { Urn = "101010", Ukprn = academy.OutgoingAcademyUkprn }); + } + + Mock.Get(transferProject).Setup(x => x.TransferringAcademies).Returns(transferringAcademies); + } + + var advisoryDecision = _fixture.Create(); + var successResponse = _fixture.Create(); + var projectGroup = _fixture.Create(); + var mockContext = new Mock(); + + _mockTransferProjectRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + _mockCompleteTransmissionLogRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + + _mockTransferProjectRepository.Setup(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync(transferProjects); + _mockAdvisoryBoardDecisionRepository.Setup(repo => repo.GetTransferProjectDecsion(It.IsAny())) + .ReturnsAsync(advisoryDecision); + _mockProjectGroupRepository.Setup(repo => repo.GetById(It.IsAny())) + .ReturnsAsync(projectGroup); + _mockAcademiesQueryService.Setup(x => x.GetBulkEstablishmentsByUkprn(It.IsAny>())).ReturnsAsync(establishments); + _mockPollyPolicyFactory.Setup(pol => pol.GetCompleteHttpClientRetryPolicy(It.IsAny())) + .Returns(Policy.NoOpAsync()); + + var handlerMock = CreateHttpMessageHandlerMock(HttpStatusCode.Created, successResponse); + var httpClient = new HttpClient(handlerMock.Object) { BaseAddress = new Uri("http://localhost") }; + + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.IsAny())) + .Returns(httpClient); + + _handler = CreateCreateCompleteFormAMatTransferProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + // Assert + Assert.IsType(result); + + // Verifying that the logger was called for the "Success sending conversion" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("Success sending transfer to complete with project urn")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Exactly(transferProjects.SelectMany(x => x.TransferringAcademies).Count())); + + _mockTransferProjectRepository.Verify(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + [Fact] + public async Task Handle_ConversionProjectsExist_ErrorResponse_ReturnsCommandSuccessResult() + { + // Arrange + var transferProjects = _fixture.CreateMany().ToList(); + var establishments = new List(); + + foreach (var transferProject in transferProjects) + { + Mock.Get(transferProject).Setup(x => x.Id).Returns(_fixture.Create()); + Mock.Get(transferProject).Setup(x => x.SpecificReasonsForTransfer).Returns(new List { "Forced" }); + Mock.Get(transferProject).Setup(x => x.AssignedUserEmailAddress).Returns("test@test.com"); + Mock.Get(transferProject).Setup(x => x.AssignedUserFullName).Returns("TestFirst TestLast"); + Mock.Get(transferProject).Setup(x => x.AssignedUserId).Returns(Guid.NewGuid()); + Mock.Get(transferProject).Setup(x => x.OutgoingTrustUkprn).Returns("111111"); + Mock.Get(transferProject).Setup(x => x.HtbDate).Returns(DateTime.Now); + Mock.Get(transferProject).Setup(x => x.TargetDateForTransfer).Returns(DateTime.Now); + + var transferringAcademies = _fixture.CreateMany().ToList(); + + foreach (var academy in transferringAcademies) + { + Mock.Get(academy).Setup(x => x.TransferProjectId).Returns(transferProject.Id); + Mock.Get(academy).Setup(x => x.OutgoingAcademyUkprn).Returns(_fixture.Create()); + Mock.Get(academy).Setup(x => x.IncomingTrustName).Returns(_fixture.Create()); + establishments.Add(new EstablishmentDto { Urn = "101010", Ukprn = academy.OutgoingAcademyUkprn }); + } + + Mock.Get(transferProject).Setup(x => x.TransferringAcademies).Returns(transferringAcademies); + } + + var command = _fixture.Create(); + var advisoryDecision = _fixture.Create(); + var errorResponse = _fixture.Create(); + var projectGroup = _fixture.Create(); + var mockContext = new Mock(); + + _mockTransferProjectRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + _mockCompleteTransmissionLogRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + + _mockTransferProjectRepository.Setup(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync(transferProjects); + _mockAdvisoryBoardDecisionRepository.Setup(repo => repo.GetTransferProjectDecsion(It.IsAny())) + .ReturnsAsync(advisoryDecision); + _mockProjectGroupRepository.Setup(repo => repo.GetById(It.IsAny())) + .ReturnsAsync(projectGroup); + _mockAcademiesQueryService.Setup(x => x.GetBulkEstablishmentsByUkprn(It.IsAny>())).ReturnsAsync(establishments); + _mockPollyPolicyFactory.Setup(pol => pol.GetCompleteHttpClientRetryPolicy(It.IsAny())) + .Returns(Policy.NoOpAsync()); + + var handlerMock = CreateHttpMessageHandlerMock(HttpStatusCode.BadRequest, errorResponse); + var httpClient = new HttpClient(handlerMock.Object) { BaseAddress = new Uri("http://localhost") }; + + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.IsAny())) + .Returns(httpClient); + + _handler = CreateCreateCompleteFormAMatTransferProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + // Assert + Assert.IsType(result); + + // Verifying that the logger was called for the "Success sending conversion" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("Error sending transfer project to complete with project urn")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Exactly(transferProjects.SelectMany(x => x.TransferringAcademies).Count())); + + // Verifying that the GetFormAMatProjectsToSendToCompleteAsync was called once + _mockTransferProjectRepository.Verify(repo => repo.GetFormAMatProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + } +} + diff --git a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandlerTests.cs b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandlerTests.cs new file mode 100644 index 000000000..8d4bfead1 --- /dev/null +++ b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandlerTests.cs @@ -0,0 +1,276 @@ +using AutoFixture.AutoMoq; +using AutoFixture; +using Dfe.Academies.Academisation.Core; +using System.Net; +using Dfe.Academies.Academisation.Core.Utils; +using Dfe.Academies.Academisation.Data.Http; +using Dfe.Academies.Academisation.Domain.CompleteTransmissionLog; +using Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate; +using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; +using Dfe.Academies.Academisation.Domain.SeedWork; +using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IDomain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IService.Query; +using Dfe.Academies.Academisation.IService.ServiceModels.Complete; +using Dfe.Academies.Academisation.Service.Commands.CompleteProject; +using Dfe.Academies.Academisation.Service.Factories; +using Dfe.Academies.Contracts.V4.Establishments; +using Dfe.Academisation.CorrelationIdMiddleware; +using Microsoft.Extensions.Logging; +using Moq; +using Moq.Protected; +using Newtonsoft.Json; +using Polly; +using Xunit; + +namespace Dfe.Academies.Academisation.Service.UnitTest.Commands.CompleteProject +{ + public class CreateCompleteTransferProjectsCommandHandlerTests + { + private MockRepository mockRepository; + private Fixture _fixture = new Fixture(); + + private Mock _mockTransferProjectRepository; + private Mock _mockAdvisoryBoardDecisionRepository; + private Mock _mockAcademiesQueryService; + private Mock _mockProjectGroupRepository; + private Mock _mockCompleteTransmissionLogRepository; + private Mock _mockCompleteApiClientFactory; + private Mock _mockDateTimeProvider; + private ICorrelationContext _correlationContext; + private Mock _mockPollyPolicyFactory; + private Mock> _mockLogger; + private CreateCompleteTransferProjectsCommandHandler _handler; + + public CreateCompleteTransferProjectsCommandHandlerTests() + { + this.mockRepository = new MockRepository(MockBehavior.Default); + + this._mockTransferProjectRepository = this.mockRepository.Create(); + this._mockAdvisoryBoardDecisionRepository = this.mockRepository.Create(); + this._mockAcademiesQueryService = this.mockRepository.Create(); + this._mockProjectGroupRepository = this.mockRepository.Create(); + this._mockCompleteTransmissionLogRepository = this.mockRepository.Create(); + this._mockCompleteApiClientFactory = this.mockRepository.Create(); + this._mockDateTimeProvider = this.mockRepository.Create(); + this._mockPollyPolicyFactory = this.mockRepository.Create(); + this._mockLogger = this.mockRepository.Create>(); + + this._correlationContext = new CorrelationContext(); + _correlationContext.SetContext(Guid.NewGuid()); + + _fixture.Customize(new AutoMoqCustomization()); + } + + private CreateCompleteTransferProjectsCommandHandler CreateCreateCompleteTransferProjectsCommandHandler() + { + return new CreateCompleteTransferProjectsCommandHandler( + this._mockTransferProjectRepository.Object, + this._mockAdvisoryBoardDecisionRepository.Object, + this._mockAcademiesQueryService.Object, + this._mockProjectGroupRepository.Object, + this._mockCompleteTransmissionLogRepository.Object, + this._mockCompleteApiClientFactory.Object, + this._mockDateTimeProvider.Object, + this._correlationContext, + this._mockPollyPolicyFactory.Object, + this._mockLogger.Object); + } + + public static Mock CreateHttpMessageHandlerMock(HttpStatusCode code, object content) + { + var handlerMock = new Mock(); + handlerMock.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .ReturnsAsync(() => + { + return new HttpResponseMessage(code) + { + Content = new StringContent(JsonConvert.SerializeObject(content)) + }; + }); + return handlerMock; + } + + [Fact] + public async Task Handle_NoConversionProjectsFound_ReturnsNotFoundCommandResult() + { + // Arrange + var command = _fixture.Create(); + _mockTransferProjectRepository.Setup(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync((IEnumerable)null); + + var mockClient = new Mock(); + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.Is(x => x == _correlationContext))) + .Returns(mockClient.Object); + + _handler = CreateCreateCompleteTransferProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + + // Assert + Assert.IsType(result); + // Verifying that the logger was called for the "No transfer projects found" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("No transfer projects found.")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Once); + + // Verifying that the GetFormAMatProjectsToSendToCompleteAsync was called once + _mockTransferProjectRepository.Verify(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + [Fact] + public async Task Handle_ConversionProjectsExist_SuccessfulResponse_ReturnsCommandSuccessResult() + { + // Arrange + var command = _fixture.Create(); + var transferProjects = _fixture.CreateMany().ToList(); + var establishments = new List(); + + foreach (var transferProject in transferProjects) + { + Mock.Get(transferProject).Setup(x => x.Id).Returns(_fixture.Create()); + Mock.Get(transferProject).Setup(x => x.SpecificReasonsForTransfer).Returns(new List { "Forced" }); + Mock.Get(transferProject).Setup(x => x.AssignedUserEmailAddress).Returns("test@test.com"); + Mock.Get(transferProject).Setup(x => x.AssignedUserFullName).Returns("TestFirst TestLast"); + Mock.Get(transferProject).Setup(x => x.AssignedUserId).Returns(Guid.NewGuid()); + Mock.Get(transferProject).Setup(x => x.OutgoingTrustUkprn).Returns("111111"); + Mock.Get(transferProject).Setup(x => x.HtbDate).Returns(DateTime.Now); + Mock.Get(transferProject).Setup(x => x.TargetDateForTransfer).Returns(DateTime.Now); + + var transferringAcademies = _fixture.CreateMany().ToList(); + + foreach (var academy in transferringAcademies) + { + Mock.Get(academy).Setup(x => x.TransferProjectId).Returns(transferProject.Id); + Mock.Get(academy).Setup(x => x.OutgoingAcademyUkprn).Returns(_fixture.Create()); + Mock.Get(academy).Setup(x => x.IncomingTrustUkprn).Returns("101010"); + establishments.Add(new EstablishmentDto { Urn = "101010", Ukprn = academy.OutgoingAcademyUkprn }); + } + + Mock.Get(transferProject).Setup(x => x.TransferringAcademies).Returns(transferringAcademies); + } + + var advisoryDecision = _fixture.Create(); + var successResponse = _fixture.Create(); + var projectGroup = _fixture.Create(); + var mockContext = new Mock(); + + _mockTransferProjectRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + _mockCompleteTransmissionLogRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + + _mockTransferProjectRepository.Setup(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync(transferProjects); + _mockAdvisoryBoardDecisionRepository.Setup(repo => repo.GetTransferProjectDecsion(It.IsAny())) + .ReturnsAsync(advisoryDecision); + _mockProjectGroupRepository.Setup(repo => repo.GetById(It.IsAny())) + .ReturnsAsync(projectGroup); + _mockAcademiesQueryService.Setup(x => x.GetBulkEstablishmentsByUkprn(It.IsAny>())).ReturnsAsync(establishments); + _mockPollyPolicyFactory.Setup(pol => pol.GetCompleteHttpClientRetryPolicy(It.IsAny())) + .Returns(Policy.NoOpAsync()); + + var handlerMock = CreateHttpMessageHandlerMock(HttpStatusCode.Created, successResponse); + var httpClient = new HttpClient(handlerMock.Object) { BaseAddress = new Uri("http://localhost") }; + + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.IsAny())) + .Returns(httpClient); + + _handler = CreateCreateCompleteTransferProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + // Assert + Assert.IsType(result); + + // Verifying that the logger was called for the "Success sending conversion" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("Success sending transfer project to complete with project urn")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Exactly(transferProjects.SelectMany(x => x.TransferringAcademies).Count())); + + _mockTransferProjectRepository.Verify(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + [Fact] + public async Task Handle_ConversionProjectsExist_ErrorResponse_ReturnsCommandSuccessResult() + { + // Arrange + var transferProjects = _fixture.CreateMany().ToList(); + var establishments = new List(); + + foreach (var transferProject in transferProjects) + { + Mock.Get(transferProject).Setup(x => x.Id).Returns(_fixture.Create()); + Mock.Get(transferProject).Setup(x => x.SpecificReasonsForTransfer).Returns(new List { "Forced" }); + Mock.Get(transferProject).Setup(x => x.AssignedUserEmailAddress).Returns("test@test.com"); + Mock.Get(transferProject).Setup(x => x.AssignedUserFullName).Returns("TestFirst TestLast"); + Mock.Get(transferProject).Setup(x => x.AssignedUserId).Returns(Guid.NewGuid()); + Mock.Get(transferProject).Setup(x => x.OutgoingTrustUkprn).Returns("111111"); + Mock.Get(transferProject).Setup(x => x.HtbDate).Returns(DateTime.Now); + Mock.Get(transferProject).Setup(x => x.TargetDateForTransfer).Returns(DateTime.Now); + + var transferringAcademies = _fixture.CreateMany().ToList(); + + foreach (var academy in transferringAcademies) + { + Mock.Get(academy).Setup(x => x.TransferProjectId).Returns(transferProject.Id); + Mock.Get(academy).Setup(x => x.OutgoingAcademyUkprn).Returns(_fixture.Create()); + Mock.Get(academy).Setup(x => x.IncomingTrustUkprn).Returns("101010"); + establishments.Add(new EstablishmentDto { Urn = "101010", Ukprn = academy.OutgoingAcademyUkprn }); + } + + Mock.Get(transferProject).Setup(x => x.TransferringAcademies).Returns(transferringAcademies); + } + + var command = _fixture.Create(); + var advisoryDecision = _fixture.Create(); + var errorResponse = _fixture.Create(); + var projectGroup = _fixture.Create(); + var mockContext = new Mock(); + + _mockTransferProjectRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + _mockCompleteTransmissionLogRepository.Setup(x => x.UnitOfWork).Returns(mockContext.Object); + + _mockTransferProjectRepository.Setup(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny())) + .ReturnsAsync(transferProjects); + _mockAdvisoryBoardDecisionRepository.Setup(repo => repo.GetTransferProjectDecsion(It.IsAny())) + .ReturnsAsync(advisoryDecision); + _mockProjectGroupRepository.Setup(repo => repo.GetById(It.IsAny())) + .ReturnsAsync(projectGroup); + _mockAcademiesQueryService.Setup(x => x.GetBulkEstablishmentsByUkprn(It.IsAny>())).ReturnsAsync(establishments); + _mockPollyPolicyFactory.Setup(pol => pol.GetCompleteHttpClientRetryPolicy(It.IsAny())) + .Returns(Policy.NoOpAsync()); + + var handlerMock = CreateHttpMessageHandlerMock(HttpStatusCode.BadRequest, errorResponse); + var httpClient = new HttpClient(handlerMock.Object) { BaseAddress = new Uri("http://localhost") }; + + _mockCompleteApiClientFactory.Setup(factory => factory.Create(It.IsAny())) + .Returns(httpClient); + + _handler = CreateCreateCompleteTransferProjectsCommandHandler(); + + // Act + var result = await _handler.Handle(command, CancellationToken.None); + // Assert + Assert.IsType(result); + + // Verifying that the logger was called for the "Success sending conversion" case + _mockLogger.Verify(x => x.Log(LogLevel.Information, + // We're checking for an Information log + It.IsAny(), It.Is((v, t) => v.ToString().Contains("Error sending transfer project to complete with project urn")), + // Check if the message contains the expected string + null, + // No exception is expected here + It.IsAny>()), Times.Exactly(transferProjects.SelectMany(x => x.TransferringAcademies).Count())); + + // Verifying that the GetFormAMatProjectsToSendToCompleteAsync was called once + _mockTransferProjectRepository.Verify(repo => repo.GetProjectsToSendToCompleteAsync(It.IsAny()), Times.Once); + } + } +} diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateConversionsCompleteProjectsCommand.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommand.cs similarity index 63% rename from Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateConversionsCompleteProjectsCommand.cs rename to Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommand.cs index d2465e5f5..9d596df0b 100644 --- a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateConversionsCompleteProjectsCommand.cs +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommand.cs @@ -3,7 +3,7 @@ namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject { - public class CreateConversionsCompleteProjectsCommand : IRequest + public class CreateCompleteConversionProjectsCommand : IRequest { } } diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateConversionsCompleteProjectsCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandler.cs similarity index 68% rename from Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateConversionsCompleteProjectsCommandHandler.cs rename to Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandler.cs index 01df09e39..1f76bbd3c 100644 --- a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateConversionsCompleteProjectsCommandHandler.cs +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandler.cs @@ -1,27 +1,21 @@ -using System.Net; -using System.Net.Http.Json; -using System.Text; +using System.Net.Http.Json; using Dfe.Academies.Academisation.Core; using Dfe.Academies.Academisation.Core.Utils; using Dfe.Academies.Academisation.Data.Http; using Dfe.Academies.Academisation.Domain.ApplicationAggregate; using Dfe.Academies.Academisation.Domain.CompleteTransmissionLog; -using Dfe.Academies.Academisation.Domain.FormAMatProjectAggregate; using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; -using Dfe.Academies.Academisation.IDomain.ConversionAdvisoryBoardDecisionAggregate; -using Dfe.Academies.Academisation.IService.Query; using Dfe.Academies.Academisation.IService.ServiceModels.Complete; +using Dfe.Academies.Academisation.Service.Factories; using Dfe.Academies.Academisation.Service.Mappers.CompleteProjects; using Dfe.Academisation.CorrelationIdMiddleware; using MediatR; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Polly; namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject { - public class CreateConversionsCompleteProjectsCommandHandler : IRequestHandler + public class CreateCompleteConversionProjectsCommandHandler : IRequestHandler { private readonly IConversionProjectRepository _conversionProjectRepository; private readonly IAdvisoryBoardDecisionRepository _advisoryBoardDecisionRepository; @@ -29,10 +23,11 @@ public class CreateConversionsCompleteProjectsCommandHandler : IRequestHandler _logger; + private readonly ILogger _logger; private ICorrelationContext _correlationContext; + private readonly IPollyPolicyFactory _pollyPolicyFactory; - public CreateConversionsCompleteProjectsCommandHandler( + public CreateCompleteConversionProjectsCommandHandler( IConversionProjectRepository conversionProjectRepository, IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository, IProjectGroupRepository projectGroupRepository, @@ -40,7 +35,8 @@ public CreateConversionsCompleteProjectsCommandHandler( ICompleteApiClientFactory completeApiClientFactory, IDateTimeProvider dateTimeProvider, ICorrelationContext correlationContext, - ILogger logger) + IPollyPolicyFactory pollyPolicyFactory, + ILogger logger) { _conversionProjectRepository = conversionProjectRepository; _advisoryBoardDecisionRepository = advisoryBoardDecisionRepository; @@ -49,20 +45,15 @@ public CreateConversionsCompleteProjectsCommandHandler( _completeApiClientFactory = completeApiClientFactory; _dateTimeProvider = dateTimeProvider; _correlationContext = correlationContext; + _pollyPolicyFactory = pollyPolicyFactory; _logger = logger; } - public async Task Handle(CreateConversionsCompleteProjectsCommand request, + public async Task Handle(CreateCompleteConversionProjectsCommand request, CancellationToken cancellationToken) { var client = _completeApiClientFactory.Create(_correlationContext); - var retryPolicy = Policy.Handle() // Handle HttpRequestException - .OrResult(r => !r.IsSuccessStatusCode && r.StatusCode != HttpStatusCode.BadRequest) // Retry if response is not successful - .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), - (exception, timeSpan, retryCount, context) => - { - _logger.LogInformation($"Retry {retryCount} after {timeSpan.Seconds} seconds due to: {exception?.Exception?.Message}"); - }); + var retryPolicy = _pollyPolicyFactory.GetCompleteHttpClientRetryPolicy(_logger); var conversionProjects = await _conversionProjectRepository.GetProjectsToSendToCompleteAsync(cancellationToken).ConfigureAwait(false); @@ -74,7 +65,6 @@ public async Task Handle(CreateConversionsCompleteProjectsCommand foreach (var conversionProject in conversionProjects) { - var decision = await _advisoryBoardDecisionRepository.GetConversionProjectDecsion(conversionProject.Id); string? groupReferenceNumber = null; @@ -85,7 +75,7 @@ public async Task Handle(CreateConversionsCompleteProjectsCommand groupReferenceNumber = group.ReferenceNumber; } - var completeObject = CompleteProjectsServiceModelMapper.FromDomain(conversionProject, decision.AdvisoryBoardDecisionDetails.ApprovedConditionsDetails, groupReferenceNumber); + var completeObject = CompleteConversionProjectServiceModelMapper.FromDomain(conversionProject, decision.AdvisoryBoardDecisionDetails.ApprovedConditionsDetails, groupReferenceNumber); var response = await retryPolicy.ExecuteAsync(() => client.PostAsJsonAsync($"projects/conversions", completeObject, cancellationToken)); Guid? completeProjectId = null; @@ -96,16 +86,16 @@ public async Task Handle(CreateConversionsCompleteProjectsCommand var successResponse = await response.Content.ReadFromJsonAsync(); completeProjectId = successResponse.conversion_project_id; - _logger.LogInformation("Success completing conversion project with project urn: {project} with Status code 201 ", completeObject.urn); + _logger.LogInformation("Success sending conversion project to complete with project urn: {project} with Status code 201 ", completeObject.urn); } else { var errorResponse = await response.Content.ReadFromJsonAsync(); responseMessage = errorResponse.GetAllErrors(); - _logger.LogInformation("Error In completing conversion project with project urn: {project} due to Status code {code} and Complete Validation Errors:" + responseMessage, completeObject.urn, response.StatusCode); + _logger.LogInformation("Error sending conversion project to complete with project urn: {project} due to Status code {code} and Complete Validation Errors:" + responseMessage, completeObject.urn, response.StatusCode); } - conversionProject.SetProjectSentToComplete(); + conversionProject.SetProjectSentToCompleteDate(_dateTimeProvider.Now); _conversionProjectRepository.Update(conversionProject as Domain.ProjectAggregate.Project); await _conversionProjectRepository.UnitOfWork.SaveChangesAsync(cancellationToken); diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommand.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommand.cs new file mode 100644 index 000000000..f8f17fa12 --- /dev/null +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommand.cs @@ -0,0 +1,9 @@ +using Dfe.Academies.Academisation.Core; +using MediatR; + +namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject +{ + public class CreateCompleteFormAMatConversionProjectsCommand : IRequest + { + } +} diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandler.cs new file mode 100644 index 000000000..78830e674 --- /dev/null +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandler.cs @@ -0,0 +1,113 @@ +using System.Net; +using System.Net.Http.Json; +using Dfe.Academies.Academisation.Core; +using Dfe.Academies.Academisation.Core.Utils; +using Dfe.Academies.Academisation.Data.Http; +using Dfe.Academies.Academisation.Domain.ApplicationAggregate; +using Dfe.Academies.Academisation.Domain.CompleteTransmissionLog; +using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; +using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IService.ServiceModels.Complete; +using Dfe.Academies.Academisation.Service.Factories; +using Dfe.Academies.Academisation.Service.Mappers.CompleteProjects; +using Dfe.Academisation.CorrelationIdMiddleware; +using MediatR; +using Microsoft.Extensions.Logging; +using Polly; + +namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject +{ + public class CreateCompleteFormAMatConversionProjectsCommandHandler : IRequestHandler + { + private readonly IConversionProjectRepository _conversionProjectRepository; + private readonly IAdvisoryBoardDecisionRepository _advisoryBoardDecisionRepository; + private readonly IProjectGroupRepository _projectGroupRepository; + private readonly ICompleteTransmissionLogRepository _completeTransmissionLogRepository; + private readonly IDateTimeProvider _dateTimeProvider; + private readonly ICompleteApiClientFactory _completeApiClientFactory; + private readonly ILogger _logger; + private ICorrelationContext _correlationContext; + private readonly IPollyPolicyFactory _pollyPolicyFactory; + + public CreateCompleteFormAMatConversionProjectsCommandHandler( + IConversionProjectRepository conversionProjectRepository, + IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository, + IProjectGroupRepository projectGroupRepository, + ICompleteTransmissionLogRepository completeTransmissionLogRepository, + ICompleteApiClientFactory completeApiClientFactory, + IDateTimeProvider dateTimeProvider, + ICorrelationContext correlationContext, + IPollyPolicyFactory pollyPolicyFactory, + ILogger logger) + { + _conversionProjectRepository = conversionProjectRepository; + _advisoryBoardDecisionRepository = advisoryBoardDecisionRepository; + _projectGroupRepository = projectGroupRepository; + _completeTransmissionLogRepository = completeTransmissionLogRepository; + _completeApiClientFactory = completeApiClientFactory; + _dateTimeProvider = dateTimeProvider; + _correlationContext = correlationContext; + _pollyPolicyFactory = pollyPolicyFactory; + _logger = logger; + } + + public async Task Handle(CreateCompleteConversionProjectsCommand request, + CancellationToken cancellationToken) + { + var client = _completeApiClientFactory.Create(_correlationContext); + var retryPolicy = _pollyPolicyFactory.GetCompleteHttpClientRetryPolicy(_logger); + + var conversionProjects = await _conversionProjectRepository.GetFormAMatProjectsToSendToCompleteAsync(cancellationToken).ConfigureAwait(false); + + if (conversionProjects == null || !conversionProjects.Any()) + { + _logger.LogInformation($"No conversion projects found."); + return new NotFoundCommandResult(); + } + + foreach (var conversionProject in conversionProjects) + { + + var decision = await _advisoryBoardDecisionRepository.GetConversionProjectDecsion(conversionProject.Id); + + string? groupReferenceNumber = null; + + if (conversionProject.ProjectGroupId != null) + { + var group = await _projectGroupRepository.GetById((int)conversionProject.ProjectGroupId); + groupReferenceNumber = group.ReferenceNumber; + } + + var completeObject = CompleteConversionProjectServiceModelMapper.FormAMatFromDomain(conversionProject, decision.AdvisoryBoardDecisionDetails.ApprovedConditionsDetails, groupReferenceNumber); + + var response = await retryPolicy.ExecuteAsync(() => client.PostAsJsonAsync($"projects/conversions/form-a-mat", completeObject, cancellationToken)); + Guid? completeProjectId = null; + var responseMessage = string.Empty; + + if (response.IsSuccessStatusCode) + { + var successResponse = await response.Content.ReadFromJsonAsync(); + completeProjectId = successResponse.conversion_project_id; + + _logger.LogInformation("Success sending conversion project to complete with project urn: {project} with Status code 201 ", completeObject.urn); + } + else + { + var errorResponse = await response.Content.ReadFromJsonAsync(); + responseMessage = errorResponse.GetAllErrors(); + _logger.LogInformation("Error sending conversion project to complete with project urn: {project} due to Status code {code} and Complete Validation Errors:" + responseMessage, completeObject.urn, response.StatusCode); + } + + conversionProject.SetProjectSentToCompleteDate(_dateTimeProvider.Now); + _conversionProjectRepository.Update(conversionProject as Domain.ProjectAggregate.Project); + await _conversionProjectRepository.UnitOfWork.SaveChangesAsync(cancellationToken); + + _completeTransmissionLogRepository.Insert(CompleteTransmissionLog.CreateConversionProjectLog(conversionProject.Id, completeProjectId, response.IsSuccessStatusCode, responseMessage, _dateTimeProvider.Now)); + await _completeTransmissionLogRepository.UnitOfWork.SaveChangesAsync(cancellationToken); + + } + + return new CommandSuccessResult(); + } + } +} diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommand.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommand.cs new file mode 100644 index 000000000..3614b8e05 --- /dev/null +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommand.cs @@ -0,0 +1,9 @@ +using Dfe.Academies.Academisation.Core; +using MediatR; + +namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject +{ + public class CreateCompleteFormAMatTransferProjectsCommand : IRequest + { + } +} diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandler.cs new file mode 100644 index 000000000..f3516b16d --- /dev/null +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandler.cs @@ -0,0 +1,128 @@ +using System.Net.Http.Json; +using Dfe.Academies.Academisation.Core; +using Dfe.Academies.Academisation.Core.Utils; +using Dfe.Academies.Academisation.Data.Http; +using Dfe.Academies.Academisation.Domain.CompleteTransmissionLog; +using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; +using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IService.Query; +using Dfe.Academies.Academisation.IService.ServiceModels.Complete; +using Dfe.Academies.Academisation.Service.Factories; +using Dfe.Academies.Academisation.Service.Mappers.CompleteProjects; +using Dfe.Academisation.CorrelationIdMiddleware; +using MediatR; +using Microsoft.Extensions.Logging; + +namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject +{ + public class CreateCompleteFormAMatTransferProjectsCommandHandler : IRequestHandler + { + private readonly ITransferProjectRepository _transferProjectRepository; + private readonly IAdvisoryBoardDecisionRepository _advisoryBoardDecisionRepository; + private readonly IProjectGroupRepository _projectGroupRepository; + private readonly ICompleteTransmissionLogRepository _completeTransmissionLogRepository; + private readonly IAcademiesQueryService _academiesQueryService; + private readonly IDateTimeProvider _dateTimeProvider; + private readonly ICompleteApiClientFactory _completeApiClientFactory; + private readonly ILogger _logger; + private ICorrelationContext _correlationContext; + private readonly IPollyPolicyFactory _pollyPolicyFactory; + + public CreateCompleteFormAMatTransferProjectsCommandHandler( + ITransferProjectRepository transferProjectRepository, + IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository, + IAcademiesQueryService academiesQueryService, + IProjectGroupRepository projectGroupRepository, + ICompleteTransmissionLogRepository completeTransmissionLogRepository, + ICompleteApiClientFactory completeApiClientFactory, + IDateTimeProvider dateTimeProvider, + ICorrelationContext correlationContext, + IPollyPolicyFactory pollyPolicyFactory, + ILogger logger) + { + _transferProjectRepository = transferProjectRepository; + _advisoryBoardDecisionRepository = advisoryBoardDecisionRepository; + _academiesQueryService = academiesQueryService; + _projectGroupRepository = projectGroupRepository; + _completeTransmissionLogRepository = completeTransmissionLogRepository; + _completeApiClientFactory = completeApiClientFactory; + _dateTimeProvider = dateTimeProvider; + _correlationContext = correlationContext; + _pollyPolicyFactory = pollyPolicyFactory; + _logger = logger; + } + + public async Task Handle(CreateCompleteFormAMatTransferProjectsCommand request, + CancellationToken cancellationToken) + { + var client = _completeApiClientFactory.Create(_correlationContext); + var retryPolicy = _pollyPolicyFactory.GetCompleteHttpClientRetryPolicy(_logger); + + var transferProjects = await _transferProjectRepository.GetFormAMatProjectsToSendToCompleteAsync(cancellationToken).ConfigureAwait(false); + + if (transferProjects == null || !transferProjects.Any()) + { + _logger.LogInformation($"No transfer projects found."); + return new NotFoundCommandResult(); + } + + var transferingAcademies = transferProjects.SelectMany(x => x.TransferringAcademies, + (transferProject, academy) => new + { + academy.Id, + TransferProjectId = transferProject.Id, + Ukprn = academy.OutgoingAcademyUkprn, + Include = !academy.ProjectSentToComplete + }).Where(x => x.Include == true); + + var establishments = await _academiesQueryService.GetBulkEstablishmentsByUkprn(transferingAcademies.Select(x => x.Ukprn)); + + foreach (var transferringAcademy in transferingAcademies) + { + var transferProject = transferProjects.Single(x => x.Id == transferringAcademy.TransferProjectId); + var decision = await _advisoryBoardDecisionRepository.GetTransferProjectDecsion(transferringAcademy.TransferProjectId); + var establishment = establishments.Single(x => x.Ukprn == transferringAcademy.Ukprn); + + var transferObject = CompleteTransferProjectServiceModelMapper.FormAMatFromDomain(transferProject, + decision.AdvisoryBoardDecisionDetails.ApprovedConditionsDetails, establishment.Urn); + + var response = + await retryPolicy.ExecuteAsync(() => client.PostAsJsonAsync($"projects/transfers/form-a-mat", transferObject, cancellationToken)); + + Guid? completeProjectId = null; + var responseMessage = string.Empty; + + if (response.IsSuccessStatusCode) + { + var successResponse = + await response.Content.ReadFromJsonAsync(); + + completeProjectId = successResponse.conversion_project_id; + + _logger.LogInformation( + "Success sending transfer to complete with project urn: {project} with Status code 201 ", + transferProject.Urn); + } + else + { + var errorResponse = + await response.Content.ReadFromJsonAsync(); + responseMessage = errorResponse.GetAllErrors(); + _logger.LogInformation("Error sending transfer project to complete with project urn: {project} for transfering academy: {urn} due to Status code {code} and Complete Validation Errors:" + responseMessage, transferProject.Urn, establishment.Urn, response.StatusCode); + } + + transferProject.SetProjectSentToComplete(transferringAcademy.Ukprn); + + _transferProjectRepository.Update(transferProject as Domain.TransferProjectAggregate.TransferProject); + + await _transferProjectRepository.UnitOfWork.SaveChangesAsync(cancellationToken); + + _completeTransmissionLogRepository.Insert(CompleteTransmissionLog.CreateTransferProjectLog(transferProject.Id, transferringAcademy.Id, completeProjectId, response.IsSuccessStatusCode, responseMessage, _dateTimeProvider.Now)); + await _completeTransmissionLogRepository.UnitOfWork.SaveChangesAsync(cancellationToken); + } + + return new CommandSuccessResult(); + } + + } +} diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateTransfersCompleteProjectsCommand.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommand.cs similarity index 63% rename from Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateTransfersCompleteProjectsCommand.cs rename to Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommand.cs index ee280f0ee..f8ae23f71 100644 --- a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateTransfersCompleteProjectsCommand.cs +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommand.cs @@ -3,7 +3,7 @@ namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject { - public class CreateTransfersCompleteProjectsCommand : IRequest + public class CreateCompleteTransferProjectsCommand : IRequest { } } diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateTransfersCompleteProjectsCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandler.cs similarity index 78% rename from Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateTransfersCompleteProjectsCommandHandler.cs rename to Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandler.cs index 026116431..008c41e2b 100644 --- a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateTransfersCompleteProjectsCommandHandler.cs +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandler.cs @@ -13,6 +13,7 @@ using Dfe.Academies.Academisation.IDomain.ConversionAdvisoryBoardDecisionAggregate; using Dfe.Academies.Academisation.IService.Query; using Dfe.Academies.Academisation.IService.ServiceModels.Complete; +using Dfe.Academies.Academisation.Service.Factories; using Dfe.Academies.Academisation.Service.Mappers.CompleteProjects; using Dfe.Academisation.CorrelationIdMiddleware; using MediatR; @@ -22,7 +23,7 @@ namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject { - public class CreateTransfersCompleteProjectsCommandHandler : IRequestHandler + public class CreateCompleteTransferProjectsCommandHandler : IRequestHandler { private readonly ITransferProjectRepository _transferProjectRepository; private readonly IAdvisoryBoardDecisionRepository _advisoryBoardDecisionRepository; @@ -31,10 +32,11 @@ public class CreateTransfersCompleteProjectsCommandHandler : IRequestHandler _logger; + private readonly ILogger _logger; private ICorrelationContext _correlationContext; + private readonly IPollyPolicyFactory _pollyPolicyFactory; - public CreateTransfersCompleteProjectsCommandHandler( + public CreateCompleteTransferProjectsCommandHandler( ITransferProjectRepository transferProjectRepository, IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository, IAcademiesQueryService academiesQueryService, @@ -43,7 +45,8 @@ public CreateTransfersCompleteProjectsCommandHandler( ICompleteApiClientFactory completeApiClientFactory, IDateTimeProvider dateTimeProvider, ICorrelationContext correlationContext, - ILogger logger) + IPollyPolicyFactory pollyPolicyFactory, + ILogger logger) { _transferProjectRepository = transferProjectRepository; _advisoryBoardDecisionRepository = advisoryBoardDecisionRepository; @@ -53,20 +56,15 @@ public CreateTransfersCompleteProjectsCommandHandler( _completeApiClientFactory = completeApiClientFactory; _dateTimeProvider = dateTimeProvider; _correlationContext = correlationContext; + _pollyPolicyFactory = pollyPolicyFactory; _logger = logger; } - public async Task Handle(CreateTransfersCompleteProjectsCommand request, + public async Task Handle(CreateCompleteTransferProjectsCommand request, CancellationToken cancellationToken) { var client = _completeApiClientFactory.Create(_correlationContext); - var retryPolicy = Policy.Handle() // Handle HttpRequestException - .OrResult(r => !r.IsSuccessStatusCode && r.StatusCode != HttpStatusCode.BadRequest) // Retry if response is not successful - .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), - (exception, timeSpan, retryCount, context) => - { - _logger.LogInformation($"Retry {retryCount} after {timeSpan.Seconds} seconds due to: {exception?.Exception?.Message}"); - }); + var retryPolicy = _pollyPolicyFactory.GetCompleteHttpClientRetryPolicy(_logger); var transferProjects = await _transferProjectRepository.GetProjectsToSendToCompleteAsync(cancellationToken).ConfigureAwait(false); @@ -93,7 +91,7 @@ public async Task Handle(CreateTransfersCompleteProjectsCommand r var decision = await _advisoryBoardDecisionRepository.GetTransferProjectDecsion(transferringAcademy.TransferProjectId); var establishment = establishments.Single(x => x.Ukprn == transferringAcademy.Ukprn); - var transferObject = CompleteProjectsServiceModelMapper.FromDomain(transferProject, + var transferObject = CompleteTransferProjectServiceModelMapper.FromDomain(transferProject, decision.AdvisoryBoardDecisionDetails.ApprovedConditionsDetails, establishment.Urn); var response = @@ -110,7 +108,7 @@ public async Task Handle(CreateTransfersCompleteProjectsCommand r completeProjectId = successResponse.conversion_project_id; _logger.LogInformation( - "Success completing conversion project with project urn: {project} with Status code 201 ", + "Success sending transfer project to complete with project urn: {project} with Status code 201 ", transferProject.Urn); } else @@ -118,7 +116,7 @@ public async Task Handle(CreateTransfersCompleteProjectsCommand r var errorResponse = await response.Content.ReadFromJsonAsync(); responseMessage = errorResponse.GetAllErrors(); - _logger.LogInformation("Error In completing conversion project with project urn: {project} for transfering academy: {urn} due to Status code {code} and Complete Validation Errors:" + responseMessage, transferProject.Urn, establishment.Urn, response.StatusCode); + _logger.LogInformation("Error sending transfer project to complete with project urn: {project} for transfering academy: {urn} due to Status code {code} and Complete Validation Errors:" + responseMessage, transferProject.Urn, establishment.Urn, response.StatusCode); } transferProject.SetProjectSentToComplete(transferringAcademy.Ukprn); diff --git a/Dfe.Academies.Academisation.Service/Commands/ConversionProject/CreateFormAMatAndChildConversionCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/ConversionProject/CreateFormAMatAndChildConversionCommandHandler.cs index c9cbc76af..ea7cbc5b2 100644 --- a/Dfe.Academies.Academisation.Service/Commands/ConversionProject/CreateFormAMatAndChildConversionCommandHandler.cs +++ b/Dfe.Academies.Academisation.Service/Commands/ConversionProject/CreateFormAMatAndChildConversionCommandHandler.cs @@ -52,7 +52,7 @@ public async Task Handle(CreateFormAMatAndChildConversionCommand var project = successResult.Payload; project.SetFormAMatProjectId(newFormAMat.Id); - _conversionProjectRepository.Insert((Project)project); + await _conversionProjectRepository.CreateFormAMatProject(project); await _conversionProjectRepository.UnitOfWork.SaveChangesAsync(cancellationToken); } diff --git a/Dfe.Academies.Academisation.Service/Factories/IPollyPolicyFactory.cs b/Dfe.Academies.Academisation.Service/Factories/IPollyPolicyFactory.cs new file mode 100644 index 000000000..791c12b01 --- /dev/null +++ b/Dfe.Academies.Academisation.Service/Factories/IPollyPolicyFactory.cs @@ -0,0 +1,11 @@ +using Microsoft.Extensions.Logging; +using Polly; +using Polly.Retry; + +namespace Dfe.Academies.Academisation.Service.Factories +{ + public interface IPollyPolicyFactory + { + IAsyncPolicy GetCompleteHttpClientRetryPolicy(ILogger logger); + } +} diff --git a/Dfe.Academies.Academisation.Service/Factories/PollyPolicyFactory.cs b/Dfe.Academies.Academisation.Service/Factories/PollyPolicyFactory.cs new file mode 100644 index 000000000..33764df61 --- /dev/null +++ b/Dfe.Academies.Academisation.Service/Factories/PollyPolicyFactory.cs @@ -0,0 +1,22 @@ +using System.Net; +using Microsoft.Extensions.Logging; +using Polly; +using Polly.Retry; + +namespace Dfe.Academies.Academisation.Service.Factories +{ + public class PollyPolicyFactory : IPollyPolicyFactory + { + public IAsyncPolicy GetCompleteHttpClientRetryPolicy(ILogger logger) + { + + return Policy.Handle() // Handle HttpRequestException + .OrResult(r => !r.IsSuccessStatusCode && r.StatusCode != HttpStatusCode.BadRequest) // Retry if response is not successful + .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), + (exception, timeSpan, retryCount, context) => + { + logger.LogInformation($"Retry {retryCount} after {timeSpan.Seconds} seconds due to: {exception?.Exception?.Message}"); + }); + } + } +} diff --git a/Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteConversionProjectServiceModelMapper.cs b/Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteConversionProjectServiceModelMapper.cs new file mode 100644 index 000000000..48062f7ed --- /dev/null +++ b/Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteConversionProjectServiceModelMapper.cs @@ -0,0 +1,61 @@ +using Dfe.Academies.Academisation.IDomain.ConversionAdvisoryBoardDecisionAggregate; +using Dfe.Academies.Academisation.IDomain.ProjectAggregate; +using Dfe.Academies.Academisation.IDomain.TransferProjectAggregate; +using Dfe.Academies.Academisation.IService.ServiceModels.Complete; + +namespace Dfe.Academies.Academisation.Service.Mappers.CompleteProjects; + +internal static class CompleteConversionProjectServiceModelMapper +{ + internal static CompleteConversionProjectServiceModel FromDomain(IProject project, string conditions, string groupReferenceNumber) + { + + var assignedUser = project.Details.AssignedUser; + + string? email = assignedUser != null ? assignedUser.EmailAddress : null; + string? fullName = assignedUser != null ? assignedUser.FullName : null; + string? firstName = fullName != null ? fullName.Split(' ')[0] : null; + string? lastName = fullName != null ? fullName.Split(' ')[1] : null; + + return new CompleteConversionProjectServiceModel( + project.Details.Urn, + project.Details.HeadTeacherBoardDate.ToString(), + conditions, + project.Details.ProposedConversionDate.ToString(), + true, + email, + firstName, + lastName, + project.Id, + groupReferenceNumber, + project.Details.TrustUkprn + ); + } + + internal static CompleteFormAMatConversionProjectServiceModel FormAMatFromDomain(IProject project, string conditions, string groupReferenceNumber) + { + + var assignedUser = project.Details.AssignedUser; + + string? email = assignedUser != null ? assignedUser.EmailAddress : null; + string? fullName = assignedUser != null ? assignedUser.FullName : null; + string? firstName = fullName != null ? fullName.Split(' ')[0] : null; + string? lastName = fullName != null ? fullName.Split(' ')[1] : null; + + return new CompleteFormAMatConversionProjectServiceModel( + project.Details.Urn, + project.Details.HeadTeacherBoardDate.ToString(), + conditions, + project.Details.ProposedConversionDate.ToString(), + true, + email, + firstName, + lastName, + project.Id, + groupReferenceNumber, + // proposed trust name is held in the name of trust field, trust reference number is not available as it stands + project.Details.TrustReferenceNumber, + project.Details.NameOfTrust + ); + } +} diff --git a/Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteProjectsServiceModelMapper.cs b/Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteTransferProjectServiceModelMapper.cs similarity index 54% rename from Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteProjectsServiceModelMapper.cs rename to Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteTransferProjectServiceModelMapper.cs index dd79a43b0..9e0e04c06 100644 --- a/Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteProjectsServiceModelMapper.cs +++ b/Dfe.Academies.Academisation.Service/Mappers/CompleteProjects/CompleteTransferProjectServiceModelMapper.cs @@ -5,34 +5,9 @@ namespace Dfe.Academies.Academisation.Service.Mappers.CompleteProjects; -internal static class CompleteProjectsServiceModelMapper -{ - internal static CompleteProjectsServiceModel FromDomain(IProject project, string conditions, string groupReferenceNumber) - { - - var assignedUser = project.Details.AssignedUser; - - string? email = assignedUser != null ? assignedUser.EmailAddress : null; - string? fullName = assignedUser != null ? assignedUser.FullName : null; - string? firstName = fullName != null ? fullName.Split(' ')[0] : null; - string? lastName = fullName != null ? fullName.Split(' ')[1] : null; - - return new CompleteProjectsServiceModel( - project.Details.Urn, - project.Details.HeadTeacherBoardDate.ToString(), - conditions, - project.Details.ProposedConversionDate.ToString(), - true, - email, - firstName, - lastName, - project.Id, - groupReferenceNumber, - project.Details.TrustUkprn - ); - } - - internal static TransfersCompleteProjectsServiceModel FromDomain(ITransferProject project, string conditions, string urn) +internal static class CompleteTransferProjectServiceModelMapper +{ + internal static CompleteTransferProjectServiceModel FromDomain(ITransferProject project, string conditions, string urn) { string incomingTrustUkprn = project.TransferringAcademies.First().IncomingTrustUkprn; @@ -52,7 +27,7 @@ internal static TransfersCompleteProjectsServiceModel FromDomain(ITransferProjec string? firstName = fullName != null ? fullName.Split(' ')[0] : null; string? lastName = fullName != null ? fullName.Split(' ')[1] : null; - return new TransfersCompleteProjectsServiceModel( + return new CompleteTransferProjectServiceModel( int.Parse(urn), project.HtbDate.ToString(), conditions, @@ -70,4 +45,44 @@ internal static TransfersCompleteProjectsServiceModel FromDomain(ITransferProjec ); } + + internal static CompleteFormAMatTransferProjectServiceModel FormAMatFromDomain(ITransferProject project, string conditions, string urn) + { + string incomingName = project.TransferringAcademies.First().IncomingTrustName; + + + bool outGoingTrustToClose = project.SpecificReasonsForTransfer.Contains("VoluntaryClosure") || + project.SpecificReasonsForTransfer.Contains("VoluntaryClosureIntervention") || + project.SpecificReasonsForTransfer.Contains("InterventionClosure"); + + bool inadequeteOfsted = project.SpecificReasonsForTransfer.Contains("Forced"); + + bool financialSafeGuardingOrGovernanceIssues = project.SpecificReasonsForTransfer.Contains("Finance") || + project.SpecificReasonsForTransfer.Contains("Safeguarding") || + project.SpecificReasonsForTransfer.Contains("TrustClosed"); + + string? fullName = project.AssignedUserFullName != null ? project.AssignedUserFullName : null; + string? firstName = fullName != null ? fullName.Split(' ')[0] : null; + string? lastName = fullName != null ? fullName.Split(' ')[1] : null; + + return new CompleteFormAMatTransferProjectServiceModel( + int.Parse(urn), + project.HtbDate.ToString(), + conditions, + project.TargetDateForTransfer.ToString(), + inadequeteOfsted, + financialSafeGuardingOrGovernanceIssues, + int.Parse(project.OutgoingTrustUkprn), + outGoingTrustToClose, + project.AssignedUserEmailAddress, + firstName, + lastName, + project.Id, + // Transfer projects aren't currently added to groups + null, + // Need the trust reference number, proposed trust name is held in the incoming trust name field + "TrustReferenceNumber", + incomingName + ); + } } diff --git a/Dfe.Academies.Academisation.Service/Mappers/Legacy/ProjectAggregate/LegacyProjectServiceModelMapper.cs b/Dfe.Academies.Academisation.Service/Mappers/Legacy/ProjectAggregate/LegacyProjectServiceModelMapper.cs index 6284fb510..a48840377 100644 --- a/Dfe.Academies.Academisation.Service/Mappers/Legacy/ProjectAggregate/LegacyProjectServiceModelMapper.cs +++ b/Dfe.Academies.Academisation.Service/Mappers/Legacy/ProjectAggregate/LegacyProjectServiceModelMapper.cs @@ -151,6 +151,7 @@ internal static ConversionProjectServiceModel MapToServiceModel(this IProject pr ProjectDatesSectionComplete = project.Details.ProjectDatesSectionComplete, // if we have sent the project to complete then the project is readonly IsReadOnly = project.IsReadOnly, + ProjectSentToCompleteDate = project.ProjectSentToCompleteDate, TrustUkprn = project.Details.TrustUkprn }; diff --git a/Dfe.Academies.Academisation.SubcutaneousTest/ProjectAggregate/LegacyProjectGetTests.cs b/Dfe.Academies.Academisation.SubcutaneousTest/ProjectAggregate/LegacyProjectGetTests.cs index 93c4d92e5..0ef49c643 100644 --- a/Dfe.Academies.Academisation.SubcutaneousTest/ProjectAggregate/LegacyProjectGetTests.cs +++ b/Dfe.Academies.Academisation.SubcutaneousTest/ProjectAggregate/LegacyProjectGetTests.cs @@ -51,6 +51,7 @@ public async Task ProjectExists___ProjectReturned() .Excluding(x => x.ApplicationSharePointId) .Excluding(x => x.SchoolSharePointId) .Excluding(x => x.IsReadOnly) + .Excluding(x => x.ProjectSentToCompleteDate) ); existingProject.Id.Should().Be(serviceModel.Id); diff --git a/Dfe.Academies.Academisation.SubcutaneousTest/ProjectAggregate/LegacyProjectUpdateTests.cs b/Dfe.Academies.Academisation.SubcutaneousTest/ProjectAggregate/LegacyProjectUpdateTests.cs index dea4c0c24..0af5aad2d 100644 --- a/Dfe.Academies.Academisation.SubcutaneousTest/ProjectAggregate/LegacyProjectUpdateTests.cs +++ b/Dfe.Academies.Academisation.SubcutaneousTest/ProjectAggregate/LegacyProjectUpdateTests.cs @@ -78,6 +78,7 @@ public async Task ProjectExists___FullProjectIsUpdated() .With(p => p.Urn, existingProject.Details.Urn) .With(p => p.ExternalApplicationFormSaved, existingProject.Details.ExternalApplicationFormSaved) .With(p => p.IsReadOnly, existingProject.IsReadOnly) + .With(p => p.ProjectSentToCompleteDate, existingProject.ProjectSentToCompleteDate) // excluded from update so need to be set for equality to assert .With(x => x.KeyStage2PerformanceAdditionalInformation, existingProject.Details.KeyStage2PerformanceAdditionalInformation) .With(x => x.KeyStage4PerformanceAdditionalInformation, existingProject.Details.KeyStage4PerformanceAdditionalInformation) diff --git a/Dfe.Academies.Academisation.WebApi/Program.cs b/Dfe.Academies.Academisation.WebApi/Program.cs index d601fe39b..0471ea44b 100644 --- a/Dfe.Academies.Academisation.WebApi/Program.cs +++ b/Dfe.Academies.Academisation.WebApi/Program.cs @@ -32,6 +32,7 @@ using Dfe.Academies.Academisation.Service.Commands.TransferProject; using Dfe.Academies.Academisation.Service.CommandValidations; using Dfe.Academies.Academisation.Service.CommandValidations.ProjectGroup; +using Dfe.Academies.Academisation.Service.Factories; using Dfe.Academies.Academisation.Service.Mappers.OpeningDateHistoryMapper; using Dfe.Academies.Academisation.Service.Queries; using Dfe.Academies.Academisation.WebApi.AutoMapper; @@ -141,6 +142,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); //Validators builder.Services.AddSingleton(); diff --git a/Dfe.Academies.Academisation.WebApi/Services/CreateCompleteProjectsService.cs b/Dfe.Academies.Academisation.WebApi/Services/CreateCompleteProjectsService.cs index 59dac78c3..38f390a6f 100644 --- a/Dfe.Academies.Academisation.WebApi/Services/CreateCompleteProjectsService.cs +++ b/Dfe.Academies.Academisation.WebApi/Services/CreateCompleteProjectsService.cs @@ -38,8 +38,8 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) try { - await mediator.Send(new CreateConversionsCompleteProjectsCommand(), stoppingToken); - await mediator.Send(new CreateTransfersCompleteProjectsCommand(), stoppingToken); + await mediator.Send(new CreateCompleteConversionProjectsCommand(), stoppingToken); + await mediator.Send(new CreateCompleteTransferProjectsCommand(), stoppingToken); } catch (Exception ex) { @@ -50,7 +50,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) try { - await mediator.Send(new CreateTransfersCompleteProjectsCommand(), stoppingToken); + await mediator.Send(new CreateCompleteTransferProjectsCommand(), stoppingToken); } catch (Exception ex) {