Skip to content

Commit

Permalink
Merge pull request #39 from OS2Valghalla/dev
Browse files Browse the repository at this point in the history
Merge branch 'Dev'
  • Loading branch information
ramogens-OS2 authored Apr 29, 2024
2 parents 48a053c + 1f124c2 commit 96c9e3d
Show file tree
Hide file tree
Showing 18 changed files with 143 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
public sealed record EvaluatedParticipant
{
public Guid Id { get; init; }
public int Age { get; init; }
public DateTime Birthdate { get; init; }
public string? MunicipalityCode { get; set; }
public string? CountryCode { get; set; }
public bool Deceased { get; init; }
Expand Down
10 changes: 10 additions & 0 deletions Valghalla.Application/TaskValidation/EvaluatedTask.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Valghalla.Application.TaskValidation
{
public sealed record EvaluatedTask
{
public Guid TaskAssignmentId { get; init; }
public Guid TaskTypeId { get; init; }
public DateTime TaskDate { get; init; }
public bool ValidationNotRequired { get; init; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
public interface ITaskValidationRepository
{
Task<IEnumerable<TaskValidationRule>> GetValidationRules(Guid electionId, CancellationToken cancellationToken);
Task<EvaluatedTaskType> GetEvaluatedTaskType(Guid taskTypeId, CancellationToken cancellationToken);
Task<EvaluatedTaskType> GetEvaluatedTaskTypeByTaskId(Guid taskId, CancellationToken cancellationToken);
Task<EvaluatedTask> GetEvaluatedTask(Guid taskAssignmentId, CancellationToken cancellationToken);
Task<EvaluatedParticipant> GetEvaluatedParticipant(Guid participantId, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
{
public interface ITaskValidationService
{
TaskValidationResult Execute(EvaluatedTaskType taskType, EvaluatedParticipant participant, IEnumerable<TaskValidationRule> rules);
Task<TaskValidationResult> ExecuteAsync(Guid taskTypeId, Guid electionId, Guid participantId, CancellationToken cancellationToken);
Task<TaskValidationResult> ExecuteAsync(Guid taskTypeId, Guid electionId, string cpr, CancellationToken cancellationToken);
TaskValidationResult Execute(EvaluatedTask taskAssignment, EvaluatedParticipant participant, IEnumerable<TaskValidationRule> rules);
Task<TaskValidationResult> ExecuteAsync(Guid taskAssignmentId, Guid electionId, Guid participantId, CancellationToken cancellationToken);
Task<TaskValidationResult> ExecuteAsync(Guid taskAssignmentId, Guid electionId, string cpr, CancellationToken cancellationToken);
}
}
46 changes: 37 additions & 9 deletions Valghalla.Application/TaskValidation/TaskValidationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public TaskValidationService(ITaskValidationRepository taskValidationRepository,
this.cprService = cprService;
}

public TaskValidationResult Execute(EvaluatedTaskType taskType, EvaluatedParticipant participant, IEnumerable<TaskValidationRule> rules)
public TaskValidationResult Execute(EvaluatedTask taskAssignment, EvaluatedParticipant participant, IEnumerable<TaskValidationRule> rules)
{
var failedRules = new List<TaskValidationRule>();

Expand All @@ -25,14 +25,19 @@ public TaskValidationResult Execute(EvaluatedTaskType taskType, EvaluatedPartici
failedRules.Add(TaskValidationRule.Alive);
}

if (taskType.ValidationNotRequired)
if (taskAssignment.ValidationNotRequired)
{
return new(failedRules);
}

if (rules.Any(i => i.Id == TaskValidationRule.Age18.Id) && participant.Age < 18)
if (rules.Any(i => i.Id == TaskValidationRule.Age18.Id))
{
failedRules.Add(TaskValidationRule.Age18);
var age = CalculateAge(participant, taskAssignment);

if (age < 18)
{
failedRules.Add(TaskValidationRule.Age18);
}
}

if (rules.Any(i => i.Id == TaskValidationRule.Disenfranchised.Id) && participant.Disenfranchised)
Expand All @@ -53,25 +58,25 @@ public TaskValidationResult Execute(EvaluatedTaskType taskType, EvaluatedPartici
return new(failedRules);
}

public async Task<TaskValidationResult> ExecuteAsync(Guid taskTypeId, Guid electionId, Guid participantId, CancellationToken cancellationToken)
public async Task<TaskValidationResult> ExecuteAsync(Guid taskAssignmentId, Guid electionId, Guid participantId, CancellationToken cancellationToken)
{
var taskType = await taskValidationRepository.GetEvaluatedTaskType(taskTypeId, cancellationToken);
var taskType = await taskValidationRepository.GetEvaluatedTask(taskAssignmentId, cancellationToken);
var participant = await taskValidationRepository.GetEvaluatedParticipant(participantId, cancellationToken);
var rules = await taskValidationRepository.GetValidationRules(electionId, cancellationToken);

return Execute(taskType, participant, rules);
}

public async Task<TaskValidationResult> ExecuteAsync(Guid taskId, Guid electionId, string cpr, CancellationToken cancellationToken)
public async Task<TaskValidationResult> ExecuteAsync(Guid taskAssignmentId, Guid electionId, string cpr, CancellationToken cancellationToken)
{
var taskType = await taskValidationRepository.GetEvaluatedTaskTypeByTaskId(taskId, cancellationToken);
var taskType = await taskValidationRepository.GetEvaluatedTask(taskAssignmentId, cancellationToken);
var cprPersonInfo = await cprService.ExecuteAsync(cpr);
var record = cprPersonInfo.ToRecord();

var evaluatedParticipant = new EvaluatedParticipant()
{
Id = Guid.Empty,
Age = record.Age,
Birthdate = record.Birthdate,
CountryCode = record.CountryCode,
Deceased = record.Deceased,
Disenfranchised = record.Disenfranchised,
Expand All @@ -82,5 +87,28 @@ public async Task<TaskValidationResult> ExecuteAsync(Guid taskId, Guid electionI

return Execute(taskType, evaluatedParticipant, rules);
}

private static int CalculateAge(EvaluatedParticipant participant, EvaluatedTask taskAssignment)
{
var taskDateLocalTime = taskAssignment.TaskDate.ToLocalTime();
var birthDateLocalTime = participant.Birthdate.ToLocalTime();
var taskDate = new DateTime(taskDateLocalTime.Year, taskDateLocalTime.Month, taskDateLocalTime.Day);
var birthdate = new DateTime(birthDateLocalTime.Year, birthDateLocalTime.Month, birthDateLocalTime.Day);

var months = taskDate.Month - birthdate.Month;
var years = taskDate.Year - birthdate.Year;

if (taskDate.Day < birthdate.Day)
{
months--;
}

if (months < 0)
{
years--;
}

return years;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public async Task<Response> Handle(AcceptTaskCommand command, CancellationToken
return Response.Ok(TaskConfirmationResult.ConflictResult());
}

var validationResult = await taskValidationService.ExecuteAsync(taskAssignment.TaskTypeId, taskAssignment.ElectionId, participantId, cancellationToken);
var validationResult = await taskValidationService.ExecuteAsync(taskAssignment.Id, taskAssignment.ElectionId, participantId, cancellationToken);

if (!validationResult.Succeed)
{
Expand Down
2 changes: 1 addition & 1 deletion Valghalla.External.Web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"scripts": {
"ng": "ng",
"start": "node --max-http-header-size=100000 ./serve",
"build": "ng build",
"build": "ng build --output-hashing=all",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"lint": "ng lint",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,23 @@ public async Task<IEnumerable<TaskValidationRule>> GetValidationRules(Guid elect
return entities.Select(i => new TaskValidationRule(i.ValidationRuleId)).ToArray();
}

public async Task<EvaluatedTaskType> GetEvaluatedTaskType(Guid taskTypeId, CancellationToken cancellationToken)
{
var entity = await taskTypes
.Where(i => i.Id == taskTypeId)
.SingleAsync(cancellationToken);

return mapper.Map<EvaluatedTaskType>(entity);
}

public async Task<EvaluatedTaskType> GetEvaluatedTaskTypeByTaskId(Guid taskId, CancellationToken cancellationToken)
public async Task<EvaluatedTask> GetEvaluatedTask(Guid taskAssignmentId, CancellationToken cancellationToken)
{
var task = await tasks
.Where(i => i.Id == taskId)
.Where(i => i.Id == taskAssignmentId)
.SingleAsync(cancellationToken);

var entity = await taskTypes
.Where(i => i.Id == task.TaskTypeId)
.SingleAsync(cancellationToken);

return mapper.Map<EvaluatedTaskType>(entity);
return new EvaluatedTask()
{
TaskAssignmentId = taskAssignmentId,
TaskTypeId = entity.Id,
TaskDate = task.TaskDate,
ValidationNotRequired = entity.ValidationNotRequired
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { })));

var result = validator.TestValidate(command);
Expand All @@ -92,7 +92,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { })));

var result = validator.TestValidate(command);
Expand All @@ -118,7 +118,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { })));

var result = validator.TestValidate(command);
Expand All @@ -144,7 +144,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { })));

var result = validator.TestValidate(command);
Expand Down Expand Up @@ -172,7 +172,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { new TaskValidationRule(TaskValidationRule.Alive.Id) })));

