Skip to content

Commit

Permalink
feat(bank-sdk): Add BE integration to get configuration response
Browse files Browse the repository at this point in the history
PP-450
  • Loading branch information
abolfazlimahdi committed Jun 17, 2024
1 parent 3978ea3 commit 05a22c0
Show file tree
Hide file tree
Showing 16 changed files with 456 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.gini.android.bank.api;

import net.gini.android.bank.api.models.Configuration
import net.gini.android.bank.api.models.ExtractionsContainer
import net.gini.android.bank.api.models.ResolvePaymentInput
import net.gini.android.bank.api.models.ResolvedPayment
Expand Down Expand Up @@ -45,4 +46,8 @@ class BankApiDocumentManager internal constructor(private val documentRepository
errorEvent: ErrorEvent
): Resource<Unit> =
documentRepository.logErrorEvent(errorEvent)


suspend fun getConfigurations(): Resource<Configuration> =
documentRepository.getConfigurations()
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package net.gini.android.bank.api

import kotlinx.coroutines.withContext
import net.gini.android.bank.api.models.Configuration
import net.gini.android.bank.api.models.ResolvePaymentInput
import net.gini.android.bank.api.models.ResolvedPayment
import net.gini.android.bank.api.models.toResolvedPayment
import net.gini.android.bank.api.requests.ErrorEvent
import net.gini.android.bank.api.requests.toResolvePaymentBody
import net.gini.android.bank.api.response.toConfiguration
import net.gini.android.core.api.DocumentRemoteSource
import net.gini.android.core.api.requests.ApiException
import net.gini.android.core.api.requests.SafeApiRequest
Expand Down Expand Up @@ -34,4 +36,11 @@ class BankApiDocumentRemoteSource internal constructor(
documentService.logErrorEvent(bearerHeaderMap(accessToken, contentType = giniApiType.giniJsonMediaType), errorEvent)
}
}

suspend fun getConfigurations(accessToken: String): Configuration = withContext(coroutineContext) {
val response = SafeApiRequest.apiRequest {
documentService.getConfigurations(bearerHeaderMap(accessToken, giniApiType.giniJsonMediaType))
}
response.body()?.toConfiguration() ?: throw ApiException.forResponse("Empty response body", response)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class BankApiDocumentRepository(
}
}

suspend fun getConfigurations(): Resource<Configuration> =
withAccessToken { accessToken ->
wrapInResource {
documentRemoteSource.getConfigurations(accessToken)
}
}

