Skip to content

Commit b8253d8

Browse files
feat: DTOSS-12464 & DTOSS-12468 dummy gp rules (#1876)
* Rule 70 Added * rule 71 added * add rule 72 Welsh GP Removal * Update application/CohortManager/src/Functions/ScreeningValidationService/LookupValidation/LookupValidation.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * XML Doc issue --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 36f8aae commit b8253d8

16 files changed

Lines changed: 320 additions & 22 deletions

File tree

application/CohortManager/src/Functions/CohortDistributionServices/DistributeParticipant/DistributeParticipant.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ public async Task Run(
6969
public async Task DistributeParticipantOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
7070
{
7171
var participantRecord = context.GetInput<BasicParticipantCsvRecord>();
72+
73+
if (participantRecord is null)
74+
{
75+
_logger.LogError("Orchestration was started with null input");
76+
return;
77+
}
78+
7279
try
7380
{
7481
// Retrieve participant data
@@ -87,16 +94,17 @@ public async Task DistributeParticipantOrchestrator([OrchestrationTrigger] TaskO
8794
return;
8895
}
8996

90-
ValidationRecord validationRecord = new() { FileName = participantRecord.FileName, Participant = participantData };
97+
ValidationRecord validationRecord = new() { FileName = participantRecord.FileName, Participant = participantData, ReasonForAdding = participantRecord.ReasonForAdding };
9198

9299
var serviceNowParticipant = participantRecord?.Participant.ReferralFlag == "1";
100+
93101
if (serviceNowParticipant && !string.IsNullOrEmpty(participantRecord?.Participant.PrimaryCareProvider))
94102
{
95103
validationRecord.Participant.PrimaryCareProvider = participantRecord.Participant.PrimaryCareProvider;
96104
}
97105

98106
// Allocate service provider
99-
validationRecord.ServiceProvider = await context.CallActivityAsync<string>(nameof(Activities.AllocateServiceProvider), participantRecord.Participant);
107+
validationRecord.ServiceProvider = await context.CallActivityAsync<string>(nameof(Activities.AllocateServiceProvider), validationRecord.Participant);
100108

101109
// Validation & Transformation
102110
var transformedParticipant = await context.CallSubOrchestratorAsync<CohortDistributionParticipant?>(nameof(ValidateParticipant.ValidationOrchestrator), validationRecord);

application/CohortManager/src/Functions/CohortDistributionServices/DistributeParticipant/ValidateParticipant.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ public async Task RemoveOldValidationExceptions([ActivityTrigger] OldExceptionRe
154154
var request = new ParticipantCsvRecord
155155
{
156156
Participant = new Participant(validationRecord.Participant),
157-
FileName = validationRecord.FileName
157+
FileName = validationRecord.FileName,
158+
ReasonForAdding = validationRecord.ReasonForAdding
158159
};
159160

160161
var json = JsonSerializer.Serialize(request);
@@ -185,7 +186,9 @@ public async Task<List<ValidationRuleResult>> LookupValidation([ActivityTrigger]
185186
{
186187
NewParticipant = new Participant(validationRecord.Participant),
187188
ExistingParticipant = new Participant(validationRecord.PreviousParticipantRecord),
188-
FileName = validationRecord.FileName
189+
FileName = validationRecord.FileName,
190+
ReasonForAdding = validationRecord.ReasonForAdding
191+
189192
};
190193

191194
var json = JsonSerializer.Serialize(request);
@@ -218,7 +221,8 @@ public async Task<List<ValidationRuleResult>> LookupValidation([ActivityTrigger]
218221
FileName = validationRecord.FileName,
219222
// TODO: is this used?
220223
ServiceProvider = validationRecord.ServiceProvider,
221-
ExistingParticipant = validationRecord.PreviousParticipantRecord.ToCohortDistribution()
224+
ExistingParticipant = validationRecord.PreviousParticipantRecord.ToCohortDistribution(),
225+
ReasonForAdding = validationRecord.ReasonForAdding
222226
};
223227

224228
var json = JsonSerializer.Serialize(transformDataRequestBody);
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
namespace NHS.CohortManager.CohortDistributionServices;
22

33
using Model;
4+
using Model.Enums;
45

56
public class ValidationRecord
67
{
78
public required string FileName { get; set; }
89
public required CohortDistributionParticipant Participant { get; set; }
910
public CohortDistributionParticipant? PreviousParticipantRecord { get; set; }
1011
public string ServiceProvider { get; set; }
11-
}
12+
public ReasonForAdding? ReasonForAdding { get; set; } = null;
13+
}

application/CohortManager/src/Functions/CohortDistributionServices/TransformDataService/ITransformDataLookupFacade.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ public interface ITransformDataLookupFacade
1010
public bool ValidateLanguageCode(string languageCode);
1111
public Task<HashSet<string>> GetCachedExcludedSMUValues();
1212
string RetrievePostingCategory(string currentPosting);
13+
bool CheckIfPrimaryCareProviderExists(string primaryCareProvider);
1314
}

application/CohortManager/src/Functions/CohortDistributionServices/TransformDataService/TransformDataLookupFacade.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,18 @@ public string RetrievePostingCategory(string currentPosting)
126126
var result = _currentPostingClient.GetSingle(currentPosting).Result;
127127
return result.PostingCategory;
128128
}
129+
130+
131+
/// <summary>
132+
/// Used in rule 36 in the lookup rules, and rule 54 in the cohort rules.
133+
/// Validates the participants primary care provider (GP practice code)
134+
/// </summary>
135+
/// <param name="primaryCareProvider">The participant's primary care provider.</param>
136+
/// <returns>bool, whether or not the GP practice code exists in the DB.</returns>
137+
public bool CheckIfPrimaryCareProviderExists(string primaryCareProvider)
138+
{
139+
_logger.LogInformation("Checking Primary Care Provider {PrimaryCareProvider} Exists", primaryCareProvider);
140+
var result = _bsSelectGPPracticeClient.GetSingle(primaryCareProvider).Result;
141+
return result != null;
142+
}
129143
}

application/CohortManager/src/Functions/CohortDistributionServices/TransformDataService/TransformDataService.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Ano
7979
participant = await transformString.TransformStringFields(participant);
8080

8181
// Other transformation rules
82-
participant = await TransformParticipantAsync(participant, requestBody.ExistingParticipant, ValidationHelper.CheckManualAddFileName(requestBody.FileName));
82+
participant = await TransformParticipantAsync(participant, requestBody.ExistingParticipant, requestBody.ReasonForAdding);
8383

8484
// Name prefix transformation
8585
if (participant.NamePrefix != null)
@@ -117,7 +117,7 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Ano
117117
}
118118

119119
public async Task<CohortDistributionParticipant> TransformParticipantAsync(CohortDistributionParticipant participant,
120-
CohortDistribution databaseParticipant, bool isManualAdd = false)
120+
CohortDistribution databaseParticipant, ReasonForAdding? reasonForAdding = null)
121121
{
122122
var excludedSMUList = await _dataLookup.GetCachedExcludedSMUValues();
123123

@@ -127,7 +127,7 @@ public async Task<CohortDistributionParticipant> TransformParticipantAsync(Cohor
127127
var reSettings = new ReSettings
128128
{
129129
CustomActions = actions,
130-
CustomTypes = [typeof(Actions), typeof(CohortDistributionParticipant), typeof(CohortDistribution)],
130+
CustomTypes = [typeof(Actions), typeof(CohortDistributionParticipant), typeof(CohortDistribution), typeof(ReasonForAdding)],
131131
UseFastExpressionCompiler = false
132132
};
133133

@@ -144,11 +144,16 @@ public async Task<CohortDistributionParticipant> TransformParticipantAsync(Cohor
144144

145145
var resultList = await re.ExecuteAllRulesAsync("Common", ruleParameters);
146146

147-
if (isManualAdd)
147+
if (reasonForAdding.HasValue && reasonForAdding != ReasonForAdding.DummyGpCodeRemoval)
148148
{
149149
resultList.AddRange(await re.ExecuteAllRulesAsync("ManualAdd", ruleParameters));
150150
}
151151

152+
if (reasonForAdding.HasValue && reasonForAdding == ReasonForAdding.DummyGpCodeRemoval)
153+
{
154+
resultList.AddRange(await re.ExecuteAllRulesAsync("DummyGpRemoval", ruleParameters));
155+
}
156+
152157
await HandleExceptions(resultList, participant);
153158
await CreateTransformExecutedExceptions(resultList, participant);
154159

application/CohortManager/src/Functions/CohortDistributionServices/TransformDataService/transformRules.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,5 +796,66 @@
796796
}
797797
}
798798
]
799+
},
800+
{
801+
"WorkflowName": "DummyGpRemoval",
802+
"Rules": [
803+
{
804+
"RuleName": "71.DummyGpCodeRemoval",
805+
"Expression": "new string[] { \"RDR\", \"RDI\", \"RPR\" }.Contains(participant.ReasonForRemoval)",
806+
"Actions": {
807+
"OnSuccess": {
808+
"Name": "TransformAction",
809+
"Context": {
810+
"transformFields": [
811+
{
812+
"field": "ReasonForRemoval",
813+
"value": "ORR",
814+
"isExpression": false
815+
},
816+
{
817+
"field": "ReasonForRemovalEffectiveFromDate",
818+
"value": "DateTime.UtcNow.Date.ToString(\"yyyyMMdd\")",
819+
"isExpression": true
820+
}
821+
]
822+
}
823+
}
824+
}
825+
},
826+
{
827+
"RuleName": "72.RemoveWelshGPCodeForDummyGpRemoval",
828+
"LocalParams": [
829+
{
830+
"Name": "ValidPrimaryCareProvider",
831+
"Expression": "string.IsNullOrEmpty(participant.PrimaryCareProvider) || dbLookup.CheckIfPrimaryCareProviderExists(participant.PrimaryCareProvider)"
832+
},
833+
{
834+
"Name" : "WelshGPCode",
835+
"Expression": "string.IsNullOrEmpty(participant.PrimaryCareProvider) ? false : participant.PrimaryCareProvider.StartsWith(\"W\")"
836+
}
837+
],
838+
"Expression": "!ValidPrimaryCareProvider && WelshGPCode",
839+
"Actions": {
840+
"OnSuccess": {
841+
"Name": "TransformAction",
842+
"Context": {
843+
"transformFields": [
844+
{
845+
"field": "ReasonForRemoval",
846+
"value": "ORR",
847+
"isExpression": false
848+
},
849+
{
850+
"field": "ReasonForRemovalEffectiveFromDate",
851+
"value": "DateTime.UtcNow.Date.ToString(\"yyyyMMdd\")",
852+
"isExpression": true
853+
}
854+
]
855+
}
856+
}
857+
}
858+
}
859+
]
799860
}
800861
]

