Skip to content

Commit 5d16398

Browse files
authored
fix: Validation composition errors (#99)
* first pass, create required composition sections if missing * clean up * update empty div narrative to remove non-whitespace error, update num validation errors * fix plan of treatment missing entries, test data had incorrect plan of treatment id, update num validation errors * update double RR section, only add missing sections if there are any * update eve everywoman test data, removes rr from eicr section to reflect post processing state pre-fhir conversion * update snapshot tests, update num validation errors expected * update fhir converter api snapshot tests * add unit tests, rm comments * Update num validation errors
1 parent b6ca021 commit 5d16398

File tree

16 files changed

+373
-275
lines changed

16 files changed

+373
-275
lines changed

data/SampleData/eCR/CDAR2_IG_PHCASERPT_R2_D2_SAMPLE.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,9 @@
336336
<component>
337337
<section>
338338
<!-- [C-CDA R1.1] Plan of Care Section -->
339-
<templateId root="2.16.840.1.113883.10.20.22.2.22.10" />
339+
<templateId root="2.16.840.1.113883.10.20.22.2.10" />
340340
<!-- [C-CDA R2.0] Plan of Treatment Section (V2) -->
341-
<templateId root="2.16.840.1.113883.10.20.22.2.22.10" extension="2014-06-09" />
341+
<templateId root="2.16.840.1.113883.10.20.22.2.10" extension="2014-06-09" />
342342
<code code="18776-5" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" displayName="Plan of Treatment" />
343343
<title>Plan of Treatment</title>
344344
<text>

data/SampleData/eCR/eCR_EveEverywoman.xml

Lines changed: 0 additions & 231 deletions
Large diffs are not rendered by default.

data/SampleData/eCR/eCR_full.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,8 @@
828828
<!--******************************************************** Plan of Care/Treatment Section ********************************************************-->
829829
<section>
830830
<!--[C-CDA R1.1] Plan of Care Section new-->
831-
<templateId root="2.16.840.1.113883.10.20.22.2.22.1" />
832-
<templateId extension="2014-06-09" root="2.16.840.1.113883.10.20.22.2.22.1" />
831+
<templateId root="2.16.840.1.113883.10.20.22.2.10" />
832+
<templateId extension="2014-06-09" root="2.16.840.1.113883.10.20.22.2.10" />
833833
<code code="18776-5" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC"
834834
displayName="Plan of Treatment" />
835835
<title>Plan of Treatment</title>

data/Templates/eCR/Resource/_Composition.liquid

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,15 @@
5757
],
5858
"section":
5959
[
60+
{% assign templatesInComp = "" %}
6061
{% assign components = composition.component.structuredBody.component | to_array -%}
6162
{% for component in components -%}
6263
{
6364
{% if component.section -%}
65+
{% assign templateIds = component.section.templateId | to_array %}
66+
{% for templateId in templateIds -%}
67+
{% assign templatesInComp = templatesInComp | append: templateId.root | append: "|" %}
68+
{% endfor %}
6469
{% if component.section.id.root -%}
6570
"id": "{{ component.section.id.root }}",
6671
{% else -%}
@@ -244,6 +249,10 @@
244249
{% endif -%}
245250
},
246251
{% endfor -%}
252+
{% assign templatesInComp = templatesInComp | split: "|" | uniq | join: "|" %}
253+
{% include 'Utils/AddMissingRequiredSections' | templatesInComp: templatesInComp %}
254+
255+
{% comment %} Reportability Response Information Section (from RR) {% endcomment %}
247256
{
248257
{% if composition.section.code.code and composition.section.code.code == "88085-6" -%}
249258
{% assign sectionId = composition.section | to_json_string | generate_uuid -%}
@@ -255,7 +264,6 @@
255264
},
256265
"extension":
257266
[
258-
259267
{
260268
"url": "http://hl7.org/fhir/us/ecr/StructureDefinition/eicr-initiation-type-extension",
261269
"valueCodeableConcept":
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{% comment %} Checks and adds missing required sections in the Composition {% endcomment %}
2+
{% comment %} See https://hl7.org/fhir/us/ecr/2.1.2/StructureDefinition-eicr-composition.html for list of required Composition sections {% endcomment %}
3+
{% comment %} For template OIDs, see HL7 CDA® R2 Implementation Guide: Public Health Case Report – the Electronic Initial Case Report (eICR) Release 2, STU Release 3.1 - US Realm {% endcomment %}
4+
5+
{% assign requiredSections = "2.16.840.1.113883.10.20.22.2.12|1.3.6.1.4.1.19376.1.5.3.1.1.13.2.1|1.3.6.1.4.1.19376.1.5.3.1.3.4|2.16.840.1.113883.10.20.22.2.5.1|2.16.840.1.113883.10.20.22.2.38|2.16.840.1.113883.10.20.22.2.3.1|2.16.840.1.113883.10.20.22.2.17" | split: "|" %}
6+
{% assign missingSections = "" %}
7+
8+
{% for req in requiredSections %}
9+
{% unless templatesInComp contains req %}
10+
{% assign missingSectionIds = missingSections | append: req | append: "|" %}
11+
{% endunless %}
12+
{% endfor %}
13+
14+
{% if missingSectionIds %}
15+
{% assign missingSectionIds = missingSectionIds | split: "|" %}
16+
{% for missingSectionId in missingSectionIds %}
17+
{
18+
"code": {
19+
"coding": [
20+
{
21+
"system": "http://loinc.org",
22+
{%- include 'ValueSet/CompositionSectionCode' id: missingSectionId -%}
23+
}
24+
]
25+
},
26+
"text": {
27+
"status": "empty",
28+
"div": "{{ "No Information Available" | to_xhtml | clean_string_from_tabs | escape_special_chars }}",
29+
}
30+
},
31+
{% endfor %}
32+
{% endif %}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{%- comment -%} See https://hl7.org/fhir/us/ecr/2.1.2/StructureDefinition-eicr-composition.html for finding the corresponding LOINC code for a Composition section {%- endcomment -%}
2+
3+
{%- assign code = id | default: "" -%}
4+
{%- assign display = "" -%}
5+
{%- case id -%}
6+
{%- when "2.16.840.1.113883.10.20.22.2.12" -%} {% comment %} Reason for Visit {% endcomment %}
7+
"code": "29299-5",
8+
"display": "Reason for visit Narrative",
9+
{%- when "1.3.6.1.4.1.19376.1.5.3.1.1.13.2.1" -%} {% comment %} Chief Complaint {% endcomment %}
10+
"code": "10154-3",
11+
"display": "Chief complaint Narrative - Reported",
12+
{%- when "1.3.6.1.4.1.19376.1.5.3.1.3.4" -%} {% comment %} History of Present Illness {% endcomment %}
13+
"code": "10164-2",
14+
"display": "History of Present illness Narrative",
15+
{%- when "2.16.840.1.113883.10.20.22.2.5.1" -%} {% comment %} Problem Section - entries required {% endcomment %}
16+
"code": "11450-4",
17+
"display": "Problem list - Reported",
18+
{%- when "2.16.840.1.113883.10.20.22.2.38" -%} {% comment %} Medications Administered {% endcomment %}
19+
"code": "29549-3",
20+
"display": "Medication administered Narrative",
21+
{%- when "2.16.840.1.113883.10.20.22.2.3.1" -%} {% comment %} Results Section - entries required {% endcomment %}
22+
"code": "30954-2",
23+
"display": "Relevant diagnostic tests/laboratory data note",
24+
{%- when "2.16.840.1.113883.10.20.22.2.17" -%} {% comment %} Social History {% endcomment %}
25+
"code": "29762-2",
26+
"display": "Social history note",
27+
{%- endcase -%}

src/Dibbs.FhirConverterApi.FunctionalTests/__snapshots__/FhirConverterApiFunctionalTests.ConvertToFhir_ReturnsSuccess_WhenValidEicrWithRrProvided.snap

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,21 @@
249249
},
250250
"mode": "snapshot"
251251
},
252+
{
253+
"code": {
254+
"coding": [
255+
{
256+
"system": "http://loinc.org",
257+
"code": "10154-3",
258+
"display": "Chief complaint Narrative - Reported"
259+
}
260+
]
261+
},
262+
"text": {
263+
"status": "empty",
264+
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">No Information Available</div>"
265+
}
266+
},
252267
{
253268
"id": "d62f4d09-f06d-5033-f372-01683abba2c8",
254269
"title": "Reportability Response Information Section",

src/Dibbs.FhirConverterApi.FunctionalTests/__snapshots__/FhirConverterApiFunctionalTests.ConvertToFhir_ReturnsSuccess_WhenValidEicrWithoutRrProvided.snap

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,21 @@
248248
]
249249
},
250250
"mode": "snapshot"
251+
},
252+
{
253+
"code": {
254+
"coding": [
255+
{
256+
"system": "http://loinc.org",
257+
"code": "10154-3",
258+
"display": "Chief complaint Narrative - Reported"
259+
}
260+
]
261+
},
262+
"text": {
263+
"status": "empty",
264+
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">No Information Available</div>"
265+
}
251266
}
252267
],
253268
"subject": {

src/Dibbs.FhirConverterApi/Processors/EcrProcessor.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,6 @@ public static XDocument MergeEicrAndRR(XDocument ecrXDocument, string rrData)
3232

3333
try
3434
{
35-
// Check for eICR Processing Status entry (required & only available in RR)
36-
if (ecrXDocument.XPathSelectElement("//*[@root=\"2.16.840.1.113883.10.20.15.2.3.29\"]") is not null)
37-
{
38-
Console.WriteLine("This eCR has already been merged with RR data.");
39-
return ecrXDocument;
40-
}
41-
4235
// If eICR >=R3, remove (optional) RR section that came from eICR
4336
// This is duplicate/incomplete info from RR
4437
var ecrVersion = ecrXDocument.XPathEvaluate("string(//*[@root=\"2.16.840.1.113883.10.20.15.2\"]/@extension)")?.ToString();
@@ -53,6 +46,13 @@ public static XDocument MergeEicrAndRR(XDocument ecrXDocument, string rrData)
5346
rrFromEicr?.Remove();
5447
}
5548

49+
// Check for eICR Processing Status entry (required & only available in RR)
50+
if (ecrXDocument.XPathSelectElement("//*[@root=\"2.16.840.1.113883.10.20.15.2.3.29\"]") is not null)
51+
{
52+
Console.WriteLine("This eCR has already been merged with RR data.");
53+
return ecrXDocument;
54+
}
55+
5656
// Create the tags for elements we'll be looking for
5757
string[] rrTags =
5858
[

src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/BaseConvertDataFunctionalTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,11 @@ public static IEnumerable<object[]> GetDataForEcr()
239239
// 4. whether the file should fail at parsing or validation when testing if valid (if it is fully valid, "validation" is what should be there)
240240
// 5. The number of expected failures at the step in (4) for the numFailures parameter
241241
// ]
242-
new[] { @"EICR", @"eCR_full.xml", @"eCR_full-expected.json", "validation", "6" },
242+
new[] { @"EICR", @"eCR_full.xml", @"eCR_full-expected.json", "validation", "4" },
243243
new[] { @"EICR", @"eCR_RR_combined_3_1.xml", @"eCR_RR_combined_3_1-expected.json", "validation", "10" },
244-
new[] { @"EICR", @"eCR_EveEverywoman.xml", @"eCR_EveEverywoman-expected.json", "validation", "34" },
245-
new[] { @"EICR", @"eicr04152020.xml", @"eicr04152020-expected.json", "validation", "16" },
246-
new[] { @"EICR", @"CDAR2_IG_PHCASERPT_R2_D2_SAMPLE.xml", @"CDAR2_IG_PHCASERPT_R2_D2_SAMPLE-expected.json", "validation", "18" },
244+
new[] { @"EICR", @"eCR_EveEverywoman.xml", @"eCR_EveEverywoman-expected.json", "validation", "32" },
245+
new[] { @"EICR", @"eicr04152020.xml", @"eicr04152020-expected.json", "validation", "15" },
246+
new[] { @"EICR", @"CDAR2_IG_PHCASERPT_R2_D2_SAMPLE.xml", @"CDAR2_IG_PHCASERPT_R2_D2_SAMPLE-expected.json", "validation", "15" },
247247
};
248248
return data.Select(item => new[]
249249
{

0 commit comments

Comments
 (0)