diff --git a/application/CohortManager/src/Functions/CaasIntegration/RetrieveMeshFile/RetrieveMeshFile.csproj b/application/CohortManager/src/Functions/CaasIntegration/RetrieveMeshFile/RetrieveMeshFile.csproj
index c7da6e5da8..546d66720d 100644
--- a/application/CohortManager/src/Functions/CaasIntegration/RetrieveMeshFile/RetrieveMeshFile.csproj
+++ b/application/CohortManager/src/Functions/CaasIntegration/RetrieveMeshFile/RetrieveMeshFile.csproj
@@ -26,6 +26,9 @@
PreserveNewest
+
+
+ PreserveNewest
PreserveNewest
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/CallDurableDemographicFunc.cs b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/CallDurableDemographicFunc.cs
index cad696d519..8a79bf9ad2 100644
--- a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/CallDurableDemographicFunc.cs
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/CallDurableDemographicFunc.cs
@@ -51,7 +51,7 @@ public CallDurableDemographicFunc(IHttpClientFunction httpClientFunction, ILogge
/// This method handles posting data, logging, and checking the status of the durable function.
/// Implements retry logic for status checking.
///
- public async Task PostDemographicDataAsync(List participants, string DemographicFunctionURI, string fileName)
+ public async Task PostDemographicDataAsync(List participants, string DemographicFunctionURI, string fileName, List parquetValuesForRetry)
{
var batchSize = participants.Count;
var responseContent = "";
@@ -92,7 +92,9 @@ public async Task PostDemographicDataAsync(List pa
_logger.LogError("Check limit reached or demographic function failed for a batch of size: {BatchSize} {FinalStatus}", batchSize, finalStatus);
await _copyFailedBatchToBlob.writeBatchToBlob(
JsonSerializer.Serialize(participants),
- new InvalidOperationException("there was an error while adding batch of participants to the demographic table")
+ new InvalidOperationException("there was an error while adding batch of participants to the demographic table"),
+ parquetValuesForRetry,
+ fileName
);
return false;
@@ -106,7 +108,9 @@ await _copyFailedBatchToBlob.writeBatchToBlob(
await _copyFailedBatchToBlob.writeBatchToBlob(
JsonSerializer.Serialize(participants),
- new InvalidOperationException("there was an error while adding batch of participants to the demographic table")
+ new InvalidOperationException("there was an error while adding batch of participants to the demographic table"),
+ parquetValuesForRetry,
+ fileName
);
return false;
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/CopyFailedBatchToBlob.cs b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/CopyFailedBatchToBlob.cs
index fd020ecd83..88f3785823 100644
--- a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/CopyFailedBatchToBlob.cs
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/CopyFailedBatchToBlob.cs
@@ -1,11 +1,14 @@
namespace NHS.Screening.ReceiveCaasFile;
-using System.Text;
+using System;
+using System.Collections.Generic;
using System.Text.Json;
+using Azure.Storage.Blobs;
using Common;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Model;
+using Parquet.Serialization;
public class CopyFailedBatchToBlob : ICopyFailedBatchToBlob
{
@@ -15,32 +18,131 @@ public class CopyFailedBatchToBlob : ICopyFailedBatchToBlob
private readonly ReceiveCaasFileConfig _config;
- public CopyFailedBatchToBlob(ILogger logger, IBlobStorageHelper blobStorageHelper, IExceptionHandler handleException, IOptions config)
+ private readonly IFailedBatchDict _failedBatchDict;
+
+ public CopyFailedBatchToBlob(ILogger logger, IBlobStorageHelper blobStorageHelper, IExceptionHandler handleException, IOptions config, IFailedBatchDict failedBatchDict)
{
_config = config.Value;
_logger = logger;
_blobStorageHelper = blobStorageHelper;
_handleException = handleException;
+ _failedBatchDict = failedBatchDict;
}
- public async Task writeBatchToBlob(string jsonFromBatch, InvalidOperationException invalidOperationException)
+ public async Task writeBatchToBlob(string jsonFromBatch, InvalidOperationException invalidOperationException, List parquetValuesForRetry, string fileName = "")
{
using (var stream = GenerateStreamFromString(jsonFromBatch))
{
- var blobFile = new BlobFile(stream, $"failedBatch-{Guid.NewGuid()}.json");
- var copied = await _blobStorageHelper.UploadFileToBlobStorage(_config.caasfolder_STORAGE, "failed-batch", blobFile);
-
- if (copied)
+ if (!string.IsNullOrEmpty(fileName))
{
- _logger.LogInformation("adding failed batch to blob was successful");
- await _handleException.CreateSystemExceptionLog(invalidOperationException, new Participant(), "file name unknown but batch was copied to FailedBatch blob store");
- return true;
+ if (_failedBatchDict.ShouldRetryFile(fileName))
+ {
+ var fileRetryCount = _failedBatchDict.GetRetryCount(fileName);
+ upsertRetryValue(fileName, fileRetryCount);
+ var pathOfFileToRetry = await convertBatchToParquet(parquetValuesForRetry, fileName);
+ if (!string.IsNullOrEmpty(pathOfFileToRetry))
+ {
+ await RetryFailedBatch(pathOfFileToRetry, fileName);
+ }
+ }
+ else
+ {
+ var filePath = FileDirectoryPath(fileName);
+ if (File.Exists(fileName))
+ {
+ File.Delete(fileName);
+ }
+ }
}
+
+ fileName = $"failedBatch-{Guid.NewGuid()}.json";
+ await AddItemToBlob(stream, fileName);
+
+ await _handleException.CreateSystemExceptionLog(invalidOperationException, new Participant(), "file name unknown but batch was copied to FailedBatch blob store");
_logger.LogInformation("adding failed batch to blob was unsuccessful");
- return false;
+ return true;
+ }
+ }
+
+ private void upsertRetryValue(string filename, int fileRetryCount)
+ {
+ fileRetryCount = fileRetryCount + 1;
+ if (!_failedBatchDict.HasFileFailedBefore(filename))
+ {
+
+ _failedBatchDict.AddFailedBatchDataToDict(filename, fileRetryCount);
+ }
+ else
+ {
+ _failedBatchDict.UpdateFileFailureCount(filename, fileRetryCount);
+ }
+ }
+
+ private async Task convertBatchToParquet(List parquetValuesForRetry, string fileName)
+ {
+ try
+ {
+ var parquetData = parquetValuesForRetry
+ .Select(ParticipantsParquetMap.ToParticipantParquet)
+ .ToList();
+
+ var filePath = FileDirectoryPath(fileName);
+ await ParquetSerializer.SerializeAsync(parquetData, filePath);
+
+ return filePath;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "There was a problem when converting a failed batch to parquet for retry {error}", ex.Message);
+ return "";
+ }
+
+ }
+
+ private async Task RetryFailedBatch(string localFilePath, string fileName)
+ {
+
+ var copied = false;
+ using (FileStream fileStream = File.OpenRead(localFilePath))
+ {
+ var blobFile = new BlobFile(fileStream, fileName);
+ copied = await _blobStorageHelper.UploadFileToBlobStorage(_config.caasfolder_STORAGE, "inbound", blobFile, true);
+ }
+
+ if (copied)
+ {
+ _logger.LogInformation("Adding failed batch to blob was successful");
+ return true;
+ }
+ _logger.LogError("Adding failed batch to blob was unsuccessful");
+ return false;
+ }
+
+
+ private async Task AddItemToBlob(Stream stream, string fileName)
+ {
+ var blobFile = new BlobFile(stream, fileName);
+ var copied = await _blobStorageHelper.UploadFileToBlobStorage(_config.caasfolder_STORAGE, "failed-batch", blobFile);
+
+ if (copied)
+ {
+ _logger.LogInformation("Adding failed batch to blob was successful");
+ return true;
}
+ return false;
}
+ private string FileDirectoryPath(string fileName)
+ {
+ var currentDirectory = Directory.GetCurrentDirectory();
+ var filePath = Path.Combine(currentDirectory, fileName);
+
+ filePath = filePath.Replace("bin/output/", "");
+
+ return filePath;
+ }
+
+
private static Stream GenerateStreamFromString(string s)
{
var stream = new MemoryStream();
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/FailedBatchDict.cs b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/FailedBatchDict.cs
new file mode 100644
index 0000000000..995d2031d9
--- /dev/null
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/FailedBatchDict.cs
@@ -0,0 +1,62 @@
+using Common;
+using Microsoft.Azure.Functions.Worker;
+
+public class FailedBatchDict : IFailedBatchDict
+{
+ private Dictionary RetryDictionary;
+
+ private static readonly int RetryCount = 3;
+ public FailedBatchDict()
+ {
+ RetryDictionary = new Dictionary();
+ }
+
+ public void AddFailedBatchDataToDict(string FileName, int retryCount)
+ {
+ RetryDictionary.Add(FileName, retryCount);
+ }
+
+ public int GetRetryCount(string fileName)
+ {
+ if (RetryDictionary.TryGetValue(fileName, out int fileRetryCount))
+ {
+ return fileRetryCount;
+ }
+ return 0;
+ }
+
+ public bool HasFileFailedBefore(string fileName)
+ {
+ return RetryDictionary.ContainsKey(fileName);
+ }
+
+ public void UpdateFileFailureCount(string fileName, int failureCount)
+ {
+ RetryDictionary[fileName] = failureCount;
+ }
+
+
+ public bool ShouldRetryFile(string filename)
+ {
+ if (RetryDictionary.Count < 1)
+ {
+ return true;
+ }
+
+ if (RetryDictionary.TryGetValue(filename, out int fileRetryCount))
+ {
+ if (fileRetryCount < RetryCount)
+ {
+ return true;
+ }
+ RetryDictionary.Remove(filename);
+ return false;
+ }
+
+ return true;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ICallDurableDemographicFunc.cs b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ICallDurableDemographicFunc.cs
index 161a5ee2fa..c5e8248db0 100644
--- a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ICallDurableDemographicFunc.cs
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ICallDurableDemographicFunc.cs
@@ -4,6 +4,6 @@ namespace NHS.Screening.ReceiveCaasFile;
public interface ICallDurableDemographicFunc
{
- Task PostDemographicDataAsync(List participants, string DemographicFunctionURI, string fileName);
+ Task PostDemographicDataAsync(List participants, string DemographicFunctionURI, string fileName, List values);
}
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ICopyFailedBatchToBlob.cs b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ICopyFailedBatchToBlob.cs
index 698ad06630..f09f3fc4c4 100644
--- a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ICopyFailedBatchToBlob.cs
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ICopyFailedBatchToBlob.cs
@@ -1,6 +1,8 @@
namespace NHS.Screening.ReceiveCaasFile;
+using Model;
+
public interface ICopyFailedBatchToBlob
{
- Task writeBatchToBlob(string jsonFromBatch, InvalidOperationException invalidOperationException);
+ Task writeBatchToBlob(string jsonFromBatch, InvalidOperationException invalidOperationException, List parquetValuesForRetry, string fileName = "");
}
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/IFailedBatchDict.cs b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/IFailedBatchDict.cs
new file mode 100644
index 0000000000..896a073ed9
--- /dev/null
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/IFailedBatchDict.cs
@@ -0,0 +1,8 @@
+public interface IFailedBatchDict
+{
+ void AddFailedBatchDataToDict(string FileName, int retryCount);
+ bool ShouldRetryFile(string filename);
+ int GetRetryCount(string fileName);
+ bool HasFileFailedBefore(string fileName);
+ void UpdateFileFailureCount(string fileName, int failureCount);
+}
\ No newline at end of file
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ProcessCaasFile.cs b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ProcessCaasFile.cs
index 3d46356549..df189cd340 100644
--- a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ProcessCaasFile.cs
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/ProcessFileClasses/ProcessCaasFile.cs
@@ -64,30 +64,35 @@ IOptions receiveCaasFileConfig
public async Task ProcessRecords(List values, ParallelOptions options, ScreeningLkp screeningService, string name)
{
var currentBatch = new Batch();
+
await Parallel.ForEachAsync(values, options, async (rec, cancellationToken) =>
{
var participant = _receiveCaasFileHelper.MapParticipant(rec, screeningService.ScreeningId.ToString(), screeningService.ScreeningName, name);
if (participant == null)
{
+ values.Remove(rec);
await _exceptionHandler.CreateSystemExceptionLogFromNhsNumber(new Exception($"Could not map participant in file {name}"), rec.NhsNumber.ToString(), name, screeningService.ScreeningName, "");
return;
}
if (!ValidationHelper.ValidateNHSNumber(participant.NhsNumber))
{
+ values.Remove(rec);
await _exceptionHandler.CreateSystemExceptionLog(new Exception($"Invalid NHS Number was passed in for participant {participant} and file {name}"), participant, name, nameof(ExceptionCategory.CaaS));
return; // skip current participant
}
if (!_validateDates.ValidateAllDates(participant))
{
+ values.Remove(rec);
await _exceptionHandler.CreateSystemExceptionLog(new Exception($"Invalid effective date found in participant data {participant} and file name {name}"), participant, name);
return; // Skip current participant
}
if (!_recordsProcessTracker.RecordAlreadyProcessed(participant.RecordType, participant.NhsNumber))
{
+ values.Remove(rec);
await _exceptionHandler.CreateSystemExceptionLog(new Exception($"Duplicate Participant was in the file"), participant, name);
return; // Skip current participant
}
@@ -95,7 +100,7 @@ await Parallel.ForEachAsync(values, options, async (rec, cancellationToken) =>
await AddRecordToBatch(participant, currentBatch, name);
});
- if (await _callDurableDemographicFunc.PostDemographicDataAsync(currentBatch.DemographicData.ToList(), DemographicURI, name))
+ if (await _callDurableDemographicFunc.PostDemographicDataAsync(currentBatch.DemographicData.ToList(), DemographicURI, name, values))
{
await AddBatchToQueue(currentBatch, name);
}
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/Program.cs b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/Program.cs
index db7f262421..5c333009d9 100644
--- a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/Program.cs
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/Program.cs
@@ -35,8 +35,9 @@
services.AddScoped();
services.AddScoped();
services.AddScoped(); //Do not change the lifetime of this.
- services.AddTransient();
- services.AddTransient();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
services.AddScoped();
// Register health checks
services.AddBlobStorageHealthCheck("receiveCaasFile");
diff --git a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/receiveCaasFile.csproj b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/receiveCaasFile.csproj
index 2d3df00af5..e69e3d51d1 100644
--- a/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/receiveCaasFile.csproj
+++ b/application/CohortManager/src/Functions/CaasIntegration/receiveCaasFile/receiveCaasFile.csproj
@@ -15,6 +15,7 @@
+
diff --git a/application/CohortManager/src/Functions/DemographicServices/DemographicDurableFunction/DurableDemographicFunction.cs b/application/CohortManager/src/Functions/DemographicServices/DemographicDurableFunction/DurableDemographicFunction.cs
index 1f014cd20e..1ae374e5a2 100644
--- a/application/CohortManager/src/Functions/DemographicServices/DemographicDurableFunction/DurableDemographicFunction.cs
+++ b/application/CohortManager/src/Functions/DemographicServices/DemographicDurableFunction/DurableDemographicFunction.cs
@@ -37,60 +37,42 @@ public DurableDemographicFunction(IDataServiceClient dat
public async Task RunOrchestrator(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
- var orchestrationTimeout = TimeSpan.FromHours(2.5);
- var expirationTime = context.CurrentUtcDateTime.Add(orchestrationTimeout);
- using (var cts = new CancellationTokenSource(orchestrationTimeout))
+ try
{
- try
- {
- var demographicJsonData = context.GetInput();
-
- if (string.IsNullOrEmpty(demographicJsonData))
- {
- throw new InvalidDataException("demographicJsonData was null or empty in Orchestration function");
- }
-
- var retryOptions = TaskOptions.FromRetryPolicy(new RetryPolicy(
- maxNumberOfAttempts: 1, // this means the function will not retry and therefore add duplicates
- firstRetryInterval: TimeSpan.FromSeconds(100))
- );
-
- // Add timeout-aware logic
- var task = context.CallActivityAsync(
- nameof(InsertDemographicData),
- demographicJsonData,
- options: retryOptions
- );
-
- // Monitor for timeout
- var timeoutTask = context.CreateTimer(expirationTime, cts.Token);
- var completedTask = await Task.WhenAny(task, timeoutTask);
-
- if (completedTask == timeoutTask)
- {
- _logger.LogWarning("Orchestration timed out.");
- throw new TimeoutException("Orchestration function exceeded its timeout.");
- }
-
- cts.Cancel();
- var recordsInserted = await task;
-
- if (!recordsInserted)
- {
- throw new InvalidOperationException("Demographic records were not added to the database in the orchestration function");
- }
- return true;
+ var demographicJsonData = context.GetInput();
+ if (string.IsNullOrEmpty(demographicJsonData))
+ {
+ throw new InvalidDataException("demographicJsonData was null or empty in Orchestration function");
}
- catch (Exception ex)
+
+ var retryOptions = TaskOptions.FromRetryPolicy(new RetryPolicy(
+ maxNumberOfAttempts: 1, // this means the function will not retry and therefore add duplicates
+ firstRetryInterval: TimeSpan.FromSeconds(100))
+ );
+
+ var recordsInserted = await context.CallActivityAsync(
+ nameof(InsertDemographicData),
+ demographicJsonData,
+ options: retryOptions
+ );
+
+ if (!recordsInserted)
{
- _logger.LogError(ex, "Orchestration failed with exception. {exception}", ex.Message);
- throw;
+ throw new InvalidOperationException("Demographic records were not added to the database in the orchestration function");
}
+ return true;
+
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Orchestration failed with exception. {exception}", ex.Message);
+ throw;
}
}
+
///
/// Inserts demographic data into the data store.
///
@@ -103,7 +85,7 @@ public async Task InsertDemographicData([ActivityTrigger] string demograph
try
{
var participantData = JsonSerializer.Deserialize>(demographicJsonData);
- return await _participantDemographic.AddRange(participantData);
+ return await _participantDemographic.AddRange(participantData!);
}
catch (Exception ex)
{
diff --git a/application/CohortManager/src/Functions/Shared/Model/Mapping/PartcipantsMapToParquet.cs b/application/CohortManager/src/Functions/Shared/Model/Mapping/PartcipantsMapToParquet.cs
new file mode 100644
index 0000000000..755a3c0f74
--- /dev/null
+++ b/application/CohortManager/src/Functions/Shared/Model/Mapping/PartcipantsMapToParquet.cs
@@ -0,0 +1,43 @@
+namespace Model;
+
+public struct ParticipantsParquet
+{
+ public string? record_type { get; set; }
+ public long? change_time_stamp { get; set; }
+ public long? serial_change_number { get; set; }
+ public long? nhs_number { get; set; }
+ public long? superseded_by_nhs_number { get; set; }
+ public string? primary_care_provider { get; set; }
+ public string? primary_care_effective_from_date { get; set; }
+ public string? current_posting { get; set; }
+ public string? current_posting_effective_from_date { get; set; }
+ public string? name_prefix { get; set; }
+ public string? given_name { get; set; }
+ public string? other_given_name { get; set; }
+ public string? family_name { get; set; }
+ public string? previous_family_name { get; set; }
+ public string? date_of_birth { get; set; }
+ public long? gender { get; set; }
+ public string? address_line_1 { get; set; }
+ public string? address_line_2 { get; set; }
+ public string? address_line_3 { get; set; }
+ public string? address_line_4 { get; set; }
+ public string? address_line_5 { get; set; }
+ public string? postcode { get; set; }
+ public string? paf_key { get; set; }
+ public string? address_effective_from_date { get; set; }
+ public string? reason_for_removal { get; set; }
+ public string? reason_for_removal_effective_from_date { get; set; }
+ public string? date_of_death { get; set; }
+ public int? death_status { get; set; }
+ public string? home_telephone_number { get; set; }
+ public string? home_telephone_effective_from_date { get; set; }
+ public string? mobile_telephone_number { get; set; }
+ public string? mobile_telephone_effective_from_date { get; set; }
+ public string? email_address { get; set; }
+ public string? email_address_effective_from_date { get; set; }
+ public string? preferred_language { get; set; }
+ public bool? is_interpreter_required { get; set; }
+ public bool? invalid_flag { get; set; }
+ public bool? eligibility { get; set; }
+}
\ No newline at end of file
diff --git a/application/CohortManager/src/Functions/Shared/Model/Mapping/ParticipantsParquetMap.cs b/application/CohortManager/src/Functions/Shared/Model/Mapping/ParticipantsParquetMap.cs
index a2dde28a94..1a80279ec8 100644
--- a/application/CohortManager/src/Functions/Shared/Model/Mapping/ParticipantsParquetMap.cs
+++ b/application/CohortManager/src/Functions/Shared/Model/Mapping/ParticipantsParquetMap.cs
@@ -1,5 +1,9 @@
namespace Model;
+
using ParquetSharp.RowOriented;
+using Parquet.Serialization.Attributes;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Security.Cryptography;
public struct ParticipantsParquetMap
{
@@ -116,4 +120,49 @@ public struct ParticipantsParquetMap
[MapToColumn("eligibility")]
public bool? EligibilityFlag { get; set; }
+
+ public static ParticipantsParquet ToParticipantParquet(ParticipantsParquetMap participantsParquetMap)
+ {
+ return new ParticipantsParquet()
+ {
+ record_type = participantsParquetMap.RecordType,
+ change_time_stamp = participantsParquetMap.ChangeTimeStamp,
+ serial_change_number = participantsParquetMap.SerialChangeNumber,
+ nhs_number = participantsParquetMap.NhsNumber,
+ superseded_by_nhs_number = participantsParquetMap.SupersededByNhsNumber,
+ primary_care_provider = participantsParquetMap.PrimaryCareProvider,
+ primary_care_effective_from_date = participantsParquetMap.PrimaryCareEffectiveFromDate,
+ current_posting = participantsParquetMap.CurrentPosting,
+ current_posting_effective_from_date = participantsParquetMap.CurrentPostingEffectiveFromDate,
+ name_prefix = participantsParquetMap.NamePrefix,
+ given_name = participantsParquetMap.FirstName,
+ other_given_name = participantsParquetMap.OtherGivenNames,
+ family_name = participantsParquetMap.SurnamePrefix,
+ previous_family_name = participantsParquetMap.PreviousSurnamePrefix,
+ date_of_birth = participantsParquetMap.DateOfBirth,
+ gender = participantsParquetMap.Gender,
+ address_line_1 = participantsParquetMap.AddressLine1,
+ address_line_2 = participantsParquetMap.AddressLine2,
+ address_line_3 = participantsParquetMap.AddressLine3,
+ address_line_4 = participantsParquetMap.AddressLine4,
+ address_line_5 = participantsParquetMap.AddressLine5,
+ postcode = participantsParquetMap.Postcode,
+ paf_key = participantsParquetMap.PafKey,
+ address_effective_from_date = participantsParquetMap.UsualAddressEffectiveFromDate,
+ reason_for_removal = participantsParquetMap.ReasonForRemoval,
+ reason_for_removal_effective_from_date = participantsParquetMap.ReasonForRemovalEffectiveFromDate,
+ date_of_death = participantsParquetMap.DateOfDeath,
+ death_status = participantsParquetMap.DeathStatus,
+ home_telephone_number = participantsParquetMap.TelephoneNumber,
+ home_telephone_effective_from_date = participantsParquetMap.TelephoneNumberEffectiveFromDate,
+ mobile_telephone_number = participantsParquetMap.MobileNumber,
+ mobile_telephone_effective_from_date = participantsParquetMap.MobileNumberEffectiveFromDate,
+ email_address = participantsParquetMap.EmailAddress,
+ email_address_effective_from_date = participantsParquetMap.EmailAddressEffectiveFromDate,
+ preferred_language = participantsParquetMap.PreferredLanguage,
+ is_interpreter_required = participantsParquetMap.IsInterpreterRequired,
+ invalid_flag = participantsParquetMap.InvalidFlag,
+ eligibility = participantsParquetMap.EligibilityFlag
+ };
+ }
}
diff --git a/application/CohortManager/src/Functions/Shared/Model/Model.csproj b/application/CohortManager/src/Functions/Shared/Model/Model.csproj
index 1671fb51d5..dfbb87c457 100644
--- a/application/CohortManager/src/Functions/Shared/Model/Model.csproj
+++ b/application/CohortManager/src/Functions/Shared/Model/Model.csproj
@@ -8,6 +8,7 @@
+