Payroll / Timesheet — Góc nhìn end-user
Bốn bề mặt: Finance Settings (admin chọn cơ sở giờ), Staff Attendance (staff/admin chấm công), Timesheet Approved tab (admin duyệt & export) và dòng nghỉ không ca (leave-only row).
A. Finance Settings → Payroll tab
Admin Portal → Settings → Finance → Payroll. Tab chỉ hiện khi BU đang bật Staff Roster.
- Tab
Payrollhiện ngay sau Subsidy Settings; ẩn khi user/session không có quyềnSTAFF_ROSTERcho BU hiện tại. - Route
/settings/finance/payrollbảo vệ cùng quy tắc: truy cập thẳng khi không cóSTAFF_ROSTER→ không mở được. - Form có 2 lựa chọn map thẳng backend:
Rostered Hours=0,Actual Hours=1; thiếu setting → mặc địnhRostered Hours(0). - Lưu yêu cầu quyền
SettingFinance; payloadBusinessUnitPayrollSettingModelquaGET/POST /api/BusinessUnitSetting/Payroll(route là ranh giới quyền, không phải table).
Ví dụ thực tế: Admin không thấy tab Payroll trong Settings → Finance. → BU thiếu STAFF_ROSTER hoặc chưa bật Staff Roster. → Tab không render đúng quy tắc, không phải lỗi UI.
B. Staff Attendance — clock-in / clock-out
Màn chấm công; tạo ca mới cho nhân viên trong BU hiện tại.
- Clock-in ca mới: thiếu link
OrgEmployeeactive choEmployeeId+OrgId→ tự tạo rồi gánShift.OrgEmployeeId; đã có → tái dùng, không tạo trùng. - Clock-out tạo ca kế tiếp: ca copy thiếu/inactive
OrgEmployeeId→ resolve/tạo link active trước khi lưu ca mới. - Nhân viên hoặc org không active trong BU → ca mới bị reject, không tạo
OrgEmployee, không tạo ca.
Ví dụ thực tế: Staff chưa có OrgEmployee ở site mới, bấm clock-in. → Không để ca lưu fail vì thiếu link. → Backend tự tạo OrgEmployee active gắn vào Shift.OrgEmployeeId.
C. Timesheet Approved tab — export CSV
Timesheet → tab Approved → chọn dòng → Export. Toàn bộ file do server dựng, browser không assemble.
- Chọn dòng xong bấm Export → hệ thống hỏi chọn mode trước khi sinh file, mặc định
separated.separated: mỗi dòng timesheet được chọn = 1 CSV record.grouped: mỗi staff = 1 CSV record, gộp tổng giờ các dòng đã chọn.
- Hủy prompt: không sinh file, không đánh dấu dòng exported, giữ nguyên selection.
- File tải về là CSV duy nhất (không xlsx/PDF), tên file suy từ khoảng ngày yêu cầu.
- Dòng exported thành công được đánh dấu
exported; action un-export xóa cờ để dòng được chọn lại. - Dòng đã exported bị khóa chọn; chỉ còn action un-export.
Ví dụ thực tế: Admin chọn 3 dòng, Export mode separated. → File không phụ thuộc nội dung hiển thị của browser. → Server re-query 3 id, jsReport render CSV, đánh dấu 3 dòng exported trong một round-trip.
D. Dòng nghỉ không ca (leave-only row)
EmployeeAbsenceapproved vào ngày không có ca → hiện thành một dòng riêng vớiDate,Name,Leave Hours,Tracking Code;Orgvà cột giờ ca để trống.- Có vòng duyệt riêng: chuyển giữa draft / approved tab theo trạng thái timesheet của chính absence, không đụng duyệt leave.
- Approve/un-approve/export/un-export hoạt động như dòng ca, nhưng không ghi paid time / duration (không tồn tại trên leave).
- Leave trùng ca không tạo leave-only row — vẫn hiển thị bên trong cột leave của dòng ca.
- Leave chưa approved (pending/rejected) không xuất hiện thành dòng timesheet ở bất kỳ tab nào.
Ví dụ thực tế: Nghỉ approved 09:00–13:00 (code AL) hôm không có ca. → Dòng nghỉ vẫn vào bảng lương. → Timesheet hiện 1 dòng leave-only: Leave Hours = 4.00, Tracking Code = AL, cột giờ ca trống.
Tóm lại
| Vai | Làm gì |
|---|---|
| Admin (Finance) | Bật/đổi cơ sở giờ Rostered Hours / Actual Hours theo BU trong Settings → Finance → Payroll. |
| Staff / Admin (Attendance) | Clock-in/out; ca mới tự đảm bảo link OrgEmployee. |
| Admin (Timesheet) | Duyệt/un-duyệt dòng, chọn mode export, un-export; xử lý cả dòng ca và dòng nghỉ không ca. |