Moved API and DB methods to interfaces in order to leverage Dependency Injection, disolved APICaller class, including functionality in several other functions, included Single Load Lock information into Production Passdown report, changed persistant data file to json instead of xml, and adjusted persistant data file to include a week's worth of data instead of a single day.

This commit is contained in:
Daniel Wathen 2022-12-02 14:41:19 -07:00
parent e9c071c8f7
commit 740896adf0
31 changed files with 857 additions and 549 deletions

View File

@ -6,55 +6,39 @@ namespace ReportingServices.Test
public class UnitTest1
{
[TestMethod]
public void CheckAPIIsNotNull()
public void CheckShortDateWithPassedInDate()
{
// Arrange
APICaller apiCaller = new APICaller();
string date = DateTime.Now.ToString("yyyy-M-d") + " 0:0:0";
// Act
apiCaller.CallAllAPIs();
string callerDate = APIHelperFunctions.GetDateTimeAsAPIString(DateTime.Now.ToString(), false);
// Assert
Assert.IsNotNull(apiCaller);
Assert.AreEqual(date, callerDate);
}
[TestMethod]
public void CheckFullDateWithPassedInDate()
{
// Arrange
string date = DateTime.Now.ToString("yyyy-M-d HH:mm:ss");
// Act
string callerDate = APIHelperFunctions.GetDateTimeAsAPIString(DateTime.Now.ToString(), true);
// Assert
Assert.AreEqual(date, callerDate);
}
[TestMethod]
public void CheckStartDateForWeekNow()
{
// Arrange
APICaller apiCaller = new APICaller();
string date = DetermineDate();
// Act
string callerDate = apiCaller.DetermineStartDate();
// Assert
Assert.AreEqual(date, callerDate);
}
[TestMethod]
public void CheckStartDateForWeekWednesday()
{
// Arrange
APICaller apiCaller = new APICaller();
string date = "2022-11-21%200%3A0%3A0";
// Act
string callerDate = apiCaller.DetermineStartDate("11/23/2022");
// Assert
Assert.AreEqual(date, callerDate);
}
[TestMethod]
public void CheckStartDateForWeekMonday()
{
// Arrange
APICaller apiCaller = new APICaller();
string date = "2022-11-14%200%3A0%3A0";
// Act
string callerDate = apiCaller.DetermineStartDate("11/21/2022");
string callerDate = APIHelperFunctions.GetBeginningOfWeekAsAPIString();
// Assert
Assert.AreEqual(date, callerDate);
@ -64,11 +48,10 @@ namespace ReportingServices.Test
public void CheckStartDateForDayPassedInAndHoursAdded()
{
// Arrange
APICaller apiCaller = new APICaller();
string date = "2022-11-23%200%3A0%3A0";
string date = "2022-11-23 0:0:0";
// Act
string callerDate = apiCaller.DetermineStartDate("11/23/2022 12:30 PM", 12.5f);
string callerDate = APIHelperFunctions.GetDateWithOffsetAsAPIString("11/23/2022 12:30 PM", -12.5f);
// Assert
Assert.AreEqual(date, callerDate);
@ -79,27 +62,27 @@ namespace ReportingServices.Test
DateTime date = DateTime.Now;
if (date.DayOfWeek == DayOfWeek.Monday)
return date.Year + "-" + date.Month + "-" + (date.Day - 7) + "%200%3A0%3A0";
date = date.AddDays(-7);
if (date.DayOfWeek == DayOfWeek.Tuesday)
return date.Year + "-" + date.Month + "-" + (date.Day - 1) + "%200%3A0%3A0";
date = date.AddDays(-1);
if (date.DayOfWeek == DayOfWeek.Wednesday)
return date.Year + "-" + date.Month + "-" + (date.Day - 2) + "%200%3A0%3A0";
date = date.AddDays(-2);
if (date.DayOfWeek == DayOfWeek.Thursday)
return date.Year + "-" + date.Month + "-" + (date.Day - 3) + "%200%3A0%3A0";
date = date.AddDays(-3);
if (date.DayOfWeek == DayOfWeek.Friday)
return date.Year + "-" + date.Month + "-" + (date.Day - 4) + "%200%3A0%3A0";
date = date.AddDays(-4);
if (date.DayOfWeek == DayOfWeek.Saturday)
return date.Year + "-" + date.Month + "-" + (date.Day - 5) + "%200%3A0%3A0";
date = date.AddDays(-5);
if (date.DayOfWeek == DayOfWeek.Sunday)
return date.Year + "-" + date.Month + "-" + (date.Day - 6) + "%200%3A0%3A0";
date = date.AddDays(-6);
return "";
return date.Year + "-" + date.Month + "-" + date.Day + " 0:0:0"; ;
}
}
}

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using ReportingServices.Dependency_Injections;
using ReportingServices.HelperClasses;
using ReportingServices.Models.PlanningReport;
@ -6,19 +7,25 @@ namespace ReportingServices.Controllers
{
public class PlanningReportController : Controller
{
private readonly IScrapeDatabaseRepository _scrapeDatabaseRepository;
public PlanningReportController(IScrapeDatabaseRepository scrapeDatabaseRepository)
{
_scrapeDatabaseRepository = scrapeDatabaseRepository;
}
public IActionResult Index()
{
return View();
}
public IActionResult WeeklyPartChangesReport(DateTime StartDate, DateTime EndDate)
public IActionResult WeeklyPartChangesReport(DateTime startDate, DateTime endDate)
{
DBCaller caller = new();
int numberOfPartChanges = _scrapeDatabaseRepository.GetNumberOfPartChanges(startDate.ToString(), endDate.ToString());
List<ReactorPSNWORuns> reactorPSNWORuns = _scrapeDatabaseRepository.GetReactorPSNWORuns(startDate.ToString(), endDate.ToString());
List<WeeklyPartChanges> weeklyPartChanges = caller.GetWeeklyPartChanges(StartDate.ToString(), EndDate.ToString());
ViewBag.NumberOfPartChanges = caller.GetNumberOfPartChanges(StartDate.ToString(), EndDate.ToString());
ViewBag.StartDate = StartDate.ToShortDateString();
ViewBag.EndDate = EndDate.ToShortDateString();
WeeklyPartChanges weeklyPartChanges = new WeeklyPartChanges(numberOfPartChanges, startDate.ToShortDateString(),
endDate.ToShortDateString(), reactorPSNWORuns);
return View(weeklyPartChanges);
}

View File

@ -1,12 +1,29 @@
using Microsoft.AspNetCore.Mvc;
using ReportingServices.Dependency_Injections;
using ReportingServices.HelperClasses;
using ReportingServices.Models.ProductionReport;
using ReportingServices.ReportingObjects;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Web;
namespace ReportingServices.Controllers
{
public class ProductionReportController : Controller
{
private readonly IJsonFileHandler _jsonFileHandler;
private readonly IScrapeDatabaseRepository _scrapeDatabaseRepository;
private readonly IFabTimeReportingRepository _fabTimeReportingRepository;
private readonly int _reportIndex = (int)DateTime.Now.DayOfWeek;
private readonly string _dailyRptFileName = "wwwroot/Assets/DailyReportInfo.json";
private readonly string _toolFilter = "~R76%2C%20~R78%2C%20~R25%2C%20~R67%2C%20~R69%2C%20~R71%2C%20~R47%2C%20~R51%2C%20~R28";
public ProductionReportController(IJsonFileHandler jsonFileHandler, IScrapeDatabaseRepository scrapeDatabaseRepository, IFabTimeReportingRepository fabTimeReportingRepository)
{
_jsonFileHandler = jsonFileHandler;
_scrapeDatabaseRepository = scrapeDatabaseRepository;
_fabTimeReportingRepository = fabTimeReportingRepository;
}
public IActionResult Index()
@ -16,37 +33,98 @@ namespace ReportingServices.Controllers
public IActionResult DailyReport()
{
APICaller caller = new APICaller();
caller.CallAllAPIs();
DailyReport dailyReport = new DailyReport(caller.OutsByDay, caller.ScrapByDay, caller.ToolAvailibilityByTypes, caller.ToolStateByTypes);
DailyReport dailyReport = SetUpDailyReport();
return View(dailyReport);
}
public IActionResult EditDailyReport()
{
XMLReader xmlReader = new XMLReader();
JsonNode node = _jsonFileHandler.LoadJSONFile<JsonNode>(_dailyRptFileName);
DailyReportingSummary rpt = xmlReader.LoadJSONFile();
ManualReportEntries rpt = JsonSerializer.Deserialize<ManualReportEntries>(node[(int)DateTime.Now.DayOfWeek]["Entries"]);
return View(rpt);
}
[HttpPost]
public IActionResult EditDailyReport(DailyReportingSummary rpt)
public IActionResult EditDailyReport(ManualReportEntries rpt)
{
XMLReader xmlReader = new XMLReader();
List<ManualReportEntriesByDay> report = _jsonFileHandler.LoadJSONFile<List<ManualReportEntriesByDay>>(_dailyRptFileName);
//xmlReader.SaveXMLFile(rpt);
xmlReader.SaveJSONFile(rpt);
report[_reportIndex].Entries = rpt;
_jsonFileHandler.SaveJSONFile(report, _dailyRptFileName);
return RedirectToAction("DailyReport");
}
public IActionResult Headcount()
public async Task<List<ReactorOutsByRDS>> MovesTrendCaller()
{
return View();
string url = APIHelperFunctions.GenerateURLWithParameters(chart: "MOVESLOTLIST", areasLike: "CLEANROOM", operationsLike: "1UNLOAD");
List<ReactorOutsByRDS> outsByRDS = await _fabTimeReportingRepository.GetMovesTrendData(url);
return outsByRDS;
}
public async Task<List<EquipmentStateByDay>> ToolStateTrendCaller(string toolType)
{
string url = APIHelperFunctions.GenerateURLWithParameters(chart: "TOOLSTATE", periodLen: "24", capacityTypesLike: toolType, toolsLike: _toolFilter);
List<EquipmentStateByDay> toolAvailability = await _fabTimeReportingRepository.GetToolStateTrendData(url);
return toolAvailability;
}
public async Task<List<ToolStateCurrent>> ToolStatesCaller(string toolType)
{
string capacityFilter = toolType == "ASM" ? toolType + "%2CASM%2B" : toolType;
string startDate = HttpUtility.UrlEncode(APIHelperFunctions.GetDateWithOffsetAsAPIString(DateTime.Now.ToString(), 12.5f));
string url = APIHelperFunctions.GenerateURLWithParameters(chart: "ToolStateGantt", periodLen: "24",
capacityTypesLike: capacityFilter, toolsLike: _toolFilter, startDate: startDate);
List<ToolStateCurrent> toolStates = await _fabTimeReportingRepository.GetToolStateData(url);
return toolStates;
}
public DailyReport SetUpDailyReport()
{
DailyReport report = new();
Task<List<ReactorOutsByRDS>> task1 = MovesTrendCaller();
Task<List<EquipmentStateByDay>> task2 = ToolStateTrendCaller("ASM");
Task<List<EquipmentStateByDay>> task3 = ToolStateTrendCaller("EPP");
Task<List<EquipmentStateByDay>> task4 = ToolStateTrendCaller("HTR");
Task<List<ToolStateCurrent>> task5 = ToolStatesCaller("ASM");
Task<List<ToolStateCurrent>> task6 = ToolStatesCaller("EPP");
Task<List<ToolStateCurrent>> task7 = ToolStatesCaller("HTR");
report.SetOutsByDay(task1.Result);
List<ScrapByDay> scrap = _scrapeDatabaseRepository.GetScrapByDay(task1.Result);
report.SetScrapByDay(scrap);
report.AddToolAvailibilityByType("ASM", task2.Result);
report.AddToolAvailibilityByType("EPP", task3.Result);
report.AddToolAvailibilityByType("HTR", task4.Result);
report.AddToolStateByType("ASM", task5.Result);
report.AddToolStateByType("EPP", task6.Result);
report.AddToolStateByType("HTR", task7.Result);
report.ReverseLists();
List<ManualReportEntriesByDay> entries = _jsonFileHandler.LoadJSONFile<List<ManualReportEntriesByDay>>(_dailyRptFileName);
report.Entries = entries;
int[] singleLoadLocks = _scrapeDatabaseRepository.GetNumberOfSingleLoadLocks();
report.Entries[_reportIndex].Entries.SingleLoadLockASM = singleLoadLocks[0];
report.Entries[_reportIndex].Entries.SingleLoadLockHTR = singleLoadLocks[1];
return report;
}
}
}

View File

@ -0,0 +1,41 @@
using ReportingServices.ReportingObjects;
using System.Text.Json;
namespace ReportingServices.Dependency_Injections
{
public class FabTimeReportingRepository : IFabTimeReportingRepository
{
public async Task<List<ReactorOutsByRDS>> GetMovesTrendData(string url)
{
return await GetJsonData<List<ReactorOutsByRDS>>(url);
}
public async Task<List<EquipmentStateByDay>> GetToolStateTrendData(string url)
{
return await GetJsonData<List<EquipmentStateByDay>>(url);
}
public async Task<List<ToolStateCurrent>> GetToolStateData(string url)
{
return await GetJsonData<List<ToolStateCurrent>>(url);
}
public async Task<T> GetJsonData<T>(string url)
{
T deserializedJson;
using (var client = new HttpClient())
{
using (HttpResponseMessage response = await client.GetAsync(url))
{
string apiResponse = await response.Content.ReadAsStringAsync();
deserializedJson = JsonSerializer.Deserialize<T>(apiResponse);
}
}
return deserializedJson;
}
}
}

View File

@ -0,0 +1,19 @@
using System.Text.Json;
namespace ReportingServices.Dependency_Injections
{
public class JsonFileHandler : IJsonFileHandler
{
public T LoadJSONFile<T>(string file)
{
string json = File.ReadAllText(file);
return JsonSerializer.Deserialize<T>(json);
}
public void SaveJSONFile<T>(T obj, string file)
{
string json = JsonSerializer.Serialize(obj);
File.WriteAllText(file, json);
}
}
}

View File

@ -0,0 +1,164 @@
using Microsoft.Data.SqlClient;
using ReportingServices.Models.PlanningReport;
using ReportingServices.ReportingObjects;
using System.Data;
namespace ReportingServices.Dependency_Injections
{
public class ScrapeDatabaseRepository : IScrapeDatabaseRepository
{
private SqlConnection _connection;
private string _connectionString = "Server=Messv01ec.ec.local\\PROD1,53959;Database=LSL2SQL;User Id=srpadmin;Password=0okm9ijn;TrustServerCertificate=true";
public void OpenConnection()
{
if (_connection == null)
_connection = new SqlConnection(_connectionString);
if (_connection.State != ConnectionState.Open)
_connection.Open();
}
public void CloseConnection()
{
if (_connection.State != ConnectionState.Closed)
_connection.Close();
}
public int GetNumberOfPartChanges(string startDate, string endDate)
{
int result = 0;
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT COUNT(*) FROM " +
"(SELECT REACTOR, COUNT(PROD_SPEC_ID) - 1 AS PCHANGE FROM " +
"(SELECT REACTOR, PROD_SPEC_ID, COUNT(WO) AS PSN_COUNT FROM RDS WHERE DATE_OUT BETWEEN @startDate AND @endDate GROUP BY REACTOR, PROD_SPEC_ID) AS t " +
"GROUP BY REACTOR) AS l WHERE PCHANGE > 0";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@startDate", startDate);
cmd.Parameters.AddWithValue("@endDate", endDate);
using (SqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
result = int.Parse(reader[0].ToString());
}
cmd.Dispose();
CloseConnection();
return result;
}
public List<ScrapByDay> GetScrapByDay(List<ReactorOutsByRDS> outs)
{
List<ScrapByDay> scrap = new();
string rdsNumbers = "";
foreach (ReactorOutsByRDS rout in outs)
rdsNumbers = rdsNumbers + "'" + rout.RDS_NO + "', ";
rdsNumbers = rdsNumbers.Substring(0, rdsNumbers.Length - 2);
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT " +
" DATE_OUT," +
" SUM(CUST_TOT_REJ) AS TOT_REJ_CUST," +
" SUM(LSL_TOT_REJ) AS TOT_REJ_MANU," +
" SUM(TW_PROD) AS TW_PROD " +
"FROM RDS " +
"WHERE SEQ IN (" + rdsNumbers + ") " +
"GROUP BY DATE_OUT " +
"ORDER BY 1 DESC";
cmd.CommandText = query;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read() && reader[0].ToString() != "1/1/1900 12:00:00 AM")
scrap.Add(new ScrapByDay(reader[0].ToString(), reader[3].ToString(), reader[1].ToString(), reader[2].ToString()));
}
cmd.Dispose();
CloseConnection();
return scrap;
}
public List<ReactorPSNWORuns> GetReactorPSNWORuns(string startDate, string endDate)
{
List<ReactorPSNWORuns> weeklyPartChanges = new();
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT REACTOR, PROD_SPEC_ID, COUNT(WO) FROM RDS " +
"WHERE DATE_OUT BETWEEN @startDate AND @endDate " +
"GROUP BY REACTOR, PROD_SPEC_ID " +
"ORDER BY 1";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@startDate", startDate);
cmd.Parameters.AddWithValue("@endDate", endDate);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
weeklyPartChanges.Add(new ReactorPSNWORuns(reader[0].ToString(), reader[1].ToString(), int.Parse(reader[2].ToString())));
}
cmd.Dispose();
CloseConnection();
return weeklyPartChanges;
}
public int[] GetNumberOfSingleLoadLocks()
{
int[] singleLoadLocks = new int[2];
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT REACT_TYPE, COUNT(ACTIVE_LL_DISABLED) AS SLL" +
" FROM REACTOR " +
" WHERE REACT_ASSIGNMENT IS NOT NULL " +
" AND REACT_ASSIGNMENT <> 'Out of Service' " +
" AND REACT_ASSIGNMENT<> '' " +
" AND REACT_TYPE IN('ASM', 'HTR') " +
"GROUP BY REACT_TYPE";
cmd.CommandText = query;
using (SqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
singleLoadLocks[0] = int.Parse(reader[1].ToString());
reader.Read();
singleLoadLocks[1] = int.Parse(reader[1].ToString());
}
cmd.Dispose();
CloseConnection();
return singleLoadLocks;
}
}
}

