In der Nutzerverwaltung kannst du jetzt pro Konto die Rolle, die AG-Zuordnung und die Freigaberollen bearbeiten. Die feste 3er-Freigabelogik bleibt Vorstand A / Vorstand B / Finanz-AG, aber jetzt legst du über die Nutzer fest, wer diese Schritte autorisieren darf. Zusätzlich gibt es unter Nutzer anlegen eine eigene Insel für die Freigabe-Schwelle, und diese Schwelle wird jetzt auch wirklich überall verwendet: in der Erfassungslogik, in den Budgetkarten, im CSV-Backup/-Import und im Audit-Restore. Die Hauptänderungen sitzen in dashboard-shell.tsx, budget-column.tsx, route.ts, schema.prisma und route.ts.
All checks were successful
CI / build-and-deploy (push) Successful in 1m22s
All checks were successful
CI / build-and-deploy (push) Successful in 1m22s
Den Zeitraum-Bereich habe ich dabei gleich mit aufgeräumt: die Auswahl des aktuellen Haushalts ist breiter und sauberer angeordnet, und die Desktop-Nutzerverwaltung ist jetzt wirklich links Anlegen + Schwelle und rechts die Nutzerliste. Seed und Backup/Restore kennen die neuen Felder ebenfalls in seed.ts, route.ts und route.ts.
This commit is contained in:
@@ -42,6 +42,7 @@ type BudgetColumnProps = {
|
||||
group: DashboardWorkingGroup;
|
||||
viewer: DashboardViewer;
|
||||
busy: boolean;
|
||||
approvalThreshold: number;
|
||||
onApprove: (expenseId: string, approvalType: "CHAIR_A" | "CHAIR_B" | "FINANCE") => Promise<void>;
|
||||
onMarkPaid: (expenseId: string) => Promise<void>;
|
||||
onDocument: (expenseId: string, proofUrl?: string) => Promise<void>;
|
||||
@@ -51,7 +52,6 @@ type BudgetColumnProps = {
|
||||
onDeleteBudget: (budgetId: string) => Promise<void>;
|
||||
onDeleteExpense: (expenseId: string) => Promise<void>;
|
||||
};
|
||||
|
||||
type BudgetDraft = {
|
||||
name: string;
|
||||
totalBudget: string;
|
||||
@@ -125,6 +125,7 @@ export function BudgetColumn({
|
||||
group,
|
||||
viewer,
|
||||
busy,
|
||||
approvalThreshold,
|
||||
onApprove,
|
||||
onMarkPaid,
|
||||
onDocument,
|
||||
@@ -471,7 +472,7 @@ export function BudgetColumn({
|
||||
sx={{ ...wrappingChipSx, width: "fit-content" }}
|
||||
/>
|
||||
<Typography color="text.secondary">
|
||||
{"Unter 50 EUR werden sofort freigegeben. Gr\u00f6\u00dfere Ausgaben bleiben blass, bis alle drei Signaturen vorliegen."}
|
||||
{`Unter ${formatCurrency(approvalThreshold)} werden sofort freigegeben. Groessere Ausgaben bleiben blass, bis alle drei Signaturen vorliegen.`}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
@@ -563,8 +564,8 @@ export function BudgetColumn({
|
||||
|
||||
{budget.expenses.map((expense) => {
|
||||
const doneApprovalTypes = expense.approvals.map((approval) => approval.approvalType);
|
||||
const availableApprovals = requiresManualApproval(expense.amount)
|
||||
? getAvailableApprovalTypes(viewer.role, viewer.approvalPreference, doneApprovalTypes)
|
||||
const availableApprovals = requiresManualApproval(expense.amount, approvalThreshold)
|
||||
? getAvailableApprovalTypes(viewer.approvalPermissions, doneApprovalTypes)
|
||||
: [];
|
||||
|
||||
return (
|
||||
@@ -602,7 +603,7 @@ export function BudgetColumn({
|
||||
</Typography>
|
||||
) : null}
|
||||
|
||||
{requiresManualApproval(expense.amount) ? (
|
||||
{requiresManualApproval(expense.amount, approvalThreshold) ? (
|
||||
<Stack direction="row" gap={1} useFlexGap flexWrap="wrap">
|
||||
{APPROVAL_FLOW.map((approvalType) => {
|
||||
const matchingApproval = expense.approvals.find(
|
||||
|
||||
Reference in New Issue
Block a user