From e7f532244229356c6b5b35a85088e6fd1d04c16a Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Fri, 5 Dec 2025 15:55:45 +0100 Subject: [PATCH 01/10] feat(capture): Add creditNoteHintEnabled flag capture SDK PP-2180 --- .../android/bank/sdk/capture/Configuration.kt | 10 +++++++++- .../net/gini/android/capture/GiniCapture.java | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/bank-sdk/sdk/src/main/java/net/gini/android/bank/sdk/capture/Configuration.kt b/bank-sdk/sdk/src/main/java/net/gini/android/bank/sdk/capture/Configuration.kt index b4377e36e4..83f4a2f2cc 100644 --- a/bank-sdk/sdk/src/main/java/net/gini/android/bank/sdk/capture/Configuration.kt +++ b/bank-sdk/sdk/src/main/java/net/gini/android/bank/sdk/capture/Configuration.kt @@ -142,7 +142,7 @@ data class CaptureConfiguration( val bottomNavigationBarEnabled: Boolean = false, /** - * Enable/disable the payment hint. + * Enable/disable the already paid hint. * * On by default. */ @@ -162,6 +162,13 @@ data class CaptureConfiguration( */ val paymentDueHintThresholdDays: Int = GiniCapture.PAYMENT_DUE_HINT_THRESHOLD_DAYS, + /** + * Enable/disable the credit note hint. + * + * On by default. + */ + val creditNoteHintEnabled: Boolean = true, + /** * Set an adapter implementation to show a custom bottom navigation bar on the onboarding screen. */ @@ -276,6 +283,7 @@ internal fun GiniCapture.Builder.applyConfiguration(configuration: CaptureConfig .setAlreadyPaidHintEnabled(configuration.alreadyPaidHintEnabled) .setPaymentDueHintEnabled(configuration.paymentDueHintEnabled) .setPaymentDueHintThresholdDays(configuration.paymentDueHintThresholdDays) + .setCreditNoteHintEnabled(configuration.creditNoteHintEnabled) .setEntryPoint(configuration.entryPoint) .setAllowScreenshots(configuration.allowScreenshots) .setSaveInvoicesLocallyEnabled(configuration.saveInvoicesLocallyEnabled) diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/GiniCapture.java b/capture-sdk/sdk/src/main/java/net/gini/android/capture/GiniCapture.java index e6ba9decdd..ce4e9342a0 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/GiniCapture.java +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/GiniCapture.java @@ -124,6 +124,7 @@ public class GiniCapture { private final boolean isAlreadyPaidHintEnabled; private final boolean isPaymentDueHintEnabled; private final int paymentDueHintThresholdDays; + private final boolean isCreditNoteHintEnabled; private final InjectedViewAdapterInstance onboardingAlignCornersIllustrationAdapterInstance; private final InjectedViewAdapterInstance onboardingLightingIllustrationAdapterInstance; private final InjectedViewAdapterInstance onboardingMultiPageIllustrationAdapterInstance; @@ -435,6 +436,7 @@ private GiniCapture(@NonNull final Builder builder) { isAlreadyPaidHintEnabled = builder.isAlreadyPaidHintEnabled(); isPaymentDueHintEnabled = builder.isPaymentDueHintEnabled(); paymentDueHintThresholdDays = builder.getPaymentDueHintThresholdDays(); + isCreditNoteHintEnabled = builder.isCreditNoteHintEnabled(); onboardingAlignCornersIllustrationAdapterInstance = builder.getOnboardingAlignCornersIllustrationAdapterInstance(); onboardingLightingIllustrationAdapterInstance = builder.getOnboardingLightingIllustrationAdapterInstance(); onboardingMultiPageIllustrationAdapterInstance = builder.getOnboardingMultiPageIllustrationAdapterInstance(); @@ -736,6 +738,10 @@ public int getPaymentDueHintThresholdDays() { return paymentDueHintThresholdDays; } + public boolean isCreditNoteHintEnabled() { + return isCreditNoteHintEnabled; + } + @Nullable public OnboardingIllustrationAdapter getOnboardingAlignCornersIllustrationAdapter() { if (onboardingAlignCornersIllustrationAdapterInstance == null) { @@ -942,6 +948,7 @@ public void onAnalysisScreenEvent(@NotNull final Event even private boolean isAlreadyPaidHintEnabled = true; private boolean isPaymentDueHintEnabled = true; private int paymentDueHintThresholdDays = PAYMENT_DUE_HINT_THRESHOLD_DAYS; + private boolean isCreditNoteHintEnabled = true; private InjectedViewAdapterInstance onboardingAlignCornersIllustrationAdapterInstance; private InjectedViewAdapterInstance onboardingLightingIllustrationAdapterInstance; private InjectedViewAdapterInstance onboardingMultiPageIllustrationAdapterInstance; @@ -1378,6 +1385,11 @@ public Builder setPaymentDueHintThresholdDays(final int thresholdDays){ return this; } + public Builder setCreditNoteHintEnabled(final Boolean enabled){ + isCreditNoteHintEnabled = enabled; + return this; + } + private boolean isBottomNavigationBarEnabled() { return isBottomNavigationBarEnabled; } @@ -1394,6 +1406,10 @@ private int getPaymentDueHintThresholdDays(){ return paymentDueHintThresholdDays; } + private boolean isCreditNoteHintEnabled(){ + return isCreditNoteHintEnabled; + } + @NonNull private InjectedViewAdapterInstance getOnboardingAlignCornersIllustrationAdapterInstance() { return onboardingAlignCornersIllustrationAdapterInstance; From 1fedd82b502c0667574a8077df7dc9cc99d34cf5 Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Fri, 5 Dec 2025 16:04:59 +0100 Subject: [PATCH 02/10] feat(bank-sdk): Add credit note hint toggle in example app PP-2180 --- .../bank/sdk/exampleapp/ui/ConfigurationActivity.kt | 12 ++++++++++++ .../bank/sdk/exampleapp/ui/ConfigurationViewModel.kt | 4 +++- .../ui/data/ExampleAppBankConfiguration.kt | 4 ++++ .../src/main/res/layout/layout_feature_toggles.xml | 8 +++++++- bank-sdk/example-app/src/main/res/values/strings.xml | 1 + 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationActivity.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationActivity.kt index d587165791..fa20dd8791 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationActivity.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationActivity.kt @@ -240,6 +240,10 @@ class ConfigurationActivity : AppCompatActivity() { binding.layoutFeatureToggle.editTextPaymentDueHintThresholdDays.hint = configuration.paymentDueHintThresholdDays.toString() + // enable credit note hint + binding.layoutFeatureToggle.switchCreditNoteHint.isChecked = + configuration.isCreditNoteHintEnabled + // enable return reasons dialog binding.layoutReturnAssistantToggles.switchReturnReasonsDialog.isChecked = configuration.isReturnReasonsEnabled @@ -602,6 +606,14 @@ class ConfigurationActivity : AppCompatActivity() { } } + //enable credit note hint for showing warning + binding.layoutFeatureToggle.switchCreditNoteHint.setOnCheckedChangeListener{ _, isChecked -> + configurationViewModel.setConfiguration( + configurationViewModel.configurationFlow.value.copy( + isCreditNoteHintEnabled = isChecked + ) + ) + } // enable supported format help screen binding.layoutHelpToggles.switchSupportedFormatsScreen.setOnCheckedChangeListener { _, isChecked -> diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationViewModel.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationViewModel.kt index abd64b6ca3..ad237113f1 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationViewModel.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationViewModel.kt @@ -121,12 +121,14 @@ class ConfigurationViewModel @Inject constructor( documentImportEnabledFileTypes = configuration.documentImportEnabledFileTypes, // enable bottom navigation bar bottomNavigationBarEnabled = configuration.isBottomNavigationBarEnabled, - // enable payment hints + // enable already paid hint alreadyPaidHintEnabled = configuration.isAlreadyPaidHintEnabled, // enable payment due hint paymentDueHintEnabled = configuration.isPaymentDueHintEnabled, // set payment due hint threshold days paymentDueHintThresholdDays = configuration.paymentDueHintThresholdDays, + // enable credit note hint + creditNoteHintEnabled = configuration.isCreditNoteHintEnabled, // enable onboarding screens at first launch showOnboardingAtFirstRun = configuration.isOnboardingAtFirstRunEnabled, // enable onboarding at every launch diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/ExampleAppBankConfiguration.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/ExampleAppBankConfiguration.kt index be39fb6646..4a8df874f1 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/ExampleAppBankConfiguration.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/ExampleAppBankConfiguration.kt @@ -161,6 +161,9 @@ data class ExampleAppBankConfiguration( // payment due hint threshold days val paymentDueHintThresholdDays: Int = GiniCapture.PAYMENT_DUE_HINT_THRESHOLD_DAYS, + // enable credit note hint + val isCreditNoteHintEnabled: Boolean = true, + // Digital invoice onboarding custom illustration val isDigitalInvoiceOnboardingCustomIllustrationEnabled: Boolean = false, @@ -219,6 +222,7 @@ data class ExampleAppBankConfiguration( isAlreadyPaidHintEnabled = defaultCaptureConfiguration.alreadyPaidHintEnabled, isPaymentDueHintEnabled = defaultCaptureConfiguration.paymentDueHintEnabled, paymentDueHintThresholdDays = defaultCaptureConfiguration.paymentDueHintThresholdDays, + isCreditNoteHintEnabled = defaultCaptureConfiguration.creditNoteHintEnabled, isOnboardingAtFirstRunEnabled = defaultCaptureConfiguration.showOnboardingAtFirstRun, isOnboardingAtEveryLaunchEnabled = defaultCaptureConfiguration.showOnboarding, isSupportedFormatsHelpScreenEnabled = defaultCaptureConfiguration.supportedFormatsHelpScreenEnabled, diff --git a/bank-sdk/example-app/src/main/res/layout/layout_feature_toggles.xml b/bank-sdk/example-app/src/main/res/layout/layout_feature_toggles.xml index 6fcb09ceb3..a802e0c1ce 100644 --- a/bank-sdk/example-app/src/main/res/layout/layout_feature_toggles.xml +++ b/bank-sdk/example-app/src/main/res/layout/layout_feature_toggles.xml @@ -204,5 +204,11 @@ tools:text="Hello@World and stuff and foo and bar and whatchamacallit" /> - + + diff --git a/bank-sdk/example-app/src/main/res/values/strings.xml b/bank-sdk/example-app/src/main/res/values/strings.xml index 707972b722..7f2c8fd15c 100644 --- a/bank-sdk/example-app/src/main/res/values/strings.xml +++ b/bank-sdk/example-app/src/main/res/values/strings.xml @@ -62,6 +62,7 @@ Already Paid Hint Payment Due Hint Payment Due Hint Threshold Days + Credit Note Hint Open with QR code scanning QR code scanning only From ae80e6805121ee1257888b6425ea671e9ecdb6f0 Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Fri, 5 Dec 2025 16:37:00 +0100 Subject: [PATCH 03/10] feat(capture-sdk): Add creditNoteHint client side flag PP-2180 --- .../net/gini/android/bank/api/models/Configuration.kt | 1 + .../android/bank/api/response/ConfigurationResponse.kt | 2 ++ .../network/GiniCaptureDefaultNetworkService.kt | 3 ++- .../analysis/AnalysisScreenPresenterExtension.kt | 4 ++++ .../net/gini/android/capture/di/paymentHintsModule.kt | 7 +++++++ .../android/capture/internal/network/Configuration.kt | 1 + .../internal/provider/GiniBankConfigurationProvider.kt | 3 ++- .../paymentHints/GetCreditNoteHintEnabledUseCase.kt | 10 ++++++++++ 8 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 capture-sdk/sdk/src/main/java/net/gini/android/capture/paymentHints/GetCreditNoteHintEnabledUseCase.kt diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/Configuration.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/Configuration.kt index 84fad64323..8661b0698b 100644 --- a/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/Configuration.kt +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/Configuration.kt @@ -13,4 +13,5 @@ data class Configuration( val isSavePhotosLocallyEnabled: Boolean, val isAlreadyPaidHintEnabled: Boolean, val isPaymentDueHintEnabled: Boolean, + val isCreditNoteHintEnabled: Boolean, ) diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/response/ConfigurationResponse.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/response/ConfigurationResponse.kt index d5fbf2656c..009fae626e 100644 --- a/bank-api-library/library/src/main/java/net/gini/android/bank/api/response/ConfigurationResponse.kt +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/response/ConfigurationResponse.kt @@ -18,6 +18,7 @@ data class ConfigurationResponse( @Json(name = "alreadyPaidHintEnabled") val alreadyPaidHintEnabled: Boolean?, @Json(name = "paymentDueHintEnabled") val paymentDueHintEnabled: Boolean?, @Json(name = "savePhotosLocallyEnabled") val savePhotosLocallyEnabled: Boolean?, + @Json(name = "creditNoteHintEnabled") val creditNoteHintEnabled: Boolean?, ) internal fun ConfigurationResponse.toConfiguration() = Configuration( @@ -33,5 +34,6 @@ internal fun ConfigurationResponse.toConfiguration() = Configuration( isAlreadyPaidHintEnabled = alreadyPaidHintEnabled ?: false, isPaymentDueHintEnabled = paymentDueHintEnabled ?: false, isSavePhotosLocallyEnabled = savePhotosLocallyEnabled ?: false, + isCreditNoteHintEnabled = creditNoteHintEnabled ?: false, ) diff --git a/capture-sdk/default-network/src/main/java/net/gini/android/capture/network/GiniCaptureDefaultNetworkService.kt b/capture-sdk/default-network/src/main/java/net/gini/android/capture/network/GiniCaptureDefaultNetworkService.kt index a9835aa72e..5bb0ad540b 100644 --- a/capture-sdk/default-network/src/main/java/net/gini/android/capture/network/GiniCaptureDefaultNetworkService.kt +++ b/capture-sdk/default-network/src/main/java/net/gini/android/capture/network/GiniCaptureDefaultNetworkService.kt @@ -206,7 +206,8 @@ internal constructor( isPaymentDueHintEnabled = configuration.isPaymentDueHintEnabled, isEInvoiceEnabled = configuration.isEInvoiceEnabled, amplitudeApiKey = configuration.amplitudeApiKey ?: "", - isSavePhotosLocallyEnabled = configuration.isSavePhotosLocallyEnabled + isSavePhotosLocallyEnabled = configuration.isSavePhotosLocallyEnabled, + isCreditNoteHintEnabled = configuration.isCreditNoteHintEnabled, ) @Suppress("LongMethod") diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenterExtension.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenterExtension.kt index fcdd354aa1..dcf9f753c0 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenterExtension.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenterExtension.kt @@ -30,6 +30,7 @@ import net.gini.android.capture.network.model.GiniCaptureCompoundExtraction import net.gini.android.capture.network.model.GiniCaptureReturnReason import net.gini.android.capture.network.model.GiniCaptureSpecificExtraction import net.gini.android.capture.paymentHints.GetAlreadyPaidHintEnabledUseCase +import net.gini.android.capture.paymentHints.GetCreditNoteHintEnabledUseCase import net.gini.android.capture.paymentHints.GetPaymentDueHintEnabledUseCase import net.gini.android.capture.tracking.AnalysisScreenEvent import net.gini.android.capture.tracking.EventTrackingHelper @@ -48,6 +49,9 @@ internal class AnalysisScreenPresenterExtension( val paymentDueHintEnabledUseCase: GetPaymentDueHintEnabledUseCase by getGiniCaptureKoin().inject() + val creditNoteHintEnabledUseCase: + GetCreditNoteHintEnabledUseCase by getGiniCaptureKoin().inject() + val lastAnalyzedDocumentProvider: LastAnalyzedDocumentProvider by getGiniCaptureKoin().inject() diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/di/paymentHintsModule.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/di/paymentHintsModule.kt index 247bc46f59..269c69e42a 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/di/paymentHintsModule.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/di/paymentHintsModule.kt @@ -1,6 +1,7 @@ package net.gini.android.capture.di import net.gini.android.capture.paymentHints.GetAlreadyPaidHintEnabledUseCase +import net.gini.android.capture.paymentHints.GetCreditNoteHintEnabledUseCase import net.gini.android.capture.paymentHints.GetPaymentDueHintEnabledUseCase import org.koin.dsl.module @@ -18,4 +19,10 @@ internal val paymentHintsModule = module { ) } + factory { + GetCreditNoteHintEnabledUseCase( + giniBankConfigurationProvider = get(), + ) + } + } diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/network/Configuration.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/network/Configuration.kt index f50fc6ddc2..2c1448c7e4 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/network/Configuration.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/network/Configuration.kt @@ -16,4 +16,5 @@ data class Configuration( val isSavePhotosLocallyEnabled: Boolean, val isAlreadyPaidHintEnabled: Boolean, val isPaymentDueHintEnabled: Boolean, + val isCreditNoteHintEnabled: Boolean, ) diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/provider/GiniBankConfigurationProvider.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/provider/GiniBankConfigurationProvider.kt index 1ebd784831..4b36cd8bfe 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/provider/GiniBankConfigurationProvider.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/provider/GiniBankConfigurationProvider.kt @@ -16,7 +16,8 @@ class GiniBankConfigurationProvider { isEInvoiceEnabled = false, isSavePhotosLocallyEnabled = false, isAlreadyPaidHintEnabled = false, - isPaymentDueHintEnabled = false + isPaymentDueHintEnabled = false, + isCreditNoteHintEnabled = false, ) fun provide(): Configuration = configuration diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/paymentHints/GetCreditNoteHintEnabledUseCase.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/paymentHints/GetCreditNoteHintEnabledUseCase.kt new file mode 100644 index 0000000000..3b61b6eb29 --- /dev/null +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/paymentHints/GetCreditNoteHintEnabledUseCase.kt @@ -0,0 +1,10 @@ +package net.gini.android.capture.paymentHints + +import net.gini.android.capture.internal.provider.GiniBankConfigurationProvider + +class GetCreditNoteHintEnabledUseCase( + private val giniBankConfigurationProvider: GiniBankConfigurationProvider, +) { + operator fun invoke() = giniBankConfigurationProvider.provide().isCreditNoteHintEnabled + +} \ No newline at end of file From 87b4ae95b7bce9f1264bc9fa32bbed9ccb7fb35b Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Thu, 11 Dec 2025 14:51:11 +0100 Subject: [PATCH 04/10] feat(capture-sdk): Add credit notes to WarningType enum PP-2180 --- .../analysis/warning/WarningBottomSheet.kt | 24 ++++++++----- .../capture/analysis/warning/WarningType.java | 33 +++++++++++++---- .../src/main/res/drawable/gc_warning_icon.xml | 13 +++++++ .../layout-land/gc_warning_bottom_sheet.xml | 20 ++++++----- .../gc_warning_bottom_sheet.xml | 22 ++++++------ .../gc_warning_bottom_sheet.xml | 22 ++++++------ .../res/layout/gc_warning_bottom_sheet.xml | 36 +++++++++---------- .../sdk/src/main/res/values-en/strings.xml | 6 ++-- .../sdk/src/main/res/values/strings.xml | 6 ++-- 9 files changed, 115 insertions(+), 67 deletions(-) create mode 100644 capture-sdk/sdk/src/main/res/drawable/gc_warning_icon.xml diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningBottomSheet.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningBottomSheet.kt index 0b24ee10cd..932b4cc3ba 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningBottomSheet.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningBottomSheet.kt @@ -39,6 +39,7 @@ class WarningBottomSheet : BottomSheetDialogFragment() { private var titleText: CharSequence? = null private var descText: CharSequence? = null + private var icon: Int? = null var listener: Listener? = null @@ -54,6 +55,7 @@ class WarningBottomSheet : BottomSheetDialogFragment() { if (type != null) { titleText = getString(type.titleRes) descText = getString(type.descriptionRes) + icon = type.iconRes } } @@ -135,9 +137,11 @@ class WarningBottomSheet : BottomSheetDialogFragment() { BottomSheetBehavior.STATE_COLLAPSED -> { state = BottomSheetBehavior.STATE_EXPANDED } + BottomSheetBehavior.STATE_HIDDEN -> { state = BottomSheetBehavior.STATE_EXPANDED } + else -> Unit } } @@ -149,11 +153,13 @@ class WarningBottomSheet : BottomSheetDialogFragment() { } } } + override fun onStart() { super.onStart() if (!resources.getBoolean(R.bool.gc_is_tablet) && - resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) { + resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + ) { val bottomSheet = (dialog as? BottomSheetDialog) ?.findViewById(com.google.android.material.R.id.design_bottom_sheet) @@ -171,26 +177,28 @@ class WarningBottomSheet : BottomSheetDialogFragment() { } private fun bindUi() { - binding.warningTitle.text = titleText - binding.warningDescription.text = descText + binding.gcWarningTitleWarningBottomSheet.text = titleText + binding.gcWarningDescriptionWarningBottomSheet.text = descText + icon?.let { binding.gcWarningIconWarningBottomSheet?.setBackgroundResource(it) } - binding.warningIcon?.contentDescription = getString(R.string.gc_warning_icon_content_description) - binding.warningIcon?.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES + binding.gcWarningIconWarningBottomSheet?.contentDescription = + getString(R.string.gc_warning_icon_content_description) + binding.gcWarningIconWarningBottomSheet?.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES - binding.cancelButton.setOnClickListener { + binding.gcCancelButtonWarningBottomSheet.setOnClickListener { listener?.onCancelAction() dismissAllowingStateLoss() } - binding.proceedButton.setOnClickListener { + binding.gcProceedButtonWarningBottomSheet.setOnClickListener { listener?.onProceedAction() dismissAllowingStateLoss() } } - companion object { private const val ARG_TYPE = "arg_type" + @JvmStatic fun newInstance(type: WarningType) = WarningBottomSheet().apply { arguments = Bundle().apply { diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningType.java b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningType.java index 3cb50ccc2c..3838b712d8 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningType.java +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningType.java @@ -1,5 +1,6 @@ package net.gini.android.capture.analysis.warning; +import androidx.annotation.DrawableRes; import androidx.annotation.StringRes; import net.gini.android.capture.R; @@ -13,16 +14,36 @@ public enum WarningType { DOCUMENT_MARKED_AS_PAID( R.string.gc_document_marked_paid_title, - R.string.gc_document_marked_paid_desc + R.string.gc_document_marked_paid_desc, + R.drawable.gc_bg_warning_circle + ), DOCUMENT_MARKED_AS_CREDIT_NOTE( + R.string.gc_document_marked_credit_note_title, + R.string.gc_document_marked_credit_note_desc, + R.drawable.gc_warning_icon ); - @StringRes private final int titleRes; - @StringRes private final int descriptionRes; + @StringRes + private final int titleRes; + @StringRes + private final int descriptionRes; + @DrawableRes + private final int iconRes; - WarningType(@StringRes int titleRes, @StringRes int descriptionRes) { + WarningType(@StringRes int titleRes, @StringRes int descriptionRes, @DrawableRes int iconRes) { this.titleRes = titleRes; this.descriptionRes = descriptionRes; + this.iconRes = iconRes; + } + + public int getTitleRes() { + return titleRes; + } + + public int getDescriptionRes() { + return descriptionRes; + } + + public int getIconRes() { + return iconRes; } - public int getTitleRes() { return titleRes; } - public int getDescriptionRes() { return descriptionRes; } } diff --git a/capture-sdk/sdk/src/main/res/drawable/gc_warning_icon.xml b/capture-sdk/sdk/src/main/res/drawable/gc_warning_icon.xml new file mode 100644 index 0000000000..d5dfce48ee --- /dev/null +++ b/capture-sdk/sdk/src/main/res/drawable/gc_warning_icon.xml @@ -0,0 +1,13 @@ + + + + diff --git a/capture-sdk/sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml b/capture-sdk/sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml index c1add9286e..4c3da576a9 100644 --- a/capture-sdk/sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml +++ b/capture-sdk/sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml @@ -27,7 +27,7 @@ android:padding="@dimen/gc_large"> + android:layout_marginStart="@dimen/gc_large" + android:text="@string/gc_proceed_anyway" /> + android:text="@string/gc_cancel_transfer" /> + + diff --git a/capture-sdk/sdk/src/main/res/layout-sw600dp-land/gc_warning_bottom_sheet.xml b/capture-sdk/sdk/src/main/res/layout-sw600dp-land/gc_warning_bottom_sheet.xml index 4f56661011..0958a0d9fe 100644 --- a/capture-sdk/sdk/src/main/res/layout-sw600dp-land/gc_warning_bottom_sheet.xml +++ b/capture-sdk/sdk/src/main/res/layout-sw600dp-land/gc_warning_bottom_sheet.xml @@ -15,7 +15,7 @@ android:padding="@dimen/gc_large"> + app:layout_constraintEnd_toEndOf="@+id/gc_textScroll_warningBottomSheet" + app:layout_constraintStart_toStartOf="@+id/gc_textScroll_warningBottomSheet" + app:layout_constraintTop_toBottomOf="@+id/gc_warningIcon_warningBottomSheet"> + app:layout_constraintEnd_toEndOf="@+id/gc_textScroll_warningBottomSheet" + app:layout_constraintStart_toStartOf="@+id/gc_textScroll_warningBottomSheet" + app:layout_constraintTop_toBottomOf="@+id/gc_warningIcon_warningBottomSheet"> + /> @@ -49,10 +48,10 @@ android:orientation="vertical" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/warningIcon"> + app:layout_constraintTop_toBottomOf="@+id/gc_warningIcon_warningBottomSheet"> + android:layout_marginTop="@dimen/gc_medium" + android:text="@string/gc_proceed_anyway" /> + android:text="@string/gc_cancel_transfer" /> + diff --git a/capture-sdk/sdk/src/main/res/values-en/strings.xml b/capture-sdk/sdk/src/main/res/values-en/strings.xml index c61e242bf9..9157c33812 100644 --- a/capture-sdk/sdk/src/main/res/values-en/strings.xml +++ b/capture-sdk/sdk/src/main/res/values-en/strings.xml @@ -180,10 +180,12 @@ - Cancel Transfer - Proceed Anyway + Cancel transfer + Proceed anyway Document marked as paid This document states that it has already been paid. Please check the note in the document to be sure. + Credit Note Warning + It seems you submitted a credit note instead of a regular invoice. You might want to check your document mentioning “Gutschrift” or if the amount is negative. Warning Dialog Warning icon diff --git a/capture-sdk/sdk/src/main/res/values/strings.xml b/capture-sdk/sdk/src/main/res/values/strings.xml index 482e8d038f..fc69352f8f 100644 --- a/capture-sdk/sdk/src/main/res/values/strings.xml +++ b/capture-sdk/sdk/src/main/res/values/strings.xml @@ -198,12 +198,14 @@ analyse der Rechnung läuft - Überweisung Abbrechen - Trotzdem Fortfahren + Überweisung abbrechen + Trotzdem fortfahren Dokument als bezahlt gekennzeichnet Auf diesem Dokument steht, dass es bereits bezahlt wurde. Bitte prüfen Sie den Hinweis in dem Dokument, um sicherzugehen. + Achtung: Gutschrift hochgeladen + Anscheinend haben Sie eine Gutschrift statt einer Rechnung hochgeladen. Bitte überprüfen Sie Ihr Dokument auf den Begriff „Gutschrift“ oder ob der Betrag negativ ist. Warndialog Warnsymbol From 5b59d1bc843bec504b9bd09f32c74e398ca73e50 Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Mon, 15 Dec 2025 16:47:25 +0100 Subject: [PATCH 05/10] feat(capture-sdk): Add logic for credit note warning hint PP-2180 --- .../analysis/AnalysisFragmentImpl.java | 9 +++-- .../analysis/AnalysisScreenContract.java | 1 + .../analysis/AnalysisScreenPresenter.java | 34 +++++++++++++++++++ .../AnalysisScreenPresenterExtension.kt | 30 ++++++++++++++++ .../analysis/warning/BusinessDocType.kt | 33 ++++++++++++++++++ 5 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/BusinessDocType.kt diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisFragmentImpl.java b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisFragmentImpl.java index 5f7f6732e8..cc81e405f3 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisFragmentImpl.java +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisFragmentImpl.java @@ -1,8 +1,5 @@ package net.gini.android.capture.analysis; -import static net.gini.android.capture.tracking.EventTrackingHelper.trackAnalysisScreenEvent; -import static net.gini.android.capture.util.SharedPreferenceHelper.SAF_STORAGE_URI_KEY; - import android.app.Activity; import android.content.Context; import android.content.DialogInterface; @@ -68,6 +65,7 @@ import kotlin.Unit; import static net.gini.android.capture.tracking.EventTrackingHelper.trackAnalysisScreenEvent; +import static net.gini.android.capture.util.SharedPreferenceHelper.SAF_STORAGE_URI_KEY; /** * Main logic implementation for analysis UI presented by {@link AnalysisFragment} @@ -352,6 +350,11 @@ void showAlreadyPaidWarning(@NonNull WarningType warningType, @NonNull Runnable mFragment.showWarning(warningType, onProceed); } + @Override + void showCreditNoteWarning(@NonNull WarningType warningType, @NonNull Runnable onProceed) { + mFragment.showWarning(warningType, onProceed); + } + @Override void showPaymentDueHint(PaymentDueHintDismissListener listener, String dueDate) { fragmentExtension.showPaymentDueHint(() -> { diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenContract.java b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenContract.java index da550cf7e8..60fc2460df 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenContract.java +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenContract.java @@ -67,6 +67,7 @@ abstract void showAlertDialog(@NonNull final String message, abstract void showError(String errorMessage, Document document); abstract void showAlreadyPaidWarning(@NonNull WarningType warningType, @NonNull Runnable onProceed); + abstract void showCreditNoteWarning(@NonNull WarningType warningType, @NonNull Runnable onProceed); abstract void showPaymentDueHint(PaymentDueHintDismissListener listener, String dueDate); abstract void showError(ErrorType errorType, Document document); diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenter.java b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenter.java index c2c1171b75..1f777693bc 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenter.java +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenter.java @@ -12,6 +12,7 @@ import net.gini.android.capture.Document; import net.gini.android.capture.GiniCapture; import net.gini.android.capture.GiniCaptureError; +import net.gini.android.capture.analysis.warning.BusinessDocType; import net.gini.android.capture.analysis.warning.WarningPaymentState; import net.gini.android.capture.document.DocumentFactory; import net.gini.android.capture.document.GiniCaptureDocument; @@ -66,6 +67,7 @@ class AnalysisScreenPresenter extends AnalysisScreenContract.Presenter { private static final String EXTRACTION_PAYMENT_STATE = "paymentState"; private static final String EXTRACTION_PAYMENT_DUE_DATE = "paymentDueDate"; + private static final String EXTRACTION_BUSINESS_DOC_TYPE = "businessDocType"; private static final Logger LOG = LoggerFactory.getLogger(AnalysisScreenPresenter.class); @@ -349,6 +351,14 @@ public Void apply(final AnalysisInteractor.ResultHolder resultHolder, isSavingInvoicesInProgress, successResultHolder, getActivity()); + } else if (shouldShowCreditNoteWarning(resultHolder)) { + successResultHolder = resultHolder; + shouldClearImageCaches = false; + extension.showCreditNoteHint( + mIsInvoiceSavingEnabled, + isSavingInvoicesInProgress, + successResultHolder, + getActivity()); } else if (shouldShowPaymentDueHint(resultHolder)) { successResultHolder = resultHolder; shouldClearImageCaches = false; @@ -573,6 +583,22 @@ private boolean shouldShowAlreadyPaidInvoiceWarning( return state.isPaid(); } + private boolean shouldShowCreditNoteWarning( + @NonNull final AnalysisInteractor.ResultHolder resultHolder) { + // Feature flags / config + final boolean creditNoteHintClientFlagEnabled = extension.getCreditNoteHintEnabledUseCase().invoke(); + + final boolean creditNoteHintSDKFlag = GiniCapture.hasInstance() && GiniCapture.getInstance().isCreditNoteHintEnabled(); + + if (!creditNoteHintClientFlagEnabled || !creditNoteHintSDKFlag) { + return false; + } + + // business doc type + final BusinessDocType businessDocType = extractBusinessDocType(resultHolder.getExtractions()); + return businessDocType.isCreditNote(); + } + private boolean shouldShowPaymentDueHint( @NonNull final AnalysisInteractor.ResultHolder resultHolder) { @@ -633,4 +659,12 @@ private WarningPaymentState extractPaymentState( return WarningPaymentState.from(paymentStateValue); } + // extracts the business doc type from extractions + private BusinessDocType extractBusinessDocType( + @NonNull final Map extractions) { + final GiniCaptureSpecificExtraction businessDocTypeExtraction = extractions.get(EXTRACTION_BUSINESS_DOC_TYPE); + final String paymentStateValue = businessDocTypeExtraction != null ? businessDocTypeExtraction.getValue() : null; + return BusinessDocType.from(paymentStateValue); + } + } diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenterExtension.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenterExtension.kt index dcf9f753c0..a91c043792 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenterExtension.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenterExtension.kt @@ -177,6 +177,36 @@ internal class AnalysisScreenPresenterExtension( } } + fun showCreditNoteHint( + mIsInvoiceSavingEnabled: Boolean, + isSavingInvoicesInProgress: Boolean, + resultHolder: ResultHolder, + activity: Activity + ) { + if (isSavingInvoicesInProgress) { + handleSaveInvoicesLocally( + mIsInvoiceSavingEnabled, + true, + resultHolder, + activity + ) + } else { + doWhenEducationFinished { + view.showCreditNoteWarning( + WarningType.DOCUMENT_MARKED_AS_CREDIT_NOTE + ) { + handleSaveInvoicesLocally( + mIsInvoiceSavingEnabled, + false, + resultHolder, + activity + ) + } + } + } + } + + private fun handleSaveInvoicesLocally( mIsInvoiceSavingEnabled: Boolean, isSavingInvoicesInProgress: Boolean, diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/BusinessDocType.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/BusinessDocType.kt new file mode 100644 index 0000000000..1f3961dba4 --- /dev/null +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/BusinessDocType.kt @@ -0,0 +1,33 @@ +package net.gini.android.capture.analysis.warning + +/** + * Represents the type of a business document, such as a credit note. + * + * Responsibilities: + * - Encapsulates the supported business document types relevant to the app + * (CREDIT_NOTE, UNKNOWN). + * - Provides a safe conversion from raw string values (via [from]) into one of the enum constants, + * handling nulls and unexpected values gracefully. + * - Offers convenience methods (e.g. [isCreditNote]) to simplify conditional checks in presenters or views. + */ +enum class BusinessDocType { + CREDIT_NOTE, UNKNOWN; + + companion object { + @JvmStatic + fun from(raw: String?): BusinessDocType { + return when (raw?.trim()) { + "CreditNote" -> CREDIT_NOTE + else -> UNKNOWN + } + } + } + + /** + * Checks if the business doc type indicates that the document is a credit note. + * + * @return true if the business doc type is [CREDIT_NOTE], false otherwise. + */ + fun isCreditNote(): Boolean = this == CREDIT_NOTE + +} \ No newline at end of file From b5d9249afc2fcd33b9935f7d799f5150f5277317 Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Mon, 15 Dec 2025 17:45:44 +0100 Subject: [PATCH 06/10] feat(capture-sdk): Remove amountToPay from credit note extractions PP-2180 --- .../analysis/AnalysisScreenPresenter.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenter.java b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenter.java index 1f777693bc..b3bf8b2136 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenter.java +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/AnalysisScreenPresenter.java @@ -39,6 +39,7 @@ import java.time.LocalDate; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -352,7 +353,7 @@ public Void apply(final AnalysisInteractor.ResultHolder resultHolder, successResultHolder, getActivity()); } else if (shouldShowCreditNoteWarning(resultHolder)) { - successResultHolder = resultHolder; + successResultHolder = removeAmountToPay(resultHolder); shouldClearImageCaches = false; extension.showCreditNoteHint( mIsInvoiceSavingEnabled, @@ -667,4 +668,19 @@ private BusinessDocType extractBusinessDocType( return BusinessDocType.from(paymentStateValue); } + private AnalysisInteractor.ResultHolder removeAmountToPay(@NonNull final AnalysisInteractor.ResultHolder resultHolder) { + Map extractions = new HashMap<>(resultHolder.getExtractions()); + extractions.remove("amountToPay"); + return new AnalysisInteractor.ResultHolder( + resultHolder.getResult(), + extractions, + new HashMap<>(), + new ArrayList<>(), + resultHolder.getDocumentId(), + resultHolder.getDocumentFileName() + ); + + + } + } From a3fc015af18e5562e6ef5d1258d481e844a190ea Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Thu, 18 Dec 2025 10:50:39 +0100 Subject: [PATCH 07/10] feat(capture-sdk): Add margins between bottom sheet buttons in landscape mode PP-2180 --- .../sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/capture-sdk/sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml b/capture-sdk/sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml index 4c3da576a9..ccac664efb 100644 --- a/capture-sdk/sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml +++ b/capture-sdk/sdk/src/main/res/layout-land/gc_warning_bottom_sheet.xml @@ -62,6 +62,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginStart="@dimen/gc_large" + android:layout_marginEnd="@dimen/gc_small" android:text="@string/gc_proceed_anyway" /> From b0a96fe0ba7ee6a4143d8eb55e13a34313d13b39 Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Thu, 18 Dec 2025 11:53:57 +0100 Subject: [PATCH 08/10] feat(capture-sdk): Add credit note hint configuration flag to tests PP-2180 --- .../capture/network/GiniCaptureDefaultNetworkServiceTest.kt | 3 ++- .../android/capture/ginicapture/GiniCaptureFragmentTest.kt | 3 ++- .../gini/android/capture/analysis/warning/BusinessDocType.kt | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/capture-sdk/default-network/src/test/java/net/gini/android/capture/network/GiniCaptureDefaultNetworkServiceTest.kt b/capture-sdk/default-network/src/test/java/net/gini/android/capture/network/GiniCaptureDefaultNetworkServiceTest.kt index c302391817..363c0ea4f7 100644 --- a/capture-sdk/default-network/src/test/java/net/gini/android/capture/network/GiniCaptureDefaultNetworkServiceTest.kt +++ b/capture-sdk/default-network/src/test/java/net/gini/android/capture/network/GiniCaptureDefaultNetworkServiceTest.kt @@ -130,7 +130,8 @@ class GiniCaptureDefaultNetworkServiceTest { isQrCodeEducationEnabled = true, isSavePhotosLocallyEnabled = true, isAlreadyPaidHintEnabled = true, - isPaymentDueHintEnabled = true + isPaymentDueHintEnabled = true, + isCreditNoteHintEnabled = true ) // Add more stubs if mapBankConfigurationToConfiguration uses other properties diff --git a/capture-sdk/sdk/src/androidTest/java/net/gini/android/capture/ginicapture/GiniCaptureFragmentTest.kt b/capture-sdk/sdk/src/androidTest/java/net/gini/android/capture/ginicapture/GiniCaptureFragmentTest.kt index a6e36fb97c..7cf02668b1 100644 --- a/capture-sdk/sdk/src/androidTest/java/net/gini/android/capture/ginicapture/GiniCaptureFragmentTest.kt +++ b/capture-sdk/sdk/src/androidTest/java/net/gini/android/capture/ginicapture/GiniCaptureFragmentTest.kt @@ -196,7 +196,8 @@ class GiniCaptureFragmentTest { amplitudeApiKey = TEST_API_KEY, isSavePhotosLocallyEnabled = savePhotosLocallyEnabled, isPaymentDueHintEnabled = false, - isAlreadyPaidHintEnabled = false + isAlreadyPaidHintEnabled = false, + isCreditNoteHintEnabled = false ) return ConfigurationNetworkResult(testConfig, UUID.randomUUID()) diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/BusinessDocType.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/BusinessDocType.kt index 1f3961dba4..f811667f63 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/BusinessDocType.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/BusinessDocType.kt @@ -30,4 +30,4 @@ enum class BusinessDocType { */ fun isCreditNote(): Boolean = this == CREDIT_NOTE -} \ No newline at end of file +} From 810557b476d87e0a76d82dbbab0b37d8802d2a5b Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Thu, 18 Dec 2025 12:57:58 +0100 Subject: [PATCH 09/10] refactor(bank-sdk): Format code and suppress lint warnings in example app PP-2180 --- .../ui/CaptureSdkStandAloneActivity.kt | 6 ++-- .../exampleapp/ui/ConfigurationActivity.kt | 5 +++- .../ui/data/ExampleAppBankConfiguration.kt | 30 ++++++++++++------- .../ui/util/CaptureResultListener.kt | 5 ++-- .../GetCreditNoteHintEnabledUseCase.kt | 2 +- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/CaptureSdkStandAloneActivity.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/CaptureSdkStandAloneActivity.kt index 2968093738..c1a70708fa 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/CaptureSdkStandAloneActivity.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/CaptureSdkStandAloneActivity.kt @@ -55,7 +55,9 @@ class CaptureSdkStandAloneActivity : AppCompatActivity() { private fun restoreFragmentListener() { val fragment = - supportFragmentManager.findFragmentByTag(ClientCaptureSDKFragment::class.java.name) as? ClientCaptureSDKFragment? + supportFragmentManager.findFragmentByTag( + ClientCaptureSDKFragment::class.java.name + ) as? ClientCaptureSDKFragment? listener?.let { fragment?.setListener(it) } } @@ -83,4 +85,4 @@ class ClientCaptureSDKFragmentFactory( else -> super.instantiate(classLoader, className) } } -} \ No newline at end of file +} diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationActivity.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationActivity.kt index fa20dd8791..3fe51e8c36 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationActivity.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationActivity.kt @@ -25,6 +25,7 @@ import net.gini.android.capture.util.SharedPreferenceHelper import net.gini.android.capture.util.SharedPreferenceHelper.SAF_STORAGE_URI_KEY import javax.inject.Inject +@Suppress("LargeClass") @AndroidEntryPoint class ConfigurationActivity : AppCompatActivity() { @@ -109,6 +110,7 @@ class ConfigurationActivity : AppCompatActivity() { finish() } + @Suppress("LongMethod") private fun updateUIWithConfigurationObject(configuration: ExampleAppBankConfiguration) { // setup sdk with default configuration binding.layoutFeatureToggle.switchSetupSdkWithDefaultConfiguration.isChecked = @@ -118,7 +120,8 @@ class ConfigurationActivity : AppCompatActivity() { // Capture SDK binding.layoutFeatureToggle.switchCaptureSdk.isChecked = configuration.isCaptureSDK // Saving Invoices Locally - binding.layoutFeatureToggle.switchSaveInvoicesLocallyFeature.isChecked = configuration.saveInvoicesLocallyEnabled + binding.layoutFeatureToggle.switchSaveInvoicesLocallyFeature.isChecked = + configuration.saveInvoicesLocallyEnabled // QR code scanning binding.layoutFeatureToggle.switchQrCodeScanning.isChecked = configuration.isQrCodeEnabled // only QR code scanning diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/ExampleAppBankConfiguration.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/ExampleAppBankConfiguration.kt index 4a8df874f1..80888a174e 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/ExampleAppBankConfiguration.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/ExampleAppBankConfiguration.kt @@ -39,15 +39,18 @@ data class ExampleAppBankConfiguration( val isFlashDefaultStateEnabled: Boolean = false, // set import document type support - // net.gini.android.capture.GiniCapture.Builder#setDocumentImportEnabledFileTypes → radio buttons to select an available enum value - val documentImportEnabledFileTypes: DocumentImportEnabledFileTypes = DocumentImportEnabledFileTypes.PDF_AND_IMAGES, + // net.gini.android.capture.GiniCapture.Builder#setDocumentImportEnabledFileTypes → + // radio buttons to select an available enum value + val documentImportEnabledFileTypes: DocumentImportEnabledFileTypes = + DocumentImportEnabledFileTypes.PDF_AND_IMAGES, // enable bottom navigation bar // net.gini.android.capture.GiniCapture.Builder#setBottomNavigationBarEnabled → on/off switch val isBottomNavigationBarEnabled: Boolean = false, // enable Help screens custom bottom navigation bar - // net.gini.android.capture.GiniCapture.Builder#setHelpNavigationBarBottomAdapter → on/off switch to show a custom adapter implementation + // net.gini.android.capture.GiniCapture.Builder#setHelpNavigationBarBottomAdapter → + // on/off switch to show a custom adapter implementation val isHelpScreensCustomBottomNavBarEnabled: Boolean = false, // enable Error screens custom bottom navigation bar @@ -56,11 +59,13 @@ data class ExampleAppBankConfiguration( val isErrorScreensCustomBottomNavBarEnabled: Boolean = false, // enable camera screens custom bottom navigation bar - // net.gini.android.capture.GiniCapture.Builder#setCameraNavigationBarBottomAdapter → on/off switch to show a custom adapter implementation + // net.gini.android.capture.GiniCapture.Builder#setCameraNavigationBarBottomAdapter → + // on/off switch to show a custom adapter implementation val isCameraBottomNavBarEnabled: Boolean = false, // enable review screens custom bottom navigation bar - // net.gini.android.capture.GiniCapture.Builder#setReviewBottomBarNavigationAdapter → on/off switch to show a custom adapter implementation + // net.gini.android.capture.GiniCapture.Builder#setReviewBottomBarNavigationAdapter → + // on/off switch to show a custom adapter implementation val isReviewScreenCustomBottomNavBarEnabled: Boolean = false, // enable image picker screens custom bottom navigation bar -> was implemented on iOS, not needed for Android @@ -74,7 +79,8 @@ data class ExampleAppBankConfiguration( val isOnboardingAtEveryLaunchEnabled: Boolean = false, // enable custom onboarding pages - // net.gini.android.capture.GiniCapture.Builder#setCustomOnboardingPages → on/off switch to show custom onboarding pages + // net.gini.android.capture.GiniCapture.Builder#setCustomOnboardingPages → + // on/off switch to show custom onboarding pages val isCustomOnboardingPagesEnabled: Boolean = false, // enable align corners in custom onboarding pages @@ -86,7 +92,8 @@ data class ExampleAppBankConfiguration( val isLightingInCustomOnboardingEnabled: Boolean = false, // enable QR code in custom onboarding pages - // net.gini.android.capture.GiniCapture.Builder#setOnboardingQRCodeIllustrationAdapter-> on/off switch to show custom adapter with animated illustrations + // net.gini.android.capture.GiniCapture.Builder#setOnboardingQRCodeIllustrationAdapter-> + // on/off switch to show custom adapter with animated illustrations val isQRCodeInCustomOnboardingEnabled: Boolean = false, // enable multi page in custom onboarding pages @@ -99,11 +106,13 @@ data class ExampleAppBankConfiguration( // enable button's custom loading indicator - // net.gini.android.capture.GiniCapture.Builder#setOnButtonLoadingIndicatorAdapter → on/off switch to show a custom adapter implementation + // net.gini.android.capture.GiniCapture.Builder#setOnButtonLoadingIndicatorAdapter → + // on/off switch to show a custom adapter implementation val isButtonsCustomLoadingIndicatorEnabled: Boolean = false, // enable screen's custom loading indicator - // net.gini.android.capture.GiniCapture.Builder#setLoadingIndicatorAdapter → on/off switch to show a custom adapter implementation + // net.gini.android.capture.GiniCapture.Builder#setLoadingIndicatorAdapter → + // on/off switch to show a custom adapter implementation val isScreenCustomLoadingIndicatorEnabled: Boolean = false, @@ -116,7 +125,8 @@ data class ExampleAppBankConfiguration( val isCustomHelpItemsEnabled: Boolean = false, // enable custom navigation bar - // net.gini.android.capture.GiniCapture.Builder#setNavigationBarTopAdapter → on/off switch to show a custom adapter implementation + // net.gini.android.capture.GiniCapture.Builder#setNavigationBarTopAdapter → + // on/off switch to show a custom adapter implementation val isCustomNavBarEnabled: Boolean = false, // enable custom primary button in compose diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/util/CaptureResultListener.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/util/CaptureResultListener.kt index 3cb38446ba..605b4f8060 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/util/CaptureResultListener.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/util/CaptureResultListener.kt @@ -35,7 +35,8 @@ class CaptureResultListener(val context: Activity) : GiniCaptureFragmentListener is CaptureSDKResult.Error -> { Toast.makeText( context, - "Error: ${(result.value as ResultError.FileImport).code} ${(result.value as ResultError.FileImport).message}", + "Error: ${(result.value as ResultError.FileImport).code} " + + "${(result.value as ResultError.FileImport).message}", Toast.LENGTH_LONG ).show() @@ -54,4 +55,4 @@ class CaptureResultListener(val context: Activity) : GiniCaptureFragmentListener } } } -} \ No newline at end of file +} diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/paymentHints/GetCreditNoteHintEnabledUseCase.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/paymentHints/GetCreditNoteHintEnabledUseCase.kt index 3b61b6eb29..a5169b3c5b 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/paymentHints/GetCreditNoteHintEnabledUseCase.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/paymentHints/GetCreditNoteHintEnabledUseCase.kt @@ -7,4 +7,4 @@ class GetCreditNoteHintEnabledUseCase( ) { operator fun invoke() = giniBankConfigurationProvider.provide().isCreditNoteHintEnabled -} \ No newline at end of file +} From ff066c225b796e48e22bf8bac84238d94ad85615 Mon Sep 17 00:00:00 2001 From: Mahdi Abolfazli Date: Mon, 26 Jan 2026 16:48:34 +0100 Subject: [PATCH 10/10] refactor(capture-sdk): Replace setBackground with setImageResource for credit note bottom sheet icon PP-2180 --- .../gini/android/capture/analysis/warning/WarningBottomSheet.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningBottomSheet.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningBottomSheet.kt index 932b4cc3ba..2d11fe0305 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningBottomSheet.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/analysis/warning/WarningBottomSheet.kt @@ -179,7 +179,7 @@ class WarningBottomSheet : BottomSheetDialogFragment() { private fun bindUi() { binding.gcWarningTitleWarningBottomSheet.text = titleText binding.gcWarningDescriptionWarningBottomSheet.text = descText - icon?.let { binding.gcWarningIconWarningBottomSheet?.setBackgroundResource(it) } + icon?.let { binding.gcWarningIconWarningBottomSheet?.setImageResource(it) } binding.gcWarningIconWarningBottomSheet?.contentDescription = getString(R.string.gc_warning_icon_content_description)