Skip to content

Commit

Permalink
feat: refunds success rate (#1917)
Browse files Browse the repository at this point in the history
  • Loading branch information
sagarnaikjuspay authored Dec 16, 2024
1 parent ed97da4 commit 4693520
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/container/NewAnalyticsContainer.res
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ let make = () => {
if newAnalyticsRefunds {
tabs->Array.push({
title: "Refunds",
renderContent: () => React.null,
renderContent: () => <NewRefundsAnalytics />,
})
}

Expand Down
2 changes: 1 addition & 1 deletion src/screens/NewAnalytics/NewAnalyticsTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type dimension = [
| #refund_error_message
| #refund_reason
]
type status = [#charged | #failure]
type status = [#charged | #failure | #success | #pending]
type metrics = [
| #sessionized_smart_retried_amount
| #sessionized_payments_success_rate
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@react.component
let make = () => {
open NewRefundsAnalyticsEntity

<div className="flex flex-col gap-14 mt-5 pt-7">
<RefundsSuccessRate
entity={refundsSuccessRateEntity} chartEntity={refundsSuccessRateChartEntity}
/>
</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
open NewAnalyticsTypes

// Refunds Success Rate
let refundsSuccessRateEntity: moduleEntity = {
requestBodyConfig: {
delta: false,
metrics: [#sessionized_refund_success_rate],
},
title: "Refunds Success Rate",
domain: #refunds,
}

let refundsSuccessRateChartEntity: chartEntity<
LineGraphTypes.lineGraphPayload,
LineGraphTypes.lineGraphOptions,
JSON.t,
> = {
getObjects: RefundsSuccessRateUtils.refundsSuccessRateMapper,
getChatOptions: LineGraphUtils.getLineGraphOptions,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
open NewAnalyticsTypes
open NewAnalyticsHelper
open LineGraphTypes
open RefundsSuccessRateUtils

module PaymentsSuccessRateHeader = {
open NewAnalyticsUtils
open LogicUtils
@react.component
let make = (~data, ~keyValue, ~granularity, ~setGranularity) => {
let setGranularity = value => {
setGranularity(_ => value)
}
let {filterValueJson} = React.useContext(FilterContext.filterContext)
let comparison = filterValueJson->getString("comparison", "")->DateRangeUtils.comparisonMapprer

let primaryValue = getMetaDataValue(~data, ~index=0, ~key=keyValue)
let secondaryValue = getMetaDataValue(~data, ~index=1, ~key=keyValue)

let (value, direction) = calculatePercentageChange(~primaryValue, ~secondaryValue)
<div className="w-full px-7 py-8 grid grid-cols-2">
// will enable it in future
<div className="flex gap-2 items-center">
<div className="text-fs-28 font-semibold">
{primaryValue->valueFormatter(Rate)->React.string}
</div>
<RenderIf condition={comparison == EnableComparison}>
<StatisticsCard value direction tooltipValue={secondaryValue->valueFormatter(Rate)} />
</RenderIf>
</div>
<RenderIf condition={false}>
<div className="flex justify-center">
<Tabs option={granularity} setOption={setGranularity} options={tabs} />
</div>
</RenderIf>
<div />
</div>
}
}

@react.component
let make = (
~entity: moduleEntity,
~chartEntity: chartEntity<lineGraphPayload, lineGraphOptions, JSON.t>,
) => {
open LogicUtils
open APIUtils
let getURL = useGetURL()
let updateDetails = useUpdateMethod()
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading)

let (paymentsSuccessRateData, setPaymentsSuccessRateData) = React.useState(_ =>
JSON.Encode.array([])
)
let (paymentsSuccessRateMetaData, setpaymentsProcessedMetaData) = React.useState(_ =>
JSON.Encode.array([])
)

let (granularity, setGranularity) = React.useState(_ => defaulGranularity)
let {filterValueJson} = React.useContext(FilterContext.filterContext)
let startTimeVal = filterValueJson->getString("startTime", "")
let endTimeVal = filterValueJson->getString("endTime", "")
let compareToStartTime = filterValueJson->getString("compareToStartTime", "")
let compareToEndTime = filterValueJson->getString("compareToEndTime", "")
let comparison = filterValueJson->getString("comparison", "")->DateRangeUtils.comparisonMapprer

let getPaymentsSuccessRate = async () => {
setScreenState(_ => PageLoaderWrapper.Loading)
try {
let url = getURL(
~entityName=ANALYTICS_REFUNDS,
~methodType=Post,
~id=Some((entity.domain: domain :> string)),
)

let primaryBody = NewAnalyticsUtils.requestBody(
~startTime=startTimeVal,
~endTime=endTimeVal,
~delta=entity.requestBodyConfig.delta,
~metrics=entity.requestBodyConfig.metrics,
~granularity=granularity.value->Some,
)

let secondaryBody = NewAnalyticsUtils.requestBody(
~startTime=compareToStartTime,
~endTime=compareToEndTime,
~delta=entity.requestBodyConfig.delta,
~metrics=entity.requestBodyConfig.metrics,
~granularity=granularity.value->Some,
)

let primaryResponse = await updateDetails(url, primaryBody, Post)
let primaryData = primaryResponse->getDictFromJsonObject->getArrayFromDict("queryData", [])
let primaryMetaData = primaryResponse->getDictFromJsonObject->getArrayFromDict("metaData", [])

let (secondaryMetaData, secondaryModifiedData) = switch comparison {
| EnableComparison => {
let secondaryResponse = await updateDetails(url, secondaryBody, Post)
let secondaryData =
secondaryResponse->getDictFromJsonObject->getArrayFromDict("queryData", [])
let secondaryMetaData =
secondaryResponse->getDictFromJsonObject->getArrayFromDict("metaData", [])
let secondaryModifiedData = [secondaryData]->Array.map(data => {
NewAnalyticsUtils.fillMissingDataPoints(
~data,
~startDate=compareToStartTime,
~endDate=compareToEndTime,
~timeKey="time_bucket",
~defaultValue={
"payment_count": 0,
"payment_processed_amount": 0,
"time_bucket": startTimeVal,
}->Identity.genericTypeToJson,
~granularity=granularity.value,
)
})
(secondaryMetaData, secondaryModifiedData)
}
| DisableComparison => ([], [])
}
if primaryData->Array.length > 0 {
let primaryModifiedData = [primaryData]->Array.map(data => {
NewAnalyticsUtils.fillMissingDataPoints(
~data,
~startDate=startTimeVal,
~endDate=endTimeVal,
~timeKey=Time_Bucket->getStringFromVariant,
~defaultValue={
"payment_count": 0,
"payment_success_rate": 0,
"time_bucket": startTimeVal,
}->Identity.genericTypeToJson,
~granularity=granularity.value,
)
})

setPaymentsSuccessRateData(_ =>
primaryModifiedData->Array.concat(secondaryModifiedData)->Identity.genericTypeToJson
)
setpaymentsProcessedMetaData(_ =>
primaryMetaData->Array.concat(secondaryMetaData)->Identity.genericTypeToJson
)
setScreenState(_ => PageLoaderWrapper.Success)
} else {
setScreenState(_ => PageLoaderWrapper.Custom)
}
} catch {
| _ => setScreenState(_ => PageLoaderWrapper.Custom)
}
}

React.useEffect(() => {
if startTimeVal->isNonEmptyString && endTimeVal->isNonEmptyString {
getPaymentsSuccessRate()->ignore
}
None
}, (startTimeVal, endTimeVal, compareToStartTime, compareToEndTime, comparison))

let params = {
data: paymentsSuccessRateData,
xKey: Refund_Success_Rate->getStringFromVariant,
yKey: Time_Bucket->getStringFromVariant,
comparison,
}

<div>
<ModuleHeader title={entity.title} />
<Card>
<PageLoaderWrapper
screenState customLoader={<Shimmer layoutId=entity.title />} customUI={<NoData />}>
<PaymentsSuccessRateHeader
data={paymentsSuccessRateMetaData}
keyValue={Total_Refund_Success_Rate->getStringFromVariant}
granularity
setGranularity
/>
<div className="mb-5">
<LineGraph entity={chartEntity} data={chartEntity.getObjects(~params)} className="mr-3" />
</div>
</PageLoaderWrapper>
</Card>
</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type successRateCols =
| Refund_Success_Rate
| Total_Refund_Success_Rate
| Time_Bucket

type payments_success_rate = {
refund_success_rate: float,
total_refund_success_rate: float,
time_bucket: string,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
open NewAnalyticsUtils
open RefundsSuccessRateTypes

let getStringFromVariant = value => {
switch value {
| Refund_Success_Rate => "refund_success_rate"
| Total_Refund_Success_Rate => "total_refund_success_rate"
| Time_Bucket => "time_bucket"
}
}

let getVariantValueFromString = value => {
switch value {
| "refund_success_rate" => Refund_Success_Rate
| "total_refund_success_rate" => Total_Refund_Success_Rate
| "time_bucket" | _ => Time_Bucket
}
}

let refundsSuccessRateMapper = (
~params: NewAnalyticsTypes.getObjects<JSON.t>,
): LineGraphTypes.lineGraphPayload => {
open LineGraphTypes
let {data, xKey, yKey} = params
let comparison = switch params.comparison {
| Some(val) => Some(val)
| None => None
}
let primaryCategories = data->getCategories(0, yKey)
let secondaryCategories = data->getCategories(1, yKey)

let lineGraphData = data->getLineGraphData(~xKey, ~yKey)

let title = {
text: "Refunds Success Rate",
}

{
categories: primaryCategories,
data: lineGraphData,
title,
yAxisMaxValue: 100->Some,
tooltipFormatter: tooltipFormatter(
~secondaryCategories,
~title="Refunds Success Rate",
~metricType=Rate,
~comparison,
),
}
}

open NewAnalyticsTypes
let tabs = [{label: "Daily", value: (#G_ONEDAY: granularity :> string)}]

let defaulGranularity = {
label: "Hourly",
value: (#G_ONEDAY: granularity :> string),
}

0 comments on commit 4693520

Please sign in to comment.