156 lines
5.1 KiB
TypeScript
156 lines
5.1 KiB
TypeScript
import { and, eq, ne } from 'drizzle-orm';
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
import { trainingPolicies } from '@/db/schema';
|
|
import {
|
|
AUDIT_ACTION,
|
|
AUDIT_MODULE,
|
|
getRequestMetadata,
|
|
logAuditEvent,
|
|
toAuditValue
|
|
} from '@/features/audit-logs/server/audit-service';
|
|
import type { TrainingPolicyMutationPayload } from '@/features/training-policy/api/types';
|
|
import {
|
|
getTrainingPolicyByIdForOrganization,
|
|
getTrainingPolicyByYearForOrganization,
|
|
getTrainingPolicyDetailForOrganization,
|
|
normalizeTrainingPolicyPayload,
|
|
serializeTrainingPolicy
|
|
} from '@/features/training-policy/server/training-policy-data';
|
|
import { AuthError, requirePermission } from '@/lib/auth/session';
|
|
import { db } from '@/lib/db';
|
|
|
|
type Params = { params: Promise<{ id: string }> };
|
|
|
|
export async function GET(_request: NextRequest, { params }: Params) {
|
|
try {
|
|
const { organization } = await requirePermission('training_policy:read');
|
|
const { id } = await params;
|
|
const policyId = Number(id);
|
|
const policy = await getTrainingPolicyDetailForOrganization({
|
|
id: policyId,
|
|
organizationId: organization.id
|
|
});
|
|
|
|
if (!policy) {
|
|
return NextResponse.json(
|
|
{ success: false, message: `ไม่พบนโยบายการอบรมรหัส ${id}` },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
time: new Date().toISOString(),
|
|
message: 'โหลดรายละเอียดนโยบายการอบรมเรียบร้อยแล้ว',
|
|
policy
|
|
});
|
|
} catch (error) {
|
|
if (error instanceof AuthError) {
|
|
return NextResponse.json({ message: error.message }, { status: error.status });
|
|
}
|
|
|
|
console.error('GET /api/training-policies/[id] failed', error);
|
|
return NextResponse.json({ message: 'ไม่สามารถโหลดนโยบายการอบรมได้' }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function PATCH(request: NextRequest, { params }: Params) {
|
|
try {
|
|
const { organization, session } = await requirePermission('training_policy:write');
|
|
const requestMetadata = getRequestMetadata(request);
|
|
const { id } = await params;
|
|
const policyId = Number(id);
|
|
const body = normalizeTrainingPolicyPayload(
|
|
(await request.json()) as TrainingPolicyMutationPayload
|
|
);
|
|
|
|
const existingPolicy = await getTrainingPolicyByIdForOrganization({
|
|
id: policyId,
|
|
organizationId: organization.id
|
|
});
|
|
|
|
if (!existingPolicy) {
|
|
return NextResponse.json(
|
|
{ success: false, message: `ไม่พบนโยบายการอบรมรหัส ${id}` },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
const duplicatePolicy = await getTrainingPolicyByYearForOrganization({
|
|
year: body.year,
|
|
organizationId: organization.id,
|
|
excludeId: policyId
|
|
});
|
|
|
|
if (duplicatePolicy) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
message: `มีนโยบายการอบรมสำหรับปี ${body.year} อยู่แล้ว`
|
|
},
|
|
{ status: 409 }
|
|
);
|
|
}
|
|
|
|
const policy = await db.transaction(async (tx) => {
|
|
if (body.isActive) {
|
|
await tx
|
|
.update(trainingPolicies)
|
|
.set({ isActive: false, updatedAt: new Date() })
|
|
.where(
|
|
and(
|
|
eq(trainingPolicies.organizationId, organization.id),
|
|
ne(trainingPolicies.id, policyId)
|
|
)
|
|
);
|
|
}
|
|
|
|
const [updatedPolicy] = await tx
|
|
.update(trainingPolicies)
|
|
.set({
|
|
year: body.year,
|
|
totalHours: body.totalHours,
|
|
kHours: body.kHours,
|
|
sHours: body.sHours,
|
|
aHours: body.aHours,
|
|
isActive: body.isActive,
|
|
updatedAt: new Date()
|
|
})
|
|
.where(and(eq(trainingPolicies.id, policyId), eq(trainingPolicies.organizationId, organization.id)))
|
|
.returning();
|
|
|
|
return updatedPolicy;
|
|
});
|
|
|
|
const serializedPolicy = serializeTrainingPolicy(policy, {
|
|
updatedByName: session.user.name ?? null
|
|
});
|
|
|
|
await logAuditEvent({
|
|
organizationId: organization.id,
|
|
userId: session.user.id,
|
|
module: AUDIT_MODULE.TRAINING_POLICY,
|
|
action: AUDIT_ACTION.UPDATE,
|
|
entityName: `ปี ${policy.year}`,
|
|
entityId: policy.id,
|
|
oldValue: toAuditValue(serializeTrainingPolicy(existingPolicy)),
|
|
newValue: toAuditValue(serializedPolicy),
|
|
...requestMetadata
|
|
});
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
time: new Date().toISOString(),
|
|
message: 'อัปเดตนโยบายการอบรมเรียบร้อยแล้ว',
|
|
policy: serializedPolicy
|
|
});
|
|
} catch (error) {
|
|
if (error instanceof AuthError) {
|
|
return NextResponse.json({ message: error.message }, { status: error.status });
|
|
}
|
|
|
|
console.error('PATCH /api/training-policies/[id] failed', error);
|
|
return NextResponse.json({ message: 'ไม่สามารถอัปเดตนโยบายการอบรมได้' }, { status: 500 });
|
|
}
|
|
}
|