[CLAUDE] Docs: chốt Phase 6 — Module Duyệt NCC E2E

Update 5 file:
 - STATUS.md: phase hiện tại + recently done 4 entry + cumulative stats
   (46 tables, ~110 endpoints, 12 migrations, ~26 FE pages)
 - HANDOFF.md: TL;DR + thêm row "Module Duyệt NCC E2E" 
 - changelog/migration-todos.md: thêm Phase 6 section với checklist
   done/optional (PE Workflow admin UI + Attachments + Auto-map
   Details skip MVP)
 - database/schema-diagram.md: Migration 12 row + section 11 "PurchaseEvaluation
   module" full (10 bảng + state machine + kế thừa HĐ flow)
 - changelog/sessions/2026-04-23-2300-purchase-evaluations.md: session
   log đầy đủ (user input + design + 4 commit + stats + skip MVP notes)
This commit is contained in:
pqhuy1987
2026-04-23 17:01:53 +07:00
parent a385d70c2e
commit aaf03be8d7
5 changed files with 243 additions and 18 deletions

View File

@ -296,6 +296,20 @@
- [x] **Seed master data** — 9 dept + 5 supplier + 3 project + MyDashboard — `6197c84`
- [x] **Brand identity**#1F7DC1 palette + Be Vietnam Pro + Solutions logo — `4abb559`..`bf1fbe3`
## Phase 6 — Module Duyệt NCC (tiền-HĐ) ✅ Done
- [x] **Migration 12 AddPurchaseEvaluations** — 10 bảng: PurchaseEvaluations + Suppliers + Details + Quotes + Approvals + Changelogs + Attachments + WorkflowDefinitions + WorkflowSteps + WorkflowStepApprovers
- [x] **Domain** — 2 enum (Type A/B, Phase 7 state) + Policy record + Registry + FromDefinition builder (mirror WorkflowPolicyRegistry HĐ)
- [x] **Seed** — 13 menu Pe_*/PeWf_* + 2 WorkflowDefinition v01 (QT-DN-A 3-step, QT-DN-B 5-step)
- [x] **Application CQRS** — ~900 dòng: Create/Update/Transition/List/Inbox/Get/Delete + Supplier CRUD + Detail CRUD + Quote Upsert + SelectWinner + Changelog
- [x] **PurchaseEvaluationWorkflowService** — policy-based guard + approval + notification + changelog
- [x] **PurchaseEvaluationsController** — 17 endpoint REST
- [x] **FE 2 app** — Types + PurchaseEvaluationsListPage 3-panel + PurchaseEvaluationCreatePage + PeDetailTabs (5 tab) + PeWorkflowPanel + Menu resolver Pe_*
- [x] **Kế thừa HĐ** — CreateContractFromEvaluationCommand guard DaDuyet + SelectedSupplier + !ContractId → gen Contract draft kế thừa Supplier/Project/GiaTri/DraftData. FE CreateContractDialog pick ContractType 7 loại. Link 2 chiều PE.ContractId.
- [ ] **PE Workflow admin designer UI**`/system/pe-workflows/:typeCode` (framework đã sẵn, mirror `/system/workflows/:typeCode`) — optional
- [ ] **PE Attachments upload** (pattern reuse ContractAttachmentFeatures) — optional
- [ ] **Auto-map PE Details → Contract Details per-type** khi gen HĐ — phức tạp vì 7 ContractType schema khác nhau, user điền lại manual — optional
## Post-launch (Phase 6+ — future)
- [ ] **Email outbox** (MailKit + SMTP) — blocked chờ SMTP config

View File

