Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get RelatedPerson Age and Gender via Rules Engine #3384

Merged
merged 10 commits into from
Jul 17, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import kotlin.system.measureTimeMillis
import org.hl7.fhir.r4.model.Base
import org.hl7.fhir.r4.model.Enumerations.DataType
import org.hl7.fhir.r4.model.Patient
import org.hl7.fhir.r4.model.Resource
import org.hl7.fhir.r4.model.Task
import org.jeasy.rules.api.Facts
Expand All @@ -50,6 +49,7 @@
import org.smartregister.fhircore.engine.util.extension.SDF_E_MMM_DD_YYYY
import org.smartregister.fhircore.engine.util.extension.daysPassed
import org.smartregister.fhircore.engine.util.extension.extractAge
import org.smartregister.fhircore.engine.util.extension.extractBirthDate
import org.smartregister.fhircore.engine.util.extension.extractGender
import org.smartregister.fhircore.engine.util.extension.extractLogicalIdUuid
import org.smartregister.fhircore.engine.util.extension.formatDate
Expand Down Expand Up @@ -288,17 +288,22 @@
label: String,
): String = mapResourcesToLabeledCSV(listOf(resource), fhirPathExpression, label)

/** This function extracts the patient's age from the patient resource */
fun extractAge(patient: Patient): String = patient.extractAge(context)
/** Extracts a Patient/RelatedPerson's age */
fun extractAge(resource: Resource): String {
ellykits marked this conversation as resolved.
Show resolved Hide resolved
return resource.extractAge(context)
}

/**
* This function extracts and returns a translated string for the gender in Patient resource.
*/
fun extractGender(patient: Patient): String = patient.extractGender(context) ?: ""
/** Extracts and returns a translated string for the gender in the resource */
fun extractGender(resource: Resource): String {
ellykits marked this conversation as resolved.
Show resolved Hide resolved
return resource.extractGender(context)
}

/** This function extracts the patient's DOB from the FHIR resource */
fun extractDOB(patient: Patient, dateFormat: String): String =
SimpleDateFormat(dateFormat, Locale.ENGLISH).run { format(patient.birthDate) }
/** This function extracts a Patient/RelatedPerson's DOB from the FHIR resource */
fun extractDOB(resource: Resource, dateFormat: String): String {
return SimpleDateFormat(dateFormat, Locale.ENGLISH).run {
resource.extractBirthDate()?.let { format(it) }
} ?: ""

Check warning on line 305 in android/engine/src/main/java/org/smartregister/fhircore/engine/rulesengine/RulesFactory.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/rulesengine/RulesFactory.kt#L305

Added line #L305 was not covered by tests
}

