diff --git a/application/CohortManager/src/Functions/DemographicServices/RetrievePDSDemographic/RetrievePDSDemographic.cs b/application/CohortManager/src/Functions/DemographicServices/RetrievePDSDemographic/RetrievePDSDemographic.cs index 7ffefed1b9..605f37d093 100644 --- a/application/CohortManager/src/Functions/DemographicServices/RetrievePDSDemographic/RetrievePDSDemographic.cs +++ b/application/CohortManager/src/Functions/DemographicServices/RetrievePDSDemographic/RetrievePDSDemographic.cs @@ -84,7 +84,7 @@ public async Task Run([HttpTrigger(AuthorizationLevel.Anonymou var upsertResult = await _pdsProcessor.UpsertDemographicRecordFromPDS(participantDemographic); return upsertResult ? - _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, JsonSerializer.Serialize(participantDemographic)) : + _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, JsonSerializer.Serialize(pdsDemographic)) : _createResponse.CreateHttpResponse(HttpStatusCode.InternalServerError, req); } catch (Exception ex) diff --git a/application/CohortManager/src/Functions/ParticipantManagementServices/ManageServiceNowParticipant/ManageServiceNowParticipantFunction.cs b/application/CohortManager/src/Functions/ParticipantManagementServices/ManageServiceNowParticipant/ManageServiceNowParticipantFunction.cs index 3e9115ffdd..81e0e859f8 100644 --- a/application/CohortManager/src/Functions/ParticipantManagementServices/ManageServiceNowParticipant/ManageServiceNowParticipantFunction.cs +++ b/application/CohortManager/src/Functions/ParticipantManagementServices/ManageServiceNowParticipant/ManageServiceNowParticipantFunction.cs @@ -41,8 +41,8 @@ public async Task Run([ServiceBusTrigger(topicName: "%ServiceNowParticipantManag { try { - var participantDemographic = await ValidateAndRetrieveParticipantFromPds(serviceNowParticipant); - if (participantDemographic is null) + var pdsDemographic = await ValidateAndRetrieveParticipantFromPds(serviceNowParticipant); + if (pdsDemographic is null) { return; } @@ -58,7 +58,7 @@ public async Task Run([ServiceBusTrigger(topicName: "%ServiceNowParticipantManag // TODO: Add call to subscribe to NEMS (DTOSS-3881) - var participantForDistribution = new BasicParticipantCsvRecord(serviceNowParticipant, participantDemographic, participantManagement); + var participantForDistribution = new BasicParticipantCsvRecord(serviceNowParticipant, pdsDemographic, participantManagement); var sendToQueueSuccess = await _queueClient.AddAsync(participantForDistribution, _config.CohortDistributionTopic); @@ -73,7 +73,7 @@ public async Task Run([ServiceBusTrigger(topicName: "%ServiceNowParticipantManag } } - private async Task ValidateAndRetrieveParticipantFromPds(ServiceNowParticipant serviceNowParticipant) + private async Task ValidateAndRetrieveParticipantFromPds(ServiceNowParticipant serviceNowParticipant) { var pdsResponse = await _httpClientFunction.SendGetResponse($"{_config.RetrievePdsDemographicURL}?nhsNumber={serviceNowParticipant.NhsNumber}"); string responseMessage = await _httpClientFunction.GetResponseText(pdsResponse); @@ -90,37 +90,37 @@ public async Task Run([ServiceBusTrigger(topicName: "%ServiceNowParticipantManag return null; } - var participantDemographic = await DeserializeParticipantDemographic(pdsResponse, serviceNowParticipant); - if (participantDemographic is null) return null; + var pdsDemographic = await DeserializePdsDemographic(pdsResponse, serviceNowParticipant); + if (pdsDemographic is null) return null; - return await ValidateParticipantData(serviceNowParticipant, participantDemographic) - ? participantDemographic + return await ValidateParticipantData(serviceNowParticipant, pdsDemographic) + ? pdsDemographic : null; } - private async Task DeserializeParticipantDemographic(HttpResponseMessage pdsResponse, ServiceNowParticipant serviceNowParticipant) + private async Task DeserializePdsDemographic(HttpResponseMessage pdsResponse, ServiceNowParticipant serviceNowParticipant) { var jsonString = await pdsResponse.Content.ReadAsStringAsync(); - var participantDemographic = JsonSerializer.Deserialize(jsonString); + var pdsDemographic = JsonSerializer.Deserialize(jsonString); - if (participantDemographic is null) + if (pdsDemographic is null) { - await HandleException(new Exception($"Deserialisation of PDS for ServiceNow Participant response to {typeof(ParticipantDemographic)} returned null"), serviceNowParticipant, ServiceNowMessageType.AddRequestInProgress); + await HandleException(new Exception($"Deserialisation of PDS for ServiceNow Participant response to {typeof(PdsDemographic)} returned null"), serviceNowParticipant, ServiceNowMessageType.AddRequestInProgress); return null; } - return participantDemographic; + return pdsDemographic; } - private async Task ValidateParticipantData(ServiceNowParticipant serviceNowParticipant, ParticipantDemographic participantDemographic) + private async Task ValidateParticipantData(ServiceNowParticipant serviceNowParticipant, PdsDemographic pdsDemographic) { - if (participantDemographic.NhsNumber != serviceNowParticipant.NhsNumber) + if (pdsDemographic.NhsNumber != serviceNowParticipant.NhsNumber.ToString()) { await HandleException(new Exception("NHS Numbers don't match for ServiceNow Participant and PDS, NHS Number must have been superseded"), serviceNowParticipant, ServiceNowMessageType.UnableToAddParticipant); return false; } - if (!CheckParticipantDataMatches(serviceNowParticipant, participantDemographic)) + if (!CheckParticipantDataMatches(serviceNowParticipant, pdsDemographic)) { await HandleException(new Exception("Participant data from ServiceNow does not match participant data from PDS"), serviceNowParticipant, ServiceNowMessageType.UnableToAddParticipant); return false; @@ -219,11 +219,11 @@ private async Task HandleException(Exception exception, ServiceNowParticipant se await SendServiceNowMessage(serviceNowParticipant.ServiceNowCaseNumber, serviceNowMessageType); } - private static bool CheckParticipantDataMatches(ServiceNowParticipant serviceNowParticipant, ParticipantDemographic participantDemographic) + private static bool CheckParticipantDataMatches(ServiceNowParticipant serviceNowParticipant, PdsDemographic pdsDemographic) { - return serviceNowParticipant.FirstName == participantDemographic.GivenName && - serviceNowParticipant.FamilyName == participantDemographic.FamilyName && - serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd") == participantDemographic.DateOfBirth; + return serviceNowParticipant.FirstName == pdsDemographic.FirstName && + serviceNowParticipant.FamilyName == pdsDemographic.FamilyName && + serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd") == pdsDemographic.DateOfBirth; } private async Task SendServiceNowMessage(string serviceNowCaseNumber, ServiceNowMessageType servicenowMessageType) diff --git a/application/CohortManager/src/Functions/ParticipantManagementServices/UpdateBlockedFlag/BlockParticipantHandler.cs b/application/CohortManager/src/Functions/ParticipantManagementServices/UpdateBlockedFlag/BlockParticipantHandler.cs index e469f46fe9..78bda7f685 100644 --- a/application/CohortManager/src/Functions/ParticipantManagementServices/UpdateBlockedFlag/BlockParticipantHandler.cs +++ b/application/CohortManager/src/Functions/ParticipantManagementServices/UpdateBlockedFlag/BlockParticipantHandler.cs @@ -141,7 +141,7 @@ public async Task GetParticipant(BlockParticipantDto blo var pdsRecordsMatch = ValidateRecordsMatch(pdsParticipant, blockParticipantRequest); var pdsResponseBody = JsonSerializer.Serialize(new BlockParticipantDto { - NhsNumber = pdsParticipant.NhsNumber, + NhsNumber = long.Parse(pdsParticipant.NhsNumber), FamilyName = pdsParticipant.FamilyName!, DateOfBirth = pdsParticipant.DateOfBirth! }); @@ -161,7 +161,7 @@ private async Task BlockNewParticipant(BlockParticipantD var participantManagementRecord = new ParticipantManagement { - NHSNumber = pdsParticipant.NhsNumber, + NHSNumber = long.Parse(pdsParticipant.NhsNumber), BlockedFlag = 1, EligibilityFlag = 0, }; @@ -219,7 +219,7 @@ private async Task SetBlockedFlag(ParticipantManagement participant, bool return await _participantManagementDataService.Update(participant); } - private async Task GetPDSParticipant(long nhsNumber) + private async Task GetPDSParticipant(long nhsNumber) { var pdsResponse = await _httpClient.SendGet(_config.RetrievePdsDemographicURL, CreateNhsNumberQueryParams(nhsNumber)); if (string.IsNullOrEmpty(pdsResponse)) @@ -228,7 +228,7 @@ private async Task GetPDSParticipant(long nhsNumber) return null!; } - var pdsDemographic = JsonSerializer.Deserialize(pdsResponse); + var pdsDemographic = JsonSerializer.Deserialize(pdsResponse); return pdsDemographic!; } @@ -250,6 +250,23 @@ private static bool ValidateRecordsMatch(ParticipantDemographic participant, Blo && parsedDob == dtoDateOfBirth; } + private static bool ValidateRecordsMatch(PdsDemographic 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) + && long.Parse(participant.NhsNumber) == dto.NhsNumber + && parsedDob == dtoDateOfBirth; + } + private static Dictionary CreateNhsNumberQueryParams(long nhsNumber) => new Dictionary { diff --git a/application/CohortManager/src/Functions/Shared/Model/BasicParticipantCsvRecord.cs b/application/CohortManager/src/Functions/Shared/Model/BasicParticipantCsvRecord.cs index f37436df11..0bbaf52953 100644 --- a/application/CohortManager/src/Functions/Shared/Model/BasicParticipantCsvRecord.cs +++ b/application/CohortManager/src/Functions/Shared/Model/BasicParticipantCsvRecord.cs @@ -17,7 +17,7 @@ public BasicParticipantCsvRecord() } - public BasicParticipantCsvRecord(ServiceNowParticipant serviceNowParticipant, ParticipantDemographic participantDemographic, ParticipantManagement? participantManagement) + public BasicParticipantCsvRecord(ServiceNowParticipant serviceNowParticipant, PdsDemographic pdsDemographic, ParticipantManagement? participantManagement) { FileName = serviceNowParticipant.ServiceNowCaseNumber; BasicParticipantData = new BasicParticipantData @@ -29,7 +29,7 @@ public BasicParticipantCsvRecord(ServiceNowParticipant serviceNowParticipant, Pa Participant = new Participant { ReferralFlag = "1", - Postcode = participantDemographic.PostCode, + Postcode = pdsDemographic.Postcode, ScreeningAcronym = "BSS" // TODO: Remove hardcoding when adding support for additional screening programs }; } diff --git a/tests/UnitTests/ParticipantManagementServicesTests/ManageServiceNowParticipantTests/ManageServiceNowParticipantFunctionTests.cs b/tests/UnitTests/ParticipantManagementServicesTests/ManageServiceNowParticipantTests/ManageServiceNowParticipantFunctionTests.cs index 917e8370ad..f55e76fdcb 100644 --- a/tests/UnitTests/ParticipantManagementServicesTests/ManageServiceNowParticipantTests/ManageServiceNowParticipantFunctionTests.cs +++ b/tests/UnitTests/ParticipantManagementServicesTests/ManageServiceNowParticipantTests/ManageServiceNowParticipantFunctionTests.cs @@ -113,9 +113,9 @@ public async Task Run_WhenNoPdsMatch_SendsServiceNowMessageType1() public async Task Run_WhenNhsNumberSuperseded_SendsServiceNowMessageType1() { // Arrange - var json = JsonSerializer.Serialize(new ParticipantDemographic + var json = JsonSerializer.Serialize(new PdsDemographic { - NhsNumber = 123 + NhsNumber = "123" }); _httpClientFunctionMock.Setup(x => x.SendGetResponse($"{_configMock.Object.Value.RetrievePdsDemographicURL}?nhsNumber={_serviceNowParticipant.NhsNumber}")) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) @@ -205,10 +205,10 @@ public async Task Run_WhenParticipantDataDoesNotMatchPdsData_SendsServiceNowMess string firstName, string familyName, string dateOfBirth) { // Arrange - var json = JsonSerializer.Serialize(new ParticipantDemographic + var json = JsonSerializer.Serialize(new PdsDemographic { - NhsNumber = _serviceNowParticipant.NhsNumber, - GivenName = firstName, + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = firstName, FamilyName = familyName, DateOfBirth = dateOfBirth }); @@ -241,7 +241,14 @@ public async Task Run_WhenParticipantDataDoesNotMatchPdsData_SendsServiceNowMess public async Task Run_WhenServiceNowParticipantIsValidAndDoesNotExistInTheDataStore_AddsTheNewParticipant() { // Arrange - var json = JsonSerializer.Serialize(_demographic); + var json = JsonSerializer.Serialize(new PdsDemographic + { + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = _serviceNowParticipant.FirstName, + FamilyName = _serviceNowParticipant.FamilyName, + DateOfBirth = _serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd"), + Postcode = "SW1A 2AA" + }); _httpClientFunctionMock.Setup(x => x.SendGetResponse($"{_configMock.Object.Value.RetrievePdsDemographicURL}?nhsNumber={_serviceNowParticipant.NhsNumber}")) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) { @@ -292,7 +299,14 @@ public async Task Run_WhenServiceNowParticipantIsValidAndDoesNotExistInTheDataSt public async Task Run_WhenServiceNowParticipantIsValidAndExistsInTheDataStoreButIsBlocked_DoesNotUpdateTheParticipantAndSendsMessageType1() { // Arrange - var json = JsonSerializer.Serialize(_demographic); + var json = JsonSerializer.Serialize(new PdsDemographic + { + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = _serviceNowParticipant.FirstName, + FamilyName = _serviceNowParticipant.FamilyName, + DateOfBirth = _serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd"), + Postcode = "SW1A 2AA" + }); _httpClientFunctionMock.Setup(x => x.SendGetResponse($"{_configMock.Object.Value.RetrievePdsDemographicURL}?nhsNumber={_serviceNowParticipant.NhsNumber}")) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) { @@ -341,7 +355,14 @@ public async Task Run_WhenServiceNowParticipantIsValidAndExistsInTheDataStoreBut public async Task Run_WhenServiceNowParticipantIsValidAndExistsInTheDataStoreAndIsNotBlocked_UpdatesTheParticipant() { // Arrange - var json = JsonSerializer.Serialize(_demographic); + var json = JsonSerializer.Serialize(new PdsDemographic + { + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = _serviceNowParticipant.FirstName, + FamilyName = _serviceNowParticipant.FamilyName, + DateOfBirth = _serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd"), + Postcode = "SW1A 2AA" + }); _httpClientFunctionMock.Setup(x => x.SendGetResponse($"{_configMock.Object.Value.RetrievePdsDemographicURL}?nhsNumber={_serviceNowParticipant.NhsNumber}")) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) { @@ -405,7 +426,14 @@ public async Task Run_WhenServiceNowParticipantIsVhrAndDoesNotExistInDataStore_A ReasonForAdding = ServiceNowReasonsForAdding.VeryHighRisk }; - var json = JsonSerializer.Serialize(_demographic); + var json = JsonSerializer.Serialize(new PdsDemographic + { + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = _serviceNowParticipant.FirstName, + FamilyName = _serviceNowParticipant.FamilyName, + DateOfBirth = _serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd"), + Postcode = "SW1A 2AA" + }); _httpClientFunctionMock.Setup(x => x.SendGetResponse($"{_configMock.Object.Value.RetrievePdsDemographicURL}?nhsNumber={vhrParticipant.NhsNumber}")) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) @@ -461,7 +489,14 @@ public async Task Run_WhenServiceNowParticipantIsVhrAndDoesNotExistInDataStore_A public async Task Run_WhenServiceNowParticipantIsNotVhrAndDoesNotExistInDataStore_AddsNewParticipantWithoutVhrFlag() { // Arrange - var json = JsonSerializer.Serialize(_demographic); + var json = JsonSerializer.Serialize(new PdsDemographic + { + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = _serviceNowParticipant.FirstName, + FamilyName = _serviceNowParticipant.FamilyName, + DateOfBirth = _serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd"), + Postcode = "SW1A 2AA" + }); _httpClientFunctionMock.Setup(x => x.SendGetResponse($"{_configMock.Object.Value.RetrievePdsDemographicURL}?nhsNumber={_serviceNowParticipant.NhsNumber}")) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) @@ -528,7 +563,14 @@ public async Task Run_WhenVhrParticipantExistsWithNullVhrFlag_SetsVhrFlagToTrue( ReasonForAdding = ServiceNowReasonsForAdding.VeryHighRisk }; - var json = JsonSerializer.Serialize(_demographic); + var json = JsonSerializer.Serialize(new PdsDemographic + { + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = _serviceNowParticipant.FirstName, + FamilyName = _serviceNowParticipant.FamilyName, + DateOfBirth = _serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd"), + Postcode = "SW1A 2AA" + }); var existingParticipant = new ParticipantManagement { @@ -594,7 +636,14 @@ public async Task Run_WhenVhrParticipantExistsWithNullVhrFlag_SetsVhrFlagToTrue( public async Task Run_WhenParticipantExistsWithVhrFlagAlreadySet_MaintainsVhrFlag() { // Arrange - var json = JsonSerializer.Serialize(_demographic); + var json = JsonSerializer.Serialize(new PdsDemographic + { + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = _serviceNowParticipant.FirstName, + FamilyName = _serviceNowParticipant.FamilyName, + DateOfBirth = _serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd"), + Postcode = "SW1A 2AA" + }); var existingParticipant = new ParticipantManagement { @@ -659,7 +708,14 @@ public async Task Run_WhenParticipantExistsWithVhrFlagAlreadySet_MaintainsVhrFla public async Task Run_WhenNonVhrParticipantExistsWithNullVhrFlag_LeavesVhrFlagAsNull() { // Arrange - var json = JsonSerializer.Serialize(_demographic); + var json = JsonSerializer.Serialize(new PdsDemographic + { + NhsNumber = _serviceNowParticipant.NhsNumber.ToString(), + FirstName = _serviceNowParticipant.FirstName, + FamilyName = _serviceNowParticipant.FamilyName, + DateOfBirth = _serviceNowParticipant.DateOfBirth.ToString("yyyy-MM-dd"), + Postcode = "SW1A 2AA" + }); var existingParticipant = new ParticipantManagement { diff --git a/tests/UnitTests/ParticipantManagementServicesTests/UpdateBlockedFlagTests/UpdateBlockedFlagTests.cs b/tests/UnitTests/ParticipantManagementServicesTests/UpdateBlockedFlagTests/UpdateBlockedFlagTests.cs index 217a4a6238..3f652f18a8 100644 --- a/tests/UnitTests/ParticipantManagementServicesTests/UpdateBlockedFlagTests/UpdateBlockedFlagTests.cs +++ b/tests/UnitTests/ParticipantManagementServicesTests/UpdateBlockedFlagTests/UpdateBlockedFlagTests.cs @@ -122,9 +122,9 @@ public async Task BlockParticipant_NonExistentParticipant_ReturnsSuccess() var pdsDemoResponse = JsonSerializer.Serialize( - new ParticipantDemographic + new PdsDemographic { - NhsNumber = 6427635034, + NhsNumber = "6427635034", FamilyName = "Jones", DateOfBirth = "19231012" }); @@ -256,9 +256,9 @@ public async Task BlockParticipant_NonExistentParticipantFailsThreePointCheck_Re var pdsDemoResponse = JsonSerializer.Serialize( - new ParticipantDemographic + new PdsDemographic { - NhsNumber = 6427635034, + NhsNumber = "6427635034", FamilyName = "Davies", DateOfBirth = "19231012" }); @@ -329,9 +329,9 @@ public async Task GetParticipant_ParticipantOnlyInPDS_ReturnsSuccess() .Returns(Task.FromResult(null!)); var pdsDemoResponse = JsonSerializer.Serialize( - new ParticipantDemographic + new PdsDemographic { - NhsNumber = 6427635034, + NhsNumber = "6427635034", FamilyName = "Jones", DateOfBirth = "19231012" }); @@ -367,9 +367,9 @@ public async Task GetParticipant_ParticipantNotExists_ReturnsFailure() .Returns(Task.FromResult(null!)); var pdsDemoResponse = JsonSerializer.Serialize( - new ParticipantDemographic + new PdsDemographic { - NhsNumber = 6427635034, + NhsNumber = "6427635034", FamilyName = "Jones", DateOfBirth = "19231012" });