@ -0,0 +1,144 @@
# Session 2026-04-23 ~23:00 — Module Duyệt NCC (tiền-HĐ) E2E
**Focus:** Build module mới "Quy trình chọn Thầu phụ - NCC" từ user spec
(Excel form trình duyệt so sánh giá + 2 flowchart A/B). Đây là đầu vào
của HĐ — phiếu duyệt xong kế thừa làm HĐ cho NCC đó.
4 commit (`2c6f0ca``a385d70`), 1 migration (12), ~2500 LOC BE + FE.
## User input
**2 file từ user:**
1. **Excel form** "BẢNG TỔNG HỢP TRÌNH DUYỆT SO SÁNH GIÁ" — dự án SOVI,
gói thầu Cung cấp bê tông, so sánh 4 NCC × hạng mục (nhóm A.I Bê tông,
A.II Phụ gia, A.III Bơm, A.IV Vận chuyển) + ý kiến 4 phòng ban + D
Điều kiện TT + E Thông tin liên hệ
2. **Flowchart** 2 quy trình:
- A "Duyệt NCC" (3 step): Purchasing → CCM → CEO
- B "Duyệt NCC - Phương án" (5 step): Purchasing → Dự án → CCM →
CEO (duyệt PA) → CEO (duyệt NCC)
**User confirm:**
- Menu: Quy trình chọn Thầu phụ - NCC → Duyệt NCC / Duyệt NCC Phương Án,
mỗi cái 3 sub (Danh sách / Thao tác / Duyệt)
- Kế thừa HĐ: user click "Tạo HĐ" → list phiếu đã duyệt → chọn → kế thừa
- Mã phiếu: tính sau (auto gen PE-YYYYMM-XXXX tạm)
- Tách Quotes ra bảng riêng (row-based)
- "7 bảng core" (thực tế 7 + 3 workflow config tách riêng vì Phase enum khác)
- "Config quy trình y như HĐ" (admin tự config version mới)
## Design
**10 bảng mới (migration 12 `AddPurchaseEvaluations`):**
Core 7:
1. `PurchaseEvaluations` — Header (Type enum A/B, Phase 7 state, WorkflowDefinitionId
pinned, SelectedSupplierId, PaymentTerms JSON, ContractId? FK kế thừa)
2. `PurchaseEvaluationSuppliers` — N:M NCC tham gia + contact + payment term per NCC
3. `PurchaseEvaluationDetails` — hạng mục so sánh + ngân sách (GroupCode A.I/II/III/IV)
4. `PurchaseEvaluationQuotes` — báo giá per NCC per Detail + IsSelected flag (matrix cell)
5. `PurchaseEvaluationApprovals` — workflow history
6. `PurchaseEvaluationChangelogs` — audit log unified
7. `PurchaseEvaluationAttachments` — file upload (báo giá + spec + phiếu export)
Workflow config 3:
8. `PurchaseEvaluationWorkflowDefinitions` — versioned per Type (A/B), UK(Code, Version)
9. `PurchaseEvaluationWorkflowSteps` — Order + Phase + Name + SlaDays
10. `PurchaseEvaluationWorkflowStepApprovers` — Kind (Role/User) + AssignmentValue
**Phase enum (PurchaseEvaluationPhase, 7 state + TuChoi):**
- 1 DangSoanThao / 2 ChoPurchasing / 3 ChoDuAn (chỉ B) / 4 ChoCCM
- 5 ChoCEODuyetPA (chỉ B) / 6 ChoCEODuyetNCC / 7 DaDuyet / 99 TuChoi
**Policy default (hardcoded fallback khi admin chưa author DB):**
- A NccOnly: DangSoanThao → ChoPurchasing (PRO) → ChoCCM (CCM) → ChoCEODuyetNCC (BOD) → DaDuyet
- B NccWithPlan: DangSoanThao → ChoPurchasing (PRO) → ChoDuAn (PM) → ChoCCM (CCM) → ChoCEODuyetPA (BOD) → ChoCEODuyetNCC (BOD) → DaDuyet
- SLA default: soạn 3d, step 2d, CEO 1d
- Reject path mọi phase → DangSoanThao
**Kế thừa HĐ flow:**
- Phiếu DaDuyet + SelectedSupplierId + !ContractId → banner emerald FE
- Click "Tạo HĐ từ phiếu" → dialog pick ContractType 7 loại + TenHopDong + bypass flag
- POST `/api/purchase-evaluations/{id}/create-contract`
- BE: verify → clone Supplier/Project/DepartmentId/GiaTri(sum details) → gen MaHopDong
ngay → pin ContractWorkflowDefinition[Type] → log Changelog cả 2 bảng → link
2 chiều PE.ContractId = contract.Id
- Navigate `/contracts/{newId}`
## Commits
### 1. `2c6f0ca` — Domain+Infra (migration 12)
- 10 entity files ở `Domain/PurchaseEvaluations/`
- 1 EF config file (10 configuration class)
- Policy + Registry + FromDefinition mirror HĐ
- MenuKeys +Pe_* + PeWorkflows constants
- DbInitializer seed 13 menu + 2 WorkflowDefinition v01
### 2. `(commit 2)` — App+Api CQRS
- `IPurchaseEvaluationWorkflowService` + `PurchaseEvaluationWorkflowService` impl
- 4 Features file (~900 LOC):
- `PurchaseEvaluationFeatures.cs` — Create/Update/Transition/List/Inbox/Get/Delete/Changelog
- `PurchaseEvaluationSupplierFeatures.cs` — Add/Update/Remove supplier
- `PurchaseEvaluationDetailFeatures.cs` — Add/Update/Delete hạng mục + Upsert/Delete Quote + SelectWinner
- `PurchaseEvaluationDtos.cs` — DTO records cho GetBundle
- `PurchaseEvaluationsController.cs` — 15 endpoint REST
- DI register
### 3. `(commit 3)` — FE 2 app
- `types/purchaseEvaluation.ts` — PEType/Phase enum + DTOs (copy-share)
- `pages/pe/PurchaseEvaluationsListPage.tsx` — 3-panel: list | detail tabs | workflow
- `pages/pe/PurchaseEvaluationCreatePage.tsx` — form create/edit header
- `components/pe/PeDetailTabs.tsx` — 5 tab + 4 dialog (AddSupplier/EditSupplier/DetailDialog/QuoteDialog) + matrix clickable
- `components/pe/PeWorkflowPanel.tsx` — timeline + nextPhase buttons
- Menu resolver Layout.tsx: `Pe_<Code>_<Action>` + `PeWf_<Code>` (admin only)
- App.tsx 3 route mới
- MenuKeys.ts +PurchaseEvaluations + PeWorkflows
- fe-user mirror (cùng pages, no admin hidden items)
### 4. `a385d70` — Kế thừa HĐ (Phase 4)
- `CreateContractFromEvaluationFeatures.cs` — Command + Query (list approved pending)
- 2 endpoint: `GET /approved-pending-contract` + `POST /{id}/create-contract`
- PeDetailTabs InfoTab: banner emerald + `CreateContractDialog` pick ContractType
## Build results
- Backend: 0 error, 2 pre-existing warning (DocxRenderer) — build pass
- fe-admin + fe-user: `tsc --noEmit` 0 error
## Skip MVP (tương lai)
- [ ] PE Workflow admin designer UI `/system/pe-workflows/:typeCode` (framework
đã có, mirror `/system/workflows/:typeCode`)
- [ ] PE Attachments upload endpoint + FE drag-drop (pattern reuse ContractAttachment)
- [ ] Auto-map PE Details → Contract Details per-type khi gen HĐ (phức tạp
vì 7 ContractType schema khác nhau)
- [ ] Demo data PE (1-2 phiếu sample cho UAT)
## Stats
| | Trước session | Sau session | Δ |
|---|---|---|---|
| BE LOC | ~8800 | ~11100 | +2300 |
| DB tables | 36 | 46 | +10 |
| Migrations | 11 | 12 | +1 |
| API endpoints | ~93 | ~110 | +17 |
| FE pages | ~23 | ~26 | +3 (× 2 app) |
| Commits session | — | 4 | `2c6f0ca``a385d70` |
## Notes
1. **Workflow config tách bảng riêng** thay vì share WorkflowDefinition với HĐ
— vì Phase enum khác (PurchaseEvaluationPhase vs ContractPhase). Code
duplication ~250 dòng (FromDefinition builder) nhưng design clean.
2. **Quote Dialog matrix UX** — click cell → popup nhập giá + IsSelected
per hạng mục (cho phép mỗi hạng mục NCC khác). `SelectWinner` riêng set
winner tổng thể (trường hợp 1 NCC thắng toàn bộ).
3. **Kế thừa HĐ non-copy details** — PE detail schema flat (GroupCode/NoiDung/
KhoiLuong/DonGia...) khác 7 ContractType details schemas — user điền
lại manual. Link qua PE.ContractId cho reference.
4. **MaPhieu format PE-YYYYMM-XXXX** — tạm random. Có thể đổi format sau
(vd theo dự án: `{ProjectCode}/PE/{seq}`) — user confirm format sau.