[CLAUDE] PurchaseEvaluation: Chunk A — reorder section Hạng mục lên #2 + auto-tạo 1 row mặc định
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m20s

Session 20 UI restructure (3 yêu cầu user). Chunk A xử lý:

BE — CreatePurchaseEvaluationCommandHandler thêm 1 PurchaseEvaluationDetail
mặc định khi tạo phiếu mới:
  - GroupCode="01", GroupName="Hạng mục chính"
  - NoiDung = TenGoiThau (tên gói thầu)
  - DonGiaNganSach = ThanhTienNganSach = Budget.TongNganSach (nếu link)
    fallback BudgetManualAmount fallback 0
  - DonViTinh="gói", KL=1, Order=1
  - Changelog entry kèm theo (audit Insert Detail)

FE — Đổi thứ tự 5 section trong PeDetailTabs.tsx (mirror 2 app):
  1. Thông tin gói thầu (giữ)
  2. Hạng mục + Báo giá (chuyển từ #4 lên #2)
  3. Chọn NCC / TP (từ #2 xuống #3)
  4. NCC / TP tham gia (từ #3 xuống #4 — Chunk B sẽ gộp vào #2 nested)
  5. Ý kiến cấp duyệt (giữ)

Q1=a: Giữ Section "Chọn NCC TP thắng thầu" riêng (rõ UX).
Q2=a "1 hạng mục trước tiên": auto-seed đủ, multi-hạng-mục defer.

Verify:
- dotnet build SolutionErp.slnx — 0 warning / 0 error
- Test pass mặc định skip (Phase 9 UAT iteration, Q4 user public luôn)

Pending Chunk B: Nested grid Hạng mục → NCC expand inline edit
Pending Chunk C: Section 5 gộp đồng cấp cùng Phòng (1 box / Step)
Pending Chunk D: Docs S20 changelog + STATUS + HANDOFF

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-05-11 09:54:12 +07:00
parent 7710d4345c
commit 9dee00da01
3 changed files with 50 additions and 12 deletions

View File

@ -77,6 +77,7 @@ public class CreatePurchaseEvaluationCommandHandler(
// Validate Budget link (nếu có): cùng Project + Phase=DaDuyet (chỉ cho
// pick ngân sách đã duyệt mới được dùng làm reference đối chiếu).
decimal? linkedBudgetTotal = null;
if (request.BudgetId is Guid bid)
{
var bg = await db.Budgets.AsNoTracking()
@ -86,6 +87,7 @@ public class CreatePurchaseEvaluationCommandHandler(
throw new ConflictException("Ngân sách phải cùng dự án với phiếu.");
if (bg.Phase != Domain.Budgets.BudgetPhase.DaDuyet)
throw new ConflictException("Chỉ link được ngân sách đã duyệt.");
linkedBudgetTotal = bg.TongNganSach;
}
var entity = new PurchaseEvaluation
@ -124,6 +126,36 @@ public class CreatePurchaseEvaluationCommandHandler(
Summary = $"Tạo phiếu {entity.MaPhieu} — {entity.TenGoiThau}",
});
// Auto-seed 1 Hạng mục mặc định lấy tên + giá trị từ gói thầu / ngân sách
// — user yêu cầu Session 20: hạng mục là đơn vị làm việc chính, NCC expand
// dưới hạng mục → cần có sẵn 1 row khi vào Detail. Có thể edit lại sau.
var defaultBudgetValue = linkedBudgetTotal ?? request.BudgetManualAmount ?? 0m;
var defaultDetail = new PurchaseEvaluationDetail
{
PurchaseEvaluationId = entity.Id,
GroupCode = "01",
GroupName = "Hạng mục chính",
NoiDung = request.TenGoiThau,
DonViTinh = "gói",
KhoiLuongNganSach = 1m,
KhoiLuongThiCong = 1m,
DonGiaNganSach = defaultBudgetValue,
ThanhTienNganSach = defaultBudgetValue,
Order = 1,
};
db.PurchaseEvaluationDetails.Add(defaultDetail);
db.PurchaseEvaluationChangelogs.Add(new PurchaseEvaluationChangelog
{
PurchaseEvaluationId = entity.Id,
EntityType = PurchaseEvaluationEntityType.Detail,
EntityId = defaultDetail.Id,
Action = ChangelogAction.Insert,
PhaseAtChange = entity.Phase,
UserId = currentUser.UserId,
Summary = $"Hạng mục mặc định — {defaultDetail.NoiDung}",
});
await db.SaveChangesAsync(ct);
return entity.Id;
}