Skip to content

Commit 5a3d0ce

Browse files
authored
Merge pull request #1541 from bcgov/tasks/ecer-5552
ECER-5552: PortalInvitation handlers refactored
2 parents 62bc4f5 + f9e6d95 commit 5a3d0ce

File tree

15 files changed

+171
-68
lines changed

15 files changed

+171
-68
lines changed

src/ECER.Clients.PSPPortal/ecer.clients.pspportal.client/package-lock.json

Lines changed: 0 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ public record ICRAWorkExperienceReferenceSubmissionRequest([Required] string Tok
157157
public bool? WorkedWithChildren { get; set; }
158158
public IEnumerable<ChildcareAgeRanges>? ChildcareAgeRanges { get; set; }
159159
public ReferenceRelationship? ReferenceRelationship { get; set; }
160+
public bool WillProvideReference { get; set; }
160161
public DateTime? DateSigned { get; set; }
161162

162163
}

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/package-lock.json

Lines changed: 0 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public record ICRAWorkExperienceReferenceSubmissionRequest
8686
public bool? WorkedWithChildren { get; set; }
8787
public IEnumerable<Applications.ChildcareAgeRanges>? ChildcareAgeRanges { get; set; }
8888
public Applications.ReferenceRelationship? ReferenceRelationship { get; set; }
89+
public bool WillProvideReference { get; set; }
8990
public DateTime? DateSigned { get; set; }
9091
}
9192

src/ECER.Managers.Registry/Configurer.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using ECER.Infrastructure.Common;
22
using ECER.Managers.Registry.Contract.Registrants;
3+
using ECER.Managers.Registry.PortalInvitations;
34
using ECER.Managers.Registry.UserRegistrationIdentityService;
45
using Microsoft.Extensions.Configuration;
56
using Microsoft.Extensions.DependencyInjection;
@@ -17,6 +18,9 @@ public void Configure([NotNull] ConfigurationContext configurationContext)
1718
configurationContext.Services.AddTransient<ICRAEligibilityHandlers>();
1819
configurationContext.Services.AddTransient<RegistrantHandlers>();
1920
configurationContext.Services.AddTransient<PortalInvitationHandlers>();
21+
configurationContext.Services.AddTransient<IPortalInvitationVerificationHandler, ReferencePortalInvitationVerificationHandler>();
22+
configurationContext.Services.AddTransient<IPortalInvitationVerificationHandler, IcraReferencePortalInvitationVerificationHandler>();
23+
configurationContext.Services.AddTransient<IPortalInvitationVerificationHandler, PspPortalInvitationVerificationHandler>();
2024
configurationContext.Services.AddTransient<RecaptchaHandlers>();
2125
configurationContext.Services.Configure<RecaptchaAppSettings>(recaptchaAppSettings =>
2226
configurationContext.Configuration.GetSection("Recaptcha").Bind(recaptchaAppSettings));
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using AutoMapper;
2+
using ECER.Engines.Transformation;
3+
using ECER.Engines.Transformation.PortalInvitations;
4+
using ECER.Managers.Registry.Contract.PortalInvitations;
5+
using ECER.Resources.Documents.PortalInvitations;
6+
using MediatR;
7+
8+
namespace ECER.Managers.Registry.PortalInvitations;
9+
10+
public class PortalInvitationHandlers(
11+
IPortalInvitationTransformationEngine transformationEngine,
12+
IPortalInvitationRepository portalInvitationRepository,
13+
IMapper mapper,
14+
IEnumerable<IPortalInvitationVerificationHandler> verificationHandlers)
15+
: IRequestHandler<PortalInvitationVerificationQuery, PortalInvitationVerificationQueryResult>
16+
{
17+
public async Task<PortalInvitationVerificationQueryResult> Handle(PortalInvitationVerificationQuery request, CancellationToken cancellationToken)
18+
{
19+
ArgumentNullException.ThrowIfNull(request);
20+
var response = await transformationEngine.Transform(new DecryptInviteTokenRequest(request.VerificationToken))! as DecryptInviteTokenResponse ?? throw new InvalidCastException("Invalid response type");
21+
if (response.PortalInvitation == Guid.Empty)
22+
{
23+
return PortalInvitationVerificationQueryResult.Failure("Invalid Token");
24+
}
25+
26+
var portalInvitation = await portalInvitationRepository.Query(new PortalInvitationQuery(response.PortalInvitation), cancellationToken);
27+
if (portalInvitation == null)
28+
{
29+
return PortalInvitationVerificationQueryResult.Failure("Portal Invitation not found");
30+
}
31+
var portalInvitation_Manager = mapper.Map<Contract.PortalInvitations.PortalInvitation>(portalInvitation);
32+
var handler = verificationHandlers.FirstOrDefault(h => h.CanHandle(portalInvitation_Manager.InviteType));
33+
if (handler == null)
34+
{
35+
return PortalInvitationVerificationQueryResult.Failure("Unsupported invite type.");
36+
}
37+
38+
return await handler.Verify(portalInvitation_Manager, cancellationToken);
39+
}
40+
}

