new report structure

This commit is contained in:
2026-05-06 14:11:03 +05:30
parent 7470da6d2d
commit 15f76eb5f0
10 changed files with 138 additions and 350 deletions

View File

@@ -3,9 +3,6 @@ export {
} from './useReport'
export type {
Transaction,
PeriodData,
PeriodGroup,
Period,
ReportData,
} from './report.models'
export {

View File

@@ -18,44 +18,72 @@ export interface Tag {
}
export interface Transaction {
payor: Payor;
payee: Payee;
amount: number;
account: Account;
tags: Tag[]
occurred_at: Date
payor: Payor;
payee: Payee;
amount: number;
account: Account;
tags: Tag[];
occurred_at: Date;
}
export interface _PeriodData {
// -----------------------------
// Metrics
// -----------------------------
export interface ReportMetric {
sum: number;
count: number;
average: number;
txns: Transaction[];
transactions?: Transaction[];
}
export interface PeriodData extends _PeriodData {
compare?: _PeriodData;
}
// -----------------------------
// Period
// -----------------------------
export interface PeriodGroup {
group_key: string[];
expenses: PeriodData[];
incomes: PeriodData[];
}
export interface Period {
id: string;
label: string;
export interface ReportPeriod {
start: Date;
end: Date;
groups: PeriodGroup[];
expenses: ReportMetric;
incomes: ReportMetric;
}
export interface ReportData {
period: "weekly" | "monthly" | "yearly" | "fyly" | "full";
rolling?: boolean;
report_date?: string;
group_by?: ("payee" | "tags")[];
ignore_self?: boolean;
buckets: Period[];
// -----------------------------
// Group (bucket)
// -----------------------------
export type GroupKey = {
payee?: string[];
tags?: string[];
flow?: string[];
};
export interface ReportBucket {
group_key: GroupKey;
periods: {
weekly?: ReportPeriod[];
monthly?: ReportPeriod[];
yearly?: ReportPeriod[];
fyly?: ReportPeriod[];
};
}
// -----------------------------
// Final Report
// -----------------------------
export interface ReportData {
periods: ("weekly" | "monthly" | "yearly" | "fyly")[];
rolling: boolean;
report_date?: string;
group_by: ("payee" | "tags")[];
ignore_self: boolean;
include_transactions: boolean;
buckets: ReportBucket[];
}

View File

@@ -1,4 +1,7 @@
import { ReportData } from "./report.models";
import {
ReportData,
ReportPeriod
} from "./report.models";
/* ---------- ID BUILDING ---------- */
@@ -10,7 +13,7 @@ function formatDate(d: Date): string {
}
function buildPeriodId(
type: ReportData["period"],
type: "weekly" | "monthly" | "yearly" | "fyly" | "full",
start: Date,
end: Date
): string {
@@ -65,7 +68,7 @@ function sameMonth(a: Date, b: Date) {
}
function buildLabel(
type: ReportData["period"],
type: "weekly" | "monthly" | "yearly" | "fyly" | "full",
start: Date,
end: Date
): string {
@@ -94,9 +97,6 @@ function buildLabel(
return `FY ${startY}${String(endY).slice(-2)}`;
}
case "full":
return `${monthFmt.format(start)} ${yearFmt.format(start)} - ${monthFmt.format(end)} ${yearFmt.format(end)}`;
default:
return `${monthDayFmt.format(start)} - ${monthDayFmt.format(end)}`;
}
@@ -104,13 +104,34 @@ function buildLabel(
/* ---------- MAIN ---------- */
function decoratePeriods(
type: "weekly" | "monthly" | "yearly" | "fyly" | "full",
periods: ReportPeriod[]
): (ReportPeriod & { id: string; label: string })[] {
return periods.map((p) => ({
...p,
id: buildPeriodId(type, new Date(p.start), new Date(p.end)),
label: buildLabel(type, new Date(p.start), new Date(p.end)),
}));
}
export function prepareReport(reportData: ReportData): ReportData {
return {
...reportData,
buckets: reportData.buckets.map((p) => ({
...p,
id: buildPeriodId(reportData.period, p.start, p.end),
label: buildLabel(reportData.period, p.start, p.end),
})),
buckets: reportData.buckets.map((bucket) => {
const newPeriods: typeof bucket.periods = {};
for (const type of reportData.periods) {
const arr = bucket.periods[type];
if (arr) {
newPeriods[type] = decoratePeriods(type, arr);
}
}
return {
...bucket,
periods: newPeriods,
};
}),
};
}
}

View File

@@ -1,18 +1,20 @@
import { useResourceByName } from "../../../react-openapi";
export interface ReportParams {
period: "weekly" | "monthly" | "yearly" | "fyly" | "full";
periods?: ("weekly" | "monthly" | "yearly" | "fyly" | "full")[];
rolling?: boolean;
report_date?: string;
group_by?: ("payee" | "tags")[];
ignore_self?: boolean;
include_transactions?: boolean;
}
export function useReport(params: ReportParams) {
const { useList } = useResourceByName("reports");
if (params.group_by) {
// @ts-ignore
params.group_by = params.group_by[0]
}
return useList(params);
}
return useList({
...params,
periods: params.periods,
group_by: params.group_by,
});
}