domBudg/front/src/core/services/report-service.ts

104 lines
3.4 KiB
TypeScript

import { Dayjs } from "dayjs";
import { Api } from "../api/Api";
import { ChangeRecordViewModel, SpendingGroupViewModel } from "../api/data-contracts";
import { useUserStore } from "../../store";
export type ReportData = {
label: string;
data: number | string;
};
export interface OffsetFromPlanReportData {
groupName: string;
startAt: string;
endAt: string;
planSum: number;
total: number,
data: ReportData[];
}
export interface PeriodReportData {
data: ReportData[];
total: number;
}
export class ReportService {
private readonly _api: Api
constructor(api: Api) {
this._api = api;
}
public async getOffsetFromPlanData(Id: string): Promise<OffsetFromPlanReportData> {
console.log(Id);
let res = await this._api.reportPlanDetail(Id);
console.log(res);
let reportData = getOffsetFromPlanData(res.data);
if (!reportData) throw new Error("Cannot get report data");
return reportData;
}
public async getPeriodData(from: Dayjs, to: Dayjs): Promise<PeriodReportData> {
let userId = useUserStore().user.id;
if (!userId) throw new Error("Id пользователя не найден");
let res = await this._api.reportPeriodList(userId, {
from: from.toISOString(),
to: to.toISOString()
});
console.log(res);
let reportData = getPeriodData(res.data);
if (!reportData) throw new Error("Cannot get report data");
console.log(reportData);
return reportData;
}
}
function getOffsetFromPlanData(group: SpendingGroupViewModel): OffsetFromPlanReportData | null {
let reportData : ReportData[] = [];
getReportDataFromGroup(group, reportData,
(cr) => reportData.push({
label: cr.changedAt!,
data: Math.abs(cr.sum!)
})
);
if (reportData.length == 0) return null;
return {
groupName: group.name!,
startAt: group.spendingPlans![0].startAt!,
endAt: group.spendingPlans![0].endAt!,
planSum: group.spendingPlans![0].sum!,
total: reportData.map(x => x.data as number).reduce((a, b) => a + b, 0),
data: reportData
};
}
function getPeriodData(records: ChangeRecordViewModel[]): PeriodReportData | null {
let reportData : ReportData[] = [];
getReportDataFromRecords(records, reportData,
(cr) => reportData.push({
label: cr.spendingGroupName!,
data: Math.abs(cr.sum!)
}),
(x, y) => x.label == y.spendingGroupName
);
return {
data: reportData,
total: reportData.map(x => x.data as number).reduce((a, b) => a + b, 0)
}
}
function getReportDataFromGroup(group: SpendingGroupViewModel, reportData: ReportData[], callbackPush: (changeRecor: ChangeRecordViewModel) => void) {
if (!group.changeRecords) return;
getReportDataFromRecords(group.changeRecords, reportData, callbackPush, (x, y) => x.label == y.changedAt);
}
function getReportDataFromRecords(records: ChangeRecordViewModel[], reportData: ReportData[],
callbackPush: (changeRecor: ChangeRecordViewModel) => void,
callbackFind: (x: ReportData, y: ChangeRecordViewModel) => boolean) {
records.forEach((cr) => {
if (!reportData.find(x => callbackFind(x, cr))) {
callbackPush(cr);
}
else {
(reportData.find(x => callbackFind(x, cr))!.data as number) += Math.abs(cr.sum!);
}
})
}