Skip to content

Commit

Permalink
Merge branch 'master' into 971_calc_exp
Browse files Browse the repository at this point in the history
  • Loading branch information
maimoonak authored Sep 14, 2022
2 parents 54a8f11 + 1443db1 commit 90e8c12
Show file tree
Hide file tree
Showing 12 changed files with 843 additions and 431 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Releases.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ object Releases {

object DataCapture : LibraryArtifact {
override val artifactId = "data-capture"
override val version = "0.1.0-beta04"
override val version = "0.1.0-beta05"
override val name = "Android FHIR Structured Data Capture Library"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import org.hl7.fhir.r4.model.CodeType
import org.hl7.fhir.r4.model.CodeableConcept
import org.hl7.fhir.r4.model.Coding
import org.hl7.fhir.r4.model.DecimalType
import org.hl7.fhir.r4.model.DomainResource
import org.hl7.fhir.r4.model.Enumeration
import org.hl7.fhir.r4.model.Expression
import org.hl7.fhir.r4.model.Extension
Expand Down Expand Up @@ -444,9 +445,47 @@ object ResourceMapper {
.javaClass
.getMethod("setValue", Type::class.java)
.invoke(base, questionnaireResponseItem.answer.singleOrNull()?.value)
return
} catch (e: NoSuchMethodException) {
// Do nothing
}

if (base.javaClass.getFieldOrNull(fieldName) == null) {
// If field not found in resource class, assume this is an extension
addDefinitionBasedCustomExtension(questionnaireItem, questionnaireResponseItem, base)
}
}
}

/**
* Adds custom extension for Resource.
* @param questionnaireItem QuestionnaireItemComponent with details for extension
* @param questionnaireResponseItem QuestionnaireResponseItemComponent for response value
* @param base
* - resource's Base class instance See
* https://hapifhir.io/hapi-fhir/docs/model/profiles_and_extensions.html#extensions for more on
* custom extensions
*/
private fun addDefinitionBasedCustomExtension(
questionnaireItem: Questionnaire.QuestionnaireItemComponent,
questionnaireResponseItem: QuestionnaireResponse.QuestionnaireResponseItemComponent,
base: Base
) {
if (base is Type) {
// Create an extension
val ext = Extension()
ext.url = questionnaireItem.definition
ext.setValue(questionnaireResponseItem.answer.first().value)
// Add the extension to the resource
base.addExtension(ext)
}
if (base is DomainResource) {
// Create an extension
val ext = Extension()
ext.url = questionnaireItem.definition
ext.setValue(questionnaireResponseItem.answer.first().value)
// Add the extension to the resource
base.addExtension(ext)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import java.time.ZoneId
import java.time.chrono.IsoChronology
import java.time.format.DateTimeFormatterBuilder
import java.time.format.FormatStyle
import java.util.Date
import java.util.Locale
import kotlin.math.abs
import kotlin.math.log10
Expand Down Expand Up @@ -103,16 +104,20 @@ internal object QuestionnaireItemDatePickerViewHolderFactory :
textInputLayout.hint = localePattern
textInputEditText.removeTextChangedListener(textWatcher)

textInputEditText.setText(
questionnaireItemViewItem
.answers
.singleOrNull()
?.takeIf { it.hasValue() }
?.valueDateType
?.localDate
?.localizedString
)

if (isTextUpdateRequired(
textInputEditText.context,
questionnaireItemViewItem.answers.singleOrNull()?.valueDateType,
textInputEditText.text.toString()
)
) {
textInputEditText.setText(
questionnaireItemViewItem.answers.singleOrNull()
?.takeIf { it.hasValue() }
?.valueDateType
?.localDate
?.localizedString
)
}
textWatcher = textInputEditText.doAfterTextChanged { text -> updateAnswer(text.toString()) }
}

Expand Down Expand Up @@ -159,6 +164,20 @@ internal object QuestionnaireItemDatePickerViewHolderFactory :
}
}
}

