Skip to content

Commit

Permalink
Merge branch 'main' into CFODEV-559
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulCooperWorkJustice authored Aug 15, 2024
2 parents 72624ce + 85d88a1 commit c382827
Show file tree
Hide file tree
Showing 86 changed files with 4,327 additions and 16 deletions.
4 changes: 0 additions & 4 deletions src/Application/Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,4 @@
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="DependencyInjection.cs.bak" />
<None Remove="Application.csproj.bak" />
</ItemGroup>
</Project>
3 changes: 2 additions & 1 deletion src/Application/Common/Interfaces/IApplicationDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Cfo.Cats.Domain.Entities.Assessments;
using Cfo.Cats.Domain.Entities.Documents;
using Cfo.Cats.Domain.Entities.Participants;
using Cfo.Cats.Domain.Entities.Bios;
using Cfo.Cats.Domain.Identity;
using Cfo.Cats.Domain.ValueObjects;
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
Expand Down Expand Up @@ -30,7 +31,7 @@ public interface IApplicationDbContext
DbSet<KeyValue> KeyValues { get; }

DbSet<ParticipantAssessment> ParticipantAssessments { get; }

DbSet<ParticipantBio> ParticipantBios { get; }
DbSet<ParticipantEnrolmentHistory> ParticipantEnrolmentHistories { get; }

DbSet<Timeline> Timelines { get; }
Expand Down
69 changes: 69 additions & 0 deletions src/Application/Features/Bios/Commands/BeginBio.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Cfo.Cats.Application.Common.Security;
using Cfo.Cats.Application.Features.Bios.DTOs;
using Cfo.Cats.Application.Features.Bios.DTOs.V1.Pathways.Diversity;
using Cfo.Cats.Application.Features.Bios.DTOs.V1.Pathways.ChildhoodExperiences;
using Cfo.Cats.Application.Features.Bios.DTOs.V1.Pathways.RecentExperiences;
using Cfo.Cats.Application.SecurityConstants;
using Cfo.Cats.Domain.Entities.Bios;
using Newtonsoft.Json;
using Cfo.Cats.Application.Common.Validators;


namespace Cfo.Cats.Application.Features.Bios.Commands;

public static class BeginBio
{
[RequestAuthorize(Policy = SecurityPolicies.Enrol)]
public class Command : IRequest<Result<Guid>>
{
public required string ParticipantId { get; set; }
}

public class Handler : IRequestHandler<Command, Result<Guid>>
{
private readonly IUnitOfWork _unitOfWork;
private readonly ICurrentUserService _currentUserService;
public Handler(IUnitOfWork unitOfWork, ICurrentUserService currentUserService)
{
_unitOfWork = unitOfWork;
_currentUserService = currentUserService;
}

public async Task<Result<Guid>> Handle(Command request, CancellationToken cancellationToken)
{
Bio bio = new Bio()
{
Id = Guid.NewGuid(),
ParticipantId = request.ParticipantId,
Pathways =
[
new ChildhoodExperiencesPathway(),
new DiversityPathway(),
new RecentExperiencesPathway(),
]
};

string json = JsonConvert.SerializeObject(bio, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});

ParticipantBio bioSurvey = ParticipantBio.Create(bio.Id, request.ParticipantId, bioJson: json, BioStatus.NotStarted);
await _unitOfWork.DbContext.ParticipantBios.AddAsync(bioSurvey);
return Result<Guid>.Success(bio.Id);
}
}

public class Validator : AbstractValidator<Command>
{
public Validator()
{
RuleFor(c => c.ParticipantId)
.MinimumLength(9)
.MaximumLength(9)
.Matches(ValidationConstants.AlphaNumeric)
.WithMessage(string.Format(ValidationConstants.AlphaNumericMessage, nameof(Command.ParticipantId)));
}
}

}
75 changes: 75 additions & 0 deletions src/Application/Features/Bios/Commands/SaveBio.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using Cfo.Cats.Application.Common.Security;
using Cfo.Cats.Application.Common.Validators;
using Cfo.Cats.Application.Features.Bios.DTOs;
using Cfo.Cats.Application.SecurityConstants;
using Cfo.Cats.Domain.Entities.Bios;
using Newtonsoft.Json;

namespace Cfo.Cats.Application.Features.Bios.Commands;

public static class SaveBio
{
[RequestAuthorize(Policy = SecurityPolicies.Enrol)]
public class Command : IRequest<Result>
{
public bool Submit { get; set; } = false;

public required Bio Bio { get; set; }
}

public class Handler : IRequestHandler<Command, Result>
{
private readonly IUnitOfWork _unitOfWork;

public Handler(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;

}

public async Task<Result> Handle(Command request, CancellationToken cancellationToken)
{

ParticipantBio? bio = await _unitOfWork.DbContext.ParticipantBios
.FirstOrDefaultAsync(r => r.Id == request.Bio.Id && r.ParticipantId == request.Bio.ParticipantId, cancellationToken);

if(bio == null)
{
return Result.Failure("Bio not found");
}

bio.UpdateJson(JsonConvert.SerializeObject(request.Bio, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
}));
bio.UpdateStatus(BioStatus.InProgress);
if (request.Submit)
{
bio.UpdateStatus(BioStatus.Complete);
bio.Submit();
}

return Result.Success();
}
}

