Skip to content

Commit

Permalink
feature(bank-sdk): Skonto + RA.
Browse files Browse the repository at this point in the history
PP-722
  • Loading branch information
ndubkov-distcotech committed Aug 23, 2024
1 parent 0287341 commit 114d9a7
Show file tree
Hide file tree
Showing 37 changed files with 1,925 additions and 246 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ import net.gini.android.bank.sdk.capture.digitalinvoice.DigitalInvoiceException
import net.gini.android.bank.sdk.capture.digitalinvoice.DigitalInvoiceFragment
import net.gini.android.bank.sdk.capture.digitalinvoice.DigitalInvoiceFragmentListener
import net.gini.android.bank.sdk.capture.digitalinvoice.LineItemsValidator
import net.gini.android.bank.sdk.capture.digitalinvoice.args.DigitalInvoiceSpecificExtractionsArg
import net.gini.android.bank.sdk.capture.digitalinvoice.args.ExtractionsResultData
import net.gini.android.bank.sdk.capture.extractions.skonto.SkontoInvoiceHighlightsExtractor
import net.gini.android.bank.sdk.capture.skonto.SkontoDataExtractor
import net.gini.android.bank.sdk.capture.skonto.SkontoFragment
import net.gini.android.bank.sdk.capture.skonto.SkontoFragmentListener
import net.gini.android.bank.sdk.capture.skonto.model.SkontoData
import net.gini.android.bank.sdk.di.getGiniBankKoin
import net.gini.android.bank.sdk.util.disallowScreenshots
import net.gini.android.capture.Amount

import net.gini.android.capture.CaptureSDKResult
import net.gini.android.capture.Document
Expand All @@ -38,6 +42,8 @@ import net.gini.android.capture.tracking.useranalytics.UserAnalyticsEvent
import net.gini.android.capture.tracking.useranalytics.UserAnalyticsScreen
import net.gini.android.capture.tracking.useranalytics.properties.UserAnalyticsEventProperty
import net.gini.android.capture.tracking.useranalytics.properties.UserAnalyticsUserProperty
import java.math.BigDecimal
import java.time.LocalDate

class CaptureFlowFragment(private val openWithDocument: Document? = null) :
Fragment(),
Expand Down Expand Up @@ -178,12 +184,40 @@ class CaptureFlowFragment(private val openWithDocument: Document? = null) :

