feat: add Buchhaltung module with fiscal years, budget accounts, transactions, and approval workflow

This commit is contained in:
Matthias Hochmeister
2026-03-28 19:48:32 +01:00
parent 4349de9bc9
commit 18b1300de8
14 changed files with 2791 additions and 1 deletions

View File

@@ -0,0 +1,129 @@
import { api } from './api';
import type {
Haushaltsjahr, HaushaltsjahrFormData,
Bankkonto, BankkontoFormData,
Konto, KontoFormData, KontoBudgetInfo,
KontoTyp,
Transaktion, TransaktionFormData, TransaktionFilters,
Beleg,
BuchhaltungStats,
} from '../types/buchhaltung.types';
export const buchhaltungApi = {
// ── Haushaltsjahre ──────────────────────────────────────────────────────────
getHaushaltsjahre: async (): Promise<Haushaltsjahr[]> => {
const r = await api.get('/api/buchhaltung/haushaltsjahre');
return r.data.data;
},
createHaushaltsjahr: async (data: HaushaltsjahrFormData): Promise<Haushaltsjahr> => {
const r = await api.post('/api/buchhaltung/haushaltsjahre', data);
return r.data.data;
},
updateHaushaltsjahr: async (id: number, data: Partial<HaushaltsjahrFormData>): Promise<Haushaltsjahr> => {
const r = await api.patch(`/api/buchhaltung/haushaltsjahre/${id}`, data);
return r.data.data;
},
closeHaushaltsjahr: async (id: number): Promise<Haushaltsjahr> => {
const r = await api.post(`/api/buchhaltung/haushaltsjahre/${id}/close`);
return r.data.data;
},
// ── Konto-Typen ─────────────────────────────────────────────────────────────
getKontoTypen: async (): Promise<KontoTyp[]> => {
const r = await api.get('/api/buchhaltung/konto-typen');
return r.data.data;
},
// ── Bankkonten ───────────────────────────────────────────────────────────────
getBankkonten: async (): Promise<Bankkonto[]> => {
const r = await api.get('/api/buchhaltung/bankkonten');
return r.data.data;
},
createBankkonto: async (data: BankkontoFormData): Promise<Bankkonto> => {
const r = await api.post('/api/buchhaltung/bankkonten', data);
return r.data.data;
},
updateBankkonto: async (id: number, data: Partial<BankkontoFormData>): Promise<Bankkonto> => {
const r = await api.patch(`/api/buchhaltung/bankkonten/${id}`, data);
return r.data.data;
},
deleteBankkonto: async (id: number): Promise<void> => {
await api.delete(`/api/buchhaltung/bankkonten/${id}`);
},
// ── Konten ───────────────────────────────────────────────────────────────────
getKonten: async (haushaltsjahrId: number): Promise<Konto[]> => {
const r = await api.get(`/api/buchhaltung/konten?haushaltsjahr_id=${haushaltsjahrId}`);
return r.data.data;
},
createKonto: async (data: KontoFormData): Promise<Konto> => {
const r = await api.post('/api/buchhaltung/konten', data);
return r.data.data;
},
updateKonto: async (id: number, data: Partial<KontoFormData>): Promise<Konto> => {
const r = await api.patch(`/api/buchhaltung/konten/${id}`, data);
return r.data.data;
},
deleteKonto: async (id: number): Promise<void> => {
await api.delete(`/api/buchhaltung/konten/${id}`);
},
getKontoBudget: async (id: number): Promise<KontoBudgetInfo> => {
const r = await api.get(`/api/buchhaltung/konten/${id}/budget`);
return r.data.data;
},
// ── Stats ────────────────────────────────────────────────────────────────────
getStats: async (haushaltsjahrId: number): Promise<BuchhaltungStats> => {
const r = await api.get(`/api/buchhaltung/stats?haushaltsjahr_id=${haushaltsjahrId}`);
return r.data.data;
},
// ── Transaktionen ─────────────────────────────────────────────────────────────
getTransaktionen: async (filters?: TransaktionFilters): Promise<Transaktion[]> => {
const params = new URLSearchParams();
if (filters?.haushaltsjahr_id) params.set('haushaltsjahr_id', String(filters.haushaltsjahr_id));
if (filters?.konto_id) params.set('konto_id', String(filters.konto_id));
if (filters?.status) params.set('status', filters.status);
if (filters?.typ) params.set('typ', filters.typ);
if (filters?.datum_von) params.set('datum_von', filters.datum_von);
if (filters?.datum_bis) params.set('datum_bis', filters.datum_bis);
if (filters?.search) params.set('search', filters.search);
const r = await api.get(`/api/buchhaltung?${params.toString()}`);
return r.data.data;
},
getTransaktion: async (id: number): Promise<Transaktion> => {
const r = await api.get(`/api/buchhaltung/${id}`);
return r.data.data;
},
createTransaktion: async (data: TransaktionFormData): Promise<Transaktion> => {
const r = await api.post('/api/buchhaltung', data);
return r.data.data;
},
updateTransaktion: async (id: number, data: Partial<TransaktionFormData>): Promise<Transaktion> => {
const r = await api.patch(`/api/buchhaltung/${id}`, data);
return r.data.data;
},
deleteTransaktion: async (id: number): Promise<void> => {
await api.delete(`/api/buchhaltung/${id}`);
},
buchenTransaktion: async (id: number): Promise<Transaktion> => {
const r = await api.post(`/api/buchhaltung/${id}/buchen`);
return r.data.data;
},
stornoTransaktion: async (id: number): Promise<Transaktion> => {
const r = await api.post(`/api/buchhaltung/${id}/storno`);
return r.data.data;
},
uploadBeleg: async (transaktionId: number, file: File): Promise<Beleg> => {
const formData = new FormData();
formData.append('datei', file);
const r = await api.post(`/api/buchhaltung/${transaktionId}/belege`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
return r.data.data;
},
deleteBeleg: async (id: number): Promise<void> => {
await api.delete(`/api/buchhaltung/belege/${id}`);
},
};