From af92ab977bcf16fc04455c4bb858a1252d6e5d54 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Thu, 9 Oct 2025 16:47:06 +0530 Subject: [PATCH] Added the get filter API --- Marco.Pms.Model/Filters/TaskFilter.cs | 1 + .../Controllers/TaskController.cs | 98 +++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/Marco.Pms.Model/Filters/TaskFilter.cs b/Marco.Pms.Model/Filters/TaskFilter.cs index dfb12b9..99921fd 100644 --- a/Marco.Pms.Model/Filters/TaskFilter.cs +++ b/Marco.Pms.Model/Filters/TaskFilter.cs @@ -5,6 +5,7 @@ public List? BuildingIds { get; set; } public List? FloorIds { get; set; } public List? ActivityIds { get; set; } + public List? ServiceIds { get; set; } public DateTime? dateFrom { get; set; } public DateTime? dateTo { get; set; } } diff --git a/Marco.Pms.Services/Controllers/TaskController.cs b/Marco.Pms.Services/Controllers/TaskController.cs index 5c31320..c6a96b3 100644 --- a/Marco.Pms.Services/Controllers/TaskController.cs +++ b/Marco.Pms.Services/Controllers/TaskController.cs @@ -482,6 +482,13 @@ namespace MarcoBMS.Services.Controllers taskAllocationQuery = taskAllocationQuery.Where(t => t.WorkItem != null && taskFilter.ActivityIds.Contains(t.WorkItem.ActivityId)); } + if (taskFilter.ServiceIds?.Any() ?? false) + { + taskAllocationQuery = taskAllocationQuery.Where(t => t.WorkItem != null && + t.WorkItem.ActivityMaster != null && + t.WorkItem.ActivityMaster.ActivityGroup != null && + taskFilter.ServiceIds.Contains(t.WorkItem.ActivityMaster.ActivityGroup.ServiceId)); + } if (taskFilter.dateFrom.HasValue && taskFilter.dateTo.HasValue) { taskAllocationQuery = taskAllocationQuery.Where(t => t.AssignmentDate.Date >= taskFilter.dateFrom.Value.Date && @@ -745,6 +752,97 @@ namespace MarcoBMS.Services.Controllers return Ok(ApiResponse.SuccessResponse(taskVM, "Success", 200)); } + [HttpGet("filter/{projectId}")] + public async Task GetTaskFilterObject(Guid projectId) + { + // Get the current tenant from claims/context + Guid tenantId = GetTenantId(); + + // Log API invocation with the project and tenant for traceability + _logger.LogInfo("Fetching filter objects for ProjectId={ProjectId}, TenantId={TenantId}", projectId, tenantId); + + try + { + // AsNoTracking for improved performance—no intention to update these records + // Only fetch & project properties actually required (DTO projection) + var tasks = await _context.TaskAllocations + .Include(t => t.WorkItem) + .ThenInclude(wi => wi!.WorkArea) + .ThenInclude(wa => wa!.Floor) + .ThenInclude(f => f!.Building) + .Include(t => t.WorkItem) + .ThenInclude(wi => wi!.ActivityMaster) + .ThenInclude(a => a!.ActivityGroup) + .ThenInclude(ag => ag!.Service) + .Where(t => t.WorkItem != null && + t.WorkItem.WorkArea != null && + t.WorkItem.WorkArea.Floor != null && + t.WorkItem.WorkArea.Floor.Building != null && + t.WorkItem.WorkArea.Floor.Building.ProjectId == projectId && + t.TenantId == tenantId).ToListAsync(); + + // Distinct by Id (since projection doesn't guarantee uniqueness across different allocations) + var buildings = tasks.Where(t => t.WorkItem != null && t.WorkItem.WorkArea != null && t.WorkItem.WorkArea.Floor != null && t.WorkItem.WorkArea.Floor.Building != null) + .Select(t => t.WorkItem!.WorkArea!.Floor!.Building!) + .Select(b => new + { + Id = b.Id, + Name = b.Name + }).Distinct().ToList(); + + var floors = tasks.Where(t => t.WorkItem != null && t.WorkItem.WorkArea != null && t.WorkItem.WorkArea.Floor != null) + .Select(t => t.WorkItem!.WorkArea!.Floor!) + .Select(f => new + { + Id = f.Id, + Name = f.FloorName, + BuildingId = f.BuildingId + }).Distinct().ToList(); + + var activities = tasks.Where(t => t.WorkItem != null && + t.WorkItem.ActivityMaster != null && + t.WorkItem.ActivityMaster.ActivityGroup != null && + t.WorkItem.ActivityMaster.ActivityGroup.Service != null) + .Select(t => t.WorkItem!.ActivityMaster!) + .Select(a => new + { + Id = a.Id, + Name = a.ActivityName + }).Distinct().ToList(); + + var services = tasks.Where(t => t.WorkItem != null && + t.WorkItem.ActivityMaster != null && + t.WorkItem.ActivityMaster.ActivityGroup != null && + t.WorkItem.ActivityMaster.ActivityGroup.Service != null) + .Select(t => t.WorkItem!.ActivityMaster!.ActivityGroup!.Service!) + .Select(s => new + { + Id = s.Id, + Name = s.Name + }).Distinct().ToList(); + + var response = new + { + Buildings = buildings, + Floors = floors, + Activities = activities, + Services = services + }; + + _logger.LogInfo("Successfully fetched filter objects for ProjectId={ProjectId}, TenantId={TenantId}", projectId, tenantId); + + // Use DTO in API response for clarity and easier frontend usage + return Ok(ApiResponse.SuccessResponse(response, "Filter object for task fetched successfully", 200)); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to fetch filter objects for ProjectId={ProjectId}, TenantId={TenantId}", projectId, tenantId); + // Return a standard error result + return StatusCode(500, ApiResponse.ErrorResponse("Failed to fetch filter object.", 500)); + } + } + + /// /// Approves a reported task after validation, updates status, and stores attachments/comments. ///