View File

@ -0,0 +1,12 @@
using ReportingServices.ReportingObjects;
namespace ReportingServices.Dependency_Injections
{
public interface IFabTimeReportingRepository
{
public Task<List<ReactorOutsByRDS>> GetMovesTrendData(string url);
public Task<List<EquipmentStateByDay>> GetToolStateTrendData(string url);
public Task<List<ToolStateCurrent>> GetToolStateData(string url);
public Task<T> GetJsonData<T>(string url);
}
}

View File

@ -0,0 +1,10 @@
using ReportingServices.ReportingObjects;
namespace ReportingServices.Dependency_Injections
{
public interface IJsonFileHandler
{
public void SaveJSONFile<T>(T obj, string file);
public T LoadJSONFile<T>(string file);
}
}

View File

@ -0,0 +1,15 @@
using ReportingServices.Models.PlanningReport;
using ReportingServices.ReportingObjects;
namespace ReportingServices.Dependency_Injections
{
public interface IScrapeDatabaseRepository
{
public void OpenConnection();
public void CloseConnection();
public List<ScrapByDay> GetScrapByDay(List<ReactorOutsByRDS> outs);
public List<ReactorPSNWORuns> GetReactorPSNWORuns(string startDate, string endDate);
public int GetNumberOfPartChanges(string startDate, string endDate);
public int[] GetNumberOfSingleLoadLocks();
}
}

