Files
RFP_Finanzen/src/app/api/expenses/[id]/paid/route.ts
jan 7d23214a2d
All checks were successful
CI / Build (push) Successful in 1m59s
CI / Deploy (push) Successful in 1m58s
Dokumentationsberechtigung fuer AG Orga ergaenzen
2026-05-01 17:49:42 +02:00

68 lines
1.9 KiB
TypeScript

import { NextResponse } from "next/server";
import { createAuditLog } from "@/lib/audit-log";
import { canMarkPaid } from "@/lib/domain";
import prisma from "@/lib/prisma";
import { getCurrentViewer } from "@/lib/session";
type Context = {
params: Promise<{
id: string;
}>;
};
export async function POST(_: Request, { params }: Context) {
const { id } = await params;
const viewer = await getCurrentViewer();
if (!viewer) {
return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 });
}
if (!canMarkPaid(viewer.role)) {
return NextResponse.json({ error: "Nur Vorstand allgemein, AG Orga oder AG Finanzen duerfen Bezahlt setzen." }, { status: 403 });
}
const expense = await prisma.expense.findUnique({
where: { id }
});
if (!expense) {
return NextResponse.json({ error: "Ausgabe nicht gefunden." }, { status: 404 });
}
if (expense.approvalStatus !== "APPROVED") {
return NextResponse.json({ error: "Bezahlt ist erst nach Freigabe moeglich." }, { status: 400 });
}
if (!expense.proofUrl || !expense.invoiceDate || !expense.documentedAt) {
return NextResponse.json({ error: "Bitte zuerst Rechnung mit Rechnungsdatum abgeben." }, { status: 400 });
}
const updatedExpense = await prisma.expense.update({
where: { id },
data: {
paidAt: expense.paidAt ?? new Date()
}
});
await createAuditLog(prisma, {
actorId: viewer.id,
action: "expense.markPaid",
entityType: "expense",
entityId: updatedExpense.id,
entityLabel: updatedExpense.title,
summary: `Ausgabe ${updatedExpense.title} wurde als bezahlt markiert.`,
metadata: {
rollback: {
kind: "expense.markPaid",
expenseId: updatedExpense.id,
previousPaidAt: expense.paidAt?.toISOString() ?? null,
nextPaidAt: updatedExpense.paidAt?.toISOString() ?? null
}
}
});
return NextResponse.json({ expense: updatedExpense });
}