changed questionnaire_order.json framework.
This commit is contained in:
@ -1,24 +1,41 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"file": "questionnaire_1_demographic_information.json",
|
"file": "questionnaire_1_demographic_information.json",
|
||||||
"showPoints": false
|
"showPoints": false,
|
||||||
|
"condition": {
|
||||||
|
"alwaysAvailable": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file": "questionnaire_2_rhs.json",
|
"file": "questionnaire_2_rhs.json",
|
||||||
"showPoints": true
|
"showPoints": true,
|
||||||
|
"condition": {
|
||||||
|
"alwaysAvailable": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file": "questionnaire_3_integration_index.json",
|
"file": "questionnaire_3_integration_index.json",
|
||||||
"showPoints": true
|
"showPoints": true,
|
||||||
|
"condition": {
|
||||||
|
"alwaysAvailable": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file": "questionnaire_4_consultation_results.json",
|
"file": "questionnaire_4_consultation_results.json",
|
||||||
"showPoints": false
|
"showPoints": false,
|
||||||
|
"condition": {
|
||||||
|
"requiresCompleted": [
|
||||||
|
"questionnaire_1_demographic_information",
|
||||||
|
"questionnaire_2_rhs",
|
||||||
|
"questionnaire_3_integration_index"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file": "questionnaire_5_final_interview.json",
|
"file": "questionnaire_5_final_interview.json",
|
||||||
"showPoints": false,
|
"showPoints": false,
|
||||||
"condition": {
|
"condition": {
|
||||||
|
"requiresCompleted": ["questionnaire_4_consultation_results"],
|
||||||
"questionnaire": "questionnaire_4_consultation_results",
|
"questionnaire": "questionnaire_4_consultation_results",
|
||||||
"questionId": "consultation_decision",
|
"questionId": "consultation_decision",
|
||||||
"operator": "==",
|
"operator": "==",
|
||||||
@ -27,6 +44,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"file": "questionnaire_6_follow_up_survey.json",
|
"file": "questionnaire_6_follow_up_survey.json",
|
||||||
"showPoints": false
|
"showPoints": false,
|
||||||
|
"condition": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"requiresCompleted": ["questionnaire_5_final_interview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"requiresCompleted": ["questionnaire_4_consultation_results"],
|
||||||
|
"questionnaire": "questionnaire_4_consultation_results",
|
||||||
|
"questionId": "consultation_decision",
|
||||||
|
"operator": "!=",
|
||||||
|
"value": "yellow"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -69,6 +69,11 @@ class HandlerClientCoachCode(
|
|||||||
val clientCode = clientCodeField.text.toString()
|
val clientCode = clientCodeField.text.toString()
|
||||||
val coachCode = coachCodeField.text.toString()
|
val coachCode = coachCodeField.text.toString()
|
||||||
|
|
||||||
|
// Prüfen, ob die Datenbank-Dateien vor dem Klick existieren
|
||||||
|
val dbFile = layout.context.getDatabasePath("questionnaire_database")
|
||||||
|
val dbJournalFile = layout.context.getDatabasePath("questionnaire_database-journal")
|
||||||
|
val dbExisted = dbFile.exists() || dbJournalFile.exists()
|
||||||
|
|
||||||
// Check if client code already exists asynchronously
|
// Check if client code already exists asynchronously
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val existingClient = MyApp.database.clientDao().getClientByCode(clientCode)
|
val existingClient = MyApp.database.clientDao().getClientByCode(clientCode)
|
||||||
@ -81,6 +86,13 @@ class HandlerClientCoachCode(
|
|||||||
} else {
|
} else {
|
||||||
// Either no existing client or re-using previous code
|
// Either no existing client or re-using previous code
|
||||||
saveAnswers(clientCode, coachCode)
|
saveAnswers(clientCode, coachCode)
|
||||||
|
|
||||||
|
// Datenbank-Dateien löschen, wenn sie vorher NICHT existierten
|
||||||
|
if (!dbExisted) {
|
||||||
|
dbFile.delete()
|
||||||
|
dbJournalFile.delete()
|
||||||
|
}
|
||||||
|
|
||||||
goToNextQuestion()
|
goToNextQuestion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,10 +8,11 @@ import android.view.View
|
|||||||
import android.widget.*
|
import android.widget.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONObject
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import com.dano.test1.data.CompletedQuestionnaire
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
var INTEGRATION_INDEX_POINTS: Int? = null
|
var INTEGRATION_INDEX_POINTS: Int? = null
|
||||||
|
|
||||||
class HandlerOpeningScreen(private val activity: MainActivity) {
|
class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||||
@ -52,8 +53,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
val pathExists = File(dbPath).exists()
|
val pathExists = File(dbPath).exists()
|
||||||
if (pathExists) {
|
if (pathExists) {
|
||||||
updateMainButtonsState(true)
|
updateMainButtonsState(true)
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
updateMainButtonsState(false)
|
updateMainButtonsState(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,15 +90,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
val obj = jsonArray.getJSONObject(i)
|
val obj = jsonArray.getJSONObject(i)
|
||||||
val file = obj.getString("file")
|
val file = obj.getString("file")
|
||||||
val conditionObj = obj.optJSONObject("condition")
|
val conditionObj = obj.optJSONObject("condition")
|
||||||
val condition = if (conditionObj != null) {
|
val condition = parseCondition(conditionObj)
|
||||||
QuestionItem.Condition(
|
|
||||||
questionnaire = conditionObj.getString("questionnaire"),
|
|
||||||
questionId = conditionObj.getString("questionId"),
|
|
||||||
operator = conditionObj.getString("operator"),
|
|
||||||
value = conditionObj.getString("value")
|
|
||||||
)
|
|
||||||
} else null
|
|
||||||
|
|
||||||
val showPoints = obj.optBoolean("showPoints", false)
|
val showPoints = obj.optBoolean("showPoints", false)
|
||||||
|
|
||||||
QuestionItem.QuestionnaireEntry(file, condition, showPoints)
|
QuestionItem.QuestionnaireEntry(file, condition, showPoints)
|
||||||
@ -109,6 +101,63 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parser: erzeugt ein QuestionItem.Condition? (sehr robust gegenüber verschiedenen JSON-Formaten)
|
||||||
|
private fun parseCondition(conditionObj: JSONObject?): QuestionItem.Condition? {
|
||||||
|
if (conditionObj == null) return null
|
||||||
|
|
||||||
|
// anyOf
|
||||||
|
if (conditionObj.has("anyOf")) {
|
||||||
|
val arr = conditionObj.optJSONArray("anyOf") ?: JSONArray()
|
||||||
|
val conditions = mutableListOf<QuestionItem.Condition>()
|
||||||
|
for (i in 0 until arr.length()) {
|
||||||
|
val sub = arr.optJSONObject(i)
|
||||||
|
parseCondition(sub)?.let { conditions.add(it) }
|
||||||
|
}
|
||||||
|
return QuestionItem.Condition.AnyOf(conditions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// alwaysAvailable
|
||||||
|
if (conditionObj.has("alwaysAvailable")) {
|
||||||
|
val flag = conditionObj.optBoolean("alwaysAvailable", false)
|
||||||
|
if (flag) return QuestionItem.Condition.AlwaysAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiresCompleted (array)
|
||||||
|
val requiresList = mutableListOf<String>()
|
||||||
|
if (conditionObj.has("requiresCompleted")) {
|
||||||
|
val reqArr = conditionObj.optJSONArray("requiresCompleted")
|
||||||
|
if (reqArr != null) {
|
||||||
|
for (i in 0 until reqArr.length()) {
|
||||||
|
requiresList.add(reqArr.optString(i))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// sometimes it's a single string
|
||||||
|
conditionObj.optString("requiresCompleted")?.let { if (it.isNotBlank()) requiresList.add(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// question-check fields
|
||||||
|
val questionnaire = conditionObj.optString("questionnaire", null)
|
||||||
|
val questionId = conditionObj.optString("questionId", null)
|
||||||
|
val operator = conditionObj.optString("operator", null)
|
||||||
|
val value = conditionObj.optString("value", null)
|
||||||
|
|
||||||
|
val hasQuestionCheck = !questionnaire.isNullOrBlank() && !questionId.isNullOrBlank() && !operator.isNullOrBlank() && value != null
|
||||||
|
|
||||||
|
return when {
|
||||||
|
requiresList.isNotEmpty() && hasQuestionCheck -> {
|
||||||
|
QuestionItem.Condition.Combined(requiresList, QuestionItem.Condition.QuestionCondition(questionnaire!!, questionId!!, operator!!, value!!))
|
||||||
|
}
|
||||||
|
hasQuestionCheck -> {
|
||||||
|
QuestionItem.Condition.QuestionCondition(questionnaire!!, questionId!!, operator!!, value!!)
|
||||||
|
}
|
||||||
|
requiresList.isNotEmpty() -> {
|
||||||
|
QuestionItem.Condition.RequiresCompleted(requiresList)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createQuestionnaireButtons() {
|
private fun createQuestionnaireButtons() {
|
||||||
buttonContainer.removeAllViews()
|
buttonContainer.removeAllViews()
|
||||||
dynamicButtons.clear()
|
dynamicButtons.clear()
|
||||||
@ -129,12 +178,23 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateButtonTexts()
|
updateButtonTexts()
|
||||||
setButtonsEnabled(listOf(dynamicButtons.firstOrNull()).filterNotNull())
|
|
||||||
|
// Initial: enable those with AlwaysAvailable (falls vorhanden)
|
||||||
|
val alwaysButtons = questionnaireEntries.mapIndexedNotNull { idx, entry ->
|
||||||
|
val btn = dynamicButtons.getOrNull(idx)
|
||||||
|
if (entry.condition is QuestionItem.Condition.AlwaysAvailable) btn else null
|
||||||
|
}
|
||||||
|
setButtonsEnabled(alwaysButtons)
|
||||||
|
|
||||||
dynamicButtons.forEach { button ->
|
dynamicButtons.forEach { button ->
|
||||||
button.setOnClickListener {
|
button.setOnClickListener {
|
||||||
|
// require a client code to start actual questionnaire (sichere Kontrolle)
|
||||||
|
val clientCode = editText.text.toString().trim()
|
||||||
|
|
||||||
|
GlobalValues.LAST_CLIENT_CODE = clientCode
|
||||||
startQuestionnaireForButton(button)
|
startQuestionnaireForButton(button)
|
||||||
setButtonsEnabled(dynamicButtons.filter { it != button })
|
// disable other buttons while one questionnaire is open
|
||||||
|
setButtonsEnabled(dynamicButtons.filter { it == button })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,86 +250,143 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
val message = LanguageManager.getText(languageID, "no_profile")
|
val message = LanguageManager.getText(languageID, "no_profile")
|
||||||
Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
|
Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
|
||||||
setButtonsEnabled(listOf(dynamicButtons.firstOrNull()).filterNotNull())
|
// enable only alwaysAvailable ones if no client found
|
||||||
|
val alwaysButtons = questionnaireEntries.mapIndexedNotNull { idx, entry ->
|
||||||
|
val btn = dynamicButtons.getOrNull(idx)
|
||||||
|
if (entry.condition is QuestionItem.Condition.AlwaysAvailable) btn else null
|
||||||
|
}
|
||||||
|
setButtonsEnabled(alwaysButtons)
|
||||||
}
|
}
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
updateMainButtonsState(true) // Datenbank vorhanden -> Buttons aktivieren
|
updateMainButtonsState(true) // Datenbank vorhanden -> Buttons aktivieren
|
||||||
handleNormalLoad(clientCode)
|
}
|
||||||
|
|
||||||
|
handleNormalLoad(clientCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluierung der Bedingung: suspend, weil DB-Abfragen stattfinden.
|
||||||
|
private suspend fun evaluateCondition(
|
||||||
|
condition: QuestionItem.Condition?,
|
||||||
|
clientCode: String,
|
||||||
|
completedEntries: List<CompletedQuestionnaire> // Anpassung an deinem DAO-Objekt-Name
|
||||||
|
): Boolean {
|
||||||
|
if (condition == null) return false
|
||||||
|
|
||||||
|
when (condition) {
|
||||||
|
is QuestionItem.Condition.AlwaysAvailable -> return true
|
||||||
|
is QuestionItem.Condition.RequiresCompleted -> {
|
||||||
|
// prüfen, ob alle required items in completedEntries vorhanden und isDone == true sind
|
||||||
|
val normalizedCompleted = completedEntries.map { normalizeQuestionnaireId(it.questionnaireId) }
|
||||||
|
return condition.required.all { req ->
|
||||||
|
val nReq = normalizeQuestionnaireId(req)
|
||||||
|
normalizedCompleted.any { it.contains(nReq) || nReq.contains(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is QuestionItem.Condition.QuestionCondition -> {
|
||||||
|
// need to fetch the answer for that questionnaire/questionId
|
||||||
|
val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, condition.questionnaire)
|
||||||
|
val relevant = answers.find { it.questionId.endsWith(condition.questionId, ignoreCase = true) }
|
||||||
|
val answerValue = relevant?.answerValue ?: ""
|
||||||
|
return when (condition.operator) {
|
||||||
|
"==" -> answerValue == condition.value
|
||||||
|
"!=" -> answerValue != condition.value
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is QuestionItem.Condition.Combined -> {
|
||||||
|
// Combined: requiresCompleted (if present) AND questionCheck must match
|
||||||
|
val reqOk = if (condition.requiresCompleted.isNullOrEmpty()) true
|
||||||
|
else {
|
||||||
|
val normalizedCompleted = completedEntries.map { normalizeQuestionnaireId(it.questionnaireId) }
|
||||||
|
condition.requiresCompleted.all { req ->
|
||||||
|
val nReq = normalizeQuestionnaireId(req)
|
||||||
|
normalizedCompleted.any { it.contains(nReq) || nReq.contains(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!reqOk) return false
|
||||||
|
// dann Frage-Check auswerten
|
||||||
|
val q = condition.questionCheck
|
||||||
|
if (q != null) {
|
||||||
|
val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, q.questionnaire)
|
||||||
|
val relevant = answers.find { it.questionId.endsWith(q.questionId, ignoreCase = true) }
|
||||||
|
val answerValue = relevant?.answerValue ?: ""
|
||||||
|
return when (q.operator) {
|
||||||
|
"==" -> answerValue == q.value
|
||||||
|
"!=" -> answerValue != q.value
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reqOk
|
||||||
|
}
|
||||||
|
is QuestionItem.Condition.AnyOf -> {
|
||||||
|
// true, wenn irgendeine der Sub-Bedingungen erfüllt ist
|
||||||
|
for (sub in condition.conditions) {
|
||||||
|
val subRes = evaluateCondition(sub, clientCode, completedEntries)
|
||||||
|
if (subRes) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun normalizeQuestionnaireId(name: String): String {
|
||||||
|
return name.lowercase().removeSuffix(".json")
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun handleNormalLoad(clientCode: String) {
|
private suspend fun handleNormalLoad(clientCode: String) {
|
||||||
val completedIds = withContext(Dispatchers.IO) {
|
|
||||||
MyApp.database.completedQuestionnaireDao().getCompletedQuestionnairesForClient(clientCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (completedIds.isEmpty()) {
|
|
||||||
setButtonsEnabled(listOf(dynamicButtons.firstOrNull()).filterNotNull())
|
|
||||||
val message = LanguageManager.getText(languageID, "no_profile")
|
|
||||||
Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val completedIndexes = completedIds.mapNotNull { id ->
|
|
||||||
questionnaireEntries.indexOfFirst { it.file.contains(id, ignoreCase = true) }.takeIf { it >= 0 }
|
|
||||||
}.sorted()
|
|
||||||
|
|
||||||
val completedEntries = withContext(Dispatchers.IO) {
|
val completedEntries = withContext(Dispatchers.IO) {
|
||||||
MyApp.database.completedQuestionnaireDao().getAllForClient(clientCode)
|
MyApp.database.completedQuestionnaireDao().getAllForClient(clientCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fülle buttonPoints & INTEGRATION_INDEX_POINTS
|
||||||
buttonPoints.clear()
|
buttonPoints.clear()
|
||||||
for (entry in completedEntries) {
|
for (entry in completedEntries) {
|
||||||
if (entry.isDone) {
|
if (entry.isDone) {
|
||||||
buttonPoints[entry.questionnaireId] = entry.sumPoints ?: 0
|
buttonPoints[entry.questionnaireId] = entry.sumPoints ?: 0
|
||||||
|
|
||||||
if (entry.questionnaireId.contains("questionnaire_3_integration_index", ignoreCase = true)) {
|
if (entry.questionnaireId.contains("questionnaire_3_integration_index", ignoreCase = true)) {
|
||||||
INTEGRATION_INDEX_POINTS = entry.sumPoints
|
INTEGRATION_INDEX_POINTS = entry.sumPoints
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateButtonTexts()
|
withContext(Dispatchers.Main) {
|
||||||
|
updateButtonTexts()
|
||||||
var nextIndex = (completedIndexes.lastOrNull() ?: -1) + 1
|
|
||||||
|
|
||||||
while (nextIndex < questionnaireEntries.size) {
|
|
||||||
val entry = questionnaireEntries[nextIndex]
|
|
||||||
val condition = entry.condition
|
|
||||||
|
|
||||||
if (condition != null) {
|
|
||||||
val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, condition.questionnaire)
|
|
||||||
|
|
||||||
val relevantAnswer = answers.find {
|
|
||||||
it.questionId.endsWith(condition.questionId)
|
|
||||||
}
|
|
||||||
|
|
||||||
val answerValue = relevantAnswer?.answerValue ?: ""
|
|
||||||
val conditionMet = when (condition.operator) {
|
|
||||||
"!=" -> answerValue != condition.value
|
|
||||||
"==" -> answerValue == condition.value
|
|
||||||
else -> true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conditionMet) break
|
|
||||||
else nextIndex++
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextIndex >= questionnaireEntries.size) {
|
// für jeden Fragebogen prüfen, ob er aktiv sein darf
|
||||||
setButtonsEnabled(emptyList())
|
val enabledButtons = mutableListOf<Button>()
|
||||||
val message = LanguageManager.getText(languageID, "questionnaires_finished")
|
for ((idx, entry) in questionnaireEntries.withIndex()) {
|
||||||
Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
|
val button = dynamicButtons.getOrNull(idx) ?: continue
|
||||||
} else {
|
|
||||||
val nextFileName = questionnaireEntries[nextIndex].file
|
// falls bereits erledigt: nicht anklickbar
|
||||||
val nextButton = questionnaireFiles.entries.firstOrNull { it.value == nextFileName }?.key
|
val isCompleted = completedEntries.any { completed ->
|
||||||
setButtonsEnabled(listOfNotNull(nextButton))
|
normalizeQuestionnaireId(completed.questionnaireId).let { completedNorm ->
|
||||||
|
val targetNorm = normalizeQuestionnaireId(entry.file)
|
||||||
|
completedNorm.contains(targetNorm) || targetNorm.contains(completedNorm)
|
||||||
|
} && completed.isDone
|
||||||
|
}
|
||||||
|
if (isCompleted) {
|
||||||
|
// ausdrücklich deaktivieren
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// auswerten der Bedingung (suspend)
|
||||||
|
val condMet = evaluateCondition(entry.condition, clientCode, completedEntries)
|
||||||
|
if (condMet) enabledButtons.add(button)
|
||||||
|
}
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (enabledButtons.isEmpty()) {
|
||||||
|
setButtonsEnabled(emptyList())
|
||||||
|
val message = LanguageManager.getText(languageID, "questionnaires_finished")
|
||||||
|
Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
|
||||||
|
} else {
|
||||||
|
setButtonsEnabled(enabledButtons)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,6 +395,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
|
|
||||||
val entry = questionnaireEntries.firstOrNull { it.file == fileName }
|
val entry = questionnaireEntries.firstOrNull { it.file == fileName }
|
||||||
|
|
||||||
|
// key ableiten
|
||||||
val key = fileName.substringAfter("questionnaire_").substringAfter("_").removeSuffix(".json")
|
val key = fileName.substringAfter("questionnaire_").substringAfter("_").removeSuffix(".json")
|
||||||
var buttonText = LanguageManager.getText(languageID, key)
|
var buttonText = LanguageManager.getText(languageID, key)
|
||||||
|
|
||||||
@ -574,15 +692,12 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
// --- Füge diese Funktion in deine Klasse ein ---
|
// --- Füge diese Funktion in deine Klasse ein ---
|
||||||
private fun isDatabasePopulated(): Boolean {
|
private fun isDatabasePopulated(): Boolean {
|
||||||
return try {
|
return try {
|
||||||
// Wir prüfen, ob die Datenbank mindestens eine nicht-interne Tabelle enthält.
|
|
||||||
// Das ist robust gegenüber verschiedenen Tabellennamen.
|
|
||||||
val db = MyApp.database.openHelper.readableDatabase
|
val db = MyApp.database.openHelper.readableDatabase
|
||||||
val cursor = db.query(
|
val cursor = db.query(
|
||||||
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name != 'room_master_table'"
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name != 'room_master_table'"
|
||||||
)
|
)
|
||||||
cursor.use { it.count > 0 }
|
cursor.use { it.count > 0 }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// Falls etwas schiefgeht (z.B. DB noch nicht vorhanden), gilt: nicht vorhanden
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,4 +722,4 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
button.alpha = if (isDatabaseAvailable) 1.0f else 0.5f
|
button.alpha = if (isDatabaseAvailable) 1.0f else 0.5f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,11 +112,22 @@ sealed class QuestionItem {
|
|||||||
val showPoints: Boolean = false // neu
|
val showPoints: Boolean = false // neu
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Condition(
|
// flexible Condition-Typen für die questionnaire_order.json
|
||||||
val questionnaire: String,
|
sealed class Condition {
|
||||||
val questionId: String,
|
object AlwaysAvailable : Condition()
|
||||||
val operator: String,
|
data class RequiresCompleted(val required: List<String>) : Condition()
|
||||||
val value: String
|
data class QuestionCondition(
|
||||||
)
|
val questionnaire: String,
|
||||||
}
|
val questionId: String,
|
||||||
|
val operator: String,
|
||||||
|
val value: String
|
||||||
|
) : Condition()
|
||||||
|
|
||||||
|
data class Combined(
|
||||||
|
val requiresCompleted: List<String>?,
|
||||||
|
val questionCheck: QuestionCondition?
|
||||||
|
) : Condition()
|
||||||
|
|
||||||
|
data class AnyOf(val conditions: List<Condition>) : Condition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user