using Marco.Pms.DataAccess.Data; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Projects; using Microsoft.EntityFrameworkCore; namespace MarcoBMS.Services.Helpers { public class ProjectsHelper { private readonly ApplicationDbContext _context; private readonly RolesHelper _rolesHelper; public ProjectsHelper(ApplicationDbContext context, RolesHelper rolesHelper) { _context = context; _rolesHelper = rolesHelper; } public async Task> GetAllProjectByTanentID(Guid tanentID) { List alloc = await _context.Projects.Where(c => c.TenantId == tanentID).ToListAsync(); return alloc; } public async Task> GetProjectByEmployeeID(Guid employeeID) { List alloc = await _context.ProjectAllocations.Where(c => c.EmployeeId == employeeID && c.IsActive == true).Include(c => c.Project).ToListAsync(); return alloc; } public async Task> GetTeamByProject(Guid TenantId, Guid ProjectId, bool IncludeInactive) { if (IncludeInactive) { var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId).Include(e => e.Employee).ToListAsync(); return employees; } else { var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId && c.IsActive == true).Include(e => e.Employee).ToListAsync(); return employees; } } public async Task> GetMyProjects(Guid tenantId, Employee LoggedInEmployee) { List featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeID(LoggedInEmployee.Id); string[] projectsId = []; List projects = new List(); // Define a common queryable base for projects IQueryable projectQuery = _context.Projects.Where(c => c.TenantId == tenantId); // 2. Optimized Project Retrieval Logic // User with permission 'manage project' can see all projects if (featurePermission != null && featurePermission.Exists(c => c.Id.ToString() == "172fc9b6-755b-4f62-ab26-55c34a330614")) { // If GetAllProjectByTanentID is already optimized and directly returns IQueryable or // directly executes with ToListAsync(), keep it. // If it does more complex logic or extra trips, consider inlining here. projects = await projectQuery.ToListAsync(); // Directly query the context } else { // 3. Efficiently get project allocations and then filter projects // Load allocations only once var allocation = await GetProjectByEmployeeID(LoggedInEmployee.Id); // If there are no allocations, return an empty list early if (allocation == null || !allocation.Any()) { return new List(); } // Use LINQ's Contains for efficient filtering by ProjectId var projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList(); // Get distinct Guids // Filter projects based on the retrieved ProjectIds projects = await projectQuery.Where(c => projectIds.Contains(c.Id)).ToListAsync(); } return projects; } } }