-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
323 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
src/main/java/jy95/fhir/r4/dosage/utils/functions/RatioToString.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package jy95.fhir.r4.dosage.utils.functions; | ||
|
||
import jy95.fhir.r4.dosage.utils.config.FDUConfig; | ||
import org.hl7.fhir.r4.model.Quantity; | ||
import org.hl7.fhir.r4.model.Ratio; | ||
|
||
import java.math.BigDecimal; | ||
import java.text.MessageFormat; | ||
import java.util.Map; | ||
import java.util.ResourceBundle; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public final class RatioToString { | ||
public static CompletableFuture<String> convert(ResourceBundle bundle, FDUConfig config, Ratio ratio) { | ||
var linkword = retrieveRatioLinkWord(bundle, config, ratio); | ||
|
||
var numeratorText = ratio.hasNumerator() | ||
? QuantityToString.convert(bundle, config, ratio.getNumerator()) | ||
: CompletableFuture.completedFuture(""); | ||
|
||
var denominatorText = ratio.hasDenominator() | ||
? turnDenominatorToText(bundle, config, ratio) | ||
: CompletableFuture.completedFuture(""); | ||
|
||
return numeratorText.thenCombineAsync(denominatorText, (num, dem) -> Stream | ||
.of(num, linkword, dem) | ||
.filter(s -> !s.isEmpty()) | ||
.collect(Collectors.joining(" ")) | ||
); | ||
} | ||
|
||
private static String retrieveRatioLinkWord(ResourceBundle bundle, FDUConfig config, Ratio ratio) { | ||
var hasNumerator = ratio.hasNumerator(); | ||
var hasDenominator = ratio.hasDenominator(); | ||
var hasNumeratorUnit = hasNumerator && hasUnit(ratio.getNumerator()); | ||
var hasBothElements = hasNumerator && hasDenominator; | ||
var hasDenominatorUnit = hasDenominator && hasUnit(ratio.getDenominator()); | ||
var hasUnitRatio = hasNumeratorUnit || hasDenominatorUnit; | ||
var denominatorValue = hasDenominator ? ratio.getDenominator().getValue() : BigDecimal.ONE; | ||
|
||
if (hasUnitRatio && hasBothElements) { | ||
var linkWordMsg = bundle.getString("amount.ratio.denominatorLinkword"); | ||
return new MessageFormat(linkWordMsg, config.getLocale()).format(new Object[]{denominatorValue}); | ||
} | ||
|
||
return hasBothElements ? ":" : ""; | ||
} | ||
|
||
private static CompletableFuture<String> turnDenominatorToText( | ||
ResourceBundle bundle, | ||
FDUConfig config, | ||
Ratio ratio | ||
) { | ||
var denominator = ratio.getDenominator(); | ||
// Where the denominator value is known to be fixed to "1", Quantity should be used instead of Ratio | ||
var denominatorValue = denominator.getValue(); | ||
|
||
// For titers cases (e.g. 1:128) | ||
if (!hasUnit(denominator)) { | ||
return CompletableFuture.completedFuture(denominatorValue.toString()); | ||
} | ||
|
||
// For the per case | ||
if (BigDecimal.ONE.equals(denominatorValue)) { | ||
return config.getFromFHIRQuantityUnitToString().apply(denominator); | ||
} | ||
|
||
return QuantityToString.convert(bundle, config, denominator); | ||
} | ||
|
||
// See if unit (code or text) could be found in quantity | ||
private static boolean hasUnit(Quantity quantity) { | ||
return quantity.hasUnit() || quantity.hasCode(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/main/java/jy95/fhir/r4/dosage/utils/translators/RateRatio.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package jy95.fhir.r4.dosage.utils.translators; | ||
|
||
import com.ibm.icu.text.MessageFormat; | ||
import jy95.fhir.r4.dosage.utils.classes.AbstractTranslator; | ||
import jy95.fhir.r4.dosage.utils.config.FDUConfig; | ||
import jy95.fhir.r4.dosage.utils.functions.RatioToString; | ||
import jy95.fhir.r4.dosage.utils.types.DoseAndRateKey; | ||
import org.hl7.fhir.r4.model.Dosage; | ||
import org.hl7.fhir.r4.model.Ratio; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
|
||
public class RateRatio extends AbstractTranslator { | ||
|
||
public RateRatio(FDUConfig config) { | ||
super(config); | ||
} | ||
|
||
@Override | ||
public CompletableFuture<String> convert(Dosage dosage) { | ||
var bundle = getResources(); | ||
var doseAndRate = dosage.getDoseAndRate(); | ||
var rateRatio = getConfig() | ||
.getSelectDosageAndRateField() | ||
.apply(doseAndRate, DoseAndRateKey.RATE_RATIO); | ||
|
||
return RatioToString | ||
.convert(bundle, getConfig(), (Ratio) rateRatio) | ||
.thenApplyAsync(rateRatioText -> { | ||
var doseRateMsg = bundle.getString("fields.rateRatio"); | ||
return new MessageFormat(doseRateMsg, getConfig().getLocale()).format(new Object[]{rateRatioText}); | ||
}); | ||
} | ||
|
||
@Override | ||
public boolean isPresent(Dosage dosage) { | ||
return dosage.hasDoseAndRate() && dosage | ||
.getDoseAndRate() | ||
.stream() | ||
.anyMatch(Dosage.DosageDoseAndRateComponent::hasRateRatio); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
194 changes: 194 additions & 0 deletions
194
src/test/java/jy95/fhir/r4/dosage/utils/translators/RateRatioTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
package jy95.fhir.r4.dosage.utils.translators; | ||
|
||
import jy95.fhir.r4.dosage.utils.AbstractFhirTest; | ||
import jy95.fhir.r4.dosage.utils.classes.FhirDosageUtils; | ||
import jy95.fhir.r4.dosage.utils.types.DisplayOrder; | ||
import org.hl7.fhir.r4.model.Dosage; | ||
import org.hl7.fhir.r4.model.Quantity; | ||
import org.hl7.fhir.r4.model.Ratio; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
import java.util.List; | ||
import java.util.Locale; | ||
import java.util.concurrent.ExecutionException; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
public class RateRatioTest extends AbstractFhirTest { | ||
|
||
@ParameterizedTest | ||
@MethodSource("localeProvider") | ||
void testNoRateRatio(Locale locale) throws ExecutionException, InterruptedException { | ||
Dosage dosage = new Dosage(); | ||
FhirDosageUtils dosageUtils = DayOfWeekTest.getDosageUtilsInstance(locale, DisplayOrder.RATE_RATIO); | ||
String result = dosageUtils.asHumanReadableText(dosage).get(); | ||
assertEquals("", result); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("localeProvider") | ||
void testEmptyRateRatio(Locale locale) throws ExecutionException, InterruptedException { | ||
Dosage dosage = new Dosage(); | ||
Ratio ratio = new Ratio(); | ||
Dosage.DosageDoseAndRateComponent doseAndRateComponent1 = new Dosage.DosageDoseAndRateComponent(); | ||
doseAndRateComponent1.setRate(ratio); | ||
dosage.setDoseAndRate(List.of(doseAndRateComponent1)); | ||
FhirDosageUtils dosageUtils = DayOfWeekTest.getDosageUtilsInstance(locale, DisplayOrder.RATE_RATIO); | ||
String result = dosageUtils.asHumanReadableText(dosage).get(); | ||
assertEquals("", result); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("localeProvider") | ||
void testOnlyNumerator(Locale locale) throws ExecutionException, InterruptedException { | ||
Dosage dosage = new Dosage(); | ||
Ratio ratio = new Ratio(); | ||
Quantity numerator = new Quantity(10); | ||
numerator.setUnit("ml"); | ||
ratio.setNumerator(numerator); | ||
Dosage.DosageDoseAndRateComponent doseAndRateComponent1 = new Dosage.DosageDoseAndRateComponent(); | ||
doseAndRateComponent1.setRate(ratio); | ||
dosage.setDoseAndRate(List.of(doseAndRateComponent1)); | ||
FhirDosageUtils dosageUtils = DayOfWeekTest.getDosageUtilsInstance(locale, DisplayOrder.RATE_RATIO); | ||
String result = dosageUtils.asHumanReadableText(dosage).get(); | ||
String expected = getExpectedText1(locale); | ||
assertEquals(expected, result); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("localeProvider") | ||
void testOnlyDenominator(Locale locale) throws ExecutionException, InterruptedException { | ||
Dosage dosage = new Dosage(); | ||
Ratio ratio = new Ratio(); | ||
Quantity denominator = new Quantity(10); | ||
denominator.setUnit("ml"); | ||
ratio.setDenominator(denominator); | ||
Dosage.DosageDoseAndRateComponent doseAndRateComponent1 = new Dosage.DosageDoseAndRateComponent(); | ||
doseAndRateComponent1.setRate(ratio); | ||
dosage.setDoseAndRate(List.of(doseAndRateComponent1)); | ||
FhirDosageUtils dosageUtils = DayOfWeekTest.getDosageUtilsInstance(locale, DisplayOrder.RATE_RATIO); | ||
String result = dosageUtils.asHumanReadableText(dosage).get(); | ||
String expected = getExpectedText2(locale); | ||
assertEquals(expected, result); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("localeProvider") | ||
void testNumeratorAndDenominator(Locale locale) throws ExecutionException, InterruptedException { | ||
Dosage dosage = new Dosage(); | ||
Ratio ratio = new Ratio(); | ||
Quantity numerator = new Quantity(10); | ||
numerator.setUnit("mg"); | ||
ratio.setNumerator(numerator); | ||
Quantity denominator = new Quantity(1); | ||
denominator.setUnit("ml"); | ||
ratio.setDenominator(denominator); | ||
Dosage.DosageDoseAndRateComponent doseAndRateComponent1 = new Dosage.DosageDoseAndRateComponent(); | ||
doseAndRateComponent1.setRate(ratio); | ||
dosage.setDoseAndRate(List.of(doseAndRateComponent1)); | ||
FhirDosageUtils dosageUtils = DayOfWeekTest.getDosageUtilsInstance(locale, DisplayOrder.RATE_RATIO); | ||
String result = dosageUtils.asHumanReadableText(dosage).get(); | ||
String expected = getExpectedText3(locale); | ||
assertEquals(expected, result); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("localeProvider") | ||
void testTiterCase(Locale locale) throws ExecutionException, InterruptedException { | ||
Dosage dosage = new Dosage(); | ||
Ratio ratio = new Ratio(); | ||
Quantity numerator = new Quantity(1); | ||
ratio.setNumerator(numerator); | ||
Quantity denominator = new Quantity(128); | ||
ratio.setDenominator(denominator); | ||
Dosage.DosageDoseAndRateComponent doseAndRateComponent1 = new Dosage.DosageDoseAndRateComponent(); | ||
doseAndRateComponent1.setRate(ratio); | ||
dosage.setDoseAndRate(List.of(doseAndRateComponent1)); | ||
FhirDosageUtils dosageUtils = DayOfWeekTest.getDosageUtilsInstance(locale, DisplayOrder.RATE_RATIO); | ||
String result = dosageUtils.asHumanReadableText(dosage).get(); | ||
String expected = getExpectedText4(locale); | ||
assertEquals(expected, result); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("localeProvider") | ||
void testCommon(Locale locale) throws ExecutionException, InterruptedException { | ||
Dosage dosage = new Dosage(); | ||
Ratio ratio = new Ratio(); | ||
Quantity numerator = new Quantity(10); | ||
numerator.setUnit("mg"); | ||
ratio.setNumerator(numerator); | ||
Quantity denominator = new Quantity(2); | ||
denominator.setUnit("ml"); | ||
ratio.setDenominator(denominator); | ||
Dosage.DosageDoseAndRateComponent doseAndRateComponent1 = new Dosage.DosageDoseAndRateComponent(); | ||
doseAndRateComponent1.setRate(ratio); | ||
dosage.setDoseAndRate(List.of(doseAndRateComponent1)); | ||
FhirDosageUtils dosageUtils = DayOfWeekTest.getDosageUtilsInstance(locale, DisplayOrder.RATE_RATIO); | ||
String result = dosageUtils.asHumanReadableText(dosage).get(); | ||
String expected = getExpectedText5(locale); | ||
assertEquals(expected, result); | ||
} | ||
|
||
private String getExpectedText1(Locale locale) { | ||
if (locale.equals(Locale.ENGLISH)) { | ||
return "at a rate of 10 ml"; | ||
} else if (locale.equals(Locale.FRENCH)) { | ||
return "au taux de 10 ml"; | ||
} else if (locale.equals(Locale.GERMAN)) { | ||
return "mit einem Verhältnis von 10 ml"; | ||
} else { | ||
return "met een verhouding van 10 ml"; | ||
} | ||
} | ||
|
||
private String getExpectedText2(Locale locale) { | ||
if (locale.equals(Locale.ENGLISH)) { | ||
return "at a rate of 10 ml"; | ||
} else if (locale.equals(Locale.FRENCH)) { | ||
return "au taux de 10 ml"; | ||
} else if (locale.equals(Locale.GERMAN)) { | ||
return "mit einem Verhältnis von 10 ml"; | ||
} else { | ||
return "met een verhouding van 10 ml"; | ||
} | ||
} | ||
|
||
private String getExpectedText3(Locale locale) { | ||
if (locale.equals(Locale.ENGLISH)) { | ||
return "at a rate of 10 mg per ml"; | ||
} else if (locale.equals(Locale.FRENCH)) { | ||
return "au taux de 10 mg par ml"; | ||
} else if (locale.equals(Locale.GERMAN)) { | ||
return "mit einem Verhältnis von 10 mg pro ml"; | ||
} else { | ||
return "met een verhouding van 10 mg per ml"; | ||
} | ||
} | ||
|
||
private String getExpectedText4(Locale locale) { | ||
if (locale.equals(Locale.ENGLISH)) { | ||
return "at a rate of 1 : 128"; | ||
} else if (locale.equals(Locale.FRENCH)) { | ||
return "au taux de 1 : 128"; | ||
} else if (locale.equals(Locale.GERMAN)) { | ||
return "mit einem Verhältnis von 1 : 128"; | ||
} else { | ||
return "met een verhouding van 1 : 128"; | ||
} | ||
} | ||
|
||
private String getExpectedText5(Locale locale) { | ||
if (locale.equals(Locale.ENGLISH)) { | ||
return "at a rate of 10 mg every 2 ml"; | ||
} else if (locale.equals(Locale.FRENCH)) { | ||
return "au taux de 10 mg chaque 2 ml"; | ||
} else if (locale.equals(Locale.GERMAN)) { | ||
return "mit einem Verhältnis von 10 mg jeder 2 ml"; | ||
} else { | ||
return "met een verhouding van 10 mg elke 2 ml"; | ||
} | ||
} | ||
|
||
} |