Mục lục
Hệ thống Chấm công - Tài liệu Kỹ thuật
Tổng quan
Hệ thống xử lý file Excel chấm công và tạo báo cáo chi tiết với nhiều trường hợp xử lý phức tạp.
Các trường hợp xử lý khi tạo báo cáo
1. XỬ LÝ ĐI TRỄ (LATE ARRIVALS)
1.1 Trễ dưới 20 phút
- Điều kiện: Trễ từ 4-20 phút so với giờ vào 6:00
- Xử lý: Tăng biến
lateUnder20 - Hiển thị: "Trễ X phút" với màu cam
- Ghi chú: Trễ ≤ 3 phút được bỏ qua
1.2 Trễ trên 20 phút
- Điều kiện: Trễ > 20 phút so với giờ vào 6:00
- Xử lý: Tăng biến
lateOver20 - Hiển thị: "Trễ X phút" với màu đỏ
1.3 Trễ quá 2 tiếng
- Điều kiện: Trễ > 120 phút (2 tiếng)
- Xử lý: Tính là nghỉ nửa ngày
- Hiển thị: "Nửa ngày (đi trễ > 2 tiếng)"
- Ghi chú: Dừng xử lý ngày đó, không tính tăng ca
2. XỬ LÝ TĂNG CA (OVERTIME)
2.1 Tăng ca buổi sáng
- Điều kiện: Vào sớm trước 6:00
- Công thức:
morningOvertime = (6:00 - giờ_vào) / 60 phút - Ví dụ: Vào 5:30 → tăng ca 30 phút
2.2 Tăng ca buổi chiều
- Điều kiện: Ra muộn sau 17:00
- Công thức:
eveningOvertime = (giờ_ra - 17:00) / 60 phút - Ví dụ: Ra 18:30 → tăng ca 90 phút
2.3 Ngưỡng ra sớm
- Ra trước 15:00: Tính là nửa ngày (không tăng ca)
- Ra 15:00-17:00: Đủ giờ (không tăng ca, không trừ điểm)
- Ra sau 17:00: Tính tăng ca
2.4 Trừ thời gian trễ khỏi tăng ca ⭐
- QUAN TRỌNG: Nếu có trễ > 3 phút và có tăng ca
- Công thức:
overtime = max(0, overtime - lateMinutes) - Ví dụ: Tăng ca 60 phút, trễ 20 phút → tăng ca thực tế = 40 phút
- Mục đích: Tránh tính trùng thời gian trễ và tăng ca
3. XỬ LÝ NGHỈ PHÉP (DAYS OFF)
3.1 Nghỉ hoàn toàn
- Điều kiện: Thiếu cả check-in và check-out
- Xử lý:
off = 'full' - Hiển thị: "Nghỉ phép"
- Ghi chú: Không áp dụng cho chủ nhật
3.2 Nửa ngày
- Điều kiện: Thiếu 1 trong 2 (check-in hoặc check-out)
- Xử lý:
off = 'half' - Hiển thị: "Nửa ngày"
- Ghi chú: Vẫn tính tăng ca nếu có
3.3 Đi trễ quá 2 tiếng
- Xử lý: Tính là nửa ngày
- Hiển thị: "Nửa ngày (đi trễ > 2 tiếng)"
4. XỬ LÝ CHỦ NHẬT (SUNDAY LOGIC)
4.1 Logic phân ca chủ nhật
- Nguyên tắc: Xen kẽ theo tuần từ ngày bắt đầu dữ liệu
- Team bắt đầu: Có thể chọn team1 hoặc team2
- Công thức:
$weeksDiff = floor($daysDiff / 7);
$shouldBeStartTeam = ($weeksDiff % 2 === 0);
4.2 Nghỉ chủ nhật khi phải làm
- Điều kiện: Phải làm nhưng không có check-in/check-out
- Xử lý:
sundayOff = true, tăng sundayOffDays - Hiển thị: "Nghỉ CN" (màu đỏ)
- Ghi chú: Không tính vào ngày nghỉ thường
4.3 Làm chủ nhật khi không phải lịch
- Điều kiện: Không phải làm nhưng có check-in/check-out
- Xử lý:
sundayWork = true, tăng sundayWorkDays - Hiển thị: "Làm CN" (màu xanh)
5. XỬ LÝ THỜI GIAN LÀM VIỆC
5.1 Giờ làm việc chuẩn
- Vào: 6:00
- Ra: 17:00
- Ngưỡng ra sớm: 15:00
5.2 Các trường hợp đặc biệt
- Ra trước 15:00: Nửa ngày
- Ra 15:00-17:00: Đủ giờ (không tăng ca, không trừ)
- Ra sau 17:00: Tăng ca
6. XỬ LÝ HIỂN THỊ BÁO CÁO
6.1 Tổng hợp thống kê
- Tổng tăng ca: Hiển thị giờ/phút thông minh
- Trễ < 20 phút: Số lần
- Trễ > 20 phút: Số lần
- Ngày nghỉ: Số ngày (bao gồm nửa ngày)
- Nghỉ chủ nhật: Số ngày trốn ca
- Làm chủ nhật: Số ngày làm thêm
6.2 Chi tiết từng ngày
- Giờ vào/ra: Hiển thị chính xác
- Trạng thái: Trễ, tăng ca, nghỉ, chủ nhật
- Màu sắc: Phân biệt các trạng thái
- Chủ nhật: Highlight đặc biệt
7. CÁC TRƯỜNG HỢP ĐẶC BIỆT
7.1 Xử lý dữ liệu không đầy đủ
- Thiếu cả vào/ra: Nghỉ hoàn toàn
- Thiếu 1 trong 2: Nửa ngày
- Vẫn tính tăng ca: Nếu có dữ liệu thời gian
7.2 Xử lý ngày tháng
- Tự động trích xuất: Từ file Excel
- Fallback: Tháng hiện tại nếu không trích xuất được
- Hỗ trợ format: DD/MM/YYYY, YYYY-MM-DD, tháng/năm
7.3 Xử lý team
- Phân chia: Theo file phân ca
- Logic xen kẽ: Chủ nhật theo team
- Hiển thị: Badge team trên báo cáo
Cấu trúc dữ liệu
Employee Object
php
[
'name' => 'Tên nhân viên',
'team' => 'team1|team2|null',
'overtime' => 120, // phút
'lateUnder20' => 3, // số lần
'lateOver20' => 1, // số lần
'daysOff' => 2.5, // số ngày
'sundayOffDays' => 1, // số ngày
'sundayWorkDays' => 2, // số ngày
'notes' => 'Ghi chú chi tiết',
'details' => [...] // chi tiết từng ngày
]Day Detail Object
[
'date' => '15/06/2024',
'lateUnder20' => 15, // phút trễ
'lateOver20' => 0,
'overtime' => 60, // phút tăng ca
'off' => 'full|half|', // trạng thái nghỉ
'checkIn' => '06:15',
'checkOut' => '17:30',
'isSunday' => false,
'sundayOff' => false,
'sundayWork' => false
]Các hàm quan trọng
processData($filePath, $teamFilePath, $startTeam)
- Xử lý chính file Excel
- Trả về mảng employees với đầy đủ thông tin
generateReport($data)
- Tạo HTML báo cáo
- Hiển thị thống kê và chi tiết
getSundayTeam($date, $team1, $team2, $startTeam, $firstDataDate)
- Tính toán team làm chủ nhật
- Logic xen kẽ theo tuần
parseTime($timeStr)
- Parse nhiều format thời gian
- Hỗ trợ AM/PM, 24h, có/không giây
Lưu ý quan trọng
1. Trừ thời gian trễ khỏi tăng ca: Đây là logic quan trọng để tránh tính trùng
2. Logic chủ nhật: Phức tạp, cần hiểu rõ team và tuần
3. Xử lý dữ liệu thiếu: Linh hoạt, vẫn tính được tăng ca
4. Hiển thị thông minh: Tự động ẩn giá trị 0, format giờ/phút
5. Bảo mật: Validate file Excel, CSRF protection, sanitize filename
Cài đặt và sử dụng
1. Upload file chấm công (Excel)
2. Upload file phân ca (Excel)
3. Chọn team bắt đầu
4. Xem báo cáo chi tiết
5. In hoặc xuất PDF
Công nghệ sử dụng
- Backend: PHP 7.4+
- Excel: PhpSpreadsheet
- Frontend: HTML5, CSS3, JavaScript
- UI: Responsive design, Font Awesome icons
- Security: CSRF protection, file validation