NTP-53051 | Show NAV applicability in purchase journey (#15687)

This commit is contained in:
Varun Jain
2025-04-09 16:31:38 +05:30
committed by GitHub
parent 11ec648a7b
commit 82ff18a316
10 changed files with 215 additions and 9 deletions

View File

@@ -12,6 +12,7 @@ import com.google.gson.annotations.SerializedName
import com.navi.amc.fundbuy.models.AmcHeaderData
import com.navi.amc.fundbuy.models.BankDetailsData
import com.navi.amc.fundbuy.models.LabelData
import com.navi.amc.fundbuy.models.NavInfoData
import com.navi.amc.fundbuy.models.RewardsData
import com.navi.design.textview.model.TextWithStyle
import kotlinx.parcelize.Parcelize
@@ -37,6 +38,7 @@ data class OptionCardLayoutData(
@SerializedName("note") val note: InformationCardData? = null,
@SerializedName("rewards") val rewards: RewardsData? = null,
@SerializedName("accountFooter") val accountFooter: Footer? = null,
@SerializedName("navInfoData") val navInfoData: NavInfoData? = null,
)
@Parcelize

View File

@@ -51,6 +51,7 @@ import com.navi.amc.utils.Constant.DISMISS
import com.navi.amc.utils.Constant.FREQUENCY
import com.navi.amc.utils.Constant.INVESTMENT_TYPE
import com.navi.amc.utils.Constant.ORDER_AMOUNT
import com.navi.amc.utils.Constant.PAYMENT_MODE
import com.navi.amc.utils.Constant.SHOW_BOTTOMSHEET
import com.navi.amc.utils.Constant.SIP_DATE
import com.navi.amc.utils.Constant.TO_SHOW_LUMPSUM_RECOMMENDATION
@@ -73,6 +74,7 @@ import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.base.utils.isNull
import com.navi.base.utils.orFalse
import com.navi.base.utils.orZero
import com.navi.base.utils.toDoubleWithSafe
import com.navi.common.animation.slideInFromTop
import com.navi.common.animation.snapOut
import com.navi.common.listeners.FragmentInterchangeListener
@@ -95,6 +97,8 @@ import com.navi.naviwidgets.base.InputWidgetModel
import com.navi.naviwidgets.callbacks.WidgetCallback
import com.navi.naviwidgets.databinding.RewardCalloutWidgetLayoutBinding
import com.navi.naviwidgets.databinding.TimerWithImageWidgetLayoutBinding
import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler
import com.navi.naviwidgets.extensions.setImageFieldData
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
import com.navi.naviwidgets.models.RewardCalloutWidget
import com.navi.naviwidgets.models.RewardCalloutWidgetData
@@ -230,6 +234,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
private fun sipSelected() {
binding.sipFrequency.visibility = View.VISIBLE
binding.navInfoData.root.visibility = View.GONE
if (viewModel.sipType.isNullOrEmpty().not()) {
if (!viewModel.toHideDate) binding.date.visibility = View.VISIBLE
binding.sipAmount.visibility = View.VISIBLE
@@ -279,6 +284,26 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
binding.sipRecommended.isVisible = false
binding.lumpsumRecommended.isVisible = true
binding.lumpsumRecommended.refreshChipWidth(binding.lumpsumRecommended)
viewModel.fundBuyScreenData.value?.content?.navInfoData?.let { data ->
binding.navInfoData.navInfoLl.isVisible = true
binding.navInfoData.root.isVisible = true
binding.navInfoData.navInfoLl.background =
getNaviDrawable(
backgroundColor = data.properties?.bgColor.parseColorSafe(),
radii =
CornerRadius(
leftTop = dpToPx(data.properties?.radius?.leftTop.orZero()),
rightTop = dpToPx(data.properties?.radius?.rightTop.orZero()),
rightBottom = dpToPx(data.properties?.radius?.rightBottom.orZero()),
leftBottom = dpToPx(data.properties?.radius?.leftBottom.orZero()),
),
)
binding.navInfoData.navInfo.setSpannableString(data.title)
binding.navInfoData.navInfoIcon.setImageFieldData(data.icon)
binding.navInfoData.root.addOnMultipleClicksHandler {
data.actionData?.let { actionData -> actionListener(actionData) }
}
}
viewModel.fundBuyScreenData.value?.content?.fundInvestmentType?.lumpsumPaymentMode?.let {
binding.lumpsumPaymentCard.isVisible = true
@@ -680,7 +705,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
actionData.parameters
?.singleOrNull { pair -> pair.key == Constant.LUMPSUM }
?.value
val bundle = Bundle().apply { putString(Constant.DATA, data) }
val bundle = Bundle().apply { putString(DATA, data) }
val bottomSheet = CutOffTimeBankBottomSheet.newInstance(bundle)
safelyShowBottomSheet(bottomSheet, CutOffTimeBankBottomSheet.SCREEN)
}
@@ -969,6 +994,37 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
NotificationConstants.DISMISS -> {
// Do nothing
}
SHOW_BOTTOMSHEET -> {
var data = action.parameters?.getOrNull(0)?.value
val key = action.parameters?.getOrNull(0)?.key
if (key == "AMC_PAYMENT_BOTTOMSHEET") {
if (
viewModel.sipAmount.toDoubleWithSafe() >
viewModel.paymentModeLimit.toDoubleWithSafe()
) {
data = action.parameters?.getOrNull(1)?.value
}
}
val bundle =
Bundle().apply {
putString(DATA, data)
putString(PAYMENT_MODE, buyFlowVM.paymentMode.value)
}
key?.let { key ->
getBottomSheet(
key,
bundle,
genericListener = { action ->
if (key == "AMC_PAYMENT_BOTTOMSHEET") {
viewModel.setPaymentMode(action)
} else {
actionListener(action)
}
},
)
?.let { safelyShowBottomSheet(it, key) }
}
}
else -> {
fragmentInterchangeListener?.navigateToNextScreen(action)
}
@@ -1160,7 +1216,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
val bundle =
Bundle().apply {
putParcelable(Constant.CALENDAR_DATA, viewModel.getCalendarData())
putParcelableArrayList(Constant.DATA, data as ArrayList<LineItem>)
putParcelableArrayList(DATA, data as ArrayList<LineItem>)
}
safelyShowDialogFragment(
@@ -1276,7 +1332,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
}
}
val bundle = Bundle().apply { putString(Constant.DATA, bottomSheetData) }
val bundle = Bundle().apply { putString(DATA, bottomSheetData) }
getBottomSheet(
SubPageStatusType.AMC_COMMON_BOTTOMSHEET,
bundle = bundle,
@@ -1293,7 +1349,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
sendEvent(
getCreateSipEventName(),
hashMapOf(
Pair(AmcAnalytics.IS_VALID, AmcAnalytics.FALSE),
Pair(AmcAnalytics.IS_VALID, FALSE),
Pair(
AmcAnalytics.FUND_ID,
arguments?.getString(AmcAnalytics.ISIN).orEmpty(),
@@ -1388,7 +1444,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
sendEvent(
getCreateSipEventName(),
hashMapOf(
Pair(AmcAnalytics.IS_VALID, AmcAnalytics.FALSE),
Pair(AmcAnalytics.IS_VALID, FALSE),
Pair(
AmcAnalytics.FUND_ID,
arguments?.getString(AmcAnalytics.ISIN).orEmpty(),
@@ -1442,7 +1498,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
val bottomSheetData = viewModel.getLumpsumBottomSheetData()
bottomSheetData?.let {
val bsheetDataBundle = Bundle().apply { putString(Constant.DATA, it) }
val bsheetDataBundle = Bundle().apply { putString(DATA, it) }
getBottomSheet(
SubPageStatusType.AMC_COMMON_BOTTOMSHEET,
bundle = bsheetDataBundle,
@@ -1458,7 +1514,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
sendEvent(
AmcAnalytics.AMC_BTN_INVEST_SETUP_CREATE_LUMPSUM,
hashMapOf(
Pair(AmcAnalytics.IS_VALID, AmcAnalytics.FALSE),
Pair(AmcAnalytics.IS_VALID, FALSE),
Pair(
AmcAnalytics.FUND_ID,
arguments?.getString(AmcAnalytics.ISIN).orEmpty(),
@@ -1472,7 +1528,7 @@ class FundBuyingFragmentV2 : AmcBaseFragment(), WidgetCallback {
sendEvent(
viewModel.getSelectedFooter()?.nextCta?.metaData?.clickedData,
hashMapOf(
Pair(AmcAnalytics.IS_VALID, AmcAnalytics.FALSE),
Pair(AmcAnalytics.IS_VALID, FALSE),
Pair(
AmcAnalytics.FUND_ID,
arguments?.getString(AmcAnalytics.ISIN).orEmpty(),

View File

@@ -117,6 +117,7 @@ import com.navi.naviwidgets.base.InputWidgetModel
import com.navi.naviwidgets.callbacks.WidgetCallback
import com.navi.naviwidgets.databinding.RewardCalloutWidgetLayoutBinding
import com.navi.naviwidgets.databinding.TimerWithImageWidgetLayoutBinding
import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler
import com.navi.naviwidgets.extensions.setImageFieldData
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
import com.navi.naviwidgets.models.RewardCalloutWidget
@@ -289,6 +290,7 @@ class FundBuyingFragmentV3 : AmcBaseFragment(), WidgetCallback {
private fun sipSelected() {
binding.sipAmount.visibility = View.VISIBLE
binding.navInfoData.root.isVisible = false
binding.sipRecommended.isVisible = viewModel.toShowSipRecommended
binding.sipRecommended.refreshChipWidth(binding.sipRecommended)
binding.sipFrequency.visibility = View.VISIBLE
@@ -340,6 +342,24 @@ class FundBuyingFragmentV3 : AmcBaseFragment(), WidgetCallback {
binding.lumpsumAmount.visibility = View.VISIBLE
binding.sipRecommended.isVisible = false
binding.lumpsumRecommended.isVisible = true
viewModel.fundBuyScreenData.value?.content?.navInfoData?.let { data ->
binding.navInfoData.navInfoLl.isVisible = true
binding.navInfoData.root.isVisible = true
binding.navInfoData.navInfoLl.background =
getNaviDrawable(
backgroundColor = data.properties?.bgColor.parseColorSafe(),
radii =
CornerRadius(
leftTop = dpToPx(data.properties?.radius?.leftTop.orZero()),
rightTop = dpToPx(data.properties?.radius?.rightTop.orZero()),
rightBottom = dpToPx(data.properties?.radius?.rightBottom.orZero()),
leftBottom = dpToPx(data.properties?.radius?.leftBottom.orZero()),
),
)
binding.navInfoData.navInfo.setSpannableString(data.title)
binding.navInfoData.navInfoIcon.setImageFieldData(data.icon)
binding.navInfoData.root.addOnMultipleClicksHandler { handleOnClick(data.actionData) }
}
binding.sipRecommended.refreshChipWidth(
binding.lumpsumRecommended
) // can add a counter to run this only for first iteration

View File

@@ -58,6 +58,7 @@ import com.navi.design.textview.model.NaviSpan
import com.navi.design.textview.model.TextWithStyle
import com.navi.design.utils.*
import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler
import com.navi.naviwidgets.extensions.setImageFieldData
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
import com.navi.naviwidgets.utils.getGradientDrawable
import com.navi.payment.listener.PaymentListener
@@ -198,6 +199,29 @@ class PaymentSummaryFragment : AmcBaseFragment() {
if (response.content?.accountFooter != null) {
binding.footer.root.isVisible = false
binding.accountFooter.root.isVisible = true
response.content.navInfoData?.let { data ->
binding.navInfoData.navInfoLl.isVisible = true
binding.navInfoData.root.isVisible = true
binding.navInfoData.navInfoLl.background =
getNaviDrawable(
backgroundColor = data.properties?.bgColor.parseColorSafe(),
radii =
CornerRadius(
leftTop = dpToPx(data.properties?.radius?.leftTop.orZero()),
rightTop =
dpToPx(data.properties?.radius?.rightTop.orZero()),
rightBottom =
dpToPx(data.properties?.radius?.rightBottom.orZero()),
leftBottom =
dpToPx(data.properties?.radius?.leftBottom.orZero()),
),
)
binding.navInfoData.navInfo.setSpannableString(data.title)
binding.navInfoData.navInfoIcon.setImageFieldData(data.icon)
binding.navInfoData.root.addOnMultipleClicksHandler {
onFooterClick(footer = Footer(nextCta = data.actionData))
}
}
binding.accountFooter.title.setSpannableString(
response.content.accountFooter.title
)

View File

@@ -18,11 +18,13 @@ import com.navi.common.model.Header
import com.navi.common.model.LabelDataVariation
import com.navi.design.textview.model.TextWithStyle
import com.navi.design.textview.model.TextWithStyleVariation
import com.navi.naviwidgets.models.CardProperties
import com.navi.naviwidgets.models.NaviWidget
import com.navi.naviwidgets.models.RewardCalloutWidgetData
import com.navi.naviwidgets.models.SingleSelectionBottomSheetData
import com.navi.naviwidgets.models.TimerWithImageWidgetData
import com.navi.naviwidgets.models.response.CardType
import com.navi.naviwidgets.models.response.ImageFieldData
import kotlinx.parcelize.Parcelize
data class FundBuyScreenData(
@@ -56,6 +58,7 @@ data class FundBuyData(
@SerializedName("cutOffTimeData") val cutOffData: TimerWithImageWidgetData? = null,
@SerializedName("paymentModeLimit") val paymentModeLimit: String? = null,
@SerializedName("onTimeAssuranceData") val onTimeAssuranceData: OnTimeAssuranceData? = null,
@SerializedName("navInfoData") val navInfoData: NavInfoData? = null,
)
open class GenericFooter(
@@ -180,3 +183,10 @@ data class InstallmentDateMap(
@SerializedName("amountLessThanMandate") val amountLessThanMandate: String? = null,
@SerializedName("amountGreaterThanMandate") val amountGreaterThanMandate: String? = null,
)
data class NavInfoData(
@SerializedName("title") val title: TextWithStyle? = null,
@SerializedName("icon") val icon: ImageFieldData? = null,
@SerializedName("properties") val properties: CardProperties? = null,
@SerializedName("actionData") val actionData: ActionData? = null,
)

View File

@@ -103,6 +103,7 @@
android:id="@+id/image_banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="parent"
android:layout_marginHorizontal="@dimen/dp_16"

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
@@ -386,6 +387,17 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
android:id="@+id/nav_info_data"
layout="@layout/nav_info_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintBottom_toTopOf="@id/payment_footer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
android:id="@+id/payment_footer"
layout="@layout/payment_btn_layout"

View File

@@ -403,11 +403,23 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
android:id="@+id/nav_info_data"
layout="@layout/nav_info_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintBottom_toTopOf="@id/payment_footer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
android:id="@+id/payment_footer"
layout="@layout/payment_btn_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:visibility="visible"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/nav_info_ll"
android:layout_marginHorizontal="@dimen/dp_16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/ctaSecondaryColor"
android:paddingHorizontal="@dimen/dp_16"
android:paddingVertical="@dimen/dp_8"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<com.navi.design.textview.NaviTextView
android:id="@+id/nav_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:textSize="@dimen/_10sp"
android:visibility="gone"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="@id/nav_info_ll"
app:layout_constraintEnd_toStartOf="@id/nav_info_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/nav_info_ll"
tools:text="NAV depends on your order time and payment method"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/nav_info_icon"
android:layout_width="@dimen/dp_12"
android:layout_height="@dimen/dp_12"
android:layout_marginStart="@dimen/dp_8"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/nav_info"
app:layout_constraintEnd_toEndOf="@id/nav_info_ll"
app:layout_constraintStart_toEndOf="@id/nav_info"
app:layout_constraintTop_toTopOf="@id/nav_info"
tools:src="@drawable/info_icon_purple"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
@@ -120,7 +121,17 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
android:id="@+id/nav_info_data"
layout="@layout/nav_info_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"
android:layout_marginHorizontal="@dimen/dp_16"
app:layout_constraintBottom_toTopOf="@id/account_footer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
android:id="@+id/account_footer"
layout="@layout/new_footer_layout"