Giao diện
Kiến trúc 5 lớp Workforce Planner
TÓM TẮT
Workforce Planner chuyển đổi forecast thành kế hoạch nhân sự qua 5 lớp xử lý tuần tự. Tuân thủ Bộ luật Lao động Việt Nam 2019. Hỗ trợ 2-4 ca/ngày tùy loại ngày.
File chính: src/services/modules/workforce/workforcePlanningEngine.ts (~1270 dòng, 60KB)
Sơ đồ 5 lớp
Layer 1: Forecast Decomposition
Tách forecast tổng thành:
| Dimension | Giá trị |
|---|---|
| Complexity | L1 (simple) → L6 (very complex), mỗi level có WLU weight |
| Channel | Shopee, TikTokShop, Lazada, Other |
| Carrier | SPX, JT, LEX, GHN, BEST, VTP |
Layer 2: Work Hours
typescript
// Variable UPH theo staff level
const pickHours = volume / variableUPH.pickUPH[level][dayType];
const packHours = wlu / variableUPH.packUPH[level][dayType];
// Table capacity
const tableCap = (standardTables * staffPerTable) + (fieldTables * staffPerTable);Layer 3: Headcount by Shift
| DayType | Số ca | Phân bổ |
|---|---|---|
| NORMAL | 2 | Sáng 70%, Chiều 30% |
| MINI_SPIKE | 3 | 45%, 30%, 25% |
| DOUBLE_DAY | 4 (+ đêm) | 40%, 25%, 25%, 10% |
| MEGA_SALE | 4 (+ đêm) | 35%, 25%, 25%, 15% |
Có tính break time deduction và fatigue factor.
Layer 4: Staff Allocation
Decision tree cho từng ca:
- Official staff — phân bổ proportional
- Complex tasks (L4-L6) — chỉ officials
- OT — capped theo Luật Lao động
- CTV — field table eligibility
- Cross-department — Controller→Pick, Inbound→Pack (min-keep rules)
Layer 5: Capacity & Cost
typescript
// Capacity bottleneck
const capacity = Math.min(pickCapacity, packCapacity);
// Backlog (carries forward)
const backlog = Math.max(0, demand - capacity);
nextShift.carryOver = backlog;
// Cost breakdown
const cost = officialNormalCost + otCost + tempCost + nightSurcharge;BUG ĐÃ BIẾT
- BUG-01:
totalOfficialNormalCostluôn = 0 (chưa tính) - BUG-02:
dailyBacklogByChannelbị overwrite thay vì accumulate - BUG-04:
config.isHolidayluôn = false (hardcoded)
Xem Bugs đã biết.