26ff8d9b4f
Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
449 lines
18 KiB
C#
Executable File
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
|
|
};
|
|
}
|
|
}
|
|
} |