[CLAUDE] PurchaseEvaluation: User chọn quy trình duyệt V2 lúc tạo phiếu (Mig 23)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m11s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m11s
User feedback: thay field "Loại quy trình (theo menu — khóa)" disabled
→ Select dropdown cho User pick quy trình ApprovalWorkflowsV2 (Mig 22)
ngay từ workspace tạo mới. Hiển thị "Mã + Tên + Version".
BE Domain:
- PurchaseEvaluation +ApprovalWorkflowId Guid? (nullable, FK Restrict)
- EF Configuration: Index + FK Restrict to ApprovalWorkflows
- Migration 23 `AddApprovalWorkflowIdToPurchaseEvaluation` (1 ALTER +
1 IX + 1 FK), applied cả _Design + _Dev LocalDB
- Field WorkflowDefinitionId (Mig 21 legacy) giữ song song để Service
PE chạy logic cũ tới khi Session sau wire qua schema mới
BE Application:
- CreatePurchaseEvaluationCommand +ApprovalWorkflowId? Guid? optional
param (default null)
- Validate: nếu set, phải tồn tại + ApplicableType khớp PE.Type
(DuyetNcc=1 → ApprovalWorkflowApplicableType.DuyetNcc, etc)
- Handler set entity.ApprovalWorkflowId từ request
- UpdatePurchaseEvaluationDraftCommand mirror — cho User đổi quy trình
khi sửa Nháp/Trả lại (validate same)
- PurchaseEvaluationDetailBundleDto +ApprovalWorkflowId/Code/Name/Version
- GetPurchaseEvaluationByIdQuery handler load workflow info join
- Update Phase guard: cho sửa cả DangSoanThao + TraLai (Trả lại =
editable per Session 17 spec)
FE (cả 2 app mirror):
- types/purchaseEvaluation.ts: PeDetail +approvalWorkflowId/Code/Name/Version
- PeWorkspaceCreateView.tsx:
- Replace field disabled "Loại quy trình" → Select bắt buộc
- useQuery `/api/approval-workflows-v2?applicableType=N` filter theo
defaultType (1=DuyetNcc / 2=DuyetNccPhuongAn)
- Display option: "QT-DN-V2-001 v01 — Quy trình Duyệt NCC (đang áp dụng)"
- List cả version active + archived (UAT cần test compare)
- Empty state hint amber "Chưa có quy trình, vào /system/approval-workflows-v2"
- canSubmit require approvalWorkflowId set
- POST payload include approvalWorkflowId
Verify: dotnet build OK · 81 test pass · npm build × 2 OK · Mig 23 applied
cả 2 LocalDB.
Logic Service PE chưa wire qua ApprovalWorkflowId — vẫn pin
WorkflowDefinitionId Mig 21 legacy chạy. Session sau wire Service iterate
ApprovalWorkflowSteps + match approver theo schema V2 + drop legacy.
This commit is contained in:
@ -27,9 +27,18 @@ public class PurchaseEvaluationConfiguration : IEntityTypeConfiguration<Purchase
|
||||
b.HasIndex(x => x.ProjectId);
|
||||
b.HasIndex(x => x.SlaDeadline);
|
||||
b.HasIndex(x => x.WorkflowDefinitionId);
|
||||
b.HasIndex(x => x.ApprovalWorkflowId);
|
||||
b.HasIndex(x => x.ContractId);
|
||||
b.HasIndex(x => x.BudgetId);
|
||||
|
||||
// FK ApprovalWorkflowId Restrict (Mig 23 Session 17) — schema mới
|
||||
// ApprovalWorkflowsV2 pin lúc create. Restrict để KHÔNG xóa workflow
|
||||
// nếu còn phiếu pin.
|
||||
b.HasOne<SolutionErp.Domain.ApprovalWorkflowsV2.ApprovalWorkflow>()
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.ApprovalWorkflowId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasMany(x => x.Suppliers).WithOne(s => s.PurchaseEvaluation).HasForeignKey(s => s.PurchaseEvaluationId).OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasMany(x => x.Details).WithOne(d => d.PurchaseEvaluation).HasForeignKey(d => d.PurchaseEvaluationId).OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasMany(x => x.Approvals).WithOne(a => a.PurchaseEvaluation).HasForeignKey(a => a.PurchaseEvaluationId).OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace SolutionErp.Infrastructure.Persistence.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddApprovalWorkflowIdToPurchaseEvaluation : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "ApprovalWorkflowId",
|
||||
table: "PurchaseEvaluations",
|
||||
type: "uniqueidentifier",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PurchaseEvaluations_ApprovalWorkflowId",
|
||||
table: "PurchaseEvaluations",
|
||||
column: "ApprovalWorkflowId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_PurchaseEvaluations_ApprovalWorkflows_ApprovalWorkflowId",
|
||||
table: "PurchaseEvaluations",
|
||||
column: "ApprovalWorkflowId",
|
||||
principalTable: "ApprovalWorkflows",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_PurchaseEvaluations_ApprovalWorkflows_ApprovalWorkflowId",
|
||||
table: "PurchaseEvaluations");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_PurchaseEvaluations_ApprovalWorkflowId",
|
||||
table: "PurchaseEvaluations");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ApprovalWorkflowId",
|
||||
table: "PurchaseEvaluations");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2485,6 +2485,9 @@ namespace SolutionErp.Infrastructure.Persistence.Migrations
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<Guid?>("ApprovalWorkflowId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<Guid?>("BudgetId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
@ -2578,6 +2581,8 @@ namespace SolutionErp.Infrastructure.Persistence.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ApprovalWorkflowId");
|
||||
|
||||
b.HasIndex("BudgetId");
|
||||
|
||||
b.HasIndex("ContractId");
|
||||
@ -3562,6 +3567,14 @@ namespace SolutionErp.Infrastructure.Persistence.Migrations
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SolutionErp.Domain.PurchaseEvaluations.PurchaseEvaluation", b =>
|
||||
{
|
||||
b.HasOne("SolutionErp.Domain.ApprovalWorkflowsV2.ApprovalWorkflow", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ApprovalWorkflowId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SolutionErp.Domain.PurchaseEvaluations.PurchaseEvaluationApproval", b =>
|
||||
{
|
||||
b.HasOne("SolutionErp.Domain.PurchaseEvaluations.PurchaseEvaluation", "PurchaseEvaluation")
|
||||
|
||||
Reference in New Issue
Block a user