application/CohortManager/src/Functions/ScreeningValidationService/LookupValidation/Breast_Screening_lookupRules.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
{
66
"Name": "ValidPrimaryCareProvider",
77
"Expression": "string.IsNullOrEmpty(newParticipant.PrimaryCareProvider) || dbLookup.CheckIfPrimaryCareProviderExists(newParticipant.PrimaryCareProvider)"
8+
},
9+
{
10+
"Name": "DummyGPCodeRemovalAdd",
11+
"Expression": "(reasonForAdding == null ? false : reasonForAdding == ReasonForAdding.DummyGpCodeRemoval)"
812
}
913
],
1014
"Rules": [
@@ -20,7 +24,7 @@
2024
"Expression": "dbLookup.CheckIfPrimaryCareProviderInExcludedSmuList(newParticipant.PrimaryCareProvider)"
2125
}
2226
],
23-
"Expression": "(WelshPostingCategory || ValidPrimaryCareProvider || IsExcluded)",
27+
"Expression": "(DummyGPCodeRemovalAdd || WelshPostingCategory || ValidPrimaryCareProvider || IsExcluded)",
2428
"Actions": {
2529
"OnFailure": {
2630
"Name": "OutputExpression",
@@ -29,6 +33,18 @@
2933
}
3034
}
3135
}
36+
},
37+
{
38+
"RuleName": "70.DummyGpRemovalWithInvalidGP.BSS.NonFatal",
39+
"Expression": "!DummyGPCodeRemovalAdd OR ValidPrimaryCareProvider OR (string.IsNullOrEmpty(newParticipant.PrimaryCareProvider) ? false : newParticipant.PrimaryCareProvider.StartsWith(\"W\"))",
40+
"Actions":{
41+
"OnFailure":{
42+
"Name":"OutputExpression",
43+
"Context":{
44+
"Expression":"\"Reason for adding is Dummy GP code removal but primary care provider is not a valid GP code\""
45+
}
46+
}
47+
}
3248
}
3349
]
3450
},

