Skip to content

Timekeeping - Technical Map

Auto-generated bởi codebase-doc-generator ngày 2026-03-23 (verified từ code thực). Không chỉnh sửa thủ công.

Routes

RoutePathMục đích
ROUTE_TIMEKEEPING_WORKING_SCHEDULE/t/working-scheduleMa trận lịch làm việc theo tuần
ROUTE_TIMEKEEPING_WORKING_SHEET/t/working-sheetBảng chấm công theo tháng
ItemGiá trị
Menu titleChấm Công
Menu moduleIdclocking_management
Working schedule moduleIdworking_schedule
Working sheet moduleIdclocking_history
PlatformsAdmin, CRM, POS

Permission matrix

AreaPermissions
Working schedule routeITLeader, ITStaff, BranchPOS, USER_GROUP_TREE[CallCenter]
Working sheet route configITLeader, ITStaff, BranchPOS
Working sheet submenuITLeader, ITStaff
FullPermissionWorkingTimeSheetBOD, HRLeader, HRStaff, HRCheck, AuditLeader, ITLeader, ITStaff

FE Pages (3)

PageFileVai trò
Working schedulepages/WorkingSchedule.tsxMa trận 7 ngày, filter phòng ban, import/export, edit
Working schedule create/editpages/WorkingScheduleCreate.tsxWrapper submit cho WorkingScheduleForm
Working time sheetpages/WorkingTimeSheet.tsxMa trận chấm công theo tháng

FE Components (8)

ComponentVai trò
WorkingScheduleFormForm tạo/sửa lịch làm việc
WorkingScheduleImportImport lịch từ Excel
WorkingScheduleUpdateBtnNút edit overlay khi hover cell
WorkingTimeSheetItemCell detail cho timesheet
NoClockCellPopup giải thích ô thiếu clocking và request liên quan
ExportWorkingTimeSheetExport bảng công
ExportWorkingTimeSheetByDayExport theo ngày
ExportTotalWorkingTimeSheetByDayExport tổng hợp theo ngày

GraphQL Operations

File: diva-admin/src/modules/timekeeping/graphql/working-schedule.graphql

Schedule/template

OperationMục đích
GetActiveTimeSlotTemplateLấy mẫu ca active
GetAllTimeSlotTemplateLấy toàn bộ ca để import/map
upsertTimeSlotUserDelete lịch cũ trong range rồi insert/upsert lịch mới
ListWorkingShiftLấy lịch làm việc theo user + ca + request approved
ListUserByDepartmentLấy user theo phòng ban
ListTimeSlotUserLấy slot user trong ngày để giải thích cell timesheet

Timesheet

OperationMục đích
ListTimeKeepingLấy time_slot_time_keeping cho bảng công
GetExportListTimeKeepingExport raw timesheet
ListRequestWorkingScheduleOverlay request approved lên timesheet

Supporting

OperationMục đích
getUserForWorkingScheduleLấy thông tin user khi thao tác lịch

FE Runtime logic

WorkingSchedule.tsx

LogicGhi chú
Weekly rangeDùng startOfWeek(..., weekStartsOn: 1)endOfWeek
Default departmentFull-permission role -> "all", user thường -> phòng ban đầu tiên không in_charge
ColumnsSinh 7 cột từ thứ 2 đến chủ nhật
User scopeKết hợp department, keyword, branch user, shift group
ImportsMở WorkingScheduleImport

WorkingScheduleCreate.tsx

LogicGhi chú
Create modeUpsert cả tuần
Edit modeNếu có workingDate hoặc slot đang sửa thì chỉ thao tác theo ngày đó
SubmitMutation upsertTimeSlotUser với userIds: [value.user_id]

WorkingTimeSheet.tsx

LogicGhi chú
Monthly rangeDùng startOfMonth / endOfMonth
Default departmentTương tự working schedule nhưng hỗ trợ multi-department
Data sourcesListTimeKeeping + ListRequestWorkingSchedule + helper user scope
Cell renderingDùng WorkingTimeSheetItem hoặc NoClockCell tùy trạng thái

NoClockCell.tsx

LogicGhi chú
Request overlayLọc request approved theo thời gian phủ lên ngày đang xem
remote_weeklyKiểm tra thêm weekday để match đúng thứ
Popup detailGọi ListTimeSlotUser để hiển thị khung giờ chuẩn và request liên quan

