Skip to content

Commit ee36747

Browse files
authored
Merge pull request #1498 from bcgov/stories/ecer-5182-new
Stories/ecer 5182: Reference form 1 for ICRA eligibility object employment references
2 parents cc9375b + 9579eb0 commit ee36747

File tree

11 files changed

+254
-3
lines changed

11 files changed

+254
-3
lines changed

src/ECER.Clients.RegistryPortal/ECER.Clients.RegistryPortal.Server/References/ReferencesEndpoints.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,34 @@ public void Register(IEndpointRouteBuilder endpointRouteBuilder)
9292
}
9393
return TypedResults.Ok();
9494
}).WithOpenApi("Handles reference optout", string.Empty, "reference_optout").WithParameterValidation();
95+
96+
endpointRouteBuilder.MapPost("/api/References/ICRAWorkExperience", async Task<Results<Ok, BadRequest<ProblemDetails>>> (ICRAWorkExperienceReferenceSubmissionRequest request, IMediator messageBus, IMapper mapper, CancellationToken ct) =>
97+
{
98+
if (request.Token == null) return TypedResults.BadRequest(new ProblemDetails { Detail = "Token is required" });
99+
100+
var recaptchaResult = await messageBus.Send(new Managers.Registry.Contract.Recaptcha.VerifyRecaptchaCommand(request.RecaptchaToken), ct);
101+
if (!recaptchaResult.Success)
102+
{
103+
var problemDetails = new ProblemDetails
104+
{
105+
Status = StatusCodes.Status400BadRequest,
106+
Detail = "Invalid recaptcha token",
107+
Extensions = { ["errors"] = recaptchaResult.ErrorCodes }
108+
};
109+
return TypedResults.BadRequest(problemDetails);
110+
}
111+
112+
var mapped = mapper.Map<Managers.Registry.Contract.ICRA.ICRAWorkExperienceReferenceSubmissionRequest>(request);
113+
var result = await messageBus.Send(new Managers.Registry.Contract.Applications.SubmitReferenceCommand(request.Token)
114+
{
115+
ICRAWorkExperienceReferenceSubmissionRequest = mapped
116+
}, ct);
117+
if (!result.IsSuccess)
118+
{
119+
return TypedResults.BadRequest(new ProblemDetails { Detail = result.ErrorMessage });
120+
}
121+
return TypedResults.Ok();
122+
}).WithOpenApi("Handles ICRA work experience reference submission", string.Empty, "icra_workExperience_reference_post").WithParameterValidation();
95123
}
96124
}
97125

@@ -115,6 +143,24 @@ public enum UnabletoProvideReferenceReasons
115143
Other
116144
}
117145

146+
public record ICRAWorkExperienceReferenceSubmissionRequest([Required] string Token, [Required] string RecaptchaToken)
147+
{
148+
public string? FirstName { get; set; }
149+
public string? LastName { get; set; }
150+
public string? EmailAddress { get; set; }
151+
public string? PhoneNumber { get; set; }
152+
public string? CountryId { get; set; }
153+
public string? EmployerName { get; set; }
154+
public string? PositionTitle { get; set; }
155+
public DateTime? StartDate { get; set; }
156+
public DateTime? EndDate { get; set; }
157+
public bool? WorkedWithChildren { get; set; }
158+
public IEnumerable<ChildcareAgeRanges>? ChildcareAgeRanges { get; set; }
159+
public ReferenceRelationship? ReferenceRelationship { get; set; }
160+
public DateTime? DateSigned { get; set; }
161+
162+
}
163+
118164
public record WorkExperienceReferenceDetails()
119165
{
120166
[Required]

src/ECER.Clients.RegistryPortal/ECER.Clients.RegistryPortal.Server/References/ReferencesMapper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ public ReferencesMapper()
1313
CreateMap<WorkExperienceReferenceSubmissionRequest, Managers.Registry.Contract.Applications.WorkExperienceReferenceSubmissionRequest>();
1414
CreateMap<WorkExperienceReferenceCompetenciesAssessment, Managers.Registry.Contract.Applications.WorkExperienceReferenceCompetenciesAssessment>();
1515
CreateMap<WorkExperienceReferenceDetails, Managers.Registry.Contract.Applications.WorkExperienceReferenceDetails>();
16+
CreateMap<ICRAWorkExperienceReferenceSubmissionRequest, Managers.Registry.Contract.ICRA.ICRAWorkExperienceReferenceSubmissionRequest>();
1617
}
1718
}

