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.Entitlements;
|
||||||
using Marco.Pms.Model.Expenses;
|
using Marco.Pms.Model.Expenses;
|
||||||
using Marco.Pms.Model.OrganizationModel;
|
using Marco.Pms.Model.OrganizationModel;
|
||||||
using Marco.Pms.Model.ServiceProject;
|
|
||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.ViewModels.Activities;
|
using Marco.Pms.Model.ViewModels.Activities;
|
||||||
using Marco.Pms.Model.ViewModels.AttendanceVM;
|
using Marco.Pms.Model.ViewModels.AttendanceVM;
|
||||||
@ -1679,61 +1678,25 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
query = query.Where(jt => jt.ProjectId == projectId.Value);
|
query = query.Where(jt => jt.ProjectId == projectId.Value);
|
||||||
}
|
}
|
||||||
var jobs = await query
|
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();
|
.ToListAsync();
|
||||||
|
|
||||||
var inProgressJobIds = jobs.Where(jt => jt.StatusId == InProgressStatus).Select(jt => jt.Id).ToList();
|
|
||||||
|
|
||||||
var latestTagIns = await _context.JobAttendance
|
var assignedJobs = jobs.Where(jt => jt.StatusId == AssignedStatus).Take(5).OrderBy(jt => jt.Title).ToList();
|
||||||
.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
|
var inProgressJobs = jobs.Where(jt => jt.StatusId == InProgressStatus).Take(5).OrderBy(jt => jt.Title).ToList();
|
||||||
.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 selfAssignedJobs = jobs.Where(jt => jobIds.Contains(jt.Id)).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 response = new
|
var response = new
|
||||||
{
|
{
|
||||||
|
|||||||
@ -249,67 +249,67 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
var hasViewAllEmployeesPermission = viewAllTask.Result;
|
var hasViewAllEmployeesPermission = viewAllTask.Result;
|
||||||
var hasViewTeamMembersPermission = viewTeamTask.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>();
|
List<Employee> employees = new List<Employee>();
|
||||||
|
|
||||||
// Step 4: Query based on permission
|
var employeeQuery = _context.Employees
|
||||||
if (hasViewAllEmployeesPermission && !projectId.HasValue)
|
|
||||||
{
|
|
||||||
// OrganizationId needs to be retrieved from loggedInEmployee or context based on your app's structure
|
|
||||||
var employeeQuery = _context.Employees
|
|
||||||
.AsNoTracking() // Optimize EF query for read-only operation[web:1][web:13][web:18]
|
.AsNoTracking() // Optimize EF query for read-only operation[web:1][web:13][web:18]
|
||||||
.Include(e => e.JobRole)
|
.Include(e => e.JobRole)
|
||||||
.Where(e => e.OrganizationId == organizationId);
|
.Where(e => e.IsActive != showInactive);
|
||||||
|
|
||||||
employeeQuery = showInactive
|
// Step 4: Query based on permission
|
||||||
? employeeQuery.Where(e => !e.IsActive)
|
if (hasViewAllEmployeesPermission)
|
||||||
: employeeQuery.Where(e => e.IsActive);
|
{
|
||||||
|
// OrganizationId needs to be retrieved from loggedInEmployee or context based on your app's structure
|
||||||
employees = await employeeQuery.ToListAsync();
|
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);
|
_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
|
// Only active team members with limited permission
|
||||||
var projectIds = await _projectServices.GetMyProjectIdsAsync(loggedInEmployee, tenantId);
|
|
||||||
|
|
||||||
employees = await _context.ProjectAllocations
|
employees = await employeeQuery
|
||||||
.AsNoTracking()
|
.Where(e => employeeIds.Contains(e.Id))
|
||||||
.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!)
|
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
_logger.LogInfo("Employee list fetched with limited access (active only). Count: {Count}", employees.Count);
|
_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
|
// Step 5: Map to view model
|
||||||
result = employees.Select(e => _mapper.Map<EmployeeVM>(e)).Distinct().ToList();
|
result = employees.Select(e => _mapper.Map<EmployeeVM>(e)).Distinct().ToList();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user