Import logic

LogicGhi chú
Parse rowBỏ qua 2 dòng đầu, đọc từ row 3
Day mapping7 ô ngày map sang tuần hiện tại hoặc tuần sau
User mappinguserName -> userName@diva.vn
Multi-shiftMột ô có thể chứa nhiều mã ca, tách bằng dấu phẩy

Backend Actions / Events

check_attendance.go

Hành viGhi chú
Action namecheckAttendance
Inputstatus
Supported pathHiện chỉ xử lý check_in
First download pathNếu account chưa is_downloaded, cập nhật account và insert attendance trong cùng mutation
Side effectsCustomer popup event + gamification login mission

attendance_insert.go

Hành viGhi chú
Event nameattendance_insert
TriggerSau khi insert attendance
Side effectAddPointsToCustomer() theo app settings

Timekeeping/request events liên quan

EventVai trò
request_working_schedule_insertXử lý lifecycle request liên quan lịch/chấm công
request_working_schedule_updateĐồng bộ request approved vào time_slot_time_keeping / slot
time_slot_template_updateĐồng bộ thay đổi template xuống time_slot_user hiện có

Store / Data model

time_slot_user

FieldÝ nghĩa
user_idNhân viên
start_time, end_timeGiờ ca
nameTên ca snapshot
break_time, start_break_time, end_break_timeNghỉ giữa ca
workdayGiá trị ngày công của ca
time_keeping_idLink sang bản ghi timesheet nếu đã map

time_slot_time_keeping

FieldÝ nghĩa
created_byNhân viên được chấm công
created_atThời điểm record
clock_in, clock_outGiờ vào/ra
late_arrival, leave_early, off, overtime, is_holidayFlags nghiệp vụ
workdayGiá trị ngày công thực tế
position_in, position_outVị trí check-in/out
device_id_in, device_id_outThiết bị chấm công
auto_update_reasonLý do hệ thống tự hiệu chỉnh dữ liệu

request_working_schedule

FieldÝ nghĩa
status_idpending, approved, rejected, recalled, canceled, approved_step_one
typechange_shift, overtime, leave, late_arrival_early_leave, forget_clock_in_out, clock_in_out, onsite, remote, ...
behaviorChi tiết hành vi như late_arrival, early_leave, remote_weekly, annual_leave
from, toKhoảng thời gian request
workdayNgày công điều chỉnh
clock_in_out_itemsItem con cho request clocking
weekdayJSON weekday cho các request lặp như remote_weekly

attendance

FieldÝ nghĩa
user_idUser attendance
statuscheck_in / check_out
created_atThời điểm attendance
consecutiveChuỗi streak hiện tại
consecutive_recordKỷ lục streak

Key helper functions

FunctionVai trò
GetStartEndTimeKeeping()Tính lại khung giờ chuẩn dựa trên slot + request
MutationTimeSlotTimeKeeping()Upsert timesheet với danh sách cột update khá rộng, gồm cả auto_update_reason
QueryTimeSlotUser()Query slot theo where/order; trả ErrTimeSlotUserNotFound nếu rỗng
dateCompare()So sánh request có phủ lên ngày chấm công hay không

Attendance schema

Migration 1666248708222_attendance

ObjectVai trò
attendance_statusMaster 2 trạng thái check_in, check_out
attendanceBảng log attendance
attendance_uniqueView lấy min(created_at) theo user_id, status, ngày ở timezone Asia/Ho_Chi_Minh

Migration 1667186720446_alter_table_public_attendance_add_column_consecutive

CộtVai trò
consecutiveChuỗi ngày liên tiếp
consecutive_recordKỷ lục chuỗi ngày liên tiếp

Rủi ro / Findings kỹ thuật

#Note
1MODULE_TIMEKEEPING = "t" làm route ngắn nhưng gây khó đọc khi tìm code theo tên module.
2Mutation upsertTimeSlotUser xóa lịch cũ trong range trước khi insert lại, nên là mô hình replace-window chứ không patch từng slot nhỏ.
3Attendance action hiện chỉ có branch xử lý check_in; check_out chưa thấy implementation thực sự trong action này.
4Quyền clocking_history giữa route config và submenu không đồng bộ hoàn toàn cho BranchPOS.