From 2b6c8861863c6c7b43f30df0531b9889f4a099ce Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Tue, 11 Nov 2025 18:21:29 +0530 Subject: [PATCH] Added the pagination in get service project list --- .../Dtos/ServiceProject/ServiceProjectDto.cs | 1 + .../Controllers/ServiceProjectController.cs | 16 +-- .../ServiceInterfaces/IServiceProject.cs | 12 +- .../Service/ServiceProjectService.cs | 120 +++++++++++++++--- 4 files changed, 116 insertions(+), 33 deletions(-) diff --git a/Marco.Pms.Model/Dtos/ServiceProject/ServiceProjectDto.cs b/Marco.Pms.Model/Dtos/ServiceProject/ServiceProjectDto.cs index b5c7e1e..4e969e8 100644 --- a/Marco.Pms.Model/Dtos/ServiceProject/ServiceProjectDto.cs +++ b/Marco.Pms.Model/Dtos/ServiceProject/ServiceProjectDto.cs @@ -4,6 +4,7 @@ namespace Marco.Pms.Model.Dtos.ServiceProject { public class ServiceProjectDto { + public Guid? Id { get; set; } public required string Name { get; set; } public required string ShortName { get; set; } public required Guid ClientId { get; set; } diff --git a/Marco.Pms.Services/Controllers/ServiceProjectController.cs b/Marco.Pms.Services/Controllers/ServiceProjectController.cs index 60c4182..fd62672 100644 --- a/Marco.Pms.Services/Controllers/ServiceProjectController.cs +++ b/Marco.Pms.Services/Controllers/ServiceProjectController.cs @@ -1,6 +1,5 @@ using Marco.Pms.Model.Dtos.ServiceProject; using Marco.Pms.Model.Employees; -using Marco.Pms.Model.ServiceProject; using Marco.Pms.Model.Utilities; using Marco.Pms.Services.Service.ServiceInterfaces; using MarcoBMS.Services.Helpers; @@ -20,7 +19,8 @@ namespace Marco.Pms.Services.Controllers private readonly ILoggingService _logger; private readonly ISignalRService _signalR; private readonly Guid tenantId; - public ServiceProjectController(IServiceProject serviceProject,UserHelper userHelper, ILoggingService logger, ISignalRService signalR) { + public ServiceProjectController(IServiceProject serviceProject, UserHelper userHelper, ILoggingService logger, ISignalRService signalR) + { _serviceProject = serviceProject; _userHelper = userHelper; _logger = logger; @@ -30,7 +30,7 @@ namespace Marco.Pms.Services.Controllers } - [HttpPost] + [HttpPost("create")] public async Task CreateProject([FromBody] ServiceProjectDto serviceProject) { if (!ModelState.IsValid) @@ -38,7 +38,7 @@ namespace Marco.Pms.Services.Controllers var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } - Employee LoggedInEmploee = await _userHelper.GetCurrentEmployeeAsync(); + Employee LoggedInEmploee = await _userHelper.GetCurrentEmployeeAsync(); var response = await _serviceProject.CreateServiceProject(serviceProject, tenantId, LoggedInEmploee); if (response.Success) { @@ -49,8 +49,8 @@ namespace Marco.Pms.Services.Controllers } - [HttpGet] - public async Task GetServiceProjectList() + [HttpGet("list")] + public async Task GetServiceProjectList([FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20) { if (!ModelState.IsValid) { @@ -58,7 +58,7 @@ namespace Marco.Pms.Services.Controllers return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } Employee LoggedInEmploee = await _userHelper.GetCurrentEmployeeAsync(); - var response = await _serviceProject.GetServiceProjectList(tenantId, LoggedInEmploee); + var response = await _serviceProject.GetServiceProjectList(pageNumber, pageSize, LoggedInEmploee, tenantId); return StatusCode(response.StatusCode, response); @@ -66,7 +66,7 @@ namespace Marco.Pms.Services.Controllers - [HttpPut("updat/serviceProject/{id}")] + [HttpPut("edit/{id}")] public async Task UpdateProject(Guid id, [FromBody] ServiceProjectDto serviceProject) { if (!ModelState.IsValid) diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IServiceProject.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IServiceProject.cs index 8b1642f..65557de 100644 --- a/Marco.Pms.Services/Service/ServiceInterfaces/IServiceProject.cs +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IServiceProject.cs @@ -1,20 +1,18 @@ using Marco.Pms.Model.Dtos.ServiceProject; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Utilities; -using MarcoBMS.Services.Helpers; -using Microsoft.AspNetCore.Mvc; namespace Marco.Pms.Services.Service.ServiceInterfaces { public interface IServiceProject { - Task> CreateServiceProject(ServiceProjectDto serviceProject,Guid TenantId,Employee loggedInEmployee); - Task> GetServiceProjectList(Guid tenantId, Employee loggedInEmployee); - Task> UpdateServiceProject(Guid id,ServiceProjectDto serviceProject, Guid tenantId, Employee loggedInEmployee); + Task> CreateServiceProject(ServiceProjectDto serviceProject, Guid TenantId, Employee loggedInEmployee); + Task> GetServiceProjectList(int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId); + Task> UpdateServiceProject(Guid id, ServiceProjectDto serviceProject, Guid tenantId, Employee loggedInEmployee); } - - } + +} diff --git a/Marco.Pms.Services/Service/ServiceProjectService.cs b/Marco.Pms.Services/Service/ServiceProjectService.cs index d2a74ce..1800fa5 100644 --- a/Marco.Pms.Services/Service/ServiceProjectService.cs +++ b/Marco.Pms.Services/Service/ServiceProjectService.cs @@ -79,8 +79,8 @@ namespace Marco.Pms.Services.Service serviceProject.Id = Guid.NewGuid(); serviceProject.CreatedById = loggedInEmployee.Id; serviceProject.CreatedAt = DateTime.UtcNow; - serviceProject.TenantId = tenantId; serviceProject.IsActive = true; + serviceProject.TenantId = tenantId; var projectServiceMapping = model.Services.Where(sdto => services.Any(s => s.Id == sdto.ServiceId)).Select(sdto => new ServiceProjectServiceMapping { @@ -92,17 +92,21 @@ namespace Marco.Pms.Services.Service { _context.ServiceProjects.Add(serviceProject); _context.ServiceProjectServiceMapping.AddRange(projectServiceMapping); + await _context.SaveChangesAsync(); + _logger.LogInfo("Service Project {ProjectId} created successfully for TenantId={TenantId}, by Employee {EmployeeId}.", serviceProject.Id, tenantId, loggedInEmployee); var serviceProjectVM = _mapper.Map(serviceProject); + serviceProjectVM.Client = _mapper.Map(client); serviceProjectVM.Status = status; + serviceProjectVM.Services = services.Where(s => serviceIds.Contains(s.Id)).Select(s => _mapper.Map(s)).ToList(); - serviceProjectVM.CreatedBy = _mapper.Map(loggedInEmployee); serviceProjectVM.CreatedAt = DateTime.UtcNow; + serviceProjectVM.CreatedBy = _mapper.Map(loggedInEmployee); return ApiResponse.SuccessResponse(serviceProjectVM, "An Successfullly occurred while saving the project.", 201); } @@ -114,18 +118,23 @@ namespace Marco.Pms.Services.Service } - - public async Task> GetServiceProjectList(Guid tenantId, Employee loggedInEmployee) + public async Task> GetServiceProjectList(int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId) { try { - var serviceProjects = await _context.ServiceProjects + var serviceProjectQuery = _context.ServiceProjects .Include(sp => sp.Client) .Include(sp => sp.Status) .Include(sp => sp.CreatedBy).ThenInclude(e => e!.JobRole) .Include(sp => sp.UpdatedBy).ThenInclude(e => e!.JobRole) - .Where(sp => sp.TenantId == tenantId && sp.IsActive).ToListAsync(); + .Where(sp => sp.TenantId == tenantId && sp.IsActive); + + var serviceProjects = await serviceProjectQuery + .OrderByDescending(e => e.CreatedAt) + .Skip((pageNumber - 1) * pageSize) + .Take(pageSize) + .ToListAsync(); var serviceProjectIds = serviceProjects.Select(sp => sp.Id).ToList(); var serviceProjectServiceMappings = await _context.ServiceProjectServiceMapping @@ -153,12 +162,41 @@ namespace Marco.Pms.Services.Service } } - - public async Task> UpdateServiceProject(Guid id, ServiceProjectDto model, Guid tenantId, Employee loggedInEmployee) { try { + var serviceIds = model.Services.Select(s => s.ServiceId).ToList(); + var clientTask = Task.Run(async () => + { + await using var context = await _dbContextFactory.CreateDbContextAsync(); + return await context.Organizations.FirstOrDefaultAsync(o => o.Id == model.ClientId && o.IsActive); + }); + var serviceTask = Task.Run(async () => + { + await using var context = await _dbContextFactory.CreateDbContextAsync(); + return await context.ServiceMasters.Where(s => serviceIds.Contains(s.Id) && s.TenantId == tenantId && s.IsActive).ToListAsync(); + }); + var statusTask = Task.Run(async () => + { + await using var context = await _dbContextFactory.CreateDbContextAsync(); + return await context.StatusMasters.FirstOrDefaultAsync(s => s.Id == model.StatusId); + }); + + await Task.WhenAll(clientTask, serviceTask, statusTask); + + var client = clientTask.Result; + var services = serviceTask.Result; + var status = statusTask.Result; + + if (client == null) + { + return ApiResponse.ErrorResponse("Client not found", "Client not found", 404); + } + if (status == null) + { + return ApiResponse.ErrorResponse("Project Status not found", "Project Status not found", 404); + } var serviceProject = await _context.ServiceProjects.Where(sp => sp.Id == id && sp.TenantId == tenantId).FirstOrDefaultAsync(); @@ -168,23 +206,73 @@ namespace Marco.Pms.Services.Service return ApiResponse.ErrorResponse("Project not found.", $"No project found with ID {id}.", 404); } - - _mapper.Map(model, serviceProject); - serviceProject.UpdatedAt = DateTime.UtcNow; serviceProject.UpdatedById = loggedInEmployee.Id; + + var serviceProjectServiceMappings = await _context.ServiceProjectServiceMapping + .AsNoTracking() + .Where(sps => sps.ProjectId == serviceProject.Id && sps.TenantId == tenantId) + .ToListAsync(); + + var newMapping = new List(); + var removedMapping = new List(); + + foreach (var dto in model.Services) + { + var serviceProjectServiceMapping = serviceProjectServiceMappings + .FirstOrDefault(sps => sps.ServiceId == dto.ServiceId); + + if (dto.IsActive && serviceProjectServiceMapping == null) + { + newMapping.Add(new ServiceProjectServiceMapping + { + Id = Guid.NewGuid(), + ServiceId = dto.ServiceId, + ProjectId = serviceProject.Id, + TenantId = tenantId, + }); + } + else if (!dto.IsActive && serviceProjectServiceMapping != null) + { + removedMapping.Add(serviceProjectServiceMapping); + } + } + + _context.ServiceProjectServiceMapping.AddRange(newMapping); + _context.ServiceProjectServiceMapping.RemoveRange(removedMapping); + await _context.SaveChangesAsync(); + var serviceProjectTask = Task.Run(async () => + { + await using var context = await _dbContextFactory.CreateDbContextAsync(); + return await context.ServiceProjects + .Include(sp => sp.Client) + .Include(sp => sp.Status) + .Include(sp => sp.CreatedBy).ThenInclude(e => e!.JobRole) + .Include(sp => sp.UpdatedBy).ThenInclude(e => e!.JobRole) + .Where(sp => sp.TenantId == tenantId && sp.IsActive).FirstOrDefaultAsync(); + }); - serviceProject = await _context.ServiceProjects.Include(sp => sp.UpdatedBy).Where(sp => sp.Id == id && sp.TenantId == tenantId).FirstOrDefaultAsync(); + var servicesTask = Task.Run(async () => + { + await using var context = await _dbContextFactory.CreateDbContextAsync(); + return await context.ServiceProjectServiceMapping + .Include(sps => sps.Service) + .Where(sps => sps.ProjectId == serviceProject.Id && sps.Service != null && sps.TenantId == tenantId) + .Select(sps => sps.Service!) + .ToListAsync(); + }); - var services = await _context.ServiceProjectServiceMapping.Include(t => t.Service).Where(t => t.ProjectId == serviceProject!.Id && t.Service != null && t.TenantId == tenantId).Select(t => t.Service!).ToListAsync(); + await Task.WhenAll(serviceProjectTask, servicesTask); + serviceProject = serviceProjectTask.Result; + services = servicesTask.Result; + ServiceProjectVM serviceProjectVm = _mapper.Map(serviceProject); - serviceProjectVm.Services = _mapper.Map>(services); return ApiResponse.SuccessResponse(serviceProjectVm, "Service Project updated successfully.", 200); @@ -198,9 +286,5 @@ namespace Marco.Pms.Services.Service } - - - - } }