var result = validator.TestValidate(command);
Expand Down Expand Up @@ -202,7 +202,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { new TaskValidationRule(TaskValidationRule.Age18.Id) })));

var result = validator.TestValidate(command);
Expand Down Expand Up @@ -232,7 +232,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { new TaskValidationRule(TaskValidationRule.ResidencyMunicipality.Id) })));

var result = validator.TestValidate(command);
Expand Down Expand Up @@ -262,7 +262,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { new TaskValidationRule(TaskValidationRule.Disenfranchised.Id) })));

var result = validator.TestValidate(command);
Expand Down Expand Up @@ -292,7 +292,7 @@ public void AssignParticipantToTaskCommandHandlerTests_Should_ReturnValidationEr
var validator = new AssignParticipantToTaskCommandValidator(_mockTaskValidationService, _mockElectionWorkLocationTasksQueryRepository);

_mockTaskValidationService
.ExecuteAsync(request.TaskTypeId, request.ElectionId, request.ParticipantId, default)
.ExecuteAsync(request.TaskAssignmentId, request.ElectionId, request.ParticipantId, default)
.Returns(Task.FromResult(new TaskValidationResult(new List<TaskValidationRule> { new TaskValidationRule(TaskValidationRule.Citizenship.Id) })));

var result = validator.TestValidate(command);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public AssignParticipantToTaskCommandValidator(ITaskValidationService taskValida
.Must((command) => !electionWorkLocationTasksQueryRepository.CheckIfTaskHasConflictsAsync(command.ElectionId, command.TaskAssignmentId, command.ParticipantId, default).Result)
.WithMessage("tasks.error.task_conflict");

RuleFor(x => taskValidationService.ExecuteAsync(x.TaskTypeId, x.ElectionId, x.ParticipantId, default).Result).Custom((result, context) =>
RuleFor(x => taskValidationService.ExecuteAsync(x.TaskAssignmentId, x.ElectionId, x.ParticipantId, default).Result).Custom((result, context) =>
{
if (!result.IsAlive())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ public sealed record ParticipantTaskDetailsResponse
public string? ParticipantEmail { get; set; }
public string? ParticipantAddress { get; set; }
public string? ParticipantSpecialDiets { get; set; }
public bool ParticipantDigitalPostStatus { get; set; }
public string? AreaName { get; set; }
public string? TeamName { get; set; }
public string? WorkLocation { get; set; }
public string? TaskTypeName { get; set; }
public DateTime? TaskDate { get; set; }
public string? TaskStatus { get; set; }
Expand Down
2 changes: 2 additions & 0 deletions Valghalla.Internal.Infrastructure/Automapper/TaskProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public TaskProfile()
.ForMember(f => f.ParticipantName, opt => opt.MapFrom(src => src.Participant != null ? src.Participant.FirstName + " " + src.Participant.LastName : null))
.ForMember(f => f.ParticipantCpr, opt => opt.MapFrom(src => src.Participant!.Cpr))
.ForMember(f => f.ParticipantAge, opt => opt.MapFrom(src => src.Participant!.Age))
.ForMember(f => f.ParticipantDigitalPostStatus, opt => opt.MapFrom(src => !src.Participant!.ExemptDigitalPost))
.ForMember(f => f.ParticipantPhoneNumber, opt => opt.MapFrom(src => src.Participant!.MobileNumber))
.ForMember(f => f.ParticipantEmail, opt => opt.MapFrom(src => src.Participant!.Email))
.ForMember(f => f.ParticipantAddress, opt => opt.MapFrom(src => string.Join(", ", (new List<string>() { src.Participant!.CoAddress, src.Participant!.StreetAddress, src.Participant!.PostalCode, src.Participant!.City }).Where(s => !string.IsNullOrEmpty(s)))))
Expand All @@ -64,6 +65,7 @@ public TaskProfile()
.ForMember(f => f.TeamName, opt => opt.MapFrom(src => src.Team!.Name))
.ForMember(f => f.TaskTypeName, opt => opt.MapFrom(src => src.TaskType!.Title))
.ForMember(f => f.TaskDate, opt => opt.MapFrom(src => src.TaskDate))
.ForMember(f => f.WorkLocation, opt => opt.MapFrom(src => src.WorkLocation.Title))
.ForMember(f => f.TaskStartTime, opt => opt.MapFrom(src => src.TaskType!.StartTime))
.ForMember(f => f.TaskPayment, opt => opt.MapFrom(src => src.TaskType!.Payment))
.ForMember(f => f.TaskStatus, opt => opt.MapFrom(src => src.Accepted ? TaskStatus.Accepted.ToString() : (src.ParticipantId.HasValue ? TaskStatus.Unanswered.ToString() : TaskStatus.Available.ToString())))
Expand Down
2 changes: 1 addition & 1 deletion Valghalla.Internal.Web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"scripts": {
"ng": "ng",
"start": "node --max-http-header-size=100000 ./serve",
"build": "ng build",
"build": "ng build --output-hashing=all",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"lint": "ng lint",
Expand Down
2 changes: 2 additions & 0 deletions Valghalla.Internal.Web/src/assets/i18n/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@
"participant_list": {
"page_title": "Deltagerlister",
"labels": {
"participant_digital_post_status": "Digital Post status",
"work_location": "Arbejdssted",
"show_preview": "Vis preview",
"export_to_excel": "Eksportér som Excel-fil",
"export_to_csv": "Eksportér som CSV-fil",
Expand Down
4 changes: 3 additions & 1 deletion Valghalla.Internal.Web/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@
"participant_list": {
"page_title": "Participant lists",
"labels": {
"participant_digital_post_status": "Digital Post status",
"work_location": "Work location",
"show_preview": "Show preview",
"export_to_excel": "Export to Excel",
"export_to_csv": "Export to CSV",
Expand Down Expand Up @@ -1162,4 +1164,4 @@
"content": "404! Can't find the resource you are looking for"
}
}
}
}
Loading

0 comments on commit 96c9e3d

Please sign in to comment.