private fun isTextUpdateRequired(
context: Context,
answer: DateType?,
inputText: String?
): Boolean {
val inputDate =
try {
parseDate(inputText, context)
} catch (e: Exception) {
null
}
return answer?.localDate != inputDate
}
}

internal const val TAG = "date-picker"
Expand Down Expand Up @@ -196,14 +215,17 @@ internal val DateType.localDate
internal val LocalDate.dateType
get() = DateType(year, monthValue - 1, dayOfMonth)

internal val Date.localDate
get() = LocalDate.of(year + 1900, month + 1, date)

internal fun parseDate(text: CharSequence?, context: Context): LocalDate {
val date =
val localDate =
if (isAndroidIcuSupported()) {
DateFormat.getDateInstance(DateFormat.SHORT).parse(text.toString())
} else {
android.text.format.DateFormat.getDateFormat(context).parse(text.toString())
}
val localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
DateFormat.getDateInstance(DateFormat.SHORT).parse(text.toString())
} else {
android.text.format.DateFormat.getDateFormat(context).parse(text.toString())
}
.localDate
// date/localDate with year more than 4 digit throws data format exception if deep copy
// operation get performed on QuestionnaireResponse,
// QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent in org.hl7.fhir.r4.model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ internal object QuestionnaireItemDateTimePickerViewHolderFactory :
val dateTime = questionnaireItemViewItem.answers.singleOrNull()?.valueDateTimeType
updateDateTimeInput(
dateTime?.let {
LocalDateTime.of(it.year, it.month + 1, it.day, it.hour, it.minute, it.second)
it.localDateTime.also {
localDate = it.toLocalDate()
localTime = it.toLocalTime()
}
}
)
textWatcher =
Expand Down Expand Up @@ -197,7 +200,12 @@ internal object QuestionnaireItemDateTimePickerViewHolderFactory :
/** Update the date and time input fields in the UI. */
private fun updateDateTimeInput(localDateTime: LocalDateTime?) {
enableOrDisableTimePicker(enableIt = localDateTime != null)
if (dateInputEditText.text.isNullOrEmpty()) {
if (isTextUpdateRequired(
dateInputEditText.context,
localDateTime,
dateInputEditText.text.toString()
)
) {
dateInputEditText.setText(localDateTime?.localizedDateString ?: "")
}
timeInputEditText.setText(
Expand Down Expand Up @@ -281,6 +289,21 @@ internal object QuestionnaireItemDateTimePickerViewHolderFactory :
timeInputLayout.isEnabled = enableIt
timeInputLayout.isEnabled = enableIt
}

private fun isTextUpdateRequired(
context: Context,
answer: LocalDateTime?,
inputText: String?
): Boolean {
val inputDate =
try {
generateLocalDateTime(parseDate(inputText, context), localTime)
} catch (e: Exception) {
null
}
if (answer == null || inputDate == null) return true
return answer.toLocalDate() != inputDate.toLocalDate()
}
}
}

Expand All @@ -301,3 +324,14 @@ internal val DateTimeType.localTime
minute,
second,
)

internal val DateTimeType.localDateTime
get() =
LocalDateTime.of(
year,
month + 1,
day,
hour,
minute,
second,
)
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,11 @@ internal object QuestionnaireItemRadioGroupViewHolderFactory :
}

private fun updateAnswer(answerOption: Questionnaire.QuestionnaireItemAnswerOptionComponent) {
// if-else block to prevent over-writing of "items" nested within "answer"
if (questionnaireItemViewItem.answers.isNotEmpty()) {
questionnaireItemViewItem.answers.apply { this[0].value = answerOption.value }
} else {
questionnaireItemViewItem.setAnswer(
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply {
value = answerOption.value
}
)
}
questionnaireItemViewItem.setAnswer(
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply {
value = answerOption.value
}
)
}
}
}
Loading

0 comments on commit 90e8c12

Please sign in to comment.