Files
alla-tms/src/app/api/employee-directory/[id]/target/route.ts
2026-07-16 09:53:14 +07:00

108 lines
3.1 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { AuthError, requireHRD } from '@/lib/auth/session';
import {
getEmployeeTargetForOrganization,
upsertEmployeeTargetForOrganization
} from '@/features/employee-directory/server/employee-directory-data';
const targetSchema = z
.object({
year: z.number().int().min(2000),
totalHours: z.number().min(0),
kHours: z.number().min(0),
sHours: z.number().min(0),
aHours: z.number().min(0)
})
.refine((value) => Number((value.kHours + value.sHours + value.aHours).toFixed(2)) === Number(value.totalHours.toFixed(2)), {
message: 'ผลรวม K/S/A ต้องเท่ากับชั่วโมงรวม',
path: ['totalHours']
});
export async function GET(
request: NextRequest,
context: { params: Promise<{ id: string }> }
) {
try {
const { organization } = await requireHRD();
const params = await context.params;
const employeeId = Number(params.id);
const year = Number(request.nextUrl.searchParams.get('year') ?? new Date().getUTCFullYear());
const target = await getEmployeeTargetForOrganization({
organizationId: organization.id,
employeeId,
year
});
if (!target) {
return NextResponse.json({ message: 'Employee not found' }, { status: 404 });
}
return NextResponse.json({
success: true,
time: new Date().toISOString(),
message: 'Employee target loaded successfully',
target
});
} catch (error) {
if (error instanceof AuthError) {
return NextResponse.json({ message: error.message }, { status: error.status });
}
return NextResponse.json({ message: 'Unable to load employee target' }, { status: 500 });
}
}
export async function PUT(
request: NextRequest,
context: { params: Promise<{ id: string }> }
) {
try {
const { organization, session } = await requireHRD();
const params = await context.params;
const employeeId = Number(params.id);
const body = await request.json();
const parsed = targetSchema.safeParse({
year: Number(body.year),
totalHours: Number(body.totalHours),
kHours: Number(body.kHours),
sHours: Number(body.sHours),
aHours: Number(body.aHours)
});
if (!parsed.success) {
return NextResponse.json(
{
message: parsed.error.issues[0]?.message ?? 'Invalid target payload'
},
{ status: 400 }
);
}
const target = await upsertEmployeeTargetForOrganization({
organizationId: organization.id,
employeeId,
actorUserId: session.user.id,
values: parsed.data
});
if (!target) {
return NextResponse.json({ message: 'Employee not found' }, { status: 404 });
}
return NextResponse.json({
success: true,
time: new Date().toISOString(),
message: 'Employee target updated successfully',
target
});
} catch (error) {
if (error instanceof AuthError) {
return NextResponse.json({ message: error.message }, { status: error.status });
}
return NextResponse.json({ message: 'Unable to update employee target' }, { status: 500 });
}
}