src/ECER.Managers.Registry.Contract/Applications/Contract.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ public record WorkExperienceReference(string? FirstName, string? LastName, strin
117117
public int? TotalNumberofHoursObserved { get; set; }
118118
public WorkExperienceTypes? Type { get; set; }
119119
}
120+
120121
public record ProfessionalDevelopment(string? Id, string? CourseName, string? OrganizationName, DateTime StartDate, DateTime EndDate)
121122
{
122123
public string? CourseorWorkshopLink { get; set; }
@@ -372,6 +373,7 @@ public record SubmitReferenceCommand(string Token) : IRequest<ReferenceSubmissio
372373
{
373374
public WorkExperienceReferenceSubmissionRequest? WorkExperienceReferenceSubmissionRequest { get; set; }
374375
public CharacterReferenceSubmissionRequest? CharacterReferenceSubmissionRequest { get; set; }
376+
public Managers.Registry.Contract.ICRA.ICRAWorkExperienceReferenceSubmissionRequest? ICRAWorkExperienceReferenceSubmissionRequest { get; set; }
375377
}
376378

377379
public record UpdateWorkExperienceReferenceCommand(WorkExperienceReference workExperienceRef, string applicationId, string referenceId, string userId) : IRequest<UpdateWorkExperienceReferenceResult>;

src/ECER.Managers.Registry.Contract/ICRA/Contract.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,23 @@ public record EmploymentReference
7272
public string? PhoneNumber { get; set; }
7373
}
7474

75+
public record ICRAWorkExperienceReferenceSubmissionRequest
76+
{
77+
public string? FirstName { get; set; }
78+
public string? LastName { get; set; }
79+
public string? EmailAddress { get; set; }
80+
public string? PhoneNumber { get; set; }
81+
public string? CountryId { get; set; }
82+
public string? EmployerName { get; set; }
83+
public string? PositionTitle { get; set; }
84+
public DateTime? StartDate { get; set; }
85+
public DateTime? EndDate { get; set; }
86+
public bool? WorkedWithChildren { get; set; }
87+
public IEnumerable<Applications.ChildcareAgeRanges>? ChildcareAgeRanges { get; set; }
88+
public Applications.ReferenceRelationship? ReferenceRelationship { get; set; }
89+
public DateTime? DateSigned { get; set; }
90+
}
91+
7592
public enum CertificateStatus
7693
{
7794
Valid,

src/ECER.Managers.Registry/ApplicationHandlers.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using ECER.Managers.Registry.Contract.Applications;
77
using ECER.Resources.Documents.Applications;
88
using ECER.Resources.Documents.PortalInvitations;
9+
using ECER.Resources.Documents.ICRA;
910
using ECER.Utilities.DataverseSdk.Model;
1011
using MediatR;
1112

@@ -20,7 +21,8 @@ public class ApplicationHandlers(
2021
IApplicationRepository applicationRepository,
2122
IMapper mapper,
2223
IApplicationValidationEngineResolver validationResolver,
23-
EcerContext ecerContext)
24+
EcerContext ecerContext,
25+
IICRARepository iCRARepository)
2426
: IRequestHandler<SaveDraftApplicationCommand, Contract.Applications.Application?>,
2527
IRequestHandler<CancelDraftApplicationCommand, string>,
2628
IRequestHandler<SubmitApplicationCommand, ApplicationSubmissionResult>,
@@ -220,10 +222,19 @@ public async Task<ReferenceSubmissionResult> Handle(SubmitReferenceCommand reque
220222
case InviteType.WorkExperienceReferenceforApplication:
221223
submitReferenceRequest = mapper.Map<Resources.Documents.Applications.WorkExperienceReferenceSubmissionRequest>(request.WorkExperienceReferenceSubmissionRequest);
222224
break;
225+
226+
case InviteType.WorkExperienceReferenceforICRA:
227+
var icraReferenceId = portalInvitation.WorkexperienceReferenceId!;
228+
var icraPayload = mapper.Map<Resources.Documents.ICRA.ICRAWorkExperienceReferenceSubmissionRequest>(request.ICRAWorkExperienceReferenceSubmissionRequest!);
229+
await iCRARepository.SubmitEmploymentReference(icraReferenceId, icraPayload, cancellationToken);
230+
break;
223231
}
224232
submitReferenceRequest.PortalInvitation = portalInvitation;
225233
submitReferenceRequest.DateSigned = DateTime.Today;
226-
await applicationRepository.SubmitReference(submitReferenceRequest, cancellationToken);
234+
if (portalInvitation.InviteType == InviteType.CharacterReference || portalInvitation.InviteType == InviteType.WorkExperienceReferenceforApplication)
235+
{
236+
await applicationRepository.SubmitReference(submitReferenceRequest, cancellationToken);
237+
}
227238
await portalInvitationRepository.Complete(new CompletePortalInvitationCommand(transformationResponse.PortalInvitation), cancellationToken);
228239
ecerContext.CommitTransaction();
229240
return ReferenceSubmissionResult.Success();

