From 186486d934b93f449806d11c0f5eff252f280290 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Sat, 11 Oct 2025 15:36:52 +0530 Subject: [PATCH] Added the new API to get organizations for dropdown --- .../Controllers/ProjectController.cs | 7 + Marco.Pms.Services/Service/ProjectServices.cs | 122 ++++++++++++++++++ .../ServiceInterfaces/IProjectServices.cs | 1 + 3 files changed, 130 insertions(+) diff --git a/Marco.Pms.Services/Controllers/ProjectController.cs b/Marco.Pms.Services/Controllers/ProjectController.cs index df23a29..0cbb1ad 100644 --- a/Marco.Pms.Services/Controllers/ProjectController.cs +++ b/Marco.Pms.Services/Controllers/ProjectController.cs @@ -560,6 +560,13 @@ namespace MarcoBMS.Services.Controllers var response = await _projectServices.GetAssignedOrganizationsToProjectAsync(projectId, tenantId, loggedInEmployee); return StatusCode(response.StatusCode, response); } + [HttpGet("get/assigned/organization/dropdown/{projectId}")] + public async Task GetAssignedOrganizationsToProjectForDropdownAsync(Guid projectId) + { + Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _projectServices.GetAssignedOrganizationsToProjectForDropdownAsync(projectId, tenantId, loggedInEmployee); + return StatusCode(response.StatusCode, response); + } #endregion } diff --git a/Marco.Pms.Services/Service/ProjectServices.cs b/Marco.Pms.Services/Service/ProjectServices.cs index a3d56e0..2110ab9 100644 --- a/Marco.Pms.Services/Service/ProjectServices.cs +++ b/Marco.Pms.Services/Service/ProjectServices.cs @@ -2805,6 +2805,128 @@ namespace Marco.Pms.Services.Service return ApiResponse.ErrorResponse("Internal error", "An internal exception occurred", 500); } } + public async Task> GetAssignedOrganizationsToProjectForDropdownAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee) + { + _logger.LogDebug("Started fetching assigned organizations for ProjectId: {ProjectId} and TenantId: {TenantId} by user {UserId}", + projectId, tenantId, loggedInEmployee.Id); + + try + { + // Create a scoped PermissionServices instance for permission checks + using var scope = _serviceScopeFactory.CreateScope(); + var permissionService = scope.ServiceProvider.GetRequiredService(); + + // Retrieve the project by projectId and tenantId + var projectTask = Task.Run(async () => + { + await using var context = await _dbContextFactory.CreateDbContextAsync(); + return await context.Projects.AsNoTracking().Include(p => p.Promoter).Include(p => p.PMC).FirstOrDefaultAsync(p => p.Id == projectId && p.TenantId == tenantId); + }); + + var tenantTask = Task.Run(async () => + { + await using var context = await _dbContextFactory.CreateDbContextAsync(); + return await context.Tenants.AsNoTracking().Include(t => t.Organization).FirstOrDefaultAsync(t => t.Id == tenantId); + }); + var projectServiceTask = Task.Run(async () => + { + await using var context = await _dbContextFactory.CreateDbContextAsync(); + return await context.ProjectServiceMappings + .AsNoTracking() + .Include(ps => ps!.Service) + .Where(ps => ps.ProjectId == projectId && ps.TenantId == tenantId).ToListAsync(); + }); + + await Task.WhenAll(projectTask, tenantTask, projectServiceTask); + + var project = projectTask.Result; + var tenant = tenantTask.Result; + var projectService = projectServiceTask.Result; + + if (project == null || tenant == null) + { + _logger.LogWarning("Project {ProjectId} not found in database for tenant {TenantId}", projectId, tenantId); + return ApiResponse.ErrorResponse("Project not found", "Project not found", 404); + } + + // Check if the logged in employee has permission to access the project + var hasPermission = await permissionService.HasProjectPermission(loggedInEmployee, projectId); + if (!hasPermission) + { + _logger.LogWarning("Access denied for user {UserId} on project {ProjectId}", loggedInEmployee.Id, projectId); + return ApiResponse.ErrorResponse("Access Denied", "You do not have permission to access this project.", 403); + } + + // Fetch all project-organization mappings with related service and organization data + var projectOrgMappingsQuery = _context.ProjectOrgMappings + .AsNoTracking() + .Include(po => po.ProjectService) + .ThenInclude(ps => ps!.Service) + .Include(po => po.AssignedBy) + .Include(po => po.OrganizationType) + .Include(po => po.Organization) + .Where(po => po.ProjectService != null + && po.ProjectService.ProjectId == projectId + && po.TenantId == tenantId); + + if (loggedInEmployee.OrganizationId != project.PMCId && loggedInEmployee.OrganizationId != project.PromoterId && loggedInEmployee.OrganizationId != tenant.OrganizationId) + { + projectOrgMappingsQuery = projectOrgMappingsQuery.Where(po => po.ParentOrganizationId == loggedInEmployee.OrganizationId || po.OrganizationId == loggedInEmployee.OrganizationId); + } + + var projectOrgMappings = await projectOrgMappingsQuery + .Distinct() + .ToListAsync(); + var organizations = projectOrgMappings.Select(po => po.Organization!).ToList(); + + if (loggedInEmployee.OrganizationId == project.PMCId || loggedInEmployee.OrganizationId == project.PromoterId || loggedInEmployee.OrganizationId == tenant.OrganizationId) + { + var pmc = project.PMC; + var promoter = project.Promoter; + var organization = tenant.Organization; + + if (!organizations.Any(r => r.Id == project.PMCId) && pmc != null) + { + organizations.Add(pmc); + } + if (!organizations.Any(r => r.Id == project.PromoterId) && promoter != null) + { + organizations.Add(promoter); + } + if (!organizations.Any(r => r.Id == tenant.OrganizationId) && organization != null) + { + organizations.Add(organization); + } + } + + organizations = organizations.Distinct().ToList(); + + // Filter and map the data to the desired view model + var response = organizations + .Select(o => new ProjectOrganizationVM + { + Id = o.Id, + Name = o.Name, + SPRID = 0 + }) + .ToList(); + + _logger.LogInfo("Fetched {Count} assigned organizations for ProjectId: {ProjectId}", response.Count, projectId); + + return ApiResponse.SuccessResponse(response, "Successfully fetched the list of organizations assigned to the project", 200); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Database exception while fetching assigned organizations for ProjectId: {ProjectId}", projectId); + return ApiResponse.ErrorResponse("Internal error", "A database exception occurred", 500); + } + catch (Exception ex) + { + _logger.LogError(ex, "Unhandled exception while fetching assigned organizations for ProjectId: {ProjectId}", projectId); + return ApiResponse.ErrorResponse("Internal error", "An internal exception occurred", 500); + } + } + #endregion diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IProjectServices.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IProjectServices.cs index 7151187..06dd0b8 100644 --- a/Marco.Pms.Services/Service/ServiceInterfaces/IProjectServices.cs +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IProjectServices.cs @@ -49,6 +49,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces Task> DeassignServiceToProjectAsync(DeassignServiceDto model, Guid tenantId, Employee loggedInEmployee); Task> GetAssignedOrganizationsToProjectAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee); + Task> GetAssignedOrganizationsToProjectForDropdownAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee); } }