View File

@ -0,0 +1,111 @@
using ReportingServices.Dependency_Injections;
using ReportingServices.ReportingObjects;
using System.Web;
namespace ReportingServices.HelperClasses
{
public static class APIHelperFunctions
{
private readonly static string fabTimeServer = "http://messa004.infineon.com/fabtime717service/GetChartData.aspx?";
public static string GetBeginningOfWeekAsAPIString()
{
DateTime date = DateTime.Now;
int dayOfWeek = (int)date.DayOfWeek;
date = dayOfWeek switch
{
0 => date.AddDays(-6),
1 => date.AddDays(-7),
_ => date.AddDays(1 - dayOfWeek)
};
return GetDateTimeAsAPIString(date.ToString(), false);
}
public static string GetDateWithOffsetAsAPIString(string dateString, float offset)
{
DateTime date = DateTime.Parse(dateString);
date = date.AddHours(offset);
return GetDateTimeAsAPIString(date.ToString(), true);
}
public static string GetDateTimeAsAPIString(string dateString, bool fullDateTime)
{
DateTime date = DateTime.Parse(dateString);
if (fullDateTime)
dateString = date.Year + "-" + date.Month + "-" + date.Day + " " + date.Hour + ":" + date.Minute + ":" + date.Second;
else
dateString = date.Year + "-" + date.Month + "-" + date.Day + " 0:0:0";
return dateString;
}
public static Dictionary<string, string> SetParameters(string startDate = "", string chart = "", string periodLen = "",
string areasLike = "", string toolsLike = "", string operationsLike = "", string capacityTypesLike = "")
{
Dictionary<string, string> parameters = new();
startDate = startDate == "" ? HttpUtility.UrlEncode(GetBeginningOfWeekAsAPIString()) : startDate;
string endDate = HttpUtility.UrlEncode(GetDateTimeAsAPIString(DateTime.Now.ToString(), true));
parameters.Add("chart", chart);
parameters.Add("starttime", startDate);
parameters.Add("endtime", endDate);
parameters.Add("periodlen", periodLen);
parameters.Add("areaslike", areasLike);
parameters.Add("toolslike", toolsLike);
parameters.Add("operationslike", operationsLike);
parameters.Add("capacitytypeslike", capacityTypesLike);
parameters.Add("login", "administrator");
parameters.Add("password", "admin");
parameters.Add("fabtimeauthentication", "1");
return parameters;
}
public static string GenerateURL(Dictionary<string, string> parameters)
{
int count = 0;
string url = fabTimeServer;
foreach (KeyValuePair<string, string> pair in parameters)
{
if (pair.Value != "")
url = url + pair.Key + "=" + pair.Value;
if (count != parameters.Count - 1 && !string.IsNullOrEmpty(pair.Value))
url += "&";
count++;
}
return url;
}
public static string GenerateURLWithParameters(string startDate = "", string chart = "", string periodLen = "",
string areasLike = "", string toolsLike = "", string operationsLike = "", string capacityTypesLike = "")
{
Dictionary<string, string> parameters = SetParameters(startDate, chart,
periodLen, areasLike, toolsLike, operationsLike, capacityTypesLike);
return GenerateURL(parameters);
}
public static List<T> ReverseList<T>(List<T> inputList)
{
List<T> temp = new();
for (int i = inputList.Count - 1; i >= 0; i--)
{
temp.Add(inputList[i]);
}
return temp;
}
}
}

