- 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>
16 lines
1.2 KiB
TypeScript
16 lines
1.2 KiB
TypeScript
import { clockAccess, clockFailure, clockJson } from '@/lib/clock-api';
|
|
import { ClockRepeat, saveClock } from '@/lib/clock';
|
|
import { clockPB, clockStore } from '@/lib/clock-store';
|
|
export async function POST(request:Request) {
|
|
try {
|
|
const user=await clockAccess(request);if(user instanceof Response)return user;
|
|
if(user.access==='mechanic'||user.access==='office')return Response.json({error:'Mechanics cannot clock in or out.'},{status:403});
|
|
let body:unknown;try{body=await request.json();}catch{return Response.json({error:'Supply valid JSON.'},{status:400});}
|
|
const event=await saveClock(clockStore(await clockPB()),body,user.user.id);
|
|
return clockJson({id:event.id,employeeName:event.employee_name,employeeNo:event.employee_no,direction:event.direction,at:event.scanned_at,sessionMinutes:event.session_minutes});
|
|
}catch(e){
|
|
// A repeat read is not a failure: the scan that counts is already saved, so say which one.
|
|
if(e instanceof ClockRepeat)return Response.json({error:e.message,repeat:{employeeName:e.employeeName,direction:e.last.direction,at:e.last.scanned_at}},{status:409,headers:{'Cache-Control':'no-store'}});
|
|
return clockFailure(e);
|
|
}
|
|
}
|