From 0095cd54f650f474ad3c4a90facec6e554dc23fa Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Wed, 23 Jul 2025 12:50:42 +0530 Subject: [PATCH] Added persigned Urls in Expesne Details API --- .../MongoDBModels/DocumentMongoDB.cs | 11 +++ .../Expenses/ExpenseDetailsMongoDB.cs | 3 +- .../ViewModels/DocumentManager/DocumentVM.cs | 8 ++ .../ViewModels/Expenses/ExpenseDetailsVM.cs | 4 +- .../Controllers/AttendanceController.cs | 4 +- .../Controllers/ForumController.cs | 16 ++-- .../Controllers/ImageController.cs | 12 +-- .../Controllers/TaskController.cs | 8 +- .../Controllers/WeatherForecastController.cs | 2 +- .../Helpers/CacheUpdateHelper.cs | 44 +++++++---- .../MappingProfiles/MappingProfile.cs | 11 +++ Marco.Pms.Services/Service/ExpensesService.cs | 77 ++++++++++--------- Marco.Pms.Services/Service/S3UploadService.cs | 3 +- 13 files changed, 126 insertions(+), 77 deletions(-) create mode 100644 Marco.Pms.Model/MongoDBModels/DocumentMongoDB.cs diff --git a/Marco.Pms.Model/MongoDBModels/DocumentMongoDB.cs b/Marco.Pms.Model/MongoDBModels/DocumentMongoDB.cs new file mode 100644 index 0000000..d65af2a --- /dev/null +++ b/Marco.Pms.Model/MongoDBModels/DocumentMongoDB.cs @@ -0,0 +1,11 @@ +namespace Marco.Pms.Model.MongoDBModels +{ + public class DocumentMongoDB + { + public string DocumentId { get; set; } = string.Empty; + public string FileName { get; set; } = string.Empty; + public string ContentType { get; set; } = string.Empty; + public string S3Key { get; set; } = string.Empty; + public string ThumbS3Key { get; set; } = string.Empty; + } +} diff --git a/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs b/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs index c0ffdd9..c58a22c 100644 --- a/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs +++ b/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs @@ -18,8 +18,7 @@ public string? TransactionId { get; set; } public string Description { get; set; } = string.Empty; public string? Location { get; set; } - public List S3Key { get; set; } = new List(); - public List? ThumbS3Key { get; set; } + public List Documents { get; set; } = new List(); public string? GSTNumber { get; set; } public int? NoOfPersons { get; set; } public bool IsActive { get; set; } = true; diff --git a/Marco.Pms.Model/ViewModels/DocumentManager/DocumentVM.cs b/Marco.Pms.Model/ViewModels/DocumentManager/DocumentVM.cs index 4940600..d971ea4 100644 --- a/Marco.Pms.Model/ViewModels/DocumentManager/DocumentVM.cs +++ b/Marco.Pms.Model/ViewModels/DocumentManager/DocumentVM.cs @@ -11,4 +11,12 @@ public string ContentType { get; set; } = string.Empty; public DateTime UploadedAt { get; set; } } + public class BasicDocumentVM + { + public Guid DocumentId { get; set; } + public string FileName { get; set; } = string.Empty; + public string ContentType { get; set; } = string.Empty; + public string? PreSignedUrl { get; set; } + public string? ThumbPreSignedUrl { get; set; } + } } diff --git a/Marco.Pms.Model/ViewModels/Expenses/ExpenseDetailsVM.cs b/Marco.Pms.Model/ViewModels/Expenses/ExpenseDetailsVM.cs index e44347a..34ecc24 100644 --- a/Marco.Pms.Model/ViewModels/Expenses/ExpenseDetailsVM.cs +++ b/Marco.Pms.Model/ViewModels/Expenses/ExpenseDetailsVM.cs @@ -1,4 +1,5 @@ using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.DocumentManager; using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Projects; @@ -22,8 +23,7 @@ namespace Marco.Pms.Model.ViewModels.Expenses public string? TransactionId { get; set; } public string Description { get; set; } = string.Empty; public string? Location { get; set; } - public List S3Key { get; set; } = new List(); - public List? ThumbS3Key { get; set; } + public List Documents { get; set; } = new List(); public string? GSTNumber { get; set; } public int? NoOfPersons { get; set; } public bool IsActive { get; set; } = true; diff --git a/Marco.Pms.Services/Controllers/AttendanceController.cs b/Marco.Pms.Services/Controllers/AttendanceController.cs index 7339966..5af6c67 100644 --- a/Marco.Pms.Services/Controllers/AttendanceController.cs +++ b/Marco.Pms.Services/Controllers/AttendanceController.cs @@ -74,7 +74,7 @@ namespace MarcoBMS.Services.Controllers foreach (var attendanceLog in lstAttendance) { string objectKey = attendanceLog.Document != null ? attendanceLog.Document.S3Key : string.Empty; - string preSignedUrl = string.IsNullOrEmpty(objectKey) ? string.Empty : _s3Service.GeneratePreSignedUrlAsync(objectKey); + string preSignedUrl = string.IsNullOrEmpty(objectKey) ? string.Empty : _s3Service.GeneratePreSignedUrl(objectKey); attendanceLogVMs.Add(attendanceLog.ToAttendanceLogVMFromAttendanceLog(preSignedUrl, preSignedUrl)); } _logger.LogInfo("{count} Attendance records fetched successfully", lstAttendance.Count); @@ -708,7 +708,7 @@ namespace MarcoBMS.Services.Controllers var objectKey = $"tenant-{tenantId}/Employee/{recordAttendanceDot.EmployeeID}/Attendance/{fileName}"; await _s3Service.UploadFileAsync(base64, fileType, objectKey); - preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(objectKey); + preSignedUrl = _s3Service.GeneratePreSignedUrl(objectKey); document = new Document { diff --git a/Marco.Pms.Services/Controllers/ForumController.cs b/Marco.Pms.Services/Controllers/ForumController.cs index fb6d0e7..4e3b948 100644 --- a/Marco.Pms.Services/Controllers/ForumController.cs +++ b/Marco.Pms.Services/Controllers/ForumController.cs @@ -129,7 +129,7 @@ namespace Marco.Pms.Services.Controllers string preSignedUrl = string.Empty; if (document != null) { - preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key); + preSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); } attachmentVMs.Add(attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl)); } @@ -301,7 +301,7 @@ namespace Marco.Pms.Services.Controllers string preSignedUrl = string.Empty; if (document != null) { - preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key); + preSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); } if (attachment.CommentId == null) { @@ -418,7 +418,7 @@ namespace Marco.Pms.Services.Controllers string preSignedUrl = string.Empty; if (document != null) { - preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key); + preSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); } attachmentVMs.Add(attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl)); } @@ -532,7 +532,7 @@ namespace Marco.Pms.Services.Controllers string preSignedUrl = string.Empty; if (document != null) { - preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key); + preSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); } attachmentVMs.Add(attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl)); } @@ -606,7 +606,7 @@ namespace Marco.Pms.Services.Controllers _context.TicketAttachments.Add(attachment); await _context.SaveChangesAsync(); - string preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key); + string preSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); TicketAttachmentVM attachmentVM = attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl); ticketAttachmentVMs.Add(attachmentVM); @@ -671,7 +671,7 @@ namespace Marco.Pms.Services.Controllers string preSignedUrl = string.Empty; if (document != null) { - preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key); + preSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); } if (attachment.CommentId == null) { @@ -749,7 +749,7 @@ namespace Marco.Pms.Services.Controllers string preSignedUrl = string.Empty; if (document != null) { - preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key); + preSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); } if (attachment.CommentId == null) { @@ -851,7 +851,7 @@ namespace Marco.Pms.Services.Controllers string preSignedUrl = string.Empty; if (document != null) { - preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key); + preSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); } if (attachment.CommentId == null) { diff --git a/Marco.Pms.Services/Controllers/ImageController.cs b/Marco.Pms.Services/Controllers/ImageController.cs index 9014171..cf046a8 100644 --- a/Marco.Pms.Services/Controllers/ImageController.cs +++ b/Marco.Pms.Services/Controllers/ImageController.cs @@ -220,8 +220,8 @@ namespace Marco.Pms.Services.Controllers Documents = d.Documents?.Select(x => new { Id = x.Id, - thumbnailUrl = x.ThumbS3Key != null ? _s3Service.GeneratePreSignedUrlAsync(x.ThumbS3Key) : (x.S3Key != null ? _s3Service.GeneratePreSignedUrlAsync(x.S3Key) : null), - Url = x.S3Key != null ? _s3Service.GeneratePreSignedUrlAsync(x.S3Key) : null, + thumbnailUrl = x.ThumbS3Key != null ? _s3Service.GeneratePreSignedUrl(x.ThumbS3Key) : (x.S3Key != null ? _s3Service.GeneratePreSignedUrl(x.S3Key) : null), + Url = x.S3Key != null ? _s3Service.GeneratePreSignedUrl(x.S3Key) : null, UploadedBy = x.UploadedBy?.ToBasicEmployeeVMFromEmployee() ?? uploadedBy?.ToBasicEmployeeVMFromEmployee(), UploadedAt = x.UploadedAt, }).ToList(), @@ -334,8 +334,8 @@ namespace Marco.Pms.Services.Controllers Documents = documents?.Select(x => new { Id = x.Id, - thumbnailUrl = x.ThumbS3Key != null ? _s3Service.GeneratePreSignedUrlAsync(x.ThumbS3Key) : (x.S3Key != null ? _s3Service.GeneratePreSignedUrlAsync(x.S3Key) : null), - Url = x.S3Key != null ? _s3Service.GeneratePreSignedUrlAsync(x.S3Key) : null, + thumbnailUrl = x.ThumbS3Key != null ? _s3Service.GeneratePreSignedUrl(x.ThumbS3Key) : (x.S3Key != null ? _s3Service.GeneratePreSignedUrl(x.S3Key) : null), + Url = x.S3Key != null ? _s3Service.GeneratePreSignedUrl(x.S3Key) : null, UploadedBy = x.UploadedBy?.ToBasicEmployeeVMFromEmployee() ?? uploadedBy?.ToBasicEmployeeVMFromEmployee(), UploadedAt = x.UploadedAt, }).ToList(), @@ -382,11 +382,11 @@ namespace Marco.Pms.Services.Controllers // Step 4: Generate pre-signed URLs for thumbnail and full image (if keys exist) string? thumbnailUrl = document.ThumbS3Key != null - ? _s3Service.GeneratePreSignedUrlAsync(document.ThumbS3Key) + ? _s3Service.GeneratePreSignedUrl(document.ThumbS3Key) : null; string? imageUrl = document.S3Key != null - ? _s3Service.GeneratePreSignedUrlAsync(document.S3Key) + ? _s3Service.GeneratePreSignedUrl(document.S3Key) : null; // Step 5: Prepare the response object diff --git a/Marco.Pms.Services/Controllers/TaskController.cs b/Marco.Pms.Services/Controllers/TaskController.cs index 6a1921b..9f648ac 100644 --- a/Marco.Pms.Services/Controllers/TaskController.cs +++ b/Marco.Pms.Services/Controllers/TaskController.cs @@ -499,7 +499,7 @@ namespace MarcoBMS.Services.Controllers .ToList(); response.ReportedPreSignedUrls = taskDocs - .Select(d => _s3Service.GeneratePreSignedUrlAsync(d.S3Key)) + .Select(d => _s3Service.GeneratePreSignedUrl(d.S3Key)) .ToList(); // Add team members @@ -532,7 +532,7 @@ namespace MarcoBMS.Services.Controllers var commentVm = comment.ToCommentVMFromTaskComment(); commentVm.PreSignedUrls = commentDocs - .Select(d => _s3Service.GeneratePreSignedUrlAsync(d.S3Key)) + .Select(d => _s3Service.GeneratePreSignedUrl(d.S3Key)) .ToList(); commentVMs.Add(commentVm); @@ -649,7 +649,7 @@ namespace MarcoBMS.Services.Controllers .ToList(); taskVM.PreSignedUrls = taskDocuments - .Select(d => _s3Service.GeneratePreSignedUrlAsync(d.S3Key)) + .Select(d => _s3Service.GeneratePreSignedUrl(d.S3Key)) .ToList(); // Construct CommentVM list with document URLs @@ -667,7 +667,7 @@ namespace MarcoBMS.Services.Controllers var commentVM = comment.ToCommentVMFromTaskComment(); commentVM.PreSignedUrls = commentDocs - .Select(d => _s3Service.GeneratePreSignedUrlAsync(d.S3Key)) + .Select(d => _s3Service.GeneratePreSignedUrl(d.S3Key)) .ToList(); return commentVM; diff --git a/Marco.Pms.Services/Controllers/WeatherForecastController.cs b/Marco.Pms.Services/Controllers/WeatherForecastController.cs index fae8c73..2ffd222 100644 --- a/Marco.Pms.Services/Controllers/WeatherForecastController.cs +++ b/Marco.Pms.Services/Controllers/WeatherForecastController.cs @@ -39,7 +39,7 @@ namespace MarcoBMS.Services.Controllers // return BadRequest("Base64 data is missing"); // var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, 1, "Forum"); // //var objectKey = await _s3Service.UploadFileAsync(Image.FileName, Image.ContentType); - // var preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(objectKey); + // var preSignedUrl = _s3Service.GeneratePreSignedUrl(objectKey); // return Ok(new // { diff --git a/Marco.Pms.Services/Helpers/CacheUpdateHelper.cs b/Marco.Pms.Services/Helpers/CacheUpdateHelper.cs index 13de18a..d7466c6 100644 --- a/Marco.Pms.Services/Helpers/CacheUpdateHelper.cs +++ b/Marco.Pms.Services/Helpers/CacheUpdateHelper.cs @@ -4,6 +4,7 @@ using Marco.Pms.Helpers; using Marco.Pms.Helpers.CacheHelper; using Marco.Pms.Model.Expenses; using Marco.Pms.Model.Master; +using Marco.Pms.Model.MongoDBModels; using Marco.Pms.Model.MongoDBModels.Expenses; using Marco.Pms.Model.MongoDBModels.Masters; using Marco.Pms.Model.MongoDBModels.Project; @@ -872,21 +873,26 @@ namespace Marco.Pms.Services.Helpers try { - var billAttachments = await _context.BillAttachments + var billAttachment = await _context.BillAttachments .Include(ba => ba.Document) .AsNoTracking() .Where(ba => ba.ExpensesId == expense.Id && ba.Document != null) .GroupBy(ba => ba.ExpensesId) .Select(g => new { - S3Keys = g.Select(ba => ba.Document!.S3Key).ToList(), - ThumbS3Keys = g.Select(ba => ba.Document!.ThumbS3Key ?? ba.Document.S3Key).ToList() + Documents = g.Select(ba => new DocumentMongoDB + { + DocumentId = ba.Document!.Id.ToString(), + FileName = ba.Document.FileName, + ContentType = ba.Document.ContentType, + S3Key = ba.Document.S3Key, + ThumbS3Key = ba.Document.ThumbS3Key ?? ba.Document.S3Key + }).ToList() }) .FirstOrDefaultAsync(); ; - if (billAttachments != null) + if (billAttachment != null) { - expenseCache.S3Key = billAttachments.S3Keys; - expenseCache.ThumbS3Key = billAttachments.ThumbS3Keys; + expenseCache.Documents = billAttachment.Documents; } } catch (Exception ex) @@ -922,14 +928,19 @@ namespace Marco.Pms.Services.Helpers .GroupBy(ba => ba.ExpensesId) .Select(g => new { - S3Keys = g.Select(ba => ba.Document!.S3Key).ToList(), - ThumbS3Keys = g.Select(ba => ba.Document!.ThumbS3Key ?? ba.Document.S3Key).ToList() + Documents = g.Select(ba => new DocumentMongoDB + { + DocumentId = ba.Document!.Id.ToString(), + FileName = ba.Document.FileName, + ContentType = ba.Document.ContentType, + S3Key = ba.Document.S3Key, + ThumbS3Key = ba.Document.ThumbS3Key ?? ba.Document.S3Key + }).ToList() }) .FirstOrDefaultAsync(); if (billAttachments != null) { - expenseCache.S3Key = billAttachments.S3Keys; - expenseCache.ThumbS3Key = billAttachments.ThumbS3Keys; + expenseCache.Documents = billAttachments.Documents; } } catch (Exception ex) @@ -965,14 +976,19 @@ namespace Marco.Pms.Services.Helpers .Select(g => new { ExpensesId = g.Key, - S3Keys = g.Select(ba => ba.Document!.S3Key).ToList(), - ThumbS3Keys = g.Select(ba => ba.Document!.ThumbS3Key ?? ba.Document.S3Key).ToList() + Documents = g.Select(ba => new DocumentMongoDB + { + DocumentId = ba.Document!.Id.ToString(), + FileName = ba.Document.FileName, + ContentType = ba.Document.ContentType, + S3Key = ba.Document.S3Key, + ThumbS3Key = ba.Document.ThumbS3Key ?? ba.Document.S3Key + }).ToList() }) .ToListAsync(); foreach (var expenseCache in expensesCache) { - expenseCache.S3Key = billAttachments.Where(ba => ba.ExpensesId == Guid.Parse(expenseCache.Id)).Select(ba => ba.S3Keys).FirstOrDefault() ?? new List(); - expenseCache.ThumbS3Key = billAttachments.Where(ba => ba.ExpensesId == Guid.Parse(expenseCache.Id)).Select(ba => ba.ThumbS3Keys).FirstOrDefault(); + expenseCache.Documents = billAttachments.Where(ba => ba.ExpensesId == Guid.Parse(expenseCache.Id)).Select(ba => ba.Documents).FirstOrDefault() ?? new List(); } } catch (Exception ex) diff --git a/Marco.Pms.Services/MappingProfiles/MappingProfile.cs b/Marco.Pms.Services/MappingProfiles/MappingProfile.cs index c21b93d..5db13c1 100644 --- a/Marco.Pms.Services/MappingProfiles/MappingProfile.cs +++ b/Marco.Pms.Services/MappingProfiles/MappingProfile.cs @@ -5,12 +5,14 @@ using Marco.Pms.Model.Dtos.Project; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Expenses; using Marco.Pms.Model.Master; +using Marco.Pms.Model.MongoDBModels; using Marco.Pms.Model.MongoDBModels.Employees; using Marco.Pms.Model.MongoDBModels.Expenses; using Marco.Pms.Model.MongoDBModels.Masters; using Marco.Pms.Model.MongoDBModels.Project; using Marco.Pms.Model.Projects; using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.DocumentManager; using Marco.Pms.Model.ViewModels.Employee; using Marco.Pms.Model.ViewModels.Expanses; using Marco.Pms.Model.ViewModels.Expenses; @@ -234,6 +236,15 @@ namespace Marco.Pms.Services.MappingProfiles #endregion + + #region ======================================================= Document ======================================================= + + CreateMap() + .ForMember( + dest => dest.DocumentId, + opt => opt.MapFrom(src => Guid.Parse(src.DocumentId))); + + #endregion } } } diff --git a/Marco.Pms.Services/Service/ExpensesService.cs b/Marco.Pms.Services/Service/ExpensesService.cs index a8ea7b8..4da381d 100644 --- a/Marco.Pms.Services/Service/ExpensesService.cs +++ b/Marco.Pms.Services/Service/ExpensesService.cs @@ -184,7 +184,7 @@ namespace Marco.Pms.Services.Service } expenseVM = await GetAllExpnesRelatedTables(expensesList); - + totalPages = (int)Math.Ceiling((double)totalEntites / pageSize); } else @@ -246,8 +246,13 @@ namespace Marco.Pms.Services.Service if (expenseDetails == null) { expenseDetails = await _cache.AddExpenseByIdAsync(id, tenantId); + if (expenseDetails == null) + { + return ApiResponse.ErrorResponse("Expense Not Found", "Expense Not Found", 404); + } } - var vm = GetAllExpnesRelatedTablesFromMongoDB([expenseDetails]); + var vm = await GetAllExpnesRelatedTablesFromMongoDB(expenseDetails); + return ApiResponse.SuccessResponse(vm, "Successfully fetched the details of expense", 200); } @@ -826,40 +831,32 @@ namespace Marco.Pms.Services.Service return expenseList; } - private async Task> GetAllExpnesRelatedTablesFromMongoDB(List model) + private async Task GetAllExpnesRelatedTablesFromMongoDB(ExpenseDetailsMongoDB model) { - List expenseList = new List(); - var projectIds = model.Select(m => Guid.Parse(m.ProjectId)).ToList(); - var statusIds = model.Select(m => Guid.Parse(m.StatusId)).ToList(); - var expensesTypeIds = model.Select(m => Guid.Parse(m.ExpensesTypeId)).ToList(); - var paymentModeIds = model.Select(m => Guid.Parse(m.PaymentModeId)).ToList(); - var createdByIds = model.Select(m => Guid.Parse(m.CreatedById)).ToList(); - var paidByIds = model.Select(m => Guid.Parse(m.PaidById)).ToList(); - var projectTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Projects.AsNoTracking().Where(p => projectIds.Contains(p.Id)).ToListAsync(); + return await dbContext.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Id == Guid.Parse(model.ProjectId)); }); var paidByTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.AsNoTracking().Where(e => paidByIds.Contains(e.Id)).ToListAsync(); + return await dbContext.Employees.AsNoTracking().FirstOrDefaultAsync(e => e.Id == Guid.Parse(model.PaidById)); }); var createdByTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.AsNoTracking().Where(e => createdByIds.Contains(e.Id)).ToListAsync(); + return await dbContext.Employees.AsNoTracking().FirstOrDefaultAsync(e => e.Id == Guid.Parse(model.CreatedById)); }); var expenseTypeTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesTypeMaster.AsNoTracking().Where(et => expensesTypeIds.Contains(et.Id)).ToListAsync(); + return await dbContext.ExpensesTypeMaster.AsNoTracking().FirstOrDefaultAsync(et => et.Id == Guid.Parse(model.ExpensesTypeId)); }); var paymentModeTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.PaymentModeMatser.AsNoTracking().Where(pm => paymentModeIds.Contains(pm.Id)).ToListAsync(); + return await dbContext.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(pm => pm.Id == Guid.Parse(model.PaymentModeId)); }); var statusMappingTask = Task.Run(async () => { @@ -868,44 +865,50 @@ namespace Marco.Pms.Services.Service .Include(s => s.Status) .Include(s => s.NextStatus) .AsNoTracking() - .Where(es => statusIds.Contains(es.StatusId) && es.Status != null) + .Where(es => es.StatusId == Guid.Parse(model.StatusId) && es.Status != null) .GroupBy(s => s.StatusId) .Select(g => new { - StatusId = g.Key, Status = g.Select(s => s.Status).FirstOrDefault(), NextStatus = g.Select(s => s.NextStatus).ToList() - }).ToListAsync(); + }).FirstOrDefaultAsync(); }); // Await all prerequisite checks at once. await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask); - var projects = await projectTask; - var expenseTypes = await expenseTypeTask; - var paymentModes = await paymentModeTask; - var statusMappings = await statusMappingTask; - var paidBys = await paidByTask; - var createdBys = await createdByTask; + var project = await projectTask; + var expenseType = await expenseTypeTask; + var paymentMode = await paymentModeTask; + var statusMapping = await statusMappingTask; + var paidBy = await paidByTask; + var createdBy = await createdByTask; - expenseList = model.Select(m => + var response = _mapper.Map(model); + + response.Project = _mapper.Map(project); + response.PaidBy = _mapper.Map(paidBy); + response.CreatedBy = _mapper.Map(createdBy); + response.PaymentMode = _mapper.Map(paymentMode); + response.ExpensesType = _mapper.Map(expenseType); + if (statusMapping != null) { - var response = _mapper.Map(m); + response.Status = _mapper.Map(statusMapping.Status); + response.NextStatus = _mapper.Map>(statusMapping.NextStatus); + } - response.Project = projects.Where(p => p.Id == Guid.Parse(m.ProjectId)).Select(p => _mapper.Map(p)).FirstOrDefault(); - response.PaidBy = paidBys.Where(p => p.Id == Guid.Parse(m.PaidById)).Select(p => _mapper.Map(p)).FirstOrDefault(); - response.CreatedBy = createdBys.Where(e => e.Id == Guid.Parse(m.CreatedById)).Select(e => _mapper.Map(e)).FirstOrDefault(); - response.Status = statusMappings.Where(s => s.StatusId == Guid.Parse(m.StatusId)).Select(s => _mapper.Map(s.Status)).FirstOrDefault(); - response.NextStatus = statusMappings.Where(s => s.StatusId == Guid.Parse(m.StatusId)).Select(s => _mapper.Map>(s.NextStatus)).FirstOrDefault(); - response.PaymentMode = paymentModes.Where(pm => pm.Id == Guid.Parse(m.PaymentModeId)).Select(pm => _mapper.Map(pm)).FirstOrDefault(); - response.ExpensesType = expenseTypes.Where(et => et.Id == Guid.Parse(m.ExpensesTypeId)).Select(et => _mapper.Map(et)).FirstOrDefault(); + foreach (var document in model.Documents) + { + var vm = response.Documents.FirstOrDefault(d => d.DocumentId == Guid.Parse(document.DocumentId)); - return response; - }).ToList(); + vm!.PreSignedUrl = _s3Service.GeneratePreSignedUrl(document.S3Key); + vm!.ThumbPreSignedUrl = _s3Service.GeneratePreSignedUrl(document.ThumbS3Key); + } - return expenseList; + return response; } + /// /// Deserializes the filter string, handling multiple potential formats (e.g., direct JSON vs. escaped JSON string). /// diff --git a/Marco.Pms.Services/Service/S3UploadService.cs b/Marco.Pms.Services/Service/S3UploadService.cs index b07093c..57a46fa 100644 --- a/Marco.Pms.Services/Service/S3UploadService.cs +++ b/Marco.Pms.Services/Service/S3UploadService.cs @@ -71,8 +71,9 @@ namespace Marco.Pms.Services.Service } - public string GeneratePreSignedUrlAsync(string objectKey) + public string GeneratePreSignedUrl(string objectKey) { + int expiresInMinutes = 10; var request = new GetPreSignedUrlRequest {