Added new API to get list of employees assigned to project and filtered by services and organizations #140

Merged
ashutosh.nehete merged 1 commits from Ashutosh_Task#1360 into Organization_Management 2025-09-26 06:02:25 +00:00
3 changed files with 193 additions and 0 deletions

View File

@ -319,6 +319,14 @@ namespace MarcoBMS.Services.Controllers
return StatusCode(response.StatusCode, response);
}
[HttpGet("get/task/team/{projectId}")]
public async Task<IActionResult> GetProjectTeamByServiceAndOrganization(Guid projectId, [FromQuery] Guid? serviceId, [FromQuery] Guid? organizationId)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetProjectTeamByServiceAndOrganizationAsync(projectId, serviceId, organizationId, tenantId, loggedInEmployee);
return StatusCode(response.StatusCode, response);
}
#endregion
#region =================================================================== Project InfraStructure Get APIs ===================================================================

View File

@ -1166,6 +1166,190 @@ namespace Marco.Pms.Services.Service
500);
}
}
public async Task<ApiResponse<object>> GetProjectTeamByServiceAndOrganization(Guid projectId, Guid? serviceId, Guid? organizationId, Guid tenantId, Employee loggedInEmployee)
{
using var scope = _serviceScopeFactory.CreateScope();
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
var projectTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.Projects.FirstOrDefaultAsync(p => p.Id == projectId && p.TenantId == tenantId);
});
var tenantTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.Tenants.FirstOrDefaultAsync(t => t.Id == tenantId);
});
await Task.WhenAll(projectTask, tenantTask);
var project = projectTask.Result;
var tenant = tenantTask.Result;
if (project == null || tenant == null)
{
_logger.LogWarning("Project {ProjectId} not found in database for tenant {TenantId}", projectId, tenantId);
return ApiResponse<object>.ErrorResponse("Project not found", "Project not found", 404);
}
// Check if the logged-in employee has permission for the requested project
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
if (!hasProjectPermission)
{
_logger.LogWarning("User {EmployeeId} attempts to get employees for project {ProjectId} without permission", loggedInEmployee.Id, projectId);
return ApiResponse<object>.ErrorResponse("Access denied", "User does not have access to view the employees for this project", 403);
}
var organizationQuery = _context.ProjectOrgMappings
.Include(po => po.ProjectService)
.Where(po => po.ProjectService != null && po.ProjectService.ProjectId == projectId);
if (loggedInEmployee.OrganizationId != project.PMCId && loggedInEmployee.OrganizationId != project.PromoterId && loggedInEmployee.OrganizationId != tenant.OrganizationId)
{
organizationQuery = organizationQuery.Where(po => po.ParentOrganizationId == loggedInEmployee.OrganizationId || po.OrganizationId == loggedInEmployee.OrganizationId);
}
var organizationIds = await organizationQuery.Select(po => po.OrganizationId).ToListAsync();
if (loggedInEmployee.OrganizationId == project.PMCId || loggedInEmployee.OrganizationId == project.PromoterId || loggedInEmployee.OrganizationId == tenant.OrganizationId)
{
organizationIds.Add(project.PMCId);
organizationIds.Add(project.PromoterId);
organizationIds.Add(tenant.OrganizationId);
}
var projectAllocationQuery = _context.ProjectAllocations
.Include(pa => pa.Employee)
.ThenInclude(e => e!.JobRole)
.Where(pa => pa.ProjectId == projectId && pa.Employee != null && organizationIds.Contains(pa.Employee.OrganizationId));
if (serviceId.HasValue)
{
projectAllocationQuery = projectAllocationQuery.Where(pa => pa.ServiceId == serviceId);
}
if (organizationId.HasValue)
{
projectAllocationQuery = projectAllocationQuery.Where(pa => pa.Employee != null && pa.Employee.OrganizationId == organizationId);
}
var projectAllocations = await projectAllocationQuery
.ToListAsync();
var result = projectAllocations.Select(pa => _mapper.Map<EmployeeVM>(pa.Employee)).Distinct().ToList();
return ApiResponse<object>.SuccessResponse(result, "Employee list fetched successfully", 200);
}
public async Task<ApiResponse<object>> GetProjectTeamByServiceAndOrganizationAsync(
Guid projectId, Guid? serviceId, Guid? organizationId, Guid tenantId, Employee loggedInEmployee)
{
_logger.LogDebug("Started fetching project team. ProjectId: {ProjectId}, ServiceId: {ServiceId}, OrganizationId: {OrganizationId}, TenantId: {TenantId}, EmployeeId: {EmployeeId}",
projectId, serviceId ?? Guid.Empty, organizationId ?? Guid.Empty, tenantId, loggedInEmployee.Id);
try
{
// Use a single DbContext instance
using var scope = _serviceScopeFactory.CreateScope();
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
// Fetch project and tenant entities in parallel
var projectTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.Projects.FirstOrDefaultAsync(p => p.Id == projectId && p.TenantId == tenantId);
});
var tenantTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.Tenants.FirstOrDefaultAsync(t => t.Id == tenantId);
});
await Task.WhenAll(projectTask, tenantTask);
var project = await projectTask;
var tenant = await tenantTask;
if (project == null || tenant == null)
{
_logger.LogWarning("Project {ProjectId} or Tenant {TenantId} not found in the database.", projectId, tenantId);
return ApiResponse<object>.ErrorResponse("Project or tenant not found", "Project or tenant record not found", 404);
}
// Check permission to view project team
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
if (!hasProjectPermission)
{
_logger.LogWarning("Access denied: User {EmployeeId} tried to get team for Project {ProjectId}", loggedInEmployee.Id, projectId);
return ApiResponse<object>.ErrorResponse("Access denied", "User does not have permission to view this project team", 403);
}
// Query ProjectOrgMappings for associated organizations
var organizationQuery = _context.ProjectOrgMappings
.Include(po => po.ProjectService)
.Where(po => po.ProjectService != null && po.ProjectService.ProjectId == projectId);
// Restrict organizations for non-PMC/Promoter users
if (loggedInEmployee.OrganizationId != project.PMCId &&
loggedInEmployee.OrganizationId != project.PromoterId &&
loggedInEmployee.OrganizationId != tenant.OrganizationId)
{
organizationQuery = organizationQuery.Where(po =>
po.ParentOrganizationId == loggedInEmployee.OrganizationId ||
po.OrganizationId == loggedInEmployee.OrganizationId);
}
var organizationIds = await organizationQuery.Select(po => po.OrganizationId).Distinct().ToListAsync();
// Add PMC, Promoter, Tenant organizations for privileged users
if (loggedInEmployee.OrganizationId == project.PMCId ||
loggedInEmployee.OrganizationId == project.PromoterId ||
loggedInEmployee.OrganizationId == tenant.OrganizationId)
{
organizationIds.Add(project.PMCId);
organizationIds.Add(project.PromoterId);
organizationIds.Add(tenant.OrganizationId);
}
organizationIds = organizationIds.Distinct().ToList();
// Build ProjectAllocation query for employees by service/organization if specified
var allocationQuery = _context.ProjectAllocations
.Include(pa => pa.Employee)
.ThenInclude(e => e!.JobRole)
.Where(pa => pa.ProjectId == projectId
&& pa.Employee != null
&& organizationIds.Contains(pa.Employee.OrganizationId));
if (serviceId.HasValue)
{
allocationQuery = allocationQuery.Where(pa => pa.ServiceId == serviceId);
}
if (organizationId.HasValue)
{
allocationQuery = allocationQuery.Where(pa => pa.Employee != null && pa.Employee.OrganizationId == organizationId);
}
var projectAllocations = await allocationQuery.ToListAsync();
// Map to distinct EmployeeVM results
var employeeList = projectAllocations
.Select(pa => _mapper.Map<EmployeeVM>(pa.Employee))
.Distinct()
.ToList();
_logger.LogInfo("Fetched {EmployeeCount} employees for Project {ProjectId}.", employeeList.Count, projectId);
return ApiResponse<object>.SuccessResponse(employeeList, "Employee list fetched successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occurred while fetching project team for ProjectId: {ProjectId}", projectId);
return ApiResponse<object>.ErrorResponse("Internal error", "An error occurred while fetching the project team", 500);
}
}
#endregion

View File

@ -23,6 +23,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
Task<ApiResponse<object>> GetProjectsByEmployeeAsync(Guid employeeId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<List<ProjectAllocationVM>>> AssigneProjectsToEmployeeAsync(List<ProjectsAllocationDto> projectAllocationDtos, Guid employeeId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetProjectByEmployeeBasicAsync(Guid employeeId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetProjectTeamByServiceAndOrganizationAsync(Guid projectId, Guid? serviceId, Guid? organizationId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetInfraDetailsAsync(Guid projectId, Guid? serviceId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetWorkItemsAsync(Guid workAreaId, Guid? serviceId, Guid tenantId, Employee loggedInEmployee);