From 8f7bd7d0c9c4b31a8a6fd27bfbc74643719c85a0 Mon Sep 17 00:00:00 2001 From: Sagar naik Date: Tue, 17 Dec 2024 13:22:45 +0530 Subject: [PATCH] feat: refunds overview section (#1932) --- .../NewRefundsAnalytics.res | 1 + .../NewRefundsAnalyticsEntity.res | 9 + .../RefundsOverviewSection.res | 178 ++++++++++++++++++ .../RefundsOverviewSectionTypes.res | 14 ++ .../RefundsOverviewSectionUtils.res | 115 +++++++++++ 5 files changed, 317 insertions(+) create mode 100644 src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSection.res create mode 100644 src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSectionTypes.res create mode 100644 src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSectionUtils.res diff --git a/src/screens/NewAnalytics/NewRefundsAnalytics/NewRefundsAnalytics.res b/src/screens/NewAnalytics/NewRefundsAnalytics/NewRefundsAnalytics.res index 91e3cd041..666b74b70 100644 --- a/src/screens/NewAnalytics/NewRefundsAnalytics/NewRefundsAnalytics.res +++ b/src/screens/NewAnalytics/NewRefundsAnalytics/NewRefundsAnalytics.res @@ -3,6 +3,7 @@ let make = () => { open NewRefundsAnalyticsEntity
+ { + 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)) + + }> +
+ + + + + +
+
+} diff --git a/src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSectionTypes.res b/src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSectionTypes.res new file mode 100644 index 000000000..16f8b4454 --- /dev/null +++ b/src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSectionTypes.res @@ -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, +} diff --git a/src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSectionUtils.res b/src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSectionUtils.res new file mode 100644 index 000000000..635067746 --- /dev/null +++ b/src/screens/NewAnalytics/NewRefundsAnalytics/RefundsOverviewSection/RefundsOverviewSectionUtils.res @@ -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) => { + 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 +}