- .NET 10 Clean Architecture: Domain/Application/Infrastructure/Api (4 project) - 2 React + Vite + TS app: fe-admin (:8082), fe-user (:8080) voi proxy /api - Node engines >=20, .nvmrc = 20 cho CI (bai hoc NamGroup) - SQL Server 2022 qua docker-compose (dev) - Parse 8 FORM -> docs/forms-spec.md (catalog + ma HD format RG-001) - Parse QUY_TRINH -> docs/workflow-contract.md (9 phase state machine + role matrix) - docs: CLAUDE.md, STATUS.md, PROJECT-MAP.md, migration-todos.md (roadmap 5 phase) - .claude/skills: 3 placeholder (contract-workflow, form-engine, permission-matrix) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
157 lines
8.0 KiB
Markdown
157 lines
8.0 KiB
Markdown
# Workflow — Quy trình trình ký Hợp đồng TP/NCC/Tổ đội
|
||
|
||
> **Nguồn:** `QUY_TRINH/QT TRINH KY HOP DONG TP-NCC.docx`
|
||
> **Raw dump:** [`workflow-raw.md`](workflow-raw.md)
|
||
> **Phase 3 deliverable:** Implement state machine + role guard + SLA timer + notification
|
||
|
||
## 1. Phạm vi
|
||
|
||
Áp dụng cho Hợp đồng/Phụ lục HĐ ký với: **Thầu phụ (NTP)** · **Nhà cung cấp (NCC)** · **Tổ đội (TĐ)**. Tham chiếu ISO 9001.
|
||
|
||
## 2. Glossary (viết tắt)
|
||
|
||
| Mã | Nghĩa | Role trong system |
|
||
|---|---|---|
|
||
| **BOD** | Ban Giám đốc | `Director` |
|
||
| **NĐUQ** | Người được ủy quyền | `AuthorizedSigner` |
|
||
| **CCM** | Phòng Kiểm soát Chi phí | `CostControl` |
|
||
| **PRO** | Phòng Cung ứng | `Procurement` |
|
||
| **FIN** | Phòng Tài chính | `Finance` |
|
||
| **ACT** | Phòng Kế toán | `Accounting` |
|
||
| **EQU** | Phòng Thiết bị | `Equipment` |
|
||
| **HRA** | Nhân sự - Hành chính (đóng dấu) | `HR_Admin` |
|
||
| **PB** | Phòng ban | `Department` |
|
||
| **BCH CT** | Ban chỉ huy công trường | `SiteCommand` |
|
||
| **PD** | Giám đốc Thi công | `ProjectDirector` |
|
||
| **PM** | Giám đốc Dự án | `ProjectManager` |
|
||
| **TPB** | Trưởng Phòng ban | `DeptManager` |
|
||
| **TBP** | Trưởng Bộ phận | `SectionLeader` |
|
||
| **QS/NV.PB** | QS công trường / Nhân viên PB | `Drafter` (người soạn) |
|
||
| **NTP/NCC/TĐ** | Đối tác ký HĐ | Partner (external — không login) |
|
||
|
||
## 3. State Machine (9 phase)
|
||
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> DangChon: Tạo mới
|
||
DangChon --> DangSoanThao: Chọn NCC xong (chuyển Drafter)
|
||
DangSoanThao --> DangGopY: Gửi email góp ý (7d)
|
||
DangGopY --> DangDamPhan: Nhận xong comment (7d)
|
||
DangDamPhan --> DangInKy: Thỏa thuận xong (7d)
|
||
DangInKy --> DangKiemTraCCM: Đã ký nháy QS/PD/TPB, chuyển CCM (1d)
|
||
DangKiemTraCCM --> DangTrinhKy: CCM ký nháy xong (3d)
|
||
DangTrinhKy --> DangDongDau: BOD/NĐUQ ký duyệt (1d)
|
||
DangDongDau --> DaPhatHanh: HRA đóng dấu xong
|
||
DaPhatHanh --> [*]: PB scan + gửi bản gốc + lưu Filing
|
||
|
||
DangSoanThao --> TuChoi: Cancel
|
||
DangGopY --> DangSoanThao: Revise
|
||
DangKiemTraCCM --> DangSoanThao: CCM reject
|
||
DangTrinhKy --> DangSoanThao: BOD reject
|
||
TuChoi --> [*]
|
||
```
|
||
|
||
## 4. Chi tiết từng phase
|
||
|
||
| # | Phase (state) | Role thực hiện | Input | Output | SLA | Form liên quan |
|
||
|---|---|---|---|---|---|---|
|
||
| 1 | `DangChon` — Lựa chọn NTP/NCC | `PB` / `BCH CT` | Yêu cầu công việc | Chốt đối tác | — | (theo Quy trình Cung ứng SOL-PRO-SP-001) |
|
||
| 2 | `DangSoanThao` — Soạn thảo HĐ | `Drafter` (QS/NV.PB) + `TBP`/`TPB` check | Template HĐ | Dự thảo HĐ | **7 ngày** | FO-002.02/.03/.04/.05/.06 (chọn loại phù hợp) |
|
||
| 3 | `DangGopY` — Góp ý nội dung | `PD`/`PM`/`PRO`/`CCM`/`FIN`/`ACT`/`EQU` | Dự thảo | Comment (email → hệ thống) | **7 ngày** | (đính kèm comment thread) |
|
||
| 4 | `DangDamPhan` — Đàm phán | `Drafter` + `TBP`/`TPB`/`PD`/`PM` | Comment | Bản cuối thỏa thuận | **7 ngày** | — |
|
||
| 5 | `DangInKy` — In + đối tác ký | `Drafter` + **NTP/NCC/TĐ** (external) + `PD`/`PM`/`TPB` ký nháy | Bản cuối | 2 mặt, có chữ ký đối tác + ký nháy nội bộ | **1 ngày** | FO-002.01 (cover approval) |
|
||
| 6 | `DangKiemTraCCM` — CCM kiểm tra | `CCM` (`TP.CCM` ký nháy) | HĐ đã ký nháy | HĐ CCM approved | **3 ngày** | FO-002.01 |
|
||
| 7 | `DangTrinhKy` — BOD ký duyệt | `BOD` hoặc `NĐUQ` | HĐ CCM approved | HĐ ký duyệt | **1 ngày** | FO-002.01 |
|
||
| 8 | `DangDongDau` — Đóng dấu | `HRA`/`ISO` | HĐ đã ký | HĐ có dấu | — | — |
|
||
| 9 | `DaPhatHanh` — Phát hành + lưu trữ | `PB`/`BCH CT` + `CCM` | HĐ có dấu | Scan + bản gốc gửi NCC + lưu Filing System | — | — |
|
||
|
||
**Tổng SLA:** ~19 ngày (phase 2-7) cho 1 HĐ hoàn chỉnh.
|
||
|
||
## 5. Role × Phase Matrix (quyền xem/thao tác)
|
||
|
||
Ký hiệu: `R` = read, `W` = write/update draft, `A` = approve (chuyển phase tiếp), `-` = không có quyền.
|
||
|
||
| Role \ Phase | 1.Chọn | 2.Soạn | 3.GópÝ | 4.ĐàmPhán | 5.InKý | 6.CCMCheck | 7.BODKý | 8.ĐóngDấu | 9.PhátHành |
|
||
|---|---|---|---|---|---|---|---|---|---|
|
||
| **Drafter** (QS/NV.PB) | R | W,A | R | W,A | W,A | R | R | R | W |
|
||
| **TBP/TPB** | R | R,A | R,A | R,A | R,A | R | R | R | R |
|
||
| **PD/PM** | R | R | W,A | R,A | R,A | R | R | R | R |
|
||
| **PRO/EQU/FIN/ACT** | A | R | W,A | R | - | - | - | - | R |
|
||
| **CCM** | - | R | W,A | R | R | W,A | R | R | W |
|
||
| **BOD/NĐUQ** | - | - | - | - | - | - | A | - | R |
|
||
| **HRA** | - | - | - | - | - | - | - | W,A | R |
|
||
| **Admin** (system) | R | R | R | R | R | R | R | R | R (+ override) |
|
||
|
||
**Guard rule:**
|
||
- Đặc biệt: HĐ với **Chủ đầu tư** → có thể **bypass** phase 3 + 6 (không cần PRO/CCM góp ý + kiểm tra). Cờ `BypassProcurementAndCCM: bool` ở entity HĐ.
|
||
- Quá SLA mỗi phase không action → **auto-approve** (chuyển phase tiếp). Gửi notification warning khi còn 2h.
|
||
- Nếu cần kéo dài → bộ phận kiểm tra phải comment vào "Ý kiến" trước khi SLA hết.
|
||
|
||
## 6. Notification triggers
|
||
|
||
| Event | Người nhận | Kênh |
|
||
|---|---|---|
|
||
| Chuyển `DangSoanThao` → `DangGopY` | Tất cả role góp ý (PD/PM/PRO/CCM/FIN/ACT) | email + in-app |
|
||
| Chuyển `DangKiemTraCCM` | `CCM` | email + in-app |
|
||
| Chuyển `DangTrinhKy` | `BOD` + `NĐUQ` | email + in-app (high priority) |
|
||
| Quá SLA 80% thời gian | Role đang giữ phase | in-app warning |
|
||
| Quá SLA → auto-approve | Drafter + role giữ phase | email + in-app (log audit) |
|
||
| Reject (quay về `DangSoanThao`) | Drafter | email + in-app |
|
||
|
||
## 7. Data model implication (cho Phase 3)
|
||
|
||
```csharp
|
||
// Domain
|
||
public enum ContractPhase {
|
||
DangChon = 1,
|
||
DangSoanThao,
|
||
DangGopY,
|
||
DangDamPhan,
|
||
DangInKy,
|
||
DangKiemTraCCM,
|
||
DangTrinhKy,
|
||
DangDongDau,
|
||
DaPhatHanh,
|
||
TuChoi
|
||
}
|
||
|
||
public class Contract : AuditableEntity {
|
||
public Guid Id { get; set; }
|
||
public string MaHopDong { get; set; } // tự gen theo RG-001
|
||
public ContractType Type { get; set; } // HDTP, HDGK, NCC, HDDV...
|
||
public ContractPhase Phase { get; set; }
|
||
public Guid SupplierId { get; set; }
|
||
public Guid ProjectId { get; set; }
|
||
public decimal GiaTri { get; set; }
|
||
public bool BypassProcurementAndCCM { get; set; }
|
||
public DateTime? SlaDeadline { get; set; } // khi nào phase hiện tại hết hạn
|
||
// ...
|
||
public List<ContractComment> Comments { get; set; } // thread góp ý phase 3
|
||
public List<ContractApproval> Approvals { get; set; } // ai ký phase nào, lúc nào
|
||
public List<ContractAttachment> Attachments { get; set; } // scan bản gốc, file export
|
||
}
|
||
|
||
public class ContractApproval {
|
||
public Guid ContractId { get; set; }
|
||
public ContractPhase Phase { get; set; }
|
||
public Guid ApproverUserId { get; set; }
|
||
public DateTime? ApprovedAt { get; set; }
|
||
public ApprovalDecision Decision { get; set; } // Approve | Reject | AutoApprove
|
||
public string? Comment { get; set; }
|
||
}
|
||
```
|
||
|
||
**Service chính:**
|
||
- `IContractWorkflowService.TransitionAsync(contractId, targetPhase, userId, comment)` — check guard + update state + tạo approval + notify
|
||
- `IContractCodeGenerator.GenerateAsync(projectId, type, supplierId)` — dùng SEMAPHORE/transaction tránh race condition
|
||
- `ISlaExpiryJob` — hosted service chạy mỗi 15 phút, auto-approve các HĐ quá hạn
|
||
|
||
## 8. Business rules summary
|
||
|
||
1. **Một role chỉ có 1 phase active tại 1 thời điểm** cho 1 HĐ.
|
||
2. **Auto-approve nếu quá SLA** — nhưng phải log `Decision=AutoApprove` rõ ràng trong `ContractApproval`.
|
||
3. **Reject → quay về `DangSoanThao`** — Drafter nhận lại, toàn bộ approval trước đó bị invalidate (kept as history).
|
||
4. **Không cho xóa HĐ** đã qua phase 5 (`DangInKy`) — chỉ soft delete.
|
||
5. **Mã HĐ** gen theo `forms-spec.md § RG-001` — chỉ gen khi transition sang phase 5.
|
||
6. **Audit log đầy đủ** — mọi transition đều ghi `AuditLog(entityId, action, oldPhase, newPhase, userId, timestamp, diff)`.
|