112 lines
4.6 KiB
C#
112 lines
4.6 KiB
C#
using Marco.Pms.DataAccess.Data;
|
|
using Marco.Pms.Model.Employees;
|
|
using Marco.Pms.Model.Entitlements;
|
|
using Marco.Pms.Model.Projects;
|
|
using Marco.Pms.Services.Helpers;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace MarcoBMS.Services.Helpers
|
|
{
|
|
public class ProjectsHelper
|
|
{
|
|
private readonly ApplicationDbContext _context;
|
|
private readonly RolesHelper _rolesHelper;
|
|
private readonly CacheUpdateHelper _cache;
|
|
|
|
|
|
public ProjectsHelper(ApplicationDbContext context, RolesHelper rolesHelper, CacheUpdateHelper cache)
|
|
{
|
|
_context = context;
|
|
_rolesHelper = rolesHelper;
|
|
_cache = cache;
|
|
}
|
|
|
|
public async Task<List<Project>> GetAllProjectByTanentID(Guid tanentID)
|
|
{
|
|
List<Project> alloc = await _context.Projects.Where(c => c.TenantId == tanentID).ToListAsync();
|
|
return alloc;
|
|
}
|
|
|
|
public async Task<List<ProjectAllocation>> GetProjectByEmployeeID(Guid employeeID)
|
|
{
|
|
List<ProjectAllocation> alloc = await _context.ProjectAllocations.Where(c => c.EmployeeId == employeeID && c.IsActive == true).Include(c => c.Project).ToListAsync();
|
|
return alloc;
|
|
}
|
|
|
|
public async Task<List<ProjectAllocation>> 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<List<Project>> GetMyProjects(Guid tenantId, Employee LoggedInEmployee)
|
|
{
|
|
string[] projectsId = [];
|
|
List<Project> projects = new List<Project>();
|
|
|
|
var projectIds = await _cache.GetProjects(LoggedInEmployee.Id);
|
|
|
|
if (projectIds != null)
|
|
{
|
|
projects = await _context.Projects.Where(p => projectIds.Contains(p.Id)).ToListAsync();
|
|
}
|
|
else
|
|
{
|
|
var featurePermissionIds = await _cache.GetPermissions(LoggedInEmployee.Id);
|
|
if (featurePermissionIds == null)
|
|
{
|
|
List<FeaturePermission> featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeID(LoggedInEmployee.Id);
|
|
featurePermissionIds = featurePermission.Select(fp => fp.Id).ToList();
|
|
}
|
|
// Define a common queryable base for projects
|
|
IQueryable<Project> projectQuery = _context.Projects.Where(c => c.TenantId == tenantId);
|
|
|
|
// 2. Optimized Project Retrieval Logic
|
|
// User with permission 'manage project' can see all projects
|
|
if (featurePermissionIds != null && featurePermissionIds.Contains(Guid.Parse("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<Project>();
|
|
}
|
|
|
|
// Use LINQ's Contains for efficient filtering by ProjectId
|
|
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();
|
|
|
|
}
|
|
projectIds = projects.Select(p => p.Id).ToList();
|
|
await _cache.AddProjects(LoggedInEmployee.Id, projectIds);
|
|
}
|
|
|
|
return projects;
|
|
}
|
|
|
|
}
|
|
}
|