7.4 KiB
7.4 KiB
Management Change Import Employee KSA Targets Review
1. Summary
เพิ่มการนำเข้าชั่วโมงเป้าหมายรายบุคคล K/S/A ผ่านหน้า Import Employees โดยยังคงพฤติกรรมเดิมของการนำเข้าพนักงานไว้ครบถ้วน และเพิ่ม fallback จาก Training Policy เมื่อแถวใดไม่ระบุเป้าหมายรายบุคคล
ลำดับการ resolve เป้าหมายที่ระบบใช้หลังการเปลี่ยนแปลง:
employee_training_targetstraining_policies- ค่าเริ่มต้น 0 ชั่วโมง
2. Files Changed
src/db/schema.tssrc/constants/thai-labels.tssrc/features/training-policy/server/employee-training-target-data.tssrc/features/import-employees/api/types.tssrc/app/api/import-employees/route.tssrc/app/api/import-employees/template/route.tssrc/features/import-employees/components/employee-import-page.tsxsrc/features/audit-logs/server/audit-service.tssrc/features/audit-logs/server/audit-log-data.tssrc/features/overview/server/overview-data.tssrc/features/reports/api/types.tssrc/features/reports/server/report-data.tssrc/features/reports/components/reports-page-content.tsx
3. Database Changes
เพิ่มตาราง employee_training_targets
idorganization_iduser_idyeartotal_hoursk_hourss_hoursa_hourscreated_byupdated_bycreated_atupdated_at
Unique constraint:
organization_id + user_id + year
เหตุผลที่ใช้ user_id:
- ระบบ runtime ปัจจุบันใช้
usersเป็น source of truth - dashboard, reports, training records อ้างอิง
training_records.user_id
4. Excel Template Changes
เพิ่มคอลัมน์ท้าย template:
ชั่วโมงรวมชั่วโมง Kชั่วโมง Sชั่วโมง A
Template download ตัวอย่างแถวข้อมูลถูกอัปเดตให้มีคอลัมน์ใหม่ครบ
5. Validation Rules
กติกา validation ที่เพิ่ม:
- ถ้าไม่กรอกคอลัมน์ target ทั้ง 4 ช่อง จะ import พนักงานตามปกติ
- ถ้ากรอก target อย่างน้อย 1 ช่อง ต้องกรอกให้ครบทั้ง 4 ช่อง
- ต้องเป็นตัวเลข
- ต้องมากกว่าหรือเท่ากับ 0
ชั่วโมงรวมต้องมากกว่า 0K + S + Aต้องเท่ากับชั่วโมงรวม- ปีที่ใช้บันทึก target จะใช้ปีปัจจุบัน หรือปีที่ส่งมาจาก form ถ้ามี
- ถ้าส่งปีแบบ พ.ศ. ระบบจะแปลงเป็น ค.ศ. ก่อนจัดเก็บ
ข้อความ error หลักที่รองรับ:
กรุณาระบุชั่วโมงรวมกรุณาระบุชั่วโมง Kกรุณาระบุชั่วโมง Sกรุณาระบุชั่วโมง Aชั่วโมงต้องเป็นตัวเลขชั่วโมงต้องเป็นตัวเลขที่มากกว่าหรือเท่ากับ 0ชั่วโมงรวมต้องมากกว่า 0ผลรวมของชั่วโมง K/S/A ต้องเท่ากับชั่วโมงรวม
6. Import Behavior
ต่อ 1 แถวที่ผ่าน validation:
- upsert
usersและmembershipsตาม behavior เดิม - ถ้ามี target รายบุคคล จะ upsert
employee_training_targets - ถ้าไม่มี target รายบุคคล ระบบจะถือว่าแถวนั้นใช้ fallback จาก
Training Policy
Import summary ที่เพิ่ม:
- จำนวนเป้าหมาย K/S/A ที่นำเข้า
- จำนวนรายการที่ใช้
Training Policy
7. Dashboard Impact
Employee dashboard:
- ใช้ target รายบุคคลก่อน
- ถ้าไม่พบ target รายบุคคล จะ fallback ไป
Training Policy - K/S/A progress และ completion cards จะอิง target ที่ resolve แล้ว
HRD dashboard:
- การคำนวณ
ผ่านเป้าหมายและยังไม่ผ่านเป้าหมายเปลี่ยนเป็นใช้ target รายคน - ถ้าไม่พบ target รายคน จะ fallback ไป
Training Policy
8. Reports Impact
Training Matrix:
- เพิ่มข้อมูล
approvedHours - เพิ่มข้อมูล
targetHours - เพิ่ม
targetSource - เพิ่ม
targetStatus
รายงานหน้า UI จะแสดง:
- ชั่วโมงอนุมัติ
- เป้าหมายชั่วโมง
- แหล่งที่มาของเป้าหมาย
- สถานะผ่าน/ยังไม่ผ่านเป้าหมาย
9. Audit Events
เพิ่ม audit actions:
EMPLOYEE_TARGET_CREATEEMPLOYEE_TARGET_UPDATE
ข้อมูลที่บันทึก:
employeeCodeyear- ค่า target เดิม
- ค่า target ใหม่
10. Permission Rules
- ใช้
requireHRD()เหมือนเดิม - เฉพาะ HRD/Admin ที่เข้าถึง import route ได้
- พนักงานไม่มี route สำหรับแก้ target รายบุคคลโดยตรง
11. Manual Test Checklist
- Download template includes K/S/A target columns.
- Import employee without K/S/A target works.
- Import employee with valid target works.
- Import creates employee-specific target.
- Re-import updates existing employee target.
- Import blocks missing partial target fields.
- Import blocks non-numeric target fields.
- Import blocks K+S+A not equal total.
- Import summary shows target counts.
- Employee dashboard uses employee target.
- Employee dashboard falls back to Training Policy when no target exists.
- HRD dashboard pass/fail uses employee target.
- Training Matrix uses employee target.
- Audit log records target create/update.
- Employee cannot edit target directly.
- Mobile import page remains responsive.
12. Known Limitations
- Import UI ปัจจุบันยังไม่มี year picker แยก จึงใช้ปีปัจจุบันเป็นค่า default
- Export header ของรายงานยังควรทดสอบกับข้อมูลจริงอีกครั้งหลัง migrate/seed
- การ import ต่อแถวไม่ได้ห่อ transaction แยกทั้งแถว จึงเป็น partial success ได้ตาม behavior เดิมของระบบ