Skip to content

Commit 3e616a1

Browse files
feat: convert admission medications (#66)
1 parent bf17c1a commit 3e616a1

File tree

9 files changed

+171
-3
lines changed

9 files changed

+171
-3
lines changed

data/Templates/eCR/DataType/_CodeableConcept.liquid

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
{%- endif -%}
2121
{% endfor -%}
2222
{%- if minCardinality > 0 and bindingStrength != "required" and num_concepts == 0 -%}
23-
{%- if org_text == empty or org_test == nil -%}
23+
{%- if org_text == empty or org_text == nil -%}
2424
{% comment %} We only need to use a data-absent-reason coding if there is no coding, it has to exist (has a minimum cardinality > 0), and it has a binding strenght that allows use to use the data absent coding (anything but "required") {% endcomment %}
2525
{%- assign num_concepts = num_concepts | plus: 1 -%}
2626
{

data/Templates/eCR/EICR.liquid

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
{% include 'Section/SocialHistory' -%}
3434
{% include 'Section/VitalSign' -%}
3535
{% include 'Section/PlanOfTreatment' -%}
36-
36+
{% include 'Section/AdmissionMedication' -%}
3737
{% include 'Section/Procedure' -%}
3838
{% include 'Section/Immunization' -%}
3939
{% include 'Section/FunctionalStatus' -%}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{ entry.act.entryRelationship | to_array | batch_render: 'Entry/AdmissionMedication/entry_act_entryRelationship', 'relationship' }}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{% assign substanceAdministrationId = relationship.substanceAdministration | to_json_string | generate_uuid -%}
2+
{% include 'Resource/MedicationAdministration' medicationAdministration: relationship.substanceAdministration, ID: substanceAdministrationId -%}
3+
{% assign manufacturedMaterialId = relationship.substanceAdministration.consumable.manufacturedProduct.manufacturedMaterial | to_json_string | generate_uuid -%}
4+
{% include 'Resource/Medication' medication: relationship.substanceAdministration.consumable.manufacturedProduct.manufacturedMaterial, ID: manufacturedMaterialId -%}
5+
{% if relationship.substanceAdministration.author -%}
6+
{% evaluate practitionerAuthorId using 'Utils/GenerateId' obj: relationship.substanceAdministration.author.assignedAuthor -%}
7+
{% include 'Resource/Practitioner', practitioner: relationship.substanceAdministration.author.assignedAuthor, ID: practitionerAuthorId -%}
8+
{% assign fullPractitionerAuthorId = practitionerAuthorId | prepend: 'Practitioner/' -%}
9+
{% include 'Reference/MedicationAdministration/Performer_Actor' ID: substanceAdministrationId, REF: fullPractitionerAuthorId -%}
10+
{% endif -%}
11+
{% if relationship.substanceAdministration.author -%}
12+
{% evaluate practitionerAuthorId using 'Utils/GenerateId' obj: relationship.substanceAdministration.author.assignedAuthor -%}
13+
{% include 'Resource/Practitioner', practitioner: relationship.substanceAdministration.author.assignedAuthor, ID: practitionerAuthorId -%}
14+
{% assign fullPractitionerAuthorId = practitionerAuthorId | prepend: 'Practitioner/' -%}
15+
{% include 'Reference/MedicationAdministration/Performer_Actor' ID: substanceAdministrationId, REF: fullPractitionerAuthorId -%}
16+
{% endif -%}
17+
{% include 'Reference/MedicationAdministration/Subject' ID: substanceAdministrationId, REF: fullPatientId -%}
18+
{% assign fullManufacturedMaterialId = manufacturedMaterialId | prepend: 'Medication/' -%}
19+
{% include 'Reference/MedicationAdministration/MedicationReference' ID: substanceAdministrationId, REF: fullManufacturedMaterialId -%}
20+
21+
22+
23+
{{ relationship.substanceAdministration.entryRelationship | to_array | batch_render: 'Entry/AdmissionMedication/entry_act_entryRelationship_substanceAdministration_entryRelationship', 'entryRelationship' }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{% assign observationId = entryRelationship.observation | to_json_string | generate_uuid -%}
2+
{% assign templateIdString = entryRelationship.observation.templateId | to_json_string -%}
3+
4+
{% if templateIdString contains '"2.16.840.1.113883.10.20.22.4.19"' -%}
5+
{% include 'Resource/Condition' conditionEntry: entryRelationship.observation, ID: observationId -%}
6+
{% assign fullObservationId = observationId | prepend: 'Condition/' -%}
7+
{% include 'Reference/MedicationAdministration/ReasonReference' ID: substanceAdministrationId, REF: fullObservationId-%}
8+
{% endif -%}
9+
10+
{% if templateIdString contains '"2.16.840.1.113883.10.20.22.4.9"' -%}
11+
{% include 'Resource/AdverseEvent' adverseEventEntry: entryRelationship.observation, ID: observationId, REF: fullMedicationAdministrationId -%}
12+
{% include 'Reference/AdverseEvent/Subject' ID: observationId, REF: fullPatientId -%}
13+
{% assign fullAdverseEventId = observationId | prepend: 'AdverseEvent/' -%}
14+
{% include 'Reference/MedicationAdministration/SupportingInformation' ID: substanceAdministrationId, REF: fullAdverseEventId -%}
15+
{% endif -%}
16+
17+
{% assign templateIdString = entryRelationship.supply.templateId | to_json_string -%}
18+
{% if templateIdString contains '"2.16.840.1.113883.10.20.22.4.17"' -%}
19+
{% if entryRelationship.supply.author.assignedAuthor -%}
20+
{% evaluate practitionerSupAuthId using 'Utils/GenerateId' obj: entryRelationship.supply.author.assignedAuthor -%}
21+
{% include 'Resource/Practitioner', practitioner: entryRelationship.supply.author.assignedAuthor, ID: practitionerSupAuthId -%}
22+
{% assign fullPractitionerSupAuthId = practitionerSupAuthId | prepend: 'Practitioner/' -%}
23+
{% include 'Reference/MedicationAdministration/Performer_Actor' ID: substanceAdministrationId, REF: fullPractitionerSupAuthId -%}
24+
{% endif -%}
25+
{% endif -%}
26+
27+
{% if templateIdString contains '"2.16.840.1.113883.10.20.22.4.18"' -%}
28+
{% assign supplyId = entryRelationship.supply | to_json_string | generate_uuid -%}
29+
{% include 'Resource/MedicationDispense' medicationDispense: entryRelationship.supply, ID: supplyId -%}
30+
{% evaluate practitionerSupPerfId using 'Utils/GenerateId' obj: entryRelationship.supply.performer.assignedEntity -%}
31+
{% include 'Resource/Practitioner' practitioner: entryRelationship.supply.performer.assignedEntity, ID: practitionerSupPerfId -%}
32+
{% assign fullPractitionerSupPerfId = practitionerSupPerfId | prepend: 'Practitioner/' -%}
33+
{% include 'Reference/MedicationDispense/Performer_Actor' ID: supplyId, REF: fullPractitionerSupPerfId -%}
34+
{% include 'Reference/MedicationDispense/MedicationReference' ID: supplyId, REF: fullManufacturedMaterialId -%}
35+
{% include 'Reference/MedicationDispense/Subject' ID: supplyId, REF: fullPatientId -%}
36+
{% assign fullMedicationDispenseId = supplyId | prepend: 'MedicationDispense/' -%}
37+
{% include 'Reference/MedicationAdministration/PartOf' ID: substanceAdministrationId, REF: fullMedicationDispenseId -%}
38+
{% endif -%}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"fullUrl":"urn:uuid:{{ID}}",
3+
"resource":{
4+
"resourceType": "AdverseEvent",
5+
"id":"{{ID}}",
6+
"identifier":
7+
[
8+
{% assign ids = adverseEventEntry.id | to_array -%}
9+
{% for i in ids -%}
10+
{% include 'DataType/Identifier' Identifier: i -%}
11+
{% endfor -%}
12+
],
13+
"status": "{{ adverseEventEntry.statusCode.code }}",
14+
"actuality": "actual",
15+
{% if adverseEventEntry.effectiveTime.low.value -%}
16+
"date": "{{ adverseEventEntry.effectiveTime.low.value | format_as_date_time }}",
17+
{% endif -%}
18+
{% if adverseEventEntry.effectiveTime.high.value -%}
19+
"extension": [
20+
{
21+
"url": "http://hl7.org/fhir/uv/ae-research-backport-ig/StructureDefinition/resolve-date",
22+
"valueDateTime": "{{ adverseEventEntry.effectiveTime.high.value | format_as_date_time }}"
23+
}
24+
],
25+
{% endif -%}
26+
27+
"event": { {% include 'DataType/CodeableConcept' CodeableConcept: adverseEventEntry.value -%} },
28+
"suspectEntity": [
29+
{ "instance": { "reference": "{{ REF }}" } }
30+
]
31+
},
32+
},

data/Templates/eCR/Resource/_Composition.liquid

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
{% endif -%}
127127
"entry":
128128
[
129-
{% if component.section.templateId.root == "2.16.840.1.113883.10.20.22.2.38" or component.section.templateId[0].root == "2.16.840.1.113883.10.20.22.2.38" %}
129+
{% if component.section.templateId.root == "2.16.840.1.113883.10.20.22.2.38" or component.section.templateId[0].root == "2.16.840.1.113883.10.20.22.2.38" or component.section.templateId[0].root == "2.16.840.1.113883.10.20.22.2.44" %}
130130
{% assign entries = component.section.entry | to_array -%}
131131
{% for entry in entries -%}
132132
{% assign medicationAdministrationId = entry.substanceAdministration | to_json_string | generate_uuid -%}
@@ -136,6 +136,16 @@
136136
},
137137
{% endfor %}
138138
{% endif %}
139+
{% if component.section.templateId.root == "2.16.840.1.113883.10.20.22.2.44" or component.section.templateId[0].root == "2.16.840.1.113883.10.20.22.2.44" %}
140+
{% assign entries = component.section.entry | to_array -%}
141+
{% for entry in entries -%}
142+
{% assign medicationAdministrationId = entry.act.entryRelationship.substanceAdministration | to_json_string | generate_uuid -%}
143+
{% assign fullMedicationAdministrationId = medicationAdministrationId | prepend: 'MedicationAdministration/' -%}
144+
{
145+
"reference": "{{ fullMedicationAdministrationId }}",
146+
},
147+
{% endfor %}
148+
{% endif %}
139149
{% if component.section.templateId.root == "2.16.840.1.113883.10.20.22.2.2.1" %}
140150
{% assign entries = component.section.entry | to_array -%}
141151
{% for entry in entries -%}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{% assign firstSections = msg | get_first_ccda_sections_by_template_id: '2.16.840.1.113883.10.20.22.2.44' -%}
2+
{{ firstSections.2_16_840_1_113883_10_20_22_2_44.entry | to_array | batch_render: 'Entry/AdmissionMedication/entry', 'entry' }}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text;
5+
using System.Linq;
6+
using DotLiquid;
7+
using Hl7.Fhir.Model;
8+
using Xunit;
9+
using Xunit.Abstractions;
10+
using Microsoft.Health.Fhir.Liquid.Converter.Parsers;
11+
12+
13+
namespace Microsoft.Health.Fhir.Liquid.Converter.UnitTests
14+
{
15+
public class AdverseEventTests : BaseECRLiquidTests
16+
{
17+
18+
private static readonly string ECRPath = Path.Join(
19+
TestConstants.ECRTemplateDirectory,
20+
"Resource",
21+
"_AdverseEvent.liquid"
22+
);
23+
24+
[Fact]
25+
public void AdverseEvent_AllFields()
26+
{
27+
// from 3.1 spec
28+
var xmlStr = @"
29+
<observation classCode=""OBS"" moodCode=""EVN"">
30+
<templateId root=""2.16.840.1.113883.10.20.22.4.9"" extension=""2014-06-09"" />
31+
<id root=""4adc1020-7b14-11db-9fe1-0800200c9a64"" />
32+
<code code=""ASSERTION"" codeSystem=""2.16.840.1.113883.5.4"" />
33+
<text>
34+
<reference value=""#reaction1"" />
35+
</text>
36+
<statusCode code=""completed"" />
37+
<effectiveTime>
38+
<low value=""200802260805-0800"" />
39+
<high value=""200802281205-0800"" />
40+
</effectiveTime>
41+
<value type=""CD"" code=""422587007"" codeSystem=""2.16.840.1.113883.6.96"" displayName=""Nausea"" />
42+
</observation>
43+
";
44+
var parsed = new CcdaDataParser().Parse(xmlStr) as Dictionary<string, object>;
45+
46+
var attributes = new Dictionary<string, object>
47+
{
48+
{ "ID", "1234" },
49+
{ "adverseEventEntry", parsed["observation"]},
50+
};
51+
var actualFhir = GetFhirObjectFromTemplate<AdverseEvent>(ECRPath, attributes);
52+
53+
Assert.Equal("AdverseEvent", actualFhir.TypeName);
54+
Assert.Equal("1234" ,actualFhir.Id);
55+
Assert.Equal("2008-02-26T08:05:00-08:00", actualFhir.Date);
56+
Assert.NotNull(actualFhir.Event);
57+
Assert.NotEmpty(actualFhir.Event.Coding);
58+
var coding = actualFhir.Event.Coding.First();
59+
Assert.Equal("Nausea", coding.Display);
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)