Files
edr-platform/apps/finance-web/src/features/budgeting/api.ts
2026-08-25 00:11:39 +03:00

162 lines
3.9 KiB
TypeScript

import { financeApi } from "@/auth/http";
import type { LocalizedName } from "@/shared/types";
export type CostCenter = {
id: string;
code: string;
name: LocalizedName;
parentId: string | null;
unitId: string | null;
unitName: LocalizedName | null;
managerEmployeeId: string | null;
managerName: string | null;
isGroup: boolean;
isActive: boolean;
};
export type CostCenterNode = {
id: string;
code: string;
name: LocalizedName;
parentId: string | null;
isGroup: boolean;
isActive: boolean;
children: CostCenterNode[];
};
export type Budget = {
id: string;
fiscalYearId: string;
name: string;
status: "DRAFT" | "APPROVED" | "CLOSED";
description: string | null;
approvedBy: string | null;
approvedAt: string | null;
};
export type BudgetLine = {
id: string;
accountId: string;
accountCode: string;
accountName: LocalizedName;
costCenterId: string | null;
costCenterCode: string | null;
costCenterName: LocalizedName | null;
fiscalPeriodId: string;
periodNumber: number;
periodName: LocalizedName;
amount: number | string;
note: string | null;
};
export type BudgetDetail = Budget & { lines: BudgetLine[] };
export type VarianceRow = {
accountId: string;
accountCode: string;
accountName: LocalizedName;
accountType: string;
costCenterId: string | null;
costCenterCode: string | null;
costCenterName: LocalizedName | null;
budget: number;
actual: number;
committed: number;
variance: number;
remaining: number;
percentUsed: number | null;
isOverBudget: boolean;
isUnbudgeted: boolean;
};
export const BUDGET_STATUS_COLOR: Record<string, string> = {
DRAFT: "gray",
APPROVED: "green",
CLOSED: "blue",
};
export const fetchCostCenters = async (): Promise<CostCenter[]> => {
const { data } = await financeApi.get("/budgeting/cost-centers");
return data;
};
export const fetchCostCenterTree = async (
search?: string,
): Promise<CostCenterNode[]> => {
const { data } = await financeApi.get("/budgeting/cost-centers/tree", {
params: search ? { search } : undefined,
});
return data;
};
export const fetchUnlinkedUnits = async (): Promise<
{ id: string; name: LocalizedName }[]
> => {
const { data } = await financeApi.get("/budgeting/cost-centers/unlinked-units");
return data;
};
export const createCostCenter = async (payload: {
code: string;
name: { en: string; am: string };
parentId?: string;
unitId?: string;
isGroup?: boolean;
}): Promise<CostCenter> => {
const { data } = await financeApi.post("/budgeting/cost-centers", payload);
return data;
};
export const deleteCostCenter = async (id: string): Promise<void> => {
await financeApi.delete(`/budgeting/cost-centers/${id}`);
};
export const fetchBudgets = async (): Promise<Budget[]> => {
const { data } = await financeApi.get("/budgeting/budgets");
return data;
};
export const fetchBudget = async (id: string): Promise<BudgetDetail> => {
const { data } = await financeApi.get(`/budgeting/budgets/${id}`);
return data;
};
export const createBudget = async (payload: {
fiscalYearId: string;
name: string;
description?: string;
}): Promise<Budget> => {
const { data } = await financeApi.post("/budgeting/budgets", payload);
return data;
};
export const spreadBudget = async (
id: string,
entries: {
accountId: string;
costCenterId?: string;
annualAmount: number;
note?: string;
}[],
): Promise<BudgetDetail> => {
const { data } = await financeApi.post(`/budgeting/budgets/${id}/spread`, {
entries,
});
return data;
};
export const approveBudget = async (id: string): Promise<BudgetDetail> => {
const { data } = await financeApi.post(`/budgeting/budgets/${id}/approve`);
return data;
};
export const fetchVariance = async (
id: string,
fiscalPeriodId?: string,
): Promise<VarianceRow[]> => {
const { data } = await financeApi.get(`/budgeting/budgets/${id}/variance`, {
params: fiscalPeriodId ? { fiscalPeriodId } : undefined,
});
return data;
};