[CLAUDE] PE-Workflow: Chunk A — Mig 28 +6 Allow* column ApprovalWorkflow (F1+F2+F3 advanced options)
Domain `ApprovalWorkflow` (Mig 22 — Session 17) thêm 6 boolean cấu hình "Cấu hình nâng cao" cho admin Designer (F1 trả lại modes + F2 skip cấp cuối + F3 approver edit Section 2): - AllowReturnOneLevel (default false) — F1 mode 1 lùi 1 Cấp peer review - AllowReturnOneStep (default false) — F1 mode 2 lùi 1 Bước - AllowReturnToAssignee (default false) — F1 mode 3 pick runtime từ NV đã duyệt - AllowReturnToDrafter (default TRUE) — F1 mode 4 backward compat S17 fallback - AllowDrafterSkipToFinal (default false) — F2 Drafter trình thẳng Cấp cuối - AllowApproverEditDetails (default false) — F3 Approver edit HangMuc/NCC/Báo giá Default backward compat S17: AllowReturnToDrafter=true → mọi workflow cũ chạy đúng "Trả về Drafter" Phase=TraLai. 5 flag còn lại default false → admin opt-in per workflow để audit nghiêm. Mig 28 `AddAdvancedOptionsToApprovalWorkflows`: - AddColumn × 6 bit NOT NULL DEFAULT 0/1 (3-file rule complete + Designer + Snapshot) - Apply LocalDB SolutionErp_Dev (runtime) + SolutionErp_Design (ef tooling) EF config ApprovalWorkflowConfiguration thêm 6 HasDefaultValue match Mig 28 default (backfill rows cũ + ef snapshot consistency). 3 mode Trả lại mới giữ Phase=ChoDuyet, chỉ lùi pointer (peer review chain sequential). Mode Drafter giữ Phase=TraLai + clear pointer như S17. Behavior implement trong Chunk B (Service.TransitionAsync extend branches). Verify: - dotnet ef migrations add success (no compile error) - 3-file rule complete: 28 mig × 2 + Snapshot = 57 file Migrations dir - LocalDB Dev + Design both apply success Pending Chunk B: BE Service branches + handlers + Controller body extend. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -34,6 +34,46 @@ public class ApprovalWorkflow : BaseEntity
|
|||||||
// khi tạo version mới (mirror IsActive default), admin có thể unstick.
|
// khi tạo version mới (mirror IsActive default), admin có thể unstick.
|
||||||
public bool IsUserSelectable { get; set; }
|
public bool IsUserSelectable { get; set; }
|
||||||
|
|
||||||
|
// ===== Mig 28 (Session 21 turn 4) — 6 advanced options per workflow =====
|
||||||
|
// Cấu hình "Cấu hình nâng cao" trong Admin Designer. User eOffice render
|
||||||
|
// dropdown/checkbox theo flag enabled. 4 flag Return* = mode Trả lại (F1).
|
||||||
|
// 1 flag Skip = Drafter trình thẳng Cấp cuối (F2). 1 flag EditDetails =
|
||||||
|
// Approver chỉnh Section 2 (F3).
|
||||||
|
//
|
||||||
|
// Default backward compat S17: AllowReturnToDrafter=true (mọi workflow cũ
|
||||||
|
// chạy đúng — fallback "Trả về Drafter" như Session 17 spec). 5 flag còn
|
||||||
|
// lại default false — admin opt-in per workflow để audit nghiêm.
|
||||||
|
|
||||||
|
/// F1 mode 1 — Cho phép Approver Trả lại 1 Cấp trước (lùi pointer trong
|
||||||
|
/// cùng Step). Phiếu GIỮ Phase=ChoDuyet (peer review chain).
|
||||||
|
public bool AllowReturnOneLevel { get; set; }
|
||||||
|
|
||||||
|
/// F1 mode 2 — Cho phép Approver Trả lại 1 Bước trước (lùi sang Step trước,
|
||||||
|
/// set level = max của step đó). Phiếu GIỮ Phase=ChoDuyet.
|
||||||
|
public bool AllowReturnOneStep { get; set; }
|
||||||
|
|
||||||
|
/// F1 mode 3 — Cho phép Approver Trả lại Người chỉ định (pick runtime từ
|
||||||
|
/// list NV ĐÃ DUYỆT trong PeLevelOpinions). Phiếu GIỮ Phase=ChoDuyet, set
|
||||||
|
/// Step/Level = vị trí của user pick trong workflow.
|
||||||
|
public bool AllowReturnToAssignee { get; set; }
|
||||||
|
|
||||||
|
/// F1 mode 4 — Cho phép Approver Trả lại Người soạn thảo (Drafter). Phiếu
|
||||||
|
/// đi vào Phase=TraLai, clear pointer (như Session 17 spec). Default TRUE
|
||||||
|
/// để backward compat — admin có thể unstick force peer review only.
|
||||||
|
public bool AllowReturnToDrafter { get; set; } = true;
|
||||||
|
|
||||||
|
/// F2 — Cho phép Drafter gửi thẳng Cấp cuối (skip mọi Bước/Cấp trung gian).
|
||||||
|
/// UI eOffice trình duyệt thêm dropdown 2 option ("Gửi tuần tự" default vs
|
||||||
|
/// "Gửi thẳng Cấp cuối"). BE set CurrentWorkflowStepIndex=maxStep,
|
||||||
|
/// CurrentApprovalLevelOrder=maxLevel. Audit changelog "Drafter skip C1..N".
|
||||||
|
public bool AllowDrafterSkipToFinal { get; set; }
|
||||||
|
|
||||||
|
/// F3 — Cho phép Approver chỉnh sửa Section 2 (Hạng mục + NCC + Báo giá)
|
||||||
|
/// khi phase=ChoDuyet + actor match CurrentLevel.ApproverUserId. KHÔNG đụng
|
||||||
|
/// PE Header (TenGoiThau/Project/Budget). KHÔNG reset workflow. Audit ghi
|
||||||
|
/// PurchaseEvaluationChangelog cho mỗi field/row thay đổi.
|
||||||
|
public bool AllowApproverEditDetails { get; set; }
|
||||||
|
|
||||||
public List<ApprovalWorkflowStep> Steps { get; set; } = new();
|
public List<ApprovalWorkflowStep> Steps { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,15 @@ public class ApprovalWorkflowConfiguration : IEntityTypeConfiguration<ApprovalWo
|
|||||||
|
|
||||||
e.HasIndex(x => new { x.Code, x.Version }).IsUnique();
|
e.HasIndex(x => new { x.Code, x.Version }).IsUnique();
|
||||||
e.HasIndex(x => new { x.ApplicableType, x.IsActive });
|
e.HasIndex(x => new { x.ApplicableType, x.IsActive });
|
||||||
|
|
||||||
|
// Mig 28 — 6 advanced options. 5 default false (admin opt-in). 1
|
||||||
|
// AllowReturnToDrafter default true (backward compat S17 fallback).
|
||||||
|
e.Property(x => x.AllowReturnOneLevel).HasDefaultValue(false);
|
||||||
|
e.Property(x => x.AllowReturnOneStep).HasDefaultValue(false);
|
||||||
|
e.Property(x => x.AllowReturnToAssignee).HasDefaultValue(false);
|
||||||
|
e.Property(x => x.AllowReturnToDrafter).HasDefaultValue(true);
|
||||||
|
e.Property(x => x.AllowDrafterSkipToFinal).HasDefaultValue(false);
|
||||||
|
e.Property(x => x.AllowApproverEditDetails).HasDefaultValue(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,84 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace SolutionErp.Infrastructure.Persistence.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddAdvancedOptionsToApprovalWorkflows : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "AllowApproverEditDetails",
|
||||||
|
table: "ApprovalWorkflows",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "AllowDrafterSkipToFinal",
|
||||||
|
table: "ApprovalWorkflows",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "AllowReturnOneLevel",
|
||||||
|
table: "ApprovalWorkflows",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "AllowReturnOneStep",
|
||||||
|
table: "ApprovalWorkflows",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "AllowReturnToAssignee",
|
||||||
|
table: "ApprovalWorkflows",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "AllowReturnToDrafter",
|
||||||
|
table: "ApprovalWorkflows",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AllowApproverEditDetails",
|
||||||
|
table: "ApprovalWorkflows");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AllowDrafterSkipToFinal",
|
||||||
|
table: "ApprovalWorkflows");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AllowReturnOneLevel",
|
||||||
|
table: "ApprovalWorkflows");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AllowReturnOneStep",
|
||||||
|
table: "ApprovalWorkflows");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AllowReturnToAssignee",
|
||||||
|
table: "ApprovalWorkflows");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AllowReturnToDrafter",
|
||||||
|
table: "ApprovalWorkflows");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -134,6 +134,36 @@ namespace SolutionErp.Infrastructure.Persistence.Migrations
|
|||||||
b.Property<DateTime?>("ActivatedAt")
|
b.Property<DateTime?>("ActivatedAt")
|
||||||
.HasColumnType("datetime2");
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<bool>("AllowApproverEditDetails")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false);
|
||||||
|
|
||||||
|
b.Property<bool>("AllowDrafterSkipToFinal")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false);
|
||||||
|
|
||||||
|
b.Property<bool>("AllowReturnOneLevel")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false);
|
||||||
|
|
||||||
|
b.Property<bool>("AllowReturnOneStep")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false);
|
||||||
|
|
||||||
|
b.Property<bool>("AllowReturnToAssignee")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false);
|
||||||
|
|
||||||
|
b.Property<bool>("AllowReturnToDrafter")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(true);
|
||||||
|
|
||||||
b.Property<int>("ApplicableType")
|
b.Property<int>("ApplicableType")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user