View File

@ -1,241 +0,0 @@
using ReportingServices.ReportingObjects;
using System.Text.Json;
namespace ReportingServices.HelperClasses
{
public class APICaller
{
public List<ReactorOutsByDay> OutsByDay { get; set; }
public List<ScrapByDay> ScrapByDay { get; set; }
public Dictionary<string, ToolAvailibilityByType> ToolAvailibilityByTypes { get; set; }
public Dictionary<string, ToolStateByType> ToolStateByTypes { get; set; }
private readonly string fabTimeServer = "http://messa004.infineon.com/fabtime717service/GetChartData.aspx?";
private Dictionary<string, string> Parameters = new();
private readonly string toolFilter = "~R76%2C%20~R78%2C%20~R25%2C%20~R67%2C%20~R69%2C%20~R71%2C%20~R47%2C%20~R51%2C%20~R28";
public APICaller()
{
Parameters.Add("chart", "");
Parameters.Add("starttime", DetermineStartDate());
Parameters.Add("endtime", DetermineEndDate());
Parameters.Add("periodlen", "");
Parameters.Add("areaslike", "");
Parameters.Add("toolsslike", "");
Parameters.Add("operationslike", "");
Parameters.Add("capacitytypeslike", "");
Parameters.Add("login", "administrator");
Parameters.Add("password", "admin");
Parameters.Add("fabtimeauthentication", "1");
ToolAvailibilityByTypes = new();
ToolStateByTypes = new();
}
public void CallAllAPIs()
{
Task[] tasks = new Task[7];
tasks[0] = MovesTrendCaller();
tasks[1] = ToolStateTrendCaller("ASM");
tasks[2] = ToolStateTrendCaller("EPP");
tasks[3] = ToolStateTrendCaller("HTR");
tasks[4] = ToolStatesCaller("ASM");
tasks[5] = ToolStatesCaller("EPP");
tasks[6] = ToolStatesCaller("HTR");
Task.WaitAll(tasks);
ReverseLists();
}
public async Task MovesTrendCaller()
{
Dictionary<string, string> parameters = Parameters;
parameters["chart"] = "MOVESLOTLIST";
parameters["areaslike"] = "CLEANROOM";
parameters["operationslike"] = "1UNLOAD";
List<ReactorOutsByRDS> outsByDay = await GetJsonData<ReactorOutsByRDS>(GetAPIURL(parameters));
GetReactorOutsByDay(outsByDay);
DBCaller db = new();
ScrapByDay = db.GetScrap(outsByDay);
}
public async Task ToolStateTrendCaller(string toolType)
{
Dictionary<string, string> parameters = Parameters;
parameters["chart"] = "TOOLSTATE";
parameters["periodlen"] = "24";
parameters["capacitytypeslike"] = toolType;
parameters["toolslike"] = toolFilter;
List<EquipmentStateByDay> toolAvailability = await GetJsonData<EquipmentStateByDay>(GetAPIURL(parameters));
ToolAvailibilityByTypes.Add(toolType, new ToolAvailibilityByType(toolAvailability));
}
public async Task ToolStatesCaller(string toolType)
{
Dictionary<string, string> parameters = Parameters;
parameters["starttime"] = DetermineStartDate(DateTime.Now.ToString(), 12.5f);
parameters["chart"] = "ToolStateGantt";
parameters["periodlen"] = "24";
parameters["capacitytypeslike"] = toolType == "ASM" ? toolType + "%2CASM%2B" : toolType;
parameters["toolslike"] = toolFilter;
List<ToolStateCurrent> toolStates = await GetJsonData<ToolStateCurrent>(GetAPIURL(parameters));
ToolStateByTypes.Add(toolType, new ToolStateByType(toolStates));
}
private async Task<List<T>> GetJsonData<T>(string url)
{
List<T> deserializedJson;
using (var httpClient = new HttpClient())
{
using (var response = await httpClient.GetAsync(url))
{
string apiResponse = await response.Content.ReadAsStringAsync();
deserializedJson = JsonSerializer.Deserialize<List<T>>(apiResponse);
}
}
return deserializedJson;
}
public string DetermineStartDate(string date = null)
{
if (!DateTime.TryParse(date, out DateTime startDate))
startDate = DateTime.Now.Date;
int dayOfWeek = (int)startDate.DayOfWeek;
switch (dayOfWeek)
{
case 0:
startDate = startDate.AddDays(-6);
break;
case 1:
startDate = startDate.AddDays(-7);
break;
case 2:
startDate = startDate.AddDays(-1);
break;
case 3:
startDate = startDate.AddDays(-2);
break;
case 4:
startDate = startDate.AddDays(-3);
break;
case 5:
startDate = startDate.AddDays(-4);
break;
case 6:
startDate = startDate.AddDays(-5);
break;
default:
break;
}
return startDate.Year + "-" + startDate.Month + "-" + startDate.Day + "%200%3A0%3A0";
}
public string DetermineStartDate(string date, float numberOfHours)
{
DateTime startDate = DateTime.Parse(date);
startDate = startDate.AddHours(-numberOfHours);
return startDate.Year + "-" + startDate.Month + "-" + startDate.Day + "%20" + startDate.Hour + "%3A" + startDate.Minute + "%3A" + startDate.Second;
}
public string DetermineEndDate(string date = null)
{
if (!DateTime.TryParse(date, out DateTime endDate))
endDate = DateTime.Now;
return endDate.Year + "-" + endDate.Month + "-" + endDate.Day + "%20" + endDate.Hour + "%3A" + endDate.Minute + "%3A" + endDate.Second;
}
public string GetAPIURL(Dictionary<string, string> parameters)
{
int count = 0;
string url = fabTimeServer;
foreach (KeyValuePair<string, string> pair in parameters)
{
if (pair.Value != "")
url = url + pair.Key + "=" + pair.Value;
if (count != parameters.Count - 1 && !string.IsNullOrEmpty(pair.Value))
url = url + "&";
count++;
}
return url;
}
public void GetReactorOutsByDay(List<ReactorOutsByRDS> outs)
{
List<ReactorOutsByDay> outsByDay = new();
List<string> dates = GetDistinctDates(outs);
foreach (string date in dates)
{
int waferCount = 0;
foreach (ReactorOutsByRDS rout in outs)
{
if (DateTime.Parse(rout.EndProcessTime).Date.ToString() == date)
waferCount += (int)float.Parse(rout.Units);
}
outsByDay.Add(new ReactorOutsByDay(date, waferCount));
}
OutsByDay = outsByDay;
}
public List<string> GetDistinctDates(List<ReactorOutsByRDS> outs)
{
List<string> dates = new();
foreach (ReactorOutsByRDS rout in outs)
{
if (!dates.Contains(DateTime.Parse(rout.EndProcessTime).Date.ToString()))
dates.Add(DateTime.Parse(rout.EndProcessTime).Date.ToString());
}
return dates;
}
public void ReverseLists()
{
List<ScrapByDay> temp2 = new();
for (int i = ScrapByDay.Count - 1; i >= 0; i--)
{
temp2.Add(ScrapByDay[i]);
}
ScrapByDay = temp2;
foreach (KeyValuePair<string, ToolAvailibilityByType> keyValuePair in ToolAvailibilityByTypes)
{
List<EquipmentStateByDay> temp3 = new();
for (int i = keyValuePair.Value.EquipmentStates.Count - 1; i >= 0; i--)
{
temp3.Add(keyValuePair.Value.EquipmentStates[i]);
}
}
}
}
}

