Reorganized project structure to separate backend process from frontend process.
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace ReportingServices.Shared.Models.ProductionReport
|
||||
{
|
||||
public class EquipmentStateByDay
|
||||
{
|
||||
public string StartTime { get; set; }
|
||||
public string AvailablePct { get; set; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
11
ReportingServices.Shared/Models/ProductionReport/RDS.cs
Normal file
11
ReportingServices.Shared/Models/ProductionReport/RDS.cs
Normal 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; }
|
||||
}
|
||||
}
|
10
ReportingServices.Shared/Models/ProductionReport/Reactor.cs
Normal file
10
ReportingServices.Shared/Models/ProductionReport/Reactor.cs
Normal 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; }
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace ReportingServices.Shared.Models.ProductionReport
|
||||
{
|
||||
public class ReactorOutsByDay
|
||||
{
|
||||
public string StartDate { get; set; }
|
||||
public int TotalWafers { get; set; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
|
||||
}
|
||||
}
|
13
ReportingServices.Shared/ReportingServices.Shared.csproj
Normal file
13
ReportingServices.Shared/ReportingServices.Shared.csproj
Normal 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>
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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"]);
|
||||
}
|
||||
}
|
||||
}
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user