calcuation fixes

This commit is contained in:
2026-04-04 22:42:34 +05:30
parent 4eca3b7124
commit b07de2b03c

View File

@@ -9,12 +9,35 @@ const DEFAULT_ICON = React.createElement(MonetizationOnIcon, {
sx: { color: "#388e3c" }
});
// ---------------- HELPERS ----------------
const format = (d: Date) =>
`${d.getDate()} ${d.toLocaleString("default", { month: "short" })}`;
const startOfDay = (d: Date) => {
const x = new Date(d);
x.setHours(0, 0, 0, 0);
return x;
};
const endOfDay = (d: Date) => {
const x = new Date(d);
x.setHours(23, 59, 59, 999);
return x;
};
const getStartOfWeek = (d: Date) => {
const date = new Date(d);
const day = date.getDay() || 7;
if (day !== 1) date.setDate(date.getDate() - (day - 1));
return startOfDay(date);
};
// ---------------- LATEST ----------------
export async function fetchLatestTransactions(
type: "expense" | "income"
): Promise<LatestItem[]> {
const res = await api.get('/expenses', {
params: { limit: 100, sort: '-occurred_at' }
const res = await api.get("/expenses", {
params: { limit: 100, sort: "-occurred_at" }
});
const items = res.data?.items || res.data || [];
@@ -54,11 +77,11 @@ export interface AggregatedDashboardData {
topPayees: Array<{ payeeName: string; amount: number }>;
}
// ---------------- GENERIC AGGREGATOR ----------------
// ---------------- AGGREGATION ----------------
export async function fetchAggregatedData(
type: "expense" | "income"
): Promise<AggregatedDashboardData> {
const res = await api.get('/expenses', { params: { limit: 0 } });
const res = await api.get("/expenses", { params: { limit: 0 } });
const all: any[] = res.data?.items || res.data || [];
const now = new Date();
@@ -71,56 +94,58 @@ export async function fetchAggregatedData(
const normalize = (amt: number) => Math.abs(amt);
// ---------------- WEEK ----------------
const weekBuckets: Record<string, number> = {
"Mon":0,"Tue":0,"Wed":0,"Thu":0,
"Fri":0,"Sat":0,"Sun":0
Mon: 0, Tue: 0, Wed: 0, Thu: 0,
Fri: 0, Sat: 0, Sun: 0
};
const monthBuckets: Record<string, { amount: number; range: string }> = {};
const yearBuckets: Record<string, { amount: number; range: string }> = {};
const weekStart = getStartOfWeek(now);
const weekEnd = endOfDay(new Date(weekStart.getTime() + 6 * 86400000));
const getStartOfWeek = (d: Date) => {
const date = new Date(d);
const day = date.getDay() || 7;
if (day !== 1) date.setDate(date.getDate() - (day - 1));
date.setHours(0,0,0,0);
return date;
};
// ---------------- MONTH (5 rolling weeks) ----------------
const monthBuckets: {
label: string;
start: Date;
end: Date;
amount: number;
}[] = [];
const format = (d: Date) =>
`${d.getDate()} ${d.toLocaleString('default', { month: 'short' })}`;
// -------- MONTH (5 rolling weeks) --------
for (let i = 0; i < 5; i++) {
const end = new Date(now);
end.setDate(end.getDate() - i * 7);
const end = endOfDay(new Date(now.getTime() - i * 7 * 86400000));
const start = startOfDay(new Date(end.getTime() - 6 * 86400000));
const start = new Date(end);
start.setDate(start.getDate() - 6);
const key = `${format(start)} - ${format(end)}`;
monthBuckets[key] = { amount: 0, range: key };
monthBuckets.push({
label: `${format(start)} - ${format(end)}`,
start,
end,
amount: 0
});
}
// -------- YEAR (12 months rolling) --------
// ---------------- YEAR (12 months) ----------------
const yearBuckets: {
label: string;
start: Date;
end: Date;
amount: number;
}[] = [];
for (let i = 0; i < 12; i++) {
const d = new Date(now);
d.setMonth(d.getMonth() - i);
const start = new Date(d.getFullYear(), d.getMonth(), 1);
const end = new Date(d.getFullYear(), d.getMonth() + 1, 0);
const end = endOfDay(new Date(d.getFullYear(), d.getMonth() + 1, 0));
const label = d.toLocaleString('default', { month: 'short' });
const range = `${format(start)} - ${format(end)}`;
yearBuckets[label] = { amount: 0, range };
yearBuckets.push({
label: d.toLocaleString("default", { month: "short" }),
start,
end,
amount: 0
});
}
const weekStart = getStartOfWeek(now);
const weekEnd = new Date(weekStart);
weekEnd.setDate(weekStart.getDate() + 6);
// ---------------- LOOP ----------------
for (const item of all) {
const d = new Date(
@@ -137,7 +162,7 @@ export async function fetchAggregatedData(
const payee = item.payee?.name || item.payee || "Unknown";
payeeMap[payee] = (payeeMap[payee] || 0) + amt;
// ---- WEEK
// WEEK
if (d >= weekStart && d <= weekEnd) {
const day = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][d.getDay()];
if (weekBuckets[day] !== undefined) {
@@ -145,25 +170,17 @@ export async function fetchAggregatedData(
}
}
// ---- MONTH
Object.entries(monthBuckets).forEach(([_, obj]) => {
const [startStr, endStr] = obj.range.split(" - ");
const start = new Date(startStr);
const end = new Date(endStr);
if (d >= start && d <= end) {
obj.amount += amt;
// MONTH
monthBuckets.forEach(b => {
if (d >= b.start && d <= b.end) {
b.amount += amt;
}
});
// ---- YEAR
Object.entries(yearBuckets).forEach(([_, obj]) => {
const [startStr, endStr] = obj.range.split(" - ");
const start = new Date(startStr);
const end = new Date(endStr);
if (d >= start && d <= end) {
obj.amount += amt;
// YEAR
yearBuckets.forEach(b => {
if (d >= b.start && d <= b.end) {
b.amount += amt;
}
});
}
@@ -184,7 +201,9 @@ export async function fetchAggregatedData(
// highlight max
Object.values(chartData).forEach(group => {
let max = group[0];
for (const g of group) if (g.amount > max.amount) max = g;
for (const g of group) {
if (g.amount > max.amount) max = g;
}
if (max.amount > 0) max.highlighted = true;
});