@Throws(JSONException::class)
private fun parseReturnReason(returnReasonsJson: JSONArray?): List<ReturnReason> {
if (returnReasonsJson == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package net.gini.android.bank.api

import net.gini.android.bank.api.requests.ErrorEvent
import net.gini.android.bank.api.requests.ResolvePaymentBody
import net.gini.android.bank.api.response.ConfigurationResponse
import net.gini.android.bank.api.response.ResolvePaymentResponse
import net.gini.android.core.api.DocumentService
import okhttp3.RequestBody
Expand All @@ -19,4 +20,7 @@ internal interface BankApiDocumentService: DocumentService {

@POST("events/error")
suspend fun logErrorEvent(@HeaderMap bearer: Map<String, String>, @Body errorEvent: ErrorEvent): Response<ResponseBody>

@GET("configurations")
suspend fun getConfigurations(@HeaderMap bearer: Map<String, String>): Response<ConfigurationResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.gini.android.bank.api.models

data class Configuration(
val clientID: String,
val isUserJourneyAnalyticsEnabled: Boolean,
val isSkontoEnabled: Boolean,
val isReturnAssistantEnabled: Boolean,
val mixpanelToken: String?,
val amplitudeApiKey: String?,

)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.gini.android.bank.api.response

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import net.gini.android.bank.api.models.Configuration

@JsonClass(generateAdapter = true)
data class ConfigurationResponse(
@Json(name = "clientID") val clientID: String?,
@Json(name = "userJourneyAnalyticsEnabled") val userJourneyAnalyticsEnabled: Boolean?,
@Json(name = "skontoEnabled") val skontoEnabled: Boolean?,
@Json(name = "returnAssistantEnabled") val returnAssistantEnabled: Boolean?,
@Json(name = "mixpanelToken") val mixpanelToken: String?,
@Json(name = "amplitudeApiKey") val amplitudeApiKey: String?,
)

internal fun ConfigurationResponse.toConfiguration() = Configuration(
clientID = clientID ?: "",
isUserJourneyAnalyticsEnabled = userJourneyAnalyticsEnabled ?: false,
isSkontoEnabled = skontoEnabled ?: false,
isReturnAssistantEnabled = returnAssistantEnabled ?: false,
mixpanelToken = mixpanelToken,
amplitudeApiKey = amplitudeApiKey
)

Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import net.gini.android.capture.tracking.useranalytics.properties.UserAnalyticsU
*/
internal class CaptureFlowActivity : AppCompatActivity(), CaptureFlowFragmentListener {

private val userAnalyticsEventTracker by lazy { UserAnalytics.getAnalyticsEventTracker() }
// TODO: move this to GiniCaptureFragment
//private val userAnalyticsEventTracker by lazy { UserAnalytics.getAnalyticsEventTracker() }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand Down Expand Up @@ -108,6 +109,7 @@ internal class CaptureFlowActivity : AppCompatActivity(), CaptureFlowFragmentLis
const val EXTRA_OUT_RESULT = "GBS_EXTRA_OUT_RESULT"
}

// TODO: uncomment the last part and move this to GiniCaptureFragment
private fun setAnalyticsEntryPointProperty(isOpenWithDocumentExists: Boolean) {

val entryPointProperty = if (isOpenWithDocumentExists) {
Expand All @@ -120,17 +122,17 @@ internal class CaptureFlowActivity : AppCompatActivity(), CaptureFlowFragmentLis
}
)
}

userAnalyticsEventTracker.setUserProperty(
setOf(
UserAnalyticsUserProperty.ReturnAssistantEnabled(
GiniBank.getCaptureConfiguration()?.returnAssistantEnabled ?: false
),
UserAnalyticsUserProperty.ReturnReasonsEnabled(GiniBank.enableReturnReasons),
)
)

userAnalyticsEventTracker.setEventSuperProperty(entryPointProperty)
//
// userAnalyticsEventTracker.setUserProperty(
// setOf(
// UserAnalyticsUserProperty.ReturnAssistantEnabled(
// GiniBank.getCaptureConfiguration()?.returnAssistantEnabled ?: false
// ),
// UserAnalyticsUserProperty.ReturnReasonsEnabled(GiniBank.enableReturnReasons),
// )
// )
//
// userAnalyticsEventTracker.setEventSuperProperty(entryPointProperty)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import net.gini.android.bank.api.GiniBankAPIBuilder
import net.gini.android.capture.Document
import net.gini.android.capture.GiniCapture
import net.gini.android.capture.document.GiniCaptureMultiPageDocument
import net.gini.android.capture.internal.network.Configuration
import net.gini.android.bank.api.models.Configuration as BankConfiguration
import net.gini.android.capture.logging.ErrorLog
import net.gini.android.capture.network.GiniCaptureDefaultNetworkService.Companion.builder
import net.gini.android.capture.network.logging.formattedErrorMessage
Expand All @@ -25,6 +27,7 @@ import net.gini.android.core.api.authorization.SessionManager
import okhttp3.Cache
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.util.UUID
import java.util.concurrent.TimeUnit
import javax.net.ssl.TrustManager
import kotlin.coroutines.CoroutineContext
Expand Down Expand Up @@ -59,7 +62,8 @@ class GiniCaptureDefaultNetworkService(
) : GiniCaptureNetworkService {

private val coroutineScope = CoroutineScope(coroutineContext)
private val giniApiDocuments: MutableMap<String, net.gini.android.core.api.models.Document> = mutableMapOf()
private val giniApiDocuments: MutableMap<String, net.gini.android.core.api.models.Document> =
mutableMapOf()

/**
* Contains the document which was created when the user uploaded an image or a pdf for
Expand All @@ -76,6 +80,46 @@ class GiniCaptureDefaultNetworkService(
var analyzedGiniApiDocument: net.gini.android.core.api.models.Document? = null
private set

override fun getConfiguration(callback: GiniCaptureNetworkCallback<Configuration, Error>): CancellationToken? =
launchCancellable {
when (val configurationResource = giniBankApi.documentManager.getConfigurations()) {
is Resource.Success -> {
LOG.debug(
"Get configuration success"
)
callback.success(mapBankConfigurationToConfiguration(configurationResource.data))
}

is Resource.Error -> {
LOG.debug(
"Get configuration error for {}: {}"
)
val error = Error(configurationResource.formattedErrorMessage)
LOG.error(
"Document deletion failed for api id {}",
error.message
)
callback.failure(error)
}

is Resource.Cancelled -> {
LOG.debug("Get configuration cancelled for")
callback.cancelled()
}
}
}

private fun mapBankConfigurationToConfiguration(configuration: BankConfiguration) =
Configuration(
UUID.randomUUID(),
configuration.clientID,
configuration.isUserJourneyAnalyticsEnabled,
configuration.isSkontoEnabled,
configuration.isReturnAssistantEnabled,
configuration.mixpanelToken ?: "",
configuration.amplitudeApiKey ?: "",
)

override fun upload(
document: Document,
callback: GiniCaptureNetworkCallback<Result, Error>
Expand Down Expand Up @@ -119,16 +163,20 @@ class GiniCaptureDefaultNetworkService(
giniApiDocuments[apiDocument.id] = apiDocument
callback.success(Result(apiDocument.id))
}

is Resource.Error -> {

val error = Error(partialDocumentResource.responseStatusCode,
partialDocumentResource.responseHeaders, partialDocumentResource.exception)
val error = Error(
partialDocumentResource.responseStatusCode,
partialDocumentResource.responseHeaders, partialDocumentResource.exception
)
LOG.error(
"Document upload failed for {}: {}", document.id,
error.message
)
callback.failure(error)
}

is Resource.Cancelled -> {
LOG.debug(
"Document upload cancelled for {}",
Expand All @@ -151,12 +199,14 @@ class GiniCaptureDefaultNetworkService(
callback: GiniCaptureNetworkCallback<Result, Error>
): CancellationToken = launchCancellable {
LOG.debug("Delete document with api id {}", giniApiDocumentId)
val deleteResource = giniBankApi.documentManager.deletePartialDocumentAndParents(giniApiDocumentId)
val deleteResource =
giniBankApi.documentManager.deletePartialDocumentAndParents(giniApiDocumentId)
when (deleteResource) {
is Resource.Success -> {
LOG.debug("Document deletion success for api id {}", giniApiDocumentId)
callback.success(Result(giniApiDocumentId))
}

is Resource.Error -> {
val error = Error(deleteResource.formattedErrorMessage)
LOG.error(
Expand All @@ -165,6 +215,7 @@ class GiniCaptureDefaultNetworkService(
)
callback.failure(error)
}

is Resource.Cancelled -> {
LOG.debug("Document deletion cancelled for api id {}", giniApiDocumentId)
callback.cancelled()
Expand Down Expand Up @@ -199,9 +250,10 @@ class GiniCaptureDefaultNetworkService(
.mapSuccess { compositeDocumentResource ->
val compositeDocument = compositeDocumentResource.data
giniApiDocuments[compositeDocument.id] = compositeDocument
giniBankApi.documentManager.getAllExtractionsWithPolling(compositeDocument).mapSuccess {
Resource.Success(compositeDocument to it.data)
}
giniBankApi.documentManager.getAllExtractionsWithPolling(compositeDocument)
.mapSuccess {
Resource.Success(compositeDocument to it.data)
}
}
when (compositeDocumentAndExtractionsResource) {
is Resource.Cancelled -> {
Expand All @@ -210,6 +262,7 @@ class GiniCaptureDefaultNetworkService(
giniApiDocumentIdRotationMap
)
}

is Resource.Error -> {
val error = Error(compositeDocumentAndExtractionsResource.formattedErrorMessage)
LOG.error(
Expand All @@ -218,22 +271,33 @@ class GiniCaptureDefaultNetworkService(
)
callback.failure(error)
}

is Resource.Success -> {
val compositeDocument = compositeDocumentAndExtractionsResource.data.first
val allExtractions = compositeDocumentAndExtractionsResource.data.second

analyzedGiniApiDocument = compositeDocument

val extractions = SpecificExtractionMapper.mapToGiniCapture(allExtractions.specificExtractions)
val compoundExtractions = CompoundExtractionsMapper.mapToGiniCapture(allExtractions.compoundExtractions)
val returnReasons = ReturnReasonsMapper.mapToGiniCapture(allExtractions.returnReasons)
val extractions =
SpecificExtractionMapper.mapToGiniCapture(allExtractions.specificExtractions)
val compoundExtractions =
CompoundExtractionsMapper.mapToGiniCapture(allExtractions.compoundExtractions)
val returnReasons =
ReturnReasonsMapper.mapToGiniCapture(allExtractions.returnReasons)

LOG.debug(
"Document analysis success for documents {}: extractions = {}; compoundExtractions = {}; returnReasons = {}",
giniApiDocumentIdRotationMap, extractions, compoundExtractions, returnReasons
)

callback.success(AnalysisResult(compositeDocument.id, extractions, compoundExtractions, returnReasons))
callback.success(
AnalysisResult(
compositeDocument.id,
extractions,
compoundExtractions,
returnReasons
)
)
}
}
}
Expand All @@ -249,7 +313,10 @@ class GiniCaptureDefaultNetworkService(
// We require the Gini Bank API lib's net.gini.android.core.api.models.Document for sending the feedback
if (document != null) {
val feedbackResource = if (compoundExtractions.isEmpty()) {
documentManager.sendFeedbackForExtractions(document, SpecificExtractionMapper.mapToApiSdk(extractions))
documentManager.sendFeedbackForExtractions(
document,
SpecificExtractionMapper.mapToApiSdk(extractions)
)
} else {
documentManager.sendFeedbackForExtractions(
document,
Expand All @@ -265,9 +332,14 @@ class GiniCaptureDefaultNetworkService(
)
callback.success(null)
}

is Resource.Error -> {
val error = Error(feedbackResource.formattedErrorMessage)
LOG.error("Send feedback failed for api document {}: {}", document.id, error.message)
LOG.error(
"Send feedback failed for api document {}: {}",
document.id,
error.message
)
handleErrorLog(
ErrorLog(
description = "Failed to send feedback for document ${document.id}",
Expand All @@ -276,8 +348,9 @@ class GiniCaptureDefaultNetworkService(
)
callback.failure(error)
}

is Resource.Cancelled -> {
LOG.debug(
LOG.debug(
"Send feedback cancelled for api document {}",
document.id
)
Expand Down Expand Up @@ -547,7 +620,8 @@ class GiniCaptureDefaultNetworkService(
}

companion object {
private val LOG: Logger = LoggerFactory.getLogger(GiniCaptureDefaultNetworkService::class.java)
private val LOG: Logger =
LoggerFactory.getLogger(GiniCaptureDefaultNetworkService::class.java)

/**
* Creates a new [GiniCaptureDefaultNetworkService.Builder] to configure and create a new
Expand Down
Loading

0 comments on commit 05a22c0

Please sign in to comment.