Files
Core_Be/Services/DocumentService.cs
T
Dhananjaya99 bffc9b1686 first commit
2026-09-28 11:44:26 +05:30

264 lines
11 KiB
C#

using Fitness_core_BE.Interfaces;
using Fitness_core_BE.Interfaces.Services;
using Fitness_core_BE.Models;
using Fitness_core_BE.Infra.UoW;
using System.Text.Json;
using Fitness_core_BE.Helpers;
using Fitness_core_BE.Exceptions;
using Fitness_core_BE.DTOs;
namespace Fitness_core_BE.Services.Document
{
public class DocumentService : IDocumentService
{
private readonly IDocumentRepository _docRepository;
private readonly IUnitOfWork _uow;
public DocumentService(IDocumentRepository docRepository, IUnitOfWork uow)
{
_docRepository = docRepository;
_uow = uow;
}
public async Task<object> UploadDocument(object payload, HttpContext httpContext)
{
await _uow.BeginAsync();
try
{
Guid userId = DataExtractor.GetUserIdFromContext(httpContext);
var data = DeserializePayload.Deserialize(payload);
var files = data["document"].EnumerateArray();
bool isTicketDoc = data.TryGetValue("IsTicketDoc", out JsonElement isTicketDocElement) && isTicketDocElement.GetBoolean();
var uploadResults = new List<object>();
Guid? ticketId = null;
if (isTicketDoc && data.TryGetValue("TicketId", out JsonElement ticketIdElement))
{
ticketId = ticketIdElement.GetGuid();
}
string uploadsRoot = "./desktop";
if (isTicketDoc && ticketId.HasValue)
{
// uploadsRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "Uploads", userId.ToString(), ticketId.ToString()));
uploadsRoot = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "Uploads", userId.ToString(), ticketId.Value.ToString()));
}
else
{
// uploadsRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "Uploads", userId.ToString()));
uploadsRoot = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "Uploads", userId.ToString()));
}
if (!Directory.Exists(uploadsRoot))
{
Directory.CreateDirectory(uploadsRoot);
}
foreach (var file in files)
{
string lastnum = await _docRepository.GetLastSequnce();
string originalFileName = file.GetProperty("FileName").GetString() ?? "document";
string extension = Path.GetExtension(originalFileName).ToLowerInvariant();
string[] allowedExtensions = { ".pdf", ".jpg", ".jpeg", ".png", ".docx", ".mp4", ".mov", ".avi", ".mkv", ".webm", ".3gp" };
if (!allowedExtensions.Contains(extension))
throw new BadRequestException("File type not allowed.");
string safeTimestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string filename = $"{lastnum}_{userId}_{safeTimestamp}{extension}";
string baseFile = file.GetProperty("Base64").GetString();
if (baseFile.Contains(","))
baseFile = baseFile.Substring(baseFile.IndexOf(",") + 1);
byte[] fileBytes = Convert.FromBase64String(baseFile);
if (fileBytes.Length > 10 * 1024 * 1024)
throw new BadRequestException("File too large.");
string filePath = Path.Combine(uploadsRoot, filename);
await File.WriteAllBytesAsync(filePath, fileBytes);
// Extract FileType from the file element
var fileData = new Dictionary<string, JsonElement> { { "FileType", file.GetProperty("FileType") } };
int docTypeId = DataExtractor.GetRequiredInt(fileData, "FileType");
UserDocument documentMeta = new UserDocument { };
if (isTicketDoc && ticketId.HasValue)
{
documentMeta = new UserDocument
{
UserId = userId,
DocumentName = originalFileName,
DocumentUrl = $"/Uploads/{userId}/{ticketId.Value}/{Uri.EscapeDataString(filename)}",
FkDocumentTypeId = docTypeId,
};
}
else
{
documentMeta = new UserDocument
{
UserId = userId,
DocumentName = originalFileName,
DocumentUrl = $"/Uploads/{userId}/{Uri.EscapeDataString(filename)}",
FkDocumentTypeId = docTypeId,
};
}
var savedDocument = await _docRepository.UploadDocumentAsync(documentMeta);
await _uow.SaveChangesAsync();
uploadResults.Add(new
{
savedDocument.DocumentId,
savedDocument.DocumentName,
DocumentURL = savedDocument.DocumentUrl
});
}
await _uow.CommitAsync();
return new { Message = "Documents uploaded successfully.", uploadResults };
}
catch
{
await _uow.RollbackAsync();
throw;
}
}
public async Task<object> GetDocumentsByUserId(object payload, HttpContext httpContext)
{
// TODO: Uncomment for production - Currently using static userId for testing
// if (!Guid.TryParse(httpContext.User.FindFirst("UserId")?.Value, out Guid userId))
// {
// throw new InvalidOperationException("Invalid UserId in token.");
// }
Guid userId = Guid.Parse("5b664468-9ba5-4e6e-b73a-97c9a791c9a0");
List<UserDocument> docResults = await _docRepository.GetDocumentsByUserId(userId);
if (docResults == null || docResults.Count == 0)
return new List<object>();
string uploadsRoot = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), ".."));
var documents = new List<object>();
foreach (var doc in docResults)
{
if (string.IsNullOrEmpty(doc.DocumentUrl))
continue;
string relativePath = doc.DocumentUrl.Replace("/", Path.DirectorySeparatorChar.ToString());
Console.WriteLine("Relative Path: " + relativePath);
string filePath = uploadsRoot + relativePath;
Console.WriteLine("File Path: " + filePath);
if (!File.Exists(filePath))
continue; // Skip missing files safely
byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
documents.Add(new
{
FileName = doc.DocumentName,
FileType = Path.GetExtension(doc.DocumentName),
doc.DocumentUrl,
doc.DocumentType.DocumentType,
Data = Convert.ToBase64String(fileBytes)
});
}
return documents;
}
public async Task<object> GetDocumentById(object payload, HttpContext httpContext)
{
var data = DeserializePayload.Deserialize(payload);
var documentId = DataExtractor.GetRequiredInt(data, "documentId");
var document = await _docRepository.GetDocumentById(documentId);
if (document != null && !string.IsNullOrEmpty(document.DocumentUrl))
{
string uploadsRoot = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), ".."));
Console.WriteLine("Uploads Root: " + uploadsRoot);
string relativePath = document.DocumentUrl.Replace("/", Path.DirectorySeparatorChar.ToString());
Console.WriteLine("Relative Path: " + relativePath);
string filePath = uploadsRoot + relativePath;
Console.WriteLine("File Path: " + filePath);
if (!File.Exists(filePath))
throw new FileNotFoundException("Document file not found.");
byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
return new
{
FileName = document.DocumentName,
FileType = Path.GetExtension(document.DocumentName),
document.DocumentUrl,
document.DocumentType.DocumentType,
Data = Convert.ToBase64String(fileBytes)
};
}
throw new InvalidOperationException("Document not found or invalid document data.");
}
public async Task<object> RemoveDocument(object payload, HttpContext httpContext)
{
await _uow.BeginAsync();
try
{
var data = DeserializePayload.Deserialize(payload);
var documentId = DataExtractor.GetRequiredInt(data, "documentId");
var result = await _docRepository.RemoveDocument(documentId);
if (!result)
{
throw new NotFoundException("Document not found");
}
await _uow.CommitAsync();
return new { success = true, message = "Document removed successfully" };
}
catch
{
await _uow.RollbackAsync();
throw;
}
}
public async Task<DocumentDownloadModel> GetFileBytesById(int documentId)
{
var document = await _docRepository.GetDocumentById(documentId);
if (document == null || string.IsNullOrEmpty(document.DocumentUrl))
throw new NotFoundException("Document record not found.");
string uploadsRoot = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), ".."));
string relativePath = document.DocumentUrl.Replace("/", Path.DirectorySeparatorChar.ToString());
string filePath = uploadsRoot + relativePath;
if (!File.Exists(filePath))
throw new FileNotFoundException("Physical file is missing on the server.");
byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
return new DocumentDownloadModel
{
FileName = document.DocumentName,
FileType = Path.GetExtension(document.DocumentName),
FileData = fileBytes
};
}
}
}