using Managing.Application.Abstractions.Repositories; using Managing.Domain.MoneyManagements; using Managing.Domain.Users; using Microsoft.EntityFrameworkCore; namespace Managing.Infrastructure.Databases.PostgreSql; public class PostgreSqlSettingsRepository : ISettingsRepository { private readonly ManagingDbContext _context; public PostgreSqlSettingsRepository(ManagingDbContext context) { _context = context; } public async Task DeleteMoneyManagementAsync(string name) { var moneyManagement = await _context.MoneyManagements .AsTracking() .FirstOrDefaultAsync(m => m.Name == name) .ConfigureAwait(false); if (moneyManagement != null) { _context.MoneyManagements.Remove(moneyManagement); await _context.SaveChangesAsync().ConfigureAwait(false); } } public async Task DeleteMoneyManagementsAsync() { var moneyManagements = await _context.MoneyManagements .AsTracking() .ToListAsync() .ConfigureAwait(false); _context.MoneyManagements.RemoveRange(moneyManagements); await _context.SaveChangesAsync().ConfigureAwait(false); } public async Task GetMoneyManagement(string name) { var moneyManagement = await _context.MoneyManagements .AsNoTracking() .Include(m => m.User) .FirstOrDefaultAsync(m => m.Name == name) .ConfigureAwait(false); return PostgreSqlMappers.Map(moneyManagement); } public async Task> GetMoneyManagementsAsync() { var moneyManagements = await _context.MoneyManagements .AsNoTracking() .Include(m => m.User) .ToListAsync() .ConfigureAwait(false); return PostgreSqlMappers.Map(moneyManagements); } public async Task InsertMoneyManagement(LightMoneyManagement request, User user) { // Check if money management already exists for the same user var existingMoneyManagement = await _context.MoneyManagements .AsNoTracking() .FirstOrDefaultAsync(m => m.Name == request.Name && ((user == null && m.UserName == null) || (user != null && m.UserName == user.Name))) .ConfigureAwait(false); if (existingMoneyManagement != null) { throw new InvalidOperationException( $"Money management with name '{request.Name}' already exists for user '{user?.Name}'"); } var entity = PostgreSqlMappers.Map(request); entity.UserName = user?.Name; // Set the UserId if user is provided if (user != null) { var userEntity = await _context.Users .AsNoTracking() .FirstOrDefaultAsync(u => u.Name == user.Name) .ConfigureAwait(false); entity.UserId = userEntity?.Id; } await _context.MoneyManagements.AddAsync(entity).ConfigureAwait(false); await _context.SaveChangesAsync().ConfigureAwait(false); } public async Task UpdateMoneyManagementAsync(LightMoneyManagement moneyManagement, User user) { var entity = await _context.MoneyManagements .AsTracking() .FirstOrDefaultAsync(m => m.Name == moneyManagement.Name && (user != null && m.UserName == user.Name)) .ConfigureAwait(false); if (entity != null) { entity.Timeframe = moneyManagement.Timeframe; entity.StopLoss = moneyManagement.StopLoss; entity.TakeProfit = moneyManagement.TakeProfit; entity.Leverage = moneyManagement.Leverage; entity.UserName = user?.Name; entity.UpdatedAt = DateTime.UtcNow; await _context.SaveChangesAsync().ConfigureAwait(false); } } // User-specific implementations public async Task GetMoneyManagementByUser(User user, string name) { var moneyManagement = await _context.MoneyManagements .AsNoTracking() .Include(m => m.User) .FirstOrDefaultAsync(m => m.Name == name && m.UserName != null && m.UserName == user.Name) .ConfigureAwait(false); return PostgreSqlMappers.Map(moneyManagement); } public async Task> GetMoneyManagementsByUserAsync(User user) { var moneyManagements = await _context.MoneyManagements .AsNoTracking() .Include(m => m.User) .Where(m => m.UserName != null && m.UserName == user.Name) .ToListAsync() .ConfigureAwait(false); return PostgreSqlMappers.Map(moneyManagements); } public async Task DeleteMoneyManagementByUserAsync(User user, string name) { var moneyManagement = await _context.MoneyManagements .AsTracking() .FirstOrDefaultAsync(m => m.Name == name && m.UserName != null && m.UserName == user.Name) .ConfigureAwait(false); if (moneyManagement != null) { _context.MoneyManagements.Remove(moneyManagement); await _context.SaveChangesAsync().ConfigureAwait(false); } } public async Task DeleteMoneyManagementsByUserAsync(User user) { var moneyManagements = await _context.MoneyManagements .AsTracking() .Where(m => m.UserName != null && m.UserName == user.Name) .ToListAsync() .ConfigureAwait(false); _context.MoneyManagements.RemoveRange(moneyManagements); await _context.SaveChangesAsync().ConfigureAwait(false); } }