/**
* This function takes [inputDate] and returns a difference (for examples 7 hours, 2 day, 5
Expand Down Expand Up @@ -546,12 +551,11 @@
}
.getOrNull()

fun generateTaskServiceStatus(task: Task): String {
val serviceStatus: String
if (task.isOverDue()) {
serviceStatus = ServiceStatus.OVERDUE.name
} else {
serviceStatus =
fun generateTaskServiceStatus(task: Task?): String {
return when {
task == null -> ""
task.isOverDue() -> ServiceStatus.OVERDUE.name
else -> {
when (task.status) {
Task.TaskStatus.NULL,
Task.TaskStatus.RECEIVED,
Expand All @@ -569,9 +573,10 @@
Task.TaskStatus.CANCELLED -> ServiceStatus.EXPIRED.name
Task.TaskStatus.INPROGRESS -> ServiceStatus.IN_PROGRESS.name
Task.TaskStatus.COMPLETED -> ServiceStatus.COMPLETED.name
else -> ""

Check warning on line 576 in android/engine/src/main/java/org/smartregister/fhircore/engine/rulesengine/RulesFactory.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/rulesengine/RulesFactory.kt#L576

Added line #L576 was not covered by tests
}
}
}
return serviceStatus
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,7 @@

package org.smartregister.fhircore.engine.util.extension

import android.content.Context
import org.hl7.fhir.r4.model.Enumerations
import org.hl7.fhir.r4.model.Patient
import org.hl7.fhir.r4.model.codesystems.AdministrativeGender
import org.smartregister.fhircore.engine.R

fun Patient.extractGender(context: Context): String? =
if (hasGender()) {
when (AdministrativeGender.valueOf(this.gender.name)) {
AdministrativeGender.MALE -> context.getString(R.string.male)
AdministrativeGender.FEMALE -> context.getString(R.string.female)
AdministrativeGender.OTHER -> context.getString(R.string.other)
AdministrativeGender.UNKNOWN -> context.getString(R.string.unknown)
AdministrativeGender.NULL -> ""
}
} else {
null
}

fun Patient.extractAge(context: Context): String {
if (!hasBirthDate()) return ""
return calculateAge(birthDate, context)
}

fun String?.join(other: String?, separator: String) =
this.orEmpty().plus(other?.plus(separator).orEmpty())
Expand All @@ -47,10 +25,3 @@ fun Patient.extractFamilyTag() =
this.meta.tag.firstOrNull {
it.display.contentEquals("family", true) || it.display.contains("head", true)
}

fun Enumerations.AdministrativeGender.translateGender(context: Context) =
when (this) {
Enumerations.AdministrativeGender.MALE -> context.getString(R.string.male)
Enumerations.AdministrativeGender.FEMALE -> context.getString(R.string.female)
else -> context.getString(R.string.unknown)
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import org.hl7.fhir.r4.model.Coding
import org.hl7.fhir.r4.model.Composition
import org.hl7.fhir.r4.model.Condition
import org.hl7.fhir.r4.model.Encounter
import org.hl7.fhir.r4.model.Enumerations
import org.hl7.fhir.r4.model.Extension
import org.hl7.fhir.r4.model.Flag
import org.hl7.fhir.r4.model.Group
Expand All @@ -54,16 +55,19 @@ import org.hl7.fhir.r4.model.Quantity
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.Reference
import org.hl7.fhir.r4.model.RelatedPerson
import org.hl7.fhir.r4.model.Resource
import org.hl7.fhir.r4.model.ResourceType
import org.hl7.fhir.r4.model.StringType
import org.hl7.fhir.r4.model.StructureMap
import org.hl7.fhir.r4.model.Task
import org.hl7.fhir.r4.model.Timing
import org.hl7.fhir.r4.model.Type
import org.hl7.fhir.r4.model.codesystems.AdministrativeGender
import org.joda.time.Instant
import org.json.JSONException
import org.json.JSONObject
import org.smartregister.fhircore.engine.R
import org.smartregister.fhircore.engine.configuration.LinkIdType
import org.smartregister.fhircore.engine.configuration.QuestionnaireConfig
import org.smartregister.fhircore.engine.data.local.DefaultRepository
Expand Down Expand Up @@ -567,3 +571,47 @@ fun List<RepositoryResourceData>.filterByFhirPathExpression(
}
}
}

/** Extracts and returns a translated string for the gender in the resource */
fun Resource.extractGender(context: Context): String {
return when (this) {
is Patient -> getGenderString(this.gender, context)
is RelatedPerson -> getGenderString(this.gender, context)
else -> ""
}
}

private fun getGenderString(gender: Enumerations.AdministrativeGender?, context: Context): String {
return when (gender) {
Enumerations.AdministrativeGender.MALE -> context.getString(R.string.male)
Enumerations.AdministrativeGender.FEMALE -> context.getString(R.string.female)
Enumerations.AdministrativeGender.OTHER -> context.getString(R.string.other)
Enumerations.AdministrativeGender.UNKNOWN -> context.getString(R.string.unknown)
else -> ""
}
}

fun Enumerations.AdministrativeGender.translateGender(context: Context) =
when (this) {
Enumerations.AdministrativeGender.MALE -> context.getString(R.string.male)
Enumerations.AdministrativeGender.FEMALE -> context.getString(R.string.female)
else -> context.getString(R.string.unknown)
}

/** Extract a Resource's age if birthDate is an available field */
fun Resource.extractAge(context: Context): String {
return when (this) {
is Patient -> this.birthDate?.let { calculateAge(it, context) } ?: ""
is RelatedPerson -> this.birthDate?.let { calculateAge(it, context) } ?: ""
else -> ""
}
}

/** Extract a Resource's birthDate if it's an available field */
fun Resource.extractBirthDate(): Date? {
return when (this) {
is Patient -> this.birthDate
is RelatedPerson -> this.birthDate
else -> null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ class RulesEngineServiceTest : RobolectricTest() {
)
}

@Test
fun `generateTaskServiceStatus() should return en empty string when Task is NULL`() {
Assert.assertEquals(
"",
rulesEngineService.generateTaskServiceStatus(null),
)
}

@Test
fun `generateTaskServiceStatus() should return UPCOMING when Task#status is NULL`() {
val task = Task().apply { status = Task.TaskStatus.NULL }
Expand Down
Loading
Loading