View File

@ -1,134 +0,0 @@
using System.Data;
using Microsoft.Data.SqlClient;
using ReportingServices.Models.PlanningReport;
using ReportingServices.ReportingObjects;
namespace ReportingServices.HelperClasses
{
public class DBCaller
{
private SqlConnection _connection;
public void OpenConnection()
{
if (_connection == null || _connection.State == ConnectionState.Closed)
{
_connection = new SqlConnection("Server=Messv01ec.ec.local\\PROD1,53959;Database=LSL2SQL;User Id=srpadmin;Password=0okm9ijn;TrustServerCertificate=true");
_connection.Open();
}
}
public void CloseConnection()
{
if (_connection.State != ConnectionState.Closed)
_connection.Close();
}
public List<ScrapByDay> GetScrap(List<ReactorOutsByRDS> outs)
{
List<ScrapByDay> scrap = new();
string rdsNumbers = "";
foreach (ReactorOutsByRDS rout in outs)
rdsNumbers = rdsNumbers + "'" + rout.RDS_NO + "', ";
rdsNumbers = rdsNumbers.Substring(0, rdsNumbers.Length - 2);
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
try
{
string query = "SELECT " +
" DATE_OUT," +
" SUM(CUST_TOT_REJ) AS TOT_REJ_CUST," +
" SUM(LSL_TOT_REJ) AS TOT_REJ_MANU," +
" SUM(TW_PROD) AS TW_PROD " +
"FROM RDS " +
"WHERE SEQ IN (" + rdsNumbers + ") " +
"GROUP BY DATE_OUT " +
"ORDER BY 1 DESC";
cmd.CommandText = query;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read() && reader[0].ToString() != "1/1/1900 12:00:00 AM")
scrap.Add(new ScrapByDay(reader[0].ToString(), reader[3].ToString(), reader[1].ToString(), reader[2].ToString()));
}
}
catch (Exception ex)
{
}
cmd.Dispose();
CloseConnection();
return scrap;
}
public List<WeeklyPartChanges> GetWeeklyPartChanges(string startDate, string endDate)
{
List<WeeklyPartChanges> weeklyPartChanges = new();
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT REACTOR, PROD_SPEC_ID, COUNT(WO) FROM RDS " +
"WHERE DATE_OUT BETWEEN @startDate AND @endDate " +
"GROUP BY REACTOR, PROD_SPEC_ID " +
"ORDER BY 1";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@startDate", startDate);
cmd.Parameters.AddWithValue("@endDate", endDate);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
weeklyPartChanges.Add(new WeeklyPartChanges(reader[0].ToString(), reader[1].ToString(), int.Parse(reader[2].ToString())));
}
cmd.Dispose();
CloseConnection();
return weeklyPartChanges;
}
public int GetNumberOfPartChanges(string startDate, string endDate)
{
int result = 0;
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT COUNT(*) FROM " +
"(SELECT REACTOR, COUNT(PROD_SPEC_ID) - 1 AS PCHANGE FROM " +
"(SELECT REACTOR, PROD_SPEC_ID, COUNT(WO) AS PSN_COUNT FROM RDS WHERE DATE_OUT BETWEEN @startDate AND @endDate GROUP BY REACTOR, PROD_SPEC_ID) AS t " +
"GROUP BY REACTOR) AS l WHERE PCHANGE > 0";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@startDate", startDate);
cmd.Parameters.AddWithValue("@endDate", endDate);
using (SqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
result = int.Parse(reader[0].ToString());
}
cmd.Dispose();
CloseConnection();
return result;
}
}
}

View File

@ -1,20 +0,0 @@
using ReportingServices.ReportingObjects;
using System.Text.Json;
namespace ReportingServices.HelperClasses
{
public class XMLReader
{
public void SaveJSONFile(DailyReportingSummary rpt)
{
string json = JsonSerializer.Serialize(rpt);
File.WriteAllText("wwwroot/Assets/DailyReportInfo.json", json);
}
public DailyReportingSummary LoadJSONFile()
{
string json = File.ReadAllText("wwwroot/Assets/DailyReportInfo.json");
return JsonSerializer.Deserialize<DailyReportingSummary>(json);
}
}
}

View File

@ -2,7 +2,7 @@ namespace ReportingServices.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}

View File

@ -0,0 +1,16 @@
namespace ReportingServices.Models.PlanningReport
{
public class ReactorPSNWORuns
{
public string REACTOR { get; set; }
public string PSN { get; set; }
public int WO_COUNT { get; set; }
public ReactorPSNWORuns(string reactor, string psn, int wo_count)
{
REACTOR = reactor;
PSN = psn;
WO_COUNT = wo_count;
}
}
}

View File

