Added API to get list of combined projects and add current in get status list API

This commit is contained in:
ashutosh.nehete 2025-11-18 16:57:55 +05:30
parent 6dfbf655ef
commit f4e6fab3d6
6 changed files with 226 additions and 134 deletions

View File

@ -228,7 +228,7 @@ namespace Marco.Pms.Services.Controllers
// --- Step 1: Get the list of projects the user can access ---
// This query is more efficient as it only selects the IDs needed.
var projects = await _projectServices.GetMyProjectIdsAsync(tenantId, loggedInEmployee);
var projects = await _projectServices.GetMyProjectIdsAsync(loggedInEmployee, tenantId);
var accessibleActiveProjectIds = await _context.Projects
.Where(p => p.ProjectStatusId == ActiveId && projects.Contains(p.Id))
@ -354,7 +354,7 @@ namespace Marco.Pms.Services.Controllers
// --- Logic for ALL Accessible Projects ---
// 2c. Get a list of all projects the user is allowed to see.
var accessibleProjectIds = await _projectServices.GetMyProjectIdsAsync(tenantId, loggedInEmployee);
var accessibleProjectIds = await _projectServices.GetMyProjectIdsAsync(loggedInEmployee, tenantId);
if (!accessibleProjectIds.Any())
{

View File

@ -270,7 +270,7 @@ namespace MarcoBMS.Services.Controllers
else if (hasViewTeamMembersPermission && !showInactive && !projectId.HasValue)
{
// Only active team members with limited permission
var projectIds = await _projectServices.GetMyProjectIdsAsync(tenantId, loggedInEmployee);
var projectIds = await _projectServices.GetMyProjectIdsAsync(loggedInEmployee, tenantId);
employees = await _context.ProjectAllocations
.AsNoTracking()

View File

@ -40,12 +40,21 @@ namespace MarcoBMS.Services.Controllers
#region =================================================================== Project Get APIs ===================================================================
[HttpGet("list/basic/all")]
public async Task<IActionResult> GetBothProjectBasicList([FromQuery] string? searchString)
{
// Get the current user
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetBothProjectBasicListAsync(searchString, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpGet("list/basic")]
public async Task<IActionResult> GetAllProjectsBasic([FromQuery] bool provideAll = false)
{
// Get the current user
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetAllProjectsBasicAsync(provideAll, tenantId, loggedInEmployee);
var response = await _projectServices.GetAllProjectsBasicAsync(provideAll, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -70,7 +79,7 @@ namespace MarcoBMS.Services.Controllers
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid request data provided.", errors, 400));
}
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetAllProjectsAsync(pageNumber, pageSize, tenantId, loggedInEmployee);
var response = await _projectServices.GetAllProjectsAsync(pageNumber, pageSize, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -93,11 +102,10 @@ namespace MarcoBMS.Services.Controllers
}
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetProjectAsync(id, tenantId, loggedInEmployee);
var response = await _projectServices.GetProjectAsync(id, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpGet("details/{id}")]
public async Task<IActionResult> GetProjectDetails([FromRoute] Guid id)
{
@ -116,7 +124,7 @@ namespace MarcoBMS.Services.Controllers
// Step 2: Get logged-in employee
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetProjectDetailsAsync(id, tenantId, loggedInEmployee);
var response = await _projectServices.GetProjectDetailsAsync(id, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -137,7 +145,7 @@ namespace MarcoBMS.Services.Controllers
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetProjectDetailsOldAsync(id, tenantId, loggedInEmployee);
var response = await _projectServices.GetProjectDetailsOldAsync(id, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -158,7 +166,7 @@ namespace MarcoBMS.Services.Controllers
// 2. Prepare data without I/O
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.CreateProjectAsync(projectDto, tenantId, loggedInEmployee);
var response = await _projectServices.CreateProjectAsync(projectDto, loggedInEmployee, tenantId);
if (response.Success)
{
var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Create_Project", Response = response.Data };
@ -188,7 +196,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.UpdateProjectAsync(id, updateProjectDto, tenantId, loggedInEmployee);
var response = await _projectServices.UpdateProjectAsync(id, updateProjectDto, loggedInEmployee, tenantId);
if (response.Success)
{
var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Update_Project", Response = response.Data };
@ -214,7 +222,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetEmployeeByProjectIdAsync(projectId, organizationId, includeInactive, tenantId, loggedInEmployee);
var response = await _projectServices.GetEmployeeByProjectIdAsync(projectId, organizationId, includeInactive, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -231,7 +239,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetProjectAllocationAsync(projectId, organizationId, serviceId, includeInactive, tenantId, loggedInEmployee);
var response = await _projectServices.GetProjectAllocationAsync(projectId, organizationId, serviceId, includeInactive, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -248,7 +256,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.ManageAllocationAsync(projectAllocationDot, tenantId, loggedInEmployee);
var response = await _projectServices.ManageAllocationAsync(projectAllocationDot, loggedInEmployee, tenantId);
if (response.Success)
{
List<Guid> employeeIds = response.Data.Select(pa => pa.EmployeeId).ToList();
@ -274,7 +282,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetProjectsByEmployeeAsync(employeeId, tenantId, loggedInEmployee);
var response = await _projectServices.GetProjectsByEmployeeAsync(employeeId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -291,7 +299,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetProjectByEmployeeBasicAsync(employeeId, tenantId, loggedInEmployee);
var response = await _projectServices.GetProjectByEmployeeBasicAsync(employeeId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -308,7 +316,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.AssigneProjectsToEmployeeAsync(projectAllocationDtos, employeeId, tenantId, loggedInEmployee);
var response = await _projectServices.AssigneProjectsToEmployeeAsync(projectAllocationDtos, employeeId, loggedInEmployee, tenantId);
if (response.Success)
{
List<Guid> projectIds = response.Data.Select(pa => pa.ProjectId).ToList();
@ -323,7 +331,7 @@ namespace MarcoBMS.Services.Controllers
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);
var response = await _projectServices.GetProjectTeamByServiceAndOrganizationAsync(projectId, serviceId, organizationId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -344,7 +352,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetInfraDetailsAsync(projectId, serviceId, tenantId, loggedInEmployee);
var response = await _projectServices.GetInfraDetailsAsync(projectId, serviceId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -362,7 +370,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetWorkItemsAsync(workAreaId, serviceId, tenantId, loggedInEmployee);
var response = await _projectServices.GetWorkItemsAsync(workAreaId, serviceId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -382,7 +390,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetTasksByEmployeeAsync(employeeId, fromDate.Value, toDate.Value, tenantId, loggedInEmployee);
var response = await _projectServices.GetTasksByEmployeeAsync(employeeId, fromDate.Value, toDate.Value, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -403,7 +411,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var serviceResponse = await _projectServices.ManageProjectInfraAsync(infraDtos, tenantId, loggedInEmployee);
var serviceResponse = await _projectServices.ManageProjectInfraAsync(infraDtos, loggedInEmployee, tenantId);
var response = serviceResponse.Response;
var notification = serviceResponse.Notification;
if (notification != null)
@ -427,7 +435,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.CreateProjectTaskAsync(workItemDtos, tenantId, loggedInEmployee);
var response = await _projectServices.CreateProjectTaskAsync(workItemDtos, loggedInEmployee, tenantId);
if (response.Success)
{
List<Guid> workAreaIds = response.Data.Select(pa => pa.WorkItem?.WorkAreaId ?? Guid.Empty).ToList();
@ -453,7 +461,7 @@ namespace MarcoBMS.Services.Controllers
// --- Step 2: Prepare data without I/O ---
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var serviceResponse = await _projectServices.DeleteProjectTaskAsync(id, tenantId, loggedInEmployee);
var serviceResponse = await _projectServices.DeleteProjectTaskAsync(id, loggedInEmployee, tenantId);
var response = serviceResponse.Response;
var notification = serviceResponse.Notification;
if (notification != null)
@ -471,7 +479,7 @@ namespace MarcoBMS.Services.Controllers
public async Task<IActionResult> ManageProjectLevelPermission([FromBody] ProjctLevelPermissionDto model)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.ManageProjectLevelPermissionAsync(model, tenantId, loggedInEmployee);
var response = await _projectServices.ManageProjectLevelPermissionAsync(model, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -479,7 +487,7 @@ namespace MarcoBMS.Services.Controllers
public async Task<IActionResult> GetAssignedProjectLevelPermission(Guid employeeId, Guid projectId)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetAssignedProjectLevelPermissionAsync(employeeId, projectId, tenantId, loggedInEmployee);
var response = await _projectServices.GetAssignedProjectLevelPermissionAsync(employeeId, projectId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -495,7 +503,7 @@ namespace MarcoBMS.Services.Controllers
public async Task<IActionResult> AssignProjectLevelModules()
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.AssignProjectLevelModulesAsync(tenantId, loggedInEmployee);
var response = await _projectServices.AssignProjectLevelModulesAsync(loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -503,7 +511,7 @@ namespace MarcoBMS.Services.Controllers
public async Task<IActionResult> GetEmployeeToWhomProjectLevelAssigned(Guid projectId)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetEmployeeToWhomProjectLevelAssignedAsync(projectId, tenantId, loggedInEmployee);
var response = await _projectServices.GetEmployeeToWhomProjectLevelAssignedAsync(projectId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -515,7 +523,7 @@ namespace MarcoBMS.Services.Controllers
public async Task<IActionResult> AssignServiceToProject(Guid projectId)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetAssignedServiceToProjectAsync(projectId, tenantId, loggedInEmployee);
var response = await _projectServices.GetAssignedServiceToProjectAsync(projectId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -524,7 +532,7 @@ namespace MarcoBMS.Services.Controllers
public async Task<IActionResult> AssignServiceToProject([FromBody] AssignServiceDto model)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.AssignServiceToProjectAsync(model, tenantId, loggedInEmployee);
var response = await _projectServices.AssignServiceToProjectAsync(model, loggedInEmployee, tenantId);
if (response.Success)
{
string message = response.Message;
@ -539,7 +547,7 @@ namespace MarcoBMS.Services.Controllers
public async Task<IActionResult> DeassignServiceToProject([FromBody] DeassignServiceDto model)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.DeassignServiceToProjectAsync(model, tenantId, loggedInEmployee);
var response = await _projectServices.DeassignServiceToProjectAsync(model, loggedInEmployee, tenantId);
if (response.Success)
{
string message = response.Message;
@ -557,14 +565,15 @@ namespace MarcoBMS.Services.Controllers
public async Task<IActionResult> GetAssignedOrganizationsToProject(Guid projectId)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetAssignedOrganizationsToProjectAsync(projectId, tenantId, loggedInEmployee);
var response = await _projectServices.GetAssignedOrganizationsToProjectAsync(projectId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpGet("get/assigned/organization/dropdown/{projectId}")]
public async Task<IActionResult> GetAssignedOrganizationsToProjectForDropdownAsync(Guid projectId)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.GetAssignedOrganizationsToProjectForDropdownAsync(projectId, tenantId, loggedInEmployee);
var response = await _projectServices.GetAssignedOrganizationsToProjectForDropdownAsync(projectId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}

View File

@ -58,22 +58,21 @@ namespace Marco.Pms.Services.Service
#region =================================================================== Job Status APIs ===================================================================
/// <summary>
/// Retrieves job status records filtered by optional statusId and projectId within tenant context.
/// If both statusId and projectId are specified, returns next possible statuses based on team role mappings.
/// Otherwise, returns all global statuses ordered by name.
/// Retrieves job statuses based on optional filtering by status ID, project ID, team role, and tenant context.
/// Returns allowed next statuses for a given status in a project or all statuses if no filters provided.
/// </summary>
/// <param name="statusId">Optional current job status ID to find next possible statuses.</param>
/// <param name="projectId">Optional project ID for filtering based on employee's allocation.</param>
/// <param name="loggedInEmployee">Employee requesting the statuses.</param>
/// <param name="tenantId">Tenant identifier for multi-tenant scope.</param>
/// <returns>ApiResponse containing list of job statuses or error details.</returns>
/// <param name="statusId">Optional current job status ID to retrieve next allowed statuses.</param>
/// <param name="projectId">Optional project ID to scope the status mappings.</param>
/// <param name="loggedInEmployee">Currently authenticated employee.</param>
/// <param name="tenantId">Tenant ID for multi-tenant isolation.</param>
/// <returns>ApiResponse containing the list of job statuses or error information.</returns>
public async Task<ApiResponse<object>> GetJobStatusAsync(Guid? statusId, Guid? projectId, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogDebug("GetJobStatusAsync called by employee {EmployeeId} in tenant {TenantId}", loggedInEmployee.Id, tenantId);
_logger.LogDebug("GetJobStatusAsync called by EmployeeId {EmployeeId} in TenantId {TenantId}", loggedInEmployee.Id, tenantId);
if (tenantId == Guid.Empty)
{
_logger.LogWarning("TenantId is missing in GetJobStatusAsync request by employee {EmployeeId}", loggedInEmployee.Id);
_logger.LogWarning("Invalid tenant context (empty TenantId) in GetJobStatusAsync for EmployeeId {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "Invalid tenant context.", 403);
}
@ -83,11 +82,13 @@ namespace Marco.Pms.Services.Service
if (statusId.HasValue && projectId.HasValue)
{
var statusMappingQuery = _context.JobStatusMappings
// Base query for status mappings scoped by tenant and status filter, including related statuses
var baseMappingQuery = _context.JobStatusMappings
.Include(jsm => jsm.Status)
.Include(jsm => jsm.NextStatus)
.Where(jsm => jsm.StatusId == statusId && jsm.NextStatus != null && jsm.TenantId == tenantId);
.Where(jsm => jsm.StatusId == statusId && jsm.Status != null && jsm.NextStatus != null && jsm.TenantId == tenantId);
// Find employee's latest project allocation to determine team role
// Find employee's most recent active allocation to get team role context
var projectAllocation = await _context.ServiceProjectAllocations
.Where(spa => spa.ProjectId == projectId && spa.EmployeeId == loggedInEmployee.Id && spa.TenantId == tenantId && spa.IsActive)
.OrderByDescending(spa => spa.AssignedAt)
@ -95,35 +96,46 @@ namespace Marco.Pms.Services.Service
var teamRoleId = projectAllocation?.TeamRoleId;
// Check if mappings exist for the employee's team role; fallback to null team role mappings
var hasTeamStatusMapping = projectAllocation != null &&
await statusMappingQuery.AnyAsync(jsm => jsm.TeamRoleId == teamRoleId);
// Determine if mappings exist for employee's team role, fallback to null team role otherwise
bool hasTeamSpecificMapping = projectAllocation != null &&
await baseMappingQuery.AnyAsync(jsm => jsm.TeamRoleId == teamRoleId);
if (hasTeamStatusMapping)
IQueryable<JobStatusMapping> filteredMappingQuery = hasTeamSpecificMapping
? baseMappingQuery.Where(jsm => jsm.TeamRoleId == teamRoleId)
: baseMappingQuery.Where(jsm => jsm.TeamRoleId == null);
var mappedStatuses = await filteredMappingQuery.ToListAsync();
// Aggregate next statuses plus the current status, ordered by Level for meaningful sequence
statuses = mappedStatuses.Select(jsm => jsm.NextStatus!).ToList();
var currentStatus = mappedStatuses.Select(jsm => jsm.Status!).FirstOrDefault();
if (currentStatus != null && !statuses.Any(js => js.Id == currentStatus.Id))
{
statusMappingQuery = statusMappingQuery.Where(jsm => jsm.TeamRoleId == teamRoleId);
statuses.Add(currentStatus);
}
statuses = statuses.OrderBy(js => js.Level).ToList();
}
else
{
statusMappingQuery = statusMappingQuery.Where(jsm => jsm.TeamRoleId == null);
// No filters: return all job statuses ordered by Level ascending
statuses = await _context.JobStatus
.OrderBy(js => js.Level)
.ToListAsync();
}
statuses = await statusMappingQuery.Select(jsm => jsm.NextStatus!).OrderBy(js => js.Level).ToListAsync();
}
else
{
// No specific filters - return all job statuses ordered by name
statuses = await _context.JobStatus.OrderBy(js => js.Level).ToListAsync();
}
_logger.LogInfo("Fetched {Count} job status records for tenant {TenantId}", statuses.Count, tenantId);
_logger.LogInfo("GetJobStatusAsync fetched {Count} status record(s) for TenantId {TenantId}", statuses.Count, tenantId);
return ApiResponse<object>.SuccessResponse(statuses, $"{statuses.Count} job status record(s) fetched successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error fetching job status for employee {EmployeeId} in tenant {TenantId}", loggedInEmployee.Id, tenantId);
return ApiResponse<object>.ErrorResponse("Internal Server Error", "An error occurred while fetching job statuses. Please try again later.", 500);
_logger.LogError(ex, "Error retrieving job statuses for EmployeeId {EmployeeId} in TenantId {TenantId}", loggedInEmployee.Id, tenantId);
return ApiResponse<object>.ErrorResponse(
"Internal Server Error",
"An error occurred while fetching job statuses. Please try again later.",
500);
}
}

View File

@ -53,8 +53,82 @@ namespace Marco.Pms.Services.Service
}
#region =================================================================== Project Get APIs ===================================================================
/// <summary>
/// Retrieves a combined list of basic infrastructure and active service projects accessible by the logged-in employee within a tenant.
/// </summary>
/// <param name="searchString">Optional search term to filter projects by name (if implemented).</param>
/// <param name="loggedInEmployee">Authenticated employee requesting the data.</param>
/// <param name="tenantId">Tenant identifier to ensure multi-tenant data isolation.</param>
/// <returns>Returns an ApiResponse containing the distinct combined list of basic project view models or an error response.</returns>
public async Task<ApiResponse<object>> GetBothProjectBasicListAsync(string? searchString, Employee loggedInEmployee, Guid tenantId)
{
if (tenantId == Guid.Empty)
{
_logger.LogWarning("GetBothProjectBasicListAsync called with invalid tenant context by EmployeeId {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "Invalid tenant context.", 403);
}
public async Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Guid tenantId, Employee loggedInEmployee)
try
{
// Retrieve list of project IDs accessible by the employee for tenant isolation and security
var accessibleProjectIds = await GetMyProjects(loggedInEmployee, tenantId);
// Fetch infrastructure projects concurrently filtered by accessible IDs and tenant
var infraProjectTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
var infraProjectsQuery = context.Projects
.Where(p => accessibleProjectIds.Contains(p.Id) && p.TenantId == tenantId);
if (!string.IsNullOrWhiteSpace(searchString))
{
var normalized = searchString.Trim().ToLowerInvariant();
infraProjectsQuery = infraProjectsQuery
.Where(p => p.Name.ToLower().Contains(normalized));
}
var infraProjects = await infraProjectsQuery.ToListAsync();
return infraProjects.Select(p => _mapper.Map<BasicProjectVM>(p)).ToList();
});
// Fetch active service projects concurrently with tenant isolation
var serviceProjectTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
var serviceProjectsQuery = context.ServiceProjects
.Where(sp => sp.TenantId == tenantId && sp.IsActive);
if (!string.IsNullOrWhiteSpace(searchString))
{
var normalized = searchString.Trim().ToLowerInvariant();
serviceProjectsQuery = serviceProjectsQuery
.Where(sp => sp.Name.ToLower().Contains(normalized));
}
var serviceProjects = await serviceProjectsQuery.ToListAsync();
return serviceProjects.Select(sp => _mapper.Map<BasicProjectVM>(sp)).ToList();
});
// Wait for both concurrent tasks to complete
await Task.WhenAll(infraProjectTask, serviceProjectTask);
// Combine, remove duplicates, and prepare response list
var combinedProjects = infraProjectTask.Result.Concat(serviceProjectTask.Result).OrderBy(p => p.Name).Distinct().ToList();
_logger.LogInfo("GetBothProjectBasicListAsync returning {Count} projects for tenant {TenantId} by EmployeeId {EmployeeId}",
combinedProjects.Count, tenantId, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(combinedProjects, "Service and infrastructure projects fetched successfully.", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error in GetBothProjectBasicListAsync for tenant {TenantId} by EmployeeId {EmployeeId}",
tenantId, loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Server Error", "An error occurred while fetching projects.", 500);
}
}
public async Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Employee loggedInEmployee, Guid tenantId)
{
try
{
@ -74,7 +148,7 @@ namespace Marco.Pms.Services.Service
}
else
{
accessibleProjectIds = await GetMyProjects(tenantId, loggedInEmployee);
accessibleProjectIds = await GetMyProjects(loggedInEmployee, tenantId);
}
if (accessibleProjectIds == null || !accessibleProjectIds.Any())
@ -97,14 +171,14 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("An internal server error occurred. Please try again later.", null, 500);
}
}
public async Task<ApiResponse<object>> GetAllProjectsAsync(int pageNumber, int pageSize, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetAllProjectsAsync(int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId)
{
try
{
_logger.LogInfo("Starting GetAllProjects for TenantId: {TenantId}, User: {UserId}", tenantId, loggedInEmployee.Id);
// --- Step 1: Get a list of project IDs the user can access ---
List<Guid> projectIds = await GetMyProjects(tenantId, loggedInEmployee);
List<Guid> projectIds = await GetMyProjects(loggedInEmployee, tenantId);
if (!projectIds.Any())
{
_logger.LogInfo("User has no assigned projects. Returning empty list.");
@ -171,7 +245,7 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("An internal server error occurred. Please try again later.", null, 500);
}
}
public async Task<ApiResponse<object>> GetProjectAsync(Guid id, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetProjectAsync(Guid id, Employee loggedInEmployee, Guid tenantId)
{
try
{
@ -216,7 +290,7 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("An internal server error occurred.", null, 500);
}
}
public async Task<ApiResponse<object>> GetProjectDetailsAsync(Guid id, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetProjectDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId)
{
try
{
@ -280,7 +354,7 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("An internal server error occurred. Please try again later.", null, 500);
}
}
public async Task<ApiResponse<object>> GetProjectDetailsOldAsync(Guid id, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetProjectDetailsOldAsync(Guid id, Employee loggedInEmployee, Guid tenantId)
{
var project = await _context.Projects
.Where(c => c.TenantId == tenantId && c.Id == id)
@ -375,7 +449,7 @@ namespace Marco.Pms.Services.Service
#region =================================================================== Project Manage APIs ===================================================================
public async Task<ApiResponse<object>> CreateProjectAsync(CreateProjectDto model, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> CreateProjectAsync(CreateProjectDto model, Employee loggedInEmployee, Guid tenantId)
{
// Begin a new scope for service resolution.
using var scope = _serviceScopeFactory.CreateScope();
@ -489,7 +563,7 @@ namespace Marco.Pms.Services.Service
/// <param name="id">The ID of the project to update.</param>
/// <param name="updateProjectDto">The data to update the project with.</param>
/// <returns>An ApiResponse confirming the update or an appropriate error.</returns>
public async Task<ApiResponse<object>> UpdateProjectAsync(Guid id, UpdateProjectDto model, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> UpdateProjectAsync(Guid id, UpdateProjectDto model, Employee loggedInEmployee, Guid tenantId)
{
using var scope = _serviceScopeFactory.CreateScope();
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
@ -624,7 +698,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">The ID of the current tenant.</param>
/// <param name="loggedInEmployee">The current authenticated employee (used for permission checks).</param>
/// <returns>An ApiResponse containing a list of employees or an error.</returns>
public async Task<ApiResponse<object>> GetEmployeeByProjectIdAsync(Guid projectId, Guid? organizationId, bool includeInactive, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetEmployeeByProjectIdAsync(Guid projectId, Guid? organizationId, bool includeInactive, Employee loggedInEmployee, Guid tenantId)
{
// --- Step 1: Input Validation ---
if (projectId == Guid.Empty)
@ -706,7 +780,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">The ID of the current tenant.</param>
/// <param name="loggedInEmployee">The current authenticated employee for permission checks.</param>
/// <returns>An ApiResponse containing allocation details or an appropriate error.</returns>
public async Task<ApiResponse<object>> GetProjectAllocationAsync(Guid projectId, Guid? organizationId, Guid? serviceId, bool includeInactive, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetProjectAllocationAsync(Guid projectId, Guid? organizationId, Guid? serviceId, bool includeInactive, Employee loggedInEmployee, Guid tenantId)
{
// --- Step 1: Input Validation ---
if (projectId == Guid.Empty)
@ -810,7 +884,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">The ID of the current tenant.</param>
/// <param name="loggedInEmployee">The current authenticated employee for permission checks.</param>
/// <returns>An ApiResponse containing the list of processed allocations.</returns>
public async Task<ApiResponse<List<ProjectAllocationVM>>> ManageAllocationAsync(List<ProjectAllocationDot> allocationsDto, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<List<ProjectAllocationVM>>> ManageAllocationAsync(List<ProjectAllocationDot> allocationsDto, Employee loggedInEmployee, Guid tenantId)
{
using var scope = _serviceScopeFactory.CreateScope();
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
@ -933,7 +1007,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">The ID of the current tenant.</param>
/// <param name="loggedInEmployee">The current authenticated employee for permission checks.</param>
/// <returns>An ApiResponse containing a list of basic project details or an error.</returns>
public async Task<ApiResponse<object>> GetProjectsByEmployeeAsync(Guid employeeId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetProjectsByEmployeeAsync(Guid employeeId, Employee loggedInEmployee, Guid tenantId)
{
// --- Step 1: Input Validation ---
if (employeeId == Guid.Empty)
@ -953,7 +1027,7 @@ namespace Marco.Pms.Services.Service
// This is a placeholder for your actual, more specific permission logic.
// It should also handle the case where a user is requesting their own projects (employeeId == loggedInEmployee.Id).
var hasPermission = await _permission.HasPermission(PermissionsMaster.ViewProject, loggedInEmployee.Id);
var projectIds = await GetMyProjects(tenantId, loggedInEmployee);
var projectIds = await GetMyProjects(loggedInEmployee, tenantId);
if (!hasPermission)
{
_logger.LogWarning("Access DENIED for user {UserId} trying to view projects for employee {TargetEmployeeId}.", loggedInEmployee.Id, employeeId);
@ -1011,7 +1085,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">The ID of the current tenant.</param>
/// <param name="loggedInEmployee">The current authenticated employee for permission checks.</param>
/// <returns>An ApiResponse containing the list of processed allocations.</returns>
public async Task<ApiResponse<List<ProjectAllocationVM>>> AssigneProjectsToEmployeeAsync(List<ProjectsAllocationDto> allocationsDto, Guid employeeId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<List<ProjectAllocationVM>>> AssigneProjectsToEmployeeAsync(List<ProjectsAllocationDto> allocationsDto, Guid employeeId, Employee loggedInEmployee, Guid tenantId)
{
using var scope = _serviceScopeFactory.CreateScope();
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
@ -1140,8 +1214,7 @@ namespace Marco.Pms.Services.Service
});
return ApiResponse<List<ProjectAllocationVM>>.SuccessResponse(resultVm, "Assignments managed successfully.", 200);
}
public async Task<ApiResponse<object>> GetProjectByEmployeeBasicAsync(Guid employeeId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetProjectByEmployeeBasicAsync(Guid employeeId, Employee loggedInEmployee, Guid tenantId)
{
// Log the start of the method execution with key input parameters
_logger.LogInfo("Fetching projects for EmployeeId: {EmployeeId}, TenantId: {TenantId} by User: {UserId}",
@ -1206,7 +1279,7 @@ namespace Marco.Pms.Services.Service
500);
}
}
public async Task<ApiResponse<object>> GetProjectTeamByServiceAndOrganization(Guid projectId, Guid? serviceId, Guid? organizationId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetProjectTeamByServiceAndOrganization(Guid projectId, Guid? serviceId, Guid? organizationId, Employee loggedInEmployee, Guid tenantId)
{
using var scope = _serviceScopeFactory.CreateScope();
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
@ -1281,9 +1354,8 @@ namespace Marco.Pms.Services.Service
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)
Guid projectId, Guid? serviceId, Guid? organizationId, Employee loggedInEmployee, Guid tenantId)
{
_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);
@ -1391,7 +1463,6 @@ namespace Marco.Pms.Services.Service
}
}
#endregion
#region =================================================================== Project InfraStructure Get APIs ===================================================================
@ -1400,7 +1471,7 @@ namespace Marco.Pms.Services.Service
/// Retrieves the full infrastructure hierarchy (Buildings, Floors, Work Areas) for a project,
/// including aggregated work summaries.
/// </summary>
public async Task<ApiResponse<object>> GetInfraDetailsAsync(Guid projectId, Guid? serviceId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetInfraDetailsAsync(Guid projectId, Guid? serviceId, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("GetInfraDetails called for ProjectId: {ProjectId}", projectId);
@ -1530,7 +1601,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">The ID of the current tenant.</param>
/// <param name="loggedInEmployee">The current authenticated employee for permission checks.</param>
/// <returns>An ApiResponse containing a list of work items or an error.</returns>
public async Task<ApiResponse<object>> GetWorkItemsAsync(Guid workAreaId, Guid? serviceId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetWorkItemsAsync(Guid workAreaId, Guid? serviceId, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("GetWorkItems called for WorkAreaId: {WorkAreaId} by User: {UserId}", workAreaId, loggedInEmployee.Id);
@ -1659,7 +1730,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">The tenant ID to filter tasks.</param>
/// <param name="loggedInEmployee">The employee requesting the data (for authorization/logging).</param>
/// <returns>An ApiResponse containing the task details.</returns>
public async Task<ApiResponse<object>> GetTasksByEmployeeAsync(Guid employeeId, DateTime fromDate, DateTime toDate, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetTasksByEmployeeAsync(Guid employeeId, DateTime fromDate, DateTime toDate, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("Fetching tasks for EmployeeId: {EmployeeId} from {FromDate} to {ToDate} for TenantId: {TenantId}",
employeeId, fromDate, toDate, tenantId);
@ -1730,7 +1801,7 @@ namespace Marco.Pms.Services.Service
#region =================================================================== Project Infrastructre Manage APIs ===================================================================
public async Task<ServiceResponse> ManageProjectInfraAsync(List<InfraDto> infraDtos, Guid tenantId, Employee loggedInEmployee)
public async Task<ServiceResponse> ManageProjectInfraAsync(List<InfraDto> infraDtos, Employee loggedInEmployee, Guid tenantId)
{
// 1. Guard Clause: Handle null or empty input gracefully.
if (infraDtos == null || !infraDtos.Any())
@ -1821,7 +1892,7 @@ namespace Marco.Pms.Services.Service
/// Creates or updates a batch of work items.
/// This method is optimized to perform all database operations in a single, atomic transaction.
/// </summary>
public async Task<ApiResponse<List<WorkItemVM>>> CreateProjectTaskAsync(List<WorkItemDto> workItemDtos, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<List<WorkItemVM>>> CreateProjectTaskAsync(List<WorkItemDto> workItemDtos, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("CreateProjectTask called with {Count} items by user {UserId}", workItemDtos?.Count ?? 0, loggedInEmployee.Id);
@ -1967,7 +2038,7 @@ namespace Marco.Pms.Services.Service
return ApiResponse<List<WorkItemVM>>.SuccessResponse(responseList, message, 200);
}
public async Task<ServiceResponse> DeleteProjectTaskAsync(Guid id, Guid tenantId, Employee loggedInEmployee)
public async Task<ServiceResponse> DeleteProjectTaskAsync(Guid id, Employee loggedInEmployee, Guid tenantId)
{
using var scope = _serviceScopeFactory.CreateScope();
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
@ -2074,7 +2145,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">Tenant Guid.</param>
/// <param name="loggedInEmployee">Currently logged in employee.</param>
/// <returns>API response indicating the result.</returns>
public async Task<ApiResponse<object>> ManageProjectLevelPermissionAsync(ProjctLevelPermissionDto model, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> ManageProjectLevelPermissionAsync(ProjctLevelPermissionDto model, Employee loggedInEmployee, Guid tenantId)
{
// Log: Method entry and received parameters
_logger.LogInfo("ManageProjectLevelPermissionAsync started for EmployeeId: {EmployeeId}, ProjectId: {ProjectId}, TenantId: {TenantId}",
@ -2213,7 +2284,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">Unique identifier of the tenant.</param>
/// <param name="loggedInEmployee">The authenticated employee making this request.</param>
/// <returns>ApiResponse containing the permission mappings or error details.</returns>
public async Task<ApiResponse<object>> GetAssignedProjectLevelPermissionAsync(Guid employeeId, Guid projectId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetAssignedProjectLevelPermissionAsync(Guid employeeId, Guid projectId, Employee loggedInEmployee, Guid tenantId)
{
// Log the attempt to fetch project-level permissions
_logger.LogInfo(
@ -2291,7 +2362,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">Tenant ID associated with assignment.</param>
/// <param name="loggedInEmployee">Logged-in employee context.</param>
/// <returns>API response containing feature details associated with specified modules.</returns>
public async Task<ApiResponse<object>> AssignProjectLevelModulesAsync(Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> AssignProjectLevelModulesAsync(Employee loggedInEmployee, Guid tenantId)
{
// Log entry at the start of the method.
_logger.LogInfo("AssignProjectLevelModulesAsync called for TenantId: {TenantId}, EmployeeId: {EmployeeId}", tenantId, loggedInEmployee.Id);
@ -2342,7 +2413,7 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("Failed to assign project-level modules.", ex.Message);
}
}
public async Task<ApiResponse<object>> GetEmployeeToWhomProjectLevelAssignedAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetEmployeeToWhomProjectLevelAssignedAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId)
{
// Log method entry and parameters for traceability
_logger.LogInfo("Fetching employees with project-level permissions. ProjectId: {ProjectId}, TenantId: {TenantId}, RequestedBy: {EmployeeId}",
@ -2396,7 +2467,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">The tenant identifier for multi-tenant data isolation.</param>
/// <param name="loggedInEmployee">The employee making the request, whose permissions are checked.</param>
/// <returns>An ApiResponse containing the list of assigned services or an error response.</returns>
public async Task<ApiResponse<object>> GetAssignedServiceToProjectAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetAssignedServiceToProjectAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId)
{
try
{
@ -2483,7 +2554,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">Tenant identifier for proper multi-tenant separation.</param>
/// <param name="loggedInEmployee">The employee requesting the service assignment, used for permission checks.</param>
/// <returns>ApiResponse with assigned services info or error details.</returns>
public async Task<ApiResponse<object>> AssignServiceToProjectAsync(AssignServiceDto model, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> AssignServiceToProjectAsync(AssignServiceDto model, Employee loggedInEmployee, Guid tenantId)
{
// Begin a transaction to ensure atomicity of assignments
await using var transaction = await _context.Database.BeginTransactionAsync();
@ -2586,7 +2657,7 @@ namespace Marco.Pms.Services.Service
/// <param name="tenantId">Tenant context for multi-tenant data isolation.</param>
/// <param name="loggedInEmployee">Employee executing the operation, used for permission checks.</param>
/// <returns>ApiResponse indicating success or failure.</returns>
public async Task<ApiResponse<object>> DeassignServiceToProjectAsync(DeassignServiceDto model, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> DeassignServiceToProjectAsync(DeassignServiceDto model, Employee loggedInEmployee, Guid tenantId)
{
await using var transaction = await _context.Database.BeginTransactionAsync();
@ -2660,7 +2731,7 @@ namespace Marco.Pms.Services.Service
#region =================================================================== Assign Organization APIs ===================================================================
public async Task<ApiResponse<object>> GetAssignedOrganizationsToProjectAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetAssignedOrganizationsToProjectAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogDebug("Started fetching assigned organizations for ProjectId: {ProjectId} and TenantId: {TenantId} by user {UserId}",
projectId, tenantId, loggedInEmployee.Id);
@ -2829,7 +2900,7 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("Internal error", "An internal exception occurred", 500);
}
}
public async Task<ApiResponse<object>> GetAssignedOrganizationsToProjectForDropdownAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee)
public async Task<ApiResponse<object>> GetAssignedOrganizationsToProjectForDropdownAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogDebug("Started fetching assigned organizations for ProjectId: {ProjectId} and TenantId: {TenantId} by user {UserId}",
projectId, tenantId, loggedInEmployee.Id);
@ -2951,7 +3022,6 @@ namespace Marco.Pms.Services.Service
}
}
#endregion
#region =================================================================== Helper Functions ===================================================================
@ -2988,16 +3058,16 @@ namespace Marco.Pms.Services.Service
var projectAllocation = await projectAllocationQuery.ToListAsync();
return projectAllocation;
}
public async Task<List<Guid>> GetMyProjects(Guid tenantId, Employee LoggedInEmployee)
public async Task<List<Guid>> GetMyProjects(Employee loggedInEmployee, Guid tenantId)
{
using var scope = _serviceScopeFactory.CreateScope();
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
var projectIds = await _cache.GetProjects(LoggedInEmployee.Id, tenantId);
var projectIds = await _cache.GetProjects(loggedInEmployee.Id, tenantId);
if (projectIds == null)
{
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageProject, LoggedInEmployee.Id);
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageProject, loggedInEmployee.Id);
if (hasPermission)
{
var projects = await _context.Projects.Where(c => c.TenantId == tenantId).ToListAsync();
@ -3005,18 +3075,18 @@ namespace Marco.Pms.Services.Service
}
else
{
var allocation = await GetProjectByEmployeeID(LoggedInEmployee.Id);
var allocation = await GetProjectByEmployeeID(loggedInEmployee.Id);
if (!allocation.Any())
{
return new List<Guid>();
}
projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList();
}
await _cache.AddProjects(LoggedInEmployee.Id, projectIds, tenantId);
await _cache.AddProjects(loggedInEmployee.Id, projectIds, tenantId);
}
return projectIds;
}
public async Task<List<Guid>> GetMyProjectIdsAsync(Guid tenantId, Employee loggedInEmployee)
public async Task<List<Guid>> GetMyProjectIdsAsync(Employee loggedInEmployee, Guid tenantId)
{
using var scope = _serviceScopeFactory.CreateScope();
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();

View File

@ -10,46 +10,47 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
{
public interface IProjectServices
{
Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetAllProjectsAsync(int pageNumber, int pageSize, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetProjectAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetProjectDetailsAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetProjectDetailsOldAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> CreateProjectAsync(CreateProjectDto projectDto, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> UpdateProjectAsync(Guid id, UpdateProjectDto updateProjectDto, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetEmployeeByProjectIdAsync(Guid projectId, Guid? organizationId, bool includeInactive, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetProjectAllocationAsync(Guid projectId, Guid? organizationId, Guid? serviceId, bool includeInactive, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<List<ProjectAllocationVM>>> ManageAllocationAsync(List<ProjectAllocationDot> projectAllocationDots, Guid tenantId, Employee loggedInEmployee);
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>> GetBothProjectBasicListAsync(string? searchString, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetAllProjectsAsync(int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetProjectAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetProjectDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetProjectDetailsOldAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreateProjectAsync(CreateProjectDto projectDto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> UpdateProjectAsync(Guid id, UpdateProjectDto updateProjectDto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetEmployeeByProjectIdAsync(Guid projectId, Guid? organizationId, bool includeInactive, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetProjectAllocationAsync(Guid projectId, Guid? organizationId, Guid? serviceId, bool includeInactive, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<List<ProjectAllocationVM>>> ManageAllocationAsync(List<ProjectAllocationDot> projectAllocationDots, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetProjectsByEmployeeAsync(Guid employeeId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<List<ProjectAllocationVM>>> AssigneProjectsToEmployeeAsync(List<ProjectsAllocationDto> projectAllocationDtos, Guid employeeId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetProjectByEmployeeBasicAsync(Guid employeeId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetProjectTeamByServiceAndOrganizationAsync(Guid projectId, Guid? serviceId, Guid? organizationId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetInfraDetailsAsync(Guid projectId, Guid? serviceId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetWorkItemsAsync(Guid workAreaId, Guid? serviceId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetTasksByEmployeeAsync(Guid employeeId, DateTime fromDate, DateTime toDate, Guid tenantId, Employee loggedInEmployee);
Task<ServiceResponse> ManageProjectInfraAsync(List<InfraDto> infraDtos, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<List<WorkItemVM>>> CreateProjectTaskAsync(List<WorkItemDto> workItemDtos, Guid tenantId, Employee loggedInEmployee);
Task<ServiceResponse> DeleteProjectTaskAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetInfraDetailsAsync(Guid projectId, Guid? serviceId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetWorkItemsAsync(Guid workAreaId, Guid? serviceId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetTasksByEmployeeAsync(Guid employeeId, DateTime fromDate, DateTime toDate, Employee loggedInEmployee, Guid tenantId);
Task<ServiceResponse> ManageProjectInfraAsync(List<InfraDto> infraDtos, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<List<WorkItemVM>>> CreateProjectTaskAsync(List<WorkItemDto> workItemDtos, Employee loggedInEmployee, Guid tenantId);
Task<ServiceResponse> DeleteProjectTaskAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
Task<List<Project>> GetAllProjectByTanentID(Guid tanentId);
Task<List<ProjectAllocation>> GetProjectByEmployeeID(Guid employeeId);
Task<List<ProjectAllocation>> GetTeamByProject(Guid TenantId, Guid ProjectId, Guid? OrganizationId, bool IncludeInactive);
Task<List<Guid>> GetMyProjectIdsAsync(Guid tenantId, Employee LoggedInEmployee);
Task<List<Guid>> GetMyProjectIdsAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> ManageProjectLevelPermissionAsync(ProjctLevelPermissionDto model, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetAssignedProjectLevelPermissionAsync(Guid employeeId, Guid projectId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> AssignProjectLevelModulesAsync(Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetEmployeeToWhomProjectLevelAssignedAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> ManageProjectLevelPermissionAsync(ProjctLevelPermissionDto model, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetAssignedProjectLevelPermissionAsync(Guid employeeId, Guid projectId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> AssignProjectLevelModulesAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetEmployeeToWhomProjectLevelAssignedAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetAllPermissionFroProjectAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetAssignedServiceToProjectAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> AssignServiceToProjectAsync(AssignServiceDto model, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> DeassignServiceToProjectAsync(DeassignServiceDto model, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetAssignedServiceToProjectAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> AssignServiceToProjectAsync(AssignServiceDto model, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> DeassignServiceToProjectAsync(DeassignServiceDto model, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetAssignedOrganizationsToProjectAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetAssignedOrganizationsToProjectForDropdownAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetAssignedOrganizationsToProjectAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetAssignedOrganizationsToProjectForDropdownAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId);
}
}