Optimized the get employee list API
This commit is contained in:
parent
6c35bd3bf8
commit
f7e707557a
@ -4,7 +4,6 @@ using Marco.Pms.Model.Dtos.Attendance;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.Expenses;
|
||||
using Marco.Pms.Model.OrganizationModel;
|
||||
using Marco.Pms.Model.ServiceProject;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Model.ViewModels.Activities;
|
||||
using Marco.Pms.Model.ViewModels.AttendanceVM;
|
||||
@ -1679,61 +1678,25 @@ namespace Marco.Pms.Services.Controllers
|
||||
query = query.Where(jt => jt.ProjectId == projectId.Value);
|
||||
}
|
||||
var jobs = await query
|
||||
.Select(jt => new
|
||||
{
|
||||
Id = jt.Id,
|
||||
StatusId = jt.StatusId,
|
||||
Project = jt.Project!.Name,
|
||||
AssignedBy = jt.CreatedBy!.FirstName + " " + jt.CreatedBy.LastName,
|
||||
Title = jt.Title,
|
||||
AssignedAt = jt.CreatedAt,
|
||||
|
||||
})
|
||||
.OrderByDescending(jt => jt.AssignedAt)
|
||||
.ToListAsync();
|
||||
|
||||
var inProgressJobIds = jobs.Where(jt => jt.StatusId == InProgressStatus).Select(jt => jt.Id).ToList();
|
||||
|
||||
var latestTagIns = await _context.JobAttendance
|
||||
.Include(ja => ja.Employee)
|
||||
.Where(ja => inProgressJobIds.Contains(ja.JobTicketId)
|
||||
&& ja.Action == TAGGING_MARK_TYPE.TAG_IN
|
||||
&& ja.TaggedOutAt == null
|
||||
&& ja.TenantId == tenantId)
|
||||
.GroupBy(ja => ja.JobTicketId)
|
||||
.Select(g => new
|
||||
{
|
||||
JobTicketId = g.Key,
|
||||
Employee = g.Select(ja => ja.Employee).FirstOrDefault(),
|
||||
TagInAt = g.Max(ja => ja.TaggedInAt)
|
||||
})
|
||||
.ToListAsync();
|
||||
var assignedJobs = jobs.Where(jt => jt.StatusId == AssignedStatus).Take(5).OrderBy(jt => jt.Title).ToList();
|
||||
|
||||
var assignedJobs = jobs
|
||||
.Where(jt => jt.StatusId == AssignedStatus)
|
||||
.Take(5)
|
||||
.Select(jt => new
|
||||
{
|
||||
Project = jt.Project!.Name,
|
||||
AssignedBy = jt.CreatedBy!.FirstName + " " + jt.CreatedBy.LastName,
|
||||
Title = jt.Title,
|
||||
AssignedAt = jt.CreatedAt,
|
||||
var inProgressJobs = jobs.Where(jt => jt.StatusId == InProgressStatus).Take(5).OrderBy(jt => jt.Title).ToList();
|
||||
|
||||
})
|
||||
.ToList();
|
||||
var inProgressJobs = jobs
|
||||
.Where(jt => jt.StatusId == InProgressStatus)
|
||||
.Take(5)
|
||||
.Select(jt => new
|
||||
{
|
||||
Project = jt.Project!.Name,
|
||||
AssignedBy = jt.CreatedBy!.FirstName + " " + jt.CreatedBy.LastName,
|
||||
Title = jt.Title,
|
||||
AssignedAt = jt.CreatedAt,
|
||||
|
||||
})
|
||||
.ToList();
|
||||
var selfAssignedJobs = jobs
|
||||
.Where(jt => jobIds.Contains(jt.Id))
|
||||
.Take(5)
|
||||
.Select(jt => new
|
||||
{
|
||||
Project = jt.Project!.Name,
|
||||
AssignedBy = jt.CreatedBy!.FirstName + " " + jt.CreatedBy.LastName,
|
||||
Title = jt.Title,
|
||||
AssignedAt = jt.CreatedAt,
|
||||
|
||||
})
|
||||
.ToList();
|
||||
var selfAssignedJobs = jobs.Where(jt => jobIds.Contains(jt.Id)).Take(5).OrderBy(jt => jt.Title).ToList();
|
||||
|
||||
var response = new
|
||||
{
|
||||
|
||||
@ -249,67 +249,67 @@ namespace MarcoBMS.Services.Controllers
|
||||
var hasViewAllEmployeesPermission = viewAllTask.Result;
|
||||
var hasViewTeamMembersPermission = viewTeamTask.Result;
|
||||
|
||||
if (!hasViewAllEmployeesPermission && !hasViewTeamMembersPermission)
|
||||
{
|
||||
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} does not have permission to view employees", loggedInEmployee.Id);
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access denied", "User does not have permission to view employees", 403));
|
||||
}
|
||||
|
||||
var projectIds = await _projectServices.GetMyProjectIdsAsync(loggedInEmployee, tenantId);
|
||||
|
||||
var projectAllocationQuery = _context.ProjectAllocations
|
||||
.AsNoTracking()
|
||||
.Where(pa =>
|
||||
projectIds.Contains(pa.ProjectId)
|
||||
&& pa.IsActive
|
||||
&& pa.TenantId == tenantId);
|
||||
|
||||
if (projectId.HasValue)
|
||||
projectAllocationQuery = projectAllocationQuery.Where(pa => pa.ProjectId == projectId);
|
||||
|
||||
var employeeIds = await projectAllocationQuery
|
||||
.Select(pa => pa.EmployeeId)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
List<Employee> employees = new List<Employee>();
|
||||
|
||||
// Step 4: Query based on permission
|
||||
if (hasViewAllEmployeesPermission && !projectId.HasValue)
|
||||
{
|
||||
// OrganizationId needs to be retrieved from loggedInEmployee or context based on your app's structure
|
||||
var employeeQuery = _context.Employees
|
||||
var employeeQuery = _context.Employees
|
||||
.AsNoTracking() // Optimize EF query for read-only operation[web:1][web:13][web:18]
|
||||
.Include(e => e.JobRole)
|
||||
.Where(e => e.OrganizationId == organizationId);
|
||||
.Where(e => e.IsActive != showInactive);
|
||||
|
||||
employeeQuery = showInactive
|
||||
? employeeQuery.Where(e => !e.IsActive)
|
||||
: employeeQuery.Where(e => e.IsActive);
|
||||
|
||||
employees = await employeeQuery.ToListAsync();
|
||||
// Step 4: Query based on permission
|
||||
if (hasViewAllEmployeesPermission)
|
||||
{
|
||||
// OrganizationId needs to be retrieved from loggedInEmployee or context based on your app's structure
|
||||
if (projectId.HasValue)
|
||||
{
|
||||
employeeQuery = employeeQuery
|
||||
.Where(e => employeeIds.Contains(e.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
employeeQuery = employeeQuery
|
||||
.Where(e => e.OrganizationId == organizationId || employeeIds.Contains(e.Id));
|
||||
}
|
||||
employees = await employeeQuery
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
_logger.LogInfo("Employee list fetched with full access. Count: {Count}", employees.Count);
|
||||
}
|
||||
else if (hasViewTeamMembersPermission && !showInactive && !projectId.HasValue)
|
||||
else if (hasViewTeamMembersPermission && !showInactive)
|
||||
{
|
||||
// Only active team members with limited permission
|
||||
var projectIds = await _projectServices.GetMyProjectIdsAsync(loggedInEmployee, tenantId);
|
||||
|
||||
employees = await _context.ProjectAllocations
|
||||
.AsNoTracking()
|
||||
.Include(pa => pa.Employee)
|
||||
.ThenInclude(e => e!.JobRole)
|
||||
.Where(pa =>
|
||||
projectIds.Contains(pa.ProjectId)
|
||||
&& pa.IsActive
|
||||
&& pa.Employee != null
|
||||
&& pa.Employee.IsActive
|
||||
&& pa.TenantId == tenantId)
|
||||
.Select(pa => pa.Employee!)
|
||||
employees = await employeeQuery
|
||||
.Where(e => employeeIds.Contains(e.Id))
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
_logger.LogInfo("Employee list fetched with limited access (active only). Count: {Count}", employees.Count);
|
||||
}
|
||||
|
||||
// If a specific projectId is provided, override employee fetching to ensure strict project context
|
||||
if (projectId.HasValue)
|
||||
{
|
||||
employees = await _context.ProjectAllocations
|
||||
.AsNoTracking()
|
||||
.Include(pa => pa.Employee)
|
||||
.ThenInclude(e => e!.JobRole)
|
||||
.Where(pa =>
|
||||
pa.ProjectId == projectId
|
||||
&& pa.IsActive
|
||||
&& pa.Employee != null
|
||||
&& pa.Employee.IsActive
|
||||
&& pa.TenantId == tenantId)
|
||||
.Select(pa => pa.Employee!)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
_logger.LogInfo("Employee list fetched for specific project. ProjectId: {ProjectId}. Count: {Count}",
|
||||
projectId, employees.Count);
|
||||
}
|
||||
|
||||
// Step 5: Map to view model
|
||||
result = employees.Select(e => _mapper.Map<EmployeeVM>(e)).Distinct().ToList();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user