Skip to content

Commit

Permalink
Feature/debug mode population (eu-digital-green-certificates#201)
Browse files Browse the repository at this point in the history
* Updated population of extended mode

* Updated data shown in extended mode

* Version update
  • Loading branch information
oleksandrsarapulovgl authored Sep 6, 2021
1 parent fa49177 commit d9171b7
Show file tree
Hide file tree
Showing 7 changed files with 413 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -272,19 +272,19 @@ class VerificationResultDialogFragment :
binding.personStandardisedGivenName.visibility = this
}

binding.dateOfBirth.text =
binding.dateOfBirthValue.text =
certificate.dateOfBirth.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY)

val dateOfBirth =
certificate.dateOfBirth.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY)
if (dateOfBirth.isBlank()) {
View.GONE
} else {
binding.dateOfBirth.text = dateOfBirth
binding.dateOfBirthValue.text = dateOfBirth
View.VISIBLE
}.apply {
binding.dateOfBirthTitle.visibility = this
binding.dateOfBirth.visibility = this
binding.dateOfBirthValue.visibility = this
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ import dgca.verifier.app.engine.CertLogicEngine
import dgca.verifier.app.engine.Result
import dgca.verifier.app.engine.UTC_ZONE_ID
import dgca.verifier.app.engine.ValidationResult
import dgca.verifier.app.engine.data.CertificateType
import dgca.verifier.app.engine.data.ExternalParameter
import dgca.verifier.app.engine.data.*
import dgca.verifier.app.engine.data.source.valuesets.ValueSetsRepository
import dgca.verifier.app.engine.domain.rules.GetRulesUseCase
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -122,7 +121,8 @@ class VerificationViewModel @Inject constructor(
}

if (innerVerificationResult.isApplicableCode) {
val covidCertificate = innerVerificationResult.greenCertificateData?.greenCertificate
val covidCertificate =
innerVerificationResult.greenCertificateData?.greenCertificate
val certificateModel = covidCertificate?.toCertificateModel()
val hcert: String? = innerVerificationResult.greenCertificateData?.hcertJson
val standardizedVerificationResult: StandardizedVerificationResult =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,34 @@ import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.card.MaterialCardView
import dgca.verifier.app.android.FORMATTED_YEAR_MONTH_DAY
import dgca.verifier.app.android.R
import dgca.verifier.app.android.YEAR_MONTH_DAY
import dgca.verifier.app.android.databinding.ViewDetailedCertificateViewBinding
import dgca.verifier.app.android.model.CertificateModel
import dgca.verifier.app.android.model.*
import dgca.verifier.app.android.model.rules.RuleValidationResultModelsContainer
import dgca.verifier.app.android.parseFromTo
import dgca.verifier.app.android.verification.StandardizedVerificationResult
import dgca.verifier.app.android.verification.StandardizedVerificationResultCategory
import dgca.verifier.app.android.verification.certs.RecoveryViewHolder
import dgca.verifier.app.android.verification.certs.TestViewHolder
import dgca.verifier.app.android.verification.certs.VaccinationViewHolder
import dgca.verifier.app.android.verification.rules.RuleValidationResultCard
import dgca.verifier.app.android.verification.rules.RuleValidationResultsAdapter
import dgca.verifier.app.android.verification.rules.toRuleValidationResultCard

class DetailedCertificateView(context: Context, attrs: AttributeSet?) :
MaterialCardView(context, attrs) {
private val binding: ViewDetailedCertificateViewBinding =
ViewDetailedCertificateViewBinding.inflate(LayoutInflater.from(context), this)
private var isExpanded = false
private lateinit var certificateModelAndStandardizedVerificationResult: Pair<CertificateModel, StandardizedVerificationResult>
private var isRulesListExpanded = true
private lateinit var data: Triple<CertificateModel, StandardizedVerificationResult, RuleValidationResultModelsContainer?>

init {
radius = TypedValue.applyDimension(
Expand All @@ -56,89 +68,235 @@ class DetailedCertificateView(context: Context, attrs: AttributeSet?) :

binding.expandButton.setOnClickListener {
setExpanded(!isExpanded)
setUp(certificateModelAndStandardizedVerificationResult)
}
}

fun setExpanded(expanded: Boolean) {
private fun setExpanded(expanded: Boolean) {
isExpanded = expanded
binding.expandButton.setImageResource(if (expanded) R.drawable.ic_icon_minus else R.drawable.ic_icon_plus)
setUp(certificateModelAndStandardizedVerificationResult)
setUpVisibility(data)
}

private fun setUpPersonData(personModel: PersonModel) {
binding.personStandardisedFamilyName.text = personModel.standardisedFamilyName
binding.personStandardisedGivenName.text = personModel.standardisedGivenName
}

private fun setUpVaccination(vaccinationList: List<VaccinationModel>) {
binding.greenCertificate.layoutResource = R.layout.item_vaccination
binding.greenCertificate.setOnInflateListener { stub, inflated ->
VaccinationViewHolder.create(
inflated as ViewGroup
).bind(vaccinationList.first())
}
}

private fun setUpRecovery(recoveryList: List<RecoveryModel>) {
binding.greenCertificate.layoutResource = R.layout.item_recovery
binding.greenCertificate.setOnInflateListener { stub, inflated ->
RecoveryViewHolder.create(
inflated as ViewGroup
).bind(recoveryList.first())
}
}

private fun setUpTest(testList: List<TestModel>) {
binding.greenCertificate.layoutResource = R.layout.item_test
binding.greenCertificate.setOnInflateListener { stub, inflated ->
TestViewHolder.create(
inflated as ViewGroup
).bind(testList.first())
}
}

private fun setUpGreenCertificateData(certificateModel: CertificateModel) {
if (binding.greenCertificate.parent != null) {
when {
certificateModel.vaccinations?.size == 1 -> {
setUpVaccination(certificateModel.vaccinations)
}
certificateModel.recoveryStatements?.size == 1 -> {
setUpRecovery(certificateModel.recoveryStatements)
}
certificateModel.tests?.size == 1 -> {
setUpTest(certificateModel.tests)
}
}
binding.greenCertificate.inflate()
}
}

private fun setUpErrorType(standardizedVerificationResult: StandardizedVerificationResult) {
binding.reasonForCertificateInvalidityName.text = context.getString(
when (standardizedVerificationResult) {
StandardizedVerificationResult.GREEN_CERTIFICATE_EXPIRED -> R.string.certificate_is_expired
StandardizedVerificationResult.CERTIFICATE_REVOKED -> R.string.certificate_was_revoked
StandardizedVerificationResult.VERIFICATION_FAILED -> R.string.verification_failed
StandardizedVerificationResult.CERTIFICATE_EXPIRED -> R.string.signing_certificate_is_expired
StandardizedVerificationResult.TEST_DATE_IS_IN_THE_FUTURE -> R.string.the_test_date_is_in_the_future
StandardizedVerificationResult.TEST_RESULT_POSITIVE -> R.string.test_result_positive
StandardizedVerificationResult.RECOVERY_NOT_VALID_SO_FAR -> R.string.recovery_not_valid_yet
StandardizedVerificationResult.RECOVERY_NOT_VALID_ANYMORE -> R.string.recover_not_valid_anymore
StandardizedVerificationResult.RULES_VALIDATION_FAILED -> R.string.rules_validation_failed
StandardizedVerificationResult.CRYPTOGRAPHIC_SIGNATURE_INVALID -> R.string.cryptographic_signature_invalid
else -> throw IllegalArgumentException()
}
)
}

private fun setUpRules(rulesValidationResultModelsContainer: RuleValidationResultModelsContainer) {
val ruleValidationResultCards = mutableListOf<RuleValidationResultCard>()
rulesValidationResultModelsContainer.ruleValidationResultModels.forEach {
ruleValidationResultCards.add(
it.toRuleValidationResultCard()
)
}
binding.rulesList.apply {
adapter = RuleValidationResultsAdapter(
LayoutInflater.from(context),
ruleValidationResultCards
)
layoutManager = LinearLayoutManager(context)
}

binding.reasonForCertificateInvalidityName.setOnClickListener {
isRulesListExpanded = !isRulesListExpanded
binding.rulesList.visibility =
if (isRulesListExpanded) View.VISIBLE else View.GONE
binding.reasonForCertificateInvalidityName.setCompoundDrawablesRelativeWithIntrinsicBounds(
null,
null,
ResourcesCompat.getDrawable(
resources,
if (isRulesListExpanded) R.drawable.icon_expanded else R.drawable.icon_collapsed,
null
),
null
)
}
binding.reasonForCertificateInvalidityTitle.text =
context.getString(R.string.possible_limitation)
val outValue = TypedValue()
context.theme.resolveAttribute(
android.R.attr.selectableItemBackground,
outValue,
true
)
binding.reasonForCertificateInvalidityName.setBackgroundResource(outValue.resourceId)
binding.reasonForCertificateInvalidityName.setCompoundDrawablesRelativeWithIntrinsicBounds(
null,
null,
ResourcesCompat.getDrawable(resources, R.drawable.icon_expanded, null),
null
)
}

fun setCertificateModel(
certificateModel: CertificateModel,
standardizedVerificationResult: StandardizedVerificationResult
standardizedVerificationResult: StandardizedVerificationResult,
ruleValidationResultModelsContainer: RuleValidationResultModelsContainer?
) {
certificateModelAndStandardizedVerificationResult =
Pair(certificateModel, standardizedVerificationResult)
setUp(certificateModelAndStandardizedVerificationResult)
}
setUpPersonData(certificateModel.person)
setUpGreenCertificateData(certificateModel)
if (standardizedVerificationResult.category != StandardizedVerificationResultCategory.VALID) {
setUpErrorType(standardizedVerificationResult)
}
if (standardizedVerificationResult == StandardizedVerificationResult.TEST_RESULT_POSITIVE) {
binding.testResultValue.text = TestResult.DETECTED.value
}

if (standardizedVerificationResult == StandardizedVerificationResult.RULES_VALIDATION_FAILED && ruleValidationResultModelsContainer?.ruleValidationResultModels?.isNotEmpty() == true) {
setUpRules(ruleValidationResultModelsContainer)
}

private fun setUp(certificateModelAndStandardizedVerificationResult: Pair<CertificateModel?, StandardizedVerificationResult>) {
setUpCertificateType(certificateModelAndStandardizedVerificationResult.first!!)
setUpPossibleLimitation(certificateModelAndStandardizedVerificationResult.second)
setUpDateOfBirth(certificateModelAndStandardizedVerificationResult.first!!)
data = Triple(
certificateModel,
standardizedVerificationResult,
ruleValidationResultModelsContainer
)
setExpanded(true)
}

private fun setUpCertificateType(certificateModel: CertificateModel) {
binding.certificateTypeName.text = when {
certificateModel.vaccinations?.isNotEmpty() == true -> context.getString(
R.string.type_vaccination,
certificateModel.vaccinations.first().doseNumber,
certificateModel.vaccinations.first().totalSeriesOfDoses
)
certificateModel.recoveryStatements?.isNotEmpty() == true -> context.getString(R.string.type_recovered)
certificateModel.tests?.isNotEmpty() == true -> context.getString(R.string.type_test)
else -> context.getString(R.string.type_test)
private fun setUpVisibility(data: Triple<CertificateModel, StandardizedVerificationResult, RuleValidationResultModelsContainer?>) {
val certificateModel = data.first
val standardizedVerificationResult: StandardizedVerificationResult =
data.second
val ruleValidationResultModelsContainer: RuleValidationResultModelsContainer? = data.third

if (standardizedVerificationResult.category != StandardizedVerificationResultCategory.INVALID) {
setPersonDataVisibility(certificateModel)
}

binding.greenCertificate.visibility =
if (isExpanded && standardizedVerificationResult.category != StandardizedVerificationResultCategory.INVALID) View.VISIBLE else View.GONE

setErrorVisibility(standardizedVerificationResult, ruleValidationResultModelsContainer)
}

private fun setPersonDataVisibility(certificateModel: CertificateModel) {
if (isExpanded) {
View.VISIBLE
} else {
View.GONE
}.apply {
binding.certificateTypeTitle.visibility = this
binding.certificateTypeName.visibility = this
binding.personStandardisedFamilyNameTitle.visibility = this
binding.personStandardisedFamilyName.visibility = this
}
}

private fun setUpPossibleLimitation(standardizedVerificationResult: StandardizedVerificationResult) {
if (standardizedVerificationResult == StandardizedVerificationResult.SUCCESS || !isExpanded) {
View.GONE
} else {
binding.possibleLimitationsName.text = context.getString(
when (standardizedVerificationResult) {
StandardizedVerificationResult.GREEN_CERTIFICATE_EXPIRED -> R.string.certificate_is_expired
StandardizedVerificationResult.CERTIFICATE_REVOKED -> R.string.certificate_was_revoked
StandardizedVerificationResult.VERIFICATION_FAILED -> R.string.verification_failed
StandardizedVerificationResult.CERTIFICATE_EXPIRED -> R.string.signing_certificate_is_expired
StandardizedVerificationResult.TEST_DATE_IS_IN_THE_FUTURE -> R.string.the_test_date_is_in_the_future
StandardizedVerificationResult.TEST_RESULT_POSITIVE -> R.string.test_result_positive
StandardizedVerificationResult.RECOVERY_NOT_VALID_SO_FAR -> R.string.recovery_not_valid_yet
StandardizedVerificationResult.RECOVERY_NOT_VALID_ANYMORE -> R.string.recover_not_valid_anymore
StandardizedVerificationResult.RULES_VALIDATION_FAILED -> R.string.rules_validation_failed
StandardizedVerificationResult.CRYPTOGRAPHIC_SIGNATURE_INVALID -> R.string.cryptographic_signature_invalid
else -> throw IllegalArgumentException()
}
)
if (isExpanded && certificateModel.person.standardisedGivenName?.isNotBlank() == true) {
View.VISIBLE
} else {
View.GONE
}.apply {
binding.possibleLimitationsTitle.visibility = this
binding.possibleLimitationsName.visibility = this
binding.personStandardisedGivenNameTitle.visibility = this
binding.personStandardisedGivenName.visibility = this
}

certificateModel.dateOfBirth.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY)
.let { birthday ->
if (birthday.isNotBlank() && isExpanded) {
binding.dateOfBirthValue.text = birthday
View.VISIBLE
} else {
View.GONE
}.apply {
binding.dateOfBirthTitle.visibility = this
binding.dateOfBirthValue.visibility = this
}
}
}

private fun setUpDateOfBirth(certificateModel: CertificateModel) {
val dateOfBirth =
certificateModel.dateOfBirth.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY)
if (dateOfBirth.isBlank() || !isExpanded) {
private fun setErrorVisibility(
standardizedVerificationResult: StandardizedVerificationResult,
ruleValidationResultModelsContainer: RuleValidationResultModelsContainer?,
) {
if (standardizedVerificationResult.category != StandardizedVerificationResultCategory.VALID && isExpanded) {
View.VISIBLE
} else {
View.GONE
}.let { visibility ->
binding.reasonForCertificateInvalidityTitle.visibility = visibility
binding.reasonForCertificateInvalidityName.visibility = visibility
}


if (standardizedVerificationResult == StandardizedVerificationResult.TEST_RESULT_POSITIVE && isExpanded) {
View.VISIBLE
} else {
binding.dateOfBirthName.text = dateOfBirth
View.GONE
}.let { visibility ->
binding.errorTestResult.visibility = visibility
}

if (standardizedVerificationResult == StandardizedVerificationResult.RULES_VALIDATION_FAILED
&& ruleValidationResultModelsContainer?.ruleValidationResultModels?.isNotEmpty() == true
&& isExpanded && isRulesListExpanded
) {
View.VISIBLE
}.apply {
binding.dateOfBirthTitle.visibility = this
binding.dateOfBirthName.visibility = this
} else {
View.GONE
}.let { visibility ->
binding.rulesList.visibility = visibility
}
}
}
Loading

0 comments on commit d9171b7

Please sign in to comment.