Skip to content

Commit

Permalink
Merge pull request #56 from DFE-Digital/feature/188469-create-mat-con…
Browse files Browse the repository at this point in the history
…version-proj

Create Form A MAT Conversion project
  • Loading branch information
sukhybhullar-nimble authored Jan 28, 2025
2 parents 37eb451 + b0d2850 commit 8004092
Show file tree
Hide file tree
Showing 18 changed files with 854 additions and 385 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using Dfe.Complete.Domain.Entities;
using Dfe.Complete.Domain.Enums;
using Dfe.Complete.Domain.Interfaces.Repositories;
using Dfe.Complete.Domain.ValueObjects;
using Dfe.Complete.Utils;
using MediatR;

namespace Dfe.Complete.Application.Projects.Commands.CreateProject;

public record CreateMatConversionProjectCommand(
Urn Urn,
string NewTrustName,
string NewTrustReferenceNumber,
DateOnly SignificantDate,
bool IsSignificantDateProvisional,
bool IsDueTo2Ri,
bool HasAcademyOrderBeenIssued,
DateOnly AdvisoryBoardDate,
string AdvisoryBoardConditions,
string EstablishmentSharepointLink,
string IncomingTrustSharepointLink,
bool HandingOverToRegionalCaseworkService,
string? HandoverComments,
string? UserAdId) : IRequest<ProjectId>;

