Files
Joseph Doherty 26ff8d9b4f Initial commit: JDE Scoping Tool migration project
Set up repository with legacy .NET Framework 4.8 source (OLD/),
new .NET 10 Blazor solution (NEW/), OpenSpec specifications,
documentation, and project configuration.
2026-01-02 07:43:29 -05:00

449 lines
18 KiB
C#
Executable File

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Caching;
using System.Web;
using System.Web.Mvc;
using DataModel.Helpers;
using DataModel.Process;
using DataModel.ViewModels;
using OfficeOpenXml;
using WebInterface.Helpers;
using WebInterface.Models;
namespace WebInterface.Controllers
{
/// <summary>
/// Excel file I/O controller
/// </summary>
public class FileIOController : Controller
{
/// <summary>
/// Default content type for spreadsheet
/// </summary>
private const string CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
// POST: FileIO/UploadWorkOrders
[HttpPost]
public JsonNetResult UploadWorkOrders()
{
FileUploadResult<WorkOrderViewModel> result = new FileUploadResult<WorkOrderViewModel>();
try
{
if (Request.Files.Count == 0)
{
throw new Exception("no file uploaded");
}
try
{
HttpPostedFileBase postedFile = Request.Files["lotNumberUpload"];
using (var package = new ExcelPackage(postedFile.InputStream))
{
//Get first worksheet
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
//Extract data
List<long> workOrderNumbers = new List<long>();
for (int row = 2; row <= worksheet.Dimension.End.Row; row++)
{
try
{
long workOrderNumber = long.Parse(Convert.ToString(worksheet.Cells[row, 1].Value).Trim());
workOrderNumbers.Add(workOrderNumber);
}
catch
{
//Do nothing
}
}
//Lookup work order data
result.Data.AddRange(LotFinderDB.LookupWorkorders(workOrderNumbers)
.Select(wo => wo.ToViewModel())
.DistinctBy(wo => new { wo.WorkOrderNumber, wo.ItemNumber })
.OrderBy(wo => wo.WorkOrderNumber));
//Update success flag
result.WasSuccessful = true;
}
}
catch (Exception error)
{
//Forward error with custom message
throw new Exception("failed to parse uploaded file", error);
}
}
catch (Exception error)
{
//Update result
result.WasSuccessful = false;
result.ErrorMessage = error.Message;
}
JsonNetResult jsonResult = new JsonNetResult
{
Data = result,
ContentType = HttpContext.Request.AcceptTypes.Contains("application/json") ? "application/json" : "text/plain"
};
return jsonResult;
}
// POST: FileIO/DownloadWorkOrders
[HttpPost]
public ActionResult DownloadWorkOrders(List<long> workOrders)
{
//Generate spreadsheet template
byte[] data = ExcelTemplateGenerator.Generate(workOrders, "Work Order Number");
//Cache result
string key = Guid.NewGuid().ToString().ToUpper().Replace("-", "");
ObjectCache cache = MemoryCache.Default;
cache.Add(key, data, new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1) });
return new JsonNetResult()
{
Data = key
};
}
// GET: FileIO/DownloadWorkOrders?key
public ActionResult DownloadWorkOrders(string key)
{
return DownloadFile(key, "work_order_template.xlsx");
}
// POST: FileIO/UploadPartNumbers
[HttpPost]
public JsonNetResult UploadPartNumbers()
{
FileUploadResult<ItemViewModel> result = new FileUploadResult<ItemViewModel>();
try
{
if (Request.Files.Count == 0)
{
throw new Exception("no file uploaded");
}
try
{
HttpPostedFileBase postedFile = Request.Files["partNumberUpload"];
using (var package = new ExcelPackage(postedFile.InputStream))
{
//Get first worksheet
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
//Extract data
List<string> itemNumbers = new List<string>();
for (int row = 2; row <= worksheet.Dimension.End.Row; row++)
{
try
{
string itemNumber = Convert.ToString(worksheet.Cells[row, 1].Value).Trim();
itemNumbers.Add(itemNumber);
}
catch
{
//Do nothing
}
}
//Lookup work order data
result.Data.AddRange(LotFinderDB.LookupItems(itemNumbers)
.Select(i => i.ToViewModel())
.DistinctBy(i => new { i.ItemNumber, i.Description }));
//Update success flag
result.WasSuccessful = true;
}
}
catch (Exception error)
{
//Forward error with custom message
throw new Exception("failed to parse uploaded file", error);
}
}
catch (Exception error)
{
//Update result
result.WasSuccessful = false;
result.ErrorMessage = error.Message;
}
JsonNetResult jsonResult = new JsonNetResult
{
Data = result,
ContentType = HttpContext.Request.AcceptTypes.Contains("application/json") ? "application/json" : "text/plain"
};
return jsonResult;
}
// POST: FileIO/DownloadPartNumbers
[HttpPost]
public ActionResult DownloadPartNumbers(List<ItemViewModel> items)
{
if (items == null)
{
items = new List<ItemViewModel>();
}
//Generate spreadsheet template
object[][] sourceData = items.Select(po => new object[] { po.ItemNumber }).ToArray();
string[] headerText = { "Item Number" };
byte[] data = ExcelTemplateGenerator.Generate(sourceData, headerText);
//Cache result
string key = Guid.NewGuid().ToString().ToUpper().Replace("-", "");
ObjectCache cache = MemoryCache.Default;
cache.Add(key, data, new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1) });
return new JsonNetResult()
{
Data = key
};
}
// GET: FileIO/DownloadPartNumbers?key
public ActionResult DownloadPartNumbers(string key)
{
return DownloadFile(key, "item_number_template.xlsx");
}
// POST: FileIO/UploadComponentLots
[HttpPost]
public JsonNetResult UploadComponentLots()
{
FileUploadResult<LotViewModel> result = new FileUploadResult<LotViewModel>();
try
{
if (Request.Files.Count == 0)
{
throw new Exception("no file uploaded");
}
try
{
HttpPostedFileBase postedFile = Request.Files["componentLotNumberUpload"];
using (var package = new ExcelPackage(postedFile.InputStream))
{
//Get first worksheet
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
//Extract data
List<LotViewModel> componentLotNumbers = new List<LotViewModel>();
for (int row = 2; row <= worksheet.Dimension.End.Row; row++)
{
string lotNumber = Convert.ToString(worksheet.Cells[row, 1].Value).Trim();
string itemNumber = Convert.ToString(worksheet.Cells[row, 2].Value).Trim();
if (!string.IsNullOrEmpty(lotNumber))
{
componentLotNumbers.Add(new LotViewModel() { LotNumber = lotNumber, ItemNumber = itemNumber });
}
}
//Lookup work order data
result.Data.AddRange(LotFinderDB.LookupLots(componentLotNumbers)
.Select(l => l.ToViewModel())
.DistinctBy(l => new { l.LotNumber, l.ItemNumber })
.OrderBy(l => l.LotNumber));
//Update success flag
result.WasSuccessful = true;
}
}
catch (Exception error)
{
//Forward error with custom message
throw new Exception("failed to parse uploaded file", error);
}
}
catch (Exception error)
{
//Update result
result.WasSuccessful = false;
result.ErrorMessage = error.Message;
}
JsonNetResult jsonResult = new JsonNetResult
{
Data = result,
ContentType = HttpContext.Request.AcceptTypes.Contains("application/json") ? "application/json" : "text/plain"
};
return jsonResult;
}
// POST: FileIO/DownloadComponentLots
[HttpPost]
public ActionResult DownloadComponentLots(List<LotViewModel> lotNumbers)
{
if (lotNumbers == null)
{
lotNumbers = new List<LotViewModel>();
}
//Generate spreadsheet template
object[][] sourceData = lotNumbers.Select(po => new object[] { po.LotNumber, po.ItemNumber }).ToArray();
string[] headerText = { "Component Lot Number", "Component Item Number" };
byte[] data = ExcelTemplateGenerator.Generate(sourceData, headerText);
//Cache result
string key = Guid.NewGuid().ToString().ToUpper().Replace("-", "");
ObjectCache cache = MemoryCache.Default;
cache.Add(key, data, new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1) });
return new JsonNetResult()
{
Data = key
};
}
// GET: FileIO/DownloadComponentLots?key
public ActionResult DownloadComponentLots(string key)
{
return DownloadFile(key, "component_lot_template.xlsx");
}
// POST: FileIO/UploadPartOperations
[HttpPost]
public JsonNetResult UploadPartOperations()
{
FileUploadResult<PartOperationViewModel> result = new FileUploadResult<PartOperationViewModel>();
try
{
if (Request.Files.Count == 0)
{
throw new Exception("no file uploaded");
}
try
{
HttpPostedFileBase postedFile = Request.Files["partOperationUpload"];
using (var package = new ExcelPackage(postedFile.InputStream))
{
//Get first worksheet
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
//Extract data
List<PartOperationViewModel> partOperations = new List<PartOperationViewModel>();
for (int row = 2; row <= worksheet.Dimension.End.Row; row++)
{
try
{
string itemNumber = Convert.ToString(worksheet.Cells[row, 1].Value).Trim();
string operationNumber = Convert.ToString(worksheet.Cells[row, 2].Value).Trim();
string misNumber = Convert.ToString(worksheet.Cells[row, 3].Value).Trim();
string misRevision = Convert.ToString(worksheet.Cells[row, 4].Value).Trim();
if (!string.IsNullOrEmpty(operationNumber) && operationNumber.Contains("."))
{
//Remove decimal places
operationNumber = operationNumber.Substring(0, operationNumber.IndexOf("."));
}
if (!string.IsNullOrEmpty(itemNumber) && !string.IsNullOrEmpty(operationNumber))
{
partOperations.Add(new PartOperationViewModel()
{
ItemNumber = itemNumber,
OperationNumber = operationNumber,
MisNumber = misNumber,
MisRevision = misRevision
});
}
}
catch (Exception)
{
//Do nothing
}
}
//Lookup work order data
result.Data.AddRange(partOperations);
//Update success flag
result.WasSuccessful = true;
}
}
catch (Exception error)
{
//Forward error with custom message
throw new Exception("failed to parse uploaded file", error);
}
}
catch (Exception error)
{
//Update result
result.WasSuccessful = false;
result.ErrorMessage = error.Message;
}
JsonNetResult jsonResult = new JsonNetResult
{
Data = result,
ContentType = HttpContext.Request.AcceptTypes.Contains("application/json") ? "application/json" : "text/plain"
};
return jsonResult;
}
// POST: FileIO/DownloadPartOperations
[HttpPost]
public ActionResult DownloadPartOperations(List<PartOperationViewModel> partOperations)
{
if (partOperations == null)
{
partOperations = new List<PartOperationViewModel>();
}
//Generate spreadsheet template
object[][] sourceData = partOperations.Select(po => new object[] { po.ItemNumber, po.OperationNumber, po.MisNumber, po.MisRevision }).ToArray();
string[] headerText = { "Item Number", "Operation Number", "MIS Number", "MIS Revision" };
byte[] data = ExcelTemplateGenerator.Generate(sourceData, headerText);
//Cache result
string key = Guid.NewGuid().ToString().ToUpper().Replace("-", "");
ObjectCache cache = MemoryCache.Default;
cache.Add(key, data, new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1) });
return new JsonNetResult()
{
Data = key
};
}
// GET: FileIO/DownloadPartOperations?key
public ActionResult DownloadPartOperations(string key)
{
return DownloadFile(key, "item_operations_mis_template.xlsx");
}
// GET: FileIO/DownloadFile?key&fileName
private ActionResult DownloadFile(string key, string fileName)
{
//Try to find data in cache
ObjectCache cache = MemoryCache.Default;
byte[] cachedData = cache.Get(key) as byte[];
if (cachedData == null)
{
return HttpNotFound("cached file not found");
}
//Clear data from cache
cache.Remove(key);
return new FileStreamResult(new MemoryStream(cachedData), CONTENT_TYPE)
{
FileDownloadName = fileName
};
}
}
}