@ -2,15 +2,17 @@
{
public class WeeklyPartChanges
{
public string REACTOR { get; set; }
public string PSN { get; set; }
public int WO_COUNT { get; set; }
public int TotalPartChanges { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public List<ReactorPSNWORuns> ReactorPSNWORuns { get; set; }
public WeeklyPartChanges(string reactor, string psn, int wo_count)
public WeeklyPartChanges(int totalPartChanges, string startDate, string endDate, List<ReactorPSNWORuns> reactorPSNWORuns)
{
REACTOR = reactor;
PSN = psn;
WO_COUNT = wo_count;
TotalPartChanges = totalPartChanges;
StartDate = startDate;
EndDate = endDate;
ReactorPSNWORuns = reactorPSNWORuns;
}
}
}

View File

@ -1,4 +1,5 @@
using ReportingServices.ReportingObjects;
using ReportingServices.HelperClasses;
using ReportingServices.ReportingObjects;
namespace ReportingServices.Models.ProductionReport
{
@ -6,17 +7,80 @@ namespace ReportingServices.Models.ProductionReport
{
public List<ReactorOutsByDay> OutsByDay { get; set; }
public List<ScrapByDay> ScrapByDay { get; set; }
public Dictionary<string, ToolAvailibilityByType> ToolAvailibilityByType { get; set; }
public Dictionary<string, List<EquipmentStateByDay>> ToolAvailibilityByType { get; set; }
public Dictionary<string, ToolStateByType> ToolStateByType { get; set; }
public List<ManualReportEntriesByDay> Entries { get; set; }
public DailyReport(List<ReactorOutsByDay> outsByDay, List<ScrapByDay> scrapByDay, Dictionary<string, ToolAvailibilityByType> toolAvailibilityByType, Dictionary<string, ToolStateByType> toolStateByType)
public DailyReport()
{
OutsByDay = outsByDay;
ScrapByDay = scrapByDay;
ToolAvailibilityByType = toolAvailibilityByType;
ToolStateByType = toolStateByType;
ToolAvailibilityByType = new();
ToolStateByType = new();
}
public void SetOutsByDay(List<ReactorOutsByRDS> outs)
{
OutsByDay = GetReactorOutsByDay(outs);
}
public void SetScrapByDay(List<ScrapByDay> scrap)
{
ScrapByDay = scrap;
}
public void AddToolAvailibilityByType(string key, List<EquipmentStateByDay> states)
{
ToolAvailibilityByType.Add(key, states);
}
public void AddToolStateByType(string key, List<ToolStateCurrent> states)
{
ToolStateByType state = new ToolStateByType(states);
ToolStateByType.Add(key, state);
}
public static List<string> GetDistinctDatesFromReactorOuts(List<ReactorOutsByRDS> outs)
{
List<string> dates = new();
foreach (ReactorOutsByRDS rout in outs)
{
if (!dates.Contains(DateTime.Parse(rout.EndProcessTime).Date.ToString()))
dates.Add(DateTime.Parse(rout.EndProcessTime).Date.ToString());
}
return dates;
}
public static List<ReactorOutsByDay> GetReactorOutsByDay(List<ReactorOutsByRDS> outs)
{
List<ReactorOutsByDay> outsByDay = new();
List<string> dates = GetDistinctDatesFromReactorOuts(outs);
foreach (string date in dates)
{
int waferCount = 0;
foreach (ReactorOutsByRDS rout in outs)
{
if (DateTime.Parse(rout.EndProcessTime).Date.ToString() == date)
waferCount += (int)float.Parse(rout.Units);
}
outsByDay.Add(new ReactorOutsByDay(date, waferCount));
}
return outsByDay;
}
public void ReverseLists()
{
ScrapByDay = APIHelperFunctions.ReverseList(ScrapByDay);
ToolAvailibilityByType["ASM"] = APIHelperFunctions.ReverseList(ToolAvailibilityByType["ASM"]);
ToolAvailibilityByType["EPP"] = APIHelperFunctions.ReverseList(ToolAvailibilityByType["EPP"]);
ToolAvailibilityByType["HTR"] = APIHelperFunctions.ReverseList(ToolAvailibilityByType["HTR"]);
}
}
}

View File

@ -1,7 +1,12 @@
using ReportingServices.Dependency_Injections;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddScoped<IJsonFileHandler, JsonFileHandler>();
builder.Services.AddScoped<IScrapeDatabaseRepository, ScrapeDatabaseRepository>();
builder.Services.AddScoped<IFabTimeReportingRepository, FabTimeReportingRepository>();
var app = builder.Build();

View File

@ -1,6 +1,6 @@
namespace ReportingServices.ReportingObjects
{
public class DailyReportingSummary
public class ManualReportEntries
{
public int OperatorHeadcountDays { get; set; }
public int OperatorHeadcountNights { get; set; }
@ -17,5 +17,7 @@
public string BottleChanges { get; set; }
public string DailyPartChanges { get; set; }
public string WeeklyPartChanges { get; set; }
public int SingleLoadLockASM { get; set; }
public int SingleLoadLockHTR { get; set; }
}
}

View File

@ -0,0 +1,14 @@
namespace ReportingServices.ReportingObjects
{
public class ManualReportEntriesByDay
{
public DayOfWeek Day { get; set; }
public ManualReportEntries Entries { get; set; }
public ManualReportEntriesByDay(DayOfWeek day, ManualReportEntries entries)
{
Day = day;
Entries = entries;
}
}
}

View File

@ -1,12 +0,0 @@
namespace ReportingServices.ReportingObjects
{
public class ToolAvailibilityByType
{
public List<EquipmentStateByDay> EquipmentStates { get; set; }
public ToolAvailibilityByType(List<EquipmentStateByDay> equipmentStates)
{
EquipmentStates = equipmentStates;
}
}
}

View File

@ -27,11 +27,11 @@
<div class="modal-body" style="padding-top: 15px; padding-bottom: 10px">
<div class="row">
<div class="col-6">Start Date:</div>
<div class="col-6"><input type="text" name="StartDate" id="StartDate" /></div>
<div class="col-6"><input type="text" name="startDate" id="StartDate" /></div>
</div>
<div class="row" style="padding-top: 10px; padding-bottom: 10px">
<div class="col-6">End Date:</div>
<div class="col-6"><input type="text" name="EndDate" id="EndDate" /></div>
<div class="col-6"><input type="text" name="endDate" id="EndDate" /></div>
</div>
<div class="row" style="padding-top: 10px; padding-bottom: 10px">
<div class="col text-center">

View File

@ -1,6 +1,6 @@
@using ReportingServices.Models.PlanningReport
@using ReportingServices.HelperClasses
@model List<ReportingServices.Models.PlanningReport.WeeklyPartChanges>
@model ReportingServices.Models.PlanningReport.WeeklyPartChanges
@{
ViewData["Title"] = "Weekly Part Changes | Mesa Reporting Services";
@ -20,10 +20,10 @@
<div>
<div class="row">
<div class="col-6">
<p>Number of Part Changes: @ViewBag.NumberOfPartChanges</p>
<p>Number of Part Changes: @Model.TotalPartChanges</p>
</div>
<div class="col-6">
<p class="text-end">@ViewBag.StartDate - @ViewBag.EndDate</p>
<p class="text-end">@Model.StartDate - @Model.EndDate</p>
</div>
</div>
<div>
@ -36,19 +36,19 @@
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Count; i++)
@for (int i = 0; i < Model.ReactorPSNWORuns.Count; i++)
{
int count = 1;
bool doesMatch = false;
if (i + count < Model.Count)
doesMatch = Model[i].REACTOR == Model[i + count].REACTOR;
if (i + count < Model.ReactorPSNWORuns.Count)
doesMatch = Model.ReactorPSNWORuns[i].REACTOR == Model.ReactorPSNWORuns[i + count].REACTOR;
while (doesMatch)
{
count++;
if (i + count < Model.Count)
doesMatch = Model[i].REACTOR == Model[i + count].REACTOR;
if (i + count < Model.ReactorPSNWORuns.Count)
doesMatch = Model.ReactorPSNWORuns[i].REACTOR == Model.ReactorPSNWORuns[i + count].REACTOR;
else
doesMatch = false;
}
@ -63,14 +63,14 @@
<tr class="align-middle @tableColor">
@if (j == 0)
{
<td rowspan="@(count)">@Model[i].REACTOR</td>
<td>@Model[i].PSN</td>
<td>@Model[i].WO_COUNT</td>
<td rowspan="@(count)">@Model.ReactorPSNWORuns[i].REACTOR</td>
<td>@Model.ReactorPSNWORuns[i].PSN</td>
<td>@Model.ReactorPSNWORuns[i].WO_COUNT</td>
}
else
{
<td>@Model[i + j].PSN</td>
<td>@Model[i + j].WO_COUNT</td>
<td>@Model.ReactorPSNWORuns[i + j].PSN</td>
<td>@Model.ReactorPSNWORuns[i + j].WO_COUNT</td>
}
</tr>
}

View File

@ -16,6 +16,13 @@
int EPPAvailablePct = 0;
int HTRAvailablePct = 0;
int ASMSLL = 0;
int HTRSLL = 0;
int reportIndex = (int)DateTime.Now.DayOfWeek;
ManualReportEntries rpt = Model.Entries[reportIndex].Entries;
string myClass;
List<string> toolsDownGreaterThan12Hours = new();
@ -26,10 +33,6 @@
toolsDownGreaterThan12Hours.Sort();
ReportingServices.HelperClasses.XMLReader xmlReader = new ReportingServices.HelperClasses.XMLReader();
DailyReportingSummary rpt = xmlReader.LoadJSONFile();
switch (dayOfWeek)
{
case 0:
@ -132,7 +135,7 @@
<td>Before Scrap</td>
</tr>
<tr>
<td scope="row" id="expandYield">Actual Yielded Wafers Out</td>
<td scope="row" id="expandYield">Actual Yielded Wafers Out &nbsp;&nbsp;&nbsp; <img src="~/Images/plusIcon.png" width="20" style="padding-bottom: 3px" onclick="expandYield()" id="yieldImage" /></td>
@for (int i = 0; i < 7; i++)
{
if (i < Model.OutsByDay.Count)
@ -445,10 +448,9 @@
<td scope="row">ASMs Uptime</td>
@for (int i = 0; i < 7; i++)
{
if (i < Model.ToolAvailibilityByType["ASM"].EquipmentStates.Count)
if (i < Model.ToolAvailibilityByType["ASM"].Count)
{
int availiblePct = (int)Math.Round(float.Parse(Model.ToolAvailibilityByType["ASM"].EquipmentStates[i].AvailablePct));
int availiblePct = (int)Math.Round(float.Parse(Model.ToolAvailibilityByType["ASM"][i].AvailablePct));
if (availiblePct < 82)
myClass = "table-danger text-danger";
@ -471,10 +473,9 @@
<td scope="row">EPPs Uptime</td>
@for (int i = 0; i < 7; i++)
{
if (i < Model.ToolAvailibilityByType["EPP"].EquipmentStates.Count)
if (i < Model.ToolAvailibilityByType["EPP"].Count)
{
int availiblePct = (int)Math.Round(float.Parse(Model.ToolAvailibilityByType["EPP"].EquipmentStates[i].AvailablePct));
int availiblePct = (int)Math.Round(float.Parse(Model.ToolAvailibilityByType["EPP"][i].AvailablePct));
if (availiblePct < 60)
myClass = "table-danger text-danger";
@ -497,10 +498,9 @@
<td scope="row">HTRs Uptime</td>
@for (int i = 0; i < 7; i++)
{
if (i < Model.ToolAvailibilityByType["HTR"].EquipmentStates.Count)
if (i < Model.ToolAvailibilityByType["HTR"].Count)
{
int availiblePct = (int)Math.Round(float.Parse(Model.ToolAvailibilityByType["HTR"].EquipmentStates[i].AvailablePct));
int availiblePct = (int)Math.Round(float.Parse(Model.ToolAvailibilityByType["HTR"][i].AvailablePct));
if (availiblePct < 78)
myClass = "table-danger text-danger";
@ -519,6 +519,46 @@
<td>@(HTRAvailablePct / count + "%")</td>
<td>78%</td>
</tr>
<tr>
<td scope="row">ASMs SLL Tool Count</td>
@for (int i = 0; i < 7; i++)
{
if (i < Model.Entries.Count)
{
int index = i == 6 ? 0 : i + 1;
<td>@Model.Entries[index].Entries.SingleLoadLockASM</td>
ASMSLL += @Model.Entries[index].Entries.SingleLoadLockASM;
}
else
{
<td></td>
}
}
<td>@(ASMSLL / count)</td>
<td>0</td>
</tr>
<tr>
<td scope="row">HTRs SLL Tool Count</td>
@for (int i = 0; i < 7; i++)
{
if (i < Model.Entries.Count)
{
int index = i == 6 ? 0 : i + 1;
<td>@Model.Entries[index].Entries.SingleLoadLockHTR</td>
HTRSLL += @Model.Entries[index].Entries.SingleLoadLockHTR;
}
else
{
<td></td>
}
}
<td>@(HTRSLL / count)</td>
<td>0</td>
</tr>
</tbody>
</table>
</div>

View File

@ -1,4 +1,4 @@
@model ReportingServices.ReportingObjects.DailyReportingSummary
@model ReportingServices.ReportingObjects.ManualReportEntries
@{
ViewData["Title"] = "Edit Daily Passdown | Mesa Reporting Services";

View File

@ -11,9 +11,8 @@
<br />
<div class="row">
<div class="col-3 d-grid btn btn-outline-secondary">
<img src="~/Images/ReportFile.png" class="buttonImage float-start" />
<a class="text-start text-wrap" asp-area="" asp-controller="ProductionReport" asp-action="DailyReport" onclick="displayBusyIndicator()">Production Passdown Report</a>
<div class="col-3 d-grid">
<a class="btn btn-outline-secondary text-start" asp-area="" asp-controller="ProductionReport" asp-action="DailyReport" onclick="displayBusyIndicator()"><img src="~/Images/ReportFile.png" class="buttonImage float-start" />Production Passdown Report</a>
</div>
</div>

View File

@ -51,7 +51,7 @@
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2022 - ReportingServices - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
&copy; 2022 - Mesa Reporting Services
</div>
</footer>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>

View File

@ -1,17 +1,156 @@
{
"BottleChanges": "R22",
"DailyPartChanges": "R22,R23,R25",
"EngineeringCallOutsDays": 0,
"EngineeringCallOutsNights": 0,
"EngineeringHeadcountDays": 2,
"EngineeringHeadcountNights": 2,
"MaintenanceCallOutsDays": 0,
"MaintenanceCallOutsNights": 2,
"MaintenanceHeadcountDays": 4,
"MaintenanceHeadcountNights": 5,
"OperatorCallOutsDays": 2,
"OperatorCallOutsNights": 0,
"OperatorHeadcountDays": 13,
"OperatorHeadcountNights": 13,
"WeeklyPartChanges": "R21,R23,R29,R30"
}
[
{
"Day": 0,
"Entries": {
"OperatorHeadcountDays": 6,
"OperatorHeadcountNights": 15,
"OperatorCallOutsDays": 2,
"OperatorCallOutsNights": 0,
"EngineeringHeadcountDays": 2,
"EngineeringHeadcountNights": 2,
"EngineeringCallOutsDays": 0,
"EngineeringCallOutsNights": 0,
"MaintenanceHeadcountDays": 4,
"MaintenanceHeadcountNights": 5,
"MaintenanceCallOutsDays": 0,
"MaintenanceCallOutsNights": 2,
"BottleChanges": "R22",
"DailyPartChanges": "R22,R23,R25",
"WeeklyPartChanges": "R21,R23,R29,R30",
"SingleLoadLockASM": 0,
"SingleLoadLockHTR": 0
}
},
{
"Day": 1,
"Entries": {
"OperatorHeadcountDays": 6,
"OperatorHeadcountNights": 15,
"OperatorCallOutsDays": 2,
"OperatorCallOutsNights": 0,
"EngineeringHeadcountDays": 2,
"EngineeringHeadcountNights": 2,
"EngineeringCallOutsDays": 0,
"EngineeringCallOutsNights": 0,
"MaintenanceHeadcountDays": 4,
"MaintenanceHeadcountNights": 5,
"MaintenanceCallOutsDays": 0,
"MaintenanceCallOutsNights": 2,
"BottleChanges": "R22",
"DailyPartChanges": "R22,R23,R25",
"WeeklyPartChanges": "R21,R23,R29,R30",
"SingleLoadLockASM": 0,
"SingleLoadLockHTR": 0
}
},
{
"Day": 2,
"Entries": {
"OperatorHeadcountDays": 6,
"OperatorHeadcountNights": 15,
"OperatorCallOutsDays": 2,
"OperatorCallOutsNights": 0,
"EngineeringHeadcountDays": 2,
"EngineeringHeadcountNights": 2,
"EngineeringCallOutsDays": 0,
"EngineeringCallOutsNights": 0,
"MaintenanceHeadcountDays": 4,
"MaintenanceHeadcountNights": 5,
"MaintenanceCallOutsDays": 0,
"MaintenanceCallOutsNights": 2,
"BottleChanges": "R22",
"DailyPartChanges": "R22,R23,R25",
"WeeklyPartChanges": "R21,R23,R29,R30",
"SingleLoadLockASM": 0,
"SingleLoadLockHTR": 0
}
},
{
"Day": 3,
"Entries": {
"OperatorHeadcountDays": 6,
"OperatorHeadcountNights": 15,
"OperatorCallOutsDays": 2,
"OperatorCallOutsNights": 0,
"EngineeringHeadcountDays": 2,
"EngineeringHeadcountNights": 2,
"EngineeringCallOutsDays": 0,
"EngineeringCallOutsNights": 0,
"MaintenanceHeadcountDays": 4,
"MaintenanceHeadcountNights": 5,
"MaintenanceCallOutsDays": 0,
"MaintenanceCallOutsNights": 2,
"BottleChanges": "R22",
"DailyPartChanges": "R22,R23,R25",
"WeeklyPartChanges": "R21,R23,R29,R30",
"SingleLoadLockASM": 0,
"SingleLoadLockHTR": 0
}
},
{
"Day": 4,
"Entries": {
"OperatorHeadcountDays": 6,
"OperatorHeadcountNights": 15,
"OperatorCallOutsDays": 2,
"OperatorCallOutsNights": 0,
"EngineeringHeadcountDays": 2,
"EngineeringHeadcountNights": 2,
"EngineeringCallOutsDays": 0,
"EngineeringCallOutsNights": 0,
"MaintenanceHeadcountDays": 4,
"MaintenanceHeadcountNights": 5,
"MaintenanceCallOutsDays": 0,
"MaintenanceCallOutsNights": 2,
"BottleChanges": "R22",
"DailyPartChanges": "R22,R23,R25",
"WeeklyPartChanges": "R21,R23,R29,R30",
"SingleLoadLockASM": 0,
"SingleLoadLockHTR": 0
}
},
{
"Day": 5,
"Entries": {
"OperatorHeadcountDays": 0,
"OperatorHeadcountNights": 15,
"OperatorCallOutsDays": 2,
"OperatorCallOutsNights": 0,
"EngineeringHeadcountDays": 2,
"EngineeringHeadcountNights": 2,
"EngineeringCallOutsDays": 0,
"EngineeringCallOutsNights": 0,
"MaintenanceHeadcountDays": 4,
"MaintenanceHeadcountNights": 5,
"MaintenanceCallOutsDays": 0,
"MaintenanceCallOutsNights": 2,
"BottleChanges": "R22",
"DailyPartChanges": "R22,R23,R25",
"WeeklyPartChanges": "R21,R23,R29,R30",
"SingleLoadLockASM": 0,
"SingleLoadLockHTR": 0
}
},
{
"Day": 6,
"Entries": {
"OperatorHeadcountDays": 6,
"OperatorHeadcountNights": 15,
"OperatorCallOutsDays": 2,
"OperatorCallOutsNights": 0,
"EngineeringHeadcountDays": 2,
"EngineeringHeadcountNights": 2,
"EngineeringCallOutsDays": 0,
"EngineeringCallOutsNights": 0,
"MaintenanceHeadcountDays": 4,
"MaintenanceHeadcountNights": 5,
"MaintenanceCallOutsDays": 0,
"MaintenanceCallOutsNights": 2,
"BottleChanges": "R22",
"DailyPartChanges": "R22,R23,R25",
"WeeklyPartChanges": "R21,R23,R29,R30",
"SingleLoadLockASM": 0,
"SingleLoadLockHTR": 0
}
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

View File

@ -15,10 +15,8 @@ function initMultiselect() {
document.addEventListener("click", function (evt) {
var flyoutElement = document.getElementsByClassName("myMultiselect");
var yieldElement = document.getElementById("expandYield");
var targetElement = evt.target; // clicked element
var myMultiselect = false;
var clickedYield = false;
var count = 0;
@ -34,14 +32,9 @@ function initMultiselect() {
myMultiselect = true;
break;
}
if (targetElement == yieldElement) {
clickedYield = true;
break;
}
}
if (myMultiselect || clickedYield)
if (myMultiselect)
break;
// Go up the DOM
@ -52,10 +45,6 @@ function initMultiselect() {
if (!myMultiselect) {
toggleCheckboxArea(true);
}
if (clickedYield)
expandYield();
});
}
@ -154,4 +143,9 @@ function expandYield() {
for (let i = 0; i < yieldDivs.length; i++) {
yieldDivs[i].classList.toggle("hidden");
}
if (source.substring(source.indexOf("Images/") + 7) == "plusIcon.png")
document.getElementById("yieldImage").src = "../Images/minusIcon.png";
else
document.getElementById("yieldImage").src = "../Images/plusIcon.png";
}