SRS — App Chấm công (Longdo ERP nội bộ)¶
App_chấm công.xlsx | Nguồn màn: mockup ui-mockups/longdo-erp/app-longdo-erp/pace-1/cham-cong/
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ụ đọc trực tiếp từ code mockup, và phân quyền từng màn.
Bản 0.8 — viết lại bám mockup hiện tại (29/07/2026)
Bản 0.7 mô tả bộ mockup cũ (thư mục app-cham-cong, màn giai-trinh-cong.html).
Bộ mockup đã đổi lớn — bản 0.8 này viết lại theo mockup đang có, thay đổi chính:
- Thư mục nguồn duy nhất:
app-longdo-erp/pace-1/cham-cong/. Thư mụcapp-cham-congkhông còn tồn tại — mọi mô tả cũ theo thư mục đó đã bỏ. - Màn trung tâm mới: "Công tháng" (
cong-thang.htmlcho Văn phòng,cong-thang-cong-truong.htmlcho Công trường) — gộp lịch tháng + chi tiết từng ngày + tổng công + tiền phạt + lối vào đơn. Thay cho màngiai-trinh-cong.html(đã xoá) và thay vai trò củanhan-su-checkin-a.html. - Đơn của tôi (
don-cua-toi.html) tách thành màn riêng, có lọc trạng thái và vuốt để Sửa / Xoá đơn Chờ duyệt. - Loại giải trình: ✦ 8 loại, lọc theo khối (thêm Thiếu giờ công, Đi công tác, ✦ Khác) — thay cho 5 loại ở bản 0.7.
- Công trường bỏ hẳn Đi muộn / Về sớm, thay bằng Thiếu giờ công. ✦ Sửa 19/08/2026: Công trường bỏ hẳn ca chuẩn / khung giờ — chấm công bất kỳ giờ nào trong ngày, giờ giấc linh hoạt hoàn toàn, được chia nhiều phiên trong ngày, chỉ cần tổng đủ 8 giờ = 1 công (thay ca chuẩn 07:00–16:30 và định mức 9,5 giờ). Khối Văn phòng giữ nguyên: 1 phiên / ngày, ca chuẩn 08:00–17:30. Chi tiết: Business Rule — Chấm công & Giải trình công.
- Tiền phạt / tiền tăng ca lần đầu được đặc tả (§4.5) — mockup đã tính và hiển thị.
- Bỏ tab "Giải trình / Đăng ký" cạnh tab Chấm công; màn
giai-trinh-thanh-cong.htmlkhông còn được dùng (form gửi xong hiện toast rồi quay lại).
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, tự theo dõi công tháng của mình (kèm tiền phạt / giờ tăng ca) và tự gửi đơn giải trình / đăng ký; 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 |
|---|---|
| Tự chấm công vào/ra (GPS + khuôn mặt) | Đăng nhập / Quên mật khẩu |
| Công tháng của bản thân — lịch tháng, chi tiết từng ngày, tổng công, tiền phạt, giờ tăng ca | Màn duyệt đơn của Quản lý trực tiếp & Nhân sự — thuộc web, module Hành chính – Nhân sự |
| Giải trình / Đăng ký — tạo, sửa, xoá đơn của bản thân; xem danh sách "Đơn của tôi" | Thiết lập tham số nghiệp vụ (định mức công, bậc tiền phạt, đơn giá tăng ca) — làm ở web, đợt sau |
| Danh sách nhân sự · Trạng thái nhân sự trong ngày · xem công tháng của nhân viên (HR) | Bảng lương / chốt lương (app chỉ hiển thị số tiền phạt & tiền tăng ca do server tính) |
| Thống kê chấm công · Cấu hình vị trí chấm công (geofence) | Trang chủ module (trang-chu.html) — dashboard tổng quan, đặc tả ở tài liệu khác |
| Thông báo chấm công & cài đặt thông báo · Hồ sơ cá nhân · Đổi mật khẩu | Các module khác của app (Chat, Danh bạ, Đề xuất, Công việc) |
1.3 Thuật ngữ¶
| Thuật ngữ | Ý nghĩa |
|---|---|
| Khối Công trường | Nhân sự theo dự án (Linh Đàm, Đông Anh, Yên Bái). ✦ Không có ca chuẩn — chấm công bất kỳ giờ nào trong ngày, nhiều phiên/ngày, tính theo tổng giờ của các phiên, không chia buổi. |
| Khối Văn phòng | Nhân sự theo phòng ban (IT, Hành chính–Kế toán, Kỹ thuật). Ca chuẩn 08:00–17:30, có mốc đi muộn 08:10. |
| Công tháng | Màn trung tâm của nhân viên: lịch tháng + chi tiết ngày + tổng công/quota + tiền phạt + giờ tăng ca + lối vào đơn. |
| Định mức ngày | Số giờ làm cần đạt để tính 1 công: ✦ Văn phòng 8 giờ làm thực (sau khi trừ giờ nghỉ trưa do Nhân sự thiết lập — giờ thô = 8g + nghỉ trưa), ✦ Công trường 8 giờ (tổng thời lượng các phiên trong ngày) — riêng ca chấm 1 lượt xuyên trưa (phiên bao trọn khung nghỉ trưa) thì định mức là 9,5 giờ vì nghỉ trưa nằm trong phiên. |
| 3 nhóm hiển thị ngày | Đủ định mức (xanh) · Thiếu định mức (vàng) · Không công (xám) — xem §4.3. |
| 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ả. |
| Đơn giải trình / đăng ký | Đơn nhân viên tự gửi cho một ngày lệch định mức, hoặc đăng ký trước (nghỉ, tăng ca, công tác). ✦ 8 loại, lọc theo khối — xem §4.6. |
2. Vai trò & nguyên tắc phân quyền¶
| Vai trò | Phạm vi & quyền tổng quát |
|---|---|
| HR | Toàn công ty: xem danh sách nhân sự, trạng thái trong ngày, công tháng & đơn của mọi nhân viên, mọi thống kê, cấu hình vị trí chấm công. Bản thân vẫn tự chấm công & tự gửi đơn ở luồng nhân viên. |
| Quản lý | Giới hạn trong phạm vi quản lý (đơn vị của mình): như HR nhưng chỉ với nhân sự thuộc đơn vị mình; không cấu hình vị trí chấm công. |
| Nhân viên | Chỉ dữ liệu của chính mình: tự chấm công, xem Công tháng của mình, tạo/sửa/xoá đơn của mình. Không thấy danh sách nhân sự, 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 nhân sự, Trạng thái nhân sự, Công tháng của người khác, 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.
Mockup dựng 3 lối vào: Nhân viên Văn phòng · Nhân viên Công trường · HR (chỉ-xem)
✦ Màn chon-vai-tro.html (chỉ để demo cho Dev, không có trong bản chạy thật) mở 3 lối vào:
Nhân viên — Văn phòng → cong-thang.html (1 phiên/ngày); Nhân viên — Công trường
→ cong-thang-cong-truong.html (nhiều phiên/ngày); HR → nhan-su.html. Luồng Quản lý chưa dựng riêng —
theo bảng phân quyền, Quản lý dùng đúng bộ màn của HR nhưng dữ liệu bị khoá trong phạm vi
đơn vị mình và không có nút "Thêm vị trí chấm công".
HR / Quản lý chỉ XEM, không thao tác hộ nhân viên
Trong mockup, HR mở công tháng của nhân viên bằng cong-thang.html?role=hr&nv=<tên>. Ở chế độ
này: tiêu đề đổi thành tên nhân viên + phụ đề "HR đang xem · chỉ đọc"; ẩn nút
"Giải trình / Đăng ký", ẩn lối vào "Đơn của tôi", ẩn cảnh báo nhắc giải trình, ẩn
nút "Giải trình ngay" trong chi tiết ngày (thay bằng nhãn tĩnh "Chưa giải trình"). Ở màn Đơn,
HR không vuốt được để Sửa/Xoá. Duyệt đơn và điều chỉnh tiền phạt làm ở web HCNS, không
làm trên app.
3. Ma trận phân quyền theo màn¶
| Màn hình | HR | Quản lý | Nhân viên |
|---|---|---|---|
| Chấm công (tự chấm) | ✓ | ✓ | ✓ |
| Công tháng — của bản thân | ✓ | ✓ | ✓ |
| Công tháng — của nhân viên khác | ✓ — chỉ đọc, toàn công ty | ✓ — chỉ đọc, trong phạm vi mình | ✗ |
| Giải trình / Đăng ký (tạo · sửa · xoá) | ✓ — cho bản thân | ✓ — cho bản thân | ✓ — cho bản thân |
| Đơn của tôi / Đơn của nhân viên | ✓ — xem đơn nhân viên (chỉ đọc) | ✓ — trong phạm vi mình (chỉ đọc) | ✓ — đơn của mình, sửa/xoá khi Chờ duyệt |
| Danh sách nhân sự | ✓ — full | ✓ — chỉ nhân sự thuộc phạm vi mình | ✗ |
| Trạng thái nhân sự trong ngày | ✓ — full | ✓ — trong phạm vi mình | ✗ |
| Thống kê | ✓ — full | ✓ — trong phạm vi mình | ✗ |
| Thêm vị trí chấm công | ✓ | ✗ | ✗ |
| Thông báo · Cá nhân / Hồ sơ / Đổi mật khẩu | ✓ | ✓ | ✓ |
Điều hướng theo vai trò
- Nhân viên → vào thẳng Công tháng (FR-09/FR-10); từ đó sang Chấm công (FR-05), Đơn của tôi (FR-11), Form giải trình (FR-08).
- HR / Quản lý → vào Danh sách nhân sự (FR-01) → chọn 1 người → Công tháng chỉ-đọc của người đó; hoặc Trạng thái nhân sự hôm nay (FR-12), Thống kê (FR-07).
- Module Chấm công tự chứa thanh điều hướng riêng, vào từ tab Cá nhân của app ERP.
4. Mô hình nghiệp vụ chấm công¶
4.1 Hai khối nhân sự¶
| Tiêu chí | Khối Công trường | Khối Văn phòng |
|---|---|---|
| Đơn vị mẫu | Linh Đàm, Đông Anh, Yên Bái | IT, Hành chính–Kế toán, Kỹ thuật |
| Ca chuẩn | ✦ Không có — chấm bất kỳ giờ nào trong ngày, giờ giấc linh hoạt | 08:00 – 17:30 (mốc đi muộn 08:10) |
| Đơn vị tính | Cả ngày — chỉ nhìn tổng giờ, không chia buổi. ✦ Tối đa 2 phiên / ngày: phiên 1 trước nghỉ trưa, phiên 2 sau nghỉ trưa | Có chia buổi sáng/chiều (nghỉ nửa ngày) |
| Nghỉ trưa | ✦ Không trừ — nhân viên chấm ra trước trưa, chấm vào lại sau trưa nên giờ nghỉ nằm ngoài phiên, tự động không được tính | ✦ Trừ đúng khung nghỉ trưa do Nhân sự thiết lập (không hard-code) |
| Định mức 1 công | ✦ 8 giờ — tổng thời lượng các phiên; 9,5 giờ nếu chấm 1 lượt xuyên trưa | ✦ 8 giờ làm thực — giờ thô cần đạt = 8g + giờ nghỉ trưa đã set |
| Đi muộn / Về sớm | Không có khái niệm này — chỉ đủ / thiếu tổng giờ | Có — theo mốc 08:10 và 17:30 |
| Định mức tháng (mẫu) | 25 công | 25 công |
Tham số nghiệp vụ phải cấu hình được, không hard-code
Các con số trên (ca chuẩn Văn phòng, mốc 08:10, định mức 8 giờ làm thực cả hai khối, khung giờ nghỉ trưa, quota 25 công) trong mockup là hằng số mẫu đặt ở đầu file JS. Bản thật phải đọc từ Thiết lập ở web HCNS theo từng khối / từng đơn vị.
4.2 Tập trạng thái ngày¶
Khối Văn phòng (cong-thang.html):
| Trạng thái | Điều kiện |
|---|---|
| Đủ công | Vào trước 08:10 và ra ≥ 17:30; ✦ giờ làm sau khi trừ khung nghỉ trưa do HR set đạt 8 giờ |
| Đi muộn | Giờ vào ≥ 08:10 — số phút muộn tính từ 08:10 |
| Về sớm | Giờ ra < 17:30 — số phút sớm tính tới 17:30 |
| Quên chấm công | Thiếu 1 trong 2 mốc (chỉ có giờ vào hoặc chỉ có giờ ra) |
| Tăng ca | Có đủ 2 mốc và làm thêm ngoài ca chuẩn — chỉ tính giờ đã được duyệt |
| Nghỉ | Có đơn nghỉ (phép năm / không lương / công tác / khác) áp cho cả ngày hoặc nửa ngày |
| Vắng | Hết ngày làm việc theo lịch mà không có bản ghi chấm công và không có đơn |
Khối Công trường (cong-thang-cong-truong.html):
| Trạng thái | Điều kiện |
|---|---|
| Đủ định mức | ✦ Tổng thời lượng các phiên ≥ định mức ngày — 8 giờ (nghỉ trưa ngoài phiên) hoặc 9,5 giờ (1 lượt xuyên trưa). Chấm giờ nào trong ngày cũng được |
| Thiếu giờ công | ✦ Mọi phiên đều đủ 2 mốc nhưng tổng giờ < định mức ngày — thay cho Đi muộn/Về sớm của Văn phòng |
| Quên chấm công | ✦ Bất kỳ phiên nào trong ngày thiếu 1 trong 2 mốc |
| Tăng ca | Làm vượt định mức — chỉ tính giờ đã duyệt |
| Nghỉ | Có đơn nghỉ (không lương / công tác / khác) |
| Vắng | Không có bản ghi và không có đơn |
Khác biệt lớn so với bản 0.7 — Dev đọc kỹ
- Công trường KHÔNG còn "Đi muộn"/"Về sớm" dưới mọi hình thức. Ngày làm không đủ giờ ở công trường là "Thiếu giờ công", giải trình bằng loại đơn cùng tên.
- Văn phòng tách riêng "Đi muộn" và "Về sớm" thành 2 sự kiện độc lập trong cùng một ngày (mockup ngày 02/06: vừa đi muộn vừa về sớm → 2 dòng sự kiện, 2 đơn riêng, 2 trạng thái duyệt riêng). Quy ước "gộp 1 nhãn Đi muộn / Về sớm" của bản 0.7 chỉ còn dùng ở màn Chấm công tuần (FR-05a) và các màn Thống kê (FR-07) — ở Công tháng thì luôn tách.
- Nghỉ phép năm chỉ có ở Văn phòng; form của Công trường ẩn lựa chọn này.
4.3 Ba nhóm hiển thị ngày (dùng chung cả 2 khối)¶
Ô lịch và badge chi tiết ngày không tô theo 6–7 trạng thái ở §4.2 mà quy về 3 nhóm:
| Nhóm | Màu nền ô | Ngày thuộc nhóm |
|---|---|---|
| Đủ định mức | Xanh | Đủ công · Tăng ca · Nghỉ CÓ LƯƠNG đã được duyệt (phép năm) |
| Thiếu định mức | Vàng | Đi muộn · Về sớm · Thiếu giờ công · Quên chấm công · ngày đi làm nhưng có phần nghỉ không công |
| Không công | Xám | Vắng · Nghỉ không lương · nghỉ chưa duyệt hoặc bị từ chối (cả ngày) |
Chấm góc ô lịch — 2 màu (giữ như bản 0.7):
| Chấm góc | Ý nghĩa |
|---|---|
| Đỏ + dấu ! | Chưa giải trình — ngày lệch định mức chưa có đơn |
| Tím + dấu ✓ | Đã có đơn — gộp chung Chờ duyệt / Đã duyệt / Từ chối (phân biệt khi mở chi tiết) |
- Ngày hôm nay: viền tím (
ring) quanh ô; ở Văn phòng ô hôm nay tô nền tím đậm. - Ngày cuối tuần và ngày tương lai chưa có dữ liệu: ô trống, không bấm được.
4.4 Quy đổi giờ làm ra công¶
| Khối | Giờ làm tính được | Công của ngày |
|---|---|---|
| Văn phòng ✦ | giờ ra − giờ vào − giờ nghỉ trưa (do HR set) |
min(giờ làm ÷ 8 giờ, 1) |
| Công trường ✦ | Σ (giờ ra − giờ vào) của các phiên đã đóng — bỏ phiên < 5 phút; không trừ nghỉ trưa |
min(tổng giờ ÷ định mức ngày, 1) với định mức = 8g + 1,5g nếu có phiên bao trọn khung nghỉ trưa |
Quy tắc kèm theo (đọc từ mockup):
- Tối đa 1 công/ngày — phần dôi ra không cộng vào công, mà tính riêng thành giờ tăng ca.
- ✦ Giờ tăng ca tính RIÊNG theo giờ, KHÔNG quy đổi ra ngày công — áp chung cả hai khối (Văn phòng không chia 8g/ngày, Công trường không chia định mức 8g). Giờ tăng ca đứng thành chỉ số riêng (ô Giờ tăng ca) và vào lương theo đơn giá giờ tăng ca, không làm đổi tổng công tháng. Xem BR-GT-10. (Sửa 19/08/2026.)
- Nghỉ có lương đã duyệt = 1 công. Nghỉ không lương / chưa duyệt / bị từ chối = 0 công.
- Ngày hôm nay chưa chấm ra: công hiển thị "—", chưa cộng vào tổng tháng.
- Thiếu 1 mốc chấm (Quên chấm công): công hiển thị "—" kèm cảnh báo "Chưa chốt công — thiếu lần chấm. Bổ sung giờ để tính công."; ở tổng tháng tạm tính đủ 1 công, chốt lại sau khi đơn bổ sung giờ được duyệt.
- Thanh tiến độ ở thẻ tổng =
tổng công ÷ định mức tháng(mẫu 25 công).
4.5 Tiền phạt & tiền tăng ca¶
Mockup đã tính và hiển thị 3 khoản. Giá trị dưới đây là mẫu, phải cấu hình được ở Thiết lập.
| Khoản | Đơn giá mẫu | Điều kiện phát sinh |
|---|---|---|
| Phạt đi muộn | 50.000 ₫ / lần | Chỉ khối Văn phòng. Tính khi ngày đã qua và đơn chưa được duyệt (gồm cả: chưa giải trình, đang chờ duyệt, bị từ chối). Về sớm KHÔNG bị phạt. |
| Phạt ngày nghỉ | 1.200.000 ₫ / ngày | Cả 2 khối. Tính khi ngày đã qua và đơn ở trạng thái chưa giải trình hoặc bị từ chối — đang chờ duyệt thì chưa tính phạt. |
| Tiền tăng ca | 60.000 ₫ / giờ | Cả 2 khối. Chỉ cộng giờ tăng ca đã được duyệt; giờ làm thêm chưa đăng ký / bị từ chối hiển thị nhưng không tính tiền. |
✦ Tiền tăng ca KHÔNG hiện ở bản ghi tăng ca của chi tiết ngày (sửa 19/08/2026)
Bản ghi Tăng ca trong khối Sự kiện & giải trình của chi tiết ngày chỉ hiện “Làm thêm <thời lượng>” — bỏ dòng “+ <tiền> đ lương tăng ca”. Lý do: giờ tăng ca là chỉ số riêng, không quy đổi ra ngày công (BR-GT-10); tiền tăng ca thuộc bảng lương. Tiền tăng ca vẫn hiện ở sheet “Giờ tăng ca tháng” (tổng giờ đã duyệt + thành tiền) — đó là màn chuyên cho tăng ca.
Bất nhất trong mockup — cần chốt trước khi code
Điều kiện phạt của đi muộn và của ngày nghỉ đang khác nhau ở trạng thái "Chờ duyệt": đi muộn đang-chờ-duyệt vẫn bị tính phạt, còn nghỉ đang-chờ-duyệt chưa bị tính. Xem §8 mục 1 — cần BA chốt một quy tắc thống nhất.
Ngày tương lai không bao giờ bị phạt
Ngày chưa diễn ra (kể cả đã có đơn bị từ chối) chỉ hiển thị trạng thái, không cộng vào tiền phạt.
4.6 Giải trình / Đăng ký — ✦ 8 loại theo khối¶
| Loại | Văn phòng | Công trường | Trường nhập riêng |
|---|---|---|---|
| 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" (mẫu 12/12 ngày) + dòng tóm tắt "Nghỉ từ Sáng dd/mm → Chiều dd/mm · N công" |
| Nghỉ không lương | ✓ | ✓ | Như trên, không có khối phép năm còn lại |
| Đi muộn / Về sớm | ✓ | ✗ | Chọn Đi muộn / Về sớm · Loại lý do (Cá nhân / Công việc) · Ngày · Từ giờ → Đến giờ (khoảng giờ vắng mặt). Chọn "Lý do công việc" → hiện thêm ô Nội dung công việc |
| Thiếu giờ công | ✗ | ✓ | Ngày · Giờ vào thực tế · Giờ ra thực tế |
| Quên chấm công | ✓ | ✓ | Chọn Quên chấm vào / Quên chấm ra · Ngày · 1 ô giờ thực tế (nhãn đổi theo lựa chọn) |
| Tăng ca | ✓ | ✓ | Ngày · Giờ bắt đầu → Giờ kết thúc · ô Nội dung công việc (thay cho ô Lý do). ✦ Kết quả là số giờ tăng ca — tính riêng, không quy đổi ra ngày công ở cả hai khối (BR-GT-10) |
| Đi công tác | ✓ | ✓ | Từ ngày + buổi → Đến ngày + buổi · Nơi công tác (bắt buộc) · dòng tóm tắt "Đi công tác tại X · Sáng dd/mm → Chiều dd/mm · N công". ✦ Phạm vi Theo giờ (1 ngày + Từ giờ → Đến giờ): khối Công trường phải chọn Phiên 1 / Phiên 2; phạm vi Theo ngày thì không chọn phiên |
| ✦ Khác | ✓ | ✓ | Loại đơn mở cho tình huống không khớp 7 loại trên: Ngày · Giờ vào · Giờ ra · Lý do (bắt buộc) · File đính kèm. Đơn duyệt = một phiên làm việc hợp lệ, hợp nhất với phiên đã chấm (không cộng trùng) — xem Business Rule Nhóm H |
✦ Thời hạn nộp đơn — 1 tuần kể từ ngày xảy ra sự việc (chốt 19/08/2026)
Gọi D = ngày cần giải trình. Đơn chỉ gửi được tới hết 23:59 ngày D+7; từ 00:00 ngày D+8 ngày D đóng hẳn — báo “Đã quá hạn giải trình”.
- Áp MỌI loại đơn, không trừ loại nào: quá D+7 là chặn hết.
- Nghỉ phép năm và Nghỉ không lương là đơn xin nghỉ trước nên còn chặt hơn: chặn toàn bộ ngày quá khứ (kể cả trong 7 ngày); riêng Nghỉ phép năm chặn cả hôm nay.
- Ngày tương lai: cho mọi loại trừ Quên chấm công và Thiếu giờ công.
- Áp cả hai khối (Văn phòng · Công trường), không tách luật theo khối.
- Cửa sổ 7 ngày được phép vắt sang tháng sau.
- Thay luật cũ “cửa sổ hồi tố = phần còn lại của tháng”.
Chi tiết & bộ ca test: Business Rule — Chấm công & Giải trình công (BR-GT-18 · BR-GT-19).
Trường dùng chung (hiện sau khi đã chọn loại): Lý do (bắt buộc, trừ Tăng ca dùng "Nội dung công việc") · File đính kèm (tuỳ chọn — ảnh / video / tệp) · Người duyệt (chỉ đọc) · nút Gửi đơn.
Cách tính số công của đơn nghỉ / công tác: mỗi ngày = 1 công; bắt đầu từ buổi chiều trừ 0,5; kết thúc buổi sáng trừ 0,5; tối thiểu 0,5 công.
Người duyệt — đã chốt 03/08/2026
Người duyệt cố định, nhân viên không được chọn: Quản lý trực tiếp + Nhân sự (HR) — duyệt song song, cần đủ 2 bên, áp dụng cho mọi loại đơn và cả hai khối. Ở Công trường, chỉ huy trưởng chính là quản lý trực tiếp → không tách quy tắc theo khối. (Khớp form tạo đơn; bottom sheet chi tiết đơn đã sửa 27/08/2026 — mục "Tiến trình duyệt" hiện đủ 2 bên cho mọi loại đơn, xem FR-11.)
Hạn nộp đơn: giải trình được cho quá khứ trong tháng, hạn cuối là ngày cuối tháng
Sửa 05/08/2026 (thay luật "không giải trình cho quá khứ" chốt 03/08/2026): được giải trình cho ngày đã qua, nhưng chỉ trong tháng hiện tại — hạn cuối là hết ngày cuối cùng của tháng. Sang tháng mới, mọi ngày của tháng trước khoá hẳn. Ngày tương lai vẫn đăng ký trước bình thường, không bó trong tháng. Xem BR-GT-09.
Trên giao diện (sửa 28/08/2026 — bỏ dải cảnh báo vàng đầu màn Công tháng nhắc hạn giải trình; màn vào thẳng thẻ tổng tháng rồi tới lịch): trong chi tiết ngày, mọi ngày thuộc tháng đang xem là tháng hiện tại đều có nút "Giải trình ngay"; ngày thuộc tháng trước chưa có đơn hiện nhãn tĩnh "Đã quá hạn" và không cho tạo đơn. (Cửa ngoại lệ cho HR khai bù ngày của tháng đã đóng: chưa mở.)
Đi công tác: tính công, không phụ cấp
Đơn Đi công tác ở trạng thái Đã duyệt → ngày trong đơn được tính công (quy đổi theo buổi như đơn nghỉ), không cần bằng chứng làm việc kèm theo và không có phụ cấp công tác đi kèm. Đơn Chờ duyệt / Từ chối thì không tính công. Xem BR-GT-10.
Trạng thái đơn: Chờ duyệt (vàng) · Đã duyệt (xanh) · Từ chối (đỏ). Đơn bị Từ chối →
ngày đó giữ nguyên phần công thiếu và bị tính phạt như chưa giải trình.
Sửa / xoá đơn: nhân viên vuốt ngang một đơn đang Chờ duyệt ở màn Đơn của tôi để lộ 2
nút Sửa (mở lại form ở chế độ ?edit=<mã đơn>, tiêu đề "Sửa đơn giải trình", nút "Cập nhật
đơn") và Xoá (có hộp thoại xác nhận). Đơn Đã duyệt / Từ chối không sửa/xoá được.
4.7 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".
Ngoại lệ ghi nhận ở màn Trạng thái nhân sự
Màn trang-thai-nhan-su.html có dữ liệu mẫu "Chấm ngoài phạm vi 180 m — đã ghi nhận kèm ảnh,
chờ Nhân sự xác nhận", tức có trường hợp bản ghi ngoài vùng vẫn được lưu và chờ HR xác
nhận — mâu thuẫn với quy tắc chặn cứng ở mục 3. Xem §8 mục 3.
4.8 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 + độ khớp.
- Độ khớp hiển thị dạng phần trăm — biên nhận ở FR-05e hiện chip "Khớp 99%".
Cách tính % khớp và ngưỡng tối thiểu — chưa chốt
Mockup chỉ hiển thị con số %; cách quy đổi từ khoảng cách/độ tương đồng vector đặc trưng khuôn mặt (face embedding) ra %, cùng ngưỡng tối thiểu để chấp nhận, là tham số kỹ thuật phụ thuộc SDK nhận diện được chọn — Dev/kỹ thuật xác nhận, không phải quy tắc BA đặt. Kèm theo đó là hành vi khi dưới ngưỡng (xem §8 mục 7) — mockup chưa dựng nhánh này.
4.9 Chốt kỳ công — hệ thống tự chốt, không có nút¶
(Chốt 10/08/2026 — đóng vấn đề mở "chấm công đã chốt" ở SRS HCNS.)
Kỳ chấm công không có nút Chốt trên giao diện. Hệ thống tự chốt kỳ tháng M vào
23:59 ngày N của tháng M+1, với N là tham số cấu hình, mặc định 03.
Vì sao tự động, và vì sao không chốt lúc 23:59 ngày cuối tháng
Tự động vì mốc trùng với hạn giải trình đã có (hết tháng — §4.6), nhân viên đã quen; không cần dựng màn quản lý kỳ công; và không ai quên chốt làm kẹt kỳ lương.
Ba ngày đệm vì rủi ro lớn nhất không phải đơn giải trình mà là punch về trễ (thiết bị mất mạng, face-service sync chậm — lần chấm ngày 30 lên hệ thống sáng 01). Chốt cứng lúc nửa đêm là loại oan lần chấm công có thật. Ba ngày đủ để punch trôi về hết và đơn gửi ngày 31 được duyệt kịp, vẫn xong trước khi làm lương.
Phạm vi đóng băng — 5 nhóm:
| # | Đối tượng | Sau khi chốt |
|---|---|---|
| 1 | Dữ liệu punch của kỳ | Không nhận thêm, không sửa; punch về trễ ghi vào nhật ký lệch, không đổi công |
| 2 | Nhãn trạng thái từng ngày | Khoá |
| 3 | Số công từng ngày & tổng công tháng | Khoá |
| 4 | Tiền phạt đi muộn · về sớm · vắng không phép | Khoá |
| 5 | Đơn giải trình thuộc kỳ | Không thêm/sửa/xoá — nhưng luồng duyệt vẫn mở (xem dưới) |
Kết sổ ngày còn treo trạng thái — việc mà §4.4 gọi là "chốt lại sau":
| Ngày | Đang tạm tính | Khi chốt |
|---|---|---|
| Quên chấm công, có đơn Đã duyệt | — | Cộng công theo đơn (BR-GT-16) |
| Quên chấm công, không có đơn | đủ 1 công | 0 công — hạn giải trình cả tháng đã đủ rộng; giữ 1 công biến quên chấm công thành miễn phí. Tham số cấu hình được (0 / 1 công) |
| Đơn Từ chối | — | Giữ nguyên trạng thái lệch, không đủ công (BR-GT-15) |
| Đơn còn Chờ duyệt | chưa tính phạt (§8 mục 1) | Chốt theo hiện trạng chưa phạt; kết quả duyệt sau đó đi đường điều chỉnh |
Đơn gửi đúng hạn nhưng duyệt không kịp — đơn cần đủ 2 bên: Quản lý trực tiếp + Nhân sự (chốt 03/08/2026, §8 mục 2), nên đơn treo là chuyện có thật. Nhân viên đã làm đúng nghĩa vụ, không được để họ chịu. Ba tầng:
- Thúc trước hạn — từ ngày 26 hàng tháng nhắc mỗi người duyệt số đơn còn treo; nhắc nhân viên "còn 2 ngày để giải trình công tháng 6" vào ngày 01 và 03.
- Duyệt thay — HR/Admin được duyệt vượt cấp thay Quản lý vắng mặt, bắt buộc ghi lý do, log rõ "Nhân sự duyệt thay Quản lý". Không có đường này thì một người nghỉ phép là kẹt cả kỳ.
- Vẫn chốt đúng hạn, đơn treo không mất — đơn đi tiếp luồng duyệt bình thường sau khi chốt. Đơn ở lại kỳ của ngày áp dụng, vĩnh viễn; chỉ hệ quả tiền đi sang kỳ sau.
Đơn ở lại kỳ cũ — chỉ tiền đi sang kỳ mới
Đơn giải trình cho ngày 20/06 mãi mãi là đơn của kỳ tháng 6, dù duyệt ngày 15/07. Chuyển đơn sang kỳ 7 sẽ làm bẩn dữ liệu chấm công tháng 7 (tính công sai, lịch hiện ngày lạ, báo cáo hỏng).
Chênh lệch tiền nạp vào kỳ lương tương ứng nếu kỳ đó còn mở — khoảng đệm giữa chốt công (~03/07) và chốt lương (~10/07) hấp thụ phần lớn ca trễ, không sinh truy lĩnh gì cả. Chỉ khi cả hai kỳ đều đã chốt mới đi đường điều chỉnh sang kỳ sau (FR-PL-CHOT).
Sau khi chốt hệ thống làm gì: ① kết sổ ngày còn treo (bảng trên); ② chụp snapshot bảng công (tổng công · số ngày muộn/sớm/vắng · tiền phạt · giờ tăng ca từng người); ③ khoá 5 nhóm dữ liệu; ④ gỡ cảnh báo "Chưa chốt công — thiếu lần chấm" (ngày đã có kết quả cuối, không còn tạm tính); ⑤ badge Đã chốt trên màn Công tháng; ⑥ mở cổng cho bảng lương lấy số; ⑦ thông báo nhân viên "Bảng công tháng 6 đã chốt"; ⑧ ghi nhật ký (thời điểm · số đơn treo · số ngày kết sổ 0 công).
Mở lại kỳ công — bất đối xứng có chủ đích: đóng tự động, mở thủ công. Chỉ Admin, bắt nhập lý do, ghi log. Dành cho ca thật: máy chấm công hỏng cả ngày, cả tổ mất punch, phát hiện sau khi chốt.
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.
Toàn bộ file nằm trong ui-mockups/longdo-erp/app-longdo-erp/pace-1/cham-cong/.
| Luồng Nhân viên | Luồng HR / Quản lý | Dùng chung |
|---|---|---|
| FR-05 Chấm công (tự chấm) | FR-01 Danh sách nhân sự | FR-13 Thông báo & cài đặt |
| FR-09 Công tháng — Văn phòng | FR-12 Trạng thái nhân sự trong ngày | FR-14 Cá nhân · Hồ sơ · Mật khẩu |
| FR-10 Công tháng — Công trường | FR-07 Thống kê | FR-15 Chọn vai trò (chỉ demo) |
| FR-08 Form giải trình / đăng ký | FR-06 Thêm vị trí chấm công | — |
| FR-11 Đơn của tôi | FR-04 Thông tin nhân sự | — |
FR-01. Danh sách nhân sự¶
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: tìm nhân sự, mở công tháng chỉ-đọc của họ, và vào màn Trạng thái nhân sự trong ngày.
| Thành phần | Ghi chú |
|---|---|
| Lối vào "Trạng thái nhân sự hôm nay" | thẻ đầu màn, phụ đề "Ai đang làm việc, nghỉ, đi công tác — kèm địa điểm chấm công" → FR-12 |
| Ô tìm kiếm theo tên | placeholder "Tìm theo tên nhân sự…" |
| Lọc theo đơn vị | 2 nhóm: Công trường (Linh Đàm / Đông Anh / Yên Bái) · Văn phòng (IT / Hành chính–Kế toán / Kỹ thuật) |
| Item nhân sự | avatar · tên · chức vụ · đơn vị · mũi tên |
Tương tác: bấm 1 nhân sự → mở Công tháng chỉ-đọc của người đó, đúng theo khối:
- Nhân sự Văn phòng →
cong-thang.html?role=hr&nv=<tên>(FR-09) - Nhân sự Công trường →
cong-thang-cong-truong.html?role=hr&nv=<tên>(FR-10)
Đã bỏ so với bản 0.7
Màn này không còn FAB "Thêm nhân viên" (tạo hồ sơ nhân sự làm ở web HCNS), và
không còn trỏ sang nhan-su-checkin-a.html.
Dev lưu ý
Mockup: mọi item trỏ về cùng 1 file (chưa truyền id thật, chỉ có nv=<tên>). Dev tham số
hoá theo mã nhân viên và chọn màn theo khối của nhân sự đó. Ô tìm kiếm & bộ lọc đơn vị
chưa gắn logic — cần hiện thực.
FR-02. Thêm mới nhân viên — đã đưa ra khỏi app¶
Không còn màn tương ứng trong
pace-1/cham-cong/.
Tạo hồ sơ nhân sự thực hiện ở web, module Hành chính – Nhân sự. File them-nguoi-dung.html
chỉ còn ở pace-2 (giai đoạn 2, ngoài phạm vi SRS này). Mã FR-02 giữ chỗ để không lệch số
hiệu các mã cũ.
FR-03. Xem chấm công của một nhân viên (HR / Quản lý)¶
File:
cong-thang.html?role=hr&nv=…/cong-thang-cong-truong.html?role=hr&nv=…Quyền: HR (full) · Quản lý (nhân sự phạm vi mình) — Nhân viên không
Trước đây là màn riêng nhan-su-checkin-a.html (lịch tháng + ô đếm trạng thái). Nay dùng lại
đúng màn Công tháng ở chế độ chỉ-đọc — xem FR-09 / FR-10 và khối "HR / Quản lý chỉ XEM" ở §2.
File cũ vẫn còn trong repo nhưng không còn lối vào
nhan-su-checkin-a.html chỉ còn được mở từ nhan-su-thong-tin-b.html. Dev không hiện
thực màn này; nếu BA chốt bỏ hẳn thì xoá cả 2 file ở đợt dọn mockup.
FR-04. Thông tin nhân sự¶
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 một nhân sự. Vào từ FR-12 (chi tiết một người ở màn Trạng thái nhân sự).
| 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 | chip "Quản lý" |
Nhân viên không xem được màn này (kể cả hồ sơ của chính mình — hồ sơ cá nhân xem ở FR-14).
FR-05. Chấm công (tự chấm)¶
File:
cham-cong.html→kiem-tra-vi-tri-a.html→ (kiem-tra-vi-tri-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)
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 | Mẫu |
|---|---|
| Thẻ hôm nay | ngày · chip trạng thái ca (Chưa vào ca / Đang trong ca / Đã ra ca) |
| Giờ vào · Giờ ra · Đã làm | "—" khi chưa chấm |
| Gợi ý vị trí | "Bạn đang ở VP Longdo · trong phạm vi chấm công" |
| Danh sách "Chấm công tuần này" | mỗi dòng: thứ · ngày · vào → ra · chip trạng thái; chạm → bottom sheet chi tiết ngày |
| Nút tròn "Chấm công vào" | ngay trên bottom nav → FR-05b |
| Chuông thông báo | → FR-13 |
- Chip trạng thái ở màn này dùng nhãn gộp "Đi muộn / Về sớm" và có thêm nhãn "Chưa chấm công" cho ngày hôm nay/tương lai chưa chấm.
- Đã bỏ: tab "Giải trình / Đăng ký" cạnh tab Chấm công (bản 0.7 có, nay không còn).
FR-05b. Kiểm tra vị trí (kiem-tra-vi-tri-a.html — Phương án A: bản đồ toàn màn.
kiem-tra-vi-tri-b.html / -c.html là 2 phương án không chọn, Dev bỏ qua)
| Thành phần | Nguồn | Mẫu |
|---|---|---|
| Bản đồ toàn màn | hệ thống | vòng geofence nét đứt + pin địa điểm + chấm vị trí người dùng (có halo) |
| Chip trạng thái nổi | hệ thống | "Bạn đang trong phạm vi chấm công" |
| Tên + địa chỉ địa điểm | hệ thống | VP Longdo · 123 Phố Láng Hạ, Đống Đa, Hà Nội |
| Khoảng cách | GPS | cách 8 m |
| Độ chính xác GPS | GPS | ±5 m |
| Nút chính | — | "Tiếp tục nhận diện khuôn mặt" → FR-05d |
Phương án A chỉ hiển thị 2 chỉ số
Mockup A không hiện "Chống vị trí giả mạo" và "Toạ độ hiện tại" — 2 mục đó chỉ có ở phương án B / C (đã loại). Việc kiểm tra mock location vẫn là yêu cầu bắt buộc (§4.7 mục 2) nhưng chạy ngầm: phát hiện vị trí giả mạo thì chặn như trường hợp ngoài phạm vi. Nếu BA muốn hiện kết quả kiểm tra lên UI thì phải bổ sung vào mockup A trước.
FR-05c. Ngoài phạm vi (kiem-tra-vi-tri-ngoai-pham-vi.html) — hiện khoảng cách thực vs bán
kính cho phép; nút chấm công vô hiệu hoá; chỉ 1 nút "Thử lại" (luồng "Xin chấm công từ xa"
đã bỏ hẳn — mockup còn nút này thì Dev bỏ qua).
FR-05d. Nhận diện khuôn mặt (cham-cong-khuon-mat.html) — thẻ ca (ngày · giờ · "Ca hành chính
· 08:00") + khung camera + hướng dẫn liveness động + chip "Phát hiện khuôn mặt thật" → nút "Xác
nhận chấm công vào".
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 · vị trí + toạ độ · nhắc giờ ra dự kiến. Nút "Xong" → 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· Quyền: chỉ HR
| 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 | ✓ | 21.1402 |
| Kinh độ | số thực | ✓ | 105.8542 |
| Bán kính cho phép (m) | số nguyên | ✓ | > 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".
- Không có bán kính mặc định — mỗi vị trí tự set; không tự điền sẵn 100 khi HR bỏ trống.
- Mockup chưa validate: Dev cần bắt buộc Đơn vị áp dụng, validate toạ độ & bán kính > 0; lưu theo mã đơn vị (không lưu chuỗi hiển thị).
FR-07. Thống kê¶
Quyền: HR (full) · Quản lý (phạm vi mình) — Nhân viên không
FR-07a. Thống kê (màn chính) (thong-ke.html)
| Thành phần | Ghi chú |
|---|---|
| Bộ lọc khoảng ngày | Từ ngày – Đến ngày + nút Lọc (giới hạn trong khoảng có dữ liệu) |
| Segmented khối | 🏢 Văn phòng / 🏗 Công trường |
| Chips chọn công trường | chỉ hiện khi chọn khối Công trường |
| Segmented chế độ xem | Lịch / Danh sách + đếm "N nhân viên" |
| View Lịch | mỗi tháng trong khoảng lọc là 1 thẻ; mỗi ngày tô màu theo trạng thái có nhiều nhân viên nhất; chạm ngày → xem theo nhân viên. Chú thích 3 nhóm màu: Đủ công · (Đi muộn/Về sớm · Quên chấm công · Tăng ca) · Vắng / ngày nghỉ |
| View Danh sách | bảng chấm công tháng: nhân sự × ngày + cột tổng |
| Khối "Tổng hợp" | các ô đếm lượt theo trạng thái (Đi muộn/Về sớm · Quên chấm công · Vắng · Đủ công · Tăng ca) → bấm sang FR-07d |
| Nút lọc phòng ban | ở app bar |
FR-07b. Chi tiết thống kê 1 nhân sự (chi-tiet-thong-ke.html)
- Thẻ đầu: avatar · tên · "chức vụ · phòng ban" · chip kỳ (Tháng 06/2026) · nút xuất file.
- Lưới 2×2: Đủ công (ngày) · Đi muộn / Về sớm (lần) · Nghỉ phép (ngày) · Tăng ca (tổng giờ).
- Thẻ Tổng kết: Tổng ngày công · Tổng giờ làm · Giờ vào trung bình · Tỉ lệ đúng giờ.
- Mục Chi tiết theo ngày: mỗi dòng
thứ · ngày · vào → ra · tổng giờ · chip trạng thái.
FR-07c–e. Bộ màn thống kê theo đơn vị (bản trước)
thong-ke-cham-cong-hr.html (hub chọn dự án / phòng ban) · thong-ke-phong-ban-chi-tiet.html ·
thong-ke-du-an-chi-tiet.html · thong-ke-theo-ngay.html · thong-ke-theo-trang-thai.html.
- Hub: segmented Công trường / Văn phòng → thẻ đơn vị (kèm số người); HR thấy mọi đơn vị + nút "Thêm vị trí" (→ FR-06); Quản lý chỉ thấy đơn vị mình, không có nút Thêm vị trí.
- Chi tiết phòng ban / dự án: lọc khoảng ngày; View Lịch (heatmap theo trạng thái trội nhất, chạm ngày → panel chi tiết) và View Danh sách (ma trận nhân viên × ngày + cột tổng Công / Muộn-Sớm / Thêm / Vắng / Giờ + hàng Tổng + nút Excel).
- Thống kê theo ngày: toàn bộ nhân sự trong 1 ngày, dải ô trạng thái + bảng giờ.
- Thống kê theo trạng thái: 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.
| Chỉ số/tháng | Định nghĩa |
|---|---|
| Công | số ngày trạng thái Đủ công |
| Muộn-Sớm | số ngày có Đi muộn và/hoặc Về sớm |
| Thêm | số ngày có Tăng ca |
| Vắng | số ngày Vắng (không tính ngày nghỉ theo lịch) |
| Giờ | Σ max(0, ra − vào) |
Chồng lấn — cần BA chốt giữ bộ nào
thong-ke.html (FR-07a) và bộ thong-ke-cham-cong-hr.html + chi tiết phòng ban/dự án
(FR-07c–e) làm gần như cùng một việc bằng 2 bố cục khác nhau, đều đang có lối vào (một từ
mục lục module, một từ tab Cá nhân). Xem §8 mục 4.
Dev lưu ý — điều hướng & phạm vi
Thẻ đơn vị / ô ngày trong mockup 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ò. Nút xuất Excel hiện mới là mô phỏng.
FR-08. Form giải trình / Đăng ký¶
File:
giai-trinh-cong-form.html— nhận?khoi=vp|ct,?loai=<mã loại>,?edit=<mã đơn>Quyền: HR · Quản lý · Nhân viên (tất cả tạo đơn cho bản thân) — nghiệp vụ ở §4.6
Vào form từ đâu: nút "Giải trình / Đăng ký" ở Công tháng (FR-09/FR-10) · nút "Giải trình
ngay" trong chi tiết ngày hôm nay (kèm sẵn ?loai=) · nút Sửa khi vuốt đơn Chờ duyệt ở Đơn
của tôi (?edit=).
Cấu trúc form: ô Loại giải trình đứng đầu (bắt buộc). Chưa chọn loại thì chỉ hiện ô này — chọn xong mới hiện nhóm trường tương ứng + ô Lý do + File đính kèm + Người duyệt + nút Gửi. Ô chọn loại hiện icon màu theo loại.
Lọc lựa chọn theo khối (tham số ?khoi=):
| Khối | Số lựa chọn | Ẩn |
|---|---|---|
vp — Văn phòng (mặc định) |
✦ 7 | Thiếu giờ công |
ct — Công trường |
✦ 6 | Nghỉ phép năm, Đi muộn / Về sớm |
Chi tiết trường theo từng loại: xem bảng ở §4.6.
Hành vi khác:
- Ô ngày là ô chỉ đọc, chạm mở dialog lịch Material (điều hướng tháng, chọn ngày, xác nhận).
- Ô giờ dùng bàn phím số, tự chèn dấu
:sau 2 chữ số, tối đa 5 ký tự. - Có cảnh báo tự soát cho các cặp giờ của Tăng ca / Đi muộn–Về sớm / Thiếu giờ công.
- Đổi loại → hiện đúng nhóm trường + reset các khối liên quan.
- Gửi đơn: hiện toast rồi quay lại màn trước (
history.back()). Không còn dùng màngiai-trinh-thanh-cong.html— file này hiện không có lối vào nào. - Chế độ sửa (
?edit=): tiêu đề "Sửa đơn giải trình", nút "Cập nhật đơn"; dữ liệu đơn cũ do bản thật nạp từ API (mockup chưa nạp).
FR-09. Công tháng — Khối Văn phòng¶
File:
cong-thang.html— nhận?role=hr,?nv=<tên>Quyền: mọi vai trò cho bản thân · HR/Quản lý xem người khác ở chế độ chỉ-đọc
Mục đích: màn trung tâm của nhân viên — xem toàn bộ công tháng của mình, biết ngay ngày nào thiếu định mức / bị phạt, và giải trình ngay tại chỗ.
Bố cục từ trên xuống:
| # | Khối | Nội dung |
|---|---|---|
| 1 | App bar | nút quay lại (về Cá nhân, hoặc về Danh sách nhân sự khi ?role=hr) · tiêu đề "Công tháng" (chế độ HR: tên nhân viên + phụ đề "HR đang xem · chỉ đọc") · chuông thông báo có chấm đỏ |
| 2 | Thanh chọn tháng | ‹ › + "Tháng M · YYYY"; nút tháng sau khoá khi đang ở tháng hiện tại |
| 3 | Thẻ tổng tháng | tổng công / định mức + thanh tiến độ; 3 ô bấm được: Lần đi muộn (kèm tiền phạt) · Ngày nghỉ (kèm tiền phạt) · Giờ tăng ca |
| 4 | Cảnh báo | chỉ hiện khi hôm nay thiếu định mức và chưa có đơn (ẩn ở chế độ HR) |
| 5 | Lịch tháng | ô ngày tô theo 3 nhóm (§4.3) + chấm góc 2 màu; chạm ngày → mở khối 6 |
| 6 | Chi tiết 1 ngày | hiện ngay dưới lịch (không phải bottom sheet) — xem bảng dưới |
| 7 | Chú giải | 4 mục màu nền (Đủ định mức / Thiếu định mức / Không công / Hôm nay) + 2 mục chấm góc |
| 8 | Lối vào Đơn của tôi | kèm badge "N chờ duyệt" (ẩn ở chế độ HR) → FR-11 |
| 9 | Nút "Giải trình / Đăng ký" | nút chính, mở FR-08 với ?khoi=vp (ẩn ở chế độ HR) |
Khối 6 — Chi tiết 1 ngày gồm:
- Dòng đầu:
Thứ, dd/mm+ badge nhóm (Đủ định mức / Thiếu định mức / Vắng) + nút đóng. - 3 ô: Giờ vào · Giờ ra · Công ngày (thiếu mốc → "—" màu đỏ).
- Nếu công = "—": dải cảnh báo "Chưa chốt công — thiếu lần chấm. Bổ sung giờ để tính công."
- Danh sách "Giải trình trong ngày · N" — mỗi sự kiện 1 thẻ: tên sự kiện · chip trạng thái
(Chưa giải trình / Chờ duyệt / Đã duyệt / Từ chối) · dòng chi tiết (vd "Vào 08:22 · muộn 12
phút", "Buổi sáng") · dòng tiền (
− 50.000 ₫ tiền phạt · quá hạnhoặc+ 150.000 ₫ lương tăng ca · 2g 30p) · nút hành động:- chưa có đơn và ngày thuộc tháng hiện tại (hôm nay hoặc đã qua trong tháng) →
"Giải trình ngay" (mở FR-08 kèm
?loai=) - chưa có đơn và ngày thuộc tháng trước → nhãn tĩnh "Đã quá hạn"
- đã có đơn → "Xem đơn ›" (mở bottom sheet chi tiết đơn)
- chế độ HR → luôn là nhãn tĩnh "Chưa giải trình"
- chưa có đơn và ngày thuộc tháng hiện tại (hôm nay hoặc đã qua trong tháng) →
"Giải trình ngay" (mở FR-08 kèm
- Ngày đủ định mức, không có sự kiện → dải xanh "Đủ định mức — không có gì cần giải trình."
3 bottom sheet thống kê (mở từ 3 ô ở khối 3):
| Sheet | Nội dung | Ghi chú |
|---|---|---|
| Đi muộn | chỉ liệt kê các lần bị phạt; mỗi dòng dd/mm · Đi muộn · Vào hh:mm · muộn N phút · Phạt 50.000 ₫; dòng tổng "Tổng tiền phạt" |
Về sớm không xuất hiện vì không bị phạt |
| Ngày nghỉ | chỉ liệt kê ngày bị phạt (chưa giải trình / bị từ chối); mỗi dòng dd/mm · <loại nghỉ> (cả ngày\|sáng\|chiều\|nửa ngày) · Phạt 1.200.000 ₫; dòng tổng |
ngày Chờ duyệt không vào danh sách |
| Tăng ca | liệt kê các ngày OT đã duyệt: thứ · dd/mm/yyyy, từ – đến, số giờ; dòng tổng "Tổng giờ OT" |
OT bị từ chối / chưa duyệt không tính |
Bấm 1 dòng trong sheet: đã có đơn → mở chi tiết đơn; chưa có đơn → đóng sheet, mở chi tiết ngày tương ứng ở lịch.
Bottom sheet chi tiết đơn (dùng chung với FR-11): icon + tên loại + ngày/buổi + chip trạng thái · danh sách dòng key–value (ngày, giờ, chế độ, loại lý do, lý do…) · mục File đính kèm (ảnh/video hiện ô xem trước, tệp hiện thẻ tên + đuôi; trống thì ghi "Trống") · mục Tiến trình duyệt.
Tiến trình duyệt thay cho dòng \"Người phê duyệt\" / \"Trạng thái duyệt\" — chốt 27/08/2026
Bảng key–value không chứa dòng Người phê duyệt và Trạng thái duyệt (trạng thái đã có ở chip trên đầu sheet). Hai thông tin đó gộp vào mục Tiến trình duyệt ở cuối sheet: mỗi bên duyệt 1 dòng — icon trạng thái · tên bước (Quản lý trực tiếp duyệt / Nhân sự) · tên người duyệt (dòng phụ, chữ nghiêng) · kết quả (Chờ duyệt / Đã duyệt / Từ chối). Đủ 2 bước cho mọi loại đơn, cả hai khối (BR-CC-10b). Nếu kết quả duyệt có ghi chú kèm (vd "phiên 2 được tính 3g30") thì hiện thành 1 dòng chú thích ngay dưới tiến trình.
Dữ liệu mẫu để Dev đối chiếu (tháng 6/2026, hôm nay 17/06)
Mockup cài sẵn các tình huống: ngày có 2 sự kiện trong cùng ngày (02/06 đi muộn + về sớm, 04/06 nghỉ nửa ngày + về sớm), nghỉ có lương đã duyệt (18/06 → vẫn đủ công), nghỉ bị từ chối (09/06 → coi như vắng, bị phạt), quên chấm ra (12/06 → công "—"), tăng ca đã duyệt (11/06), ngày tương lai đã đăng ký nghỉ (22/06 → không phạt).
FR-10. Công tháng — Khối Công trường¶
File:
cong-thang-cong-truong.html— nhận?role=hr,?nv=<tên>Quyền: như FR-09
Bố cục giống hệt FR-09, khác ở phần nghiệp vụ:
| Điểm | Văn phòng (FR-09) | Công trường (FR-10) |
|---|---|---|
| Tiêu đề thẻ tổng | "Tổng công tháng M · YYYY" | thêm tên dự án — vd "… · Dự án Đông Anh" |
| 3 ô đếm | Lần đi muộn (có tiền phạt) · Ngày nghỉ (có tiền phạt) · Giờ tăng ca | Ngày thiếu giờ (không có tiền phạt) · Ngày nghỉ (có tiền phạt) · Giờ tăng ca |
| Sheet thứ nhất | "Đi muộn — Tháng M" | "Thiếu giờ công" — liệt kê ngày có tổng giờ các phiên chưa đủ định mức ngày |
| Chi tiết ngày | có thể chia buổi sáng / buổi chiều; hiện 1 bản ghi Giờ vào / Giờ ra | ✦ không chia buổi; hiện bảng phiên — cột trái mỗi phiên 1 dòng Giờ vào → Giờ ra (không cột thời lượng), cột phải là ô gộp hiện số công của ngày (tính trên tổng các phiên); không có dòng Tổng giờ công, Định mức ngày, cũng không có số công cỡ lớn ở đầu (sửa 20/08/2026 — xem FR-CTP-03) |
| ✦ Số phiên / ngày | Đúng 1 — chấm ra là khoá | Tối đa 2 — phiên 1 trước nghỉ trưa, phiên 2 sau nghỉ trưa; đóng phiên 2 là khoá nút |
| ✦ Khoảng giữa hai phiên | — | Mặc định là nghỉ giữa ca / nghỉ trưa: không tính công và không hiển thị dòng nào |
| ✦ Quên chấm công | thiếu 1 trong 2 mốc của phiên duy nhất | chỉ xảy ra ở phiên cuối và luôn là quên chấm ra — phiên đó hiện Giờ ra —, nhãn ngày Quên chấm công như cũ |
| ✦ Giờ của phiên hở mốc | — | Không được tính công; các phiên đã đóng vẫn cộng bình thường. Chỉ khi đơn giải trình được duyệt (bổ sung giờ ra) thì phần giờ đó mới vào tổng và ngày mới chốt công — xem BR-CTP-04 |
| Chú giải | 4 mục màu + 2 mục chấm góc | 4 mục màu (không có khối chấm góc riêng) |
| Nút tạo đơn ✦ | "Giải trình / Đăng ký" → ?khoi=vp |
giống hệt: "Giải trình / Đăng ký" → ?khoi=ct, cùng kiểu nút và cùng vị trí — nằm dưới lối vào Đơn của tôi (thống nhất 20/08/2026) |
| Lối vào Đơn của tôi | don-cua-toi.html |
don-cua-toi.html?khoi=ct |
Nhãn nút tạo đơn — đã thống nhất (20/08/2026)
Cả hai khối dùng chung nhãn "Giải trình / Đăng ký", cùng kiểu nút và cùng vị trí: đặt dưới lối vào Đơn của tôi. Nhãn cũ của Công trường "Tạo đơn — Giải trình / Đăng ký nghỉ, OT" đã bỏ.
FR-11. Đơn của tôi¶
File:
don-cua-toi.html— nhận?khoi=ct,?role=hr,?nv=<tên>Quyền: mọi vai trò cho đơn của mình · HR/Quản lý xem đơn nhân viên (chỉ đọc)
Mục đích: danh sách toàn bộ đơn giải trình / đăng ký của một người, lọc theo trạng thái.
| Thành phần | Ghi chú |
|---|---|
| App bar | nút quay lại giữ nguyên tham số khoi / role / nv; tiêu đề "Đơn của tôi" (chế độ HR: "Đơn của nhân viên") |
| Bộ lọc trạng thái | 4 chip: Tất cả · Chờ duyệt · Đã duyệt · Từ chối |
| Dòng đếm | "N đơn" theo bộ lọc đang chọn |
| Item đơn | icon theo loại · tên loại · ngày/khoảng ngày · chip trạng thái; nhóm theo tháng |
| Trạng thái rỗng | "Không có đơn nào — Chưa có đơn ở trạng thái này." |
| Vuốt ngang một đơn Chờ duyệt | lộ 2 nút Sửa (→ FR-08 ?edit=) và Xoá (confirm trước khi xoá) — chỉ nhân viên, chế độ HR không vuốt được |
| Chạm 1 đơn | mở bottom sheet chi tiết đơn (cùng bố cục với FR-09) |
FR-12. Trạng thái nhân sự trong ngày¶
File:
trang-thai-nhan-su.html· Quyền: HR (full) · Quản lý (phạm vi mình) — Nhân viên không
Mục đích: nhìn một ngày bất kỳ, biết ai đang làm việc / nghỉ / công tác / chưa chấm công, kèm địa điểm chấm và cảnh báo bất thường.
5 trạng thái trong ngày (khác với trạng thái công ở §4.2):
| Trạng thái | Có đơn kèm theo? |
|---|---|
| Đang làm việc | không |
| Nghỉ | có (đơn nghỉ) |
| Đi công tác | có (đơn công tác) |
| Chưa chấm công | không |
| Nghỉ việc | không — nhân sự đã nghỉ việc từ ngày X |
| Thành phần | Ghi chú |
|---|---|
| Thanh ngày | ‹ › đổi ngày + nút mở lịch; không đi quá ngày hôm nay |
| Lưới tóm tắt 3 cột | 5 ô đếm theo 5 trạng thái — bấm để lọc danh sách |
| Tìm kiếm | "Tìm nhân sự…" |
| Lọc đơn vị | dropdown: Tất cả · nhóm Công trường (Đông Anh / Linh Đàm / Yên Bái) · nhóm Văn phòng (Phòng IT / Hành chính – Kế toán / Phòng Kỹ thuật) |
| Dòng đếm + nút | "N / M nhân sự · lọc: |
| Item nhân sự | tên · đơn vị · giờ vào/ra · địa điểm chấm công · chip trạng thái |
| Cảnh báo trên item | vd "Đi muộn 11 phút — chưa có đơn giải trình", "Chấm ngoài phạm vi 180 m — đã ghi nhận kèm ảnh, chờ Nhân sự xác nhận" |
| Chi tiết 1 người | mở panel: nếu có đơn → hiện mã đơn · loại · nơi · từ–đến · nội dung · trạng thái · người duyệt; nút Nhắc chấm công cho người chưa chấm; lối sang FR-04 |
FR-13. Thông báo & Cài đặt thông báo¶
File:
thong-bao-cham-cong.html·cai-dat-thong-bao.html· Quyền: mọi vai trò
FR-13a. Thông báo — chip lọc Tất cả / Chưa đọc (N); nút đánh dấu tất cả đã đọc; lối vào Cài đặt thông báo; danh sách nhóm theo Hôm nay / Hôm qua / …, mỗi item: icon · tiêu đề · nội dung · giờ · chấm "Chưa đọc". Bấm item → mở màn liên quan (vd cảnh báo đi muộn → chi tiết thống kê; nhắc tan ca → màn Chấm công).
Loại thông báo mẫu: Cảnh báo đi muộn · Sắp đến giờ tan ca · kết quả duyệt đơn.
FR-13b. Cài đặt thông báo — nhóm "Chấm công" với các công tắc bật/tắt từng loại nhắc.
FR-14. Cá nhân · Hồ sơ · Đổi mật khẩu¶
File:
nguoi-dung.html·chinh-sua-ho-so.html·doi-mat-khau.html· Quyền: mọi vai trò, chỉ cho bản thân
nguoi-dung.html— thẻ hồ sơ người đang đăng nhập (avatar + chấm trạng thái + tên + "chức vụ · phòng ban") · nút Chỉnh sửa hồ sơ · nhóm Thông tin nhân sự (mã NV, phòng ban, chức vụ) · nhóm Thông tin liên hệ (email, điện thoại) · nhóm Tài khoản (Đổi mật khẩu, Cài đặt thông báo).chinh-sua-ho-so.html— sửa thông tin liên hệ & ảnh đại diện của chính mình.doi-mat-khau.html— đổi mật khẩu.
FR-15. Chọn vai trò (màn demo)¶
File:
chon-vai-tro.html· Không thuộc bản chạy thật
✦ Màn cửa vào để demo cho Dev: 3 thẻ vai trò + bảng so sánh quyền.
| Thẻ | Mở màn | Khác biệt nghiệp vụ |
|---|---|---|
| Nhân viên — Văn phòng | cong-thang.html |
Ca chuẩn 08:00–17:30 · 1 phiên / ngày · chi tiết ngày hiện 1 bản ghi Giờ vào / Giờ ra |
| ✦ Nhân viên — Công trường | cong-thang-cong-truong.html |
Không khung giờ · tối đa 2 phiên / ngày · chi tiết ngày hiện danh sách phiên + tổng giờ công · đủ 8g = 1 công |
| HR / Nhân sự | nhan-su.html |
Chọn người → chi tiết chấm công (?role=hr&nv=), chỉ xem |
Màn tự ghi rõ: "Bản chạy thật sẽ tự nhận vai trò theo tài khoản đăng nhập" — nên lựa chọn khối
ở đây chỉ là công tắc demo, bản thật lấy khối của nhân viên từ hồ sơ (NhanVien.khoi). Dev không hiện thực màn này.
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 |
| khoi | ENUM | Khối (Văn phòng / Công trường) |
| 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 |
| quan_ly_truc_tiep_id | FK | Quản lý trực tiếp |
| quota_phep_nam | INTEGER | Mẫu 12 ngày/năm |
| nghi_viec_tu | DATE | Dùng ở FR-12 |
| 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) |
Tham số nghiệp vụ theo khối / đơn vị — thay cho hằng số hard-code trong mockup
| Cột | Kiểu | Mô tả |
|---|---|---|
| pham_vi | ENUM | khoi | don_vi |
| gio_vao_chuan | TIME | VP 08:00 · CT 07:00 |
| gio_ra_chuan | TIME | VP 17:30 · CT 16:30 |
| moc_di_muon | TIME | 08:10 |
| nghi_trua_phut | INTEGER | VP 60 · CT 0 |
| dinh_muc_phut | INTEGER | ✦ 480 (8g làm thực) cho cả hai khối. VP: trừ khung nghỉ trưa trước khi so. CT: ca xuyên trưa cộng thêm thời lượng khung nghỉ trưa → 570 (9,5g) |
| quota_cong_thang | INTEGER | Mẫu 25 |
| tien_phat_di_muon | INTEGER | Mẫu 50.000 ₫ |
| tien_phat_nghi | INTEGER | Mẫu 1.200.000 ₫ |
| don_gia_tang_ca | INTEGER | Mẫu 60.000 ₫/giờ |
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 ngày (theo khối — §4.2) |
| nhom_hien_thi | ENUM | Nhóm hiển thị (§4.3) |
| cong_ngay | DECIMAL | Null khi chưa chốt (thiếu mốc chấm) |
| phut_tang_ca | INTEGER | Chỉ giờ đã duyệt mới tính tiền |
| tien_phat | INTEGER | §4.5 |
| do_khop_mat | DECIMAL | Hiển thị "Khớp N%" ở biên nhận (§4.8) |
| vi_do | DECIMAL | GPS lúc chấm |
| kinh_do | DECIMAL | GPS lúc chấm |
| trong_vung | BOOLEAN | Kèm khoảng cách lệch nếu false |
| anh_mat | TEXT | Đường dẫn ảnh |
1 đơn giải trình/đăng ký của 1 nhân viên (FR-08, FR-11)
| Cột | Kiểu | Mô tả |
|---|---|---|
| id | PK | Mã đơn (mẫu GT-2607) |
| ma_nv | FK | Người gửi (tự giải trình cho bản thân) |
| loai | ENUM | ✦ 8 loại, lọc theo khối (§4.6) |
| loai_con | ENUM | Phân nhánh trong loại |
| ly_do_loai | ENUM | Ảnh hưởng việc có được cộng lại công hay không |
| tu_thoi_diem | DATETIME | Tuỳ loại |
| den_thoi_diem | DATETIME | Tuỳ loại |
| buoi_bat_dau | ENUM | Dùng để tính 0,5 công |
| buoi_ket_thuc | ENUM | Dùng để tính 0,5 công |
| so_cong | DECIMAL | Tối thiểu 0,5 |
| gio_vao_thuc_te | TIME | Null nếu không nhập |
| gio_ra_thuc_te | TIME | Null nếu không nhập |
| noi_cong_tac | STRING | Chỉ loại Đi công tác |
| ly_do | TEXT | Bắt buộc |
| file_dinh_kem | TEXT | Ảnh / video / tệp |
| trang_thai | ENUM | Chờ duyệt / Đã duyệt / Từ chối |
| ly_do_tu_choi | TEXT | Chỉ có khi trạng thái = Từ chối |
Tiến trình duyệt — mỗi bên duyệt 1 dòng (hiển thị ở mục "Tiến trình duyệt")
| Cột | Kiểu | Mô tả |
|---|---|---|
| don_id | FK | Đơn giải trình |
| ben_duyet | ENUM | Bên phải duyệt |
| nguoi_duyet_id | FK | Người duyệt cụ thể |
| ket_qua | ENUM | Kết quả của bước này |
| thoi_diem | DATETIME | Null khi chưa duyệt |
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).
- Tham số nghiệp vụ cấu hình được: mọi mốc giờ, định mức, đơn giá phạt/tăng ca đọc từ Thiết lập, không hard-code (xem §4.1, §4.5).
- Tính tiền ở server: app chỉ hiển thị số công, tiền phạt, tiền tăng ca — không tự tính lại.
- 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.
- Khả dụng: mọi ô ngày, ô đếm, item đơn đều là vùng chạm ≥ 44 px; có
aria-labelmô tả trạng thái ngày (mockup đã làm) — bản Flutter giữ tương đương bằngSemantics.
8. Vấn đề mở — cần BA chốt trước khi Dev code¶
7 điểm phát sinh khi đối chiếu SRS với mockup mới
- Điều kiện tính phạt khi đơn đang "Chờ duyệt" chưa thống nhất — đi muộn đang chờ duyệt bị tính phạt, nghỉ đang chờ duyệt chưa bị tính. Đề xuất: chờ duyệt thì chưa tính phạt cho cả hai, chốt lại khi có kết quả duyệt. Xem §4.5.
- ~~Người duyệt: 1 bên hay 2 bên?~~ — đã chốt 03/08/2026: 2 bên = Quản lý trực tiếp + Nhân sự (HR), duyệt song song, cần đủ 2 bên, mọi loại đơn, không tách theo khối (chỉ huy trưởng công trường cũng là quản lý trực tiếp). Sheet chi tiết đơn trong mockup đã sửa 27/08/2026 — hiện đủ 2 bước kèm tên người duyệt, ở cả hai khối. Xem §4.6.
- Chấm công ngoài phạm vi: chặn cứng hay ghi nhận chờ duyệt? — §4.7 mục 3 nói chặn hoàn toàn, nhưng FR-12 có dữ liệu "Chấm ngoài phạm vi 180 m — đã ghi nhận kèm ảnh, chờ Nhân sự xác nhận". Hai luồng này loại trừ nhau.
- Giữ bộ màn Thống kê nào? —
thong-ke.html(FR-07a, mới) và bộthong-ke-cham-cong-hr.html+ chi tiết phòng ban/dự án (FR-07c–e, cũ) trùng chức năng. Đề xuất: giữ FR-07a làm màn chính, giữthong-ke-theo-ngay/thong-ke-theo-trang-thailàm màn con, bỏ hub + 2 màn chi tiết cũ. - ~~Nhãn nút tạo đơn khác nhau giữa 2 khối~~ — đã chốt 20/08/2026: cả hai khối dùng "Giải trình / Đăng ký", đặt dưới lối vào Đơn của tôi.
- Màn Kiểm tra vị trí có hiện kết quả chống giả mạo & toạ độ không? — phương án A (đã chọn) chỉ hiện Khoảng cách + Độ chính xác GPS; 2 mục "Chống vị trí giả mạo" và "Toạ độ hiện tại" chỉ có ở phương án B/C đã loại. Nghiệp vụ vẫn bắt buộc kiểm tra mock location — cần chốt có hiển thị lên UI hay chạy ngầm, nếu hiển thị thì BA bổ sung vào mockup A. Xem §5 FR-05b.
- Nhận diện khuôn mặt dưới ngưỡng thì làm gì? — mockup
cham-cong-khuon-mat.htmlchỉ dựng luồng thành công, chưa có màn/thông báo khi không khớp. Cần chốt: thông báo hiển thị, số lần thử tối đa, và hành vi sau khi hết lượt (báo liên hệ HR? mở luồng chấm công thủ công?). Kèm theo: cách quy đổi vector đặc trưng ra % khớp và ngưỡng tối thiểu (§4.8) — phần này Dev/kỹ thuật xác nhận theo SDK.
Đã chốt từ các bản trước — vẫn giữ nguyên
- Bán kính geofence: không có giá trị mặc định, mỗi vị trí tự set (§5 FR-06).
- Nền tảng so khớp khuôn mặt: dùng vector đặc trưng (face embedding); thông số ngưỡng do Dev/kỹ thuật xác nhận theo SDK được chọn (chi tiết còn mở — mục 7 ở trên).
- Mốc 08:10 (Văn phòng): vào trước 08:10 không tính muộn/không phạt; từ 08:10 tính muộn (tính từ 08:10) và bắt đầu phạt. Công trường không có khái niệm đi muộn.
- "Xin chấm công từ xa": bỏ hẳn, không làm.
- Đơn vị đếm thống kê: "lượt" gom theo "ngày".
- Nhân viên không xem Tab Thông tin nhân sự (FR-04) — hồ sơ cá nhân xem ở FR-14.
- Tạo tài khoản / hồ sơ nhân sự: làm ở web HCNS, không có trong app (FR-02).
- Màn duyệt đơn: ở web HCNS, không thuộc app này.
- Chấm góc lịch 2 màu (Chưa giải trình / Đã giải trình) — không cần đủ 4 màu như web.
- Đăng nhập & Trang chủ module: tách khỏi phạm vi SRS này.
Việc dọn mockup còn tồn (BA làm)
giai-trinh-thanh-cong.html— không còn lối vào nào, cân nhắc xoá.nhan-su-checkin-a.html— chỉ còn vào được từnhan-su-thong-tin-b.html, chức năng đã bị Công tháng thay thế.- Mục lục
pace-1/index.htmlchưa liệt kê các màn mới:cong-thang.html,cong-thang-cong-truong.html,don-cua-toi.html,giai-trinh-cong-form.html,chon-vai-tro.html,trang-thai-nhan-su.html. - Các file nháp tiền tố
_(bản so sánh phương án) đã được dọn sau khi chốt và áp vào mockup chính — thư mụccham-cong/không còn file_*.html.
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 sự / Trạng thái nhân sự / Thống kê Then chỉ thấy nhân sự & dữ liệu 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 module Chấm công Then vào thẳng Công tháng của bản thân; không thấy Danh sách nhân sự, Trạng thái nhân sự, Thống kê, Thêm vị trí.
AC-3 — HR xem công tháng nhân viên ở chế độ chỉ đọc
Given HR mở Danh sách nhân sự → chọn 1 nhân viên khối Văn phòng Then mở Công tháng của người đó với tiêu đề = tên nhân viên + phụ đề "HR đang xem · chỉ đọc"; không có nút "Giải trình / Đăng ký", không có lối vào "Đơn của tôi", không vuốt được để Sửa/Xoá đơn; nút quay lại về Danh sách nhân sự.
Trường hợp biên — nhân viên thuộc khối Công trường → mở đúng màn
cong-thang-cong-truong, không phải màn Văn phòng.
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 (chip "Khớp N%"); trạng thái ca → "Đang trong ca".
Chưa nghiệm thu được — nhánh khuôn mặt dưới ngưỡng khớp chưa có trong mockup, chờ chốt ở §8 mục 7.
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á, chỉ có nút "Thử lại"; không tạo bản ghi. (Phụ thuộc §8 mục 3.)
AC-6 — Trạng thái & công của ngày, khối Văn phòng
✦ Given ca 08:00–17:30, mốc muộn 08:10, định mức 8 giờ làm thực sau khi trừ khung nghỉ trưa do HR set (mẫu 1,5 giờ → giờ thô cần 9,5 giờ) When vào 08:22, ra 16:40 Then ngày đó có 2 sự kiện riêng: "Đi muộn — Vào 08:22 · muộn 12 phút" và "Về sớm — Ra 16:40 · sớm 50 phút"; ô lịch nhóm Thiếu định mức (vàng); công ngày =
(16:40 − 08:22 − nghỉ trưa) ÷ 8glàm tròn 1 chữ số thập phân — với nghỉ trưa 1,5g thì =(8g18 − 1g30) ÷ 8g ≈ 0,9.Trường hợp biên — vào 08:08: không tính đi muộn, không phạt.
Trường hợp biên — chỉ check-in, không check-out → trạng thái "Quên chấm công", công ngày hiển thị "—" kèm cảnh báo "Chưa chốt công".
Trường hợp biên — nghỉ phép năm đã duyệt cả ngày → ô lịch xanh (Đủ định mức), công ngày = 1.
Trường hợp biên — nghỉ phép năm bị từ chối → ô lịch xám (Không công), công = 0, bị tính phạt ngày nghỉ.
AC-7 — Trạng thái & công của ngày, khối Công trường
✦ Given định mức 8 giờ tính trên tổng các phiên (ca xuyên trưa thì 9,5 giờ), không có khung giờ — chấm giờ nào trong ngày cũng hợp lệ, không có khái niệm đi muộn When phiên 1
07:00 – 11:30(4g30) và phiên 213:00 – 16:00(3g00) → tổng 7g30 Then trạng thái = "Thiếu giờ công" (7,5 < 8 giờ), ô lịch vàng, công ngày =7,5 ÷ 8≈ 0,9; giờ nghỉ trưa11:30 – 13:00không được tính; không phát sinh phạt đi muộn; loại đơn giải trình gợi ý = "Thiếu giờ công".✦ Trường hợp biên — phiên
04:30 – 08:30+18:00 – 22:00(tổng 8g) → Đủ công, vì Công trường không còn ràng buộc khung giờ.✦ Trường hợp biên — phiên chiều chỉ có mốc vào → cả ngày = Quên chấm công, công
—.✦ Trường hợp biên — chấm 1 lượt
07:00 – 16:00(bao trọn khung nghỉ trưa) → 9g < 9,5g → Thiếu giờ công; chấm07:00 – 17:00→ 10g ≥ 9,5g → Đủ công.✦ Trường hợp biên — phiên dưới 5 phút (bấm nhầm) → bỏ hẳn, không cộng giờ và không hiện ở danh sách phiên.
AC-8 — Tiền phạt & tiền tăng ca ở thẻ tổng tháng
Given trong tháng có 3 lần đi muộn chưa được duyệt và 2 ngày nghỉ bị từ chối, tổng OT đã duyệt 5 giờ Then ô "Lần đi muộn" hiện
3và− 150.000 ₫; ô "Ngày nghỉ" hiện tiền phạt tương ứng; ô "Giờ tăng ca" hiện5g 00p.Trường hợp biên — ngày tương lai đã có đơn bị từ chối: không cộng vào tiền phạt.
Trường hợp biên — mở sheet "Đi muộn": danh sách chỉ có các lần bị phạt, không có dòng "Về sớm" nào.
AC-9 — Hạn giải trình: hết tháng
Given trong tháng hiện tại có ngày thiếu định mức chưa có đơn When mở chi tiết ngày hôm nay → Then có nút "Giải trình ngay", mở form đã chọn sẵn đúng loại. When mở chi tiết một ngày đã qua nhưng cùng tháng chưa có đơn → Then vẫn có nút "Giải trình ngay". When mở chi tiết một ngày thuộc tháng trước chưa có đơn → Then hiện nhãn "Đã quá hạn", không cho tạo đơn.
AC-10 — Loại đơn lọc theo khối
Given nhân viên khối Công trường mở form giải trình Then danh sách loại có 6 lựa chọn, không có Nghỉ phép năm và Đi muộn / Về sớm, có Thiếu giờ công.
Given nhân viên khối Văn phòng → Then có 7 lựa chọn, không có Thiếu giờ công.
AC-11 — Sửa / xoá đơn Chờ duyệt
Given nhân viên có 1 đơn trạng thái Chờ duyệt ở màn Đơn của tôi When vuốt ngang đơn đó → Then lộ 2 nút Sửa và Xoá; bấm Sửa mở form ở chế độ sửa (tiêu đề "Sửa đơn giải trình", nút "Cập nhật đơn"); bấm Xoá phải xác nhận trước khi xoá.
Trường hợp biên — đơn Đã duyệt hoặc Từ chối: không vuốt ra được nút nào.
Trường hợp biên — người xem là HR (
?role=hr): không vuốt được, tiêu đề màn là "Đơn của nhân viên".
AC-12 — Trạng thái nhân sự trong ngày
Given HR mở màn Trạng thái nhân sự cho ngày hôm nay Then lưới 5 ô đếm đúng số người theo 5 trạng thái; bấm 1 ô thì danh sách chỉ còn người thuộc trạng thái đó và dòng đếm ghi "N / M nhân sự · lọc:
"; nút Nhắc chấm công chỉ hiện khi còn người Chưa chấm công; không chọn được ngày sau hôm nay. AC-13 — 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 (không tự điền giá trị mặc định).
Phụ lục A — Bản đồ màn ↔ file mockup¶
Tất cả file thuộc
ui-mockups/longdo-erp/app-longdo-erp/pace-1/cham-cong/.
Mã Màn File mockup Ghi chú FR-01 Danh sách nhân sự nhan-su.htmlFR-02 Thêm mới nhân viên — Đã chuyển sang web HCNS FR-03 Xem chấm công của 1 nhân viên cong-thang.html?role=hr·cong-thang-cong-truong.html?role=hrthay nhan-su-checkin-a.htmlFR-04 Thông tin nhân sự nhan-su-thong-tin-b.htmlvào từ FR-12 FR-05a Chấm công cá nhân cham-cong.htmlFR-05b Kiểm tra vị trí (Phương án A) kiem-tra-vi-tri-a.html-b/-ckhông dùngFR-05c Ngoài phạm vi kiem-tra-vi-tri-ngoai-pham-vi.htmlFR-05d Nhận diện khuôn mặt cham-cong-khuon-mat.htmlFR-05e Chấm công thành công cham-cong-thanh-cong.htmlFR-06 Thêm vị trí chấm công them-vi-tri-cham-cong.htmlchỉ HR FR-07a Thống kê (màn chính) thong-ke.htmlFR-07b Chi tiết thống kê 1 nhân sự chi-tiet-thong-ke.htmlFR-07c Hub thống kê theo đơn vị thong-ke-cham-cong-hr.htmlbộ cũ — chờ chốt §8 mục 4 FR-07c Chi tiết phòng ban / dự án thong-ke-phong-ban-chi-tiet.html·thong-ke-du-an-chi-tiet.htmlbộ cũ FR-07d Thống kê theo ngày thong-ke-theo-ngay.htmlFR-07e Thống kê theo trạng thái thong-ke-theo-trang-thai.htmlnhận ?status=&from=&to=FR-08 Form giải trình / đăng ký giai-trinh-cong-form.html?khoi=?loai=?edit=FR-09 Công tháng — Văn phòng cong-thang.htmlmàn trung tâm FR-10 Công tháng — Công trường cong-thang-cong-truong.htmlFR-11 Đơn của tôi don-cua-toi.html?khoi=?role=?nv=FR-12 Trạng thái nhân sự trong ngày trang-thai-nhan-su.htmlFR-13 Thông báo · Cài đặt thông báo thong-bao-cham-cong.html·cai-dat-thong-bao.htmlFR-14 Cá nhân · Hồ sơ · Đổi mật khẩu nguoi-dung.html·chinh-sua-ho-so.html·doi-mat-khau.htmlFR-15 Chọn vai trò chon-vai-tro.htmlchỉ demo, không code File không thuộc phạm vi SRS này:
trang-chu.html(dashboard module — tài liệu khác) ·giai-trinh-thanh-cong.html(không còn lối vào) ·nhan-su-checkin-a.html(đã bị FR-09/FR-10 thay thế) ·thong-ke-danh-sach-cac-cach.html(công cụ so layout nội bộ) ·kiem-tra-vi-tri-b.html/-c.html(phương án không chọn) · các file tiền tố_(bản nháp nội bộ).