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.
This commit is contained in:
+449
@@ -0,0 +1,449 @@
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user