src/ECER.Managers.Registry/PortalInvitationMapper.cs renamed to src/ECER.Managers.Registry/PortalInvitations/PortalInvitationMapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using ECER.Resources.Documents.Applications;
33
using ECER.Resources.Documents.PortalInvitations;
44

5-
namespace ECER.Managers.Registry;
5+
namespace ECER.Managers.Registry.PortalInvitations;
66

77
public class PortalInvitationMapper : Profile
88
{
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using ECER.Managers.Registry.Contract.PortalInvitations;
2+
3+
namespace ECER.Managers.Registry;
4+
5+
public interface IPortalInvitationVerificationHandler
6+
{
7+
bool CanHandle(InviteType? inviteType);
8+
Task<PortalInvitationVerificationQueryResult> Verify(PortalInvitation portalInvitation, CancellationToken cancellationToken);
9+
}
10+
11+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using AutoMapper;
2+
using ECER.Managers.Registry.Contract.PortalInvitations;
3+
using ECER.Resources.Accounts.Registrants;
4+
5+
namespace ECER.Managers.Registry;
6+
7+
public class IcraReferencePortalInvitationVerificationHandler(
8+
IRegistrantRepository registrantRepository,
9+
IMapper mapper)
10+
: IPortalInvitationVerificationHandler
11+
{
12+
public bool CanHandle(InviteType? inviteType)
13+
{
14+
return inviteType == InviteType.WorkExperienceReferenceforICRA;
15+
}
16+
17+
public async Task<PortalInvitationVerificationQueryResult> Verify(PortalInvitation portalInvitation, CancellationToken cancellationToken)
18+
{
19+
var emptyGuidString = Guid.Empty.ToString();
20+
if (portalInvitation == null || portalInvitation.WorkexperienceReferenceId == emptyGuidString)
21+
{
22+
return PortalInvitationVerificationQueryResult.Failure("Reference not found");
23+
}
24+
25+
var registrantResult = await registrantRepository.Query(new RegistrantQuery() { ByUserId = portalInvitation.ApplicantId }, cancellationToken);
26+
var applicant = registrantResult.SingleOrDefault();
27+
if (applicant == null)
28+
{
29+
return PortalInvitationVerificationQueryResult.Failure("Applicant not found");
30+
}
31+
32+
var result = mapper.Map<Contract.PortalInvitations.PortalInvitation>(portalInvitation);
33+
34+
switch (result.StatusCode)
35+
{
36+
case Contract.PortalInvitations.PortalInvitationStatusCode.Completed:
37+
return PortalInvitationVerificationQueryResult.Failure("Reference has already been submitted.");
38+
case Contract.PortalInvitations.PortalInvitationStatusCode.Expired:
39+
return PortalInvitationVerificationQueryResult.Failure("Reference has expired.");
40+
case Contract.PortalInvitations.PortalInvitationStatusCode.Cancelled:
41+
return PortalInvitationVerificationQueryResult.Failure("Reference has been cancelled.");
42+
case Contract.PortalInvitations.PortalInvitationStatusCode.Failed:
43+
return PortalInvitationVerificationQueryResult.Failure("Reference has failed.");
44+
}
45+
46+
// For ICRA references there is no ApplicationId; do not attempt to load application or certification data
47+
result.ApplicantFirstName = applicant.Profile.FirstName;
48+
result.ApplicantLastName = applicant.Profile.LastName;
49+
50+
return PortalInvitationVerificationQueryResult.Success(result);
51+
}
52+
}
53+
54+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using AutoMapper;
2+
using ECER.Managers.Registry.Contract.PortalInvitations;
3+
4+
namespace ECER.Managers.Registry;
5+
6+
public class PspPortalInvitationVerificationHandler(IMapper mapper) : IPortalInvitationVerificationHandler
7+
{
8+
public bool CanHandle(InviteType? inviteType)
9+
{
10+
return inviteType == InviteType.PSIProgramRepresentative;
11+
}
12+
13+
public Task<PortalInvitationVerificationQueryResult> Verify(PortalInvitation portalInvitation, CancellationToken cancellationToken)
14+
{
15+
var result = mapper.Map<Contract.PortalInvitations.PortalInvitation>(portalInvitation);
16+
return Task.FromResult(PortalInvitationVerificationQueryResult.Success(result));
17+
}
18+
}
19+
20+

0 commit comments

Comments
 (0)