public class Validator : AbstractValidator<Command>
{
public Validator()
{
RuleFor(x => x.Bio)
.NotNull();

RuleFor(x => x.Bio.ParticipantId)
.MinimumLength(9)
.MaximumLength(9)
.Matches(ValidationConstants.AlphaNumeric)
.WithMessage(string.Format(ValidationConstants.AlphaNumericMessage, nameof(Command.Bio.ParticipantId)));

RuleFor(x => x.Bio.Id)
.NotEmpty();

}
}

}
72 changes: 72 additions & 0 deletions src/Application/Features/Bios/Commands/SkipBioForNow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Cfo.Cats.Application.Common.Security;
using Cfo.Cats.Application.Common.Validators;
using Cfo.Cats.Application.Features.Bios.DTOs;
using Cfo.Cats.Application.Features.Bios.DTOs.V1.Pathways.ChildhoodExperiences;
using Cfo.Cats.Application.Features.Bios.DTOs.V1.Pathways.Diversity;
using Cfo.Cats.Application.Features.Bios.DTOs.V1.Pathways.RecentExperiences;
using Cfo.Cats.Application.SecurityConstants;
using Cfo.Cats.Domain.Entities.Bios;
using DocumentFormat.OpenXml.Office.PowerPoint.Y2021.M06.Main;
using Newtonsoft.Json;

namespace Cfo.Cats.Application.Features.Bios.Commands;

public static class SkipBioForNow
{
[RequestAuthorize(Policy = SecurityPolicies.Enrol)]
public class Command : IRequest<Result>
{
public string? ParticipantId { get; set;}
}

public class Handler(IUnitOfWork unitOfWork) : IRequestHandler<Command, Result>
{
public async Task<Result> Handle(Command request, CancellationToken cancellationToken)
{
ParticipantBio? bio = await unitOfWork.DbContext.ParticipantBios.FirstOrDefaultAsync(r => r.ParticipantId == request.ParticipantId);

if (bio == null)
{
Bio newBio = new Bio()
{
Id = Guid.NewGuid(),
ParticipantId = request.ParticipantId!,
Pathways =
[
new ChildhoodExperiencesPathway(),
new DiversityPathway(),
new RecentExperiencesPathway(),
]
};

string json = JsonConvert.SerializeObject(newBio, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});

bio = ParticipantBio.Create(newBio.Id, request.ParticipantId!, json, BioStatus.NotStarted);
unitOfWork.DbContext.ParticipantBios.Add(bio);
}

bio.UpdateStatus(BioStatus.SkippedForNow);
return Result.Success();
}
}

public class Validator : AbstractValidator<Command>
{
private IUnitOfWork _unitOfWork;

public Validator(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;

RuleFor(x => x.ParticipantId)
.MinimumLength(9)
.MaximumLength(9)
.Matches(ValidationConstants.AlphaNumeric)
.WithMessage(string.Format(ValidationConstants.AlphaNumericMessage, nameof(Command.ParticipantId)));
}
}

}
8 changes: 8 additions & 0 deletions src/Application/Features/Bios/DTOs/Bio.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Cfo.Cats.Application.Features.Bios.DTOs;

public class Bio
{
public required Guid Id { get; set; }
public required string ParticipantId { get; set; }
public required PathwayBase[] Pathways { get; set; }
}
12 changes: 12 additions & 0 deletions src/Application/Features/Bios/DTOs/BioPathwayValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Cfo.Cats.Application.Features.Bios.DTOs;

public class BioPathwayValidator : AbstractValidator<PathwayBase>
{
public BioPathwayValidator()
{
RuleForEach(model => model.Questions())
.Must(q => q.IsValid())
.WithMessage("You must select a valid option!")
.OverridePropertyName("Questions");
}
}
9 changes: 9 additions & 0 deletions src/Application/Features/Bios/DTOs/BioValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Cfo.Cats.Application.Features.Bios.DTOs;

public class BioValidator : AbstractValidator<Bio>
{
public BioValidator()
{
RuleForEach(model => model.Pathways).SetValidator(new BioPathwayValidator());
}
}
19 changes: 19 additions & 0 deletions src/Application/Features/Bios/DTOs/ParticipantBioDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Cfo.Cats.Domain.Entities.Bios;

namespace Cfo.Cats.Application.Features.Bios.DTOs;

public class ParticipantBioDto
{
public required string ParticipantId { get; set; }
public required DateTime CreatedDate { get; set; }

private class Mapping : Profile
{
public Mapping()
{
CreateMap<ParticipantBio, ParticipantBioDto>()
.ForMember(p => p.CreatedDate, options => options.MapFrom(source => source.Created));
}
}
}

15 changes: 15 additions & 0 deletions src/Application/Features/Bios/DTOs/PathwayBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Newtonsoft.Json;

namespace Cfo.Cats.Application.Features.Bios.DTOs;

public abstract class PathwayBase
{
[JsonIgnore]
public abstract string Title { get; }

[JsonIgnore]
public abstract string Icon { get; }

public abstract IEnumerable<QuestionBase> Questions();

}
53 changes: 53 additions & 0 deletions src/Application/Features/Bios/DTOs/QuestionBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Newtonsoft.Json;

namespace Cfo.Cats.Application.Features.Bios.DTOs;

/// <summary>
/// Base class for the all questions
/// </summary>
public abstract partial class QuestionBase
{

#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
protected QuestionBase()
{
}
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

protected QuestionBase(string question, string[] options)
{
this.Question = question;
this.Options = options;
}

protected QuestionBase(string question, string otherInformation, string[] options)
: this(question, options)
{
this.OtherInformation = otherInformation;
}

/// <summary>
/// The question we are asking
/// </summary>
[JsonIgnore]
public string Question { get; }

/// <summary>
/// Any other errata about the question.
/// </summary>
[JsonIgnore]
public string? OtherInformation { get; }

/// <summary>
/// A collection of options for the answers
/// </summary>
[JsonIgnore]
public string[] Options { get; }

/// <summary>
/// Is the answer valid
/// </summary>
/// <returns>True if the answer has a valid return value</returns>
public abstract bool IsValid();
}

Loading

0 comments on commit c382827

Please sign in to comment.