diff --git a/app/src/main/java/it/ministerodellasalute/immuni/api/services/ConfigurationSettingsService.kt b/app/src/main/java/it/ministerodellasalute/immuni/api/services/ConfigurationSettingsService.kt index 50e215d45..eb8612fac 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/api/services/ConfigurationSettingsService.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/api/services/ConfigurationSettingsService.kt @@ -63,7 +63,6 @@ data class ConfigurationSettings( @field:Json(name = "dummy_analytics_waiting_time") val dummyAnalyticsWaitingTime: Int, @field:Json(name = "countries") val countries: Map>, @field:Json(name = "eudcc_expiration") val eudcc_expiration: Map> - ) @JsonClass(generateAdapter = true) @@ -191,38 +190,44 @@ private fun eudccMap(): Map> { "rapid_test" to "Certificazione valida 48 ore dall'ora del prelievo", "vaccine_first_dose" to "Certificazione valida fino alla prossima dose", "vaccine_fully_completed" to "Certificazione valida 365 giorni (12 mesi) dalla data dell'ultima somministrazione", - "healing_certificate" to "Certificazione valida in Unione Europea fino alla data di fine validità e valida solo in Italia fino a 6 mesi dalla data di inizio validità" + "healing_certificate" to "Certificazione valida in Unione Europea fino alla data di fine validità e valida solo in Italia fino a 6 mesi dalla data di inizio validità", + "exemption_certificate" to "Certificato esenzione (illimitata)" ), "de" to mapOf( "molecular_test" to "Bescheinigung gültig für 72 Stunden ab dem Zeitpunkt der Abholung", "rapid_test" to "Bescheinigung gültig für 48 Stunden ab dem Zeitpunkt der Abholung", "vaccine_first_dose" to "Zertifizierung gültig bis zur nächsten Dosis", "vaccine_fully_completed" to "Zertifizierung gültig für 365 Tage (12 Monate) ab dem Datum der letzten Verabreichung", - "healing_certificate" to "Zertifizierung gültig in der Europäischen Union bis zum Gültigkeitsende und nur in Italien bis zu 6 Monate ab Gültigkeitsbeginn gültig" + "healing_certificate" to "Zertifizierung gültig in der Europäischen Union bis zum Gültigkeitsende und nur in Italien bis zu 6 Monate ab Gültigkeitsbeginn gültig", + "exemption_certificate" to "Befreiungsbescheinigung (unbefristet)" ), "en" to mapOf( "molecular_test" to "Certification valid for 72 hours from the time of collection", "rapid_test" to "Certification valid for 48 hours from the time of collection", "vaccine_first_dose" to "Certification valid until next dose", "vaccine_fully_completed" to "Certification valid for 365 days (12 months) from the date of the last administration", - "healing_certificate" to "Certification valid in the European Union until the end of validity date and valid only in Italy up to 6 months from the start of validity date" + "healing_certificate" to "Certification valid in the European Union until the end of validity date and valid only in Italy up to 6 months from the start of validity date", + "exemption_certificate" to "Certificate of exemption (unlimited)" ), "es" to mapOf( "molecular_test" to "Certificación válida por 72 horas desde el momento de la recogida.", "rapid_test" to "Certificación válida por 48 horas desde el momento de la recogida.", "vaccine_first_dose" to "Certificación válida hasta la próxima dosis", "vaccine_fully_completed" to "Certificación válida por 365 días (12 meses) a partir de la fecha de la última administración.", - "healing_certificate" to "Certificación válida en la Unión Europea hasta el final de la fecha de validez y válida solo en Italia hasta 6 meses desde el inicio de la fecha de validez" + "healing_certificate" to "Certificación válida en la Unión Europea hasta el final de la fecha de validez y válida solo en Italia hasta 6 meses desde el inicio de la fecha de validez", + "exemption_certificate" to "Certificado de exención (ilimitado)" ), "fr" to mapOf( "molecular_test" to "Attestation valable 72h à compter de la collecte", "rapid_test" to "Attestation valable 48h à compter de la collecte", "vaccine_first_dose" to "Certification valable jusqu'à la prochaine dose", "vaccine_fully_completed" to "Certification valable 365 jours (12 mois) à compter de la date de la dernière administration", - "healing_certificate" to "Certification valable dans l'Union européenne jusqu'à la date de fin de validité et valable uniquement en Italie jusqu'à 6 mois à compter de la date de début de validité" + "healing_certificate" to "Certification valable dans l'Union européenne jusqu'à la date de fin de validité et valable uniquement en Italie jusqu'à 6 mois à compter de la date de début de validité", + "exemption_certificate" to "Certificat d'exonération (illimité)" ) ) } + val defaultSettings = ConfigurationSettings( minimumBuildVersion = 0, faqUrls = languageMap { "https://get.immuni.gov.it/docs/faq-${it.code}.json" }, diff --git a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/UserManager.kt b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/UserManager.kt index 38b5d00d4..0704cc3d4 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/UserManager.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/UserManager.kt @@ -68,4 +68,12 @@ class UserManager( fun provinces(region: Region) = regionRepository.provinces(region = region) // endregion + + // DGC + val showModalDGC = userRepository.showModalDGC + + fun setShowModalDGC(show: Boolean) { + userRepository.setShowModalDGC(show) + } + // END DGC } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/repositories/UserRepository.kt b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/repositories/UserRepository.kt index 9f100debe..8a66de858 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/repositories/UserRepository.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/repositories/UserRepository.kt @@ -26,6 +26,7 @@ class UserRepository( private val setupCompleteKey = KVStorage.Key("SetupComplete") private val welcomeCompleteKey = KVStorage.Key("WelcomeComplete") private val onboardingCompleteKey = KVStorage.Key("OnboardingComplete") + private val showModalDGCKey = KVStorage.Key("showModalDGC") } val user = storage.stateFlow(userKey) @@ -51,4 +52,10 @@ class UserRepository( fun setOnboardingComplete(complete: Boolean) { storage[onboardingCompleteKey] = complete } + + val showModalDGC = storage.stateFlow(showModalDGCKey, defaultValue = true) + + fun setShowModalDGC(show: Boolean) { + storage[showModalDGCKey] = show + } } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateFragment.kt index 9388c4746..507c8b023 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateFragment.kt @@ -25,8 +25,10 @@ import android.provider.Settings import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import androidx.core.view.get import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.appbar.AppBarLayout import com.google.android.material.tabs.TabLayoutMediator @@ -40,6 +42,7 @@ import it.ministerodellasalute.immuni.ui.dialog.openConfirmationDialog import it.ministerodellasalute.immuni.util.ImageUtils import kotlin.math.abs import kotlinx.android.synthetic.main.green_certificate.* +import kotlinx.android.synthetic.main.green_certificate_tab.* import org.koin.android.ext.android.get import org.koin.androidx.viewmodel.ext.android.getViewModel @@ -58,6 +61,7 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat companion object { const val DELETE_QR = 200 const val GO_TO_SETTINGS = 201 + const val INFORMATION_ORDER = 202 } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -86,6 +90,20 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat positionOffsetPixels: Int ) { } + + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + val currentView = (viewpager[0] as RecyclerView).layoutManager?.findViewByPosition(position) + currentView?.post { + val wMeasureSpec = View.MeasureSpec.makeMeasureSpec(currentView.width, View.MeasureSpec.EXACTLY) + val hMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) + currentView.measure(wMeasureSpec, hMeasureSpec) + + if (viewpager.layoutParams.height != currentView.measuredHeight) { + viewpager.layoutParams = (viewpager.layoutParams).also { lp -> lp.height = currentView.measuredHeight } + } + } + } } greenPassAdapter = GreenPassAdapter( @@ -93,7 +111,7 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat fragment = this@GreenCertificateFragment, viewModel = viewModel ) - greenPassAdapter.data = userManager.user.value?.greenPass!! + greenPassAdapter.data = userManager.user.value?.greenPass!!.asReversed() with(viewpager) { adapter = greenPassAdapter @@ -116,29 +134,36 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat findNavController().navigate(action) } setVisibilityLayout() + informationOrder() } override fun onDialogPositive(requestCode: Int) { - if (requestCode == DELETE_QR) { - val user = userManager.user - user.value?.greenPass!!.removeAt(positionToDelete!!) - userManager.save( - User( - region = user.value?.region!!, - province = user.value?.province!!, - greenPass = user.value?.greenPass!! + when (requestCode) { + DELETE_QR -> { + val user = userManager.user + user.value?.greenPass!!.asReversed().removeAt(positionToDelete!!) + userManager.save( + User( + region = user.value?.region!!, + province = user.value?.province!!, + greenPass = user.value?.greenPass!! + ) ) - ) - greenPassAdapter.notifyItemRemoved(positionToDelete!!) - greenPassAdapter.notifyItemRangeChanged(positionToDelete!!, greenPassAdapter.itemCount) - setVisibilityLayout() - positionToDelete = null - } else { - val intent = - Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - val uri: Uri = Uri.fromParts("package", requireContext().packageName, null) - intent.data = uri - startActivity(intent) + greenPassAdapter.notifyItemRemoved(positionToDelete!!) + greenPassAdapter.notifyItemRangeChanged(positionToDelete!!, greenPassAdapter.itemCount) + setVisibilityLayout() + positionToDelete = null + } + INFORMATION_ORDER -> { + userManager.setShowModalDGC(show = false) + } + GO_TO_SETTINGS -> { + val intent = + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + val uri: Uri = Uri.fromParts("package", requireContext().packageName, null) + intent.data = uri + startActivity(intent) + } } } @@ -146,6 +171,19 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat // Pass } + private fun informationOrder() { + if (userManager.showModalDGC.value && userManager.user.value!!.greenPass.size > 1) { + openConfirmationDialog( + positiveButton = getString(R.string.green_certificate_modal_order_button), + negativeButton = null, + message = getString(R.string.green_certificate_modal_order_message), + title = getString(R.string.green_certificate_modal_order_title), + cancelable = false, + requestCode = INFORMATION_ORDER + ) + } + } + private fun setVisibilityLayout() { if (userManager.user.value?.greenPass!!.isEmpty()) { noQrCodeLayout.visibility = View.VISIBLE diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateViewModel.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateViewModel.kt index d1f96e5a6..5acf78bed 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateViewModel.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateViewModel.kt @@ -292,6 +292,9 @@ class GreenCertificateViewModel( greenCertificate.recoveryStatements != null -> { greenCertificate.recoveryStatements!![0].certificateIdentifier } + greenCertificate.exemptions != null -> { + greenCertificate.exemptions!![0].certificateIdentifier + } else -> null } @@ -310,6 +313,10 @@ class GreenCertificateViewModel( if (greenPass.data?.recoveryStatements!![0].certificateIdentifier == issuerID) saved = true } + greenPass.data?.exemptions != null -> { + if (greenPass.data?.exemptions!![0].certificateIdentifier == issuerID) saved = + true + } } } } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenPassAdapter.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenPassAdapter.kt index 8fafba167..792a8be3b 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenPassAdapter.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenPassAdapter.kt @@ -96,6 +96,9 @@ class GreenPassAdapter( greenCertificate.data?.vaccinations != null -> { greenCertificate.data!!.vaccinations!![0].certificateIdentifier } + greenCertificate.data?.exemptions != null -> { + greenCertificate.data!!.exemptions!![0].certificateIdentifier + } else -> null } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/MoreDetailGreenCertificate.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/MoreDetailGreenCertificate.kt index f6222b041..3c739acbd 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/MoreDetailGreenCertificate.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/MoreDetailGreenCertificate.kt @@ -33,9 +33,12 @@ import it.ministerodellasalute.immuni.ui.dialog.PopupDialogFragment import java.text.SimpleDateFormat import java.util.* import kotlinx.android.synthetic.main.green_certificate_more_details.* +import kotlinx.android.synthetic.main.green_certificate_more_details_exemption.* import kotlinx.android.synthetic.main.green_certificate_more_details_recovery.* import kotlinx.android.synthetic.main.green_certificate_more_details_test.* import kotlinx.android.synthetic.main.green_certificate_more_details_vaccination.* +import kotlinx.android.synthetic.main.green_certificate_more_details_vaccination.countryVaccination +import kotlinx.android.synthetic.main.green_certificate_more_details_vaccination.validityVaccine import org.koin.android.ext.android.get import org.koin.core.KoinComponent @@ -64,16 +67,19 @@ class MoreDetailGreenCertificate : PopupDialogFragment(), KoinComponent { val rapidTest = settingsManager.settings.value.eudcc_expiration[Locale.getDefault().language]!!["rapid_test"] val molecularTest = settingsManager.settings.value.eudcc_expiration[Locale.getDefault().language]!!["molecular_test"] val healing_certificate = settingsManager.settings.value.eudcc_expiration[Locale.getDefault().language]!!["healing_certificate"] + val exemptionCertificate = settingsManager.settings.value.eudcc_expiration[Locale.getDefault().language]!!["exemption_certificate"] setUI( vaccineFullyCompleted, vaccineFirstDose, molecularTest, rapidTest, - healing_certificate + healing_certificate, + exemptionCertificate ) } - private fun setUI(validUntilCompleteVaccine: String?, validUntilnotCompleteVaccine: String?, validUntilMolecularTest: String?, validUntilQuickTest: String?, healing_certificate: String?) { + private fun setUI(validUntilCompleteVaccine: String?, validUntilnotCompleteVaccine: String?, validUntilMolecularTest: String?, validUntilQuickTest: String?, healing_certificate: String?, exemptionCertificate: String?) { + var isExemption = false when (true) { greenCertificateDetail.data?.vaccinations != null -> { // Inflate layout dynamically @@ -128,6 +134,7 @@ class MoreDetailGreenCertificate : PopupDialogFragment(), KoinComponent { setTextOrDefault(greenCertificateDetail.data?.vaccinations?.get(0)!!.countryOfVaccination) certificateIssuerLabel.text = getText(R.string.green_certificate_certificate_issuer_vaccination) + certificateIssuerLabelExemption.visibility = View.GONE } greenCertificateDetail.data?.tests != null -> { // Inflate layout dynamically @@ -175,6 +182,7 @@ class MoreDetailGreenCertificate : PopupDialogFragment(), KoinComponent { countryTest.text = setTextOrDefault(greenCertificateDetail.data?.tests?.get(0)!!.countryOfVaccination) certificateIssuerLabel.text = getText(R.string.green_certificate_certificate_issuer) + certificateIssuerLabelExemption.visibility = View.GONE } greenCertificateDetail.data?.recoveryStatements != null -> { // Inflate layout dynamically @@ -202,31 +210,57 @@ class MoreDetailGreenCertificate : PopupDialogFragment(), KoinComponent { certificateIssuerLabel.visibility = View.GONE entityIssuedCertificate.visibility = View.GONE validityHealing.text = healing_certificate ?: getString(R.string.green_certificate_validity_healing) + certificateIssuerLabelExemption.visibility = View.GONE + } + greenCertificateDetail.data?.exemptions != null -> { + isExemption = true + flagEsenzione.visibility = View.VISIBLE + question.text = getString(R.string.green_certificate_exemption_title) + // Inflate layout dynamically + includeDynamicView(R.layout.green_certificate_more_details_exemption) + + subHeadingExemption.text = getString(R.string.green_certificate_subHeading_exemption) + certifying_physician_exemption.text = greenCertificateDetail.data?.exemptions?.get(0)!!.fiscalCode + exemptionValidFrom.text = greenCertificateDetail.data?.exemptions?.get(0)!!.certificateValidFrom + exemptionValidUntil.text = setTextOrDefault(greenCertificateDetail.data?.exemptions?.get(0)!!.certificateValidUntil) + uniqueCodeExemption.text = greenCertificateDetail.data?.exemptions?.get(0)!!.uniqueVaccinationExemptionIdentifier } } entityIssuedCertificate.text = getString(R.string.green_certificate_certificate_issuer_const) - val europeRestrictionUrl = - getString(R.string.green_certificate_more_details_europe_restriction_url) - europeRestrictionSite.text = "{$europeRestrictionUrl}".coloredClickable( - color = requireContext().getColorCompat(R.color.colorPrimary), - bold = true - ) { - ExternalLinksHelper.openLink( - requireContext(), - europeRestrictionUrl - ) + if (isExemption) { + certificateIssuerLabel.visibility = View.GONE + certificateIssuerLabelExemption.visibility = View.VISIBLE + certificateIssuerLabel.text = getString(R.string.green_certificate_certificate_issuer_exemption) + setTitle(getString(R.string.green_certificate_exemption_title)) + textFooter.visibility = View.GONE + europeRestrictionSite.visibility = View.GONE + textFooterExemption.visibility = View.VISIBLE + subHeading.visibility = View.GONE + subHeadingExemption.visibility = View.VISIBLE + } else { + val europeRestrictionUrl = + getString(R.string.green_certificate_more_details_europe_restriction_url) + europeRestrictionSite.text = "{$europeRestrictionUrl}".coloredClickable( + color = requireContext().getColorCompat(R.color.colorPrimary), + bold = true + ) { + ExternalLinksHelper.openLink( + requireContext(), + europeRestrictionUrl + ) + } + europeRestrictionSite.movementMethod = LinkMovementMethod.getInstance() } - europeRestrictionSite.movementMethod = LinkMovementMethod.getInstance() } private fun includeDynamicView(layout: Int) { val v = layoutInflater.inflate(layout, null) container.addView( v, - 4, + 5, ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/setup/SetupViewModel.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/setup/SetupViewModel.kt index 1606a0d2b..aaf97aa13 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/setup/SetupViewModel.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/setup/SetupViewModel.kt @@ -46,21 +46,18 @@ class SetupViewModel( val minDelay = async { delay(4000) } - val isFirstLaunch = !userManager.isSetupComplete.value - if (isFirstLaunch) { - // Let's fetch the configuration settings, - // waiting no more than 10 seconds for them to download before proceeding - val completion = CompletableDeferred() - async { - delay(10_000) - completion.complete(Unit) - } - async { - settingsManager.fetchSettingsAsync().await() - completion.complete(Unit) - } - completion.await() + // Let's fetch the configuration settings, + // waiting no more than 10 seconds for them to download before proceeding + val completion = CompletableDeferred() + async { + delay(10_000) + completion.complete(Unit) } + async { + settingsManager.fetchSettingsAsync().await() + completion.complete(Unit) + } + completion.await() minDelay.await() userManager.setSetupComplete(true) triggerNavigation() diff --git a/app/src/main/res/drawable-hdpi/immuni_flag_ita.png b/app/src/main/res/drawable-hdpi/immuni_flag_ita.png new file mode 100644 index 000000000..30dc9d597 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/immuni_flag_ita.png differ diff --git a/app/src/main/res/drawable-mdpi/immuni_flag_ita.png b/app/src/main/res/drawable-mdpi/immuni_flag_ita.png new file mode 100644 index 000000000..d96566b3f Binary files /dev/null and b/app/src/main/res/drawable-mdpi/immuni_flag_ita.png differ diff --git a/app/src/main/res/drawable-xhdpi/immuni_flag_ita.png b/app/src/main/res/drawable-xhdpi/immuni_flag_ita.png new file mode 100644 index 000000000..f45c932e6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/immuni_flag_ita.png differ diff --git a/app/src/main/res/drawable-xxhdpi/immuni_flag_ita.png b/app/src/main/res/drawable-xxhdpi/immuni_flag_ita.png new file mode 100644 index 000000000..d4ba92ee4 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/immuni_flag_ita.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/immuni_flag_ita.png b/app/src/main/res/drawable-xxxhdpi/immuni_flag_ita.png new file mode 100644 index 000000000..087c3e21e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/immuni_flag_ita.png differ diff --git a/app/src/main/res/layout/green_certificate.xml b/app/src/main/res/layout/green_certificate.xml index d7a996657..9980d6b03 100644 --- a/app/src/main/res/layout/green_certificate.xml +++ b/app/src/main/res/layout/green_certificate.xml @@ -63,7 +63,7 @@ diff --git a/app/src/main/res/layout/green_certificate_more_details.xml b/app/src/main/res/layout/green_certificate_more_details.xml index c774e4862..b8b6b8b2f 100644 --- a/app/src/main/res/layout/green_certificate_more_details.xml +++ b/app/src/main/res/layout/green_certificate_more_details.xml @@ -34,6 +34,18 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + + + android:visibility="gone" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d05679479..2005fb898 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -493,9 +493,21 @@ Betriebssystem: iOS 13.5.1; Modell: iPhone XS; Expositionsmeldungen: Aktiv; [wei Zertifizierung gültig für 365 Tage (12 Monate) ab dem Datum der letzten Verabreichung Bescheinigung gültig für 48 Stunden ab dem Zeitpunkt der Abholung Bescheinigung gültig für 72 Stunden ab dem Zeitpunkt der Abholung - Kein EU Digital Covid Certificate gefunden + Kein EU Digital Covid Certificate gefunden. Überprüfen Sie, ob die eingegebenen Daten korrekt sind Bestätigung %s von %s Die grüne COVID-19-Zertifizierung wird auf dem Smartphone-Bildschirm angezeigt, so dass sie auf Wunsch, bei Verifizierung, auch im Offline-Modus eingesehen und gezeigt werden kann. Über die Schaltfläche „Löschen“ können Sie Ihr Zertifikat jederzeit selbstständig von Ihrem Smartphone löschen. Zertifizierung gültig in der Europäischen Union bis zum Gültigkeitsende und nur in Italien bis zu 6 Monate ab Gültigkeitsbeginn gültig + Ich verstehe + Wir haben die Reihenfolge Ihrer Zertifikate geändert + Wenn Sie diese Nachricht lesen, bedeutet dies, dass Sie mehr als ein grünes COVID-19-Zertifikat auf Ihrem Gerät installiert haben: Sie werden jetzt in chronologischer Reihenfolge angezeigt, beginnend mit dem neuesten. Denken Sie daran, dass Sie sie löschen oder von einem zum anderen wechseln können, indem Sie mit Ihrem Finger zur Seite wischen + Befreiungsbescheinigung (unbefristet) + Steuernummer des zertifizierenden Arztes + Gültigkeitsbeginn der Zertifizierung + Endgültigkeitsdatum der Zertifizierung + Eindeutiger Impfbefreiungscode (CUEV) + NUR IN ITALIEN GÜLTIG + Digitale Bescheinigung der COVID-19-Impfbefreiung + Subjekt, das die digitale Freistellungsbescheinigung ausgestellt hat + Diese Zertifizierung ist nur in Italien gültig und kann verwendet werden, um die grüne COVID-19-Zertifizierung für die Durchführung von Aktivitäten und die Nutzung von Dienstleistungen gemäß der geltenden nationalen Gesetzgebung zu ersetzen diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 27eb887f9..009757673 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -498,7 +498,19 @@ Sistema operativo: iOS 13.5.1; modelo: iPhone XS; notificaciones de exposición: Certificación válida por 365 días (12 meses) a partir de la fecha de la última administración. Certificación válida por 48 horas desde el momento de la extracción. Certificación válida por 72 horas desde el momento de la extracción. - No se encontró ningún EU Digital Covid Certificate + No se encontró ningún EU Digital Covid Certificate. Comprueba que los datos introducidos son correctos La certificación verde COVID-19 se muestra en la pantalla del teléfono inteligente para que se pueda ver y mostrar a pedido, en caso de verificación, incluso en modo fuera de línea. El botón \"Eliminar\" le permite eliminar su certificado de su teléfono inteligente de forma independiente en cualquier momento. Certificación válida en la Unión Europea hasta el final de la fecha de validez y válida solo en Italia hasta 6 meses desde el inicio de la fecha de validez + Entiendo + Hemos cambiado el orden de sus Certificados + Si está leyendo este mensaje, significa que tiene más de un Certificado Verde COVID-19 instalado en su dispositivo: ahora se muestran en orden cronológico comenzando por el más reciente. Recuerda que puedes borrarlos o pasar de uno a otro deslizando el dedo lateralmente + Certificado de exención (ilimitado) + NIF del médico certificador + Fecha de inicio de validez de la certificación + Finaliza la fecha de validez de la certificación + Código único de exención de vacunación (CUEV) + Esta certificación es válida solo en Italiay puede usarse para reemplazar la certificación verde COVID-19 para el desempeño de actividades y el uso de servicios de acuerdo con la legislación nacional vigente + VÁLIDO SOLO EN ITALIA + Certificación digital de exención de vacunación COVID-19 + Sujeto que emitió el certificado de exención digital diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6935cc92f..d54d37a77 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -495,9 +495,22 @@ Système d\'exploitation : iOS 13.5.1; Modèle iPhone XS ; Notifications de risq Certification valable 365 jours (12 mois) à compter de la date de la dernière administration Attestation valable 48h à compter de la collecte Attestation valable 72h à compter de la collecte - Aucun EU Digital Covid Certificate trouvé + Aucun EU Digital Covid Certificate trouvé. Vérifiez que les données saisies sont correctes Confirmation %s sur %s La certification verte COVID-19 est affichée sur l\'écran du smartphone afin qu\'elle puisse être consultée et affichée sur demande, en cas de vérification, même en mode hors ligne. Le bouton «Supprimer» vous permet de supprimer votre certificat de votre smartphone de manière autonome à tout moment. Certification valable dans l\'Union européenne jusqu\'à la date de fin de validité et valable uniquement en Italie jusqu\'à 6 mois à compter de la date de début de validité + Je comprend + Nous avons modifié l\'ordre de vos Certificats + Si vous lisez ce message, cela signifie que plusieurs certificats verts COVID-19 sont installés sur votre appareil: ils sont désormais affichés par ordre chronologique en commençant par le plus récent. N\'oubliez pas que vous pouvez les supprimer ou passer de l\'un à l\'autre en balayant latéralement avec votre doigt + Certificat d\'exonération (illimité) + Code fiscal du médecin certificateur + Date de début de validité de la certification + Date de fin de validité de la certification + Code unique d\'exemption de vaccination (CUEV) + Cette certification est valable uniquement en Italie et peut être utilisée comme substitut de la certification verte COVID-19 pour l\'exécution d\'activités et l\'utilisation de services conformément à la législation nationale en vigueur + VALABLE UNIQUEMENT EN ITALIE + Certification numérique de l\'exemption de vaccination COVID-19 + Sujet qui a délivré le certificat d\'exemption numérique + diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index d57b7cb02..f3ff49b31 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -496,8 +496,21 @@ Sistema operativo: iOS 13.5.1; Modello iPhone XS; Notifiche di esposizione: Atti Certificazione valida 365 giorni (12 mesi) dalla data dell\'ultima somministrazione Certificazione valida 48 ore dall\'ora del prelievo Certificazione valida 72 ore dall\'ora del prelievo - Nessun EU Digital Covid Certificate trovato + Nessun EU Digital Covid Certificate trovato. Controlla che i dati inseriti siano corretti Conferma %s di %s Certificazione valida in Unione Europea fino alla data di fine validità e valida solo in Italia fino a 6 mesi dalla data di inizio validità + Abbiamo cambiato l\'ordine dei tuoi Certificati + Se stai leggendo questo messaggio vuol dire che hai più di un Certificato Verde COVID-19 installato sul tuo dispositivo: ora sono visualizzati in ordine cronologico a partire dal più recente. Ricordati che puoi eliminarli o spostarti da uno all\'altro scorrendo lateralmente con il dito + Ho capito + VALIDA SOLO IN ITALIA + Certificato esenzione (illimitata) + Codice fiscale del medico certificatore + Data di inizio validità della certificazione + Data di fine validità della certificazione + Codice univoco esenzione vaccinale (CUEV) + Questa certificazione è valida solo in Italia e può essere utilizzata in sostituzione della Certificazione verde COVID-19 per lo svolgimento di attività e la fruizione di servizi secondo quanto previsto dalla normativa nazionale vigente + Certificazione digitale di esenzione dalla vaccinazione anti-COVID-19 + Soggetto che ha rilasciato la certificazione digitale di esenzione + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b42d6bb0b..8ed305cc9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -530,6 +530,7 @@ Operating system: iOS 13.5.1; Model: iPhone XS; Exposure notifications: Active; Stato in cui è stato eseguito il test Stato in cui è stato eseguito primo test molecolare positivo Vaccination certificate + VALID ONLY IN ITALY Test certificate Recovery certificate Validity of the EU Digital Covid Certificate @@ -538,7 +539,7 @@ Operating system: iOS 13.5.1; Model: iPhone XS; Exposure notifications: Active; Certification valid for 365 days (12 months) from the date of the last administration Certification valid for 48 hours from the time of collection Certification valid for 72 hours from the time of collection - No EU Digital Covid Certificate found + No EU Digital Covid Certificate found. Check that the data entered is correct Ministero della Salute Test antigenico rapido Test molecolare @@ -575,5 +576,20 @@ Operating system: iOS 13.5.1; Model: iPhone XS; Exposure notifications: Active; Covaxin (also known as BBV152 A, B, C) The green COVID–19 certification is shown on the smartphone screen so that it can be viewed and shown on request, in case of verification, even in offline mode. The \"Delete\" button allows you to delete your certificate from your smartphone independently at any time. Certification valid in the European Union until the end of validity date and valid only in Italy up to 6 months from the start of validity date - + We have changed the order of your Certificates + If you are reading this message it means that you have more than one COVID-19 Green Certificate installed on your device: they are now displayed in chronological order starting with the most recent. Remember that you can delete them or move from one to the other by swiping sideways with your finger + I understand + Certificate of exemption (unlimited) + Fiscal code of the certifying physician + Codice fiscale del medico certificatore + Valid from + Data di inizio validità della certificazione + Person exempt from SARS-CoV-2 / COVID-19 vaccination + Valid until + Data di fine validità della certificazione + Unique vaccination exemption identifier + Codice univoco esenzione vaccinale (CUEV) + This certification is valid only in Italy and can be used to replace the COVID-19 green certification for carrying out activities and the use of services in accordance with the current national legislation + Digital certification of COVID-19 vaccination exemption + Soggetto che ha rilasciato la certificazione digitale di esenzione diff --git a/build.gradle b/build.gradle index 6d0a3fc15..77744dc0c 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { // App version digits versionMajor = 2 versionMinor = 5 - versionPatch = 7 + versionPatch = 8 // Version name follows the .. convention computeVersionName = { -> diff --git a/decoder1.0.0/src/main/java/dgca/verifier/app/decoder/model/Exemption.kt b/decoder1.0.0/src/main/java/dgca/verifier/app/decoder/model/Exemption.kt new file mode 100644 index 000000000..8ee548349 --- /dev/null +++ b/decoder1.0.0/src/main/java/dgca/verifier/app/decoder/model/Exemption.kt @@ -0,0 +1,30 @@ +package dgca.verifier.app.decoder.model + +import com.fasterxml.jackson.annotation.JsonProperty +import java.io.Serializable + +data class Exemption( + @JsonProperty("fc") + val fiscalCode: String, + + @JsonProperty("du") + val certificateValidUntil: String?, + + @JsonProperty("co") + val countryOfExemption: String, + + @JsonProperty("ci") + val certificateIdentifier: String, + + @JsonProperty("cu") + val uniqueVaccinationExemptionIdentifier: String, + + @JsonProperty("is") + val certificateIssuer: String, + + @JsonProperty("tg") + val disease: String, + + @JsonProperty("df") + val certificateValidFrom: String +) : Serializable diff --git a/decoder1.0.0/src/main/java/dgca/verifier/app/decoder/model/GreenCertificate.kt b/decoder1.0.0/src/main/java/dgca/verifier/app/decoder/model/GreenCertificate.kt index c895eefd4..d02208cd1 100644 --- a/decoder1.0.0/src/main/java/dgca/verifier/app/decoder/model/GreenCertificate.kt +++ b/decoder1.0.0/src/main/java/dgca/verifier/app/decoder/model/GreenCertificate.kt @@ -43,7 +43,10 @@ data class GreenCertificate( val tests: List?, @JsonProperty("r") - val recoveryStatements: List? + val recoveryStatements: List?, + + @JsonProperty("e") + val exemptions: List? ) : Serializable { @@ -53,6 +56,7 @@ data class GreenCertificate( vaccinations?.isNotEmpty() == true -> vaccinations.last().certificateIdentifier tests?.isNotEmpty() == true -> tests.last().certificateIdentifier recoveryStatements?.isNotEmpty() == true -> recoveryStatements.last().certificateIdentifier + exemptions?.isNotEmpty() == true -> exemptions.last().certificateIdentifier else -> "" } } catch (ex: Exception) { diff --git a/extensions/src/main/AndroidManifest.xml b/extensions/src/main/AndroidManifest.xml index 719c29321..1ed4e62a3 100644 --- a/extensions/src/main/AndroidManifest.xml +++ b/extensions/src/main/AndroidManifest.xml @@ -1,4 +1,11 @@ + + + + + + +