src/ECER.Managers.Registry/ICRAEligibilityMapper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ public ICRAEligibilityMapper()
1010
CreateMap<Contract.ICRA.ICRAEligibility, ICRAEligibility>().ReverseMap();
1111
CreateMap<Contract.ICRA.InternationalCertification, InternationalCertification>().ReverseMap();
1212
CreateMap<Contract.ICRA.EmploymentReference, Resources.Documents.ICRA.EmploymentReference>().ReverseMap();
13+
CreateMap<Contract.ICRA.ICRAWorkExperienceReferenceSubmissionRequest, Resources.Documents.ICRA.ICRAWorkExperienceReferenceSubmissionRequest>().ReverseMap();
1314
}
1415
}

src/ECER.Resources.Documents/ICRA/ICRARepository.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,27 @@ public async Task<string> SetIneligibleForUnitTests(string icraEligibilityId, Ca
114114
context.SaveChanges();
115115
return icraEligibilityId;
116116
}
117+
118+
public async Task<string> SubmitEmploymentReference(string referenceId, ICRAWorkExperienceReferenceSubmissionRequest request, CancellationToken cancellationToken)
119+
{
120+
await Task.CompletedTask;
121+
122+
var workExperienceReference = context.ecer_WorkExperienceRefSet.Single(c => c.ecer_WorkExperienceRefId == Guid.Parse(referenceId));
123+
124+
mapper.Map(request, workExperienceReference);
125+
126+
if (!string.IsNullOrWhiteSpace(request.CountryId) && Guid.TryParse(request.CountryId, out var countryGuid))
127+
{
128+
var ecer_country = context.ecer_CountrySet.SingleOrDefault(c => c.ecer_CountryId == countryGuid);
129+
if (ecer_country != null)
130+
{
131+
context.AddLink(workExperienceReference, ecer_WorkExperienceRef.Fields.ecer_Country, ecer_country);
132+
}
133+
}
134+
135+
workExperienceReference.StatusCode = ecer_WorkExperienceRef_StatusCode.ICRAEligibilitySubmitted;
136+
context.UpdateObject(workExperienceReference);
137+
context.SaveChanges();
138+
return workExperienceReference.ecer_WorkExperienceRefId.ToString()!;
139+
}
117140
}

src/ECER.Resources.Documents/ICRA/ICRARepositoryMapper.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,24 @@ public ICRARepositoryMapper()
8383
.ForMember(d => d.LastName, opts => opts.MapFrom(s => s.ecer_LastName))
8484
.ForMember(d => d.EmailAddress, opts => opts.MapFrom(s => s.ecer_EmailAddress))
8585
.ForMember(d => d.PhoneNumber, opts => opts.MapFrom(s => s.ecer_PhoneNumber));
86+
87+
88+
89+
CreateMap<ICRAWorkExperienceReferenceSubmissionRequest, ecer_WorkExperienceRef>(MemberList.Source)
90+
.ForSourceMember(s => s.CountryId, opts => opts.DoNotValidate())
91+
.ForSourceMember(s => s.WorkedWithChildren, opts => opts.DoNotValidate())
92+
.ForMember(d => d.ecer_referencefirstname, opts => opts.MapFrom(s => s.FirstName))
93+
.ForMember(d => d.ecer_referencelastname, opts => opts.MapFrom(s => s.LastName))
94+
.ForMember(d => d.ecer_referenceemailaddress, opts => opts.MapFrom(s => s.EmailAddress))
95+
.ForMember(d => d.ecer_ReferencePhoneNumber, opts => opts.MapFrom(s => s.PhoneNumber))
96+
.ForMember(d => d.ecer_NameofEmployer, opts => opts.MapFrom(s => s.EmployerName))
97+
.ForMember(d => d.ecer_Role, opts => opts.MapFrom(s => s.PositionTitle))
98+
.ForMember(d => d.ecer_StartDate, opts => opts.MapFrom(s => s.StartDate))
99+
.ForMember(d => d.ecer_EndDate, opts => opts.MapFrom(s => s.EndDate))
100+
.ForMember(d => d.ecer_Applicantworkchildren, opts => opts.MapFrom(s => s.WorkedWithChildren.HasValue ? (s.WorkedWithChildren.Value ? ecer_YesNoNull.Yes : ecer_YesNoNull.No) : (ecer_YesNoNull?)null))
101+
.ForMember(d => d.ecer_ChildcareAgeRangeNew, opts => opts.MapFrom(s => s.ChildcareAgeRanges))
102+
.ForMember(d => d.ecer_RelationshiptoApplicant, opts => opts.MapFrom(s => s.ReferenceRelationship))
103+
.ForMember(d => d.ecer_DateSigned, opts => opts.MapFrom(s => s.DateSigned));
86104
}
87105

88106
public static string IdOrEmpty(EntityReference? reference) =>

src/ECER.Resources.Documents/ICRA/IICRARepository.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
namespace ECER.Resources.Documents.ICRA;
1+

