Merge pull request 'Added the update document API' (#120) from Ashutosh_Task#1010 into Document_Manager
Reviewed-on: #120
This commit is contained in:
commit
759fa9324b
@ -12,4 +12,15 @@ namespace Marco.Pms.Model.Dtos.DocumentManager
|
||||
public required FileUploadModel Attachment { get; set; }
|
||||
public List<DocumentTagDto>? Tags { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateDocumentAttachmentDto
|
||||
{
|
||||
public required Guid Id { get; set; }
|
||||
public required string Name { get; set; }
|
||||
public string? DocumentId { get; set; }
|
||||
public required string Description { get; set; }
|
||||
public FileUploadModel? Attachment { get; set; }
|
||||
public List<DocumentTagDto>? Tags { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
using AutoMapper;
|
||||
using Marco.Pms.DataAccess.Data;
|
||||
using Marco.Pms.Helpers.Utility;
|
||||
using Marco.Pms.Model.DocumentManager;
|
||||
using Marco.Pms.Model.Dtos.DocumentManager;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.Filters;
|
||||
using Marco.Pms.Model.MongoDBModels.Utility;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Model.ViewModels.Activities;
|
||||
using Marco.Pms.Model.ViewModels.DocumentManager;
|
||||
@ -34,6 +36,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
|
||||
private static readonly Guid ProjectEntity = Guid.Parse("c8fe7115-aa27-43bc-99f4-7b05fabe436e");
|
||||
private static readonly Guid EmployeeEntity = Guid.Parse("dbb9555a-7a0c-40f2-a9ed-f0463f1ceed7");
|
||||
private static readonly string Collection = "DocumentModificationLog";
|
||||
|
||||
public DocumentController(IDbContextFactory<ApplicationDbContext> dbContextFactory,
|
||||
IServiceScopeFactory serviceScope,
|
||||
@ -54,7 +57,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
/// Fetch documents for a given entity (Project/Employee) with filtering, searching, and pagination.
|
||||
/// </summary>
|
||||
[HttpGet("list/{entityTypeId}/entity/{entityId}")]
|
||||
public async Task<IActionResult> GetDocumentList(Guid entityTypeId, Guid entityId, [FromQuery] string? filter, [FromQuery] string? searchString,
|
||||
public async Task<IActionResult> GetDocumentListAsync(Guid entityTypeId, Guid entityId, [FromQuery] string? filter, [FromQuery] string? searchString,
|
||||
[FromQuery] bool isActive = true, [FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20)
|
||||
{
|
||||
using var scope = _serviceScope.CreateScope();
|
||||
@ -237,13 +240,12 @@ namespace Marco.Pms.Services.Controllers
|
||||
/// Validates permissions, document type, entity existence, tags, and uploads to S3.
|
||||
/// </summary>
|
||||
[HttpPost("upload")]
|
||||
public async Task<IActionResult> UploadDocument([FromBody] DocumentAttachmentDto model)
|
||||
public async Task<IActionResult> UploadDocumentAsync([FromBody] DocumentAttachmentDto model)
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScope.CreateScope();
|
||||
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
||||
logger.LogInfo("Document upload initiated for EntityId: {EntityId}, DocumentTypeId: {DocumentTypeId}", model.EntityId, model.DocumentTypeId);
|
||||
_logger.LogInfo("Document upload initiated for EntityId: {EntityId}, DocumentTypeId: {DocumentTypeId}", model.EntityId, model.DocumentTypeId);
|
||||
|
||||
try
|
||||
{
|
||||
@ -256,7 +258,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
|
||||
if (!hasUploadPermission && loggedInEmployee.Id != model.EntityId)
|
||||
{
|
||||
logger.LogWarning("Access Denied. User {UserId} tried to upload document for {EntityId}", loggedInEmployee.Id, model.EntityId);
|
||||
_logger.LogWarning("Access Denied. User {UserId} tried to upload document for {EntityId}", loggedInEmployee.Id, model.EntityId);
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to upload this document", 403));
|
||||
}
|
||||
|
||||
@ -267,14 +269,14 @@ namespace Marco.Pms.Services.Controllers
|
||||
|
||||
if (documentType == null)
|
||||
{
|
||||
logger.LogWarning("DocumentTypeId {DocumentTypeId} not found for Tenant {TenantId}", model.DocumentTypeId, tenantId);
|
||||
_logger.LogWarning("DocumentTypeId {DocumentTypeId} not found for Tenant {TenantId}", model.DocumentTypeId, tenantId);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Document Type not found", "Document Type not found in database", 404));
|
||||
}
|
||||
|
||||
// Document ID validation
|
||||
if (documentType.IsMandatory && string.IsNullOrWhiteSpace(model.DocumentId))
|
||||
{
|
||||
logger.LogWarning("Mandatory DocumentId missing for DocumentTypeId: {DocumentTypeId}", documentType.Id);
|
||||
_logger.LogWarning("Mandatory DocumentId missing for DocumentTypeId: {DocumentTypeId}", documentType.Id);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Document ID missing", "User must provide the document ID for this document", 400));
|
||||
}
|
||||
|
||||
@ -282,7 +284,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
if (!Regex.IsMatch(model.DocumentId, documentType.RegexExpression))
|
||||
{
|
||||
logger.LogWarning("Invalid DocumentId format for DocumentTypeId: {DocumentTypeId}, Provided: {DocumentId}", documentType.Id, model.DocumentId);
|
||||
_logger.LogWarning("Invalid DocumentId format for DocumentTypeId: {DocumentTypeId}, Provided: {DocumentId}", documentType.Id, model.DocumentId);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Document ID", "Provided document ID is not valid", 400));
|
||||
}
|
||||
}
|
||||
@ -302,7 +304,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
|
||||
if (!entityExists)
|
||||
{
|
||||
logger.LogWarning("Entity not found. EntityType: {EntityType}, EntityId: {EntityId}", entityType, model.EntityId);
|
||||
_logger.LogWarning("Entity not found. EntityType: {EntityType}, EntityId: {EntityId}", entityType, model.EntityId);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse($"{(entityType == EmployeeEntity ? "Employee" : "Project")} Not Found", "Entity not found in database", 404));
|
||||
}
|
||||
|
||||
@ -310,19 +312,20 @@ namespace Marco.Pms.Services.Controllers
|
||||
var attachment = _mapper.Map<DocumentAttachment>(model);
|
||||
attachment.UploadedAt = DateTime.UtcNow;
|
||||
attachment.UploadedById = loggedInEmployee.Id;
|
||||
attachment.IsCurrentVersion = true;
|
||||
attachment.TenantId = tenantId;
|
||||
|
||||
// Validate Attachment
|
||||
if (model.Attachment.FileSize > documentType.MaxSizeAllowedInMB)
|
||||
{
|
||||
logger.LogWarning("File size {FileSize} exceeded max allowed {MaxSize}MB", model.Attachment.FileSize, documentType.MaxSizeAllowedInMB);
|
||||
_logger.LogWarning("File size {FileSize} exceeded max allowed {MaxSize}MB", model.Attachment.FileSize, documentType.MaxSizeAllowedInMB);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("File size limit exceeded", $"Max allowed {documentType.MaxSizeAllowedInMB} MB.", 400));
|
||||
}
|
||||
|
||||
string base64 = model.Attachment.Base64Data?.Split(',').LastOrDefault() ?? "";
|
||||
if (string.IsNullOrWhiteSpace(base64))
|
||||
{
|
||||
logger.LogWarning("Missing Base64 data for attachment.");
|
||||
_logger.LogWarning("Missing Base64 data for attachment.");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data missing", "File data required", 400));
|
||||
}
|
||||
|
||||
@ -332,7 +335,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
var validContentTypes = documentType.AllowedContentType.Split(',').ToList();
|
||||
if (!validContentTypes.Contains(fileType))
|
||||
{
|
||||
logger.LogWarning("Unsupported file type {FileType} for DocumentType {DocumentTypeId}", fileType, documentType.Id);
|
||||
_logger.LogWarning("Unsupported file type {FileType} for DocumentType {DocumentTypeId}", fileType, documentType.Id);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Unsupported file type", $"Unsupported file type: {fileType}", 400));
|
||||
}
|
||||
|
||||
@ -346,6 +349,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
// Fire-and-forget upload
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
||||
try
|
||||
{
|
||||
await s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||
@ -427,7 +431,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
logger.LogInfo("Document uploaded successfully. AttachmentId: {AttachmentId}, DocumentId: {DocumentId}", attachment.Id, document.Id);
|
||||
_logger.LogInfo("Document uploaded successfully. AttachmentId: {AttachmentId}, DocumentId: {DocumentId}", attachment.Id, document.Id);
|
||||
|
||||
var response = _mapper.Map<DocumentListVM>(attachment);
|
||||
response.UploadedBy = _mapper.Map<BasicEmployeeVM>(loggedInEmployee);
|
||||
@ -438,19 +442,313 @@ namespace Marco.Pms.Services.Controllers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Unexpected error during document upload.");
|
||||
_logger.LogError(ex, "Unexpected error during document upload.");
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal Server Error", "An error occurred while uploading the document", 500));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// PUT api/<DocumentController>/5
|
||||
[HttpPut("{id}")]
|
||||
public async Task Put(int id, [FromBody] string value)
|
||||
[HttpPut("edit/{id}")]
|
||||
public async Task<IActionResult> UpdateDocumentAsync(Guid id, [FromBody] UpdateDocumentAttachmentDto model)
|
||||
{
|
||||
// Logger initialization at the start for consistent logging
|
||||
using var scope = _serviceScope.CreateScope();
|
||||
_logger.LogInfo("Start UpdateDocument API for AttachmentId: {AttachmentId}", id);
|
||||
|
||||
try
|
||||
{
|
||||
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
// Get logged-in employee details
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||
var hasUploadPermission = await permissionService.HasPermission(PermissionsMaster.UploadDocument, loggedInEmployee.Id);
|
||||
|
||||
// Fetch the existing attachment
|
||||
var oldAttachment = await dbContext.DocumentAttachments
|
||||
.Include(da => da.DocumentType)
|
||||
.ThenInclude(dt => dt!.DocumentCategory)
|
||||
.FirstOrDefaultAsync(da => da.Id == id && da.IsCurrentVersion && da.TenantId == tenantId);
|
||||
|
||||
if (oldAttachment == null)
|
||||
{
|
||||
_logger.LogWarning("Attachment not found for Id: {AttachmentId}", id);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Attachment not found", "Attachment not found in database", 404));
|
||||
}
|
||||
|
||||
// Permission check: ensure uploader is authorized
|
||||
if (!hasUploadPermission && loggedInEmployee.Id != oldAttachment.EntityId)
|
||||
{
|
||||
_logger.LogWarning("Access denied for EmployeeId: {EmployeeId}", loggedInEmployee.Id);
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to upload this document", 403));
|
||||
}
|
||||
|
||||
// Validate the document type
|
||||
var documentType = oldAttachment.DocumentType;
|
||||
if (documentType == null)
|
||||
{
|
||||
_logger.LogWarning("Document type not found for AttachmentId: {AttachmentId}", id);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Document Type not found", "Document Type not found in database", 404));
|
||||
}
|
||||
|
||||
// Mandatory DocumentID check
|
||||
if (documentType.IsMandatory && string.IsNullOrWhiteSpace(model.DocumentId))
|
||||
{
|
||||
_logger.LogWarning("Document ID missing for mandatory DocumentTypeId: {DocumentTypeId}", documentType.Id);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Document ID missing", "User must provide the document ID for this document", 400));
|
||||
}
|
||||
|
||||
// DocumentID Regex validation
|
||||
if (documentType.IsValidationRequired && !string.IsNullOrWhiteSpace(model.DocumentId) && !string.IsNullOrWhiteSpace(documentType.RegexExpression))
|
||||
{
|
||||
if (!Regex.IsMatch(model.DocumentId, documentType.RegexExpression))
|
||||
{
|
||||
_logger.LogWarning("Provided document ID does not match regex for DocumentTypeId: {DocumentTypeId}", documentType.Id);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Document ID", "Provided document ID is not valid", 400));
|
||||
}
|
||||
}
|
||||
|
||||
// Validate entity existence and project-level permission
|
||||
var entityType = documentType.DocumentCategory!.EntityTypeId;
|
||||
bool entityExists;
|
||||
if (entityType.Equals(EmployeeEntity))
|
||||
{
|
||||
entityExists = await dbContext.Employees.AnyAsync(e => e.Id == oldAttachment.EntityId && e.TenantId == tenantId);
|
||||
}
|
||||
else if (entityType.Equals(ProjectEntity))
|
||||
{
|
||||
entityExists = await dbContext.Projects.AnyAsync(p => p.Id == oldAttachment.EntityId && p.TenantId == tenantId);
|
||||
if (entityExists)
|
||||
{
|
||||
entityExists = await permissionService.HasProjectPermission(loggedInEmployee, oldAttachment.EntityId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
entityExists = false;
|
||||
}
|
||||
|
||||
if (!entityExists)
|
||||
{
|
||||
_logger.LogWarning("Entity not found (Employee/Project) for AttachmentId: {AttachmentId}", id);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse($"{(entityType == EmployeeEntity ? "Employee" : "Project")} Not Found", "Entity not found in database", 404));
|
||||
}
|
||||
|
||||
// Prepare for versioning
|
||||
var oldVersionMapping = await dbContext.AttachmentVersionMappings
|
||||
.FirstOrDefaultAsync(av => av.ChildAttachmentId == oldAttachment.Id && av.TenantId == tenantId);
|
||||
|
||||
var updateLogHelper = scope.ServiceProvider.GetRequiredService<UtilityMongoDBHelper>();
|
||||
var existingEntityBson = updateLogHelper.EntityToBsonDocument(oldAttachment);
|
||||
|
||||
DocumentAttachment newAttachment;
|
||||
AttachmentVersionMapping newVersionMapping;
|
||||
|
||||
if (model.Attachment != null)
|
||||
{
|
||||
// File size check
|
||||
if (model.Attachment.FileSize > documentType.MaxSizeAllowedInMB)
|
||||
{
|
||||
_logger.LogWarning("Attachment exceeded max file size for DocumentTypeId: {DocumentTypeId}", documentType.Id);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("File size limit exceeded", $"Max allowed {documentType.MaxSizeAllowedInMB} MB.", 400));
|
||||
}
|
||||
|
||||
// Base64 validation
|
||||
string base64 = model.Attachment.Base64Data?.Split(',').LastOrDefault() ?? "";
|
||||
if (string.IsNullOrWhiteSpace(base64))
|
||||
{
|
||||
_logger.LogWarning("Base64 data missing for new attachment");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data missing", "File data required", 400));
|
||||
}
|
||||
|
||||
// Content type verification
|
||||
var s3Service = scope.ServiceProvider.GetRequiredService<S3UploadService>();
|
||||
var fileType = s3Service.GetContentTypeFromBase64(base64);
|
||||
var validContentTypes = documentType.AllowedContentType.Split(',').ToList();
|
||||
if (!validContentTypes.Contains(fileType))
|
||||
{
|
||||
_logger.LogWarning("Unsupported file type: {FileType}", fileType);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Unsupported file type", $"Unsupported file type: {fileType}", 400));
|
||||
}
|
||||
|
||||
// S3 keys and folder structure
|
||||
string folderName = entityType == EmployeeEntity ? "EmployeeDocuments" : "ProjectDocuments";
|
||||
string fileName = s3Service.GenerateFileName(fileType, tenantId, folderName);
|
||||
string objectKey = entityType == EmployeeEntity
|
||||
? $"tenant-{tenantId}/Employee/{oldAttachment.EntityId}/{folderName}/{fileName}"
|
||||
: $"tenant-{tenantId}/project-{oldAttachment.EntityId}/{folderName}/{fileName}";
|
||||
|
||||
// Asynchronous S3 upload with logging
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
||||
try
|
||||
{
|
||||
await s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||
logger.LogInfo("File uploaded successfully to S3: {ObjectKey}", objectKey);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "S3 upload failed for {ObjectKey}.", objectKey);
|
||||
}
|
||||
});
|
||||
|
||||
// Create Document record
|
||||
var document = new Document
|
||||
{
|
||||
BatchId = Guid.NewGuid(),
|
||||
UploadedById = loggedInEmployee.Id,
|
||||
FileName = model.Attachment.FileName ?? fileName,
|
||||
ContentType = model.Attachment.ContentType ?? fileType,
|
||||
S3Key = objectKey,
|
||||
FileSize = model.Attachment.FileSize,
|
||||
UploadedAt = DateTime.UtcNow,
|
||||
TenantId = tenantId
|
||||
};
|
||||
|
||||
dbContext.Documents.Add(document);
|
||||
|
||||
// Record new document attachment as the current version
|
||||
var attachment = new DocumentAttachment
|
||||
{
|
||||
Name = model.Name,
|
||||
DocumentId = model.DocumentId,
|
||||
Description = model.Description,
|
||||
IsCurrentVersion = true,
|
||||
EntityId = oldAttachment.EntityId,
|
||||
DocumentDataId = document.Id,
|
||||
UploadedAt = DateTime.UtcNow,
|
||||
UploadedById = loggedInEmployee.Id,
|
||||
DocumentTypeId = oldAttachment.DocumentTypeId,
|
||||
TenantId = oldAttachment.TenantId
|
||||
};
|
||||
|
||||
dbContext.DocumentAttachments.Add(attachment);
|
||||
|
||||
// Mark old version as not current
|
||||
oldAttachment.IsCurrentVersion = false;
|
||||
|
||||
// Version mapping
|
||||
AttachmentVersionMapping versionMapping;
|
||||
if (oldVersionMapping != null)
|
||||
{
|
||||
versionMapping = new AttachmentVersionMapping
|
||||
{
|
||||
ParentAttachmentId = oldVersionMapping.ParentAttachmentId,
|
||||
ChildAttachmentId = attachment.Id,
|
||||
Version = (oldVersionMapping.Version + 1),
|
||||
TenantId = tenantId
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
versionMapping = new AttachmentVersionMapping
|
||||
{
|
||||
ParentAttachmentId = attachment.Id,
|
||||
ChildAttachmentId = attachment.Id,
|
||||
Version = 1,
|
||||
TenantId = tenantId
|
||||
};
|
||||
}
|
||||
dbContext.AttachmentVersionMappings.Add(versionMapping);
|
||||
|
||||
newAttachment = attachment;
|
||||
newVersionMapping = versionMapping;
|
||||
_logger.LogInfo("Created new current version for AttachmentId: {AttachmentId}", attachment.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update attachment metadata only (no file upload)
|
||||
oldAttachment.Name = model.Name;
|
||||
oldAttachment.DocumentId = model.DocumentId;
|
||||
oldAttachment.Description = model.Description;
|
||||
if (oldAttachment.IsVerified == true)
|
||||
{
|
||||
oldAttachment.IsVerified = false;
|
||||
_logger.LogInfo("Reset verification flag for AttachmentId: {AttachmentId}", oldAttachment.Id);
|
||||
}
|
||||
oldAttachment.UpdatedAt = DateTime.UtcNow;
|
||||
oldAttachment.UpdatedById = loggedInEmployee.Id;
|
||||
|
||||
newAttachment = oldAttachment;
|
||||
newVersionMapping = oldVersionMapping ?? new AttachmentVersionMapping();
|
||||
_logger.LogInfo("Attachment metadata updated for AttachmentId: {AttachmentId}", oldAttachment.Id);
|
||||
}
|
||||
|
||||
// Tag management
|
||||
if (model.Tags?.Any() == true)
|
||||
{
|
||||
var names = model.Tags.Select(t => t.Name).ToList();
|
||||
var existingTags = await dbContext.DocumentTagMasters
|
||||
.Where(t => names.Contains(t.Name) && t.TenantId == tenantId)
|
||||
.ToListAsync();
|
||||
|
||||
var attachmentTagMappings = new List<AttachmentTagMapping>();
|
||||
var oldTagNames = await dbContext.AttachmentTagMappings
|
||||
.Include(dt => dt.DocumentTag)
|
||||
.Where(dt => dt.DocumentTag != null && dt.AttachmentId == newAttachment.Id && dt.TenantId == tenantId)
|
||||
.Select(dt => dt.DocumentTag!.Name)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var tag in model.Tags.Where(t => t.IsActive && !oldTagNames.Contains(t.Name)))
|
||||
{
|
||||
var existingTag = existingTags.FirstOrDefault(t => t.Name == tag.Name);
|
||||
var tagEntity = existingTag ?? new DocumentTagMaster
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = tag.Name,
|
||||
Description = tag.Name,
|
||||
TenantId = tenantId
|
||||
};
|
||||
|
||||
if (existingTag == null)
|
||||
{
|
||||
dbContext.DocumentTagMasters.Add(tagEntity);
|
||||
}
|
||||
|
||||
attachmentTagMappings.Add(new AttachmentTagMapping
|
||||
{
|
||||
DocumentTagId = tagEntity.Id,
|
||||
AttachmentId = newAttachment.Id,
|
||||
TenantId = tenantId
|
||||
});
|
||||
}
|
||||
|
||||
dbContext.AttachmentTagMappings.AddRange(attachmentTagMappings);
|
||||
_logger.LogInfo("Tags processed for AttachmentId: {AttachmentId}", newAttachment.Id);
|
||||
}
|
||||
|
||||
// Persist changes to database
|
||||
await dbContext.SaveChangesAsync();
|
||||
_logger.LogInfo("Database changes committed for AttachmentId: {AttachmentId}", newAttachment.Id);
|
||||
|
||||
// Update logs
|
||||
await updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
|
||||
{
|
||||
EntityId = oldAttachment.Id.ToString(),
|
||||
UpdatedById = loggedInEmployee.Id.ToString(),
|
||||
OldObject = existingEntityBson,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
}, Collection);
|
||||
_logger.LogInfo("Update logs pushed for AttachmentId: {AttachmentId}", oldAttachment.Id);
|
||||
|
||||
// Prepare response
|
||||
var response = _mapper.Map<DocumentListVM>(newAttachment);
|
||||
response.UploadedBy = _mapper.Map<BasicEmployeeVM>(loggedInEmployee);
|
||||
response.ParentAttachmentId = newVersionMapping.ParentAttachmentId;
|
||||
response.Version = newVersionMapping.Version;
|
||||
_logger.LogInfo("API completed successfully for AttachmentId: {AttachmentId}", newAttachment.Id);
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(response, "Document added successfully", 200));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception occurred while updating document for AttachmentId: {AttachmentId}", id);
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Exception occured", "Exception occured while the updating document", 500));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DELETE api/<DocumentController>/5
|
||||
[HttpDelete("{id}")]
|
||||
public async Task Delete(int id)
|
||||
@ -458,11 +756,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the filter string, handling multiple potential formats (e.g., direct JSON vs. escaped JSON string).
|
||||
/// </summary>
|
||||
/// <param name="filter">The JSON filter string from the request.</param>
|
||||
/// <returns>An <see cref="TenantFilter"/> object or null if deserialization fails.</returns>
|
||||
#region =================================================================== Helper Functions ===================================================================
|
||||
|
||||
private DocumentFilter? TryDeserializeFilter(string? filter)
|
||||
{
|
||||
@ -502,5 +796,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
}
|
||||
return documentFilter;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user