From 9d87979586808a8c8a35421ce937f687634b1c08 Mon Sep 17 00:00:00 2001 From: Confidence-bassey Date: Mon, 28 Apr 2025 19:11:55 +0100 Subject: [PATCH 1/3] Implemented the KPI percentage calculation function --- src/components/KPI/PercentageDifference.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/components/KPI/PercentageDifference.js diff --git a/src/components/KPI/PercentageDifference.js b/src/components/KPI/PercentageDifference.js new file mode 100644 index 0000000..4233ece --- /dev/null +++ b/src/components/KPI/PercentageDifference.js @@ -0,0 +1,17 @@ +export default function calculatePercentageDifference(currentValue, previousValue) { + if (!previousValue || previousValue === 0) { + return 0; + } + const difference = currentValue - previousValue; + const percentageDifference = (difference / previousValue) * 100; + return percentageDifference; + } + + export function calculateTransactionKPI(transactions, periodStart, periodEnd) { + const currentTransactions = transactions.filter(tx => { + const txDate = new Date(tx.dateTime); + return txDate >= periodStart && txDate <= periodEnd; + }); + + return currentTransactions.length; + } \ No newline at end of file From c31ea83c4190a02e5583c67e26dfedb3b55b15a2 Mon Sep 17 00:00:00 2001 From: Confidence-bassey Date: Fri, 2 May 2025 19:08:12 +0100 Subject: [PATCH 2/3] Added more helper functions for kpi percentage difference calculation --- src/components/KPI/PercentageDifference.js | 27 ++++++++++ .../KPI/calculatePercentageChange.js | 34 ++++++++++++ src/components/KPI/timeRangeHelpers.js | 53 +++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 src/components/KPI/calculatePercentageChange.js create mode 100644 src/components/KPI/timeRangeHelpers.js diff --git a/src/components/KPI/PercentageDifference.js b/src/components/KPI/PercentageDifference.js index 4233ece..cdf0c21 100644 --- a/src/components/KPI/PercentageDifference.js +++ b/src/components/KPI/PercentageDifference.js @@ -14,4 +14,31 @@ export default function calculatePercentageDifference(currentValue, previousValu }); return currentTransactions.length; + } + + export function calculateAgentKPI(agents, periodStart, periodEnd) { + const currentAgentActions = agents.filter(agent => { + const actionDate = new Date(agent.actionDate); + return actionDate >= periodStart && actionDate <= periodEnd; + }); + + return currentAgentActions.length; + } + + export function calculateCustomerKPI(customers, periodStart, periodEnd) { + const currentCustomerInteractions = customers.filter(customer => { + const interactionDate = new Date(customer.interactionDate); + return interactionDate >= periodStart && interactionDate <= periodEnd; + }); + + return currentCustomerInteractions.length; + } + + export function calculateDisputeKPI(disputes, periodStart, periodEnd) { + const currentDisputes = disputes.filter(dispute => { + const disputeDate = new Date(dispute.dateRaised); + return disputeDate >= periodStart && disputeDate <= periodEnd; + }); + + return currentDisputes.length; } \ No newline at end of file diff --git a/src/components/KPI/calculatePercentageChange.js b/src/components/KPI/calculatePercentageChange.js new file mode 100644 index 0000000..92a6fee --- /dev/null +++ b/src/components/KPI/calculatePercentageChange.js @@ -0,0 +1,34 @@ + +export default function calculatePercentageChange( + dataArray, + dateAccessorFn, + optionalFilterFn, + getCurrentRangeFn = getCurrentMonthRange +) { + const { currentRangeStart, currentRangeEnd, previousRangeStart, previousRangeEnd } = getCurrentRangeFn(); + + const filterData = (items, start, end) => + items.filter(item => { + const date = new Date(dateAccessorFn(item)); + return date >= start && date <= end && (!optionalFilterFn || optionalFilterFn(item)); + }); + + const currentItems = filterData(dataArray, currentRangeStart, currentRangeEnd); + const previousItems = filterData(dataArray, previousRangeStart, previousRangeEnd); + + const currentCount = currentItems.length; + const previousCount = previousItems.length; + const totalCount = dataArray.length; + + return previousCount === 0 + ? (currentCount === 0 ? 0 : Math.round((currentCount / totalCount) * 100)) + : Math.round(((currentCount - previousCount) / previousCount) * 100); +} + +// Function to calculate percentage of filtered data over total dataset +export function calculateFilteredPercentage(dataArray, filterFn) { + const totalCount = dataArray.length; + const filteredCount = dataArray.filter(filterFn).length; + + return totalCount === 0 ? 0 : Math.round((filteredCount / totalCount) * 100); +} diff --git a/src/components/KPI/timeRangeHelpers.js b/src/components/KPI/timeRangeHelpers.js new file mode 100644 index 0000000..2323065 --- /dev/null +++ b/src/components/KPI/timeRangeHelpers.js @@ -0,0 +1,53 @@ +export function getCurrentMonthRange() { + const now = new Date(); + const currentRangeStart = new Date(now.getFullYear(), now.getMonth(), 1); + const currentRangeEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0); + + const previousRangeStart = new Date(now.getFullYear(), now.getMonth() - 1, 1); + const previousRangeEnd = new Date(now.getFullYear(), now.getMonth(), 0); + + return { currentRangeStart, currentRangeEnd, previousRangeStart, previousRangeEnd }; + } + + export function getCurrentWeekRange() { + const now = new Date(); + const dayOfWeek = now.getDay(); // 0 (Sun) - 6 (Sat) + + const currentRangeStart = new Date(now); + currentRangeStart.setDate(now.getDate() - dayOfWeek); + + const currentRangeEnd = new Date(currentRangeStart); + currentRangeEnd.setDate(currentRangeStart.getDate() + 6); + + const previousRangeStart = new Date(currentRangeStart); + previousRangeStart.setDate(currentRangeStart.getDate() - 7); + + const previousRangeEnd = new Date(previousRangeStart); + previousRangeEnd.setDate(previousRangeStart.getDate() + 6); + + return { currentRangeStart, currentRangeEnd, previousRangeStart, previousRangeEnd }; + } + + export function getCurrentDayRange() { + const now = new Date(); + const currentRangeStart = new Date(now.setHours(0, 0, 0, 0)); + const currentRangeEnd = new Date(now.setHours(23, 59, 59, 999)); + + const previousRangeStart = new Date(currentRangeStart); + previousRangeStart.setDate(currentRangeStart.getDate() - 1); + const previousRangeEnd = new Date(previousRangeStart); + previousRangeEnd.setHours(23, 59, 59, 999); + + return { currentRangeStart, currentRangeEnd, previousRangeStart, previousRangeEnd }; + } + + export function getCurrentYearRange() { + const now = new Date(); + const currentRangeStart = new Date(now.getFullYear(), 0, 1); + const currentRangeEnd = new Date(now.getFullYear(), 11, 31); + + const previousRangeStart = new Date(now.getFullYear() - 1, 0, 1); + const previousRangeEnd = new Date(now.getFullYear() - 1, 11, 31); + + return { currentRangeStart, currentRangeEnd, previousRangeStart, previousRangeEnd }; + } \ No newline at end of file From 2bfbcd49bba90fab96578b4a929455899d0274cd Mon Sep 17 00:00:00 2001 From: Confidence-bassey Date: Mon, 5 May 2025 12:19:25 +0100 Subject: [PATCH 3/3] Added sum based percentage difference calculations --- .../KPI/calculatePercentageChange.js | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/components/KPI/calculatePercentageChange.js b/src/components/KPI/calculatePercentageChange.js index 92a6fee..c185dd7 100644 --- a/src/components/KPI/calculatePercentageChange.js +++ b/src/components/KPI/calculatePercentageChange.js @@ -1,34 +1,52 @@ +import { getCurrentMonthRange } from "./timeRangeHelpers"; export default function calculatePercentageChange( - dataArray, - dateAccessorFn, - optionalFilterFn, - getCurrentRangeFn = getCurrentMonthRange + dataArray, + dateAccessorFn, + optionalFilterFn, + getCurrentRangeFn = getCurrentMonthRange, + mode = "length", + accessorFn = null ) { - const { currentRangeStart, currentRangeEnd, previousRangeStart, previousRangeEnd } = getCurrentRangeFn(); + const { currentRangeStart, currentRangeEnd, previousRangeStart, previousRangeEnd } = getCurrentRangeFn(); - const filterData = (items, start, end) => - items.filter(item => { - const date = new Date(dateAccessorFn(item)); - return date >= start && date <= end && (!optionalFilterFn || optionalFilterFn(item)); - }); + const filterData = (items, start, end) => + items.filter(item => { + const date = new Date(dateAccessorFn(item)); + return date >= start && date <= end && (!optionalFilterFn || optionalFilterFn(item)); + }); - const currentItems = filterData(dataArray, currentRangeStart, currentRangeEnd); - const previousItems = filterData(dataArray, previousRangeStart, previousRangeEnd); + const currentItems = filterData(dataArray, currentRangeStart, currentRangeEnd); + const previousItems = filterData(dataArray, previousRangeStart, previousRangeEnd); - const currentCount = currentItems.length; - const previousCount = previousItems.length; - const totalCount = dataArray.length; + let currentValue, previousValue, totalValue; - return previousCount === 0 - ? (currentCount === 0 ? 0 : Math.round((currentCount / totalCount) * 100)) - : Math.round(((currentCount - previousCount) / previousCount) * 100); + if (mode === "sum" && accessorFn) { + currentValue = currentItems.reduce((acc, item) => acc + accessorFn(item), 0); + previousValue = previousItems.reduce((acc, item) => acc + accessorFn(item), 0); + totalValue = dataArray.reduce((acc, item) => acc + accessorFn(item), 0); + } else { + currentValue = currentItems.length; + previousValue = previousItems.length; + totalValue = dataArray.length; + } + + return previousValue === 0 + ? (currentValue === 0 ? 0 : Math.round((currentValue / totalValue) * 100)) + : Math.round(((currentValue - previousValue) / previousValue) * 100); } // Function to calculate percentage of filtered data over total dataset -export function calculateFilteredPercentage(dataArray, filterFn) { - const totalCount = dataArray.length; - const filteredCount = dataArray.filter(filterFn).length; +export function calculateFilteredPercentage(dataArray, filterFn, mode = "length", accessorFn = null) { + let totalValue, filteredValue; + + if (mode === "sum" && accessorFn) { + totalValue = dataArray.reduce((acc, item) => acc + accessorFn(item), 0); + filteredValue = dataArray.filter(filterFn).reduce((acc, item) => acc + accessorFn(item), 0); + } else { + totalValue = dataArray.length; + filteredValue = dataArray.filter(filterFn).length; + } - return totalCount === 0 ? 0 : Math.round((filteredCount / totalCount) * 100); + return totalValue === 0 ? 0 : Math.round((filteredValue / totalValue) * 100); }