TP-47206 | Repeat and Top Up Revamp on AP (#9732)

Co-authored-by: Hitesh Kumar <hitesh.kumar@navi.com>
This commit is contained in:
Anupam Kumar
2024-02-13 20:20:03 +05:30
committed by GitHub
parent dab5938986
commit a7e121ad80
19 changed files with 561 additions and 18 deletions

View File

@@ -9,6 +9,7 @@ package com.navi.ap.common.deserializer
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonElement
import com.navi.ap.common.models.CalendarWidgetData
import com.navi.ap.common.models.CardWithHeaderFooterAndLazyColumnWidgetData
import com.navi.ap.common.models.CollapsableItemsWithTitleWidgetData
import com.navi.ap.common.models.CustomWidgets
@@ -31,14 +32,25 @@ class CustomUiTronDataDeserializer : UiTronDataDeserializer() {
return when (jsonObject["viewType"].asString) {
CustomWidgets.COLLAPSABLE_ITEMS_WITH_TITLE_WIDGET.name ->
context?.deserialize(json, CollapsableItemsWithTitleWidgetData::class.java)
CustomWidgets.DYNAMIC_GRID_WIDGET.name ->
context?.deserialize(json, DynamicGridWidgetData::class.java)
CustomWidgets.DYNAMIC_COLUMN_WIDGET.name ->
context?.deserialize(json, DynamicColumnWidgetData::class.java)
CustomWidgets.DYNAMIC_ROW_WIDGET.name ->
context?.deserialize(json, DynamicRowWidgetData::class.java)
CustomWidgets.CARD_WITH_HEADER_FOOTER_AND_LAZY_COLUMN_WIDGET.name ->
context?.deserialize(json, CardWithHeaderFooterAndLazyColumnWidgetData::class.java)
context?.deserialize(
json,
CardWithHeaderFooterAndLazyColumnWidgetData::class.java
)
CustomWidgets.CALENDAR_WIDGET.name ->
context?.deserialize(json, CalendarWidgetData::class.java)
else -> super.deserialize(json, typeOfT, context)
}
}

View File

@@ -24,7 +24,7 @@ class LambdaFactory(
bridge: LambdaBridge
): Lambda {
return when (applicationType) {
ApplicationType.PL.name, ApplicationType.PL_REFILL.name -> PLLambdaHandler(bridge)
ApplicationType.PL.name, ApplicationType.PL_REPEAT.name,ApplicationType.PL_TOP_UP.name , ApplicationType.PL_REFILL.name-> PLLambdaHandler(bridge)
ApplicationType.COINS.name -> CoinsLambdaHandler(bridge)
else -> DefaultLambdaHandler(bridge)
}

View File

@@ -136,6 +136,12 @@ internal class PLLambdaHandler(
)
}
LambdaType.FETCH_CALENDER_DETAILS.name -> {
lambdaImpl.fetchCalendarDetails(
lambadaData.resolvedValue.toMutableMap()
)
}
else -> {
super.execute(lambdaApiAction, lambadaData)
}

View File

@@ -105,6 +105,7 @@ internal class PLLambdaImpl(
val amount = resolvedValues[SELECTED_LOAN_AMOUNT]?.toString()
var tenure = resolvedValues[SELECTED_TENURE]?.toString()
val emiPlanSelected = resolvedValues[SELECTED_TENURE_PILL_INDEX]?.toString()
val offerType = resolvedValues[OFFER_TYPE]?.toString()
if (savedAmount == amount && savedTenure == tenure && savedAmount.isNotNull() && savedTenure.isNotNull()) return@launch
@@ -117,7 +118,7 @@ internal class PLLambdaImpl(
}
val lambdaResponse = repository.fetchOfferDetails(
amount = amount, tenureInMonths = tenure, emiPlansSelected = emiPlanSelected
amount = amount, tenureInMonths = tenure, emiPlansSelected = emiPlanSelected, offerType = offerType
)
lambdaHandler.bridge.setLambdaState(
when {
@@ -844,7 +845,7 @@ internal class PLLambdaImpl(
lambdaResponse.data.isNotNull() -> {
val updatedLambdaApiAction =
PathInjector<LambdaApiAction, Any?>().injectData(
lambdaApiAction, lambdaResponse.data!!
lambdaApiAction, lambdaResponse.data
)
lambdaHandler.bridge.executeActions(updatedLambdaApiAction.onSuccess)
LambdaState.Success(LambdaResponseType())
@@ -905,7 +906,7 @@ internal class PLLambdaImpl(
)
val updatedLambdaApiAction = PathInjector<LambdaApiAction, Any?>().injectData(
lambdaApiAction, lambdaResponse.data!!
lambdaApiAction, lambdaResponse.data
)
updatedResponse?.let {
lambdaHandler.bridge.setMetaData(updatedResponse.screenData?.metaData ?: mapOf())
@@ -1058,6 +1059,64 @@ internal class PLLambdaImpl(
}
}
fun fetchCalendarDetails(
resolvedValues: MutableMap<String, Any?>
) {
lambdaHandler.bridge.getViewModelScope().launch(Dispatchers.IO) {
if (lambdaHandler.getClonedScreenDefinitionState().isNull()) {
lambdaHandler.setClonedScreenDefinitionState(lambdaHandler.bridge.getScreenStructurePreRenderState())
}
lambdaHandler.bridge.setLambdaState(LambdaState.Loading)
val lambdaResponse = repository.fetchOfferDetails(
fetchEmiDates = resolvedValues[FETCH_EMI_DATES]?.toString()?.toBoolean()
)
lambdaHandler.bridge.setLambdaState(
when {
lambdaResponse.data.isNotNull() && lambdaHandler.getClonedScreenDefinitionState().isNotNull() -> {
val updatedResponse =
BasePathInjector<ApScreenDefinitionStructure, Any?>().injectData(
lambdaHandler.getClonedScreenDefinitionState(),
lambdaResponse.data
)
updatedResponse?.let {
lambdaHandler.bridge.setScreenDefinitionState(
ApScreenDefinitionState.Success(updatedResponse)
)
}
LambdaState.Success(LambdaResponseType())
}
lambdaResponse.errorBottomSheetStructure.isNotNull() -> {
LambdaState.Error(
lambdaResponse.statusCode,
lambdaResponse.errorBottomSheetStructure,
lambdaResponse.genericErrorBottomSheetFields
)
}
lambdaResponse.isNull() -> {
val errorBottomSheetFields = BottomSheetHelper.getLambdaErrorBottomSheet(
ApiType.LambdaApiAction.name
)
LambdaState.Error(
lambdaResponse.statusCode,
getBottomSheetStructure(errorBottomSheetFields),
errorBottomSheetFields
)
}
else -> {
LambdaState.Nothing
}
}
)
}
}
fun initiateAgreementAndSanctionLetterDownload(
resolvedValues: MutableMap<String, Any?>,
lambdaApiAction: LambdaApiAction,

View File

@@ -59,12 +59,16 @@ class PLLambdaRepository @Inject constructor(private val retrofitService: APRetr
amount: String? = null,
tenureInMonths: String? = null,
emiPlansSelected: String? = null,
fetchEmiDates: Boolean? = false,
offerType: String? = null
): ApRepoResult<Any> {
val response =
retrofitService.getOfferDetails(
amount = amount,
tenureInMonths = tenureInMonths,
emiPlansSelected = emiPlansSelected
emiPlansSelected = emiPlansSelected,
fetchEmiDates = fetchEmiDates,
offerType = offerType
)
logApEvent(
Pair(

View File

@@ -0,0 +1,14 @@
package com.navi.ap.common.models
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class CalendarData(
@SerializedName("rawDate") val rawDate: Int,
@SerializedName("formattedDate") val formattedDate: String,
@SerializedName("isEnabled") val isEnabled: Boolean,
@SerializedName("textInWords") val textInWords: String,
@SerializedName("dateWithSuffix") val dateWithSuffix: String,
) : Parcelable

View File

@@ -0,0 +1,63 @@
package com.navi.ap.common.models
import android.os.Parcelable
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.navi.uitron.model.data.TextData
import com.navi.uitron.model.data.UiTronData
import com.navi.uitron.model.ui.ColumnProperty
import com.navi.uitron.model.ui.ImageProperty
import com.navi.uitron.model.ui.TextProperty
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.RawValue
@Parcelize
data class CalendarWidgetData(
@SerializedName("selectedDate") var selectedDate: String? = null,
@SerializedName("layoutId") var layoutId: String? = null,
@SerializedName("errorLayoutId") var errorLayoutId: String? = null,
@SerializedName("emiDates") val emiDates: @RawValue Any? = null,
@SerializedName("calendarProperties") var calendarProperties: ColumnProperty? = null,
@SerializedName("calendarPadding") val calendarPadding: String? = null,
@SerializedName("calendarRowGap") val calendarRowGap: String? = null,
@SerializedName("dateBoxSize") val dateBoxSize: String? = null,
@SerializedName("calendarColors") val calendarColors: CalendarColors? = null,
@SerializedName("calendarTextProperty") val calendarTextProperty: TextProperty? = null,
@SerializedName("errorTextProperty") val errorTextProperty: TextProperty? = null,
@SerializedName("errorIconProperty") val errorIconProperty: ImageProperty? = null,
@SerializedName("errorImageUrl") val errorImageUrl: String? = null,
@SerializedName("errorMessage") val errorMessage: TextData? = null,
) : UiTronData(), Parcelable {
@IgnoredOnParcel
val emiDate: List<CalendarData>? = null
get() {
if(field == null){
return getCalendarData()
}
return field
}
private fun getCalendarData(): List<CalendarData>? {
val type = object : TypeToken<List<CalendarData>>() {}.type
return Gson().fromJson(emiDates.toString(), type)
}
@Parcelize
data class CalendarColors(
@SerializedName("calendarBorderColor") val calendarBorderColor: String? = null,
@SerializedName("calendarErrorBorderColor") val calendarErrorBorderColor: String? = null,
@SerializedName("selectedDateColor") val selectedDateColor: String? = null,
@SerializedName("selectedDateTextColor") val selectedDateTextColor: String? = null,
@SerializedName("defaultDateTextColor") val defaultDateTextColor: String? = null,
@SerializedName("disabledDateTextColor") val disabledDateTextColor: String? = null,
) : Parcelable
}

View File

@@ -44,5 +44,6 @@ enum class CustomWidgets {
DYNAMIC_COLUMN_WIDGET,
DYNAMIC_ROW_WIDGET,
DYNAMIC_GRID_WIDGET,
CARD_WITH_HEADER_FOOTER_AND_LAZY_COLUMN_WIDGET
CARD_WITH_HEADER_FOOTER_AND_LAZY_COLUMN_WIDGET,
CALENDAR_WIDGET,
}

View File

@@ -0,0 +1,37 @@
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class LoanSummaryResponse(
@SerializedName("dataList") val dataList: List<EmiResponse>? = null,
@SerializedName("lastEmiData") val lastEmiData: EmiDetails? = null,
@SerializedName("placeHolderKey") val placeHolderKey: String? = null
) : Parcelable
@Parcelize
data class EmiResponse(
@SerializedName("year") val year: String? = null,
@SerializedName("emiDataList") val emiDataList: List<EmiData>? = null
) : Parcelable
@Parcelize
data class EmiData(
@SerializedName("emiDetails") val emiDetails: EmiDetails? = null,
@SerializedName("emiChange") val emiChange: EmiChange? = null
) : Parcelable
@Parcelize
data class EmiDetails(
@SerializedName("month") val month: Int? = null,
@SerializedName("date") val date: String? = null,
@SerializedName("amount") val amount: String? = null,
) : Parcelable
@Parcelize
data class EmiChange(
@SerializedName("originalAmount") val originalAmount: String? = null,
@SerializedName("changedAmount") val changedAmount: String? = null,
) : Parcelable

View File

@@ -0,0 +1,313 @@
package com.navi.ap.common.renderer
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.navi.ap.common.models.CalendarData
import com.navi.ap.common.models.CalendarWidgetData
import com.navi.ap.common.models.WidgetModelDefinition
import com.navi.ap.utils.constants.SELECTED_DATE
import com.navi.ap.utils.constants.SELECTED_DATE_WITH_SUFFIX
import com.navi.ap.utils.constants.SELECTED_FORMATTED_DATE
import com.navi.ap.utils.constants.SELECTED_RAW_DATE
import com.navi.ap.utils.constants.SHOW
import com.navi.ap.utils.constants.WIDGET_DATA
import com.navi.ap.utils.injector.FieldInjector
import com.navi.base.utils.EMPTY
import com.navi.design.theme.getFontFamily
import com.navi.design.theme.getFontWeight
import com.navi.uitron.model.UiTronResponse
import com.navi.uitron.model.data.ImageData
import com.navi.uitron.model.data.UiTronActionData
import com.navi.uitron.render.ImageRenderer
import com.navi.uitron.render.TextRenderer
import com.navi.uitron.utils.ShapeUtil
import com.navi.uitron.viewmodel.UiTronViewModel
import getInputId
import getTextAlignment
import hexToComposeColor
class CalendarWidget {
@Composable
fun Render(viewModel: UiTronViewModel, widget: WidgetModelDefinition<UiTronResponse>) {
val calendarWidgetData: CalendarWidgetData? =
widget.widgetData?.data?.get("$WIDGET_DATA${widget.widgetId}") as? CalendarWidgetData
val updatedSelectedDate = viewModel.handle.get<Int>(SELECTED_RAW_DATE)
?: calendarWidgetData?.selectedDate?.toIntOrNull()
CalendarView(
selectedDateInitial = updatedSelectedDate,
calendarWidgetData = calendarWidgetData ?: CalendarWidgetData(),
viewModel = viewModel,
onClickAction = calendarWidgetData?.onClick
)
}
@Composable
private fun CalendarView(
selectedDateInitial: Int? = null,
calendarWidgetData: CalendarWidgetData,
viewModel: UiTronViewModel,
onClickAction: UiTronActionData?
) {
val daysInMonth = calendarWidgetData.emiDate ?: emptyList()
val disabledDates = daysInMonth.filter { !it.isEnabled }.map { it.rawDate }.toSet()
var selectedDate by remember { mutableStateOf(selectedDateInitial) }
LaunchedEffect(selectedDate) {
if (selectedDate in disabledDates) {
selectedDate = null
}
if (selectedDate == null) return@LaunchedEffect
viewModel.handle[calendarWidgetData.layoutId.getInputId()] = selectedDate.toString()
val textInWord =
calendarWidgetData.emiDate?.firstOrNull { it.rawDate == selectedDate }?.textInWords
val selectedDateWithSuffix =
calendarWidgetData.emiDate?.firstOrNull { it.rawDate == selectedDate }?.dateWithSuffix
viewModel.handle[SELECTED_RAW_DATE] = selectedDate
viewModel.handle[SELECTED_FORMATTED_DATE] =
calendarWidgetData.emiDate?.firstOrNull { it.rawDate == selectedDate }?.formattedDate
val updatedAction = FieldInjector<UiTronActionData, Any>().injectData(
onClickAction, mapOf(
SELECTED_DATE to textInWord,
SELECTED_DATE_WITH_SUFFIX to selectedDateWithSuffix,
SELECTED_RAW_DATE to selectedDate.toString(),
SELECTED_FORMATTED_DATE to calendarWidgetData.emiDate?.firstOrNull { it.rawDate == selectedDate }?.formattedDate
)
)
viewModel.handleActions(updatedAction)
}
CalendarGrid(disabledDates = disabledDates,
daysInMonth = daysInMonth,
selectedDate = selectedDate,
calendarWidgetData = calendarWidgetData,
viewModel = viewModel,
onDateSelected = {
selectedDate = it
})
}
@Composable
private fun CalendarGrid(
disabledDates: Set<Int>,
daysInMonth: List<CalendarData>,
selectedDate: Int? = null,
calendarWidgetData: CalendarWidgetData,
viewModel: UiTronViewModel,
onDateSelected: (Int) -> Unit
) {
val columns = numberOfColumns
val rows = (daysInMonth.size + 6) / columns
Grid(
items = daysInMonth, rows = rows, columns = columns, calendarWidgetData, viewModel
) { day ->
val isDisabled = day.rawDate in disabledDates
val isSelected = day.rawDate == selectedDate
val onClickAction = { if (!isDisabled) onDateSelected(day.rawDate) }
DateColumn(
day = day.rawDate,
isSelected = isSelected,
isDisabled = isDisabled,
calendarWidgetData = calendarWidgetData,
onClick = onClickAction
)
}
}
@Composable
private fun DateColumn(
day: Int,
isSelected: Boolean,
isDisabled: Boolean,
calendarWidgetData: CalendarWidgetData,
onClick: () -> Unit
) {
val selectedColor =
calendarWidgetData.calendarColors?.selectedDateColor?.hexToComposeColor ?: Color(
SELECTED_COLOR
)
val backgroundColor = if (isSelected) selectedColor else Color.Transparent
val textColor = when {
isSelected -> calendarWidgetData.calendarColors?.selectedDateTextColor?.hexToComposeColor
?: Color.White
isDisabled -> calendarWidgetData.calendarColors?.disabledDateTextColor?.hexToComposeColor
?: Color(
DISABLED_COLOR
)
else -> calendarWidgetData.calendarColors?.defaultDateTextColor?.hexToComposeColor
?: Color(DEFAULT_COLOR)
}
val dateColumnModifier = Modifier
.width(calendarWidgetData.dateBoxSize?.toInt()?.dp ?: 26.dp)
.height(calendarWidgetData.dateBoxSize?.toInt()?.dp ?: 26.dp)
.background(backgroundColor, CircleShape)
.clickable(
enabled = !isDisabled,
indication = null,
interactionSource = remember { MutableInteractionSource() },
onClick = onClick
)
Column(
modifier = dateColumnModifier,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = day.toString(),
fontFamily = getFontFamily(calendarWidgetData.calendarTextProperty?.fontFamily),
fontWeight = getFontWeight(calendarWidgetData.calendarTextProperty?.fontWeight),
fontSize = calendarWidgetData.calendarTextProperty?.fontSize?.sp ?: 14.sp,
textAlign = getTextAlignment(calendarWidgetData.calendarTextProperty?.textAlign),
color = textColor
)
}
}
@Composable
private fun <T> Grid(
items: List<T>,
rows: Int,
columns: Int,
calendarWidgetData: CalendarWidgetData,
viewModel: UiTronViewModel,
itemContent: @Composable BoxScope.(T) -> Unit
) {
var showErrorState by remember {
mutableStateOf(false)
}
LaunchedEffect(Unit) {
viewModel.handle.getStateFlow<String?>(
calendarWidgetData.errorLayoutId.toString(), null
).collect {
showErrorState = it == SHOW
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.padding(
calendarWidgetData.calendarProperties?.padding?.start?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.top?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.end?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.bottom?.dp ?: 0.dp
)
.border(
width = calendarWidgetData.calendarProperties?.borderStrokeData?.width?.dp
?: 1.dp,
color = when {
showErrorState -> calendarWidgetData.calendarColors?.calendarErrorBorderColor?.hexToComposeColor
?: Color(ERROR_STATE_COLOR)
else -> calendarWidgetData.calendarColors?.calendarBorderColor?.hexToComposeColor
?: Color(BORDER_COLOR)
},
shape = ShapeUtil.getShape(shape = calendarWidgetData.calendarProperties?.borderStrokeData?.shape)
)
.background(
color = calendarWidgetData.calendarProperties?.backgroundColor?.hexToComposeColor
?: Color.White,
)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(calendarWidgetData.calendarPadding?.toIntOrNull()?.dp ?: 16.dp),
) {
for (i in 0 until rows) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Start,
) {
for (j in 0 until columns) {
val index = i * columns + j
Box(
modifier = Modifier.weight(1f, true),
contentAlignment = Alignment.Center
) {
if (index < items.size) {
itemContent(items[index])
} else {
Text(text = EMPTY)
}
}
if (j != columns - 1) Spacer(modifier = Modifier.weight(0.6f))
}
}
if (i != rows - 1) {
Spacer(
modifier = Modifier
.fillMaxWidth()
.height(calendarWidgetData.calendarRowGap?.toInt()?.dp ?: 10.dp)
)
}
}
}
}
if (showErrorState) {
Row(modifier = Modifier.padding(start = 16.dp, end = 16.dp)) {
calendarWidgetData.errorIconProperty?.let {
ImageRenderer().Render(
property = it,
uiTronData = ImageData(
iconUrl = calendarWidgetData.errorImageUrl,
),
uiTronViewModel = viewModel,
modifier = null
)
}
calendarWidgetData.errorTextProperty?.let {
TextRenderer().Render(
property = it,
uiTronData = calendarWidgetData.errorMessage,
uiTronViewModel = viewModel,
modifier = null
)
}
}
}
}
companion object {
const val ERROR_STATE_COLOR = 0xFFEF0000
const val BORDER_COLOR = 0xFFEBEBEB
const val SELECTED_COLOR = 0xFF1F002A
const val DISABLED_COLOR = 0xFFA8A8A8
const val DEFAULT_COLOR = 0xFF444444
private const val numberOfColumns = 7
}
}

View File

@@ -30,6 +30,7 @@ import coil.size.Size
import com.navi.ap.common.models.CollapsableItemsWithTitleWidgetData
import com.navi.ap.common.models.WidgetModelDefinition
import com.navi.ap.common.viewmodel.ApplicationPlatformVM
import com.navi.ap.utils.constants.WIDGET_DATA
import com.navi.uitron.model.UiTronResponse
import com.navi.uitron.model.data.TextData
import com.navi.uitron.model.ui.TextProperty
@@ -41,7 +42,7 @@ class CollapsableItemsWithTitleWidget {
@Composable
fun Render(viewModel: ApplicationPlatformVM, widget: WidgetModelDefinition<UiTronResponse>) {
val titleDescriptionListWidgetData =
widget.widgetData?.data?.get("widget_data_${widget.widgetId}")
widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}")
as? CollapsableItemsWithTitleWidgetData
Column(
modifier =

View File

@@ -5,6 +5,7 @@ import com.navi.uitron.serializer.UiTronDataSerializer
import com.google.gson.JsonElement
import com.google.gson.JsonSerializationContext
import com.navi.ap.common.models.CalendarWidgetData
import com.navi.ap.common.models.CardWithHeaderFooterAndLazyColumnWidgetData
import com.navi.ap.common.models.CollapsableItemsWithTitleWidgetData
import com.navi.ap.common.models.CustomWidgets
@@ -50,6 +51,12 @@ class CustomUiTronDataSerializer : UiTronDataSerializer() {
)
}
CustomWidgets.CALENDAR_WIDGET.name -> {
context?.serialize(
src as CalendarWidgetData, CalendarWidgetData::class.java
)
}
else -> super.serialize(src, typeOfSrc, context)
}
}

View File

@@ -3,6 +3,7 @@ package com.navi.ap.common.widgetfactory
import androidx.compose.runtime.Composable
import com.navi.ap.common.models.CustomWidgets
import com.navi.ap.common.models.WidgetModelDefinition
import com.navi.ap.common.renderer.CalendarWidget
import com.navi.ap.common.renderer.CardWithHeaderFooterAndLazyColumnWidget
import com.navi.ap.common.renderer.CollapsableItemsWithTitleWidget
import com.navi.ap.common.renderer.DynamicColumnWidget
@@ -21,18 +22,30 @@ fun CustomWidgetRenderer(
CustomWidgets.COLLAPSABLE_ITEMS_WITH_TITLE_WIDGET.name -> {
CollapsableItemsWithTitleWidget().Render(viewModel = viewModel, widget = widget)
}
CustomWidgets.DYNAMIC_COLUMN_WIDGET.name -> {
DynamicColumnWidget().Render(viewModel = viewModel, widget = widget)
}
CustomWidgets.DYNAMIC_ROW_WIDGET.name -> {
DynamicRowWidget().Render(viewModel = viewModel, widget = widget)
}
CustomWidgets.DYNAMIC_GRID_WIDGET.name -> {
DynamicGridWidget().Render(viewModel = viewModel, widget = widget)
}
CustomWidgets.CARD_WITH_HEADER_FOOTER_AND_LAZY_COLUMN_WIDGET.name -> {
CardWithHeaderFooterAndLazyColumnWidget().Render(applicationPlatformVM = viewModel,widget = widget)
CardWithHeaderFooterAndLazyColumnWidget().Render(
applicationPlatformVM = viewModel,
widget = widget
)
}
CustomWidgets.CALENDAR_WIDGET.name -> {
CalendarWidget().Render(viewModel = viewModel, widget = widget)
}
else -> Unit
}
}

View File

@@ -40,9 +40,11 @@ interface PlLambdaService {
@GET("/customer/offer-details")
suspend fun getOfferDetails(
@Query("offerType") offerType: String? = null,
@Query("amount") amount: String? = null,
@Query("tenureInMonths") tenureInMonths: String? = null,
@Query("emiPlansSelected") emiPlansSelected: String? = null,
@Query("fetchEmiDates") fetchEmiDates: Boolean? = null,
@Header("X-Target") target: String = ModuleName.LE.name,
): Response<GenericResponse<Any>>
@@ -53,6 +55,7 @@ interface PlLambdaService {
@Query("emiPlansSelected") emiPlansSelected: String? = null,
@Header("X-Target") target: String = ModuleName.LE.name,
): Response<GenericResponse<Any>>
@POST("/offer/{offerReferenceId}/apply")
suspend fun applyLoan(
@Header("X-Target") target: String = ModuleName.LE.name,

View File

@@ -76,4 +76,9 @@ val noLoaderScreenTypes: MutableSet<String> = mutableSetOf(
const val SUCCESS_CODE = 200
const val FAILURE = "failure"
const val HIDE_LOADER_STATE_ID = "hide_loader_state_id"
const val CUSTOMER_CAPITAL = "CUSTOMER"
const val SELECTED_RAW_DATE = "selectedRawDate"
const val CUSTOMER_CAPITAL = "CUSTOMER"
const val SELECTED_DATE = "selectedDate"
const val SELECTED_DATE_WITH_SUFFIX = "selectedDateWithSuffix"
const val SELECTED_FORMATTED_DATE = "selectedFormattedDate"
const val SHOW = "show"

View File

@@ -68,12 +68,14 @@ enum class LambdaType {
POST_PAYMENT_METHOD_STATUS,
VALIDATE_COINS_UPI_ID,
FETCH_EMI_CALENDER_DETAILS,
DOWNLOAD_LOAN_AGREEMENT_AND_SANCTION_LETTER
DOWNLOAD_LOAN_AGREEMENT_AND_SANCTION_LETTER,
FETCH_CALENDER_DETAILS,
}
enum class ApplicationType{
PL,
PL_REFILL,
COINS
COINS,
PL_REPEAT,
PL_TOP_UP,
PL_REFILL
}

View File

@@ -47,4 +47,7 @@ const val DEFAULT_BANKS_SEARCH_QUERY = ""
const val TRIGGER_LOADING_STATE = "trigger_loading_state"
const val SUCCESS_CAP = "SUCCESS"
const val FAILURE_CAP = "FAILURE"
const val DOCUMENT_TYPE = "documentType"
const val DOCUMENT_TYPE = "documentType"
const val LOAN_APPLICATION_REFERENCE_ID = "loan_application_id"
const val OFFER_TYPE = "offerType"
const val FETCH_EMI_DATES = "fetchEmiDates"

View File

@@ -6,7 +6,7 @@ import java.util.Stack
/**
* Use this to inject values with place holder pattern "key" : "${place_holder}"
* Use this to inject values with place holder pattern "key" : "@{place_holder}"
* place_holder will get replaced with corresponding values in FieldObjectType.
**/
@@ -18,7 +18,7 @@ import java.util.Stack
class FieldInjector<U, V>() : Injector<U, V>() {
override val placeHolderPattern: String
get() = "\${place_holder_name}"
get() = "@\${place_holder_name}"
override fun replacePlaceHolders(configObj: JSONObject, dataObject : JSONObject) {
val dataMap = jsonNodeToMappedValues(dataObject)
@@ -55,7 +55,7 @@ class FieldInjector<U, V>() : Injector<U, V>() {
dataMap: Map<String, Any?>
) {
val value = currentObject.get(key)
if (value is String && value.startsWith('$') && value.length > 3) {
if (value is String && value.startsWith('@') && value.length > 3) {
val trimmedValue = value.trim()
val placeHolderKey = trimmedValue.substring(2, trimmedValue.length - 1)
currentObject.putOpt(key, dataMap[placeHolderKey])