using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using LCU.API.Internal.Operations.IncentiveApiLib.Persistence; using LCU.Library.Internal.IncentiveApiModels.Common; using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using LCU.Library.Internal.IncentiveApiModels.Requests; using Microsoft.EntityFrameworkCore; namespace LCU.API.Internal.Operations.IncentiveApiLib.Repositories; public class UserRepository : BaseRepository, IUserRepository { public UserRepository(IApplicationDbContext context) : base(context) { } public async Task> GetAllUserSummariesAsync() { return await _context.AppUsers .Select(x => new UserSummary() { EmployeeId = x.EmployeeId, AdEmail = x.AdEmail, FullName = x.FullName, ManagerKey = x.ManagerKey, Terminated = x.Terminated }) .OrderBy(x => x.EmployeeId) .ToListAsync(); } public IReadOnlyCollection GetTerminatedUsersAsync(MonthRange monthRange) { if (!monthRange.IsSingleMonth) { throw new ArgumentException("Can only request terminated employees for a single month"); } return _context.AppUsers .Where(x => x.Terminated != null && x.Terminated >= monthRange.StartTime && x.Terminated <= monthRange.EndTime) .ToList() .GroupJoin(_context.PayoutLineItems, user => user.EmployeeId, pli => pli.EmployeeId, (x, pli) => new UserSummary() { EmployeeId = x.EmployeeId, AdEmail = x.AdEmail, FullName = x.FullName, ManagerKey = x.ManagerKey, Terminated = x.Terminated, AssociatedPayouts = pli.ToList() }) .OrderBy(x => x.EmployeeId) .ToList(); } public async Task> GetAllUsersAsync() { return await _context.AppUsers .Include(user => user.Departments) .ThenInclude(userDept => userDept.Department) .ToListAsync(); } public async Task> GetAllUsersToPayoutAsync(MonthRange range) { return await _context.AppUsers .AsNoTracking() .Include(user => user.Departments) .ThenInclude(userDept => userDept.Department) .Where(x => x.Terminated == null && x.Departments.Any(y => y.Department.State == DepartmentState.Active && y.StartDate.Date <= range.StartTime.Date && (y.EndDate == null || y.EndDate >= range.EndTime.Date))) .Distinct() .ToListAsync(); } public async Task FindUserAsync(string employeeId, string adEmail) { if (!string.IsNullOrWhiteSpace(employeeId)) { return await FindUserByEmployeeIdAsync(employeeId); } return await FindUserByAdEmailAsync(adEmail); } public async Task FindUserByEmployeeIdAsync(string employeeId) { return await _context.AppUsers .Include(user => user.AdditionalPermissions) .Include(user => user.Departments) .ThenInclude(userDept => userDept.Department) .Include(user => user.Assignments) .Where(user => user.EmployeeId == employeeId) .OrderByDescending(user => user.Terminated) .FirstOrDefaultAsync(); } public async Task FindUserByAdEmailAsync(string adEmail) { return await _context.AppUsers .Include(user => user.AdditionalPermissions) .Include(user => user.Departments) .ThenInclude(userDept => userDept.Department) .Include(user => user.Assignments) .Where(user => user.AdEmail.ToLower() == adEmail.ToLower()) .OrderByDescending(user => user.Terminated) .FirstOrDefaultAsync(); } public async Task FindActiveUserByEmployeeIdAsync(string employeeId) { return await _context.AppUsers .Include(user => user.AdditionalPermissions) .Include(user => user.Departments) .ThenInclude(userDept => userDept.Department) .Include(user => user.Assignments) .Where(user => user.EmployeeId == employeeId && user.Terminated == null) .FirstOrDefaultAsync(); } public async Task FindActiveUserByAdEmailAsync(string adEmail) { return await _context.AppUsers .Include(user => user.AdditionalPermissions) .Include(user => user.Departments) .ThenInclude(userDept => userDept.Department) .Include(user => user.Assignments) .Where(user => user.AdEmail.ToLower() == adEmail.ToLower() && user.Terminated == null) .FirstOrDefaultAsync(); } public async Task> FindUsersByHomeDepartmentsAsync(List homeDepartments) { return await _context.AppUsers.Where(user => homeDepartments.Contains(user.HomeDepartment)).ToListAsync(); } public async Task> FindUsersByBaseRolesAsync(List baseRoles) { return await _context.AppUsers.Where(user => baseRoles.Contains(user.BaseRole)).ToListAsync(); } public async Task SaveUserAsync(AppUser newAppUser) { await _context.AppUsers.AddAsync(newAppUser); return newAppUser; } public async Task> SaveUserRangeAsync(List newUsers) { await _context.AppUsers.AddRangeAsync(newUsers); return newUsers; } public async Task> SearchUsersAsync(UserSearchRequest userSearchRequest) { var users = _context.AppUsers.Include(user => user.Departments).AsQueryable(); if (!string.IsNullOrWhiteSpace(userSearchRequest.Query)) { var cleanQuery = userSearchRequest.Query.ToLower().Trim(); var emailQuery = BuildEmailQuery(cleanQuery); users = users.Where(user => user.AdEmail.ToLower().Contains(cleanQuery) || user.AdEmail.ToLower().Contains(emailQuery) || user.FullName.ToLower().Contains(cleanQuery) || user.EmployeeId.ToLower().Contains(cleanQuery)); } if (!string.IsNullOrWhiteSpace(userSearchRequest.FirstName)) { users = users.Where(user => user.FullName.ToLower().Contains(userSearchRequest.FirstName.ToLower())); } if (!string.IsNullOrWhiteSpace(userSearchRequest.LastName)) { users = users.Where(user => user.FullName.ToLower().Contains(userSearchRequest.LastName.ToLower())); } if (!string.IsNullOrWhiteSpace(userSearchRequest.MiddleInit)) { users = users.Where(user => user.FullName.ToLower().EndsWith($" {userSearchRequest.MiddleInit.ToLower()}")); } if (!string.IsNullOrWhiteSpace(userSearchRequest.Role)) { var foundRoles = Role.SearchRoles(userSearchRequest.Role); users = users.Where(user => user.Departments.Any(dept => foundRoles.Contains(dept.Role))); } if (userSearchRequest.DnaOrgNbr != null) { users = users.Where(user => user.Departments.Any(dept => dept.Department.DnaOrgNbr == userSearchRequest.DnaOrgNbr)); } return await users.ToListAsync(); } private string BuildEmailQuery(string cleanQuery) { if (cleanQuery.Contains(",")) { var transform = cleanQuery.Split(","); if (transform?.Length == 2) { return transform[1].Trim() + transform[0].Trim(); } } else if (cleanQuery.Contains(" ")) { return cleanQuery.Replace(" ", ""); } return cleanQuery; } }