[CLAUDE] PurchaseEvaluation: CCM 3-fix — multi-winner sum + budget=0 hợp lệ + cấp KẾT THÚC quy trình (Mig 58, anh Kiệt FDC)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m10s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m10s
CCM (Lưu Trần / anh Kiệt FDC) — làm 3/4 mục (mục 3 "CCM sửa ngân sách" để riêng): 1. Multi-winner: chọn NHIỀU NTP/NCC/ĐVDV cùng trúng → winnerQuoteTotal = SUM ThanhTien MỌI đơn vị isWinner (vd 3 ông 37.8+9+10 = 56.8tr). Cột mới PurchaseEvaluationSupplier.IsWinner (Mig 58, backfill từ SelectedSupplierId). SelectWinner → multi-toggle SupplierIds[]. FE: bảng so sánh tick nhiều ô + dòng "Tổng chi phí đã chọn"; mọi guard/checklist/computeGiaChaoThau/tạo-HĐ đổi sang isWinner (selectedSupplierId = null khi liên-danh ≥2). 2. Ngân sách = 0 hợp lệ: nới submit-guard + 3 validator (chỉ chặn khi NULL, số 0 cố ý đi qua; fallback ProInitial chỉ khi null). Mirror BE + FE. 3. Cấp KẾT THÚC quy trình: ApprovalWorkflowLevel.AllowApproverFinalize (Mig 58) — admin bật per-cấp trong Workflow Designer; duyệt tới cấp đó TỰ DaDuyet, bỏ qua CEO (AUTO theo cấu hình quy trình, không ô-tích runtime — anh Kiệt chốt). FE: banner cảnh báo + bắt chọn giá chốt. Mig 58 AddPeMultiWinnerAndLevelFinalize (2 AddColumn bool + backfill IsWinner, additive/reversible). Test 377→395 (+PeMultiWinnerTests +PeApproverFinalizeTests +budget=0; auto-model gọn bớt 2 test bypass/opt-out). FE 2 app SHA-mirror. Build sạch BE + 2 FE local. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -93,5 +93,10 @@ public class ApprovalWorkflowLevelConfiguration : IEntityTypeConfiguration<Appro
|
||||
// slot này skip thẳng Cấp cuối lúc đang duyệt ChoDuyet. Default false
|
||||
// (admin opt-in). Semantic + storage cũ ở Users table per-Drafter đã drop.
|
||||
e.Property(x => x.AllowApproverSkipToFinal).HasDefaultValue(false);
|
||||
|
||||
// Mig 58 (2026-06-24 — CCM/anh Kiệt FDC) — F5 per-NV: cho phép NV slot này
|
||||
// duyệt = KẾT THÚC quy trình (Phase=DaDuyet) miễn trình CEO. Default false
|
||||
// (admin opt-in). Khác F2 (skip = advance tới Cấp cuối): F5 = terminal ngay.
|
||||
e.Property(x => x.AllowApproverFinalize).HasDefaultValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +82,9 @@ public class PurchaseEvaluationSupplierConfiguration : IEntityTypeConfiguration<
|
||||
b.Property(x => x.PaymentTermText).HasMaxLength(200);
|
||||
b.Property(x => x.Note).HasMaxLength(500);
|
||||
|
||||
// [Mig 58] Multi-winner flag — default false (mirror per-slot bool pattern).
|
||||
b.Property(x => x.IsWinner).HasDefaultValue(false);
|
||||
|
||||
b.HasIndex(x => new { x.PurchaseEvaluationId, x.SupplierId }).IsUnique();
|
||||
b.HasIndex(x => x.SupplierId);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,50 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace SolutionErp.Infrastructure.Persistence.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddPeMultiWinnerAndLevelFinalize : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsWinner",
|
||||
table: "PurchaseEvaluationSuppliers",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "AllowApproverFinalize",
|
||||
table: "ApprovalWorkflowLevels",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
// [Mig 58] Backfill IsWinner từ winner đơn lẻ cũ (SelectedSupplierId) —
|
||||
// phiếu UAT đang chạy giữ winner đã chọn dưới mô hình multi-winner mới.
|
||||
// Chạy SAU AddColumn (cột đã tồn tại). Idempotent: chỉ set 1 (default 0
|
||||
// không đụng) → re-run no-op. KHÔNG un-backfill ở Down (DropColumn xoá hẳn).
|
||||
migrationBuilder.Sql(@"
|
||||
UPDATE pes SET IsWinner = 1
|
||||
FROM PurchaseEvaluationSuppliers pes
|
||||
INNER JOIN PurchaseEvaluations pe ON pe.Id = pes.PurchaseEvaluationId
|
||||
WHERE pe.SelectedSupplierId IS NOT NULL AND pes.SupplierId = pe.SelectedSupplierId;");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsWinner",
|
||||
table: "PurchaseEvaluationSuppliers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AllowApproverFinalize",
|
||||
table: "ApprovalWorkflowLevels");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,6 +202,11 @@ namespace SolutionErp.Infrastructure.Persistence.Migrations
|
||||
.HasColumnType("bit")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<bool>("AllowApproverFinalize")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bit")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<bool>("AllowApproverSkipToFinal")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bit")
|
||||
@ -5275,6 +5280,11 @@ namespace SolutionErp.Infrastructure.Persistence.Migrations
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("nvarchar(200)");
|
||||
|
||||
b.Property<bool>("IsWinner")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bit")
|
||||
.HasDefaultValue(false);
|
||||
|
||||
b.Property<string>("Note")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)");
|
||||
|
||||
Reference in New Issue
Block a user