Reorganized project structure to separate backend process from frontend process.

This commit is contained in:
Daniel Wathen
2022-12-22 12:10:18 -07:00
parent b5def3da89
commit 80696e5fe6
131 changed files with 494 additions and 347 deletions

View File

@ -0,0 +1,109 @@
using System.Web;
namespace ReportingServices.Shared.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.ToString("yyyy-M-d HH:mm:ss");
else
dateString = date.Year + "-" + date.Month + "-" + date.Day + " 0:0:0";
return dateString;
}
public static Dictionary<string, string> SetParameters(string startDate = "", string endDate = "", string chart = "", string periodLen = "",
string areasLike = "", string toolsLike = "", string operationsLike = "", string capacityTypesLike = "")
{
Dictionary<string, string> parameters = new();
startDate = startDate == "" ? HttpUtility.UrlEncode(GetBeginningOfWeekAsAPIString()) : startDate;
endDate = endDate == "" ? HttpUtility.UrlEncode(GetDateTimeAsAPIString(DateTime.Now.ToString(), true)) : endDate;
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 endDate = "", string chart = "", string periodLen = "",
string areasLike = "", string toolsLike = "", string operationsLike = "", string capacityTypesLike = "")
{
Dictionary<string, string> parameters = SetParameters(startDate, endDate, 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

@ -0,0 +1,84 @@
using ReportingServices.Shared.Repositories;
using ReportingServices.Shared.Models.ProductionReport;
using ReportingServices.Shared.ViewModels.ProductionReport;
namespace ReportingServices.Shared.HelperClasses
{
public static class DailyReportHelper
{
private static IFabTimeReportingRepository _fabTimeReportingRepository;
private static IScrapeDatabaseRepository _scrapeDatabaseRepository;
private static readonly string _dailyRptFilePath = "wwwroot/Assets/DailyReportInfo.json";
public static void SetRepositories(IFabTimeReportingRepository fabTimeReportingRepository, IScrapeDatabaseRepository scrapeDatabaseRepository)
{
_fabTimeReportingRepository = fabTimeReportingRepository;
_scrapeDatabaseRepository = scrapeDatabaseRepository;
}
public static DailyReport SetUpDailyReport()
{
List<Task> tasks = new();
DailyReport report = new();
Task<List<ReactorOutsByRDS>> task1 = _fabTimeReportingRepository.GetMovesTrendData();
Task<List<ReactorOutsByRDS>> task2 = _fabTimeReportingRepository.GetMovesTrendData(startDate: report.StartDate.AddDays(-7).ToString(), endDate: report.StartDate.ToString());
tasks.Add(_fabTimeReportingRepository.GetToolStateTrendData(report, "ASM"));
tasks.Add(_fabTimeReportingRepository.GetToolStateTrendData(report, "EPP"));
tasks.Add(_fabTimeReportingRepository.GetToolStateTrendData(report, "HTR"));
tasks.Add(_fabTimeReportingRepository.GetToolStateData(report, "ASM"));
tasks.Add(_fabTimeReportingRepository.GetToolStateData(report, "EPP"));
tasks.Add(_fabTimeReportingRepository.GetToolStateData(report, "HTR"));
tasks.Add(_fabTimeReportingRepository.GetToolStateData(report, "Metrology"));
tasks.Add(_fabTimeReportingRepository.GetToolStateData(report, "Cleans"));
report.QuarterlyTargets = _scrapeDatabaseRepository.GetQuarterlyTargets();
Dictionary<string, List<ManualReportEntries>> entries = JsonFileHandler.LoadJSONFile<Dictionary<string, List<ManualReportEntries>>>(_dailyRptFilePath);
report.CurrentEntries = entries["Current Week"];
report.PreviousEntries = entries["Previous Week"];
report.SetRDSInfo(_scrapeDatabaseRepository.GetRDSForLastDay());
Task.WaitAll(tasks.ToArray());
report.SetReactorInfo(_scrapeDatabaseRepository.GetReactors(), GetUnscheduledReactors(report));
List<ScrapByDay> scrap = _scrapeDatabaseRepository.GetScrapByDay(task1.Result);
List<ScrapByDay> previousScrap = _scrapeDatabaseRepository.GetScrapByDay(task2.Result);
report.CurrentWeek.SetYieldInformation(task1.Result, scrap);
report.PreviousWeek.SetYieldInformation(task2.Result, previousScrap);
report.ReverseLists();
entries["Current Week"] = report.CurrentEntries;
JsonFileHandler.SaveJSONFile(entries, _dailyRptFilePath);
return report;
}
public static List<int> GetUnscheduledReactors(DailyReport report)
{
List<int> reactors = new();
foreach (KeyValuePair<string, ToolStateByType> keyValuePairs in report.ToolStateByType)
{
if (keyValuePairs.Key != "Metrology" && keyValuePairs.Key != "Cleans")
{
foreach (ToolStateCurrent tool in keyValuePairs.Value.ToolStateCurrents)
{
if (tool.BasicStateDescription != "Productive" && tool.ReactorStatus != "Out of Service")
{
reactors.Add(int.Parse(tool.Tool.Substring(1)));
}
}
}
}
return reactors;
}
}
}

View File

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

View File

@ -0,0 +1,9 @@
namespace ReportingServices.Shared.Models.PlanningReport
{
public class ReactorPSNWORuns
{
public string REACTOR { get; set; }
public string PSN { get; set; }
public int WO_COUNT { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace ReportingServices.Shared.Models.PlanningReport
{
public class WeeklyPartChanges
{
public int TotalPartChanges { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public List<ReactorPSNWORuns> ReactorPSNWORuns { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class EquipmentStateByDay
{
public string StartTime { get; set; }
public string AvailablePct { get; set; }
}
}

View File

@ -0,0 +1,27 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class ManualReportEntries
{
public DayOfWeek Day { get; set; }
public DateTime Date { get; set; }
public int OperatorHeadcountDays { get; set; }
public int OperatorHeadcountNights { get; set; }
public int OperatorCallOutsDays { get; set; }
public int OperatorCallOutsNights { get; set; }
public int EngineeringHeadcountDays { get; set; }
public int EngineeringHeadcountNights { get; set; }
public int EngineeringCallOutsDays { get; set; }
public int EngineeringCallOutsNights { get; set; }
public int MaintenanceHeadcountDays { get; set; }
public int MaintenanceHeadcountNights { get; set; }
public int MaintenanceCallOutsDays { get; set; }
public int MaintenanceCallOutsNights { get; set; }
public string BottleChanges { get; set; }
public string DailyPartChanges { get; set; }
public string WeeklyPartChanges { get; set; }
public int ASMSingleLoadLock { get; set; }
public int HTRSingleLoadLock { get; set; }
public int ASMUnloadTempsLessThan700 { get; set; }
public int HTRUnloadTempsLessThan700 { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class QuarterlyTargets
{
public int Reactor_Outs { get; set; }
public int Yield_Outs { get; set; }
public int IFX_Scrap { get; set; }
public float Yield { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class RDS
{
public int Reactor { get; set; }
public string ReactorType { get; set; }
public DateTime DateOut { get; set; }
public int UnloadTemp { get; set; }
public string LayerType { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class Reactor
{
public int ReactorNumber { get; set; }
public string Type { get; set; }
public string PocketSize { get; set; }
public bool HasDisabledLoadlock { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class ReactorOutsByDay
{
public string StartDate { get; set; }
public int TotalWafers { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class ReactorOutsByRDS
{
public string RDS_NO { get; set; }
public string Units { get; set; }
public string EndProcessTime { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class ScrapByDay
{
public string StartDate { get; set; }
public int TW_PROD { get; set; }
public int TOT_REJ_CUST { get; set; }
public int TOT_REJ_MANU { get; set; }
public int TOT_REJ_WFRS { get; set; }
}
}

View File

@ -0,0 +1,15 @@
namespace ReportingServices.Shared.Models.ProductionReport
{
public class ToolStateCurrent
{
public string Tool { get; set; }
public string TranTime { get; set; }
public string GanttEndTime { get; set; }
public string GanttElapsedHours { get; set; }
public string BasicStateDescription { get; set; }
public string SubState { get; set; }
public string ReactorStatus { get; set; }
public string Comment { get; set; }
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.0.1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,60 @@
using ReportingServices.Shared.HelperClasses;
using ReportingServices.Shared.Models.ProductionReport;
using ReportingServices.Shared.ViewModels.ProductionReport;
using System.Text.Json;
using System.Web;
namespace ReportingServices.Shared.Repositories
{
public class FabTimeReportingRepository : IFabTimeReportingRepository
{
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 async Task<List<ReactorOutsByRDS>> GetMovesTrendData(string startDate = "", string endDate = "")
{
string url = APIHelperFunctions.GenerateURLWithParameters(startDate: startDate, endDate: endDate, chart: "MOVESLOTLIST", areasLike: "CLEANROOM", operationsLike: "1UNLOAD");
return await GetJsonData<List<ReactorOutsByRDS>>(url);
}
public async Task GetToolStateTrendData(DailyReport rpt, string toolType)
{
string url = APIHelperFunctions.GenerateURLWithParameters(chart: "TOOLSTATE", periodLen: "24", capacityTypesLike: toolType, toolsLike: _toolFilter);
rpt.AddToolAvailibilityByType(toolType, await GetJsonData<List<EquipmentStateByDay>>(url));
return;
}
public async Task GetToolStateData(DailyReport rpt, 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);
rpt.AddToolStateByType(toolType, await GetJsonData<List<ToolStateCurrent>>(url));
return;
}
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,265 @@
using Microsoft.Data.SqlClient;
using ReportingServices.Shared.Models.PlanningReport;
using ReportingServices.Shared.Models.ProductionReport;
using System.Data;
namespace ReportingServices.Shared.Repositories
{
public class ScrapeDatabaseRepository : IScrapeDatabaseRepository
{
private SqlConnection _connection;
private readonly string _connectionString;
public ScrapeDatabaseRepository()
{
_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
{
StartDate = reader[0].ToString(),
TW_PROD = int.Parse(reader[3].ToString()),
TOT_REJ_CUST = int.Parse(reader[1].ToString()),
TOT_REJ_MANU = int.Parse(reader[2].ToString()),
TOT_REJ_WFRS =
int.Parse(reader[1].ToString()) + int.Parse(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
{
REACTOR = reader[0].ToString(),
PSN = reader[1].ToString(),
WO_COUNT = int.Parse(reader[2].ToString())
});
}
cmd.Dispose();
CloseConnection();
return weeklyPartChanges;
}
public QuarterlyTargets GetQuarterlyTargets()
{
Dictionary<string, float> targets = new();
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT THRU_TARGET, THRU_QTY, THRU_PCNT FROM FISCAL_QTR_TARGETS " +
" WHERE THRU_GROUP = 'TOT' " +
" AND FISCAL_YR = " +
" (SELECT FISCAL_YR FROM FISCAL_QTR " +
" WHERE START_DT < SYSDATETIME() " +
" AND END_DT > SYSDATETIME()) " +
" AND FISCAL_QTR = " +
" (SELECT FISCAL_QTR FROM FISCAL_QTR " +
" WHERE START_DT < SYSDATETIME() " +
" AND END_DT > SYSDATETIME()) ";
cmd.CommandText = query;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
if (reader[0].ToString().ToUpper() == "YIELD")
targets.Add(reader[0].ToString(), float.Parse(reader[2].ToString()));
else if (!string.IsNullOrEmpty(reader[1].ToString()))
targets.Add(reader[0].ToString(), int.Parse(reader[1].ToString()));
}
}
cmd.Dispose();
CloseConnection();
QuarterlyTargets quarterlyTargets = new()
{
Reactor_Outs = (int)targets["Reactor_Outs"],
Yield_Outs = (int)targets["Yield_Outs"],
IFX_Scrap = (int)targets["IFX_Scrap"],
Yield = targets["Yield"]
};
return quarterlyTargets;
}
public List<Reactor> GetReactors()
{
List<Reactor> reactors = new();
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT " +
" REACT_NO, REACT_TYPE, SUSC_POCKET_SIZE, CASE WHEN ACTIVE_LL_DISABLED <> '' THEN 'TRUE' ELSE 'FALSE' END AS \"LL_DISABLED\" " +
" FROM REACTOR " +
" WHERE REACT_ASSIGNMENT IS NOT NULL " +
" AND REACT_ASSIGNMENT <> 'Out of Service' " +
" AND REACT_ASSIGNMENT<> ''";
cmd.CommandText = query;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
reactors.Add(new Reactor
{
ReactorNumber = int.Parse(reader[0].ToString()),
Type = reader[1].ToString(),
PocketSize = reader[2].ToString(),
HasDisabledLoadlock = bool.Parse(reader[3].ToString())
});
}
cmd.Dispose();
CloseConnection();
return reactors;
}
public List<RDS> GetRDSForLastDay()
{
List<RDS> rdsList = new();
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT rds.REACTOR, rds.REACTOR_TYPE, rds.DATE_OUT, " +
"CASE WHEN lay.UL_TEMP IS NULL THEN '1000' ELSE lay.UL_TEMP END, psn.LAYER_TYPE FROM RDS " +
"INNER JOIN RDS_LAYER lay ON lay.RDS_NO = SEQ " +
"INNER JOIN PROD_SPEC psn ON rds.PROD_SPEC_ID = psn.SEQ " +
"WHERE DATE_OUT > DATEADD(DAY, -1, SYSDATETIME())";
cmd.CommandText = query;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
rdsList.Add(new RDS
{
Reactor = int.Parse(reader[0].ToString()),
ReactorType = reader[1].ToString(),
DateOut = DateTime.Parse(reader[2].ToString()),
UnloadTemp = int.Parse(reader[3].ToString()),
LayerType = reader[4].ToString()
});
}
cmd.Dispose();
CloseConnection();
return rdsList;
}
}
}

View File

@ -0,0 +1,13 @@
using ReportingServices.Shared.Models.ProductionReport;
using ReportingServices.Shared.ViewModels.ProductionReport;
namespace ReportingServices.Shared.Repositories
{
public interface IFabTimeReportingRepository
{
public Task<List<ReactorOutsByRDS>> GetMovesTrendData(string startDate = "", string endDate = "");
public Task GetToolStateTrendData(DailyReport rpt, string toolType);
public Task GetToolStateData(DailyReport rpt, string toolType);
public Task<T> GetJsonData<T>(string url);
}
}

View File

@ -0,0 +1,17 @@
using ReportingServices.Shared.Models.PlanningReport;
using ReportingServices.Shared.Models.ProductionReport;
namespace ReportingServices.Shared.Repositories
{
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 QuarterlyTargets GetQuarterlyTargets();
public List<Reactor> GetReactors();
public List<RDS> GetRDSForLastDay();
}
}

View File

@ -0,0 +1,133 @@
using ReportingServices.Shared.HelperClasses;
using ReportingServices.Shared.Models.ProductionReport;
using ReportingServices.Shared.ViewModels.ProductionReport;
namespace ReportingServices.Shared.ViewModels.ProductionReport
{
public class DailyReport
{
public DateTime StartDate { get; set; }
public YieldStatistics CurrentWeek { get; set; }
public YieldStatistics PreviousWeek { get; set; }
public Dictionary<string, List<EquipmentStateByDay>> ToolAvailibilityByType { get; set; }
public Dictionary<string, ToolStateByType> ToolStateByType { get; set; }
public Dictionary<string, List<string>> ToolStatesByOwner { get; set; }
public Dictionary<string, List<int>> DualLayerReactors { get; set; }
public List<ManualReportEntries> PreviousEntries { get; set; }
public List<ManualReportEntries> CurrentEntries { get; set; }
public int NumberOfToolsWaferSize6IN { get; set; }
public int NumberOfToolsWaferSize8IN { get; set; }
public int NumberOfToolsWaferSize6INScheduled { get; set; }
public int NumberOfToolsWaferSize8INScheduled { get; set; }
public QuarterlyTargets QuarterlyTargets { get; set; }
public DailyReport()
{
ToolAvailibilityByType = new();
ToolStateByType = new();
PreviousEntries = new();
CurrentEntries = new();
DualLayerReactors = new();
StartDate = DateTime.Parse(APIHelperFunctions.GetBeginningOfWeekAsAPIString());
CurrentWeek = new(StartDate, true);
PreviousWeek = new(StartDate.AddDays(-7), false);
}
public void AddToolAvailibilityByType(string key, List<EquipmentStateByDay> states)
{
ToolAvailibilityByType.Add(key, states);
}
public void AddToolStateByType(string key, List<ToolStateCurrent> states)
{
ToolStateByType state = new(states);
ToolStateByType.Add(key, state);
}
public void SetReactorInfo(List<Reactor> reactors, List<int> unscheduledReactors)
{
SetToolsByPocketSize(reactors, unscheduledReactors);
SetDisabledLoadlocks(reactors);
}
public void SetRDSInfo(List<RDS> rdsList)
{
SetDualLayerReactors(rdsList);
SetUnloadTempsLessThan700(rdsList);
}
private void SetToolsByPocketSize(List<Reactor> reactors, List<int> unscheduledReactors)
{
NumberOfToolsWaferSize6IN = reactors.Where(react => react.PocketSize.Contains("150")).Count();
NumberOfToolsWaferSize8IN = reactors.Where(react => react.PocketSize.Contains("200")).Count();
NumberOfToolsWaferSize6INScheduled =
reactors.Where(react => !unscheduledReactors.Contains(react.ReactorNumber)
&& react.PocketSize.Contains("150")).Count();
NumberOfToolsWaferSize8INScheduled =
reactors.Where(react => !unscheduledReactors.Contains(react.ReactorNumber)
&& react.PocketSize.Contains("200")).Count();
}
private void SetDisabledLoadlocks(List<Reactor> reactors)
{
List<Reactor> reactorsWithDisabledLoadlocks = reactors.Where(react => react.HasDisabledLoadlock).ToList();
int singleLoadlockASM = reactorsWithDisabledLoadlocks.Where(react => react.Type.Contains("ASM")).Count();
int singleLoadlockHTR = reactorsWithDisabledLoadlocks.Where(react => react.Type.Contains("HTR")).Count();
CurrentEntries[(int)DateTime.Now.DayOfWeek].ASMSingleLoadLock = singleLoadlockASM;
CurrentEntries[(int)DateTime.Now.DayOfWeek].HTRSingleLoadLock = singleLoadlockHTR;
}
private void SetDualLayerReactors(List<RDS> rdsList)
{
List<RDS> rdsWithDualLayerPSN = rdsList.Where(rds => rds.LayerType.Contains("2 Layer")).ToList();
DualLayerReactors.Add("ASM", rdsWithDualLayerPSN.
Where(rds => rds.ReactorType.Contains("ASM")).
OrderBy(rds => rds.Reactor).
Select(rds => rds.Reactor).
Distinct().ToList());
DualLayerReactors.Add("HTR", rdsWithDualLayerPSN.
Where(rds => rds.ReactorType.Contains("HTR")).
OrderBy(rds => rds.Reactor).
Select(rds => rds.Reactor).
Distinct().ToList());
DualLayerReactors.Add("EPP", rdsWithDualLayerPSN.
Where(rds => rds.ReactorType.Contains("EPP")).
OrderBy(rds => rds.Reactor).
Select(rds => rds.Reactor).
Distinct().ToList());
}
private void SetUnloadTempsLessThan700(List<RDS> rdsList)
{
List<RDS> rdsWithTempsLessThan700 = rdsList.Where(rds => rds.UnloadTemp < 700).ToList();
CurrentEntries[(int)DateTime.Now.DayOfWeek].ASMUnloadTempsLessThan700 =
rdsWithTempsLessThan700.
Where(rds => rds.ReactorType.
Contains("ASM")).
Select(rds => rds.Reactor).
Distinct().Count();
CurrentEntries[(int)DateTime.Now.DayOfWeek].HTRUnloadTempsLessThan700 =
rdsWithTempsLessThan700.
Where(rds => rds.ReactorType.
Contains("HTR")).
Select(rds => rds.Reactor).
Distinct().Count();
}
public void ReverseLists()
{
CurrentWeek.ScrapByDay = APIHelperFunctions.ReverseList(CurrentWeek.ScrapByDay);
PreviousWeek.ScrapByDay = APIHelperFunctions.ReverseList(PreviousWeek.ScrapByDay);
ToolAvailibilityByType["ASM"] = APIHelperFunctions.ReverseList(ToolAvailibilityByType["ASM"]);
ToolAvailibilityByType["EPP"] = APIHelperFunctions.ReverseList(ToolAvailibilityByType["EPP"]);
ToolAvailibilityByType["HTR"] = APIHelperFunctions.ReverseList(ToolAvailibilityByType["HTR"]);
}
}
}

View File

@ -0,0 +1,71 @@
using ReportingServices.Shared.Models.ProductionReport;
namespace ReportingServices.Shared.ViewModels.ProductionReport
{
public class ToolStateByType
{
public int DownTools { get; set; }
public int UpTools { get; set; }
public List<ToolStateCurrent> ToolStateCurrents { get; set; }
public List<string> ToolsDownGreaterThan12Hours { get; set; }
public ToolStateByType(List<ToolStateCurrent> toolStateCurrents)
{
ToolStateCurrents = toolStateCurrents;
ToolsDownGreaterThan12Hours = new List<string>();
UpTools = 0;
DownTools = 0;
GetToolsDownGreaterThan12Hours();
GetMostRecentTransactions();
DetermineUpAndDownTools();
}
public void GetMostRecentTransactions()
{
for (int i = ToolStateCurrents.Count - 2; i >= 0; i--)
{
if (ToolStateCurrents[i].Tool == ToolStateCurrents[i + 1].Tool)
ToolStateCurrents.RemoveAt(i);
}
}
public void GetToolsDownGreaterThan12Hours()
{
float elapsedTime = 0f;
if (ToolStateCurrents[^1].BasicStateDescription.ToUpper() is not "PRODUCTIVE" and not "OUT OF SERVICE")
float.Parse(ToolStateCurrents[^1].GanttElapsedHours);
for (int i = ToolStateCurrents.Count - 2; i >= 0; i--)
{
if (ToolStateCurrents[i].Tool == ToolStateCurrents[i + 1].Tool)
{
if (ToolStateCurrents[i].BasicStateDescription.ToUpper() != "PRODUCTIVE" && ToolStateCurrents[^1].BasicStateDescription.ToUpper() != "OUT OF SERVICE")
elapsedTime += float.Parse(ToolStateCurrents[i].GanttElapsedHours);
}
else
{
if (elapsedTime >= 12)
ToolsDownGreaterThan12Hours.Add(ToolStateCurrents[i + 1].Tool);
if (ToolStateCurrents[i].BasicStateDescription.ToUpper() != "PRODUCTIVE" && ToolStateCurrents[^1].BasicStateDescription.ToUpper() != "OUT OF SERVICE")
elapsedTime = float.Parse(ToolStateCurrents[i].GanttElapsedHours);
else
elapsedTime = 0;
}
}
}
public void DetermineUpAndDownTools()
{
foreach (ToolStateCurrent tools in ToolStateCurrents)
{
if (tools.BasicStateDescription == "Productive")
UpTools++;
else if (tools.ReactorStatus != "Out of Service")
DownTools++;
}
}
}
}

View File

@ -0,0 +1,59 @@
using ReportingServices.Shared.Models.ProductionReport;
namespace ReportingServices.Shared.ViewModels.ProductionReport
{
public class YieldStatistics
{
public DateTime StartDate { get; set; }
public List<ReactorOutsByDay> OutsByDay { get; set; }
public List<ScrapByDay> ScrapByDay { get; set; }
public bool IsCurrentWeek { get; set; }
public YieldStatistics(DateTime startDate, bool isCurrentWeek)
{
StartDate = startDate;
IsCurrentWeek = isCurrentWeek;
}
public void SetYieldInformation(List<ReactorOutsByRDS> outs, List<ScrapByDay> scrap)
{
OutsByDay = GetReactorOutsByDay(outs);
ScrapByDay = scrap;
}
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 { StartDate = date, TotalWafers = waferCount });
}
return outsByDay;
}
}
}