mega-plant/app/api/clock/cash-float/opening/route.ts
David 1ec52961ee Cash float card, Office role + Slips tab, job card PDF, manual close/delete
- Cash Floats: ledger card (opening balance, top-ups, slips), manual entries, slip photos
- Office access level; clock app Slips tab (photograph a slip, popup for supplier/cost
  code/comments/amount); only Office sees it; per-role route table in lib/clock-access
- Job cards: Machine Service PDF (with Oil block), JC numbers, manual Close job, Delete
- Hide Expenses > Vehicle Costs and Finance (Bastion) from the menu

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 15:09:57 +02:00

28 lines
1.5 KiB
TypeScript

import { revalidatePath } from 'next/cache';
import { clockAccess, clockFailure, clockJson } from '@/lib/clock-api';
import { clockPB } from '@/lib/clock-store';
import { hasOpening, parseAmount } from '@/lib/cash-float';
// POST /api/clock/cash-float/opening { amount }
// The first-time step: what is on the card right now. Allowed ONCE; after that the balance only
// moves through slips and top-ups (a correction is made in the main app).
export async function POST(request: Request) {
try {
const user = await clockAccess(request);
if (user instanceof Response) return user;
let body: { amount?: unknown };
try { body = await request.json(); } catch { return Response.json({ error: 'Supply valid JSON.' }, { status: 400 }); }
const amount = parseAmount(body.amount, true);
if (amount === null) return Response.json({ error: 'Enter the balance on the card as a number (0 or more).' }, { status: 400 });
const pb = await clockPB();
const entries = await pb.collection('cash_float_entries').getFullList({ fields: 'kind' });
if (hasOpening(entries)) return Response.json({ error: 'The opening balance is already set.' }, { status: 409 });
await pb.collection('cash_float_entries').create({
kind: 'opening', amount, occurred_on: new Date().toISOString(), comment: 'Opening balance',
recorded_by: String(user.user.name || user.user.email || user.user.id),
});
revalidatePath('/expenses/petty-cash');
return clockJson({ ok: true, balance: amount });
} catch (e) { return clockFailure(e); }
}