public class CreateMatConversionProjectCommandHandler(
ICompleteRepository<Project> projectRepository,
ICompleteRepository<ConversionTasksData> conversionTaskRepository,
ICompleteRepository<User> userRepository)
: IRequestHandler<CreateMatConversionProjectCommand, ProjectId>
{
public async Task<ProjectId> Handle(CreateMatConversionProjectCommand request, CancellationToken cancellationToken)
{
// The user Team should be moved as a Claim or Group to the Entra (MS AD)
var projectUser = await GetUserByAdId(request.UserAdId);

var projectUserTeam = projectUser.Team;
var projectUserId = projectUser?.Id;

var projectTeam = EnumExtensions.FromDescription<ProjectTeam>(projectUserTeam);
var region = EnumMapper.MapTeamToRegion(projectTeam);

var createdAt = DateTime.UtcNow;
var conversionTaskId = Guid.NewGuid();
var projectId = new ProjectId(Guid.NewGuid());

var conversionTask = new ConversionTasksData(new TaskDataId(conversionTaskId), createdAt, createdAt);

ProjectTeam team;
DateTime? assignedAt = null;
UserId? projectUserAssignedToId = null;

if (request.HandingOverToRegionalCaseworkService)
{
team = ProjectTeam.RegionalCaseWorkerServices;
}
else
{
team = projectTeam;
assignedAt = DateTime.UtcNow;
projectUserAssignedToId = projectUserId;
}

var project = Project.CreateMatConversionProject(
projectId,
request.Urn,
createdAt,
updatedAt: createdAt,
TaskType.Conversion,
ProjectType.Conversion,
conversionTaskId,
region,
team,
projectUser?.Id,
projectUserAssignedToId,
assignedAt,
request.EstablishmentSharepointLink,
request.IncomingTrustSharepointLink,
request.AdvisoryBoardDate,
request.AdvisoryBoardConditions,
request.SignificantDate,
request.IsSignificantDateProvisional,
request.IsDueTo2Ri,
request.NewTrustName,
request.NewTrustReferenceNumber,
request.HasAcademyOrderBeenIssued,
request.HandoverComments);

await conversionTaskRepository.AddAsync(conversionTask, cancellationToken);
await projectRepository.AddAsync(project, cancellationToken);

return project.Id;
}

private async Task<User> GetUserByAdId(string? userAdId) => await userRepository.FindAsync(x => x.ActiveDirectoryUserId == userAdId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Dfe.Complete.Application.Projects.Models;

public record GetProjectByTrnResponseDto(Guid ProjectId, string? NewTrustName);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Dfe.Complete.Application.Common.Models;
using Dfe.Complete.Application.Projects.Models;
using Dfe.Complete.Domain.Entities;
using Dfe.Complete.Domain.Interfaces.Repositories;
using MediatR;

namespace Dfe.Complete.Application.Projects.Queries.GetProject;


public record GetProjectByTrnQuery(string NewTrustReferenceNumber) : IRequest<Result<GetProjectByTrnResponseDto?>>;

public class GetProjectByTrn(ICompleteRepository<Project> projectRepo) : IRequestHandler<GetProjectByTrnQuery, Result<GetProjectByTrnResponseDto?>>
{
public async Task<Result<GetProjectByTrnResponseDto?>> Handle(GetProjectByTrnQuery request, CancellationToken cancellationToken)
{
try
{
var result = await projectRepo.FindAsync(x => x.NewTrustReferenceNumber == request.NewTrustReferenceNumber, cancellationToken);
return Result<GetProjectByTrnResponseDto?>.Success(new GetProjectByTrnResponseDto(result.Id.Value, result.NewTrustName));
}
catch (Exception e)
{
return Result<GetProjectByTrnResponseDto?>.Failure(e.Message);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,35 @@
using DfE.CoreLibs.Caching.Interfaces;
using Dfe.Complete.Application.Common.Models;

namespace Dfe.Complete.Application.Projects.Queries.GetProject
{
public record GetProjectByUrnQuery(Urn Urn) : IRequest<Result<Project?>>;
namespace Dfe.Complete.Application.Projects.Queries.GetProject;

public record GetProjectByUrnQuery(Urn Urn) : IRequest<Result<Project?>>;

public class GetProjectByUrnQueryHandler(ICompleteRepository<Project> projectRepository,
ICacheService<IMemoryCacheType> cacheService)
: IRequestHandler<GetProjectByUrnQuery, Result<Project?>>
public class GetProjectByUrnQueryHandler(ICompleteRepository<Project> projectRepository,
ICacheService<IMemoryCacheType> cacheService)
: IRequestHandler<GetProjectByUrnQuery, Result<Project?>>
{
public async Task<Result<Project?>> Handle(GetProjectByUrnQuery request, CancellationToken cancellationToken)
{
public async Task<Result<Project?>> Handle(GetProjectByUrnQuery request, CancellationToken cancellationToken)
{
var cacheKey = $"Project_{CacheKeyHelper.GenerateHashedCacheKey(request.Urn.Value.ToString())}";
var cacheKey = $"Project_{CacheKeyHelper.GenerateHashedCacheKey(request.Urn.Value.ToString())}";

var methodName = nameof(GetProjectByUrnQueryHandler);
var methodName = nameof(GetProjectByUrnQueryHandler);

// Please use AutoMapper to make sure return a DTO instead of the actual aggregate/ entity
// Please use AutoMapper to make sure return a DTO instead of the actual aggregate/ entity

return await cacheService.GetOrAddAsync(cacheKey, async () =>
return await cacheService.GetOrAddAsync(cacheKey, async () =>
{
try
{
try
{
var result = await projectRepository.GetAsync(p => p.Urn == request.Urn);
var result = await projectRepository.GetAsync(p => p.Urn == request.Urn);

return Result<Project?>.Success(result);
}
catch (Exception ex)
{
return Result<Project?>.Failure(ex.Message);
}
return Result<Project?>.Success(result);
}
catch (Exception ex)
{
return Result<Project?>.Failure(ex.Message);
}

}, methodName);
}
}, methodName);
}
}
69 changes: 59 additions & 10 deletions src/Core/Dfe.Complete.Domain/Entities/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using Dfe.Complete.Domain.Enums;
using Dfe.Complete.Domain.Events;
using Dfe.Complete.Domain.ValueObjects;
using Dfe.Complete.Infrastructure.Models;
using Dfe.Complete.Utils;

namespace Dfe.Complete.Domain.Entities;

Expand Down Expand Up @@ -108,8 +106,8 @@ public Project(ProjectId id,
Guid tasksDataId,
DateOnly significantDate,
bool isSignificantDateProvisional,
Ukprn incomingTrustUkprn,
Ukprn outgoingTrustUkprn,
Ukprn? incomingTrustUkprn,
Ukprn? outgoingTrustUkprn,
Region? region,
bool isDueTo2RI,
bool? hasAcademyOrderBeenIssued,
Expand All @@ -122,7 +120,9 @@ public Project(ProjectId id,
ProjectTeam? team,
UserId? regionalDeliveryOfficerId,
UserId? assignedTo,
DateTime? assignedAt)
DateTime? assignedAt,
string? newTrustName,
string? newTrustReferenceNumber)
{
Id = id ?? throw new ArgumentNullException(nameof(id));
Urn = urn ?? throw new ArgumentNullException(nameof(urn));
Expand All @@ -149,8 +149,10 @@ public Project(ProjectId id,

AssignedAt = assignedAt;
AssignedToId = assignedTo;
}

NewTrustName = newTrustName;
NewTrustReferenceNumber = newTrustReferenceNumber;
}

public static Project CreateConversionProject(
ProjectId Id,
Expand Down Expand Up @@ -201,7 +203,9 @@ public static Project CreateConversionProject(
team,
regionalDeliveryOfficerId,
assignedToId,
assignedAt);
assignedAt,
null,
null);

if (!string.IsNullOrEmpty(handoverComments))
{
Expand All @@ -217,7 +221,6 @@ public static Project CreateConversionProject(
return project;
}


public static Project CreateTransferProject
(
ProjectId Id,
Expand All @@ -242,7 +245,7 @@ public static Project CreateTransferProject
string advisoryBoardConditions,
DateOnly significantDate,
bool isSignificantDateProvisional,
bool isDueTo2RI,
bool isDueTo2RI,
string? handoverComments
)
{
Expand Down Expand Up @@ -270,8 +273,54 @@ public static Project CreateTransferProject
team,
regionalDeliveryOfficerId,
assignedToId,
assignedAt);
assignedAt,
null,
null);

if (!string.IsNullOrEmpty(handoverComments))
{
project.AddNote(new Note
{
CreatedAt = project.CreatedAt, ProjectId = project.Id, Body = handoverComments,
TaskIdentifier = "handover", UserId = assignedToId
});
}

project.AddDomainEvent(new ProjectCreatedEvent(project));

return project;
}

public static Project CreateMatConversionProject(
ProjectId Id,
Urn urn,
DateTime createdAt,
DateTime updatedAt,
TaskType taskType,
ProjectType projectType,
Guid tasksDataId,
Region? region,
ProjectTeam team,
UserId? regionalDeliveryOfficerId,
UserId? assignedToId,
DateTime? assignedAt,
string establishmentSharepointLink,
string incomingTrustSharepointLink,
DateOnly advisoryBoardDate,
string advisoryBoardConditions,
DateOnly significantDate,
bool isSignificantDateProvisional,
bool isDueTo2Ri,
string newTrustName,
string newTrustReferenceNumber,
bool hasDirectiveAcademyOrderBeenIssue,
string? handoverComments)
{
var project = new Project(Id, urn, createdAt, updatedAt, taskType, projectType, tasksDataId, significantDate,
isSignificantDateProvisional, null, null, region, isDueTo2Ri, hasDirectiveAcademyOrderBeenIssue,
advisoryBoardDate, advisoryBoardConditions, establishmentSharepointLink, incomingTrustSharepointLink, null,
null, team, regionalDeliveryOfficerId, assignedToId, assignedAt, newTrustName, newTrustReferenceNumber);

if (!string.IsNullOrEmpty(handoverComments))
{
project.AddNote(new Note
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@
</govuk-input>


<govuk-input name="@trustRefNumber" input-class="govuk-input--width-20" asp-for="@Model.TrustReferenceNumber">
<govuk-input name="@trustName" input-class="govuk-input--width-20" asp-for="@Model.TrustName">
<govuk-input-label class="govuk-label--m">Trust name</govuk-input-label>
<govuk-input-hint>
<p>
Enter the proposed name for the new trust. This can be changed later on if necessary.
</p>
</govuk-input-hint>
@if (ErrorService.HasErrorForKey(trustRefNumber))
@if (ErrorService.HasErrorForKey(trustName))
{
<govuk-input-error-message>@(ErrorService.GetErrorMessage(trustRefNumber))</govuk-input-error-message>
<govuk-input-error-message>@(ErrorService.GetErrorMessage(trustName))</govuk-input-error-message>
}
</govuk-input>

Expand Down
Loading

0 comments on commit 8004092

Please sign in to comment.