108 lines
3.1 KiB
TypeScript
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 });
|
|
}
|
|
}
|