104 lines
3.4 KiB
TypeScript
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!);
|
|
}
|
|
})
|
|
} |