2+
using ECER.Resources.Documents.Applications;
3+
4+
namespace ECER.Resources.Documents.ICRA;
25

36
public interface IICRARepository
47
{
@@ -9,6 +12,8 @@ public interface IICRARepository
912
Task<string> Submit(string icraEligibilityId, CancellationToken cancellationToken);
1013

1114
Task<string> SetIneligibleForUnitTests(string icraEligibilityId, CancellationToken cancellationToken);
15+
16+
Task<string> SubmitEmploymentReference(string referenceId, ICRAWorkExperienceReferenceSubmissionRequest request, CancellationToken cancellationToken);
1217
}
1318

1419
public record ICRAQuery
@@ -60,6 +65,24 @@ public record EmploymentReference
6065
public string? PhoneNumber { get; set; }
6166
}
6267

68+
69+
public record ICRAWorkExperienceReferenceSubmissionRequest
70+
{
71+
public string? FirstName { get; set; }
72+
public string? LastName { get; set; }
73+
public string? EmailAddress { get; set; }
74+
public string? PhoneNumber { get; set; }
75+
public string? CountryId { get; set; }
76+
public string? EmployerName { get; set; }
77+
public string? PositionTitle { get; set; }
78+
public DateTime? StartDate { get; set; }
79+
public DateTime? EndDate { get; set; }
80+
public bool? WorkedWithChildren { get; set; }
81+
public IEnumerable<ChildcareAgeRanges>? ChildcareAgeRanges { get; set; }
82+
public ReferenceRelationship? ReferenceRelationship { get; set; }
83+
public DateTime? DateSigned { get; set; }
84+
}
85+
6386
public enum CertificateStatus
6487
{
6588
Valid,
@@ -78,3 +101,5 @@ public enum ICRAStatus
78101
Submitted,
79102
ReadyforAssessment
80103
}
104+
105+

src/ECER.Tests/Integration/RegistryApi/ReferenceTests.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,4 +260,55 @@ await Host.Scenario(_ =>
260260
_.StatusCodeShouldBeOk();
261261
});
262262
}
263+
264+
[Fact]
265+
public async Task SubmitICRAWorkExperienceReference_ShouldReturnOk()
266+
{
267+
var bus = Fixture.Services.GetRequiredService<IMediator>();
268+
var portalInvitation = Fixture.portalInvitationICRAWorkExperienceReferenceIdSubmit;
269+
var packingResponse = await bus.Send(new GenerateInviteLinkCommand(portalInvitation, 7), CancellationToken.None);
270+
packingResponse.ShouldNotBeNull();
271+
272+
var token = packingResponse.VerificationLink.Split('/')[2];
273+
var faker = new Faker("en_CA");
274+
var icraRequest = new ICRAWorkExperienceReferenceSubmissionRequest(
275+
token,
276+
faker.Random.Word())
277+
{
278+
FirstName = faker.Person.FirstName,
279+
LastName = faker.Person.LastName,
280+
EmailAddress = "[email protected]",
281+
PhoneNumber = faker.Phone.PhoneNumber(),
282+
EmployerName = faker.Company.CompanyName(),
283+
PositionTitle = faker.Name.JobTitle(),
284+
StartDate = faker.Date.Past(),
285+
EndDate = faker.Date.Soon(),
286+
WorkedWithChildren = faker.Random.Bool(),
287+
ChildcareAgeRanges = new List<ChildcareAgeRanges> { ChildcareAgeRanges._35years },
288+
ReferenceRelationship = ReferenceRelationship.Supervisor
289+
};
290+
291+
await Host.Scenario(_ =>
292+
{
293+
_.Post.Json(icraRequest).ToUrl($"/api/References/ICRAWorkExperience");
294+
_.StatusCodeShouldBeOk();
295+
});
296+
}
297+
298+
[Fact]
299+
public async Task OptOutICRAWorkExperienceReference_ShouldReturnOk()
300+
{
301+
var bus = Fixture.Services.GetRequiredService<IMediator>();
302+
var portalInvitation = Fixture.portalInvitationICRAWorkExperienceReferenceIdOptout;
303+
var packingResponse = await bus.Send(new GenerateInviteLinkCommand(portalInvitation, 7), CancellationToken.None);
304+
packingResponse.ShouldNotBeNull();
305+
306+
var token = packingResponse.VerificationLink.Split('/')[2];
307+
var optOutReferenceRequest = new OptOutReferenceRequest(token, UnabletoProvideReferenceReasons.Idonotknowthisperson, Faker.Random.Word());
308+
await Host.Scenario(_ =>
309+
{
310+
_.Post.Json(optOutReferenceRequest).ToUrl($"/api/References/OptOut");
311+
_.StatusCodeShouldBeOk();
312+
});
313+
}
263314
}

0 commit comments

Comments
 (0)