← Quay lại mục lục

Bài 27 — Đăng ký nghỉ phép (Manager → HR)

Workflow phê duyệt 2 cấp: nhân viên submit → manager duyệt cấp 1 → HR duyệt cấp 2. Test state machine, balance integrity, overlap check.

Khó #system #multi-actor #state-machine #approval #leave #date-validation

🏢 Bài 27: Đăng ký nghỉ phép — Manager → HR phê duyệt

Luồng phê duyệt 2 cấp: nhân viên submit yêu cầu → manager duyệt cấp 1 → HR duyệt cấp 2. Mỗi yêu cầu đi qua nhiều state với nhiều actor — đây là loại flow rất phổ biến trong hệ thống nội bộ doanh nghiệp.

📊 Sơ đồ flow

    Employee submit                Manager approve         HR approve
    ┌───────────┐                  ┌─────────────┐         ┌──────────┐
    │ pending_  │ ───────────────→ │ pending_hr  │ ──────→ │ approved │ (final)
    │ manager   │                  │             │         └──────────┘
    └─────┬─────┘                  └──────┬──────┘
          │ Manager reject                │ HR reject
          ↓                                ↓
    ┌──────────────────┐            ┌──────────────────┐
    │ rejected_by_     │            │ rejected_by_hr   │
    │ manager (final)  │            │ (final)          │
    └──────────────────┘            └──────────────────┘

📋 Đặc tả từng màn hình

🟦 Screen 1 — Đăng ký yêu cầu nghỉ phép

FieldYêu cầu
Nhân viênBắt buộc, chọn từ dropdown.
Loại phépannual (phép năm) | sick (phép ốm) | personal (phép cá nhân).
Từ ngàyBắt buộc. Phải ≥ hôm nay (không xin nghỉ ngày quá khứ).
Đến ngàyBắt buộc. Phải ≥ "Từ ngày".
Lý doBắt buộc, ≥ 10 ký tự.
Số ngàyTính tự động: (to_date - from_date) + 1 (inclusive cả 2 đầu). VD: 25/4 → 27/4 = 3 ngày.

Quy tắc balance:

  • Mỗi nhân viên có 12 ngày phép năm. Sick / personal KHÔNG trừ balance.
  • Khi annual: số ngày yêu cầu phải ≤ balance còn lại. Nếu vượt → báo lỗi.
  • Balance chỉ trừ khi HR approve cuối cùng. Khi submit / pending → balance giữ nguyên.
  • Nếu manager hoặc HR reject → balance giữ nguyên (không phải hoàn lại vì chưa trừ).

Quy tắc overlap: KHÔNG được phép xin nghỉ chồng đè với 1 request đã approved hoặc đang pending_* của cùng nhân viên.

Submit thành công → hiển thị message Yêu cầu nghỉ phép đã được gửi thành công!, request mới có status pending_manager.

🟨 Screen 2 — Yêu cầu của tôi

  • Filter theo nhân viên (dropdown 3 nhân viên).
  • Hiển thị tất cả yêu cầu của nhân viên đó với status badge.
  • Click vào 1 yêu cầu → đi đến Screen 5 (chi tiết + lịch sử action).

🟧 Screen 3 — Manager Queue

  • Hiển thị danh sách yêu cầu có status = pending_manager.
  • Mỗi dòng: nhân viên, loại phép, từ-đến, số ngày, lý do, balance còn lại.
  • ✅ Approve → chuyển status sang pending_hr.
  • ❌ Reject → chuyển status sang rejected_by_manager (final).
  • Sau khi xử lý, request biến mất khỏi queue.

🟪 Screen 4 — HR Queue

  • Hiển thị danh sách yêu cầu có status = pending_hr (đã qua manager).
  • ✅ Approve → status thành approved (final). Trừ balance nếu là annual leave.
  • ❌ Reject → status thành rejected_by_hr (final). Balance giữ nguyên.

🟩 Screen 5 — Chi tiết yêu cầu

  • Hiển thị toàn bộ thông tin yêu cầu + lịch sử actions (created → manager_action → hr_action).
  • Mỗi dòng lịch sử có: thời gian, actor, action, comment.

🎯 Test scenarios cần cover

  1. Happy path: Submit → manager approve → HR approve → status = approved, balance giảm.
  2. Manager reject: Submit → manager reject → status = rejected_by_manager. Kiểm tra request KHÔNG xuất hiện trong HR queue.
  3. HR reject: Submit → manager approve → HR reject → status = rejected_by_hr. Balance KHÔNG bị trừ.
  4. Past date: Submit từ ngày = hôm qua → phải bị chặn.
  5. Days count: Submit 25/4 → 27/4 → kiểm tra hệ thống tính 3 ngày (chứ không phải 2).
  6. Overlap: Submit yêu cầu 1/5 → 5/5 (approved). Submit tiếp 3/5 → 7/5 → phải bị chặn.
  7. Balance integrity: Submit 5 ngày annual → quan sát balance ở tab "Đăng ký" trước/sau submit. Theo spec phải KHÔNG đổi cho đến khi HR approve.
  8. Reject + balance: Submit → manager reject → balance phải = ban đầu (không bị trừ nhầm).

💡 Kỹ thuật test áp dụng

  • State machine testing: 6 state, ~5 transitions hợp lệ. Vẽ state diagram và verify từng transition.
  • Multi-actor flow: Action của manager phải đẩy đúng vào queue của HR (không leak / không miss).
  • Boundary value: from_date = today, today-1, today+1; days = 0, 1, 12, 13.
  • Decision table: Tổ hợp (leave_type × balance × days_request) → expected behavior.
  • Time-based: Date validation, ngày trong quá khứ.
  • Data integrity: Balance trước/sau từng action.

📝 Template bug report

STTMô tảBước tái hiệnThực tếMong đợiMức độ
1(học viên điền)
⚠️ Lưu ý: Bài này có cài cắm 6 bug. Đặc biệt chú ý các bug về chuyển trạng thái giữa manager → HR, và tính toán balance qua nhiều bước.
🔐

Vui lòng đăng nhập để nộp bài.

Đăng nhập
🔐

Tab dành cho giảng viên

Tab này chứa danh sách các lỗi đã cài cắm trong form. Vui lòng nhập mã giảng viên để mở khóa. Mã sẽ ghi nhớ trong phiên làm việc — chỉ cần nhập 1 lần cho cả 3 bài.