-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add config Composition section to support custom search parameters
- Loading branch information
Showing
6 changed files
with
252 additions
and
118 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
141 changes: 141 additions & 0 deletions
141
.../java/org/smartregister/fhircore/engine/configuration/app/CustomSearchParameterService.kt
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,141 @@ | ||
/* | ||
* Copyright 2021-2024 Ona Systems, Inc | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.smartregister.fhircore.engine.configuration.app | ||
|
||
import ca.uhn.fhir.parser.IParser | ||
import java.io.File | ||
import java.io.FileInputStream | ||
import java.io.FileOutputStream | ||
import kotlinx.coroutines.withContext | ||
import org.hl7.fhir.r4.model.Bundle | ||
import org.hl7.fhir.r4.model.Composition | ||
import org.hl7.fhir.r4.model.Enumerations | ||
import org.hl7.fhir.r4.model.Reference | ||
import org.hl7.fhir.r4.model.ResourceType | ||
import org.hl7.fhir.r4.model.SearchParameter | ||
import org.smartregister.fhircore.engine.util.DispatcherProvider | ||
import org.smartregister.fhircore.engine.util.extension.extractType | ||
|
||
class CustomSearchParameterService( | ||
private val storageDir: File, | ||
private val iParser: IParser, | ||
private val dispatcherProvider: DispatcherProvider, | ||
) { | ||
|
||
fun getCustomSearchParameters(): List<SearchParameter> { | ||
return predefinedCustomSearchParameters + readSavedSearchParameters() | ||
} | ||
|
||
private fun readSavedSearchParameters(): List<SearchParameter> { | ||
val file = File(storageDir, CUSTOM_SEARCH_PARAMETER_FILE_NAME) | ||
if (!file.exists()) { | ||
return emptyList() | ||
} | ||
|
||
val searchParametersBundle = | ||
FileInputStream(file).bufferedReader().use { iParser.parseResource(Bundle::class.java, it) } | ||
return searchParametersBundle.entry | ||
.filter { it.resource.resourceType == ResourceType.SearchParameter } | ||
.mapNotNull { it.resource as? SearchParameter } | ||
} | ||
|
||
suspend fun saveBundle(bundle: Bundle) { | ||
val file = File(storageDir, CUSTOM_SEARCH_PARAMETER_FILE_NAME) | ||
withContext(dispatcherProvider.io()) { | ||
FileOutputStream(file).use { it.write(iParser.encodeResourceToString(bundle).toByteArray()) } | ||
} | ||
} | ||
|
||
/** List of predefined custom search parameters. */ | ||
private val predefinedCustomSearchParameters: List<SearchParameter> | ||
get() { | ||
val activeGroupSearchParameter = | ||
SearchParameter().apply { | ||
url = "http://smartregister.org/SearchParameter/group-active" | ||
addBase("Group") | ||
name = ACTIVE_SEARCH_PARAM | ||
code = ACTIVE_SEARCH_PARAM | ||
type = Enumerations.SearchParamType.TOKEN | ||
expression = "Group.active" | ||
description = "Search the active field" | ||
} | ||
|
||
val flagStatusSearchParameter = | ||
SearchParameter().apply { | ||
url = "http://smartregister.org/SearchParameter/flag-status" | ||
addBase("Flag") | ||
name = STATUS_SEARCH_PARAM | ||
code = STATUS_SEARCH_PARAM | ||
type = Enumerations.SearchParamType.TOKEN | ||
expression = "Flag.status" | ||
description = "Search the status field" | ||
} | ||
|
||
val medicationSortSearchParameter = | ||
SearchParameter().apply { | ||
url = MEDICATION_SORT_URL | ||
addBase("Medication") | ||
name = SORT_SEARCH_PARAM | ||
code = SORT_SEARCH_PARAM | ||
type = Enumerations.SearchParamType.NUMBER | ||
expression = "Medication.extension.where(url = '$MEDICATION_SORT_URL').value" | ||
description = "Search the sort field" | ||
} | ||
|
||
val patientSearchParameter = | ||
SearchParameter().apply { | ||
url = "http://smartregister.org/SearchParameter/patient-search" | ||
addBase("Patient") | ||
name = SEARCH_PARAM | ||
code = SEARCH_PARAM | ||
type = Enumerations.SearchParamType.STRING | ||
expression = "Patient.name.text | Patient.identifier.value" | ||
description = "Search patients by name and identifier fields" | ||
} | ||
|
||
return listOf( | ||
activeGroupSearchParameter, | ||
flagStatusSearchParameter, | ||
medicationSortSearchParameter, | ||
patientSearchParameter, | ||
) | ||
} | ||
|
||
companion object { | ||
private const val CUSTOM_SEARCH_PARAMETER_FILE_NAME = "customSearchParameters.json" | ||
|
||
private const val ACTIVE_SEARCH_PARAM = "active" | ||
private const val STATUS_SEARCH_PARAM = "status" | ||
private const val SORT_SEARCH_PARAM = "sort" | ||
private const val SEARCH_PARAM = "search" | ||
private const val MEDICATION_SORT_URL = | ||
"http://smartregister.org/SearchParameter/medication-sort" | ||
} | ||
} | ||
|
||
fun isCompositionSectionSearchParameter(section: Composition.SectionComponent): Boolean = | ||
section.code.coding.any { | ||
it.system.lowercase() == SEARCH_PARAMETER_SECTION_SYSTEM_URL && | ||
it.code.lowercase() == SEARCH_PARAMETER_SECTION_CODE | ||
} | ||
|
||
fun isSearchParameterConfigReferenceValid(reference: Reference): Boolean = | ||
reference.extractType() == ResourceType.Bundle | ||
|
||
private const val SEARCH_PARAMETER_SECTION_SYSTEM_URL = | ||
"http://smartregister.org/CodeSystem/composition-section-codes" | ||
private const val SEARCH_PARAMETER_SECTION_CODE = "custom-search-parameter-bundle" |
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
Oops, something went wrong.