Skip to content

Commit

Permalink
Fix enhancements conflicts (#3612)
Browse files Browse the repository at this point in the history
 🐛 Fix conflicts
  • Loading branch information
dubdabasoduba authored Nov 15, 2024
1 parent 00a71a9 commit c08e6e1
Show file tree
Hide file tree
Showing 43 changed files with 2,103 additions and 1,336 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1. Added a new class (PdfGenerator) for generating PDF documents from HTML content using Android's WebView and PrintManager
2. Introduced a new class (HtmlPopulator) to populate HTML templates with data from a Questionnaire Response
3. Implemented functionality to launch PDF generation using a configuration setup
- Added Save draft MVP functionality

## [1.1.0] - 2024-02-15

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2021-2023, Ona Systems, Inc.
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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ constructor(
context = context,
configService = configService,
metadataResource = resource,
filePath =
subFilePath =
"${KnowledgeManagerUtil.KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER}/${resource.resourceType}/${resource.idElement.idPart}.json",
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.smartregister.fhircore.engine.domain.model.RuleConfig
data class RegisterContentConfig(
val separator: String? = null,
val display: String? = null,
val placeholderColor: String? = null,
val rules: List<RuleConfig>? = null,
val visible: Boolean? = null,
val computedRules: List<String>? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ data class CompoundTextProperties(
val textCase: TextCase? = null,
val overflow: TextOverFlow? = null,
val letterSpacing: Int = 0,
val textInnerPadding: Int = 0,
) : ViewProperties(), Parcelable {
override fun interpolate(computedValuesMap: Map<String, Any>): CompoundTextProperties {
return this.copy(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import ca.uhn.fhir.context.FhirContext
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport
import ca.uhn.fhir.context.support.IValidationSupport
import ca.uhn.fhir.validation.FhirValidator
import dagger.Lazy
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -30,6 +31,8 @@ import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerVali
import org.hl7.fhir.common.hapi.validation.support.UnknownCodeSystemWarningValidationSupport
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator
import org.smartregister.fhircore.engine.util.DispatcherProvider
import org.smartregister.fhircore.engine.util.validation.ResourceValidationRequestHandler

@Module
@InstallIn(SingletonComponent::class)
Expand All @@ -52,4 +55,13 @@ class FhirValidatorModule {
instanceValidator.invalidateCaches()
return fhirContext.newValidator().apply { registerValidatorModule(instanceValidator) }
}

@Provides
@Singleton
fun provideResourceValidationRequestHandler(
fhirValidatorProvider: Lazy<FhirValidator>,
dispatcherProvider: DispatcherProvider,
): ResourceValidationRequestHandler {
return ResourceValidationRequestHandler(fhirValidatorProvider.get(), dispatcherProvider)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ object AlertDialogue {
@StringRes confirmButtonText: Int = R.string.questionnaire_alert_confirm_button_title,
neutralButtonListener: ((d: DialogInterface) -> Unit)? = null,
@StringRes neutralButtonText: Int = R.string.questionnaire_alert_neutral_button_title,
negativeButtonListener: ((d: DialogInterface) -> Unit)? = null,
@StringRes negativeButtonText: Int = R.string.questionnaire_alert_negative_button_title,
cancellable: Boolean = false,
options: Array<AlertDialogListItem>? = null,
): AlertDialog {
Expand All @@ -71,6 +73,9 @@ object AlertDialogue {
confirmButtonListener?.let {
setPositiveButton(confirmButtonText) { d, _ -> confirmButtonListener.invoke(d) }
}
negativeButtonListener?.let {
setNegativeButton(negativeButtonText) { d, _ -> negativeButtonListener.invoke(d) }
}
options?.run { setSingleChoiceItems(options.map { it.value }.toTypedArray(), -1, null) }
}
.show()
Expand Down Expand Up @@ -172,6 +177,8 @@ object AlertDialogue {
@StringRes confirmButtonText: Int,
neutralButtonListener: ((d: DialogInterface) -> Unit),
@StringRes neutralButtonText: Int,
negativeButtonListener: ((d: DialogInterface) -> Unit),
@StringRes negativeButtonText: Int,
cancellable: Boolean = true,
options: List<AlertDialogListItem>? = null,
): AlertDialog {
Expand All @@ -184,6 +191,8 @@ object AlertDialogue {
confirmButtonText = confirmButtonText,
neutralButtonListener = neutralButtonListener,
neutralButtonText = neutralButtonText,
negativeButtonListener = negativeButtonListener,
negativeButtonText = negativeButtonText,
cancellable = cancellable,
options = options?.toTypedArray(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,26 @@ object KnowledgeManagerUtil {
const val KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER = "km"
private val fhirContext = FhirContext.forR4Cached()

/**
* Util method that creates a physical file and writes the Metadata FHIR resource content to it.
* Note the filepath provided is appended to the apps private directory as returned by
* Context.filesDir
*
* @param subFilePath the path of the file but within the apps private directory
* {Context.filesDir}
* @param metadataResource the actual FHIR Resource of type MetadataResource
* @param configService the configuration service
* @param context the application context
* @return File the file object after creating and writing
*/
fun writeToFile(
filePath: String,
subFilePath: String,
metadataResource: MetadataResource,
configService: ConfigService,
context: Context,
): File =
context
.createFileInPrivateDirectory(filePath)
.createFileInPrivateDirectory(subFilePath)
.also { it.parentFile?.mkdirs() }
.apply {
writeText(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.hl7.fhir.r4.model.Expression
import org.hl7.fhir.r4.model.IdType
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseStatus
import org.hl7.fhir.r4.model.StringType
import org.smartregister.fhircore.engine.configuration.LinkIdType
import org.smartregister.fhircore.engine.configuration.QuestionnaireConfig
Expand Down Expand Up @@ -292,3 +293,19 @@ suspend fun Questionnaire.prepopulateUniqueIdAssignment(
}
}
}

/**
* Determines the [QuestionnaireResponse.Status] depending on the [saveDraft] and [isEditable]
* values contained in the [QuestionnaireConfig]
*
* returns [COMPLETED] when [isEditable] is [true] returns [INPROGRESS] when [saveDraft] is [true]
*/
fun QuestionnaireConfig.questionnaireResponseStatus(): String? {
return if (this.isEditable()) {
QuestionnaireResponseStatus.COMPLETED.toCode()
} else if (this.saveDraft) {
QuestionnaireResponseStatus.INPROGRESS.toCode()
} else {
null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* 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.util.validation

import ca.uhn.fhir.validation.FhirValidator
import ca.uhn.fhir.validation.ResultSeverityEnum
import ca.uhn.fhir.validation.ValidationResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.hl7.fhir.r4.model.Resource
import org.smartregister.fhircore.engine.util.DispatcherProvider
import org.smartregister.fhircore.engine.util.extension.referenceValue
import timber.log.Timber

data class ResourceValidationRequest(val resources: List<Resource>) {
constructor(vararg resource: Resource) : this(resource.toList())
}

class ResourceValidationRequestHandler(
private val fhirValidator: FhirValidator,
private val dispatcherProvider: DispatcherProvider,
) {
fun handleResourceValidationRequest(request: ResourceValidationRequest) {
CoroutineScope(dispatcherProvider.io()).launch {
val resources = request.resources
fhirValidator.checkResources(resources).logErrorMessages()
}
}
}

internal data class ResourceValidationResult(
val resource: Resource,
val validationResult: ValidationResult,
) {
val errorMessages
get() = buildString {
val messages =
validationResult.messages.filter {
it.severity.ordinal >= ResultSeverityEnum.WARNING.ordinal
}
if (messages.isNotEmpty()) {
appendLine(resource.referenceValue())
}
for (validationMsg in messages) {
appendLine(
"${validationMsg.locationString} - ${validationMsg.message} -- (${validationMsg.severity})",
)
}
}
}

internal class FhirValidatorResultsWrapper(
val results: List<ResourceValidationResult> = emptyList(),
) {
val errorMessages = results.map { it.errorMessages }

fun logErrorMessages() {
results.forEach {
if (it.errorMessages.isNotBlank()) {
Timber.tag(TAG).e(it.errorMessages)
}
}
}

companion object {
private const val TAG = "FhirValidatorResult"
}
}

internal fun FhirValidator.checkResources(
resources: List<Resource>,
): FhirValidatorResultsWrapper {
return FhirValidatorResultsWrapper(
results =
resources.map {
val result = this@checkResources.validateWithResult(it)
ResourceValidationResult(it, result)
},
)
}
11 changes: 7 additions & 4 deletions android/engine/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@
<string name="error_saving_form">Error encountered cannot save form</string>
<string name="form_progress_message">Processing data. Please wait</string>
<string name="questionnaire_alert_back_pressed_message">Are you sure you want to go back?</string>
<string name="questionnaire_in_progress_alert_back_pressed_message">Are you sure you want to discard the answers?</string>
<string name="questionnaire_alert_back_pressed_title">Discard changes</string>
<string name="questionnaire_alert_back_pressed_button_title">Discard</string>
<string name="questionnaire_alert_back_pressed_save_draft_button_title">Save partial draft</string>
<string name="questionnaire_in_progress_alert_back_pressed_message">If you leave without saving, all your changes will not be saved</string>
<string name="questionnaire_alert_back_pressed_title">You have unsaved changes</string>
<string name="questionnaire_alert_back_pressed_button_title">Discard changes</string>
<string name="questionnaire_alert_back_pressed_save_draft_button_title">Save as draft</string>
<string name="questionnaire_alert_neutral_button_title">Cancel</string>
<string name="questionnaire_alert_negative_button_title">Discard Changes</string>
<string name="questionnaire_alert_confirm_button_title">Yes</string>
<string name="questionnaire_alert_invalid_message">Given details have validation errors. Resolve errors and submit again</string>
<string name="questionnaire_alert_invalid_title">Validation Failed</string>
Expand Down Expand Up @@ -198,4 +199,6 @@
<string name="unsynced_data_present">There\'s some un-synced data</string>
<string name="missing_supervisor_contact">Supervisor contact missing or the provided phone number is invalid</string>
<string name="apply_filter">APPLY FILTER</string>
<string name="questionnaire_save_draft_title">Save draft changes</string>
<string name="questionnaire_save_draft_message">Do you want to save draft changes?</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ class ConfigurationRegistryTest : RobolectricTest() {
configService = configService,
metadataResource = resource,
context = context,
filePath =
subFilePath =
"${KnowledgeManagerUtil.KNOWLEDGE_MANAGER_ASSETS_SUBFOLDER}/${resource.resourceType}/${resource.idElement.idPart}.json",
)
assertNotNull(resultFile)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ class AlertDialogueTest : ActivityRobolectricTest() {
confirmButtonText = R.string.questionnaire_alert_back_pressed_save_draft_button_title,
neutralButtonListener = {},
neutralButtonText = R.string.questionnaire_alert_back_pressed_button_title,
negativeButtonListener = {},
negativeButtonText = R.string.questionnaire_alert_negative_button_title,
)
val dialog = shadowOf(ShadowAlertDialog.getLatestAlertDialog())

Expand Down
Loading

0 comments on commit c08e6e1

Please sign in to comment.