SRS — App Chấm công (Longdo ERP nội bộ)¶
App_chấm công.xlsx | Nguồn màn: mockup app-cham-cong + app-longdo-erp (pace-1)
Tài liệu đặc tả yêu cầu phần mềm (SRS) cho App Chấm công nội bộ Longdo (Flutter / Material 3). Tài liệu dành cho Dev đọc để hiện thực hóa — mô tả màn hình theo mockup, logic nghiệp vụ phân tích từ code, và phân quyền từng màn theo 3 vai trò (HR / Quản lý / Nhân viên) theo bảng phân quyền BA cung cấp.
Đã chốt 13/13 vấn đề mở (bản 0.6, 03/07/2026)
Một số quyết định làm mockup hiện tại chưa khớp SRS (vd bỏ 2 loại giải trình, bỏ nút "Xin chấm công từ xa", chọn Phương án A cho Kiểm tra vị trí…) — Dev triển khai theo §8 Vấn đề mở, BA sẽ cập nhật lại mockup sau.
1. Giới thiệu¶
1.1 Mục đích¶
App cho phép nhân viên chấm công vào/ra bằng GPS + nhận diện khuôn mặt, và cho HR / Quản lý theo dõi, thống kê, quản lý nhân viên & cấu hình vị trí chấm công — phân quyền theo vai trò và phạm vi đơn vị.
1.2 Phạm vi¶
| Trong phạm vi | Ngoài phạm vi |
|---|---|
| Danh sách; chi tiết (chấm công / thông tin) | Đăng nhập / Quên mật khẩu / đổi mật khẩu |
| Tự chấm công (GPS + khuôn mặt) | Trang chủ — dashboard tổng quan hôm nay |
| Thống kê chấm công | Bảng lương / tính công ra tiền (số tiền phạt, quy đổi OT…) |
| Giải trình công / Đăng ký (nghỉ, đi muộn/về sớm, quên chấm công, tăng ca — tự tạo, xem lịch sử) | Màn duyệt đơn của Quản lý trực tiếp — thuộc web, module Hành chính – Nhân sự (đã chốt §8, không thuộc app) |
Giải trình công mới thêm ở bản 0.5 — đã chốt ở bản 0.6
Mục này trước đó (0.4) nằm ở Ngoài phạm vi. Bản 0.5 bổ sung theo mockup
giai-trinh-cong.html / giai-trinh-cong-form.html / giai-trinh-thanh-cong.html
(pace-1) — xem §4.5 và FR-08. Logic nghiệp vụ đồng bộ với bản web
(docs/longdo-erp/tai-lieu-nghiep-vu/trang-ca-nhan.md §1.4, BR-CN-09 → BR-CN-13).
Bản 0.6 chốt toàn bộ 13 vấn đề mở nêu ở §8 (v0.5) — xem quyết định chi tiết ở §8.
Vì sao Đăng nhập & Trang chủ nằm ngoài phạm vi SRS này
Hai màn này được tách khỏi đặc tả lần này (theo quyết định BA 17/06/2026). App vẫn có đăng nhập & màn chủ, nhưng phần đặc tả chi tiết sẽ làm ở tài liệu khác — SRS này tập trung vào quản lý nhân viên, chấm công, thống kê & cấu hình vị trí.
1.3 Thuật ngữ¶
| Thuật ngữ | Ý nghĩa |
|---|---|
| Phòng ban Công trường | Nhân viên theo dự án (Linh Đàm, Đông Anh, Yên Bái). Khung giờ 06:00–18:00 (linh hoạt). |
| Phòng ban Văn phòng | Nhân viên theo phòng ban (IT, Kế toán–HCNS, Kỹ thuật). Khung giờ 08:00–17:30. |
| Phạm vi quản lý | Tập phòng ban mà một Quản lý phụ trách (Phòng ban Công trường hoặc Phòng ban Văn phòng). |
| Geofence | Vùng tròn (toạ độ tâm + bán kính m) mà nhân viên phải đứng trong đó mới chấm công được. |
| Liveness | Kiểm tra khuôn mặt thật (người sống), chống ảnh/video giả. |
| Giải trình công | Gửi đơn cho một ngày lệch định mức (đi muộn/về sớm/quên chấm công) hoặc đăng ký nghỉ/tăng ca, để Quản lý trực tiếp duyệt — quyết định có tính công/phạt phần lệch hay không. Đồng nghĩa "Đăng ký" khi là nghỉ/OT. |
| Loại giải trình | 5 loại đã chốt (§8): Nghỉ phép năm, Nghỉ không lương, Đi muộn/Về sớm, Quên chấm công, Tăng ca — xem §4.5. |
2. Vai trò & nguyên tắc phân quyền¶
Hệ thống có 3 vai trò (theo bảng phân quyền):
| Vai trò | Phạm vi & quyền tổng quát |
|---|---|
| HR | Toàn công ty: xem & quản lý chấm công mọi phòng ban; xem mọi thống kê, xem danh sách nhân viên, thông tin nhân viên và chấm công của toàn bộ nhân viên thuộc tất cả phòng ban trong danh sách, chấm công cho bản thân. |
| Quản lý | Giới hạn trong phạm vi quản lý (phòng ban của mình): xem danh sách, chấm công, thông tin, thống kê của nhân viên thuộc đơn vị mình; Bản thân vẫn tự chấm công. |
| Nhân viên | Chỉ tự chấm công ở màn hình chấm công và xem chấm công của bản thân ở chi tiết nhân sự tab chấm công. Không thấy danh sách nhân viên, thống kê. |
Nguyên tắc lọc theo phạm vi (Dev bắt buộc áp dụng)
Mọi màn quản lý (Danh sách, Chi tiết, Thống kê) phải lọc dữ liệu server-side theo phạm vi của người đăng nhập: HR = tất cả; Quản lý = chỉ đơn vị mình phụ trách; Nhân viên = chỉ bản ghi của chính mình. Không dựa vào ẩn/hiện ở client.
3. Ma trận phân quyền theo màn¶
Đây là đặc tả bắt buộc — nguồn: bảng phân quyền BA cung cấp.
| Màn hình | HR | Quản lý | Nhân viên |
|---|---|---|---|
| Danh sách nhân viên | ✓ — full | ✓ — chỉ nhân viên thuộc phạm vi quản lý | ✗ |
| Tab chấm công nhân viên | ✓ — full | ✓ — chấm công của nhân viên thuộc phòng ban mình | ✓ — chỉ của bản thân |
| Tab thông tin nhân viên | ✓ — full | ✓ — thông tin nhân viên thuộc phạm vi mình | ✗ |
| Chấm công (tự chấm) | ✓ | ✓ | ✓ |
| Giải trình công / Đăng ký (tự tạo) | ✓ — cho bản thân | ✓ — cho bản thân | ✓ — cho bản thân |
| Thống kê | ✓ — full | ✓ — thống kê của nhân viên thuộc phạm vi mình | ✗ |
Điều hướng theo vai trò
- HR / Quản lý → dùng các tab quản lý: Danh sách · Chấm công · Thống kê · Cá nhân.
- Nhân viên → vào thẳng màn Chấm công (tự chấm) / xem chấm công bản thân; ẩn các tab quản lý.
- Giải trình công / Đăng ký là tab thứ 2 trong module Chấm công cá nhân (cùng cấp với tab "Chấm công" tự chấm, FR-05) — cả 3 vai trò đều có, vì ai cũng tự chấm công và có thể lệch định mức cho bản thân mình.
4. Mô hình nghiệp vụ chấm công¶
4.1 Hai phòng ban nhân viên¶
| Tiêu chí | Phòng ban Công trường | Phòng ban Văn phòng |
|---|---|---|
| Đơn vị mẫu | Linh Đàm, Đông Anh, Yên Bái | IT, Kế toán–HCNS, Kỹ thuật |
| Khung giờ | 06:00 – 18:00 (linh hoạt) | 08:00 – 17:30 (hành chính) |
| Số trạng thái | 4 | 5 |
4.2 Tập trạng thái¶
Đã chốt bản 0.7 (§8.3) — thay toàn bộ tập trạng thái v0.6
Danh sách trạng thái dưới đây thay thế mô hình 3/5 trạng thái cũ. Số trạng thái là 4/5 (§4.1) — Dev bám đúng bảng dưới, không dùng lại tên trạng thái cũ ("Đã chấm công", "Đúng giờ", "Làm thêm giờ"…).
Phòng ban Công trường — 4 trạng thái (khung giờ linh hoạt 06:00–18:00, không cố định ca):
| Trạng thái | Điều kiện |
|---|---|
| Đủ công | Giờ nghỉ trưa tự thiết lập ở Hành chính – Nhân sự; tổng giờ làm > 9,5 giờ được tính là 1 công |
| Tăng ca | Có chấm công, làm thêm ngoài khung giờ chuẩn/ngày nghỉ |
| Quên chấm công | Chỉ có 1 trong 2 mốc chấm công (chỉ check-in hoặc chỉ check-out), thiếu mốc còn lại |
| Vắng | Hết ngày vẫn không có bản ghi chấm công nào (ngày làm việc theo lịch) |
Phòng ban Văn phòng — 5 trạng thái (mốc chuẩn 08:00 vào / 17:30 ra):
| Trạng thái | Điều kiện |
|---|---|
| Đủ công | Set giờ làm 8 giờ/ngày, trừ nghỉ trưa 1,5 giờ (vào trước 08:10 và ra ≥ 17:30) |
| Đi muộn / Về sớm | Vào ≥ 08:10 ("Đi muộn") và/hoặc ra < 17:30 ("Về sớm") |
| Quên chấm công | Có đi làm nhưng thiếu 1 trong 2 mốc giờ vào/ra (không có giờ ra → luôn là trạng thái này, kể cả khi làm tăng ca qua đêm mà quên checkout) |
| Tăng ca | Phải có đủ giờ vào + giờ ra (không thiếu mốc nào): vào sớm (trước 08:10) và ra muộn (quá 17:30) |
| Vắng / Ngày nghỉ | Không có giờ vào/ra: "Vắng" nếu là ngày làm việc theo lịch; "Ngày nghỉ" nếu là ngày nghỉ theo lịch (Chủ nhật…) |
Đã chốt — quy ước hiển thị Đi muộn / Về sớm theo màn
- Màn Chấm công (tự chấm, FR-05a), Tab Chấm công — danh sách (FR-03), Thống kê (FR-07): gộp hiển thị 1 nhãn "Đi muộn / Về sớm" (không tách riêng ở các màn tổng quan/danh sách/thống kê này).
- Khi xem chi tiết (panel chi tiết ngày, bottom sheet giải trình…): hiển thị tách riêng đúng thực tế — chỉ "Đi muộn" nếu chỉ vào muộn, chỉ "Về sớm" nếu chỉ ra sớm; nếu cả hai cùng xảy ra trong 1 ngày → hiển thị cả hai nhãn (không giới hạn chỉ 1 như trước).
- Dữ liệu nền vẫn lưu độc lập 2 cờ (đi muộn / về sớm) cho từng ngày — việc gộp/tách chỉ là quy ước hiển thị, không đổi cách lưu trữ hay tính công/phạt.
Ưu tiên khi trùng điều kiện Đủ công / Tăng ca
Điều kiện "Đủ công" (ra ≥ 17:30) và "Tăng ca" (ra quá 17:30, kèm vào trước 08:10) có thể trùng nhau — chỉ khi cả hai đều có giờ ra hợp lệ. Khi trùng, ưu tiên gắn nhãn "Tăng ca" (phản ánh đúng việc có làm thêm giờ). Không áp dụng cho trường hợp thiếu giờ ra (vd tăng ca qua đêm quên checkout) — trường hợp đó luôn là "Quên chấm công", ưu tiên cao hơn cả "Tăng ca" lẫn "Đủ công" vì thiếu dữ liệu để tính giờ. Nếu đơn giải trình "Quên chấm công" được duyệt (bổ sung giờ vào/ra qua giải trình công, §4.5) → ngày đó được cộng công thường (Đủ công), không tính là Tăng ca dù giờ ra bổ sung có thể muộn hơn 17:30.
Quy tắc ngày
Văn phòng: Chủ nhật nghỉ; Thứ Bảy vẫn tính. Công trường: Chủ nhật vẫn đi làm (không nghỉ) — có dữ liệu chấm công như ngày thường. Ngày tương lai / tháng chưa tới: không có dữ liệu. Mỗi nhân viên trong một ngày chỉ thuộc đúng 1 trạng thái.
Đã chốt (§8.3, §8.13) — mốc 08:10 thống nhất (thay quyết định trước ở bản 0.6)
Văn phòng — 1 mốc duy nhất 08:10 cho cả trạng thái lẫn phạt tiền (bản 0.6 trước đó tách 2 ngưỡng riêng — nay gộp lại làm một, Dev theo bản này): - Vào trước 08:10 (tức đến 08:09) → không tính là đi muộn, không phạt. - Vào từ 08:10 trở đi → tính là "Đi muộn" (muộn tính từ 08:10, vd vào đúng 08:10 = "muộn 10 phút") và bắt đầu áp phạt tiền theo bậc (BR-CN-10 web) từ mốc này. - Số tiền phạt cụ thể (bậc thang) chưa chốt trong SRS này — sẽ cấu hình ở mục Thiết lập (làm ở đợt sau), SRS này chỉ chốt mốc thời điểm bắt đầu tính muộn/phạt. - Công trường — vẫn không có khái niệm "Đi muộn"/phạt tiền (khung giờ linh hoạt 06:00–18:00, chỉ cần chấm công trong khung này). - Quy đổi giờ làm ra công: - Văn phòng: (giờ ra − giờ vào) trừ 1,5 giờ nghỉ trưa cố định = đủ 8 giờ → 1 công. - Công trường: giờ nghỉ trưa tự thiết lập ở Hành chính – Nhân sự (không cố định/hard-code); quy ước giờ ra − giờ vào > 9,5 giờ → tính đủ 1 công. - Giải trình công bị Từ chối → ngày đó KHÔNG tính đủ công, giữ nguyên trạng thái lệch định mức ban đầu (xem thêm §4.5).
4.3 Quy tắc chấm công bằng vị trí (geofence)¶
- Mỗi vị trí chấm công gắn với 1 đơn vị, gồm: toạ độ tâm + bán kính cho phép (m).
- Khi chấm công, app kiểm tra 3 lớp: (a) khoảng cách tới tâm ≤ bán kính; (b) độ chính xác GPS (±m); (c) chống vị trí giả mạo (mock location).
- Ngoài phạm vi → chặn chấm công hoàn toàn (nút khoá); chỉ cho "Thử lại".
4.4 Quy tắc nhận diện khuôn mặt¶
- Sau khi vị trí hợp lệ → nhận diện khuôn mặt + liveness (hướng dẫn quay mặt để xác thực người sống).
- Khi xác nhận, ghi đồng thời ảnh khuôn mặt + toạ độ GPS + giờ chấm; lưu độ khớp dưới dạng khoảng cách/độ tương đồng vector đặc trưng khuôn mặt (không phải % tuỳ ý) — xem §8.2.
4.5 Giải trình công / Đăng ký¶
Nghiệp vụ chung cho cả app lẫn web (bản web: tai-lieu-nghiep-vu/trang-ca-nhan.md §1.4,
BR-CN-09 → BR-CN-13) — mỗi người tự giải trình cho ngày lệch định mức của chính mình
hoặc tự đăng ký nghỉ/tăng ca; không phân biệt vai trò (HR/Quản lý cũng tự làm cho bản thân).
| Loại | Trường nhập | Ghi chú |
|---|---|---|
| Nghỉ phép năm | Ngày bắt đầu + buổi → ngày kết thúc + buổi; hiện khối "Phép năm còn lại" (vd 8 ngày) | Khớp BR-CN-12 (web) — quota 12 ngày/năm, HR set theo người. Chỉ tính là nghỉ phép hợp lệ nếu được Quản lý trực tiếp duyệt và HR ghi nhận (luồng 2 bước) |
| Nghỉ không lương | Ngày bắt đầu + buổi → ngày kết thúc + buổi | Khớp web — không phạt, không hưởng lương ngày nghỉ |
| Đi muộn / Về sớm | Chọn Đi muộn/Về sớm + Lý do cá nhân/công việc + Ngày + Giờ vào hoặc ra thực tế | Khớp FR-CN-05 (web) & ma trận BR-CN-11 (cá nhân/công việc × duyệt/từ chối). Mốc tính muộn/phạt: 08:10 (đã chốt §4.2, §8.13 — thống nhất 1 mốc cho cả trạng thái lẫn phạt, thay ân hạn 2 ngưỡng ở bản 0.6) |
| Quên chấm công | Ngày + Giờ vào / Giờ ra thực tế | Khớp web — Quản lý trực tiếp duyệt ghi nhận đủ công |
| Tăng ca | Ngày giờ bắt đầu → ngày giờ kết thúc; tự tính thời lượng (hh:mm). Văn phòng: quy đổi thêm ra ngày công theo 8h/ngày. Công trường: tính giờ tăng ca theo đúng giờ vào/giờ ra đã đăng ký, không quy đổi theo 8h/ngày như văn phòng | Khớp web — HR quy đổi thành tiền cuối tháng, không cộng vào số công ngày |
Đã chốt — hệ quả khi đơn bị Từ chối
Với một ngày lệch định mức, nếu đơn giải trình không được duyệt (Từ chối) → ngày đó không được tính đủ công, giữ nguyên phần công bị thiếu/lệch như chưa giải trình.
Dev lưu ý — mockup chưa khớp quyết định
Mockup giai-trinh-cong-form.html hiện vẫn còn 7 lựa chọn (thừa "Nghỉ phép đặc biệt",
"Nghỉ thai sản") và mockup giai-trinh-cong.html vẫn có 2 item mẫu thuộc 2 loại này trong
danh sách "Giải trình tháng 6". Bỏ qua 2 lựa chọn/2 item mẫu này khi code — SRS là nguồn
quyết định cuối (5 loại), mockup sẽ được BA cập nhật lại sau.
Người duyệt = Quản lý trực tiếp (cố định, không cho chọn) → luồng 2 bước: gửi → Quản lý trực tiếp duyệt → HR ghi nhận (giống BR-CN-09 web). Không giới hạn số lần gửi.
Trạng thái hiển thị trên app — 2 lớp, giống mô hình web (BR-CN-07) nhưng chấm góc lịch chỉ có 2 màu (đơn giản hơn web):
| Lớp hiển thị | Giá trị | Ý nghĩa |
|---|---|---|
| Nền ô lịch | Xanh (success/10) | Ngày đủ định mức + Tăng ca |
| Vàng (warning/10) | Ngày thiếu định mức (Đi muộn / Về sớm, Quên chấm công) | |
| Xám (surfaceVariant) | Ngày không có công (Vắng / Ngày nghỉ) | |
| Chấm góc ô | Đỏ (error) + icon ! | Chưa giải trình — ngày lệch định mức chưa gửi đơn |
| Tím (primary) + icon ✓ | Đã giải trình — gộp chung cả 3 trạng thái Chờ duyệt / Đã duyệt / Từ chối của web (chỉ phân biệt lại khi mở bottom sheet chi tiết hoặc xem danh sách "Giải trình tháng N" — nơi có badge riêng Chờ duyệt/Đã duyệt/Từ chối) |
Đã chốt (§8.12) — giữ nguyên 2 màu trên app
App giữ đúng như mockup hiện tại: 2 màu chấm góc (Chưa giải trình / Đã giải trình), không cần đồng bộ đủ 4 màu như web. Chi tiết 3 trạng thái duyệt (Chờ duyệt/Đã duyệt/Từ chối) chỉ cần hiện ở bottom sheet + danh sách bên dưới lịch (như mockup đang có), không bắt buộc thể hiện lại trên chấm góc lịch.
5. Đặc tả màn hình (Yêu cầu chức năng)¶
Mỗi màn gồm: mục đích · quyền truy cập · thành phần/trường · tương tác · file mockup.
FR-01. Danh sách nhân viên¶
File:
nhan-su.html· Quyền: HR (full) · Quản lý (phạm vi mình) — Nhân viên không
Mục đích: xem/quản lý nhân viên, lọc theo phòng ban, vào chi tiết, thêm nhân viên.
Màn hiển thị + điều hướng (read-only) — bảng dưới liệt kê thành phần hiển thị, không có trường nhập (trừ ô tìm kiếm/lọc).
| Thành phần | Ghi chú |
|---|---|
| Ô tìm kiếm theo tên | placeholder "Tìm theo tên nhân viên…" |
| Lọc theo phòng ban | dropdown 2 nhóm: Phòng ban Công trường (Linh Đàm/Đông Anh/Yên Bái) · Phòng ban Văn phòng (IT/Kế toán–HCNS/Kỹ thuật) + "Tất cả" |
| Item nhân viên | avatar · tên · chức vụ · phòng ban · mũi tên |
| FAB "Thêm nhân viên" | → FR-02 |
Quyền theo vai trò:
- HR: thấy toàn bộ nhân viên, lọc mọi phòng ban.
- Quản lý: chỉ nhân viên thuộc phạm vi quản lý; dropdown phòng ban giới hạn trong phạm vi đó.
Tương tác: bấm 1 nhân viên → FR-03 (chi tiết, mở tab Chấm công).
Dev lưu ý
Mockup: mọi item trỏ về cùng 1 file chi tiết (chưa truyền id). Dev tham số hoá theo mã
nhân viên. Ô tìm kiếm theo tên hiện chưa gắn logic — cần hiện thực.
FR-02. Thêm mới nhân viên¶
File:
them-nguoi-dung.html· Quyền: HR · Quản lý (khác nhau ở phần Vai trò) — Nhân viên không
Đã bỏ khỏi Ma trận phân quyền §3 (theo yêu cầu BA)
Chi tiết màn vẫn giữ ở đây; quyền theo vai trò xem ngay dưới.
Mục đích: tạo hồ sơ nhân viên mới.
| Trường | Kiểu | Bắt buộc | Ràng buộc / lựa chọn |
|---|---|---|---|
| Ảnh đại diện | ảnh | — | chọn từ thư viện / chụp |
| Họ và tên | text | ✓ | |
| ✓ | |||
| Số điện thoại | tel | — | |
| Loại nhân viên | radio | ✓ | Phòng ban / Công trường |
| Phòng ban | chọn 1 | ✓ (nếu Loại = Phòng ban) | Kế toán–HCNS · IT · Kỹ thuật |
| Công trường | chọn 1 | ✓ (nếu Loại = Công trường) | Linh Đàm · Đông Anh · Yên Bái |
| Chức vụ | chọn 1 | — | Phòng ban → {Trưởng phòng, Nhân viên}; Công trường → {Chỉ huy trưởng, Nhân viên} |
| Vai trò | radio | — | Nhân viên / Quản lý — chỉ HR thấy |
Quyền theo vai trò:
- HR: thêm nhân viên cho mọi phòng ban/công trường; hiện mục Vai trò để gán (Quản lý / Nhân viên).
- Quản lý: chỉ thêm nhân viên vào phòng ban/công trường mình; ẩn mục Vai trò (mặc định Nhân viên); danh sách đơn vị khoá theo phạm vi.
Logic phụ thuộc: đổi "Loại nhân viên" → hiện đúng trường Phòng ban/Công trường + reset Chức vụ (danh sách chức vụ khác nhau theo loại). Chọn qua bottom sheet trượt từ đáy.
Tương tác: "Lưu" / "Lưu người dùng" → quay về Danh sách (FR-01). Cần validate các trường bắt buộc.
FR-03. Chi tiết nhân viên — Tab Chấm công¶
File:
nhan-su-checkin-a.html· Quyền: HR (full) · Quản lý (NV phòng mình) · Nhân viên (bản thân)
Mục đích: lịch sử chấm công theo tháng của 1 nhân viên, dạng lịch lưới.
Màn hiển thị (read-only) — bảng dưới liệt kê thành phần hiển thị, không có trường nhập.
| Thành phần | Ghi chú |
|---|---|
| Thẻ đầu | avatar · tên · "chức vụ · phòng ban" |
| Tab | Chấm công (active) / Thông tin (→ FR-04) |
| Bộ chọn tháng | ‹ › + "Tháng MM/YYYY"; chỉ trong khoảng có dữ liệu |
| Ô thống kê trạng thái | Đếm theo tháng, nhãn theo khối — xem tập trạng thái mới ở §4.2 (Văn phòng 5 ô: Đủ công/Đi muộn-Về sớm (gộp)/Quên chấm công/Tăng ca/Vắng-Ngày nghỉ; Công trường 4 ô: Đủ công/Tăng ca/Quên chấm công/Vắng) |
| Lịch lưới tháng | header T2–CN (T7/CN mờ); mỗi ngày chấm màu trạng thái |
| Thẻ chi tiết ngày | thứ+ngày · badge · giờ vào/ra · tổng giờ |
Mô hình 1 bản ghi ngày: { trạng thái, giờ vào, giờ ra, tổng giờ }; chưa chấm → "—".
Quyền theo vai trò:
- HR: xem chấm công mọi nhân viên.
- Quản lý: chỉ nhân viên thuộc phòng ban/công trường mình.
- Nhân viên: chỉ chấm công của chính mình (vào thẳng màn này cho bản thân, không qua Danh sách).
Tương tác: ‹ › đổi tháng; chạm ô ngày → cập nhật thẻ chi tiết (cuối tuần / chưa tới / không dữ liệu hiển thị thông điệp tương ứng); ngày tương lai không chọn được.
FR-04. Chi tiết nhân viên — Tab Thông tin¶
File:
nhan-su-thong-tin-b.html· Quyền: HR (full) · Quản lý (phạm vi mình) — Nhân viên không
Mục đích: hồ sơ liên hệ & công việc của nhân viên.
Màn hiển thị (read-only) — bảng dưới liệt kê thông tin hiển thị, không có trường nhập (chỉnh sửa hồ sơ là luồng riêng — §8.6).
| Trường | Nhóm | Mẫu |
|---|---|---|
| Họ tên | hồ sơ | Nguyễn Văn An |
| Liên hệ | nguyen.van.an@longdo.vn | |
| Số điện thoại | Liên hệ | 0912 345 678 |
| Phòng ban | Công việc | Phòng Kỹ thuật |
| Chức vụ | Công việc | Trưởng nhóm |
| Vai trò | Công việc | Quản lý nhóm (chip "Quản lý") |
Quyền: HR xem mọi nhân viên; Quản lý chỉ nhân viên thuộc phạm vi mình; Nhân viên không xem được (đã chốt lại §8.6 — Nhân viên chỉ xem chấm công bản thân ở FR-03, không có quyền vào Tab Thông tin của chính mình).
FR-05. Chấm công (tự chấm)¶
File:
cham-cong.html→kiem-tra-vi-tri-a/b/c.html→ (...ngoai-pham-vi.html) →cham-cong-khuon-mat.html→cham-cong-thanh-cong.htmlQuyền: HR · Quản lý · Nhân viên (tất cả tự chấm công cho bản thân)
Luồng:
Màn chấm công → Kiểm tra vị trí → Nhận diện khuôn mặt → Chấm công thành công
│
└─(ngoài phạm vi)→ Màn "Ngoài phạm vi" (chặn)
FR-05a. Màn chấm công cá nhân (cham-cong.html)
| Thành phần | Nguồn | Mẫu |
|---|---|---|
| Trạng thái ca hôm nay | hệ thống | Chưa vào ca / Đang trong ca / Đã ra ca |
| Giờ vào / ra · Đã làm | hệ thống | "—" khi chưa chấm |
| Vị trí hiện tại | GPS | "VP Longdo · trong phạm vi" |
| Lịch sử tuần (T2–T7) | hệ thống | ngày · vào→ra · chip trạng thái |
| Nút "Chấm công vào" | — | → Kiểm tra vị trí |
FR-05b. Kiểm tra vị trí (kiem-tra-vi-tri-a.html — đã chốt Phương án A (§8.8): bản đồ
toàn màn. kiem-tra-vi-tri-b.html / kiem-tra-vi-tri-c.html là 2 phương án không chọn,
Dev bỏ qua, không triển khai)
| Trường | Nguồn | Mẫu |
|---|---|---|
| Tên + địa chỉ địa điểm | hệ thống | VP Longdo · 123 Phố Láng Hạ… |
| Khoảng cách tới tâm | GPS | cách 8 m |
| Độ chính xác GPS | GPS | ±5 m · Cao |
| Chống vị trí giả mạo | hệ thống | Đã kiểm tra / An toàn |
| Toạ độ hiện tại | GPS | 21.0285°N, 105.8542°E |
Hợp lệ → "Tiếp tục nhận diện khuôn mặt" (FR-05d).
FR-05c. Ngoài phạm vi (kiem-tra-vi-tri-ngoai-pham-vi.html)
- Hiển thị khoảng cách thực (mẫu 1,2 km) vs bán kính cho phép (mẫu 50 m — chỉ là ví dụ minh hoạ, không phải giá trị mặc định, xem FR-06).
- Nút chấm công vô hiệu hoá ("Chưa thể chấm công"); chỉ 1 nút: Thử lại — đã chốt bỏ nút/luồng "Xin chấm công từ xa" (§8.4). Mockup hiện còn nút này, Dev bỏ qua khi code.
FR-05d. Nhận diện khuôn mặt (cham-cong-khuon-mat.html)
- Thẻ ca: ngày · giờ hiện tại · "Ca hành chính · 08:00".
- Khung camera + định vị mặt + hướng dẫn liveness động ("Quay mặt sang PHẢI…") + chip "Phát hiện khuôn mặt thật".
- "Xác nhận chấm công vào" → ghi ảnh + vị trí + giờ → FR-05e.
FR-05e. Chấm công thành công (cham-cong-thanh-cong.html)
- Biên nhận: giờ + ngày · họ tên · mã NV · phòng ban · độ khớp khuôn mặt (mẫu 99%) · vị trí + toạ độ · nhắc giờ ra dự kiến (17:30).
- "Xong" → về FR-05a.
Chấm công RA
Mockup thể hiện đầy đủ chiều VÀO; chiều RA dùng lại cùng luồng (vị trí + khuôn mặt). Dev hiện thực đối xứng.
FR-06. Thêm vị trí chấm công¶
File:
them-vi-tri-cham-cong.html(app-longdo-erp) · Quyền: chỉ HR
Đã bỏ khỏi Ma trận phân quyền §3 (theo yêu cầu BA)
Chi tiết màn vẫn giữ ở đây; quyền theo vai trò xem ngay dưới.
Mục đích: HR cấu hình geofence cho 1 đơn vị.
| Trường | Kiểu | Bắt buộc | Ràng buộc / mẫu |
|---|---|---|---|
| Đơn vị áp dụng | chọn 1 | ✓ | 1 trong 6 đơn vị (3 công trường + 3 phòng ban) |
| Địa chỉ | text | — | "Số nhà, đường, phường/xã…" |
| Vĩ độ | số thực | nên có | 21.1402 |
| Kinh độ | số thực | nên có | 105.8542 |
| Bán kính cho phép (m) | số nguyên | nên có | > 0; mẫu 100 (chỉ minh hoạ) |
- Ghim toạ độ trên bản đồ ("Chọn trên bản đồ"); nút "Lưu vị trí chấm công".
Đã chốt (§8.1) — không có bán kính mặc định
Không có giá trị bán kính mặc định chung cho toàn hệ thống. Mỗi vị trí chấm công (mỗi đơn vị) tự set bán kính riêng khi HR tạo/sửa — giá trị "100" ở mockup chỉ là ví dụ minh hoạ, không dùng làm default trong code (không được tự điền sẵn 100 nếu HR bỏ trống).
Dev lưu ý
Mockup chưa validate. Cần bắt buộc Đơn vị áp dụng, validate toạ độ & bán kính > 0 (không có default fallback); lưu theo mã đơn vị (không lưu chuỗi hiển thị).
FR-07. Thống kê¶
File:
thong-ke-cham-cong-hr.html(hub HR) +thong-ke-phong-ban-chi-tiet.html·thong-ke-du-an-chi-tiet.html·thong-ke-theo-ngay.html·thong-ke-theo-trang-thai.htmlQuyền: HR (full) · Quản lý (phạm vi mình) — Nhân viên không
Mục đích: theo dõi & tổng hợp chấm công theo khối → đơn vị → ngày / trạng thái.
FR-07a. Hub thống kê (thong-ke-cham-cong-hr.html)
- Segmented Công trường / Văn phòng → panel thẻ đơn vị (kèm số người).
- Thẻ dự án → FR-07c (chi tiết dự án); thẻ phòng ban → FR-07b (chi tiết phòng ban).
- HR: thấy mọi đơn vị + FAB "Thêm vị trí" (→ FR-06). Quản lý: chỉ thấy đơn vị mình; không có FAB Thêm vị trí.
FR-07b. Chi tiết phòng ban (Văn phòng) (thong-ke-phong-ban-chi-tiet.html)
- Lọc khoảng ngày (from–to; tự hoán đổi nếu from > to; giới hạn dữ liệu; chỉ ngày ≤ hôm nay).
- View Lịch: heatmap theo ngày (màu theo trạng thái trội nhất); chạm ngày → panel chi tiết (5 thẻ đếm + bảng nhân viên × giờ). Khối "Tổng hợp" 5 thẻ đếm lượt.
- View Danh sách: bảng ma trận tháng (nhân viên × ngày, glyph ✓/M/+/✗ — M gộp chung cho cả Đi muộn và Về sớm, đã chốt §4.2) + cột Công/Muộn-Sớm/Thêm/Vắng/Giờ + hàng Tổng; nút Excel (mô phỏng).
| Chỉ số/tháng | Định nghĩa |
|---|---|
| Công | số ngày trạng thái Đủ công |
| Muộn-Sớm | đếm ngày trạng thái Đi muộn / Về sớm (gộp — đã chốt §4.2), không tách 2 cột riêng |
| Thêm | đếm ngày trạng thái Tăng ca |
| Vắng | số ngày trạng thái Vắng (không tính Ngày nghỉ theo lịch) |
| Giờ | Σ max(0, ra − vào) |
Dev lưu ý — mockup chưa khớp
Mockup thong-ke-phong-ban-chi-tiet.html hiện tách riêng 2 glyph M/S với 2 màu khác
nhau (late/early) và nhãn Tăng ca đang ghi "Làm thêm giờ" — cần gộp lại thành 1 glyph
M (Đi muộn/Về sớm) và đổi nhãn thành "Tăng ca" cho khớp §4.2.
FR-07c. Chi tiết dự án (Công trường) (thong-ke-du-an-chi-tiet.html)
- Như FR-07b nhưng 4 trạng thái (Đủ công / Tăng ca / Quên chấm công / Vắng — xem §4.2), đơn vị "công nhân".
FR-07d. Thống kê theo ngày (thong-ke-theo-ngay.html) — toàn bộ nhân viên trong 1 ngày: dải ô trạng thái (4 hoặc 5 ô tuỳ khối, xem §4.2) + bảng giờ theo cột trạng thái.
FR-07e. Thống kê theo trạng thái (thong-ke-theo-trang-thai.html) — liệt kê lượt của 1 trạng thái trong khoảng ngày (nhận ?status=&from=&to=), gom theo ngày; đi muộn hiển thị "muộn N′" (N = giờ vào − 08:10, chỉ tính khi giờ vào ≥ 08:10 — xem §4.2).
Dev lưu ý điều hướng
Mockup: thẻ đơn vị/ô ngày đều trỏ file cố định (hard-code Đông Anh / Phòng Kỹ thuật / ngày 11/06), chưa truyền tham số. Dev tham số hoá theo mã đơn vị & ngày. Mọi truy vấn thống kê phải áp bộ lọc phạm vi theo vai trò.
FR-08. Giải trình công / Đăng ký¶
File:
giai-trinh-cong.html→giai-trinh-cong-form.html→giai-trinh-thanh-cong.htmlQuyền: HR · Quản lý · Nhân viên (tất cả tự giải trình/đăng ký cho bản thân)
Mục đích: xem lịch + lịch sử giải trình công của bản thân trong tháng, và tạo giải trình/đăng ký mới (nghỉ, đi muộn/về sớm, quên chấm công, tăng ca) — xem mô hình nghiệp vụ ở §4.5.
Luồng:
Tab "Giải trình / Đăng ký" (trong module Chấm công cá nhân, cạnh tab "Chấm công" — FR-05)
→ Bấm ô ngày / mục giải trình → Bottom sheet chi tiết → (nếu chưa giải trình) "Giải trình / Đăng ký"
→ Form tạo giải trình → Gửi giải trình → Màn thành công
FR-08a. Màn Giải trình công (lịch + danh sách) (giai-trinh-cong.html)
| Thành phần | Ghi chú |
|---|---|
| Module tab nav | 2 tab: Chấm công (→ FR-05) / Giải trình / Đăng ký (active) |
| Lịch lưới tháng | như FR-03 nhưng thêm chấm góc ô cho ngày có giải trình (đỏ = chưa giải trình, tím = đã giải trình) |
| Chú giải ngày công | 2 khối: màu nền (Đủ định mức/Thiếu định mức/Không có công/Hôm nay) + chấm góc (Chưa giải trình/Đã giải trình) |
| Danh sách "Giải trình tháng N" | mỗi dòng: icon loại · tên loại (+ phụ chú lý do/kết hôn) · badge trạng thái (Đã duyệt/Chờ duyệt/Từ chối) · ngày/khoảng ngày |
| Bottom sheet chi tiết | mở khi bấm ô ngày hoặc dòng danh sách — icon + tiêu đề + trạng thái + các dòng key–value (ngày, giờ, lý do, người phê duyệt, file đính kèm, lý do từ chối nếu có) |
| Nút "Giải trình / Đăng ký" trong sheet | chỉ hiện khi ngày chưa giải trình → mở FR-08b |
Tương tác: đổi tháng (chỉ lùi được — nút tháng sau vô hiệu hoá trên mockup, có thể do đang ở tháng hiện tại); bấm ô ngày/dòng danh sách → mở bottom sheet; bấm nút trong sheet → FR-08b.
FR-08b. Form tạo giải trình / đăng ký (giai-trinh-cong-form.html)
| Trường | Hiện với loại | Ghi chú |
|---|---|---|
| Loại giải trình (select, 5 loại — đã chốt §8.10/§8.11) | tất cả | bắt buộc chọn trước, các trường còn lại mới hiện; bỏ 2 lựa chọn "Nghỉ phép đặc biệt", "Nghỉ thai sản" (mockup hiện còn thừa — Dev bỏ qua) |
| Ngày/giờ bắt đầu → kết thúc + buổi | 2 loại Nghỉ (Nghỉ phép năm, Nghỉ không lương) | có ô "Phép năm còn lại" riêng cho Nghỉ phép năm; ô tóm tắt "Nghỉ từ buổi X ngày A đến buổi Y ngày B" |
| Ngày giờ bắt đầu → kết thúc (tự tính thời lượng) | Tăng ca | Văn phòng: quy đổi ra "X giờ Y phút · Z ngày công" (8h/ngày); Công trường: chỉ tính theo giờ vào/ra đã đăng ký, không quy đổi 8h/ngày (xem §4.5) |
| Chọn Đi muộn/Về sớm + Lý do cá nhân/công việc + Ngày + Giờ thực tế | Đi muộn/Về sớm | gợi ý tự tính "muộn/sớm N phút" so với mốc 08:00/17:30, có ân hạn 08:00–08:10 trước khi tính muộn/phạt (đã chốt §8.13 — Dev sửa hàm updateHint trong mockup hiện đang tính thẳng từ 08:00, chưa có ân hạn) |
| Ngày + Giờ vào/ra thực tế | Quên chấm công | 2 ô giờ riêng, có thể để trống 1 ô (vd quên chấm ra) |
| Lý do (textarea) + File đính kèm | tất cả (sau khi chọn loại) | bắt buộc nhập lý do |
| Người phê duyệt | tất cả | cố định = Quản lý trực tiếp, không cho chọn |
Tương tác: đổi "Loại giải trình" → hiện đúng nhóm trường tương ứng + reset các khối liên quan; nút "Gửi giải trình" chỉ hiện sau khi đã chọn loại → FR-08c.
FR-08c. Gửi giải trình thành công (giai-trinh-thanh-cong.html)
- Icon thành công + thông báo "Đã gửi giải trình… sẽ nhận thông báo khi có kết quả".
- Tóm tắt: Loại · Từ · Đến · Người duyệt · Trạng thái (badge "Chờ duyệt").
- 2 nút: "Gửi thêm giải trình" (→ FR-08b) · "Về màn Chấm công" (→ FR-05a).
Đã chốt (§8.9) — màn duyệt đơn nằm ở web
Màn duyệt đơn giải trình cho Quản lý trực tiếp không thuộc app này — sẽ làm ở web,
trong module Hành chính – Nhân sự (phần Chấm công). App chỉ có phía người gửi (FR-08
ở đây); module Đề xuất (de-xuat.html, app-longdo-erp) không dùng cho luồng này.
Dev lưu ý
Badge trạng thái (Chờ duyệt/Đã duyệt/Từ chối) và số liệu phạt/trừ công không tính toán trên app, chỉ hiển thị kết quả — khớp BR-CN-13 (web): "số tiền hiển thị ở Tài chính cá nhân, không hiện trên màn Chấm công".
6. Đặc tả dữ liệu (gợi ý)¶
Hồ sơ nhân viên + phân quyền
| Cột | Kiểu | Mô tả |
|---|---|---|
| ma_nv | STRING PK | Mã NV (đăng nhập) |
| ho_ten | STRING | Họ tên |
| STRING | ||
| sdt | STRING | Điện thoại |
| loai | ENUM | Loại nhân viên (khối) |
| don_vi_id | FK | Đơn vị trực thuộc |
| chuc_vu | STRING | Chức vụ |
| vai_tro | ENUM | Vai trò phân quyền |
| mat_khau_hash | STRING | Mật khẩu (hash) |
Dự án (công trường) hoặc phòng ban (văn phòng)
| Cột | Kiểu | Mô tả |
|---|---|---|
| id | PK | Mã đơn vị |
| ten | STRING | Linh Đàm / Phòng IT… |
| loai | ENUM | Loại đơn vị |
| quan_ly_id | FK | Quản lý phụ trách (xác định phạm vi) |
Geofence của 1 đơn vị (FR-06)
| Cột | Kiểu | Mô tả |
|---|---|---|
| id | PK | Mã vị trí |
| don_vi_id | FK | Đơn vị áp dụng |
| dia_chi | STRING | Địa chỉ |
| vi_do | DECIMAL | Latitude |
| kinh_do | DECIMAL | Longitude |
| ban_kinh_m | INTEGER | Bán kính (m) |
1 dòng = 1 nhân viên × 1 ngày
| Cột | Kiểu | Mô tả |
|---|---|---|
| id | PK | Mã bản ghi |
| ma_nv | FK | Nhân viên |
| ngay | DATE | Ngày |
| gio_vao | TIME | Null nếu chưa vào |
| gio_ra | TIME | Null nếu chưa ra |
| trang_thai | ENUM | Trạng thái (theo khối) |
| do_khop_mat | INTEGER | % khớp khi chấm |
| vi_do | DECIMAL | GPS lúc chấm |
| kinh_do | DECIMAL | GPS lúc chấm |
| anh_mat | TEXT | Đường dẫn ảnh |
1 đơn giải trình/đăng ký của 1 nhân viên (FR-08)
| Cột | Kiểu | Mô tả |
|---|---|---|
| id | PK | Mã đơn |
| ma_nv | FK | Người gửi (tự giải trình cho bản thân) |
| loai | ENUM | Loại giải trình (5 loại đã chốt — §4.5, §8.10/§8.11) |
| loai_con | ENUM | Phân nhánh trong loại (chỉ Đi muộn/Về sớm) |
| ly_do_loai | ENUM | Lý do cá nhân/công việc (BR-CN-11 web) — ảnh hưởng có cộng lại công hay không |
| tu_thoi_diem | DATETIME | Ngày+giờ hoặc ngày+buổi bắt đầu (tuỳ loại) |
| den_thoi_diem | DATETIME | Ngày+giờ hoặc ngày+buổi kết thúc (tuỳ loại) |
| gio_vao_thuc_te | TIME | Null nếu không nhập (vd quên chấm ra) |
| gio_ra_thuc_te | TIME | Null nếu không nhập |
| ly_do | TEXT | Bắt buộc — nội dung giải trình |
| file_dinh_kem | TEXT | Tuỳ chọn |
| nguoi_duyet_id | FK | Cố định = Quản lý trực tiếp, không cho chọn (BR-CN-09 web) |
| trang_thai | ENUM | Chờ duyệt / Đã duyệt / Từ chối — 2 bước duyệt: Quản lý trực tiếp → HR ghi nhận |
| ly_do_tu_choi | TEXT | Chỉ có khi trạng thái = Từ chối |
7. Yêu cầu phi chức năng (tóm tắt)¶
- Bảo mật phân quyền: lọc dữ liệu theo vai trò + phạm vi ở server (xem §2).
- GPS/định vị: đo khoảng cách tới tâm geofence; cảnh báo độ chính xác kém; phát hiện mock location.
- Khuôn mặt: liveness + so khớp đạt ngưỡng; lưu ảnh chấm công.
- Xuất Excel: các màn thống kê cần xuất file thật (mockup mới mô phỏng).
- Hiệu năng: lịch/bảng thống kê tải nhanh theo khoảng ngày; phân trang khi danh sách lớn.
8. Vấn đề mở (đã chốt ở bản 0.6)¶
Toàn bộ 13 vấn đề mở của bản 0.5 đã được BA chốt (03/07/2026)
Không còn điểm chặn nào trước khi bàn giao Dev cho các mục dưới đây. Vài mục phát sinh việc cập nhật mockup (đánh dấu ⚠️ mockup chưa khớp) — Dev triển khai theo quyết định ở đây, không theo đúng y nguyên mockup hiện tại ở những chỗ đó.
- Bán kính geofence — không có giá trị mặc định. Mỗi vị trí chấm công tự set bán kính riêng khi HR tạo (giá trị "100"/"50" trên mockup chỉ là ví dụ minh hoạ) — xem §5 FR-06.
- Ngưỡng khớp khuôn mặt tối thiểu — dựa trên khoảng cách/độ tương đồng vector đặc trưng khuôn mặt (face embedding), không phải một mốc % tuỳ ý do BA quy định. ⚠️ Cần Dev/kỹ thuật xác nhận thông số cụ thể theo SDK/thư viện nhận diện khuôn mặt được chọn (đây là tham số kỹ thuật, không phải quy tắc nghiệp vụ) — xem §4.4.
- Grace period trạng thái —
bản 0.6: không có ân hạn, 08:02 = "Đi muộn"→ cập nhật bản 0.7: chốt 1 mốc duy nhất 08:10 cho cả trạng thái lẫn phạt tiền (gộp với mục 13, xem §4.2). Vào trước 08:10 = không đi muộn; từ 08:10 = "Đi muộn" + bắt đầu phạt. Công trường không có khái niệm "Đi muộn" (khung 06:00–18:00, linh hoạt). Công thức quy đổi công: văn phòng = (giờ ra − giờ vào) trừ 1,5h nghỉ trưa = 8h → 1 công; công trường = giờ ra − giờ vào > 9,5h → 1 công (giờ nghỉ trưa cấu hình ở mục Thiết lập). - "Xin chấm công từ xa" — bỏ hẳn, không làm. Ngoài phạm vi geofence → chặn cứng, chỉ có
nút "Thử lại". ⚠️ Mockup
kiem-tra-vi-tri-ngoai-pham-vi.htmlhiện còn nút này — Dev bỏ qua. - Đơn vị đếm thống kê — chốt là "lượt" theo "ngày" (đếm theo lượt phát sinh, gom theo từng ngày) — áp dụng thống nhất cho mọi màn thống kê (§5 FR-07).
- Nhân viên xem thông tin bản thân —
bản 0.7: có, xem được Tab Thông tin (FR-04)→ chốt lại: không. Nhân viên chỉ xem chấm công của bản thân ở FR-03 (Tab Chấm công), không có quyền vào Tab Thông tin (FR-04) kể cả của chính mình. Không cần màn hồ sơ cá nhân riêng (chinh-sua-ho-so.html,doi-mat-khau.htmlkhông thuộc phạm vi vai trò Nhân viên ở app này). - Vai trò HR được tạo ở đâu — tạo ở web, module Hành chính – Nhân sự, không phải qua form "Thêm nhân viên" của app này (form app giữ nguyên chỉ gán Nhân viên/Quản lý).
- Phương án màn Kiểm tra vị trí (FR-05b) — chốt Phương án A (
kiem-tra-vi-tri-a.html— bản đồ toàn màn, đúng như mockup). Phương án B/C không dùng. - Màn duyệt đơn giải trình (Quản lý trực tiếp) — nằm ở web, module Hành chính – Nhân sự (phần Chấm công) — không thuộc app này, không dùng module Đề xuất.
- "Nghỉ phép đặc biệt" có dùng chung quota với "Nghỉ phép năm" không? — Trả lời ban đầu:
không dùng chung (nghỉ đặc biệt không trừ vào 12 ngày phép năm) — nhưng xem mục 11: quyết
định cuối là bỏ hẳn loại này, nên câu hỏi quota không còn áp dụng. Lưu ý cho tài liệu
web:
trang-ca-nhan.md(BR-CN-12) đang quy định ngược lại (tính chung quota) — cần báo lại nhóm phụ trách tài liệu Trang cá nhân để đối chiếu, vì đây là 2 tài liệu khác nhau. - "Nghỉ thai sản" & "Nghỉ phép đặc biệt" — quyết định cuối: bỏ cả hai khỏi danh sách loại
giải trình. Còn lại đúng 5 loại (Nghỉ phép năm, Nghỉ không lương, Đi muộn/Về sớm, Quên
chấm công, Tăng ca) — khớp BR-CN-09 bản web. ⚠️ Mockup
giai-trinh-cong-form.html(dropdown) vàgiai-trinh-cong.html(2 item mẫu trong danh sách) hiện còn thừa — Dev bỏ qua, BA sẽ cập nhật lại mockup sau. Nếu phát sinh nhu cầu sau này, xử lý tạm bằng "Nghỉ không lương" hoặc bổ sung loại mới ở đợt sau — không tự gộp vào quota Nghỉ phép năm. - Số màu trạng thái giải trình trên lịch (app) — giữ nguyên như mockup hiện tại: 2 màu (Chưa giải trình / Đã giải trình). Không cần đồng bộ đủ 4 màu như web.
- Ngưỡng ân hạn đi muộn (grace period cho phạt tiền) —
bản 0.6: ân hạn 08:00–08:10, phạt từ 08:11→ cập nhật bản 0.7: gộp làm 1 mốc 08:10 với trạng thái "Đi muộn" (mục 3) — vào trước 08:10 không tính muộn/không phạt; từ 08:10 tính muộn (10 phút) và bắt đầu phạt theo bậc (BR-CN-10, số tiền cụ thể để sau — mục Thiết lập). ⚠️ Mockupgiai-trinh-cong-form.html(hàmupdateHint) hiện tính thẳng từ 08:00, chưa có mốc 08:10 — Dev sửa lại theo ngưỡng này.
Đã chốt từ trước (bản 0.4)
- Trạng thái: xem tập trạng thái mới nhất ở §4.2 (bản 0.7 đã thay tên/điều kiện trạng thái so với bản 0.4).
- Vai trò hệ thống: HR / Quản lý / Nhân viên (Chỉ huy trưởng & Trưởng phòng đều thuộc vai trò Quản lý, khóa phạm vi theo đơn vị mình).
- Đăng nhập & Trang chủ: tách khỏi phạm vi SRS này (xem §1.2).
9. Tiêu chí nghiệm thu (chính)¶
AC-1 — Phân quyền theo phạm vi (Quản lý)
Given người đăng nhập là Quản lý phòng Kỹ thuật When mở Danh sách nhân viên / Thống kê Then chỉ thấy nhân viên & dữ liệu chấm công thuộc phòng Kỹ thuật; không truy cập được dữ liệu đơn vị khác (kể cả gọi API trực tiếp).
AC-2 — Nhân viên bị giới hạn
Given người đăng nhập là Nhân viên When vào app Then vào thẳng màn Chấm công / xem chấm công bản thân; không thấy Danh sách, Thống kê, Thêm vị trí.
AC-3 — Thêm nhân viên theo vai trò
Given HR mở "Thêm nhân viên" / Quản lý mở "Thêm nhân viên" Then HR thấy mục Vai trò (gán Quản lý/Nhân viên) + chọn mọi đơn vị; Quản lý không thấy mục Vai trò và chỉ chọn được đơn vị thuộc phạm vi mình.
AC-4 — Chấm công vào thành công
Given nhân viên trong bán kính geofence When bấm "Chấm công vào" → vị trí hợp lệ → khuôn mặt đạt ngưỡng → "Xác nhận" Then lưu bản ghi (giờ + toạ độ + ảnh + % khớp) và hiển thị biên nhận; trạng thái ca → "Đang trong ca".
Trường hợp biên — khuôn mặt dưới ngưỡng khớp (theo vector, §8.2): không lưu bản ghi, báo "Nhận diện chưa đạt", cho thử lại; quá số lần thử thì dừng và báo liên hệ Quản lý/HR hỗ trợ thủ công (không có luồng "Xin chấm công từ xa" — đã chốt §8.4).
AC-5 — Chặn chấm công ngoài phạm vi
Given nhân viên ngoài bán kính cho phép When mở màn kiểm tra vị trí Then hiển thị "Ngoài phạm vi", nút chấm công khoá; không tạo bản ghi.
AC-6 — Phân loại trạng thái Văn phòng
Given ca 08:00–17:30, mốc tính muộn 08:10 (đã chốt §4.2) · When vào 08:14, ra 17:35 Then ngày đó = trạng thái "Đi muộn / Về sớm". Ở màn Chấm công/Danh sách/Thống kê hiển thị gộp nhãn "Đi muộn / Về sớm"; ở chi tiết ngày hiển thị cụ thể "Đi muộn" (đi muộn 4 phút — tính từ 08:10), màu cam — vì ra 17:35 cũng ≥ 17:30 nên chi tiết không hiện thêm "Về sớm".
Trường hợp biên — vào 08:08 (trước 08:10): không tính là đi muộn, không phạt.
Trường hợp biên — vào đúng giờ nhưng ra 17:20 (trước 17:30): ngày đó = trạng thái "Đi muộn / Về sớm" (gộp); chi tiết ngày hiện cụ thể "Về sớm", màu vàng.
Trường hợp biên — vừa đi muộn vừa về sớm cùng ngày: màn gộp vẫn hiện 1 nhãn "Đi muộn / Về sớm"; chi tiết ngày hiện cả 2 nhãn "Đi muộn" và "Về sớm" (đã chốt — không ưu tiên chỉ 1 nhãn).
Trường hợp biên — chỉ check-in, không check-out (quên/chưa ra) → ngày đó = trạng thái "Quên chấm công" (không phải "Đủ công" hay "Đi muộn / Về sớm") cho tới khi được bổ sung giờ ra qua giải trình công hoặc HR xử lý thủ công.
AC-7 — Cấu hình vị trí (HR)
Given HR mở "Thêm vị trí", chưa chọn Đơn vị áp dụng · When bấm Lưu · Then báo lỗi bắt buộc; chỉ lưu khi đủ đơn vị + toạ độ hợp lệ + bán kính > 0.
AC-8 — Gửi giải trình cho ngày chưa giải trình
Given một ngày trong tháng đang "Chưa giải trình" (chấm góc đỏ) do đi muộn When người dùng bấm ô ngày → bottom sheet → "Giải trình / Đăng ký" → chọn loại Đi muộn/Về sớm, nhập lý do, bấm "Gửi giải trình" Then đơn được tạo với trạng thái "Chờ duyệt", người duyệt = Quản lý trực tiếp của người gửi (không cho chọn khác); hiển thị màn thành công với tóm tắt đơn.
AC-9 — Quota nghỉ phép năm
Given người dùng còn 8/12 ngày phép năm When chọn loại "Nghỉ phép năm" trong form giải trình Then hiện khối "Phép năm còn lại: 8 ngày"; nếu đăng ký vượt số ngày còn lại, hệ thống chỉ cảnh báo, không chặn (theo BR-CN-13 web) — hành vi tương tự cần áp dụng khi Dev hiện thực app (§8.10 cần chốt trước khi code phần "Nghỉ phép đặc biệt").
Phụ lục A — Bản đồ màn ↔ file mockup¶
| Mã | Màn (theo bảng phân quyền) | File mockup | App nguồn |
|---|---|---|---|
| FR-01 | Danh sách nhân viên | nhan-su.html |
cả hai |
| FR-02 | Thêm mới nhân viên | them-nguoi-dung.html |
cả hai |
| FR-03 | Tab chấm công nhân viên | nhan-su-checkin-a.html |
cả hai |
| FR-04 | Tab thông tin nhân viên | nhan-su-thong-tin-b.html |
cả hai |
| FR-05a | Chấm công cá nhân | cham-cong.html |
cả hai |
| FR-05b | Kiểm tra vị trí (đã chốt PA A) | kiem-tra-vi-tri-a.html (b/c không dùng) |
cả hai |
| FR-05c | Ngoài phạm vi | kiem-tra-vi-tri-ngoai-pham-vi.html |
cả hai |
| FR-05d | Nhận diện khuôn mặt | cham-cong-khuon-mat.html |
cả hai |
| FR-05e | Chấm công thành công | cham-cong-thanh-cong.html |
cả hai |
| FR-06 | Thêm vị trí chấm công | them-vi-tri-cham-cong.html |
app-longdo-erp |
| FR-07a | Hub thống kê HR | thong-ke-cham-cong-hr.html |
app-longdo-erp |
| FR-07b | Chi tiết phòng ban | thong-ke-phong-ban-chi-tiet.html |
app-longdo-erp |
| FR-07c | Chi tiết dự án | thong-ke-du-an-chi-tiet.html |
app-longdo-erp |
| FR-07d | Thống kê theo ngày | thong-ke-theo-ngay.html |
cả hai |
| FR-07e | Thống kê theo trạng thái | thong-ke-theo-trang-thai.html |
cả hai |
| FR-08a | Giải trình công (lịch + danh sách) | giai-trinh-cong.html |
app-longdo-erp (pace-1) |
| FR-08b | Form tạo giải trình / đăng ký | giai-trinh-cong-form.html |
app-longdo-erp (pace-1) |
| FR-08c | Gửi giải trình thành công | giai-trinh-thanh-cong.html |
app-longdo-erp (pace-1) |
Ghi chú nguồn mockup
Mockup nằm ở 2 thư mục: app-cham-cong (app Chấm công độc lập)
và app-longdo-erp (module Chấm công nhúng trong ERP — có Thêm vị trí + hub thống kê HR).
SRS này hợp nhất theo bảng phân quyền. Các màn không thuộc phạm vi: dang-nhap.html,
trang-chu.html (Đăng nhập & Trang chủ — tách khỏi SRS này), nhat-ky-cong-truong.html
(module Dự án), thong-ke-danh-sach-cac-cach.html (công cụ so layout nội bộ). FR-08
(Giải trình công) hiện chỉ có ở app-longdo-erp/pace-1, chưa có bản tương ứng ở
app-cham-cong.