Skip to content

Commit

Permalink
Merge pull request #588 from DFE-Digital/feature/send-transfers-to-co…
Browse files Browse the repository at this point in the history
…mplete

Feature/send transfers to complete
  • Loading branch information
paullocknimble authored Oct 21, 2024
2 parents a92fecf + 18a88d4 commit 343159b
Show file tree
Hide file tree
Showing 18 changed files with 2,475 additions and 45 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Dfe.Academies.Academisation.Data.Migrations
{
/// <inheritdoc />
public partial class addtransferprojectisreadonly : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsReadOnly",
schema: "academisation",
table: "TransferProject",
type: "bit",
nullable: false,
defaultValue: false);
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsReadOnly",
schema: "academisation",
table: "TransferProject");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property<bool?>("IsFormAMat")
.HasColumnType("bit");
b.Property<bool>("IsReadOnly")
.HasColumnType("bit");
b.Property<DateTime>("LastModifiedOn")
.HasColumnType("datetime2");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,9 @@ private IQueryable<TransferProject> DefaultIncludes()

public async Task<IEnumerable<ITransferProject>> GetProjectsToSendToCompleteAsync(CancellationToken cancellationToken)
{
var decisions = context.ConversionAdvisoryBoardDecisions.Where(x => x.AdvisoryBoardDecisionDetails.Decision == Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDecision.Approved);
var projects = this.dbSet.Include(y => y.TransferringAcademies).Where(proj => proj.TransferringAcademies.Any(x => !x.ProjectSentToComplete) && proj.IsReadOnly);

var projects = decisions.Join(
this.dbSet.Include(y => y.TransferringAcademies).Where(proj => proj.TransferringAcademies.Any(x => !x.ProjectSentToComplete)),
decision => decision.AdvisoryBoardDecisionDetails.TransferProjectId,
project => project.Id,
(decision, project) => new { project });

return await projects.Where(y => y.project.IsFormAMat != true).Select(x => x.project).ToListAsync(cancellationToken);
return await projects.Where(y => y.IsFormAMat != true).ToListAsync(cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ protected TransferProject() { }

public int Id { get; private set; }
public int Urn { get; private set; }

public bool IsReadOnly { get; private set; } = false;

public string? ProjectReference { get; private set; }
public string OutgoingTrustUkprn { get; private set; }
public string? OutgoingTrustName { get; private set; }
Expand Down Expand Up @@ -278,6 +279,9 @@ public void SetProjectSentToComplete(string transferingAcademyUkprn)
transferingAcademy.SetProjectSentToComplete();
}


public void SetIsReadOnly(bool isReadOnly)
{
IsReadOnly = isReadOnly;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Dfe.Academies.Academisation.IDomain.TransferProjectAggregate
public interface ITransferProject
{
bool? AnyRisks { get; }
bool IsReadOnly { get; }
string? AssignedUserEmailAddress { get; }
string? AssignedUserFullName { get; }
Guid? AssignedUserId { get; }
Expand Down Expand Up @@ -74,5 +75,6 @@ public interface ITransferProject
void SetId(int id);

void SetProjectSentToComplete(string transferingAcademyUkprn);
void SetIsReadOnly(bool isReadOnly);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public class AcademyTransferProjectResponse
{
public int Id { get; set; }
public string ProjectUrn { get; set; }

public bool IsReadOnly { get; set; }
public string ProjectReference { get; set; }
public string OutgoingTrustUkprn { get; set; }
public string OutgoingTrustName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ public class AcademyTransferProjectSummaryResponse
public List<TransferringAcademyDto> TransferringAcademies { get; set; }
public AssignedUserResponse AssignedUser { get; set; }
public bool? IsFormAMat { get; set; }
public bool IsReadOnly { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public UnhandledCreateResult() : base(default) { }
private readonly Mock<IConversionAdvisoryBoardDecisionFactory> _mockDecisionFactory = new();
private readonly Mock<IConversionAdvisoryBoardDecision> _mockDecision = new();
private readonly Mock<IConversionProjectRepository> _mockConversionProjectRepository = new();
private readonly Mock<ITransferProjectRepository> _mockTransferProjectRepository = new();

[Fact]
public async Task RequestModelIsValid___CallsExecuteOnDataCommand()
Expand All @@ -56,7 +57,7 @@ public async Task RequestModelIsValid___CallsExecuteOnDataCommand()
.SetupGet(d => d.DAORevokedReasons)
.Returns(new List<AdvisoryBoardDAORevokedReasonDetails>());

var target = new AdvisoryBoardDecisionCreateCommandHandler(_mockDecisionFactory.Object, _mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionCreateCommandHandler(_mockDecisionFactory.Object, _mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act
_ = await target.Handle(new AdvisoryBoardDecisionCreateCommand(), default);
Expand Down Expand Up @@ -112,7 +113,7 @@ public async Task RequestModelIsValid___ReturnsExpectedConversionAdvisoryBoardDe
.SetupGet(d => d.DAORevokedReasons)
.Returns(daoRevoked.ToList().AsReadOnly());

var target = new AdvisoryBoardDecisionCreateCommandHandler(_mockDecisionFactory.Object, _mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionCreateCommandHandler(_mockDecisionFactory.Object, _mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act
var result = (CreateSuccessResult<ConversionAdvisoryBoardDecisionServiceModel>)await target.Handle(new(), default);
Expand All @@ -129,7 +130,7 @@ public async Task RequestModelIsInvalid_DoesNotCallExecuteOnDataCommand()
.Setup(f => f.Create(It.IsAny<AdvisoryBoardDecisionDetails>(), It.IsAny<List<AdvisoryBoardDeferredReasonDetails>>(), It.IsAny<List<AdvisoryBoardDeclinedReasonDetails>>(), It.IsAny<List<AdvisoryBoardWithdrawnReasonDetails>>(), It.IsAny<List<AdvisoryBoardDAORevokedReasonDetails>>()))
.Returns(new CreateValidationErrorResult(Enumerable.Empty<ValidationError>()));

var target = new AdvisoryBoardDecisionCreateCommandHandler(_mockDecisionFactory.Object, _mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionCreateCommandHandler(_mockDecisionFactory.Object, _mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act
_ = await target.Handle(new(), default);
Expand All @@ -146,7 +147,7 @@ public async Task FactoryReturnsUnhandledCreateResult___ThrowsException()
.Setup(f => f.Create(It.IsAny<AdvisoryBoardDecisionDetails>(), It.IsAny<List<AdvisoryBoardDeferredReasonDetails>>(), It.IsAny<List<AdvisoryBoardDeclinedReasonDetails>>(), It.IsAny<List<AdvisoryBoardWithdrawnReasonDetails>>(), It.IsAny<List<AdvisoryBoardDAORevokedReasonDetails>>()))
.Returns(new UnhandledCreateResult());

var target = new AdvisoryBoardDecisionCreateCommandHandler(_mockDecisionFactory.Object, _mockRepo.Object , _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionCreateCommandHandler(_mockDecisionFactory.Object, _mockRepo.Object , _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act && Assert
await Assert.ThrowsAsync<NotImplementedException>(() => target.Handle(new AdvisoryBoardDecisionCreateCommand(), default));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Dfe.Academies.Academisation.Core;
using AutoFixture;
using Dfe.Academies.Academisation.Core;
using Dfe.Academies.Academisation.Domain.ApplicationAggregate;
using Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate;
using Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate;
Expand All @@ -18,6 +19,8 @@ private class UnhandledCommandResult : CommandResult { }
private readonly Mock<IAdvisoryBoardDecisionRepository> _mockRepo = new();
private readonly Mock<IConversionAdvisoryBoardDecision> _mockDecision = new();
private readonly Mock<IConversionProjectRepository> _mockConversionProjectRepository = new();
private readonly Mock<ITransferProjectRepository> _mockTransferProjectRepository = new();
private readonly Fixture _fixture = new();
public AdvisoryBoardDecisionUpdateCommandExecuteTests()
{
var mockContext = new Mock<IUnitOfWork>();
Expand All @@ -28,7 +31,7 @@ public AdvisoryBoardDecisionUpdateCommandExecuteTests()
public async Task AdvisoryBoardDecisionIdIsDefault___ReturnsBadResult()
{
//Arrange
var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act
var result = await target.Handle(new(), default);
Expand All @@ -40,7 +43,7 @@ public async Task AdvisoryBoardDecisionIdIsDefault___ReturnsBadResult()
[Fact]
public async Task DataQueryReturnsNull__ReturnsCommandNotFoundResult()
{
var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act
var result = await target.Handle(new() { AdvisoryBoardDecisionId = 1 }, default);
Expand All @@ -61,7 +64,7 @@ public async Task DecisionUpdateReturnsUnhandledCommandResult__ThrowsException()
.Setup(d => d.GetAdvisoryBoardDecisionById(It.IsAny<int>()))
.ReturnsAsync(_mockDecision.Object);

var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act & Assert
await Assert.ThrowsAsync<NotImplementedException>(() => target.Handle(new() { AdvisoryBoardDecisionId = 1 }, default));
Expand All @@ -78,7 +81,7 @@ public async Task DomainReturnsValidatorError_DoesNotCallExecuteOnDataCommand()
.Setup(q => q.GetAdvisoryBoardDecisionById(It.IsAny<int>()))
.ReturnsAsync(_mockDecision.Object);

var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act
_ = await target.Handle(new() { AdvisoryBoardDecisionId = 1 }, default);
Expand All @@ -94,11 +97,13 @@ public async Task DomainReturnsSuccess___CallsExecuteOnDataCommand()
.Setup(c => c.Update(It.IsAny<AdvisoryBoardDecisionDetails>(), It.IsAny<List<AdvisoryBoardDeferredReasonDetails>>(), It.IsAny<List<AdvisoryBoardDeclinedReasonDetails>>(), It.IsAny<List<AdvisoryBoardWithdrawnReasonDetails>>(), It.IsAny<List<AdvisoryBoardDAORevokedReasonDetails>>()))
.Returns(new CommandSuccessResult());

_mockDecision.Setup(d => d.AdvisoryBoardDecisionDetails).Returns(_fixture.Build<AdvisoryBoardDecisionDetails>().With(x => x.TransferProjectId, 1).Create());

_mockRepo
.Setup(q => q.GetAdvisoryBoardDecisionById(It.IsAny<int>()))
.ReturnsAsync(_mockDecision.Object);

var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act
_ = await target.Handle(new() { AdvisoryBoardDecisionId = 1}, default);
Expand All @@ -114,12 +119,12 @@ public async Task DomainReturnsSuccess___ReturnsCommandSuccessResult()
_mockDecision
.Setup(d => d.Update(It.IsAny<AdvisoryBoardDecisionDetails>(), It.IsAny<List<AdvisoryBoardDeferredReasonDetails>>(), It.IsAny<List<AdvisoryBoardDeclinedReasonDetails>>(), It.IsAny<List<AdvisoryBoardWithdrawnReasonDetails>>(), It.IsAny<List<AdvisoryBoardDAORevokedReasonDetails>>()))
.Returns(new CommandSuccessResult());

_mockDecision.Setup(d => d.AdvisoryBoardDecisionDetails).Returns(_fixture.Build<AdvisoryBoardDecisionDetails>().With(x => x.TransferProjectId, 1).Create());
_mockRepo
.Setup(q => q.GetAdvisoryBoardDecisionById(It.IsAny<int>()))
.ReturnsAsync(_mockDecision.Object);

var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object);
var target = new AdvisoryBoardDecisionUpdateCommandHandler(_mockRepo.Object, _mockConversionProjectRepository.Object, _mockTransferProjectRepository.Object);

//Act
var result = await target.Handle(new() { AdvisoryBoardDecisionId = 1 }, default);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@

namespace Dfe.Academies.Academisation.Service.Commands.AdvisoryBoardDecision;

public class AdvisoryBoardDecisionCreateCommandHandler(IConversionAdvisoryBoardDecisionFactory factory,
IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository, IConversionProjectRepository conversionProjectRepository) : IRequestHandler<AdvisoryBoardDecisionCreateCommand, CreateResult>
public class AdvisoryBoardDecisionCreateCommandHandler(
IConversionAdvisoryBoardDecisionFactory factory,
IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository,
IConversionProjectRepository conversionProjectRepository,
ITransferProjectRepository transferProjectRepository) : IRequestHandler<AdvisoryBoardDecisionCreateCommand, CreateResult>
{
public async Task<CreateResult> Handle(AdvisoryBoardDecisionCreateCommand request, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -57,13 +60,27 @@ private async Task SetProjectReadOnlyAsync(AdvisoryBoardDecisionDetails advisory
{
if (advisoryBoardDecisionDetails != null)
{
var project = await conversionProjectRepository.GetById(advisoryBoardDecisionDetails.ConversionProjectId.GetValueOrDefault());
if (project != null)
if (advisoryBoardDecisionDetails.TransferProjectId != null)
{
project.SetIsReadOnly(advisoryBoardDecisionDetails.Decision == Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDecision.Approved);
conversionProjectRepository.Update(project);
await conversionProjectRepository.UnitOfWork.SaveChangesAsync();
var project = await transferProjectRepository.GetById(advisoryBoardDecisionDetails.TransferProjectId.GetValueOrDefault());
if (project != null)
{
project.SetIsReadOnly(advisoryBoardDecisionDetails.Decision == Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDecision.Approved);
transferProjectRepository.Update(project);
await transferProjectRepository.UnitOfWork.SaveChangesAsync();
}
}
else
{
var project = await conversionProjectRepository.GetById(advisoryBoardDecisionDetails.ConversionProjectId.GetValueOrDefault());
if (project != null)
{
project.SetIsReadOnly(advisoryBoardDecisionDetails.Decision == Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDecision.Approved);
conversionProjectRepository.Update(project);
await conversionProjectRepository.UnitOfWork.SaveChangesAsync();
}
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@

namespace Dfe.Academies.Academisation.Service.Commands.AdvisoryBoardDecision;

public class AdvisoryBoardDecisionUpdateCommandHandler(IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository, IConversionProjectRepository conversionProjectRepository) : IRequestHandler<AdvisoryBoardDecisionUpdateCommand, CommandResult>
public class AdvisoryBoardDecisionUpdateCommandHandler(
IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository,
IConversionProjectRepository conversionProjectRepository,
ITransferProjectRepository transferProjectRepository) : IRequestHandler<AdvisoryBoardDecisionUpdateCommand, CommandResult>
{
public async Task<CommandResult> Handle(AdvisoryBoardDecisionUpdateCommand command, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -59,7 +62,17 @@ private async Task<CommandResult> ExecuteDataCommand(IConversionAdvisoryBoardDec
}
private async Task SetProjectReadOnlyAsync(AdvisoryBoardDecisionDetails advisoryBoardDecisionDetails)
{
if (advisoryBoardDecisionDetails != null)
if (advisoryBoardDecisionDetails.TransferProjectId != null)
{
var project = await transferProjectRepository.GetById(advisoryBoardDecisionDetails.TransferProjectId.GetValueOrDefault());
if (project != null)
{
project.SetIsReadOnly(advisoryBoardDecisionDetails.Decision == Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDecision.Approved);
transferProjectRepository.Update(project);
await transferProjectRepository.UnitOfWork.SaveChangesAsync();
}
}
else
{
var project = await conversionProjectRepository.GetById(advisoryBoardDecisionDetails.ConversionProjectId.GetValueOrDefault());
if (project != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject
{
public class CreateCompleteProjectsCommand : IRequest<CommandResult>
public class CreateConversionsCompleteProjectsCommand : IRequest<CommandResult>
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,26 @@

namespace Dfe.Academies.Academisation.Service.Commands.CompleteProject
{
public class CreateCompleteProjectsCommandHandler : IRequestHandler<CreateCompleteProjectsCommand, CommandResult>
public class CreateConversionsCompleteProjectsCommandHandler : IRequestHandler<CreateConversionsCompleteProjectsCommand, CommandResult>
{
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<CreateCompleteProjectsCommandHandler> _logger;
private readonly ILogger<CreateConversionsCompleteProjectsCommandHandler> _logger;
private ICorrelationContext _correlationContext;

public CreateCompleteProjectsCommandHandler(
public CreateConversionsCompleteProjectsCommandHandler(
IConversionProjectRepository conversionProjectRepository,
IAdvisoryBoardDecisionRepository advisoryBoardDecisionRepository,
IProjectGroupRepository projectGroupRepository,
ICompleteTransmissionLogRepository completeTransmissionLogRepository,
ICompleteApiClientFactory completeApiClientFactory,
IDateTimeProvider dateTimeProvider,
ICorrelationContext correlationContext,
ILogger<CreateCompleteProjectsCommandHandler> logger)
ILogger<CreateConversionsCompleteProjectsCommandHandler> logger)
{
_conversionProjectRepository = conversionProjectRepository;
_advisoryBoardDecisionRepository = advisoryBoardDecisionRepository;
Expand All @@ -52,7 +52,7 @@ public CreateCompleteProjectsCommandHandler(
_logger = logger;
}

public async Task<CommandResult> Handle(CreateCompleteProjectsCommand request,
public async Task<CommandResult> Handle(CreateConversionsCompleteProjectsCommand request,
CancellationToken cancellationToken)
{
var client = _completeApiClientFactory.Create(_correlationContext);
Expand Down
Loading

0 comments on commit 343159b

Please sign in to comment.