From 587e8d2b0b6c341b31122bab4ebd8105e3d10964 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Wed, 2 Jul 2025 10:02:22 +0530 Subject: [PATCH] Added an API to get list of images in provided project. --- .../Controllers/ImageController.cs | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 Marco.Pms.Services/Controllers/ImageController.cs diff --git a/Marco.Pms.Services/Controllers/ImageController.cs b/Marco.Pms.Services/Controllers/ImageController.cs new file mode 100644 index 0000000..7a4c556 --- /dev/null +++ b/Marco.Pms.Services/Controllers/ImageController.cs @@ -0,0 +1,171 @@ +using Marco.Pms.DataAccess.Data; +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Mapper; +using Marco.Pms.Model.Utilities; +using Marco.Pms.Services.Service; +using MarcoBMS.Services.Helpers; +using MarcoBMS.Services.Service; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Marco.Pms.Services.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ImageController : ControllerBase + { + private readonly ApplicationDbContext _context; + private readonly S3UploadService _s3Service; + private readonly UserHelper _userHelper; + private readonly ILoggingService _logger; + private readonly PermissionServices _permission; + private readonly Guid tenantId; + public ImageController(ApplicationDbContext context, S3UploadService s3Service, UserHelper userHelper, ILoggingService logger, PermissionServices permission) + { + _context = context; + _s3Service = s3Service; + _userHelper = userHelper; + _logger = logger; + tenantId = userHelper.GetTenantId(); + _permission = permission; + } + + [HttpGet("images/{projectId}")] + public async Task GetImageList(Guid projectId) + { + _logger.LogInfo("GetImageList called for ProjectId: {ProjectId}", projectId); + + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + + // Step 1: Validate project existence + var isProjectExist = await _context.Projects.AnyAsync(p => p.Id == projectId && p.TenantId == tenantId); + if (!isProjectExist) + { + _logger.LogWarning("Project not found for ProjectId: {ProjectId}", projectId); + return BadRequest(ApiResponse.ErrorResponse("Project not found", "Project not found in database", 400)); + } + + // Step 2: Check permission + var hasPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId.ToString()); + if (!hasPermission) + { + _logger.LogWarning("No access to ProjectId: {ProjectId} for EmployeeId: {EmployeeId}", projectId, loggedInEmployee.Id); + return StatusCode(403, ApiResponse.ErrorResponse("You don't have access", "You don't have access", 403)); + } + + // Step 3: Fetch building > floor > work area > work item hierarchy + var buildings = await _context.Buildings + .Where(b => b.ProjectId == projectId) + .Select(b => new { b.Id, b.Name }) + .ToListAsync(); + + var buildingIds = buildings.Select(b => b.Id).ToList(); + + var floors = await _context.Floor + .Where(f => buildingIds.Contains(f.BuildingId)) + .Select(f => new { f.Id, f.BuildingId, f.FloorName }) + .ToListAsync(); + + var floorIds = floors.Select(f => f.Id).ToList(); + + var workAreas = await _context.WorkAreas + .Where(wa => floorIds.Contains(wa.FloorId)) + .Select(wa => new { wa.Id, wa.FloorId, wa.AreaName }) + .ToListAsync(); + + var workAreaIds = workAreas.Select(wa => wa.Id).ToList(); + + var workItems = await _context.WorkItems + .Include(wi => wi.ActivityMaster) + .Where(wi => workAreaIds.Contains(wi.WorkAreaId)) + .Select(wi => new { wi.Id, wi.WorkAreaId, wi.ActivityMaster }) + .ToListAsync(); + + var workItemIds = workItems.Select(wi => wi.Id).ToList(); + + // Step 4: Fetch task and comment data + var tasks = await _context.TaskAllocations + .Include(t => t.ReportedBy) + .Where(t => workItemIds.Contains(t.WorkItemId)) + .ToListAsync(); + + var taskIds = tasks.Select(t => t.Id).ToList(); + + var comments = await _context.TaskComments + .Include(c => c.Employee) + .Where(c => taskIds.Contains(c.TaskAllocationId)) + .ToListAsync(); + + var commentIds = comments.Select(c => c.Id).ToList(); + + // Step 5: Fetch attachments and related documents + var attachments = await _context.TaskAttachments + .Where(ta => taskIds.Contains(ta.ReferenceId) || commentIds.Contains(ta.ReferenceId)) + .ToListAsync(); + + var documentIds = attachments.Select(ta => ta.DocumentId).ToList(); + + var documents = await _context.Documents + .Include(d => d.UploadedBy) + .Where(d => documentIds.Contains(d.Id)) + .ToListAsync(); + + // Step 6: Prepare view models + var documentVM = documents + .Select(d => + { + var referenceId = attachments + .Where(ta => ta.DocumentId == d.Id) + .Select(ta => ta.ReferenceId) + .FirstOrDefault(); + + var task = tasks.FirstOrDefault(t => t.Id == referenceId); + var comment = comments.FirstOrDefault(c => c.Id == referenceId); + + string source = ""; + Employee? uploadedBy = null; + if (task != null) + { + uploadedBy = task.ReportedBy; + source = "Report"; + } + else if (comment != null) + { + task = tasks.FirstOrDefault(t => t.Id == comment.TaskAllocationId); + uploadedBy = comment.Employee; + source = "Comment"; + } + + var workItem = workItems.FirstOrDefault(wi => wi.Id == task?.WorkItemId); + var workArea = workAreas.FirstOrDefault(wa => wa.Id == workItem?.WorkAreaId); + var floor = floors.FirstOrDefault(f => f.Id == workArea?.FloorId); + var building = buildings.FirstOrDefault(b => b.Id == floor?.BuildingId); + + return new + { + Id = d.Id, + BatchId = d.BatchId, + thumbnailUrl = d.ThumbS3Key != null ? _s3Service.GeneratePreSignedUrlAsync(d.ThumbS3Key) : (d.S3Key != null ? _s3Service.GeneratePreSignedUrlAsync(d.S3Key) : null), + ImageUrl = d.S3Key != null ? _s3Service.GeneratePreSignedUrlAsync(d.S3Key) : null, + UploadedBy = d.UploadedBy?.ToBasicEmployeeVMFromEmployee() ?? uploadedBy?.ToBasicEmployeeVMFromEmployee(), + UploadedAt = d.UploadedAt, + Source = source, + ProjectId = projectId, + BuildingId = building?.Id, + BuildingName = building?.Name, + FloorIds = floor?.Id, + FloorName = floor?.FloorName, + WorkAreaId = workArea?.Id, + WorkAreaName = workArea?.AreaName, + TaskId = task?.Id, + ActivityName = workItem?.ActivityMaster?.ActivityName, + CommentId = comment?.Id, + Comment = comment?.Comment + }; + }).ToList(); + + _logger.LogInfo("Image list fetched for ProjectId: {ProjectId}. Total documents: {Count}", projectId, documentVM.Count); + return Ok(ApiResponse.SuccessResponse(documentVM, $"{documentVM.Count} image records fetched successfully", 200)); + } + } +}