# Session 2026-05-07 (S14) — PE 3-button workflow Duyệt/Trả lại/Từ chối **Dev:** Claude **Duration:** ~1h **Base commit:** `b06bdce` (sau Session 13 Contract N-stage mirror) **Final commit:** `0d77698` (+ Task 2 in-progress, không commit) ## Bối cảnh Sau Session 11+++++++ user thêm Phase TraLai = 98 + FE label/badge. Session 12 bỏ qua wire BE TraLai. Session 14 này user chốt: KHÔNG cần Phase TraLai trung gian (orphan). Thay vào: 3-button approval rõ ràng. User wording: "Duyệt Trả lại và Từ chối. Từ chối thì xem như phải làm phiếu mới (khóa hết chức năng). Trả lại → đc điều chỉnh → Gửi duyệt." ## Spec chốt 3 hành động cho approver: - **Duyệt** = forward phase tiếp theo (decision=Approve, target=next phase) - **Trả lại** = về DangSoanThao + Drafter sửa (decision=Reject, target=DangSoanThao). Smart reject pattern Mig 16 — set RejectedFromPhase + clear N-stage rows tại fromPhase + Drafter resume jump-back tới phase đã reject. - **Từ chối** = Phase=TuChoi (decision=Reject, target=TuChoi). Phiếu khoá vĩnh viễn (17 handler Mig 16 lock edit khi Phase != DangSoanThao). Drafter phải tạo phiếu mới. ## Implementation (1 commit `0d77698`) ### Domain — `PurchaseEvaluationPolicy.cs` **NccOnly** + **NccWithPlan** thêm `(X → TuChoi)` transition cho mọi phase trung gian với roles của phase đó: ```csharp [(ChoPurchasing, TuChoi)] = [Procurement], [(ChoCCM, TuChoi)] = [CostControl], [(ChoCEODuyetNCC, TuChoi)] = [Director, AuthorizedSigner], // + ChoDuAn, ChoCEODuyetPA cho NccWithPlan ``` **FromDefinition** expand: mỗi step (trừ DangSoanThao) thêm `(step.Phase → TuChoi)` với roles step. Trước đây chỉ DangSoanThao→TuChoi (Drafter). ### Service — `PurchaseEvaluationWorkflowService.TransitionAsync` Reject branch tách 2 case: ```csharp if (decision == Reject) { if (target != TuChoi) { // "Trả lại" RejectedFromPhase = fromPhase target = DangSoanThao // force clear N-stage rows tại fromPhase } // else target=TuChoi: giữ nguyên TuChoi, KHÔNG set RejectedFromPhase, KHÔNG clear N-stage // Phiếu khoá vĩnh viễn — không resume. } ``` ### FE — `PeWorkflowPanel.tsx` (admin + user mirror) 3 button rõ ràng: - "✓ Duyệt →