11package uk .nhs .adaptors .gp2gp .ehr .mapper ;
22
3- import java .math .BigDecimal ;
4-
5- import org .apache .commons .lang3 .StringUtils ;
63import org .hl7 .fhir .dstu3 .model .BooleanType ;
74import org .hl7 .fhir .dstu3 .model .Extension ;
85import org .hl7 .fhir .dstu3 .model .Quantity ;
96
7+ import static org .hl7 .fhir .dstu3 .model .Quantity .QuantityComparator .GREATER_OR_EQUAL ;
8+ import static org .hl7 .fhir .dstu3 .model .Quantity .QuantityComparator .LESS_OR_EQUAL ;
9+ import static org .hl7 .fhir .dstu3 .model .Quantity .QuantityComparator .LESS_THAN ;
10+
1011public final class ObservationValueQuantityMapper {
1112
12- private static final String UNITS_OF_MEASURE_SYSTEM = "http://unitsofmeasure.org" ;
13- private static final String UNCERTAINTY_EXTENSION = "https://fhir.hl7.org.uk/STU3/StructureDefinition/Extension-CareConnect-ValueApproximation-1" ;
13+ private static final String UNITS_OF_MEASURE_SYSTEM =
14+ "http://unitsofmeasure.org" ;
15+ private static final String UNCERTAINTY_EXTENSION =
16+ "https://fhir.hl7.org.uk/STU3/StructureDefinition/Extension-CareConnect-ValueApproximation-1" ;
17+ private static final String UNCERTAINTY_CODE = """
18+ <uncertaintyCode code="U" codeSystem="2.16.840.1.113883.5.1053" displayName="Recorded as uncertain" />
19+ """ ;
1420
1521 public static final String PQ_WITH_UOM_SYSTEM_AND_CODE_TEMPLATE = """
1622 <value xsi:type="PQ" value="%s" unit="%s" />""" ;
@@ -22,41 +28,44 @@ public final class ObservationValueQuantityMapper {
2228 <value xsi:type="PQ" value="%s" unit="1">%n\
2329 <translation value="%s" code="%s" codeSystem="%s" />%n\
2430 </value>""" ;
25- public static final String PQ_WITH_ANY_SYSTEM_AND_UNIT_TEMPLATE = """
31+ public static final String PQ_WITH_ANY_OR_NO_SYSTEM_AND_UNIT_TEMPLATE = """
2632 <value xsi:type="PQ" value="%s" unit="1">%n\
2733 <translation value="%s">%n\
2834 <originalText>%s</originalText>%n\
2935 </translation>%n\
3036 </value>""" ;
3137 private static final String PQ_WITH_ONLY_VALUE_TEMPLATE =
3238 "<value xsi:type=\" PQ\" value=\" %s\" unit=\" 1\" />" ;
33- private static final String IVL_PQ_ELEMENT =
34- "<value xsi:type=\" IVL_PQ\" >" ;
35- private static final String LESS_COMPARATOR_VALUE_TEMPLATE = IVL_PQ_ELEMENT
36- + "<high value=\" %s\" unit=\" %s\" inclusive=\" false\" /></value>" ;
37- private static final String LESS_OR_EQUAL_COMPARATOR_VALUE_TEMPLATE = IVL_PQ_ELEMENT
38- + "<high value=\" %s\" unit=\" %s\" inclusive=\" true\" /></value>" ;
39- private static final String GREATER_COMPARATOR_VALUE_TEMPLATE = IVL_PQ_ELEMENT + "<low value=\" %s\" "
40- + "unit=\" %s\" inclusive=\" false\" /></value>" ;
41- private static final String GREATER_OR_EQUAL_COMPARATOR_VALUE_TEMPLATE = "<value xsi:type=\" IVL_PQ\" ><low value=\" %s\" "
42- + "unit=\" %s\" inclusive=\" true\" /></value>" ;
43- private static final String LESS_COMPARATOR_NO_SYSTEM_VALUE_TEMPLATE = IVL_PQ_ELEMENT
44- + "<high value=\" %s\" unit=\" 1\" inclusive=\" false\" ><translation value=\" %s\" >"
45- + "%s</translation></high></value>" ;
46- private static final String LESS_OR_EQUAL_COMPARATOR_NO_SYSTEM_VALUE_TEMPLATE = "<value xsi:type=\" IVL_PQ\" ><high "
47- + "value=\" %s\" unit=\" 1\" inclusive=\" true\" ><translation value=\" %s\" >"
48- + "%s</translation></high></value>" ;
49- private static final String GREATER_COMPARATOR_NO_SYSTEM_VALUE_TEMPLATE = IVL_PQ_ELEMENT
50- + "<low value=\" %s\" unit=\" 1\" inclusive=\" false\" ><translation value=\" %s\" >%s"
51- + "</translation></low></value>" ;
52- private static final String GREATER_OR_EQUAL_COMPARATOR_NO_SYSTEM_VALUE_TEMPLATE = IVL_PQ_ELEMENT
53- + "<low value=\" %s\" unit=\" 1\" inclusive=\" true\" ><translation value=\" %s\" >"
54- + "%s</translation></low></value>" ;
55- private static final String UNCERTAINTY_CODE = """
56- <uncertaintyCode code="U" codeSystem="2.16.840.1.113883.5.1053" displayName="Recorded as uncertain"/>
57- """ ;
58- private static final String QUANTITY_UNIT = "<originalText>%s</originalText>" ;
5939
40+ private static final String IVL_PQ_WITH_UOM_SYSTEM_AND_CODE_TEMPLATE = """
41+ <value xsi:type="IVL_PQ">%n\
42+ <%s value="%s" unit="%s" inclusive="%s" />%n\
43+ </value>""" ;
44+
45+ public static final String IVL_PQ_WITH_NON_UOM_SYSTEM_AND_CODE_AND_UNIT_TEMPLATE = """
46+ <value xsi:type="IVL_PQ">%n\
47+ <%s value="%s" unit="%s" inclusive="%s">%n\
48+ <translation value="%s" code="%s" codeSystem="%s" displayName="%s" />%n\
49+ </%s>%n\
50+ </value>""" ;
51+ public static final String IVL_PQ_WITH_NON_UOM_SYSTEM_AND_CODE_TEMPLATE = """
52+ <value xsi:type="IVL_PQ">%n\
53+ <%s value="%s" unit="%s" inclusive="%s">%n\
54+ <translation value="%s" code="%s" codeSystem="%s" />%n\
55+ </%s>%n\
56+ </value>""" ;
57+ public static final String IVL_PQ_WITH_ANY_OR_NO_SYSTEM_AND_UNIT_TEMPLATE = """
58+ <value xsi:type="IVL_PQ">%n\
59+ <%s value="%s" unit="1" inclusive="%s">%n\
60+ <translation value="%s">%n\
61+ <originalText>%s</originalText>%n\
62+ </translation>%n\
63+ </%s>%n\
64+ </value>""" ;
65+ public static final String IVL_PQ_WITH_ONLY_VALUE_TEMPLATE = """
66+ <value xsi:type="IVL_PQ">%n\
67+ <%s value="%s" unit="1" inclusive="%s" />%n\
68+ </value>""" ;
6069
6170 private ObservationValueQuantityMapper () {
6271 }
@@ -68,18 +77,16 @@ public static String processQuantity(Quantity valueQuantity) {
6877 stringBuilder .append (UNCERTAINTY_CODE );
6978 }
7079
71- if (!valueQuantity .hasComparator ()) {
72- var result = prepareQuantityValueWithoutComparator (valueQuantity );
73- stringBuilder .append (result );
74- } else {
75- var result = prepareQuantityValueAccordingToComparator (valueQuantity );
76- stringBuilder .append (result );
77- }
80+ var quantityXml = valueQuantity .hasComparator ()
81+ ? getPhysicalQuantityIntervalXml (valueQuantity )
82+ : getPhysicalQuantityXml (valueQuantity );
7883
79- return stringBuilder .toString ();
84+ return stringBuilder
85+ .append (quantityXml )
86+ .toString ();
8087 }
8188
82- private static String prepareQuantityValueWithoutComparator (Quantity valueQuantity ) {
89+ private static String getPhysicalQuantityXml (Quantity valueQuantity ) {
8390 if (UNITS_OF_MEASURE_SYSTEM .equals (valueQuantity .getSystem ()) && valueQuantity .hasCode ()) {
8491 return PQ_WITH_UOM_SYSTEM_AND_CODE_TEMPLATE .formatted (
8592 valueQuantity .getValue (),
@@ -103,8 +110,8 @@ private static String prepareQuantityValueWithoutComparator(Quantity valueQuanti
103110 valueQuantity .getSystem ()
104111 );
105112 }
106- if (valueQuantity .hasSystem () && valueQuantity . hasUnit ()) {
107- return PQ_WITH_ANY_SYSTEM_AND_UNIT_TEMPLATE .formatted (
113+ if (valueQuantity .hasUnit ()) {
114+ return PQ_WITH_ANY_OR_NO_SYSTEM_AND_UNIT_TEMPLATE .formatted (
108115 valueQuantity .getValue (),
109116 valueQuantity .getValue (),
110117 valueQuantity .getUnit ()
@@ -114,46 +121,66 @@ private static String prepareQuantityValueWithoutComparator(Quantity valueQuanti
114121 return PQ_WITH_ONLY_VALUE_TEMPLATE .formatted (valueQuantity .getValue ());
115122 }
116123
117- private static String prepareUnit (Quantity valueQuantity ) {
118- return valueQuantity .hasUnit () ? String .format (QUANTITY_UNIT , valueQuantity .getUnit ()) : StringUtils .EMPTY ;
119- }
120-
121- private static String prepareQuantityValueAccordingToComparator (Quantity valueQuantity ) {
122- if (valueQuantity .getComparator () == Quantity .QuantityComparator .LESS_THAN ) {
123- return prepareQuantityValueByComparator (valueQuantity ,
124- LESS_COMPARATOR_VALUE_TEMPLATE ,
125- LESS_COMPARATOR_NO_SYSTEM_VALUE_TEMPLATE );
126- } else if (valueQuantity .getComparator () == Quantity .QuantityComparator .LESS_OR_EQUAL ) {
127- return prepareQuantityValueByComparator (valueQuantity ,
128- LESS_OR_EQUAL_COMPARATOR_VALUE_TEMPLATE ,
129- LESS_OR_EQUAL_COMPARATOR_NO_SYSTEM_VALUE_TEMPLATE );
130- } else if (valueQuantity .getComparator () == Quantity .QuantityComparator .GREATER_THAN ) {
131- return prepareQuantityValueByComparator (valueQuantity ,
132- GREATER_COMPARATOR_VALUE_TEMPLATE ,
133- GREATER_COMPARATOR_NO_SYSTEM_VALUE_TEMPLATE );
134- } else if (valueQuantity .getComparator () == Quantity .QuantityComparator .GREATER_OR_EQUAL ) {
135- return prepareQuantityValueByComparator (valueQuantity ,
136- GREATER_OR_EQUAL_COMPARATOR_VALUE_TEMPLATE ,
137- GREATER_OR_EQUAL_COMPARATOR_NO_SYSTEM_VALUE_TEMPLATE );
138- }
139-
140- return StringUtils .EMPTY ;
141- }
142-
143- private static String prepareQuantityValueByComparator (Quantity valueQuantity , String systemTemplate , String nonSystemTemplate ) {
124+ private static String getPhysicalQuantityIntervalXml (Quantity valueQuantity ) {
144125 if (valueQuantity .hasSystem () && valueQuantity .getSystem ().equals (UNITS_OF_MEASURE_SYSTEM )) {
145- return formatSystemTemplate (systemTemplate , valueQuantity .getValue (), valueQuantity .getCode ());
126+ return IVL_PQ_WITH_UOM_SYSTEM_AND_CODE_TEMPLATE .formatted (
127+ getHighOrLow (valueQuantity ),
128+ valueQuantity .getValue (),
129+ valueQuantity .getCode (),
130+ isInclusive (valueQuantity )
131+ );
132+ }
133+ if (valueQuantity .hasSystem () && valueQuantity .hasCode () && valueQuantity .hasUnit ()) {
134+ return IVL_PQ_WITH_NON_UOM_SYSTEM_AND_CODE_AND_UNIT_TEMPLATE .formatted (
135+ getHighOrLow (valueQuantity ),
136+ valueQuantity .getValue (),
137+ valueQuantity .getCode (),
138+ isInclusive (valueQuantity ),
139+ valueQuantity .getValue (),
140+ valueQuantity .getCode (),
141+ valueQuantity .getSystem (),
142+ valueQuantity .getUnit (),
143+ getHighOrLow (valueQuantity )
144+ );
145+ }
146+ if (valueQuantity .hasSystem () && valueQuantity .hasCode ()) {
147+ return IVL_PQ_WITH_NON_UOM_SYSTEM_AND_CODE_TEMPLATE .formatted (
148+ getHighOrLow (valueQuantity ),
149+ valueQuantity .getValue (),
150+ valueQuantity .getCode (),
151+ isInclusive (valueQuantity ),
152+ valueQuantity .getValue (),
153+ valueQuantity .getCode (),
154+ valueQuantity .getSystem (),
155+ getHighOrLow (valueQuantity )
156+ );
157+ }
158+ if (valueQuantity .hasUnit ()) {
159+ return IVL_PQ_WITH_ANY_OR_NO_SYSTEM_AND_UNIT_TEMPLATE .formatted (
160+ getHighOrLow (valueQuantity ),
161+ valueQuantity .getValue (),
162+ isInclusive (valueQuantity ),
163+ valueQuantity .getValue (),
164+ valueQuantity .getUnit (),
165+ getHighOrLow (valueQuantity )
166+ );
146167 }
147168
148- return formatNoSystemTemplate (nonSystemTemplate , valueQuantity .getValue (), prepareUnit (valueQuantity ));
169+ return IVL_PQ_WITH_ONLY_VALUE_TEMPLATE .formatted (
170+ getHighOrLow (valueQuantity ),
171+ valueQuantity .getValue (),
172+ isInclusive (valueQuantity )
173+ );
149174 }
150175
151- private static String formatSystemTemplate ( String template , BigDecimal value , String code ) {
152- return String . format ( template , value , code ) ;
176+ private static boolean isInclusive ( Quantity valueQuantity ) {
177+ return valueQuantity . getComparator () == GREATER_OR_EQUAL || valueQuantity . getComparator () == LESS_OR_EQUAL ;
153178 }
154179
155- private static String formatNoSystemTemplate (String template , BigDecimal value , String unit ) {
156- return String .format (template , value , value , unit );
180+ private static String getHighOrLow (Quantity valueQuantity ) {
181+ return valueQuantity .getComparator () == LESS_THAN || valueQuantity .getComparator () == LESS_OR_EQUAL
182+ ? "high"
183+ : "low" ;
157184 }
158185
159186 private static boolean isUncertaintyCodePresent (Quantity valueQuantity ) {
@@ -164,7 +191,6 @@ private static boolean isUncertaintyCodePresent(Quantity valueQuantity) {
164191 }
165192 }
166193 }
167-
168194 return false ;
169195 }
170196
0 commit comments