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)
7.0 KiB
7.0 KiB
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:
- 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ệ
- 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:
PurchaseEvaluations— Header (Type enum A/B, Phase 7 state, WorkflowDefinitionId pinned, SelectedSupplierId, PaymentTerms JSON, ContractId? FK kế thừa)PurchaseEvaluationSuppliers— N:M NCC tham gia + contact + payment term per NCCPurchaseEvaluationDetails— hạng mục so sánh + ngân sách (GroupCode A.I/II/III/IV)PurchaseEvaluationQuotes— báo giá per NCC per Detail + IsSelected flag (matrix cell)PurchaseEvaluationApprovals— workflow historyPurchaseEvaluationChangelogs— audit log unifiedPurchaseEvaluationAttachments— 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+PurchaseEvaluationWorkflowServiceimpl- 4 Features file (~900 LOC):
PurchaseEvaluationFeatures.cs— Create/Update/Transition/List/Inbox/Get/Delete/ChangelogPurchaseEvaluationSupplierFeatures.cs— Add/Update/Remove supplierPurchaseEvaluationDetailFeatures.cs— Add/Update/Delete hạng mục + Upsert/Delete Quote + SelectWinnerPurchaseEvaluationDtos.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 | workflowpages/pe/PurchaseEvaluationCreatePage.tsx— form create/edit headercomponents/pe/PeDetailTabs.tsx— 5 tab + 4 dialog (AddSupplier/EditSupplier/DetailDialog/QuoteDialog) + matrix clickablecomponents/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 +
CreateContractDialogpick ContractType
Build results
- Backend: 0 error, 2 pre-existing warning (DocxRenderer) — build pass
- fe-admin + fe-user:
tsc --noEmit0 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
- 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.
- 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).
SelectWinnerriêng set winner tổng thể (trường hợp 1 NCC thắng toàn bộ). - 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.
- MaPhieu format PE-YYYYMM-XXXX — tạm random. Có thể đổi format sau
(vd theo dự án:
{ProjectCode}/PE/{seq}) — user confirm format sau.