private fun tryShowingReturnAssistant(result: CaptureSDKResult.Success) {
LineItemsValidator.validate(result.compoundExtractions)
val skontoData = kotlin.runCatching {
val data = SkontoDataExtractor.extractSkontoData(
result.specificExtractions,
result.compoundExtractions
)
SkontoData(
skontoPercentageDiscounted = data.skontoPercentageDiscounted,
skontoPaymentMethod = when (data.skontoPaymentMethod) {
SkontoData.SkontoPaymentMethod.Cash -> SkontoData.SkontoPaymentMethod.Cash
SkontoData.SkontoPaymentMethod.PayPal -> SkontoData.SkontoPaymentMethod.PayPal
else -> SkontoData.SkontoPaymentMethod.Unspecified
},
skontoAmountToPay = data.skontoAmountToPay,
fullAmountToPay = data.fullAmountToPay,
skontoRemainingDays = data.skontoRemainingDays,
skontoDueDate = data.skontoDueDate
)
}.getOrNull()

val highlightBoxes = kotlin.runCatching {
skontoInvoiceHighlightsExtractor.extract(
result.compoundExtractions
)
}.getOrNull() ?: emptyList()

navController.navigate(
GiniCaptureFragmentDirections.toDigitalInvoiceFragment(
DigitalInvoiceFragment.getExtractionsBundle(result.specificExtractions),
DigitalInvoiceFragment.getCompoundExtractionsBundle(result.compoundExtractions),
result.returnReasons.toTypedArray(),
DigitalInvoiceFragment.getAmountsAreConsistentExtraction(result.specificExtractions)
ExtractionsResultData(
specificExtractions = result.specificExtractions,
compoundExtractions = result.compoundExtractions,
returnReasons = result.returnReasons
),
skontoData = skontoData,
skontoInvoiceHighlights = highlightBoxes.toTypedArray(),
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.gini.android.bank.sdk.capture.digitalinvoice

import androidx.annotation.VisibleForTesting
import net.gini.android.bank.sdk.capture.skonto.model.SkontoData
import net.gini.android.capture.AmountCurrency
import java.math.BigDecimal
import java.math.RoundingMode
Expand Down Expand Up @@ -30,7 +31,7 @@ internal val FRACTION_FORMAT = DecimalFormat(".00").apply { roundingMode = Round
internal class DigitalInvoice(
extractions: Map<String, GiniCaptureSpecificExtraction>,
compoundExtractions: Map<String, GiniCaptureCompoundExtraction>,
savedSelectableItems: List<SelectableLineItem>? = null
savedSelectableItems: List<SelectableLineItem>? = null,
) {

private var _extractions: Map<String, GiniCaptureSpecificExtraction> = extractions
Expand All @@ -53,6 +54,7 @@ internal class DigitalInvoice(

private val amountToPay: BigDecimal


init {
_selectableLineItems = when (savedSelectableItems) {
null -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ import androidx.core.os.BundleCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller
import kotlinx.coroutines.CoroutineScope
import net.gini.android.bank.sdk.GiniBank
import net.gini.android.bank.sdk.R
import net.gini.android.bank.sdk.capture.digitalinvoice.skonto.DigitalInvoiceSkontoFragment
import net.gini.android.bank.sdk.capture.digitalinvoice.skonto.args.DigitalInvoiceSkontoArgs
import net.gini.android.bank.sdk.capture.digitalinvoice.skonto.args.DigitalInvoiceSkontoResultArgs
import net.gini.android.bank.sdk.capture.digitalinvoice.view.DigitalInvoiceNavigationBarBottomAdapter
import net.gini.android.bank.sdk.capture.util.autoCleared
import net.gini.android.bank.sdk.capture.util.parentFragmentManagerOrNull
Expand All @@ -28,7 +32,6 @@ import net.gini.android.bank.sdk.util.getLayoutInflaterWithGiniCaptureTheme
import net.gini.android.capture.GiniCapture
import net.gini.android.capture.internal.ui.IntervalToolbarMenuItemIntervalClickListener
import net.gini.android.capture.internal.util.ActivityHelper.forcePortraitOrientationOnPhones
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.tracking.useranalytics.UserAnalytics
Expand All @@ -46,20 +49,17 @@ import net.gini.android.capture.view.NavButtonType
* Copyright (c) 2019 Gini GmbH.
*/

private const val ARGS_EXTRACTIONS = "GBS_ARGS_EXTRACTIONS"
private const val ARGS_COMPOUND_EXTRACTIONS = "GBS_ARGS_COMPOUND_EXTRACTIONS"
private const val ARGS_RETURN_REASONS = "GBS_ARGS_RETURN_REASONS"
private const val ARGS_INACCURATE_EXTRACTION = "GBS_ARGS_INACCURATE_EXTRACTION"

private const val TAG_RETURN_REASON_DIALOG = "TAG_RETURN_REASON_DIALOG"
private const val TAG_WHAT_IS_THIS_DIALOG = "TAG_WHAT_IS_THIS_DIALOG"

/**
* Internal use only.
*/
open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.View,
LineItemsAdapterListener {

private val args: DigitalInvoiceFragmentArgs by navArgs<DigitalInvoiceFragmentArgs>()

private var binding by autoCleared<GbsFragmentDigitalInvoiceBinding>()
private var lineItemsAdapter by autoCleared<LineItemsAdapter>()
private val screenName: UserAnalyticsScreen = UserAnalyticsScreen.ReturnAssistant
Expand All @@ -77,30 +77,30 @@ open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.Vie

private var presenter: DigitalInvoiceScreenContract.Presenter? = null

private var extractions: Map<String, GiniCaptureSpecificExtraction> = emptyMap()
private var compoundExtractions: Map<String, GiniCaptureCompoundExtraction> = emptyMap()
private var returnReasons: List<GiniCaptureReturnReason> = emptyList()
private var isInaccurateExtraction: Boolean = false
private var footerDetails: DigitalInvoiceScreenContract.FooterDetails? = null
private val userAnalyticsEventTracker by lazy { UserAnalytics.getAnalyticsEventTracker() }
private var onBackPressedCallback: OnBackPressedCallback? = null

companion object {
internal fun getExtractionsBundle(extractions: Map<String, GiniCaptureSpecificExtraction>): Bundle =
Bundle().apply {
extractions.forEach { putParcelable(it.key, it.value) }
}
private val skontoAdapterListener = object : SkontoListItemAdapterListener {

internal fun getCompoundExtractionsBundle(compoundExtractions: Map<String, GiniCaptureCompoundExtraction>): Bundle =
Bundle().apply {
compoundExtractions.forEach { putParcelable(it.key, it.value) }
}
override fun onSkontoEditClicked(listItem: DigitalInvoiceSkontoListItem) {
findNavController().navigate(
DigitalInvoiceFragmentDirections.toDigitalInvoiceSkontoFragment(
DigitalInvoiceSkontoArgs(
listItem.data,
args.skontoInvoiceHighlights.toList(),
listItem.enabled
)
)
)
}

override fun onSkontoEnabled(listItem: DigitalInvoiceSkontoListItem) {
showSkonto(listItem.copy(enabled = true))
}

internal fun getAmountsAreConsistentExtraction(extractions: Map<String, GiniCaptureSpecificExtraction>): Boolean {
val isInaccurateExtraction = extractions["amountsAreConsistent"]?.let {
it.value == "false"
} ?: true
return isInaccurateExtraction
override fun onSkontoDisabled(listItem: DigitalInvoiceSkontoListItem) {
showSkonto(listItem.copy(enabled = false))
}
}

Expand All @@ -119,7 +119,6 @@ open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.Vie
requireActivity().window.disallowScreenshots()
}
forcePortraitOrientationOnPhones(activity)
readArguments()
initListener()
createPresenter(activity, savedInstanceState)

Expand All @@ -128,38 +127,15 @@ open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.Vie
}
}

private fun readArguments() {
arguments?.run {
getBundle(ARGS_EXTRACTIONS)?.run {
extractions =
keySet().map { it to getParcelable<GiniCaptureSpecificExtraction>(it)!! }
.toMap()
}
getBundle(ARGS_COMPOUND_EXTRACTIONS)?.run {
compoundExtractions =
keySet().map { it to getParcelable<GiniCaptureCompoundExtraction>(it)!! }
.toMap()
}
returnReasons =
(BundleCompat.getParcelableArray(
this,
ARGS_RETURN_REASONS,
GiniCaptureReturnReason::class.java
)
?.toList() as? List<GiniCaptureReturnReason>) ?: emptyList()

isInaccurateExtraction = getBoolean(ARGS_INACCURATE_EXTRACTION, false)
}
}

private fun createPresenter(activity: Activity, savedInstanceState: Bundle?) =
DigitalInvoiceScreenPresenter(
activity,
this,
extractions,
compoundExtractions,
returnReasons,
isInaccurateExtraction,
args.extractionsResult.specificExtractions,
args.extractionsResult.compoundExtractions,
args.extractionsResult.returnReasons,
args.skontoData,
getAmountsAreConsistentExtraction(args.extractionsResult.specificExtractions),
savedInstanceState,
).apply {
listener = this@DigitalInvoiceFragment.listener
Expand Down Expand Up @@ -291,7 +267,7 @@ open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.Vie
}

private fun initRecyclerView() {
lineItemsAdapter = LineItemsAdapter(this, requireContext())
lineItemsAdapter = LineItemsAdapter(this, skontoAdapterListener, requireContext())
activity?.let {
binding.lineItems.apply {
layoutManager = LinearLayoutManager(it)
Expand Down Expand Up @@ -425,6 +401,9 @@ open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.Vie
lineItemsAdapter.addons = addons
}

override fun showSkonto(data: DigitalInvoiceSkontoListItem) {
lineItemsAdapter.skontoDiscount = listOf(data)
}

/**
* Internal use only.
Expand Down Expand Up @@ -461,6 +440,7 @@ open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.Vie
super.onStart()
presenter?.start()
setBottomSheetResultListener()
setSkontoResultListener()
}

private fun setBottomSheetResultListener() {
Expand All @@ -480,6 +460,27 @@ open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.Vie
}
}

private fun setSkontoResultListener() {
parentFragmentManager
.setFragmentResultListener(
DigitalInvoiceSkontoFragment.REQUEST_KEY,
viewLifecycleOwner
) { _: String?, result: Bundle ->
BundleCompat.getParcelable(
result,
DigitalInvoiceSkontoFragment.RESULT_KEY,
DigitalInvoiceSkontoResultArgs::class.java
)?.let { skontoResult ->
showSkonto(
DigitalInvoiceSkontoListItem(
skontoResult.skontoData,
skontoResult.isSkontoEnabled
)
)
}
}
}

/**
* Internal use only.
*
Expand Down Expand Up @@ -569,6 +570,13 @@ open class DigitalInvoiceFragment : Fragment(), DigitalInvoiceScreenContract.Vie
)
)
}

private fun getAmountsAreConsistentExtraction(extractions: Map<String, GiniCaptureSpecificExtraction>): Boolean {
val isInaccurateExtraction = extractions["amountsAreConsistent"]?.let {
it.value == "false"
} ?: true
return isInaccurateExtraction
}
}
// endregion

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package net.gini.android.bank.sdk.capture.digitalinvoice
import android.app.Activity
import android.os.Bundle
import kotlinx.coroutines.CoroutineScope
import net.gini.android.bank.sdk.capture.skonto.model.SkontoData
import net.gini.android.bank.sdk.capture.skonto.model.SkontoInvoiceHighlightBoxes
import net.gini.android.capture.GiniCaptureBasePresenter
import net.gini.android.capture.GiniCaptureBaseView
import net.gini.android.capture.network.model.GiniCaptureReturnReason
Expand All @@ -29,12 +31,16 @@ interface DigitalInvoiceScreenContract {
val viewLifecycleScope: CoroutineScope
fun showLineItems(lineItems: List<SelectableLineItem>, isInaccurateExtraction: Boolean)
fun showAddons(addons: List<DigitalInvoiceAddon>)
fun showSkonto(data: DigitalInvoiceSkontoListItem)
fun updateFooterDetails(data: FooterDetails)
fun showReturnReasonDialog(reasons: List<GiniCaptureReturnReason>,
resultCallback: ReturnReasonDialogResultCallback
fun showReturnReasonDialog(
reasons: List<GiniCaptureReturnReason>,
resultCallback: ReturnReasonDialogResultCallback
)

fun animateListScroll()
fun onEditLineItem(selectableLineItem: SelectableLineItem)

fun showOnboarding()
}

Expand All @@ -44,7 +50,7 @@ interface DigitalInvoiceScreenContract {
* @suppress
*/
abstract class Presenter(activity: Activity, view: View) :
GiniCaptureBasePresenter<View>(activity, view) {
GiniCaptureBasePresenter<View>(activity, view) {

var listener: DigitalInvoiceFragmentListener? = null

Expand All @@ -55,6 +61,8 @@ interface DigitalInvoiceScreenContract {
abstract fun onViewCreated()
abstract fun saveState(outState: Bundle)
abstract fun updateLineItem(selectableLineItem: SelectableLineItem)
abstract fun enableSkonto()
abstract fun disableSkonto()
}

data class FooterDetails(
Expand Down
Loading

0 comments on commit 114d9a7

Please sign in to comment.