Skip to content

Commit

Permalink
feat: refunds overview section (#1932)
Browse files Browse the repository at this point in the history
  • Loading branch information
sagarnaikjuspay authored Dec 17, 2024
1 parent e93ba39 commit 8f7bd7d
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ let make = () => {
open NewRefundsAnalyticsEntity

<div className="flex flex-col gap-14 mt-5 pt-7">
<RefundsOverviewSection entity={overviewSectionEntity} />
<RefundsProcessed entity={refundsProcessedEntity} chartEntity={refundsProcessedChartEntity} />
<RefundsSuccessRate
entity={refundsSuccessRateEntity} chartEntity={refundsSuccessRateChartEntity}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
open NewAnalyticsTypes
// OverView section
let overviewSectionEntity: moduleEntity = {
requestBodyConfig: {
delta: true,
metrics: [],
},
title: "OverView Section",
domain: #refunds,
}
// Refunds Processed
let refundsProcessedEntity: moduleEntity = {
requestBodyConfig: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
open NewAnalyticsTypes
open RefundsOverviewSectionTypes
open RefundsOverviewSectionUtils
open NewAnalyticsHelper
open LogicUtils
open APIUtils
@react.component
let make = (~entity: moduleEntity) => {
let getURL = useGetURL()
let updateDetails = useUpdateMethod()
let (data, setData) = React.useState(_ => []->JSON.Encode.array)
let {filterValueJson} = React.useContext(FilterContext.filterContext)
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Success)
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 getData = async () => {
setScreenState(_ => PageLoaderWrapper.Loading)
try {
let primaryData = defaultValue->Dict.copy
let secondaryData = defaultValue->Dict.copy

let refundsUrl = getURL(
~entityName=ANALYTICS_REFUNDS,
~methodType=Post,
~id=Some((#refunds: domain :> string)),
)

let amountRateBodyRefunds = NewAnalyticsUtils.requestBody(
~startTime=startTimeVal,
~endTime=endTimeVal,
~delta=entity.requestBodyConfig.delta,
~metrics=[#sessionized_refund_processed_amount, #sessionized_refund_success_rate],
)

// TODO: need refactor on filters
let filters = Dict.make()
filters->Dict.set(
"refund_status",
[#success, #failure, #pending]
->Array.map(item => {
(item: status :> string)->JSON.Encode.string
})
->JSON.Encode.array,
)

let statusCountBodyRefunds = NewAnalyticsUtils.requestBody(
~startTime=startTimeVal,
~endTime=endTimeVal,
~groupByNames=["refund_status"]->Some,
~filter=filters->JSON.Encode.object->Some,
~delta=entity.requestBodyConfig.delta,
~metrics=[#sessionized_refund_count],
)

let amountRateResponseRefunds = await updateDetails(refundsUrl, amountRateBodyRefunds, Post)
let statusCountResponseRefunds = await updateDetails(refundsUrl, statusCountBodyRefunds, Post)

let amountRateDataRefunds = amountRateResponseRefunds->parseResponse("metaData")
let statusCountDataRefunds = statusCountResponseRefunds->modifyStatusCountResponse

primaryData->setValue(
~data=amountRateDataRefunds,
~ids=[Total_Refund_Processed_Amount, Total_Refund_Success_Rate],
)

primaryData->setValue(
~data=statusCountDataRefunds,
~ids=[Successful_Refund_Count, Failed_Refund_Count, Pending_Refund_Count],
)

let secondaryAmountRateBodyRefunds = NewAnalyticsUtils.requestBody(
~startTime=compareToStartTime,
~endTime=compareToEndTime,
~delta=entity.requestBodyConfig.delta,
~metrics=[#sessionized_refund_processed_amount, #sessionized_refund_success_rate],
)

let secondaryStatusCountBodyRefunds = NewAnalyticsUtils.requestBody(
~startTime=compareToStartTime,
~endTime=compareToEndTime,
~groupByNames=["refund_status"]->Some,
~filter=filters->JSON.Encode.object->Some,
~delta=entity.requestBodyConfig.delta,
~metrics=[#sessionized_refund_count],
)

let secondaryData = switch comparison {
| EnableComparison => {
let secondaryResponseRefunds = await updateDetails(
refundsUrl,
secondaryAmountRateBodyRefunds,
Post,
)

let secondaryStatusCountResponseRefunds = await updateDetails(
refundsUrl,
secondaryStatusCountBodyRefunds,
Post,
)

let secondaryAmountRateDataRefunds = secondaryResponseRefunds->parseResponse("metaData")
let secondaryStatusCountDataRefunds =
secondaryStatusCountResponseRefunds->modifyStatusCountResponse

secondaryData->setValue(
~data=secondaryAmountRateDataRefunds,
~ids=[Total_Refund_Processed_Amount, Total_Refund_Success_Rate],
)

secondaryData->setValue(
~data=secondaryStatusCountDataRefunds,
~ids=[Successful_Refund_Count, Failed_Refund_Count, Pending_Refund_Count],
)

secondaryData->JSON.Encode.object
}
| DisableComparison => JSON.Encode.null
}

setData(_ => [primaryData->JSON.Encode.object, secondaryData]->JSON.Encode.array)

setScreenState(_ => PageLoaderWrapper.Success)
} catch {
| _ => setScreenState(_ => PageLoaderWrapper.Success)
}
}

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

<PageLoaderWrapper screenState customLoader={<Shimmer layoutId=entity.title />}>
<div className="grid grid-cols-3 grid-rows-2 gap-6">
<OverViewStat
data
responseKey={Total_Refund_Success_Rate}
config={getInfo(~responseKey=Total_Refund_Success_Rate)}
getValueFromObj
getStringFromVariant
/>
<OverViewStat
data
responseKey={Total_Refund_Processed_Amount}
config={getInfo(~responseKey=Total_Refund_Processed_Amount)}
getValueFromObj
getStringFromVariant
/>
<OverViewStat
data
responseKey={Successful_Refund_Count}
config={getInfo(~responseKey=Successful_Refund_Count)}
getValueFromObj
getStringFromVariant
/>
<OverViewStat
data
responseKey={Failed_Refund_Count}
config={getInfo(~responseKey=Failed_Refund_Count)}
getValueFromObj
getStringFromVariant
/>
<OverViewStat
data
responseKey={Pending_Refund_Count}
config={getInfo(~responseKey=Pending_Refund_Count)}
getValueFromObj
getStringFromVariant
/>
</div>
</PageLoaderWrapper>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
type overviewColumns =
| Total_Refund_Processed_Amount
| Total_Refund_Success_Rate
| Successful_Refund_Count
| Failed_Refund_Count
| Pending_Refund_Count

type dataObj = {
total_refund_processed_amount_in_usd: float,
total_refund_success_rate: float,
successful_refund_count: int,
failed_refund_count: int,
pending_refund_count: int,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
open RefundsOverviewSectionTypes

let getStringFromVariant = value => {
switch value {
| Total_Refund_Processed_Amount => "total_refund_processed_amount_in_usd"
| Total_Refund_Success_Rate => "total_refund_success_rate"
| Successful_Refund_Count => "successful_refund_count"
| Failed_Refund_Count => "failed_refund_count"
| Pending_Refund_Count => "pending_refund_count"
}
}

let defaultValue =
{
total_refund_processed_amount_in_usd: 0.0,
total_refund_success_rate: 0.0,
successful_refund_count: 0,
failed_refund_count: 0,
pending_refund_count: 0,
}
->Identity.genericTypeToJson
->LogicUtils.getDictFromJsonObject

let parseResponse = (response, key) => {
open LogicUtils
response
->getDictFromJsonObject
->getArrayFromDict(key, [])
->getValueFromArray(0, Dict.make()->JSON.Encode.object)
->getDictFromJsonObject
}

let getValueFromObj = (data, index, responseKey) => {
open LogicUtils
data
->getArrayFromJson([])
->getValueFromArray(index, Dict.make()->JSON.Encode.object)
->getDictFromJsonObject
->getFloat(responseKey, 0.0)
}

open NewAnalyticsTypes
let setValue = (dict, ~data, ~ids: array<overviewColumns>) => {
open NewAnalyticsUtils
open LogicUtils

ids->Array.forEach(id => {
let key = id->getStringFromVariant
let value = switch id {
| Total_Refund_Processed_Amount =>
data->getAmountValue(~id=id->getStringFromVariant)->JSON.Encode.float
| _ =>
data
->getFloat(id->getStringFromVariant, 0.0)
->JSON.Encode.float
}

dict->Dict.set(key, value)
})
}

let getInfo = (~responseKey: overviewColumns) => {
switch responseKey {
| Total_Refund_Success_Rate => {
titleText: "Refund Success Rate",
description: "Successful refunds divided by total refunds",
valueType: Rate,
}
| Total_Refund_Processed_Amount => {
titleText: "Total Refunds Processed",
description: "Total refunds processed amount on all successful refunds",
valueType: Amount,
}
| Successful_Refund_Count => {
titleText: "Successful Refunds",
description: "Total number of refunds that were successfully processed",
valueType: Volume,
}
| Failed_Refund_Count => {
titleText: "Failed Refunds",
description: "Total number of refunds that were failed during processing",
valueType: Volume,
}
| Pending_Refund_Count => {
titleText: "Pending Refunds",
description: "Total number of refunds currently in pending state",
valueType: Volume,
}
}
}

let modifyStatusCountResponse = response => {
open LogicUtils
let queryData = response->getDictFromJsonObject->getArrayFromDict("queryData", [])

let mapDict = Dict.make()

queryData->Array.forEach(query => {
let value = query->getDictFromJsonObject
let status = value->getString("refund_status", "")
let count = value->getInt("refund_count", 0)

if status == (#success: status :> string) {
mapDict->Dict.set(Successful_Refund_Count->getStringFromVariant, count->JSON.Encode.int)
}
if status == (#failure: status :> string) {
mapDict->Dict.set(Failed_Refund_Count->getStringFromVariant, count->JSON.Encode.int)
}
if status == (#pending: status :> string) {
mapDict->Dict.set(Pending_Refund_Count->getStringFromVariant, count->JSON.Encode.int)
}
})

mapDict
}

0 comments on commit 8f7bd7d

Please sign in to comment.