application/CohortManager/src/Functions/ScreeningValidationService/LookupValidation/LookupValidation.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,16 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Ano
6969

7070
var reSettings = new ReSettings
7171
{
72-
CustomTypes = [typeof(Actions)],
72+
CustomTypes = [typeof(Actions), typeof(ReasonForAdding)],
7373
UseFastExpressionCompiler = false
7474
};
7575
var re = new RulesEngine.RulesEngine(rules, reSettings);
7676

7777
var ruleParameters = new[] {
7878
new RuleParameter("existingParticipant", requestBody.ExistingParticipant),
7979
new RuleParameter("newParticipant", newParticipant),
80-
new RuleParameter("dbLookup", _dataLookup)
80+
new RuleParameter("dbLookup", _dataLookup),
81+
new RuleParameter("reasonForAdding", requestBody.ReasonForAdding)
8182
};
8283

8384
var resultList = new List<RuleResultTree>();
@@ -92,12 +93,11 @@ public async Task<HttpResponseData> RunAsync([HttpTrigger(AuthorizationLevel.Ano
9293
var ActionResults = await re.ExecuteAllRulesAsync(newParticipant.RecordType, ruleParameters);
9394
resultList.AddRange(ActionResults);
9495
}
95-
if (isManualAdd)
96+
if (isManualAdd && requestBody.ReasonForAdding.HasValue && requestBody.ReasonForAdding != ReasonForAdding.DummyGpCodeRemoval)
9697
{
9798
var ActionResults = await re.ExecuteAllRulesAsync("ManualAdd", ruleParameters);
9899
resultList.AddRange(ActionResults);
99100
}
100-
101101
// Validation rules are logically reversed
102102
var validationErrors = resultList.Where(x => !x.IsSuccess).Select(x => new ValidationRuleResult(x));
103103

application/CohortManager/src/Functions/ScreeningValidationService/StaticValidation/Breast_Screening_staticRules.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
}
9292
}
9393
},
94-
{
94+
{
9595
"RuleName": "3.PrimaryCareProviderAndReasonForRemoval.NBO.NonFatal",
9696
"Expression": "manualAdd OR ((string.IsNullOrEmpty(participant.PrimaryCareProvider) AND !string.IsNullOrEmpty(participant.ReasonForRemoval)) OR (!string.IsNullOrEmpty(participant.PrimaryCareProvider) AND string.IsNullOrEmpty(participant.ReasonForRemoval)))",
9797
"Actions": {
@@ -180,7 +180,7 @@
180180
"Rules": [
181181
{
182182
"RuleName": "97.NoDummyGPorPCP.NBO.NonFatal",
183-
"LocalParams" : [
183+
"LocalParams": [
184184
{
185185
"Name": "ValidReasonForRemoval",
186186
"Expression": "participant.ReasonForRemoval == \"RDR\" || participant.ReasonForRemoval == \"RPR\" || participant.ReasonForRemoval == \"RDI\" "

0 commit comments

Comments
 (0)