diff --git a/fe-admin/src/components/pe/PeDetailTabs.tsx b/fe-admin/src/components/pe/PeDetailTabs.tsx index dd753d5..2d1689e 100644 --- a/fe-admin/src/components/pe/PeDetailTabs.tsx +++ b/fe-admin/src/components/pe/PeDetailTabs.tsx @@ -161,19 +161,22 @@ export function PeDetailTabs({
- {/* Section 1 — đúng spec form FO-PHIẾU TRÌNH KÝ CHỌN TP/NCC */} + {/* Section order (Session 20): Hạng mục lên đầu sau Thông tin gói thầu. + BE auto-tạo 1 hạng mục mặc định (tên = TenGoiThau, giá trị = ngân sách) + khi Create. NCC tham gia tạm giữ riêng — Chunk B sẽ gộp NCC nested + expand dưới mỗi hạng mục. */}
-
+
+ +
+
-
+
-
- -
{mode === 'workspace' && (
diff --git a/fe-user/src/components/pe/PeDetailTabs.tsx b/fe-user/src/components/pe/PeDetailTabs.tsx index dd753d5..2d1689e 100644 --- a/fe-user/src/components/pe/PeDetailTabs.tsx +++ b/fe-user/src/components/pe/PeDetailTabs.tsx @@ -161,19 +161,22 @@ export function PeDetailTabs({
- {/* Section 1 — đúng spec form FO-PHIẾU TRÌNH KÝ CHỌN TP/NCC */} + {/* Section order (Session 20): Hạng mục lên đầu sau Thông tin gói thầu. + BE auto-tạo 1 hạng mục mặc định (tên = TenGoiThau, giá trị = ngân sách) + khi Create. NCC tham gia tạm giữ riêng — Chunk B sẽ gộp NCC nested + expand dưới mỗi hạng mục. */}
-
+
+ +
+
-
+
-
- -
{mode === 'workspace' && (
diff --git a/src/Backend/SolutionErp.Application/PurchaseEvaluations/PurchaseEvaluationFeatures.cs b/src/Backend/SolutionErp.Application/PurchaseEvaluations/PurchaseEvaluationFeatures.cs index 5381ef3..c37c4e1 100644 --- a/src/Backend/SolutionErp.Application/PurchaseEvaluations/PurchaseEvaluationFeatures.cs +++ b/src/Backend/SolutionErp.Application/PurchaseEvaluations/PurchaseEvaluationFeatures.cs @@ -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; }