Skip to content

Commit 26b8965

Browse files
refactor: reduced database calls and extract data from errorRecord (#1624)
* refactor: reduced database calls and extra data from errorRecord * chore: log exception * refactor: removed dataservice call, details from errorRecord, renamed allExceptions to filteredExceptions, properties added to DTO, Tests updated with variable names * fix: property name postCode to postcode * fix: property name postCode to postcode * feat: DateOfBirth Mapping
1 parent c198750 commit 26b8965

File tree

7 files changed

+118
-52
lines changed

7 files changed

+118
-52
lines changed

application/CohortManager/src/Functions/Shared/Data/Database/IValidationExceptionData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Data.Database;
77
public interface IValidationExceptionData
88
{
99
Task<bool> Create(ValidationException exception);
10-
Task<List<ValidationException>?> GetAllFilteredExceptions(ExceptionStatus? exceptionStatus, SortOrder? sortOrder, ExceptionCategory exceptionCategory);
10+
Task<List<ValidationException>?> GetFilteredExceptions(ExceptionStatus? exceptionStatus, SortOrder? sortOrder, ExceptionCategory exceptionCategory);
1111
Task<ValidationException?> GetExceptionById(int exceptionId);
1212
Task<bool> RemoveOldException(string nhsNumber, string screeningName);
1313
Task<ServiceResponseModel> UpdateExceptionServiceNowId(int exceptionId, string serviceNowId);

application/CohortManager/src/Functions/Shared/Data/Database/ValidationExceptionData.cs

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ namespace Data.Database;
33
using System;
44
using System.Data;
55
using System.Net;
6+
using System.Text.Json;
67
using System.Threading.Tasks;
78
using Common;
89
using DataServices.Client;
910
using Microsoft.Extensions.Logging;
1011
using Model;
12+
using Model.DTO;
1113
using Model.Enums;
14+
using NHS.CohortManager.Shared.Utilities;
1215

1316
public class ValidationExceptionData : IValidationExceptionData
1417
{
1518
private readonly ILogger<ValidationExceptionData> _logger;
1619
private readonly IDataServiceClient<ExceptionManagement> _validationExceptionDataServiceClient;
17-
private readonly IDataServiceClient<ParticipantDemographic> _demographicDataServiceClient;
1820
public ValidationExceptionData(
1921
ILogger<ValidationExceptionData> logger,
2022
IDataServiceClient<ExceptionManagement> validationExceptionDataServiceClient,
@@ -23,10 +25,9 @@ IDataServiceClient<ParticipantDemographic> demographicDataServiceClient
2325
{
2426
_logger = logger;
2527
_validationExceptionDataServiceClient = validationExceptionDataServiceClient;
26-
_demographicDataServiceClient = demographicDataServiceClient;
2728
}
2829

29-
public async Task<List<ValidationException>?> GetAllFilteredExceptions(ExceptionStatus? exceptionStatus, SortOrder? sortOrder, ExceptionCategory exceptionCategory)
30+
public async Task<List<ValidationException>?> GetFilteredExceptions(ExceptionStatus? exceptionStatus, SortOrder? sortOrder, ExceptionCategory exceptionCategory)
3031
{
3132
var category = (int)exceptionCategory;
3233
var exceptions = await _validationExceptionDataServiceClient.GetByFilter(x => x.Category != null && x.Category.Value == category);
@@ -45,16 +46,10 @@ IDataServiceClient<ParticipantDemographic> demographicDataServiceClient
4546
return null;
4647
}
4748

48-
if (!long.TryParse(exception.NhsNumber, out long nhsNumber))
49-
{
50-
throw new FormatException("Unable to parse NHS Number");
51-
}
52-
53-
var participantDemographic = await _demographicDataServiceClient.GetSingleByFilter(x => x.NhsNumber == nhsNumber);
54-
55-
return GetExceptionDetails(exception.ToValidationException(), participantDemographic);
49+
return GetValidationExceptionWithDetails(exception);
5650
}
5751

52+
5853
public async Task<bool> Create(ValidationException exception)
5954
{
6055
var exceptionToUpdate = new ExceptionManagement().FromValidationException(exception);
@@ -129,6 +124,27 @@ public async Task<ServiceResponseModel> UpdateExceptionServiceNowId(int exceptio
129124
return [];
130125
}
131126

127+
var filteredExceptions = await GetFilteredReportExceptions(reportDate, exceptionCategory);
128+
129+
if (filteredExceptions == null || !filteredExceptions.Any())
130+
return [];
131+
132+
var results = filteredExceptions.Select(GetValidationExceptionWithDetails);
133+
return results.Where(x => x != null).ToList()!;
134+
}
135+
136+
private ServiceResponseModel CreateSuccessResponse(string message) => CreateResponse(true, HttpStatusCode.OK, message);
137+
private ServiceResponseModel CreateErrorResponse(string message, HttpStatusCode statusCode) => CreateResponse(false, statusCode, message);
138+
139+
private ValidationException? GetValidationExceptionWithDetails(ExceptionManagement exception)
140+
{
141+
var validationException = exception.ToValidationException();
142+
var participantDemographic = ExtractParticipantDemographicFromErrorRecord(exception.ErrorRecord);
143+
return GetExceptionDetails(validationException, participantDemographic);
144+
}
145+
146+
private async Task<IEnumerable<ExceptionManagement>?> GetFilteredReportExceptions(DateTime? reportDate, ExceptionCategory exceptionCategory)
147+
{
132148
var filteredExceptions = (await _validationExceptionDataServiceClient.GetByFilter(x =>
133149
x.Category.HasValue && (x.Category.Value == (int)ExceptionCategory.Confusion || x.Category.Value == (int)ExceptionCategory.Superseded)))?.AsEnumerable();
134150

@@ -144,18 +160,48 @@ public async Task<ServiceResponseModel> UpdateExceptionServiceNowId(int exceptio
144160
filteredExceptions = filteredExceptions?.Where(x => x.DateCreated >= startDate && x.DateCreated < endDate);
145161
}
146162

147-
if (filteredExceptions?.Any() != true)
148-
return [];
163+
return filteredExceptions;
164+
}
149165

150-
var tasks = filteredExceptions.Select(async exception =>
166+
private ParticipantDemographic? ExtractParticipantDemographicFromErrorRecord(string? errorRecord)
167+
{
168+
if (string.IsNullOrWhiteSpace(errorRecord))
151169
{
152-
var validationException = exception.ToValidationException();
153-
var participantDemographic = long.TryParse(exception.NhsNumber, out long nhsNumber) ? await _demographicDataServiceClient.GetSingleByFilter(x => x.NhsNumber == nhsNumber) : null;
154-
return GetExceptionDetails(validationException, participantDemographic);
155-
});
170+
return null;
171+
}
156172

157-
var results = await Task.WhenAll(tasks);
158-
return results.Where(x => x != null).ToList()!;
173+
try
174+
{
175+
var errorRecordData = JsonSerializer.Deserialize<ErrorRecordDto>(errorRecord);
176+
if (errorRecordData == null)
177+
{
178+
return null;
179+
}
180+
181+
return new ParticipantDemographic
182+
{
183+
NhsNumber = long.TryParse(errorRecordData.NhsNumber, out long nhsNumber) ? nhsNumber : 0,
184+
GivenName = errorRecordData.FirstName,
185+
FamilyName = errorRecordData.FamilyName,
186+
DateOfBirth = MappingUtilities.FormatDateTime(MappingUtilities.ParseDates(errorRecordData.DateOfBirth)),
187+
SupersededByNhsNumber = long.TryParse(errorRecordData.SupersededByNhsNumber, out long superseded) ? superseded : null,
188+
Gender = errorRecordData.Gender,
189+
AddressLine1 = errorRecordData.AddressLine1,
190+
AddressLine2 = errorRecordData.AddressLine2,
191+
AddressLine3 = errorRecordData.AddressLine3,
192+
AddressLine4 = errorRecordData.AddressLine4,
193+
AddressLine5 = errorRecordData.AddressLine5,
194+
PostCode = errorRecordData.Postcode,
195+
TelephoneNumberHome = errorRecordData.TelephoneNumber,
196+
EmailAddressHome = errorRecordData.EmailAddress,
197+
PrimaryCareProvider = errorRecordData.PrimaryCareProvider,
198+
};
199+
}
200+
catch (JsonException ex)
201+
{
202+
_logger.LogWarning(ex, "Failed to deserialize ErrorRecord JSON: {ErrorRecord}. Error: {Error}", errorRecord, ex.Message);
203+
return null;
204+
}
159205
}
160206

161207
private ServiceResponseModel CreateResponse(bool success, HttpStatusCode statusCode, string message)
@@ -173,8 +219,6 @@ private ServiceResponseModel CreateResponse(bool success, HttpStatusCode statusC
173219
};
174220
}
175221

176-
private ServiceResponseModel CreateSuccessResponse(string message) => CreateResponse(true, HttpStatusCode.OK, message);
177-
private ServiceResponseModel CreateErrorResponse(string message, HttpStatusCode statusCode) => CreateResponse(false, statusCode, message);
178222

179223
private static string? ValidateServiceNowId(string serviceNowId)
180224
{
@@ -225,7 +269,7 @@ private ServiceResponseModel CreateResponse(bool success, HttpStatusCode statusC
225269

226270
if (participantDemographic == null)
227271
{
228-
_logger.LogWarning("Missing data: ParticipantDemographic: {ParticipantDemographic}", participantDemographic != null);
272+
_logger.LogWarning("Missing participant demographic data for exception");
229273
}
230274

231275
return exception;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace Model.DTO;
2+
3+
public class ErrorRecordDto
4+
{
5+
public string? NhsNumber { get; set; }
6+
public string? SupersededByNhsNumber { get; set; }
7+
public string? FirstName { get; set; }
8+
public string? FamilyName { get; set; }
9+
public string? DateOfBirth { get; set; }
10+
public short? Gender { get; set; }
11+
public string? AddressLine1 { get; set; }
12+
public string? AddressLine2 { get; set; }
13+
public string? AddressLine3 { get; set; }
14+
public string? AddressLine4 { get; set; }
15+
public string? AddressLine5 { get; set; }
16+
public string? Postcode { get; set; }
17+
public string? PrimaryCareProvider { get; set; }
18+
public string? TelephoneNumber { get; set; }
19+
public string? EmailAddress { get; set; }
20+
}

application/CohortManager/src/Functions/screeningDataServices/GetValidationExceptions/GetValidationExceptions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymou
7575
return CreatePaginatedResponse(req, reportExceptions!.AsQueryable(), page);
7676
}
7777

78-
var allExceptions = await _validationData.GetAllFilteredExceptions(exceptionStatus, sortOrder, exceptionCategory);
79-
return CreatePaginatedResponse(req, allExceptions!.AsQueryable(), page);
78+
var filteredExceptions = await _validationData.GetFilteredExceptions(exceptionStatus, sortOrder, exceptionCategory);
79+
return CreatePaginatedResponse(req, filteredExceptions!.AsQueryable(), page);
8080
}
8181
catch (Exception ex)
8282
{

application/CohortManager/src/Web/app/lib/utils.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
export const formatNhsNumber = (nhsNumber: string): string => {
2-
return nhsNumber.replace(/(\d{3})(\d{3})(\d{4})/, "$1 $2 $3");
1+
export const formatNhsNumber = (nhsNumber: string | number): string => {
2+
if (!nhsNumber) return '';
3+
const nhsString = String(nhsNumber);
4+
return nhsString.replace(/(\d{3})(\d{3})(\d{4})/, "$1 $2 $3");
35
};
46

57
export const formatDate = (dateString: string): string => {

0 commit comments

Comments
 (0)