-
Notifications
You must be signed in to change notification settings - Fork 246
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pack repeated groups into answers (#1936)
* Pack repeated groups into answers * Run spotless apply * Add negative test cases for packing/unpacking repeated groups * Update TestingUtils.kt * Add test for repeated groups in questionnaire view model * Change fun signature unpackRepeatedGroups to use List * Deconstruct it * Rename files and update URL * Inline variable isRepeatedGroup * Revert TestingUtils.kt * Update TestingUtils.kt
- Loading branch information
1 parent
9396c07
commit 256ab75
Showing
7 changed files
with
548 additions
and
75 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
File renamed without changes.
120 changes: 120 additions & 0 deletions
120
...rc/main/java/com/google/android/fhir/datacapture/extensions/MoreQuestionnaireResponses.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,120 @@ | ||
/* | ||
* Copyright 2022 Google LLC | ||
* | ||
* 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:https://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 com.google.android.fhir.datacapture.extensions | ||
|
||
import org.hl7.fhir.r4.model.Questionnaire | ||
import org.hl7.fhir.r4.model.QuestionnaireResponse | ||
|
||
/** Pre-order list of all questionnaire response items in the questionnaire. */ | ||
val QuestionnaireResponse.allItems: List<QuestionnaireResponse.QuestionnaireResponseItemComponent> | ||
get() = item.flatMap { it.descendant } | ||
|
||
/** | ||
* Packs repeated groups under the same questionnaire response item. | ||
* | ||
* Repeated groups need some massaging before the questionnaire view model can interpret them | ||
* correctly. This is because they are flattened out and nested directly under the parent in the | ||
* FHIR data format. | ||
* | ||
* More details: https://build.fhir.org/questionnaireresponse.html#link. | ||
* | ||
* This function should be called before the questionnaire view model accepts an | ||
* application-provided questionnaire response. | ||
* | ||
* See also [unpackRepeatedGroups]. | ||
*/ | ||
internal fun QuestionnaireResponse.packRepeatedGroups() { | ||
item = item.packRepeatedGroups() | ||
} | ||
|
||
private fun List<QuestionnaireResponse.QuestionnaireResponseItemComponent>.packRepeatedGroups(): | ||
List<QuestionnaireResponse.QuestionnaireResponseItemComponent> { | ||
forEach { it -> | ||
it.item = it.item.packRepeatedGroups() | ||
it.answer.forEach { it.item = it.item.packRepeatedGroups() } | ||
} | ||
val linkIdToPackedResponseItems = | ||
groupBy { it.linkId } | ||
.mapValues { (linkId, questionnaireResponseItems) -> | ||
questionnaireResponseItems.singleOrNull() | ||
?: QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { | ||
this.linkId = linkId | ||
answer = | ||
questionnaireResponseItems.map { | ||
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply { | ||
item = it.item | ||
} | ||
} | ||
} | ||
} | ||
return map { it.linkId }.distinct().map { linkIdToPackedResponseItems[it]!! } | ||
} | ||
|
||
/** | ||
* Unpacks repeated groups as separate questionnaire response items under their parent. | ||
* | ||
* Repeated groups need some massaging for their returned data-format; each instance of the group | ||
* should be flattened out to be its own item in the parent, rather than an answer to the main item. | ||
* | ||
* More details: https://build.fhir.org/questionnaireresponse.html#link. | ||
* | ||
* For example, if the group contains 2 questions, and the user answered the group 3 times, this | ||
* function will return a list with 3 responses; each of those responses will have the linkId of the | ||
* provided group, and each will contain an item array with 2 items (the answers to the individual | ||
* questions within this particular group instance). | ||
* | ||
* This function should be called before returning the questionnaire response to the application. | ||
* | ||
* See also [packRepeatedGroups]. | ||
*/ | ||
internal fun QuestionnaireResponse.unpackRepeatedGroups(questionnaire: Questionnaire) { | ||
item = unpackRepeatedGroups(questionnaire.item, item) | ||
} | ||
|
||
private fun unpackRepeatedGroups( | ||
questionnaireItems: List<Questionnaire.QuestionnaireItemComponent>, | ||
questionnaireResponseItems: List<QuestionnaireResponse.QuestionnaireResponseItemComponent> | ||
): List<QuestionnaireResponse.QuestionnaireResponseItemComponent> { | ||
return questionnaireItems.zip(questionnaireResponseItems).flatMap { | ||
(questionnaireItem, questionnaireResponseItem) -> | ||
unpackRepeatedGroups(questionnaireItem, questionnaireResponseItem) | ||
} | ||
} | ||
|
||
private fun unpackRepeatedGroups( | ||
questionnaireItem: Questionnaire.QuestionnaireItemComponent, | ||
questionnaireResponseItem: QuestionnaireResponse.QuestionnaireResponseItemComponent | ||
): List<QuestionnaireResponse.QuestionnaireResponseItemComponent> { | ||
questionnaireResponseItem.item = | ||
unpackRepeatedGroups(questionnaireItem.item, questionnaireResponseItem.item) | ||
questionnaireResponseItem.answer.forEach { | ||
it.item = unpackRepeatedGroups(questionnaireItem.item, it.item) | ||
} | ||
return if (questionnaireItem.type == Questionnaire.QuestionnaireItemType.GROUP && | ||
questionnaireItem.repeats | ||
) { | ||
questionnaireResponseItem.answer.map { | ||
QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { | ||
linkId = questionnaireItem.linkId | ||
text = questionnaireItem.localizedTextSpanned?.toString() | ||
item = it.item | ||
} | ||
} | ||
} else { | ||
listOf(questionnaireResponseItem) | ||
} | ||
} |
23 changes: 0 additions & 23 deletions
23
...c/main/java/com/google/android/fhir/datacapture/extensions/MoreQuestionnairesResponses.kt
This file was deleted.
Oops, something went wrong.
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.