[CLAUDE] Master: nạp master data thật từ Excel (62 dự án + 71 hạng mục + 3 NCC) + Project +4 cột (Mig 48)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m33s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m33s
Nạp master data công ty từ file Excel 'HẠNG MỤC CÔNG VIỆC DỰ ÁN': - 62 Projects (Mã + Năm; tên/CĐT/địa điểm/gói thầu cho ~6 dự án có chi tiết) - 71 WorkItems: Vật tư 16 · Thầu phụ 30 · MEP 9 · Thiết bị 16 - 3 Suppliers (TRUONGGIANG/TANPHU/TGN) Mig 48 AddProjectMasterFields: Project +4 cột nullable (Year/Investor/Location/Package) + ProjectFeatures DTO/Create/Update + ProjectsPage form ×2 app (SHA256 mirror). SeedRealMasterDataAsync per-code idempotent, UNGATED → reaches prod (coexist demo). FLOCK01 collision → skip (demo wins). Verify: build 0-err · test 216 PASS · runtime Dev proof (data landed, Investor col populates). Provenance: scripts/master-import-data.generated.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -18,7 +18,11 @@ public record ProjectDto(
|
||||
decimal? BudgetTotal,
|
||||
string? Note,
|
||||
DateTime CreatedAt,
|
||||
DateTime? UpdatedAt);
|
||||
DateTime? UpdatedAt,
|
||||
int? Year,
|
||||
string? Investor,
|
||||
string? Location,
|
||||
string? Package);
|
||||
|
||||
// ===================== LIST =====================
|
||||
public record ListProjectsQuery : PagedRequest, IRequest<PagedResult<ProjectDto>>;
|
||||
@ -44,7 +48,7 @@ public class ListProjectsQueryHandler(IApplicationDbContext db) : IRequestHandle
|
||||
var total = await query.CountAsync(ct);
|
||||
var items = await query
|
||||
.Skip((request.Page - 1) * request.PageSize).Take(request.PageSize)
|
||||
.Select(x => new ProjectDto(x.Id, x.Code, x.Name, x.StartDate, x.EndDate, x.ManagerUserId, x.BudgetTotal, x.Note, x.CreatedAt, x.UpdatedAt))
|
||||
.Select(x => new ProjectDto(x.Id, x.Code, x.Name, x.StartDate, x.EndDate, x.ManagerUserId, x.BudgetTotal, x.Note, x.CreatedAt, x.UpdatedAt, x.Year, x.Investor, x.Location, x.Package))
|
||||
.ToListAsync(ct);
|
||||
return new PagedResult<ProjectDto>(items, total, request.Page, request.PageSize);
|
||||
}
|
||||
@ -59,14 +63,15 @@ public class GetProjectQueryHandler(IApplicationDbContext db) : IRequestHandler<
|
||||
{
|
||||
var x = await db.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Id == request.Id, ct)
|
||||
?? throw new NotFoundException("Project", request.Id);
|
||||
return new ProjectDto(x.Id, x.Code, x.Name, x.StartDate, x.EndDate, x.ManagerUserId, x.BudgetTotal, x.Note, x.CreatedAt, x.UpdatedAt);
|
||||
return new ProjectDto(x.Id, x.Code, x.Name, x.StartDate, x.EndDate, x.ManagerUserId, x.BudgetTotal, x.Note, x.CreatedAt, x.UpdatedAt, x.Year, x.Investor, x.Location, x.Package);
|
||||
}
|
||||
}
|
||||
|
||||
// ===================== CREATE =====================
|
||||
public record CreateProjectCommand(
|
||||
string Code, string Name, DateTime? StartDate, DateTime? EndDate,
|
||||
Guid? ManagerUserId, decimal? BudgetTotal, string? Note) : IRequest<Guid>;
|
||||
Guid? ManagerUserId, decimal? BudgetTotal, string? Note,
|
||||
int? Year, string? Investor, string? Location, string? Package) : IRequest<Guid>;
|
||||
|
||||
public class CreateProjectCommandValidator : AbstractValidator<CreateProjectCommand>
|
||||
{
|
||||
@ -75,6 +80,9 @@ public class CreateProjectCommandValidator : AbstractValidator<CreateProjectComm
|
||||
RuleFor(x => x.Code).NotEmpty().MaximumLength(50);
|
||||
RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
|
||||
RuleFor(x => x.BudgetTotal).GreaterThanOrEqualTo(0).When(x => x.BudgetTotal.HasValue);
|
||||
RuleFor(x => x.Investor).MaximumLength(250);
|
||||
RuleFor(x => x.Location).MaximumLength(500);
|
||||
RuleFor(x => x.Package).MaximumLength(300);
|
||||
RuleFor(x => x).Must(x => !x.StartDate.HasValue || !x.EndDate.HasValue || x.EndDate >= x.StartDate)
|
||||
.WithMessage("Ngày kết thúc phải sau ngày bắt đầu");
|
||||
}
|
||||
@ -91,6 +99,7 @@ public class CreateProjectCommandHandler(IApplicationDbContext db) : IRequestHan
|
||||
Code = request.Code, Name = request.Name,
|
||||
StartDate = request.StartDate, EndDate = request.EndDate,
|
||||
ManagerUserId = request.ManagerUserId, BudgetTotal = request.BudgetTotal, Note = request.Note,
|
||||
Year = request.Year, Investor = request.Investor, Location = request.Location, Package = request.Package,
|
||||
};
|
||||
db.Projects.Add(entity);
|
||||
await db.SaveChangesAsync(ct);
|
||||
@ -101,7 +110,8 @@ public class CreateProjectCommandHandler(IApplicationDbContext db) : IRequestHan
|
||||
// ===================== UPDATE =====================
|
||||
public record UpdateProjectCommand(
|
||||
Guid Id, string Code, string Name, DateTime? StartDate, DateTime? EndDate,
|
||||
Guid? ManagerUserId, decimal? BudgetTotal, string? Note) : IRequest;
|
||||
Guid? ManagerUserId, decimal? BudgetTotal, string? Note,
|
||||
int? Year, string? Investor, string? Location, string? Package) : IRequest;
|
||||
|
||||
public class UpdateProjectCommandValidator : AbstractValidator<UpdateProjectCommand>
|
||||
{
|
||||
@ -111,6 +121,9 @@ public class UpdateProjectCommandValidator : AbstractValidator<UpdateProjectComm
|
||||
RuleFor(x => x.Code).NotEmpty().MaximumLength(50);
|
||||
RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
|
||||
RuleFor(x => x.BudgetTotal).GreaterThanOrEqualTo(0).When(x => x.BudgetTotal.HasValue);
|
||||
RuleFor(x => x.Investor).MaximumLength(250);
|
||||
RuleFor(x => x.Location).MaximumLength(500);
|
||||
RuleFor(x => x.Package).MaximumLength(300);
|
||||
RuleFor(x => x).Must(x => !x.StartDate.HasValue || !x.EndDate.HasValue || x.EndDate >= x.StartDate)
|
||||
.WithMessage("Ngày kết thúc phải sau ngày bắt đầu");
|
||||
}
|
||||
@ -131,6 +144,10 @@ public class UpdateProjectCommandHandler(IApplicationDbContext db) : IRequestHan
|
||||
entity.ManagerUserId = request.ManagerUserId;
|
||||
entity.BudgetTotal = request.BudgetTotal;
|
||||
entity.Note = request.Note;
|
||||
entity.Year = request.Year;
|
||||
entity.Investor = request.Investor;
|
||||
entity.Location = request.Location;
|
||||
entity.Package = request.Package;
|
||||
await db.SaveChangesAsync(ct);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user