shoc-backend/SeaHaven.DataServices/Implementation/UserDataService.cs
2026-09-16 21:52:44 -03:00

201 lines
7.5 KiB
C#

using Data.SeaHavenIndustries;
using Microsoft.EntityFrameworkCore;
using SeaHaven.DataServices.Dto;
using SeaHaven.DataServices.Interfaces;
namespace SeaHaven.DataServices.Implementation
{
public class UserDataService : IUserDataService
{
private readonly ApplicationDbContext _context;
public UserDataService(ApplicationDbContext context)
{
_context = context;
}
public async Task<ApplicationUser?> GetByIdAsync(string id)
{
return await _context.Users.FindAsync(id);
}
public async Task<IEnumerable<ApplicationUser>> GetAllAsync()
{
return await _context.Users.ToListAsync();
}
public async Task<ApplicationUser?> GetByEmailAsync(string email)
{
return await _context.Users
.FirstOrDefaultAsync(u => u.Email == email);
}
public async Task<bool> ExistsAsync(string id)
{
return await _context.Users.AnyAsync(u => u.Id == id);
}
public async Task<IReadOnlyList<UserListRowData>> GetAllForListAsync(CancellationToken cancellationToken)
{
return await _context.Users
.AsNoTracking()
.Select(user => new UserListRowData
{
Id = user.Id,
RoleName = (
from userRole in _context.UserRoles
join role in _context.Roles on userRole.RoleId equals role.Id
where userRole.UserId == user.Id
select role.Name).FirstOrDefault() ?? user.PhoneNumber,
Email = user.Email,
Name = ((user.FirstName ?? "") + " " + (user.LastName ?? "")).Trim(),
CreatedDate = user.CreatedDate,
Status = user.UniqueName,
Phone = user.Contact ?? user.PhoneNumber,
Color = user.Color,
PendingRegistration = user.PendingRegistration,
ServiceAreas = user.ServiceAreas
.OrderBy(area => area.Area)
.Select(area => area.Area)
.ToList()
})
.ToListAsync(cancellationToken);
}
public async Task<UserProfileData?> GetProfileAsync(string id, CancellationToken cancellationToken)
{
return await _context.Users
.AsNoTracking()
.Where(u => u.Id == id)
.Select(user => new UserProfileData
{
Id = user.Id,
FirstName = user.FirstName,
Email = user.Email,
Contact = user.Contact,
CreatedDate = user.CreatedDate
})
.FirstOrDefaultAsync(cancellationToken);
}
public async Task<bool> UpdateProfileAsync(
string id,
string? name,
string? email,
string? contact,
CancellationToken cancellationToken)
{
var updated = await _context.Users
.Where(user => user.Id == id)
.ExecuteUpdateAsync(
setters => setters
.SetProperty(user => user.FirstName, name)
.SetProperty(user => user.Email, email)
.SetProperty(user => user.Contact, contact),
cancellationToken);
return updated == 1;
}
public async Task<ApplicationUser?> GetForEditAsync(string id, CancellationToken cancellationToken)
{
return await _context.Users
.Where(w => w.Id == id)
.FirstOrDefaultAsync(cancellationToken);
}
public async Task<bool> IsAccountOwnerAsync(string userId, CancellationToken cancellationToken)
{
return await _context.Users
.AsNoTracking()
.Where(user => user.Id == userId)
.Select(user => user.IsAccountOwner)
.SingleOrDefaultAsync(cancellationToken);
}
public async Task<ApplicationUser?> GetByEmailNormalizedAsync(string email, CancellationToken cancellationToken)
{
var normalizedEmail = email.Trim().ToUpperInvariant();
return await _context.Users
.AsNoTracking()
.Where(user => user.NormalizedEmail == normalizedEmail)
.FirstOrDefaultAsync(cancellationToken);
}
public async Task UpdateUserAsync(ApplicationUser user, CancellationToken cancellationToken)
{
_context.Users.Update(user);
await _context.SaveChangesAsync(cancellationToken);
}
public async Task DeleteUserWithCascadeAsync(ApplicationUser user, CancellationToken cancellationToken)
{
var id = user.Id;
await using var transaction = await _context.Database.BeginTransactionAsync(cancellationToken);
await _context.workOrders
.Where(workOrder => workOrder.AssignTo == id)
.ExecuteUpdateAsync(
setters => setters.SetProperty(workOrder => workOrder.AssignTo, (string?)null),
cancellationToken);
await _context.Comments
.Where(comment => comment.UserId == id)
.ExecuteUpdateAsync(
setters => setters.SetProperty(comment => comment.UserId, (string?)null),
cancellationToken);
await _context.Templates
.Where(template => template.AssignTo == id)
.ExecuteUpdateAsync(
setters => setters.SetProperty(template => template.AssignTo, (string?)null),
cancellationToken);
await _context.UserRoles
.Where(role => role.UserId == id)
.ExecuteDeleteAsync(cancellationToken);
await _context.UserPermissionOverrides
.Where(permissionOverride => permissionOverride.UserId == id)
.ExecuteDeleteAsync(cancellationToken);
await _context.Users
.Where(existingUser => existingUser.Id == id)
.ExecuteDeleteAsync(cancellationToken);
await transaction.CommitAsync(cancellationToken);
}
public async Task<string?> GetEmailByIdAsync(
string userId, CancellationToken cancellationToken)
{
return await _context.Users
.AsNoTracking()
.Where(user => user.Id == userId)
.Select(user => user.Email)
.FirstOrDefaultAsync(cancellationToken);
}
public async Task<IReadOnlyDictionary<string, string>> GetDisplayNamesByIdsAsync(IEnumerable<string> ids)
{
var idList = ids
.Where(id => !string.IsNullOrWhiteSpace(id))
.Distinct(StringComparer.Ordinal)
.ToList();
if (idList.Count == 0)
return new Dictionary<string, string>(StringComparer.Ordinal);
var users = await _context.Users
.AsNoTracking()
.Where(u => idList.Contains(u.Id))
.Select(u => new { u.Id, u.FirstName, u.LastName })
.ToListAsync();
return users.ToDictionary(
u => u.Id,
u => $"{u.FirstName ?? ""} {u.LastName ?? ""}".Trim(),
StringComparer.Ordinal);
}
}
}