Compare commits
	
		
			No commits in common. "c689f2dfd84ef0dda4cd9811aed94dd55ae09740" and "4ccc69056029a7b7748f8c004340fc11c51e75e1" have entirely different histories.
		
	
	
		
			c689f2dfd8
			...
			4ccc690560
		
	
		
@ -91,19 +91,5 @@ namespace Marco.Pms.Model.Mapper
 | 
			
		||||
                EndDate = project.EndDate,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        public static ProjectInfoVM ToProjectInfoVMFromProject(this Project project)
 | 
			
		||||
        {
 | 
			
		||||
            return new ProjectInfoVM
 | 
			
		||||
            {
 | 
			
		||||
                Id = project.Id,
 | 
			
		||||
                Name = project.Name,
 | 
			
		||||
                ShortName = project.ShortName,
 | 
			
		||||
                ProjectAddress = project.ProjectAddress,
 | 
			
		||||
                ProjectStatusId = project.ProjectStatusId,
 | 
			
		||||
                ContactPerson = project.ContactPerson,
 | 
			
		||||
                StartDate = project.StartDate,
 | 
			
		||||
                EndDate = project.EndDate,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,17 +15,4 @@
 | 
			
		||||
        public double CompletedWork { get; set; }
 | 
			
		||||
        public double PlannedWork { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ProjectInfoVM
 | 
			
		||||
    {
 | 
			
		||||
        public Guid Id { get; set; }
 | 
			
		||||
        public string? Name { get; set; }
 | 
			
		||||
        public string? ShortName { get; set; }
 | 
			
		||||
        public string? ProjectAddress { get; set; }
 | 
			
		||||
        public string? ContactPerson { get; set; }
 | 
			
		||||
 | 
			
		||||
        public DateTime? StartDate { get; set; }
 | 
			
		||||
        public DateTime? EndDate { get; set; }
 | 
			
		||||
        public Guid ProjectStatusId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,55 +37,6 @@ namespace MarcoBMS.Services.Controllers
 | 
			
		||||
            _rolesHelper = rolesHelper;
 | 
			
		||||
            _projectsHelper = projectHelper;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpGet("list/basic")]
 | 
			
		||||
        public async Task<IActionResult> GetAllProjects()
 | 
			
		||||
        {
 | 
			
		||||
            if (!ModelState.IsValid)
 | 
			
		||||
            {
 | 
			
		||||
                var errors = ModelState.Values
 | 
			
		||||
                    .SelectMany(v => v.Errors)
 | 
			
		||||
                    .Select(e => e.ErrorMessage)
 | 
			
		||||
                    .ToList();
 | 
			
		||||
                return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            Guid tenantId = _userHelper.GetTenantId();
 | 
			
		||||
            var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
 | 
			
		||||
 | 
			
		||||
            // Defensive check for null employee (important for robust APIs)
 | 
			
		||||
            if (LoggedInEmployee == null)
 | 
			
		||||
            {
 | 
			
		||||
                return Unauthorized(ApiResponse<object>.ErrorResponse("Employee not found.", null, 401));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
           
 | 
			
		||||
            List<Project> projects =  await _projectsHelper.GetMyProjects(tenantId, LoggedInEmployee);
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            // 4. Project projection to ProjectInfoVM
 | 
			
		||||
            // This part is already quite efficient.
 | 
			
		||||
            // Ensure ToProjectInfoVMFromProject() is also optimized and doesn't perform N+1 queries.
 | 
			
		||||
            // If ProjectInfoVM only needs a subset of Project properties,
 | 
			
		||||
            // you can use a LINQ Select directly on the IQueryable before ToListAsync()
 | 
			
		||||
            // to fetch only the required columns from the database.
 | 
			
		||||
            List<ProjectInfoVM> response = projects
 | 
			
		||||
                .Select(project => project.ToProjectInfoVMFromProject())
 | 
			
		||||
                .ToList();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            //List<ProjectInfoVM> response = new List<ProjectInfoVM>();
 | 
			
		||||
 | 
			
		||||
            //foreach (var project in projects)
 | 
			
		||||
            //{
 | 
			
		||||
            //    response.Add(project.ToProjectInfoVMFromProject());
 | 
			
		||||
            //}
 | 
			
		||||
 | 
			
		||||
            return Ok(ApiResponse<object>.SuccessResponse(response, "Success.", 200));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
     
 | 
			
		||||
 | 
			
		||||
        [HttpGet("list")]
 | 
			
		||||
        public async Task<IActionResult> GetAll()
 | 
			
		||||
        {
 | 
			
		||||
@ -100,25 +51,21 @@ namespace MarcoBMS.Services.Controllers
 | 
			
		||||
            }
 | 
			
		||||
            Guid tenantId = _userHelper.GetTenantId();
 | 
			
		||||
            var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
 | 
			
		||||
            //List<FeaturePermission> featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeID(LoggedInEmployee.Id);
 | 
			
		||||
            //string[] projectsId = [];
 | 
			
		||||
            //List<Project> projects = new List<Project>();
 | 
			
		||||
 | 
			
		||||
            ///* User with permission manage project  can see all projects */
 | 
			
		||||
            //if (featurePermission != null && featurePermission.Exists(c => c.Id.ToString() == "172fc9b6-755b-4f62-ab26-55c34a330614"))
 | 
			
		||||
            //{
 | 
			
		||||
            //    projects = await _projectsHelper.GetAllProjectByTanentID(LoggedInEmployee.TenantId);
 | 
			
		||||
            //}
 | 
			
		||||
            //else
 | 
			
		||||
            //{
 | 
			
		||||
            //    List<ProjectAllocation> allocation = await _projectsHelper.GetProjectByEmployeeID(LoggedInEmployee.Id);
 | 
			
		||||
            //    projectsId = allocation.Select(c => c.ProjectId.ToString()).ToArray();
 | 
			
		||||
            //    projects = await _context.Projects.Where(c => projectsId.Contains(c.Id.ToString()) && c.TenantId == tenantId).ToListAsync();
 | 
			
		||||
            //}
 | 
			
		||||
 | 
			
		||||
            List<Project> projects = await _projectsHelper.GetMyProjects(tenantId, LoggedInEmployee);
 | 
			
		||||
 | 
			
		||||
            List<FeaturePermission> featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeID(LoggedInEmployee.Id);
 | 
			
		||||
            string[] projectsId = [];
 | 
			
		||||
            List<Project> projects = new List<Project>();
 | 
			
		||||
 | 
			
		||||
            /* User with permission manage project  can see all projects */
 | 
			
		||||
            if (featurePermission != null && featurePermission.Exists(c => c.Id.ToString() == "172fc9b6-755b-4f62-ab26-55c34a330614"))
 | 
			
		||||
            {
 | 
			
		||||
                projects = await _projectsHelper.GetAllProjectByTanentID(LoggedInEmployee.TenantId);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                List<ProjectAllocation> allocation = await _projectsHelper.GetProjectByEmployeeID(LoggedInEmployee.Id);
 | 
			
		||||
                projectsId = allocation.Select(c => c.ProjectId.ToString()).ToArray();
 | 
			
		||||
                projects = await _context.Projects.Where(c => projectsId.Contains(c.Id.ToString()) && c.TenantId == tenantId).ToListAsync();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            List<ProjectListVM> response = new List<ProjectListVM>();
 | 
			
		||||
@ -754,24 +701,23 @@ namespace MarcoBMS.Services.Controllers
 | 
			
		||||
 | 
			
		||||
            if (!projectList.Any())
 | 
			
		||||
            {
 | 
			
		||||
                return NotFound(ApiResponse<object>.SuccessResponse(new List<object>(), "No projects found.", 200));
 | 
			
		||||
                return NotFound(ApiResponse<object>.SuccessResponse(new List<object>(), "No projects found.",200));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            List<Project> projectlist = await _context.Projects
 | 
			
		||||
                 .Where(p => projectList.Contains(p.Id))
 | 
			
		||||
                 .ToListAsync();
 | 
			
		||||
           List<Project> projectlist = await _context.Projects
 | 
			
		||||
                .Where(p => projectList.Contains(p.Id))
 | 
			
		||||
                .ToListAsync();
 | 
			
		||||
 | 
			
		||||
            List<ProjectListVM> projects = new List<ProjectListVM>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            foreach (var project in projectlist)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
            foreach (var project in projectlist) {
 | 
			
		||||
              
 | 
			
		||||
                projects.Add(project.ToProjectListVMFromProject());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            return Ok(ApiResponse<object>.SuccessResponse(projects, "Success.", 200));
 | 
			
		||||
        }
 | 
			
		||||
@ -782,19 +728,19 @@ namespace MarcoBMS.Services.Controllers
 | 
			
		||||
        [HttpPost("assign-projects/{employeeId}")]
 | 
			
		||||
        public async Task<ActionResult> AssigneProjectsToEmployee([FromBody] List<ProjectsAllocationDto> projectAllocationDtos, [FromRoute] Guid employeeId)
 | 
			
		||||
        {
 | 
			
		||||
            if (projectAllocationDtos != null && employeeId != Guid.Empty)
 | 
			
		||||
            if(projectAllocationDtos != null && employeeId != Guid.Empty)
 | 
			
		||||
            {
 | 
			
		||||
                Guid TenentID = GetTenantId();
 | 
			
		||||
                List<object>? result = new List<object>();
 | 
			
		||||
 | 
			
		||||
                foreach (var projectAllocationDto in projectAllocationDtos)
 | 
			
		||||
                foreach(var projectAllocationDto in projectAllocationDtos)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        ProjectAllocation projectAllocation = projectAllocationDto.ToProjectAllocationFromProjectsAllocationDto(TenentID, employeeId);
 | 
			
		||||
                        ProjectAllocation projectAllocation = projectAllocationDto.ToProjectAllocationFromProjectsAllocationDto(TenentID,employeeId);
 | 
			
		||||
                        ProjectAllocation? projectAllocationFromDb = await _context.ProjectAllocations.Where(c => c.EmployeeId == employeeId && c.ProjectId == projectAllocationDto.ProjectId && c.ReAllocationDate == null && c.TenantId == TenentID).SingleOrDefaultAsync();
 | 
			
		||||
 | 
			
		||||
                        if (projectAllocationFromDb != null)
 | 
			
		||||
                        if(projectAllocationFromDb != null)
 | 
			
		||||
                        {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -839,8 +785,7 @@ namespace MarcoBMS.Services.Controllers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
                    {
 | 
			
		||||
                    catch (Exception ex) {
 | 
			
		||||
 | 
			
		||||
                        return Ok(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400));
 | 
			
		||||
                    }
 | 
			
		||||
@ -852,7 +797,7 @@ namespace MarcoBMS.Services.Controllers
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest(ApiResponse<object>.ErrorResponse("Invalid details.", "All Field is required", 400));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,25 +1,16 @@
 | 
			
		||||
using Marco.Pms.DataAccess.Data;
 | 
			
		||||
using Marco.Pms.Model.Employees;
 | 
			
		||||
using Marco.Pms.Model.Entitlements;
 | 
			
		||||
using Marco.Pms.Model.Projects;
 | 
			
		||||
using Marco.Pms.Model.Utilities;
 | 
			
		||||
using Marco.Pms.Model.ViewModels.Projects;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using ModelServices.Helpers;
 | 
			
		||||
 | 
			
		||||
namespace MarcoBMS.Services.Helpers
 | 
			
		||||
{
 | 
			
		||||
    public class ProjectsHelper
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ApplicationDbContext _context;
 | 
			
		||||
        private readonly RolesHelper _rolesHelper;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public ProjectsHelper(ApplicationDbContext context, RolesHelper rolesHelper)
 | 
			
		||||
        public ProjectsHelper(ApplicationDbContext context)
 | 
			
		||||
        {
 | 
			
		||||
            _context = context;
 | 
			
		||||
            _rolesHelper = rolesHelper;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<List<Project>> GetAllProjectByTanentID(Guid tanentID)
 | 
			
		||||
@ -51,46 +42,7 @@ namespace MarcoBMS.Services.Helpers
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<List<Project>> GetMyProjects(Guid tenantId, Employee LoggedInEmployee)
 | 
			
		||||
        {
 | 
			
		||||
            List<FeaturePermission> featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeID(LoggedInEmployee.Id);
 | 
			
		||||
 | 
			
		||||
            string[] projectsId = [];
 | 
			
		||||
            List<Project> projects = new List<Project>();
 | 
			
		||||
 | 
			
		||||
            // Define a common queryable base for projects
 | 
			
		||||
            IQueryable<Project> projectQuery = _context.Projects.Where(c => c.TenantId == tenantId);
 | 
			
		||||
 | 
			
		||||
            // 2. Optimized Project Retrieval Logic
 | 
			
		||||
            // User with permission 'manage project' can see all projects
 | 
			
		||||
            if (featurePermission != null && featurePermission.Exists(c => c.Id.ToString() == "172fc9b6-755b-4f62-ab26-55c34a330614"))
 | 
			
		||||
            {
 | 
			
		||||
                // If GetAllProjectByTanentID is already optimized and directly returns IQueryable or
 | 
			
		||||
                // directly executes with ToListAsync(), keep it.
 | 
			
		||||
                // If it does more complex logic or extra trips, consider inlining here.
 | 
			
		||||
                projects = await projectQuery.ToListAsync(); // Directly query the context
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // 3. Efficiently get project allocations and then filter projects
 | 
			
		||||
                // Load allocations only once
 | 
			
		||||
                var allocation = await GetProjectByEmployeeID(LoggedInEmployee.Id);
 | 
			
		||||
 | 
			
		||||
                // If there are no allocations, return an empty list early
 | 
			
		||||
                if (allocation == null || !allocation.Any())
 | 
			
		||||
                {
 | 
			
		||||
                    return new List<Project>();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Use LINQ's Contains for efficient filtering by ProjectId
 | 
			
		||||
                var projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList(); // Get distinct Guids
 | 
			
		||||
 | 
			
		||||
                // Filter projects based on the retrieved ProjectIds
 | 
			
		||||
                projects = await projectQuery.Where(c => projectIds.Contains(c.Id)).ToListAsync();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return projects;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user