using Azure; using CPRNIMS.Domain.Services; using CPRNIMS.Domain.UIContracts.Account; using CPRNIMS.Domain.UIContracts.Items; using CPRNIMS.Domain.UIServices.Updater; using CPRNIMS.Infrastructure.Dto.Items; using CPRNIMS.Infrastructure.Entities.Purchasing; using CPRNIMS.Infrastructure.Helper; using CPRNIMS.Infrastructure.ViewModel.Items; using CPRNIMS.Infrastructure.ViewModel.PO; using CPRNIMS.WebApps.Controllers.Base; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using System.Text.Json; namespace CPRNIMS.WebApps.Controllers.Items { public class ItemMgmtController : BaseMethod { private readonly IItem _item; List? response; ItemVM? postPutItem; private readonly IConfiguration _config; private readonly IHubContext _hubContext; public ItemMgmtController(ErrorLogHelper errorMessageService, IWebHostEnvironment webHostEnvironment, IConfiguration config, TokenHelper tokenHelper, IItem item, IHubContext hubContext,IAccount account) : base(errorMessageService, webHostEnvironment,tokenHelper, account) { _item = item; _config = config; _hubContext = hubContext; } #region PutPost public async Task PostPutItemCart(ItemVM viewModel) { try { var postPutItem = await _item.PostPutItemCart(GetUser(), viewModel); int count = await UpdateCart(viewModel); await _hubContext.Clients.User(viewModel.UserId).SendAsync("ReceiveCartUpdate", count); if (postPutItem.messCode != 0) { return Json(new { success = true, cartCount = count }); } return Json(new { success = false, Response = postPutItem.message }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } public async Task UpdateCart(ItemVM viewModel) { viewModel.IsCount = true; int count=0; var itemCartResp = await _item.GetItemCart(GetUser(), viewModel); if (itemCartResp.Count <= 0) { ViewBag.CartItemCount = 0; } else { ViewBag.CartItemCount = itemCartResp[0].CartItemCount; count = itemCartResp[0].CartItemCount; } return count; } public async Task PutItemDetail(ItemVM viewModel) { try { string base64Image; if (viewModel.ItemAttachPath==null) { var defaultImagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Content", "Common", "empty.jpg"); byte[] imageBytes = await System.IO.File.ReadAllBytesAsync(defaultImagePath); string imageBase64 = Convert.ToBase64String(imageBytes); base64Image = $"data:image/jpeg;base64,{imageBase64}"; } else { base64Image = viewModel.ItemAttachPath; } var (uploadResult,isSuccess) = await UploadBase64Image(base64Image); if (isSuccess) { viewModel.ItemAttachPath = uploadResult; postPutItem = await _item.PutItemDetail(GetUser(), viewModel); if (postPutItem.messCode != 0) { return Json(new { success = true, data = postPutItem }); } } return Json(new { success = false, response = uploadResult ?? postPutItem.statusResponse }); } catch (Exception ex) { return Json(new { success = false, response = "An error occurred.", details = ex.Message }); } } public async Task PostPutItem(ItemVM viewModel) { try { var postPutItem = await _item.PostPutItem(GetUser(), viewModel); if (postPutItem.messCode != 0) { return Json(new { success = true, data = postPutItem, itemCodeId = postPutItem.ItemCodeId }); } return Json(new { success = false, response = postPutItem.message }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } private async Task SaveAttachmentAsync(IFormFile? file, string? oldFileName) { var uploadsPath = Path.Combine( _webHostEnvironment.WebRootPath, "Content", "Uploads", "PRAttachment"); Directory.CreateDirectory(uploadsPath); // If no new file uploaded, return old filename if (file == null) return oldFileName; // Delete old file if exists if (!string.IsNullOrWhiteSpace(oldFileName)) { await DeleteAttachmentAsync(oldFileName); } // Validate file extension var allowedExtensions = new[] { ".csv", ".xlsx", ".xls", ".pdf" }; var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant(); if (!allowedExtensions.Contains(fileExtension)) { throw new InvalidOperationException("Invalid file type. Only CSV, Excel, and PDF files are allowed."); } // Validate file size (5MB max) if (file.Length > 5 * 1024 * 1024) { throw new InvalidOperationException("File size exceeds 5MB limit."); } // Generate new unique filename with original extension var newFileName = $"{Guid.NewGuid()}{fileExtension}"; var newFilePath = Path.Combine(uploadsPath, newFileName); // Save new file await using var stream = new FileStream(newFilePath, FileMode.Create); await file.CopyToAsync(stream); // Return only filename (NOT full path) return newFileName; } private async Task DeleteAttachmentAsync(string fileName) { if (string.IsNullOrWhiteSpace(fileName)) return; var uploadsPath = Path.Combine( _webHostEnvironment.WebRootPath, "Content", "Uploads", "PRAttachment"); var filePath = Path.Combine(uploadsPath, fileName); if (System.IO.File.Exists(filePath)) { await Task.Run(() => System.IO.File.Delete(filePath)); } } [HttpPost] public async Task PostPurchRequest([FromForm] string ItemCartIds, [FromForm] DateTime DateNeeded, [FromForm] byte RequestTypeId, [FromForm] int ChargeTo, [FromForm] string? Remarks, [FromForm] int ProjectCodeId, IFormFile? file) { try { // Deserialize the ItemCartIds JSON string var itemCartList = JsonSerializer.Deserialize>(ItemCartIds); if (itemCartList == null || !itemCartList.Any()) { return Json(new { success = false, response = "No items selected" }); } var viewModel = new ItemVM { DateNeeded = DateNeeded, RequestTypeId = RequestTypeId, ChargeTo = ChargeTo, Remarks = Remarks, ProjectCodeId = ProjectCodeId, ItemCartVM = new ItemCartVM { ItemCartId = itemCartList.Select(ic => ic.ItemCartId).ToList(), Qty = itemCartList.Select(ic => ic.Qty).ToList(), ItemNo = itemCartList.Select(ic => ic.ItemNo).ToList() } }; if(file?.FileName != null) { string? savedFileName = await SaveAttachmentAsync(file, null); viewModel.FileName = savedFileName; viewModel.OrigFileName = file.FileName ?? "N/A"; // Delete uploaded file if request failed if (!string.IsNullOrWhiteSpace(savedFileName)) { await DeleteAttachmentAsync(savedFileName); } } var postPutItem = await _item.PostPurchRequest(GetUser(), viewModel); if (postPutItem.messCode != 0) { return Json(new { success = true, message = "Purchase request created successfully" }); } return Json(new { success = false, response = postPutItem.message }); } catch (Exception ex) { var message = ex.InnerException?.Message ?? ex.Message; return Json(new { success = false, response = "An error occurred while processing your request" }); } } #endregion #region Get public async Task GetProjectCodeByTerm(string query) { var item = new ItemVM(); item.FileName = query; var responseQuery = await _item.GetProjectCodeByTerm(GetUser(), item); if (responseQuery == null) { responseQuery = new List(); } var formattedData = responseQuery.Select(item => new { label = $"{item.ProjectCode} {item.ProjectName}", value = item.ProjectCodeId, }); return Json(new { success = true, data = formattedData }); } public async Task GetImageFileIds() { try { var fileIds = new List(); var googleDriveService = new GoogleDriveService("secret"); fileIds.Add(await googleDriveService.GetFileIdByNameAsync("1.jpg")); fileIds.Add(await googleDriveService.GetFileIdByNameAsync("2.jpg")); fileIds.Add(await googleDriveService.GetFileIdByNameAsync("3.jpg")); return Json(fileIds); } catch (Exception ex) { // Handle exception return BadRequest(ex.Message); } } public IActionResult GetImage(string url) { return Redirect(url); } public async Task GetItemDetail(ItemVM viewModels) { try { response = await _item.GetItemDetail(GetUser(), viewModels); response[0].URL = _config["CommonEndpoints:ApiDefaultHeaders:ItemImages"]; return GetResponse(response); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } public async Task GetItemCart(ItemVM viewModels) { try { response = await _item.GetItemCart(GetUser(), viewModels); return GetResponse(response); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } [HttpGet] public async Task GetItemList(string searchItemNo = "", string searchItemName = "", string searchCategory = "", string searchStatusName = "", int pageNumber = 1, int pageSize = 10) { var viewModel = new ItemVM { SearchItemName = searchItemName, SearchItemNo = searchItemNo, SearchCategory= searchCategory, PageNumber = pageNumber, PageSize = pageSize }; var result = await _item.GetItemList(GetUser(), viewModel); return Json(new { draw = Request.Query["draw"].ToString(), recordsTotal = result.TotalCount, recordsFiltered = result.TotalCount, data = result.Data, categoryList = result.CategoryList }); } public async Task GetItemCateg(ItemVM viewModels) { try { var responseQuery = await _item.GetItemCateg(GetUser(), viewModels); if (responseQuery == null) { responseQuery = new List(); } return Json(new { success = true, data = responseQuery }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } public async Task GetItemColor(string query) { try { var viewModels = new ItemVM(); viewModels.ItemColorName = query; var responseQuery = await _item.GetItemColor(GetUser(), viewModels); if (responseQuery == null) { responseQuery = new List(); } // Convert the data to the format expected by jQuery UI Autocomplete var formattedData = responseQuery.Select(item => new { label = item.ItemColorName, value = item.ItemColorId, }); return Json(new { success = true, data = formattedData }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } public async Task GetItemLocalization(string query) { try { var viewModels = new ItemVM(); viewModels.ItemLocalName = query; var responseQuery = await _item.GetItemLocalization(GetUser(), viewModels); if (responseQuery == null) { responseQuery = new List(); } // Convert the data to the format expected by jQuery UI Autocomplete var formattedData = responseQuery.Select(item => new { label = item.ItemLocalName, value = item.ItemLocalId, }); return Json(new { success = true, data = formattedData }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } public async Task GetItemUOM(string query) { try { var viewModels = new ItemVM(); viewModels.UOMName = query; var responseQuery = await _item.GetItemUOM(GetUser(), viewModels); if (responseQuery == null) { responseQuery = new List(); } var formattedData = responseQuery.Select(item => new { label = item.UOMName, value = item.UOMId, }); return Json(new { success = true, data = formattedData }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } public async Task GetDepartment() { try { var viewModels = new ItemVM(); var responseQuery = await _item.GetDepartment(GetUser(), viewModels); if (responseQuery == null) { responseQuery = new List(); } return Json(new { success = true, data = responseQuery }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); throw; } } #endregion #region Views public async Task Index() { var viewModels = new ItemVM(); await UpdateCart(viewModels); return await IsAuthenTicated(); } public async Task ItemCart(byte TypeOfRequest) { ViewBag.TypeOfRequest = TypeOfRequest; return await IsAuthenTicated(); } #endregion #region Common public async Task<(string,bool)> UploadBase64Image(string base64Image) { try { // Extract image format from base64 string var base64Data = base64Image.Substring(base64Image.IndexOf(',') + 1); var imageFormat = base64Image.Substring(base64Image.IndexOf('/') + 1, base64Image.IndexOf(';') - base64Image.IndexOf('/') - 1); // Check image format if (imageFormat.ToLowerInvariant() != "jpeg" && imageFormat.ToLowerInvariant() != "jpg" && imageFormat.ToLowerInvariant() != "png") { return ("Only JPG and PNG images are allowed.", false); } // Decode base64 string to byte array byte[] imageBytes; try { imageBytes = Convert.FromBase64String(base64Data); } catch (FormatException) { return ("Invalid Base64 data.", false); } // Check byte array size (8MB limit) const int maxFileSizeInBytes = 8 * 1024 * 1024; // 8 MB if (imageBytes.Length > maxFileSizeInBytes) { return ("Exceed 8MB.",false); } // Save the decoded byte array to the shared folder var serverPath = _config["LLI:NonInvent:ImageUploadSettings:UploadPath"]; var fileName = Guid.NewGuid().ToString() + "." + imageFormat; var filePath = Path.Combine(serverPath, fileName); await System.IO.File.WriteAllBytesAsync(filePath, imageBytes); return (fileName,true); } catch (Exception ex) { // Handle exception Console.WriteLine(ex.ToString()); throw; } } public async Task UploadMultipleFile(List files,long itemNo) { try { foreach (var file in files) { // Check file size if (file.Length > 2 * 1024 * 1024) // 2MB limit { return Json(new { success = false, Response = "File size should not exceed 2MB." }); } // Check file extension var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant(); if (fileExtension != ".jpg" && fileExtension != ".png") { return Json(new { success = false, Response = "Only JPG and PNG files are allowed." }); } // Save the uploaded file to the shared folder var serverPath = "\\\\172.16.16.215\\NonInventory"; // Shared folder path var fileName = Guid.NewGuid().ToString() + fileExtension; // Generate unique file name var filePath = Path.Combine(serverPath, fileName); // Combine path and file name using (var stream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(stream); } return Json(new { success = true }); } return Json(new { success = true }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); return Json(new { success = false, Response ="There is something wrong, please ask administrator!" }); } } #endregion } }