using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Domain.Entities.Donations; using Domain.Entities.Donations.ValueObject; using Microsoft.EntityFrameworkCore; namespace Application.Features.Api.DonationGoal.SaveConfig; internal sealed class Handler(IAppDbContext db) : ICommandHandler { public async Task Handle(Command r, CancellationToken ct) { // 기간 중복 검증 (활성 + 기간 설정된 경우) if (r.IsActive && r.StartAt.HasValue && r.EndAt.HasValue) { var overlap = await db.DonationGoalConfig .AnyAsync(c => c.ChannelID == r.ChannelID && c.IsActive && c.ID != (r.ID ?? 0) && c.StartAt != null && c.EndAt != null && c.StartAt < r.EndAt && c.EndAt > r.StartAt, ct ); if (overlap) { throw new InvalidOperationException("해당 기간에 이미 활성화된 목표가 존재합니다."); } } if (r.ID.HasValue) { var config = await db.DonationGoalConfig.FirstOrDefaultAsync(c => c.ID == r.ID.Value && c.ChannelID == r.ChannelID, ct); if (config is null) { throw new KeyNotFoundException("설정을 찾을 수 없습니다."); } config.Update( r.Title, (GoalWidgetStyle)r.Style, r.StartAmount, r.TargetAmount, r.StartAt, r.EndAt, r.IsShowPercent, r.BarColor, r.BarBackgroundColor, r.BarHeightPx, r.TitleFontSizePx, r.TitleFontColor, r.AmountFontSizePx, r.AmountFontColor, r.TitleFontFamily, r.AmountFontFamily, r.IsActive ); } else { var config = DonationGoalConfig.Create(r.ChannelID, r.MemberID, r.Title, r.TargetAmount); config.Update( r.Title, (GoalWidgetStyle)r.Style, r.StartAmount, r.TargetAmount, r.StartAt, r.EndAt, r.IsShowPercent, r.BarColor, r.BarBackgroundColor, r.BarHeightPx, r.TitleFontSizePx, r.TitleFontColor, r.AmountFontSizePx, r.AmountFontColor, r.TitleFontFamily, r.AmountFontFamily, r.IsActive ); db.DonationGoalConfig.Add(config); } await db.SaveChangesAsync(ct); } }