Files
solution-erp/docs/workflow-contract.md
pqhuy1987 25dad7f36f [CLAUDE] Scaffold: khoi tao SOLUTION_ERP Phase 0
- .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>
2026-04-21 10:37:34 +07:00

157 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)`.