Skip to content

Commit 08a52d5

Browse files
committed
adding encounter NOPAT scenario
1 parent 9aae3b1 commit 08a52d5

File tree

9 files changed

+189
-3
lines changed

9 files changed

+189
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
### Added
10+
The GP2GP Adaptor now adds the EhrComposition / confidentialityCode field when Encounter.meta.security contains NOPAT security entry
11+
12+
913
## [2.4.0] - 2025-04-02
1014

1115
### Added

service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EncounterMapper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import lombok.RequiredArgsConstructor;
2828
import lombok.SneakyThrows;
2929
import lombok.extern.slf4j.Slf4j;
30+
import uk.nhs.adaptors.gp2gp.common.service.ConfidentialityService;
3031
import uk.nhs.adaptors.gp2gp.ehr.exception.EhrMapperException;
3132
import uk.nhs.adaptors.gp2gp.ehr.mapper.parameters.EncounterTemplateParameters;
3233
import uk.nhs.adaptors.gp2gp.ehr.utils.DateFormatUtil;
@@ -48,6 +49,7 @@ public class EncounterMapper {
4849

4950
private final MessageContext messageContext;
5051
private final EncounterComponentsMapper encounterComponentsMapper;
52+
private final ConfidentialityService confidentialityService;
5153

5254
public String mapEncounterToEhrComposition(Encounter encounter) {
5355
LOGGER.debug("Generating ehrComposition for Encounter {}", encounter.getId());
@@ -59,13 +61,16 @@ public String mapEncounterToEhrComposition(Encounter encounter) {
5961
return StringUtils.EMPTY;
6062
}
6163

64+
var confidentialityCode = confidentialityService.generateConfidentialityCode(encounter);
65+
6266
final IdMapper idMapper = messageContext.getIdMapper();
6367
AgentDirectory agentDirectory = messageContext.getAgentDirectory();
6468

6569
var encounterStatementTemplateParameters = EncounterTemplateParameters.builder()
6670
.encounterStatementId(idMapper.getOrNew(ResourceType.Encounter, encounter.getIdElement()))
6771
.effectiveTime(StatementTimeMappingUtils.prepareEffectiveTimeForEncounter(encounter))
6872
.availabilityTime(StatementTimeMappingUtils.prepareAvailabilityTime(encounter.getPeriod().getStartElement()))
73+
.confidentialityCode(confidentialityCode.orElse(null))
6974
.status(COMPLETE_CODE)
7075
.components(components)
7176
.code(buildCode(encounter))

service/src/main/java/uk/nhs/adaptors/gp2gp/ehr/mapper/parameters/EncounterTemplateParameters.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ public class EncounterTemplateParameters {
2121
private String participant2;
2222
private String author;
2323
private String locationName;
24+
private String confidentialityCode;
2425
}

service/src/main/resources/templates/ehr_encounter_to_ehr_composition_template.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
{{{effectiveTime}}}
1515
</effectiveTime>
1616
{{{availabilityTime}}}
17+
{{#confidentialityCode}}
18+
{{{confidentialityCode}}}
19+
{{/confidentialityCode}}
1720
<author typeCode="AUT" contextControlCode="OP">
1821
<time {{#authorTime}}value="{{authorTime}}"{{/authorTime}}{{^authorTime}}nullFlavor="UNK"{{/authorTime}} />
1922
<agentRef classCode="AGNT">

service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EhrExtractMapperComponentTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ codeableConceptCdMapper, new ParticipantMapper(), confidentialityService),
208208

209209
ehrExtractMapper = new EhrExtractMapper(randomIdGeneratorService,
210210
timestampService,
211-
new EncounterMapper(messageContext, encounterComponentsMapper),
211+
new EncounterMapper(messageContext, encounterComponentsMapper, confidentialityService),
212212
nonConsultationResourceMapper,
213213
agentDirectoryMapper,
214214
messageContext);

service/src/test/java/uk/nhs/adaptors/gp2gp/ehr/mapper/EncounterMapperTest.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.time.Instant;
1111
import java.util.Date;
1212
import java.util.List;
13+
import java.util.Optional;
1314
import java.util.stream.Stream;
1415

1516
import org.apache.commons.lang3.StringUtils;
@@ -30,6 +31,7 @@
3031
import org.mockito.Mock;
3132
import org.mockito.junit.jupiter.MockitoExtension;
3233

34+
import uk.nhs.adaptors.gp2gp.common.service.ConfidentialityService;
3335
import uk.nhs.adaptors.gp2gp.common.service.FhirParseService;
3436
import uk.nhs.adaptors.gp2gp.common.service.RandomIdGeneratorService;
3537
import uk.nhs.adaptors.gp2gp.ehr.exception.EhrMapperException;
@@ -44,6 +46,12 @@ public class EncounterMapperTest {
4446
private static final Date CONSULTATION_DATE = Date.from(Instant.parse("2010-01-13T15:13:32Z"));
4547
private static final String TEST_LOCATION_NAME = "Test Location";
4648
private static final String TEST_LOCATION_ID = "EB3994A6-5A87-4B53-A414-913137072F57";
49+
private static final String CONFIDENTIALITY_CODE = """
50+
<confidentialityCode
51+
code="NOPAT"
52+
codeSystem="2.16.840.1.113883.4.642.3.47"
53+
displayName="no disclosure to patient, family or caregivers without attending provider's authorization"
54+
/>""";
4755

4856
public static final Bundle.BundleEntryComponent BUNDLE_ENTRY_WITH_CONSULTATION = new Bundle.BundleEntryComponent()
4957
.setResource(new ListResource()
@@ -67,6 +75,9 @@ public class EncounterMapperTest {
6775
@Mock
6876
private Bundle bundle;
6977

78+
@Mock
79+
private ConfidentialityService confidentialityService;
80+
7081
private EncounterMapper encounterMapper;
7182
private MessageContext messageContext;
7283

@@ -80,14 +91,32 @@ public void setUp() {
8091
BUNDLE_ENTRY_WITH_CONSULTATION,
8192
BUNDLE_ENTRY_WITH_LOCATION
8293
));
83-
encounterMapper = new EncounterMapper(messageContext, encounterComponentsMapper);
94+
encounterMapper = new EncounterMapper(messageContext, encounterComponentsMapper, confidentialityService);
8495
}
8596

8697
@AfterEach
8798
public void tearDown() {
8899
messageContext.resetMessageContext();
89100
}
90101

102+
@Test
103+
public void testEncounterWithNOPATAddsConfidentialityCodeIntoEhrComposition() {
104+
lenient().when(randomIdGeneratorService.createNewId()).thenReturn(TEST_ID);
105+
var sampleComponent = ResourceTestFileUtils.getFileContent(SAMPLE_EHR_COMPOSITION_COMPONENT);
106+
var encounterJsonInput = ResourceTestFileUtils.getFileContent(TEST_FILES_DIRECTORY + "input-encounter-with-nopat.json");
107+
var expectedOutputWithConfidentialityCode
108+
= ResourceTestFileUtils.getFileContent(TEST_FILES_DIRECTORY + "output-with-confidentiality-code.xml");
109+
110+
Encounter parsedEncounter = new FhirParseService().parseResource(encounterJsonInput, Encounter.class);
111+
when(confidentialityService.generateConfidentialityCode(parsedEncounter)).thenReturn(Optional.of(CONFIDENTIALITY_CODE));
112+
when(encounterComponentsMapper.mapComponents(parsedEncounter)).thenReturn(sampleComponent);
113+
114+
String outputMessageWithConfidentialityCode = encounterMapper.mapEncounterToEhrComposition(parsedEncounter);
115+
116+
assertThat(outputMessageWithConfidentialityCode).isEqualToIgnoringWhitespace(expectedOutputWithConfidentialityCode);
117+
verify(encounterComponentsMapper).mapComponents(parsedEncounter);
118+
}
119+
91120
@ParameterizedTest
92121
@MethodSource("testFilePaths")
93122
public void When_MappingParsedEncounterJson_Expect_EhrCompositionXmlOutput(String input, String output) {

service/src/test/java/uk/nhs/adaptors/gp2gp/uat/EhrExtractUATTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public void setUp() {
152152
= new AgentPersonMapper(messageContext);
153153
final AgentDirectoryMapper agentDirectoryMapper = new AgentDirectoryMapper(messageContext, agentPersonMapper);
154154

155-
final EncounterMapper encounterMapper = new EncounterMapper(messageContext, encounterComponentsMapper);
155+
final EncounterMapper encounterMapper = new EncounterMapper(messageContext, encounterComponentsMapper, confidentialityService);
156156

157157
final NonConsultationResourceMapper nonConsultationResourceMapper =
158158
new NonConsultationResourceMapper(messageContext, randomIdGeneratorService, encounterComponentsMapper,
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"resourceType":"Encounter",
3+
"id":"F550CC56-EF65-4934-A7B1-3DC2E02243C3",
4+
"meta": {
5+
"profile": [
6+
"https://fhir.nhs.uk/STU3/StructureDefinition/CareConnect-GPC-Immunization-1"
7+
],
8+
"security": [{
9+
"system":"http://hl7.org/fhir/v3/ActCode",
10+
"code":"NOPAT",
11+
"display":"no disclosure to patient, family or caregivers without attending provider's authorization"
12+
}]
13+
},
14+
"identifier":[
15+
{
16+
"system":"https://EMISWeb/A82038",
17+
"value":"F550CC56-EF65-4934-A7B1-3DC2E02243C3"
18+
}
19+
],
20+
"status":"finished",
21+
"type":[
22+
{
23+
"text":"GP Surgery",
24+
"coding": [
25+
{
26+
"system":"http://snomed.info/sct",
27+
"code":"24671000000101",
28+
"display":"Telephone call to a patient"
29+
}
30+
]
31+
}
32+
],
33+
"subject":{
34+
"reference":"Patient/88F14BF6-CADE-47D6-90E2-B10519BF956F"
35+
},
36+
"participant":[
37+
{
38+
"type":[
39+
{
40+
"coding":[
41+
{
42+
"system":"http://hl7.org/fhir/v3/ParticipationType",
43+
"code":"PPRF",
44+
"display":"primary performer"
45+
}
46+
]
47+
}
48+
],
49+
"individual":{
50+
"reference":"Practitioner/6D340A1B-BC15-4D4E-93CF-BBCB5B74DF73"
51+
}
52+
},
53+
{
54+
"type":[
55+
{
56+
"coding":[
57+
{
58+
"system":"https://fhir.nhs.uk/STU3/CodeSystem/GPConnect-ParticipantType-1",
59+
"code":"REC",
60+
"display":"recorder"
61+
}
62+
]
63+
}
64+
],
65+
"individual":{
66+
"reference":"Practitioner/6D340A1B-BC15-4D4E-93CF-BBCB5B74DF73"
67+
}
68+
}
69+
],
70+
"period":{
71+
"start":"2010-01-13T15:20:00+00:00"
72+
},
73+
"location":[
74+
{
75+
"location":{
76+
"reference":"Location/EB3994A6-5A87-4B53-A414-913137072F57"
77+
}
78+
}
79+
],
80+
"serviceProvider":{
81+
"reference":"Organization/5E496953-065B-41F2-9577-BE8F2FBD0757"
82+
}
83+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<component typeCode="COMP">
2+
<ehrComposition classCode="COMPOSITION" moodCode="EVN">
3+
<id root="test-id" />
4+
<code code="24671000000101" displayName="Telephone call to a patient" codeSystem="2.16.840.1.113883.2.1.3.2.4.15"><originalText>GP Surgery</originalText></code>
5+
<statusCode code="COMPLETE" />
6+
<effectiveTime>
7+
<center value="20100113152000"/>
8+
</effectiveTime>
9+
<availabilityTime value="20100113152000" />
10+
<confidentialityCode
11+
code="NOPAT"
12+
codeSystem="2.16.840.1.113883.4.642.3.47"
13+
displayName="no disclosure to patient, family or caregivers without attending provider's authorization" />
14+
<author typeCode="AUT" contextControlCode="OP">
15+
<time value="20100113151332" />
16+
<agentRef classCode="AGNT">
17+
<id root="test-id" />
18+
</agentRef>
19+
</author>
20+
<location typeCode="LOC">
21+
<locatedEntity classCode="LOCE">
22+
<code code="394730007" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Healthcare related organisation" />
23+
<locatedPlace classCode="PLC" determinerCode="INSTANCE">
24+
<name>Test Location</name>
25+
</locatedPlace>
26+
</locatedEntity>
27+
</location>
28+
<Participant2 typeCode="PRF" contextControlCode="OP">
29+
<agentRef classCode="AGNT">
30+
<id root="test-id" />
31+
</agentRef>
32+
</Participant2>
33+
<component typeCode="COMP" >
34+
<ObservationStatement classCode="OBS" moodCode="EVN">
35+
<id root="BA6EA7CB-3E2F-46FA-918C-C0B5178C1D4E" />
36+
<code code="907511000006105" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="[RFC] Chest infection">
37+
<originalText>Test</originalText>
38+
</code>
39+
<statusCode code="COMPLETE" />
40+
<effectiveTime>
41+
<center value="20201110115000"/>
42+
</effectiveTime>
43+
<availabilityTime value="20201110115000"/>
44+
45+
46+
<pertinentInformation typeCode="PERT">
47+
<sequenceNumber value="+1" />
48+
<pertinentAnnotation classCode="OBS" moodCode="EVN">
49+
<text>Test Observation</text>
50+
</pertinentAnnotation>
51+
</pertinentInformation>
52+
53+
<Participant typeCode="PRF" contextControlCode="OP">
54+
<agentRef classCode="AGNT">
55+
<id root="6423EA0F-1F1C-4255-AEBA-D142BE836D50"/>
56+
</agentRef>
57+
</Participant>
58+
</ObservationStatement>
59+
</component>
60+
</ehrComposition>
61+
</component>

0 commit comments

Comments
 (0)