NTP-14194 | Vedant Aggarwal | Addressed comments for Account Management schema changes PR (#15155)

This commit is contained in:
vedant aggarwal
2025-02-27 12:53:25 +05:30
committed by GitHub
parent 0be6f35e33
commit 2b4169e10c
11 changed files with 89 additions and 102 deletions

View File

@@ -829,7 +829,8 @@ fun Activity.setBrightness(shouldSetMaximumBrightness: Boolean) {
fun getBankIconUrlFromBankCode(bankCode: String): String {
return FirebaseRemoteConfigHelper.getString(
FirebaseRemoteConfigHelper.NAVI_PAY_BANK_LOGOS_V2_URL
key = FirebaseRemoteConfigHelper.NAVI_PAY_BANK_LOGOS_V2_URL,
defaultValue = "https://public-assets.prod.navi-pay.in/bank-logos-v2/bankIdentifier.png",
)
.replace(oldValue = NAVI_PAY_BANK_LOGOS_V2_URL_BANK_IDENTIFIER_KEY, newValue = bankCode)
}

View File

@@ -9,15 +9,14 @@ package com.navi.pay.management.mandate.repository
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.navi.common.constants.EMPTY
import com.navi.common.network.models.isSuccessWithData
import com.navi.pay.common.utils.DeviceInfoProvider
import com.navi.pay.common.utils.getBankIconUrlFromBankCode
import com.navi.pay.common.utils.getMetricInfo
import com.navi.pay.management.mandate.model.network.MandateListRequest
import com.navi.pay.management.mandate.model.network.toMandateEntity
import com.navi.pay.management.mandate.model.view.MandateCategory
import com.navi.pay.management.mandate.model.view.MandateEntity
import com.navi.pay.onboarding.account.add.repository.BankRepository
import com.navi.pay.onboarding.account.common.repository.AccountsRepository
class MandateListDataSource(
@@ -26,7 +25,6 @@ class MandateListDataSource(
private val mandateCategory: MandateCategory,
private val screenName: String,
private val accountsRepository: AccountsRepository,
private val bankRepository: BankRepository,
) : PagingSource<Int, MandateEntity>() {
companion object {
@@ -71,13 +69,8 @@ class MandateListDataSource(
accountsRepository.getAccountEntityByBuid(
it.bankAccountUniqueId.orEmpty()
) ?: return@map it.toMandateEntity()
val bankEntity =
bankRepository.getBankUiModelMapFromBankCodes(
listOf(accountEntity.bankCode)
)
val bankImageUrl = bankEntity[accountEntity.bankCode]?.iconUrl ?: EMPTY
it.toMandateEntity().copy(bankImageUrl = bankImageUrl)
it.toMandateEntity()
.copy(bankImageUrl = getBankIconUrlFromBankCode(accountEntity.bankCode))
}
return LoadResult.Page(

View File

@@ -43,7 +43,6 @@ import com.navi.pay.management.mandate.model.view.MandateTab
import com.navi.pay.management.mandate.repository.MandateListDataSource
import com.navi.pay.management.mandate.repository.MandateListDataSource.Companion.MANDATE_LIST_ITEMS_LIMIT
import com.navi.pay.management.mandate.repository.MandateRepository
import com.navi.pay.onboarding.account.add.repository.BankRepository
import com.navi.pay.onboarding.account.add.util.toLinkedAccountEntity
import com.navi.pay.onboarding.account.common.repository.AccountsRepository
import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity
@@ -69,7 +68,6 @@ constructor(
private val deviceInfoProvider: DeviceInfoProvider,
private val sharedPreferenceRepository: SharedPreferenceRepository,
private val accountsRepository: AccountsRepository,
private val bankRepository: BankRepository,
private val linkedAccountsUseCase: LinkedAccountsUseCase,
private val validateVpaUseCase: ValidateVpaUseCase,
private val naviCacheRepository: NaviCacheRepository,
@@ -167,7 +165,6 @@ constructor(
mandateCategory = MandateCategory.ACTIVE,
screenName = screenName,
accountsRepository = accountsRepository,
bankRepository = bankRepository,
)
}
.flow
@@ -187,7 +184,6 @@ constructor(
mandateCategory = MandateCategory.COMPLETED,
screenName = screenName,
accountsRepository = accountsRepository,
bankRepository = bankRepository,
)
}
.flow

View File

@@ -10,10 +10,8 @@ package com.navi.pay.management.moneytransfer.bank.viewmodel
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
import com.navi.base.utils.ResourceProvider
import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.base.utils.retry
import com.navi.common.network.models.isSuccessWithData
import com.navi.common.utils.EMPTY
import com.navi.pay.R
import com.navi.pay.analytics.NaviPayAnalytics.Companion.NAVI_PAY_SEND_MONEY_BANK_DETAIL
import com.navi.pay.common.connectivity.NaviPayNetworkConnectivity
@@ -24,6 +22,7 @@ import com.navi.pay.common.usecase.NaviPayConfigUseCase
import com.navi.pay.common.usecase.ValidateVpaUseCase
import com.navi.pay.common.utils.DeviceInfoProvider
import com.navi.pay.common.utils.NaviPayCommonUtils
import com.navi.pay.common.utils.getBankIconUrlFromBankCode
import com.navi.pay.common.utils.getBankNameAccountNumberText
import com.navi.pay.common.utils.getMetricInfo
import com.navi.pay.common.viewmodel.NaviPayBaseVM
@@ -31,7 +30,6 @@ import com.navi.pay.destinations.SendMoneyScreenDestination
import com.navi.pay.management.common.model.view.WarningErrorInfoState
import com.navi.pay.management.common.sendmoney.model.view.PayeeEntity
import com.navi.pay.management.common.sendmoney.model.view.SendMoneyScreenSource
import com.navi.pay.onboarding.account.add.repository.BankRepository
import com.navi.pay.onboarding.account.common.repository.AccountsRepository
import com.navi.pay.utils.DEFAULT_CONFIG
import com.navi.pay.utils.DEFAULT_RETRY_COUNT
@@ -62,7 +60,6 @@ constructor(
private val accountsRepository: AccountsRepository,
private val deviceInfoProvider: DeviceInfoProvider,
private val validateVpaUseCase: ValidateVpaUseCase,
private val bankRepository: BankRepository,
private val naviPayNetworkConnectivity: NaviPayNetworkConnectivity,
private val naviPayConfigUseCase: NaviPayConfigUseCase,
private val resourceProvider: ResourceProvider,
@@ -347,15 +344,10 @@ constructor(
val bankDetailResponse = bankDetailFetchJob.await()
val bankCodeList =
if (validateVpaData.bankCode.isNotNullAndNotEmpty())
listOf(validateVpaData.bankCode)
else emptyList()
val bankEntityMap =
bankRepository.getBankUiModelMapFromBankCodes(
bankCodeList = bankCodeList.map { it.orEmpty() }
)
val bankImgUrl = bankEntityMap[validateVpaData.bankCode]?.iconUrl ?: EMPTY
val bankImgUrl =
validateVpaData.bankCode
?.let { getBankIconUrlFromBankCode(validateVpaData.bankCode) }
.orEmpty()
val payeeEntity =
PayeeEntity(

View File

@@ -12,10 +12,8 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import com.navi.base.utils.ResourceProvider
import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.common.network.models.RepoResult
import com.navi.common.network.models.isSuccessWithData
import com.navi.common.utils.EMPTY
import com.navi.pay.R
import com.navi.pay.analytics.NaviPayAnalytics
import com.navi.pay.analytics.NaviPayAnalytics.Companion.NAVI_PAY_SAVED_BENEFICIARY_SCREEN
@@ -28,6 +26,7 @@ import com.navi.pay.common.usecase.SyncSavedBeneficiariesUseCase
import com.navi.pay.common.usecase.ValidateVpaUseCase
import com.navi.pay.common.utils.DeviceInfoProvider
import com.navi.pay.common.utils.fetchUserPhoneNumber
import com.navi.pay.common.utils.getBankIconUrlFromBankCode
import com.navi.pay.common.viewmodel.NaviPayBaseVM
import com.navi.pay.destinations.LinkedAccountsScreenDestination
import com.navi.pay.destinations.SendMoneyScreenDestination
@@ -40,7 +39,6 @@ import com.navi.pay.management.savedbeneficiary.model.view.SavedBeneficiaryTabDa
import com.navi.pay.management.savedbeneficiary.model.view.SavedBeneficiaryType
import com.navi.pay.management.savedbeneficiary.repository.SavedBeneficiaryRepository
import com.navi.pay.management.savedbeneficiary.util.SavedBeneficiaryUtil
import com.navi.pay.onboarding.account.add.repository.BankRepository
import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity
import com.navi.pay.utils.INVALID_UPI_ID
import com.navi.pay.utils.INVALID_UPI_NUMBER
@@ -87,7 +85,6 @@ constructor(
private val linkedAccountsUseCase: LinkedAccountsUseCase,
private val naviPayNetworkConnectivity: NaviPayNetworkConnectivity,
private val validateVpaUseCase: ValidateVpaUseCase,
private val bankRepository: BankRepository,
private val deviceInfoProvider: DeviceInfoProvider,
private val naviPaySessionHelper: NaviPaySessionHelper,
private val resourceProvider: ResourceProvider,
@@ -546,14 +543,10 @@ constructor(
// In that case use the name from savedBeneficiaryEntity
val payeeName = validateVpaData.name.ifBlank { savedBeneficiaryEntity.name }
val bankCodeList =
if (validateVpaData.bankCode.isNotNullAndNotEmpty()) listOf(validateVpaData.bankCode)
else emptyList()
val bankEntityMap =
bankRepository.getBankUiModelMapFromBankCodes(
bankCodeList = bankCodeList.map { it.orEmpty() }
)
val bankImgUrl = bankEntityMap[validateVpaData.bankCode]?.iconUrl ?: EMPTY
val bankImgUrl =
validateVpaData.bankCode
?.let { getBankIconUrlFromBankCode(validateVpaData.bankCode) }
.orEmpty()
val payeeEntity =
PayeeEntity(

View File

@@ -9,9 +9,9 @@ package com.navi.pay.management.upinumber.list.model.network
import com.google.gson.annotations.SerializedName
import com.navi.common.R
import com.navi.pay.common.utils.getBankIconUrlFromBankCode
import com.navi.pay.management.upinumber.list.model.view.UpiNumber
import com.navi.pay.management.upinumber.list.model.view.UpiNumberLinkedAccountEntity
import com.navi.pay.onboarding.account.add.model.view.BankUiModel
import com.navi.pay.utils.UPI_NUMBER_STATUS_ACTIVE
import com.navi.pay.utils.getMaskedAccountNumber
@@ -40,12 +40,10 @@ data class UpiNumberResponseItem(
@SerializedName("status") val status: String,
)
fun List<UpiNumberAccountResponseItem>.toUpiNumberLinkedAccountEntity(
bankCodeToBankUiModelMap: Map<String, BankUiModel>
): List<UpiNumberLinkedAccountEntity> {
fun List<UpiNumberAccountResponseItem>.toUpiNumberLinkedAccountEntity():
List<UpiNumberLinkedAccountEntity> {
val upiNumberEntities =
this.map {
val bankLogoUrl = bankCodeToBankUiModelMap[it.bankCode]?.iconUrl ?: ""
val upiNumbers: List<UpiNumber> =
it.customerVpas?.flatMap { customerVpa ->
customerVpa.upiNumbers?.map { upiNumber ->
@@ -59,7 +57,7 @@ fun List<UpiNumberAccountResponseItem>.toUpiNumberLinkedAccountEntity(
UpiNumberLinkedAccountEntity(
fallbackBankLogoResId = R.drawable.ic_upi_bbps_default_bank_logo,
bankLogoUrl = bankLogoUrl,
bankLogoUrl = getBankIconUrlFromBankCode(it.bankCode),
bankCode = it.bankCode,
bankName = it.bankName,
maskedAccountNumber = it.maskedAccountNumber.getMaskedAccountNumber(),

View File

@@ -41,7 +41,6 @@ import com.navi.pay.management.upinumber.list.model.view.UpiNumberScreenBottomSh
import com.navi.pay.management.upinumber.list.model.view.UpiSettingsScreenState
import com.navi.pay.management.upinumber.list.repository.UpiNumberRepository
import com.navi.pay.onboarding.account.add.model.view.AccountType
import com.navi.pay.onboarding.account.add.repository.BankRepository
import com.navi.pay.onboarding.account.common.model.view.VpaEntity
import com.navi.pay.onboarding.account.common.model.view.VpaStatus
import com.navi.pay.utils.DEEPLINK_URL
@@ -73,7 +72,6 @@ class UpiNumberViewModel
constructor(
private val upiNumberRepository: UpiNumberRepository,
private val deviceInfoProvider: DeviceInfoProvider,
private val bankRepository: BankRepository,
private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler,
private val linkedAccountsUseCase: LinkedAccountsUseCase,
private val checkUpiNumberAvailabilityUseCase: CheckUpiNumberAvailabilityUseCase,
@@ -221,18 +219,10 @@ constructor(
metricInfo = getMetricInfo(screenName = screenName),
)
if (response.isSuccessWithData()) {
val savedBankUiModelMapFromBankCodes =
bankRepository.getBankUiModelMapFromBankCodes(
bankCodeList = response.data?.accounts?.map { it.bankCode } ?: listOf()
)
val upiNumberEntities =
response.data
?.accounts
?.toUpiNumberLinkedAccountEntity(
bankCodeToBankUiModelMap = savedBankUiModelMapFromBankCodes
)
?.sortedBy { !it.isPrimary } ?: listOf()
response.data?.accounts?.toUpiNumberLinkedAccountEntity()?.sortedBy {
!it.isPrimary
} ?: listOf()
upiNumberLinkedAccountEntities.refresh(upiNumberEntities)
updateAddNewNonMobileNumberUpiNumberFlag()

View File

@@ -12,6 +12,11 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
import com.navi.pay.utils.NAVI_PAY_DATABASE_BANK_TABLE_NAME
/**
* Stores PSP-specific feature support using **DB tags** (pipe-separated).
* - **Example:** If JUSPAY_AXIS (A0) and SWITCH_ICICI (A1) support UPI Lite: `isUpiLiteSupported =
* "A0|A1"`
*/
@Entity(tableName = NAVI_PAY_DATABASE_BANK_TABLE_NAME)
data class BankEntity(
@PrimaryKey @ColumnInfo(name = "code") val code: String,

View File

@@ -8,10 +8,19 @@
package com.navi.pay.onboarding.account.common.model.view
enum class VpaStatus {
/** VPA is active and can be used for transactions. */
ACTIVE,
/** VPA is deactivated either manually by the user or due to OC180 compliance. */
INACTIVE,
/** Account is not yet added on the respective PSP. */
PENDING_ADDITION,
/** Account has been removed from the respective PSP. */
VPA_REMOVED,
/** User has deregistered from Navi UPI. */
CUSTOMER_DEREGISTERED;
companion object {

View File

@@ -166,7 +166,20 @@ fun LinkedAccountVerifyScreen(
Unit
}
LaunchedEffect(Unit) { linkedAccountVerifyViewModel.navigateBack.collect { onBackClick() } }
LaunchedEffect(Unit) {
launch { linkedAccountVerifyViewModel.navigateBack.collect { onBackClick() } }
launch {
linkedAccountVerifyViewModel.finishWithResult.collect { intent ->
naviPayActivity.setResult(UPI_RESULT_CODE, intent)
naviPayActivity.finish()
}
}
launch {
linkedAccountVerifyViewModel.navigateBackWithResult.collect { result ->
resultNavigator.navigateBack(result)
}
}
}
val bottomSheetState =
rememberModalBottomSheetState(
@@ -319,27 +332,7 @@ fun LinkedAccountVerifyScreen(
lottieFileName = NAVI_PAY_SUCCESS_LOTTIE,
titleResId = R.string.pin_set_success_header,
onAnimationEnd = {
scope.launch {
if (linkedAccountVerifyViewModel.shouldFinishWithResult) {
naviPayActivity.setResult(
UPI_RESULT_CODE,
NaviPaySdkUtils.getSetPinSuccessIntent(
linkedAccountsEntity =
linkedAccountVerifyViewModel.linkedAccounts.value,
naviCacheRepository =
linkedAccountVerifyViewModel.naviCacheRepository,
),
)
naviPayActivity.finish()
} else {
resultNavigator.navigateBack(
result =
(accountVerifyScreenStates
as LinkedAccountVerifyScreenStates.SetPinSuccess)
.setPinResult
)
}
}
linkedAccountVerifyViewModel.onNavigateAfterAnimation(accountVerifyScreenStates)
},
)
}
@@ -349,27 +342,7 @@ fun LinkedAccountVerifyScreen(
lottieFileName = NAVI_PAY_SUCCESS_LOTTIE,
titleResId = R.string.pin_set_success_header,
onAnimationEnd = {
scope.launch {
if (linkedAccountVerifyViewModel.shouldFinishWithResult) {
naviPayActivity.setResult(
UPI_RESULT_CODE,
NaviPaySdkUtils.getSetPinSuccessIntent(
linkedAccountsEntity =
linkedAccountVerifyViewModel.linkedAccounts.value,
naviCacheRepository =
linkedAccountVerifyViewModel.naviCacheRepository,
),
)
naviPayActivity.finish()
} else {
resultNavigator.navigateBack(
result =
(accountVerifyScreenStates
as LinkedAccountVerifyScreenStates.ForgotPinSuccess)
.setPinResult
)
}
}
linkedAccountVerifyViewModel.onNavigateAfterAnimation(accountVerifyScreenStates)
},
)
}

View File

@@ -7,6 +7,7 @@
package com.navi.pay.onboarding.account.detail.viewmodel
import android.content.Intent
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.google.gson.reflect.TypeToken
@@ -33,6 +34,7 @@ import com.navi.pay.common.usecase.RefreshLinkedAccountsUseCase
import com.navi.pay.common.usecase.UpiRequestIdUseCase
import com.navi.pay.common.utils.DeviceInfoProvider
import com.navi.pay.common.utils.NaviPayCommonUtils
import com.navi.pay.common.utils.NaviPaySdkUtils
import com.navi.pay.common.utils.getBankNameAccountNumberText
import com.navi.pay.common.utils.getMetricInfo
import com.navi.pay.common.viewmodel.NaviPayBaseVM
@@ -165,6 +167,12 @@ constructor(
private val _navigateBack = MutableSharedFlow<Unit>()
val navigateBack = _navigateBack.asSharedFlow()
private val _finishWithResult = MutableSharedFlow<Intent>()
val finishWithResult = _finishWithResult.asSharedFlow()
private val _navigateBackWithResult = MutableSharedFlow<SetPinResult>()
val navigateBackWithResult = _navigateBackWithResult.asSharedFlow()
private val _bottomSheetStateHolder =
MutableStateFlow(
LinkedAccountVerifyBottomSheetStateHolder(
@@ -264,6 +272,14 @@ constructor(
_navigateBack.emit(Unit)
}
private suspend fun triggerNavigateBackWithResult(setPinResult: SetPinResult) {
_navigateBackWithResult.emit(setPinResult)
}
private suspend fun triggerFinishWithResult(intent: Intent) {
_finishWithResult.emit(intent)
}
fun onAadhaarNumberChanged(aadhaarNumber: String) {
val aadhaarNumberDigits = aadhaarNumber.filter { it.isDigit() }
if (aadhaarNumberDigits.length > AADHAAR_NUMBER_INPUT_MAX_LENGTH) return
@@ -632,6 +648,27 @@ constructor(
}
}
fun onNavigateAfterAnimation(state: LinkedAccountVerifyScreenStates) {
viewModelScope.launch {
if (shouldFinishWithResult) {
triggerFinishWithResult(
NaviPaySdkUtils.getSetPinSuccessIntent(
linkedAccountsEntity = linkedAccounts.value,
naviCacheRepository = naviCacheRepository,
)
)
} else {
val result =
when (state) {
is LinkedAccountVerifyScreenStates.SetPinSuccess -> state.setPinResult
is LinkedAccountVerifyScreenStates.ForgotPinSuccess -> state.setPinResult
else -> return@launch
}
triggerNavigateBackWithResult(result)
}
}
}
private suspend fun getOtpResponse(
linkedAccountEntity: LinkedAccountEntity,
otpRequestType: String? = null,