-
Notifications
You must be signed in to change notification settings - Fork 2
feat: block phase 2 pds #1423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
feat: block phase 2 pds #1423
Changes from 19 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
653f9ad
feat: Add PDS Stub
Joseph2910 d3e24bf
Merge branch 'main' into Block-Phase-2-PDS
MWClayson-NHS c960229
block participant refactor
MWClayson-NHS 2c82910
Stubbing Nems API
MWClayson-NHS fc9c802
Update Logging and returning body
MWClayson-NHS b067b34
get participant and bug fixes
MWClayson-NHS 00a155c
unblock participant
MWClayson-NHS cd08964
tidying
MWClayson-NHS 897f940
Eligbility flag logic
MWClayson-NHS f68f937
Logging and remove rule
MWClayson-NHS 45c1f94
intial tests
MWClayson-NHS b4b2277
Merge branch 'main' into Block-Phase-2-PDS
MWClayson-NHS b1f4114
tfvars and compose
MWClayson-NHS 22c8b84
function signature overlap
MWClayson-NHS 6dba115
some sonar qube fixes
MWClayson-NHS a6f0328
more sonar qube fixes
MWClayson-NHS 1536ba8
more sonar qube fixes
MWClayson-NHS 52ee103
more sonar qube
MWClayson-NHS 05b2d87
Merge branch 'main' into Block-Phase-2-PDS
MWClayson-NHS bdd0ddd
tests part one
MWClayson-NHS b8cb0f1
Correct Logging from PR Comment
MWClayson-NHS 2379d50
Addressing comments
MWClayson-NHS d32e4df
Incorrect Logic comment
MWClayson-NHS 973ed23
Block Participant Tests
MWClayson-NHS 7e79391
Addressing Comments
MWClayson-NHS d22b07d
Sonar Qube
MWClayson-NHS 801ea55
Tests
MWClayson-NHS 6ace84b
remove duplicate test
MWClayson-NHS 1c09833
Merge branch 'main' into Block-Phase-2-PDS
MWClayson-NHS 0f80b54
Merge branch 'main' into Block-Phase-2-PDS
MWClayson-NHS 1078949
Addressing Comments
MWClayson-NHS f53c8ef
using const for cannot parse message
MWClayson-NHS 227b73c
unused usings
MWClayson-NHS cc85893
Merge branch 'main' into Block-Phase-2-PDS
MWClayson-NHS efaf6b6
Merge branch 'main' into Block-Phase-2-PDS
MWClayson-NHS File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
...ager/src/Functions/ParticipantManagementServices/UpdateBlockedFlag/BlockParticipantDTO.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| namespace NHS.CohortManager.ParticipantManagementService; | ||
|
|
||
| public class BlockParticipantDto | ||
| { | ||
| public required long NhsNumber { get; set; } | ||
| public required string DateOfBirth { get; set; } | ||
| public required string FamilyName { get; set; } | ||
| } |
253 changes: 253 additions & 0 deletions
253
.../src/Functions/ParticipantManagementServices/UpdateBlockedFlag/BlockParticipantHandler.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,253 @@ | ||
| namespace NHS.CohortManager.ParticipantManagementService; | ||
|
|
||
| using System; | ||
| using System.Globalization; | ||
| using System.Text.Json; | ||
| using Common; | ||
| using DataServices.Client; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.Extensions.Options; | ||
| using Model; | ||
|
|
||
| public class BlockParticipantHandler : IBlockParticipantHandler | ||
| { | ||
| private readonly ILogger<BlockParticipantHandler> _logger; | ||
| private readonly IDataServiceClient<ParticipantManagement> _participantManagementDataService; | ||
| private readonly IDataServiceClient<ParticipantDemographic> _participantDemographicDataService; | ||
| private readonly IHttpClientFunction _httpClient; | ||
| private readonly UpdateBlockedFlagConfig _config; | ||
| public BlockParticipantHandler(ILogger<BlockParticipantHandler> logger, | ||
| IDataServiceClient<ParticipantManagement> participantManagementDataService, | ||
| IDataServiceClient<ParticipantDemographic> participantDemographicDataService, | ||
| IHttpClientFunction httpClient, | ||
| IOptions<UpdateBlockedFlagConfig> config | ||
| ) | ||
| { | ||
| _logger = logger; | ||
| _participantManagementDataService = participantManagementDataService; | ||
| _participantDemographicDataService = participantDemographicDataService; | ||
| _httpClient = httpClient; | ||
| _config = config.Value; | ||
| } | ||
|
|
||
| public async Task<BlockParticipantResult> BlockParticipant(BlockParticipantDto blockParticipantRequest) | ||
| { | ||
| if (!ValidationHelper.ValidateNHSNumber(blockParticipantRequest.NhsNumber.ToString())) | ||
| { | ||
| _logger.LogWarning("Participant had an invalid NHS Number and cannot be blocked"); | ||
| return new BlockParticipantResult(false, "Invalid NHS Number"); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| var participantManagementRecord = await _participantManagementDataService.GetSingleByFilter(x => x.NHSNumber == blockParticipantRequest.NhsNumber); | ||
|
|
||
| if (participantManagementRecord == null) | ||
| { | ||
| return await BlockNewParticipant(blockParticipantRequest); | ||
| } | ||
|
|
||
| if (participantManagementRecord.BlockedFlag == 1) | ||
| { | ||
| _logger.LogWarning("Participant already blocked and cannot be blocked"); | ||
| return new BlockParticipantResult(false, "Participant Already Blocked"); | ||
| } | ||
|
|
||
| var participantDemographic = await _participantDemographicDataService.GetSingleByFilter(x => x.NhsNumber == blockParticipantRequest.NhsNumber); | ||
|
|
||
| if (!ValidateRecordsMatch(participantDemographic, blockParticipantRequest)) | ||
| { | ||
| _logger.LogWarning("Participant had an didn't pass three point check and cannot be blocked"); | ||
|
MWClayson-NHS marked this conversation as resolved.
Outdated
|
||
| return new BlockParticipantResult(false, "Participant Didn't pass three point check"); | ||
| } | ||
|
|
||
| _logger.LogInformation("Participant has been blocked"); | ||
| return await BlockExistingParticipant(participantManagementRecord); | ||
|
|
||
|
|
||
|
|
||
| } | ||
|
|
||
| public async Task<BlockParticipantResult> UnblockParticipant(long nhsNumber) | ||
| { | ||
| if (!ValidationHelper.ValidateNHSNumber(nhsNumber.ToString())) | ||
| { | ||
| _logger.LogWarning("Invalid NHS Number and cannot be unblocked"); | ||
| return new BlockParticipantResult(false, "Invalid NHS Number"); | ||
| } | ||
|
|
||
| var participantManagementRecord = await _participantManagementDataService.GetSingleByFilter(x => x.NHSNumber == nhsNumber); | ||
|
|
||
| if (participantManagementRecord.BlockedFlag != 1) | ||
|
SamAinsworth-NHS marked this conversation as resolved.
|
||
| { | ||
| _logger.LogInformation("Participant couldn't be unblocked as they are currently blocked"); | ||
|
MWClayson-NHS marked this conversation as resolved.
Outdated
|
||
| return new BlockParticipantResult(false, "Participant is not blocked"); | ||
| } | ||
|
|
||
|
|
||
| var blockedFlagSet = await SetBlockedFlag(participantManagementRecord, false); | ||
| if (!blockedFlagSet) | ||
| { | ||
| return new BlockParticipantResult(false, "Failed to unset blocked flag"); | ||
| } | ||
|
|
||
| if (participantManagementRecord.EligibilityFlag == 1) | ||
| { | ||
| return new BlockParticipantResult(true, "Participant was unblocked but not resubscribed to Nems as they are ineligible"); | ||
|
alex-clayton-1 marked this conversation as resolved.
|
||
| } | ||
|
|
||
| var nemsSubscribed = await SubscribeParticipantToNEMS(nhsNumber); | ||
| if (!nemsSubscribed) | ||
| { | ||
| return new BlockParticipantResult(false, "Participant couldn't be subscribed in Nems"); | ||
| } | ||
|
|
||
| _logger.LogInformation("Participant has been unblocked"); | ||
| return new BlockParticipantResult(true, "Participant Unblocked"); | ||
|
|
||
|
|
||
| } | ||
|
|
||
| public async Task<BlockParticipantResult> GetParticipant(BlockParticipantDto blockParticipantRequest) | ||
| { | ||
|
|
||
| if (!ValidationHelper.ValidateNHSNumber(blockParticipantRequest.NhsNumber.ToString())) | ||
| { | ||
| _logger.LogWarning("Participant had an invalid NHS Number and cannot be blocked"); | ||
| return new BlockParticipantResult(false, "Invalid NHS Number"); | ||
| } | ||
|
|
||
| var participantDemographic = await _participantDemographicDataService.GetSingleByFilter(x => x.NhsNumber == blockParticipantRequest.NhsNumber); | ||
|
|
||
| if (participantDemographic != null) | ||
| { | ||
| var recordsMatch = ValidateRecordsMatch(participantDemographic, blockParticipantRequest); | ||
| var responseBody = JsonSerializer.Serialize(new BlockParticipantDto | ||
| { | ||
| NhsNumber = participantDemographic.NhsNumber, | ||
| FamilyName = participantDemographic.FamilyName!, | ||
| DateOfBirth = participantDemographic.DateOfBirth!, | ||
| }); | ||
| return new BlockParticipantResult(recordsMatch, responseBody); | ||
| } | ||
|
|
||
| var pdsParticipant = await GetPDSParticipant(blockParticipantRequest.NhsNumber); | ||
|
|
||
| if (pdsParticipant == null) | ||
| { | ||
| return new BlockParticipantResult(false, "Participant Couldn't be found"); | ||
| } | ||
|
|
||
| var pdsRecordsMatch = ValidateRecordsMatch(pdsParticipant, blockParticipantRequest); | ||
| var pdsResponseBody = JsonSerializer.Serialize(new BlockParticipantDto | ||
| { | ||
| NhsNumber = pdsParticipant.NhsNumber, | ||
| FamilyName = pdsParticipant.FamilyName!, | ||
| DateOfBirth = pdsParticipant.DateOfBirth! | ||
| }); | ||
|
|
||
| return new BlockParticipantResult(pdsRecordsMatch, pdsResponseBody); | ||
|
|
||
| } | ||
|
|
||
| private async Task<BlockParticipantResult> BlockNewParticipant(BlockParticipantDto blockParticipantRequest) | ||
| { | ||
| var pdsParticipant = await GetPDSParticipant(blockParticipantRequest.NhsNumber); | ||
|
|
||
| if (pdsParticipant == null || !ValidateRecordsMatch(pdsParticipant, blockParticipantRequest)) | ||
| { | ||
| return new BlockParticipantResult(false, "Participant details do not match a records in Cohort Manager or PDS"); | ||
| } | ||
|
|
||
| var participantManagementRecord = new ParticipantManagement | ||
| { | ||
| NHSNumber = pdsParticipant.NhsNumber, | ||
| BlockedFlag = 1, | ||
| EligibilityFlag = 0, | ||
| }; | ||
|
|
||
| var participantManagementAdded = await _participantManagementDataService.Add(participantManagementRecord); | ||
|
|
||
| if (!participantManagementAdded) | ||
| { | ||
| return new BlockParticipantResult(false, "Unable to add participant to Cohort Manager to be blocked"); | ||
| } | ||
|
|
||
| return new BlockParticipantResult(true, "Participant Has been blocked"); | ||
|
|
||
|
|
||
| } | ||
|
|
||
| private async Task<BlockParticipantResult> BlockExistingParticipant(ParticipantManagement participant) | ||
| { | ||
| var blockFlagUpdated = await SetBlockedFlag(participant, true); | ||
|
|
||
| if (!blockFlagUpdated) | ||
| { | ||
| return new BlockParticipantResult(false, "Failed to Update participant in Cohort Manager"); | ||
| } | ||
|
|
||
| var unsubscribeFromNems = await UnsubscribeParticipantFromNEMS(participant.NHSNumber); | ||
|
|
||
| if (!unsubscribeFromNems) | ||
| { | ||
| return new BlockParticipantResult(false, "Failed to unsubscribe Participant From NEMS"); | ||
| } | ||
|
|
||
| return new BlockParticipantResult(true, "Participant Has been blocked"); | ||
|
|
||
| } | ||
|
|
||
| private async Task<bool> UnsubscribeParticipantFromNEMS(long nhsNumber) | ||
| { | ||
| var nemsUnsubscribeResponse = await _httpClient.SendPost(_config.ManageNemsSubscriptionUnsubscribeURL, CreateNhsNumberQueryParams(nhsNumber)); | ||
|
|
||
| return nemsUnsubscribeResponse.IsSuccessStatusCode; | ||
| } | ||
|
|
||
| private async Task<bool> SubscribeParticipantToNEMS(long nhsNumber) | ||
| { | ||
| var nemsSubscribeResponse = await _httpClient.SendPost(_config.ManageNemsSubscriptionSubscribeURL, CreateNhsNumberQueryParams(nhsNumber)); | ||
|
|
||
| return nemsSubscribeResponse.IsSuccessStatusCode; | ||
| } | ||
|
|
||
|
|
||
| private async Task<bool> SetBlockedFlag(ParticipantManagement participant, bool blocked) | ||
| { | ||
| participant.BlockedFlag = blocked ? (short)1 : (short)0; | ||
| return await _participantManagementDataService.Update(participant); | ||
| } | ||
|
|
||
| private async Task<ParticipantDemographic> GetPDSParticipant(long nhsNumber) | ||
| { | ||
| var pdsResponse = await _httpClient.SendGet(_config.RetrievePdsDemographicURL, CreateNhsNumberQueryParams(nhsNumber)); | ||
| var pdsDemographic = JsonSerializer.Deserialize<ParticipantDemographic>(pdsResponse); | ||
|
|
||
| return pdsDemographic!; | ||
| } | ||
|
|
||
| private static bool ValidateRecordsMatch(ParticipantDemographic participant, BlockParticipantDto dto) | ||
| { | ||
|
|
||
| if (!DateOnly.TryParseExact(dto.DateOfBirth, "yyyy-MM-dd",new CultureInfo("en-GB"),DateTimeStyles.None, out var dtoDateOfBirth )) | ||
| { | ||
| throw new FormatException("Date of Birth not in the correct format"); | ||
| } | ||
|
|
||
| if (!DateOnly.TryParseExact(participant.DateOfBirth, "yyyyMMdd",new CultureInfo("en-GB"),DateTimeStyles.None, out var parsedDob)) | ||
| { | ||
| return false; | ||
| } | ||
| return string.Equals(participant.FamilyName, dto.FamilyName, StringComparison.InvariantCultureIgnoreCase) | ||
| && participant.NhsNumber == dto.NhsNumber | ||
| && parsedDob == dtoDateOfBirth; | ||
| } | ||
|
|
||
| private static Dictionary<string, string> CreateNhsNumberQueryParams(long nhsNumber) => | ||
| new Dictionary<string, string> | ||
| { | ||
| {"nhsNumber",nhsNumber.ToString()} | ||
| }; | ||
|
|
||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.