[CLAUDE] PurchaseEvaluation: demo seed 4 phieu + MaPhieu atomic sequence + Pe_* perm defaults

Polish session tiep cua PE module skeleton (commit 2c6f0ca..3990066):
3 task A (MISSING in MVP) khac STATUS.md In Progress:

1. Demo PE data seed (SeedDemoPurchaseEvaluationsAsync)
   - 4 phieu varied A/B x phase: A-001 DangSoanThao (mo), A-002
     ChoCEODuyetNCC (winner+9 quotes), A-003 DaDuyet (chua tao HD,
     PaymentTerms JSON), B-001 ChoDuAn (5-step giua chung).
   - Idempotent: skip-if-[DEMO]-exists.
   - Approval history dung policy A (3-step) hoac B (5-step).

2. MaPhieu atomic sequence — Migration 13
   - Format PE/{YYYY}/{TypeLetter}/{Seq:D3} (vd PE/2026/A/001).
   - PurchaseEvaluationCodeSequence entity (Prefix PK).
   - IPurchaseEvaluationCodeGenerator + impl SERIALIZABLE
     transaction (mirror ContractCodeGenerator 1:1).
   - Replace Random.Shared trong CreatePurchaseEvaluationCommandHandler.
   - Migration AddPurchaseEvaluationCodeSequences (1 bang).

3. Pe_* permission defaults
   - SeedPurchaseEvaluationPermissionDefaultsAsync — 7 role business x 9 menu key.
   - Drafter/DeptManager/Procurement: R+C+U; CostControl/PM/Director/AuthorizedSigner: R+U.
   - DeptManager them Delete (xoa nhap).
   - Idempotent per-(roleId x menuKey).

Build: 0 error, 2 warning (pre-existing DocxRenderer).

Files: 4 new + 8 modified (1 migration + entity + generator + DI + 2 ctx + 2 features).

Resolves: STATUS.md In Progress §A — 3 item PE MISSING.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-04-24 10:41:17 +07:00
parent 0048a2e83a
commit c48ac2116d
16 changed files with 3621 additions and 24 deletions

View File

@ -0,0 +1,35 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SolutionErp.Infrastructure.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddPurchaseEvaluationCodeSequences : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "PurchaseEvaluationCodeSequences",
columns: table => new
{
Prefix = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
LastSeq = table.Column<int>(type: "int", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PurchaseEvaluationCodeSequences", x => x.Prefix);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "PurchaseEvaluationCodeSequences");
}
}
}

View File

@ -2165,6 +2165,23 @@ namespace SolutionErp.Infrastructure.Persistence.Migrations
b.ToTable("PurchaseEvaluationChangelogs", (string)null);
});
modelBuilder.Entity("SolutionErp.Domain.PurchaseEvaluations.PurchaseEvaluationCodeSequence", b =>
{
b.Property<string>("Prefix")
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("LastSeq")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime2");
b.HasKey("Prefix");
b.ToTable("PurchaseEvaluationCodeSequences", (string)null);
});
modelBuilder.Entity("SolutionErp.Domain.PurchaseEvaluations.PurchaseEvaluationDetail", b =>
{
b.Property<Guid>("Id")