Fixed HTR downed tools header, added quarter to date information, and put extended downtime into tool downed tables.

This commit is contained in:
Daniel Wathen 2023-01-12 10:50:10 -07:00
parent 41b98891a8
commit 096043d6ca
13 changed files with 217 additions and 44 deletions

View File

@ -66,10 +66,28 @@ namespace ReportingServices.API.Controllers
return _scrapeDBRepository.GetReactorEvents(startDate, endDate, reactorNumber);
}
[HttpGet("GetLastUpTransaction")]
public int GetLastUpTransaction(string reactorNumber)
{
return _scrapeDBRepository.GetLastUpTransaction(reactorNumber);
}
[HttpGet("ToolEvents")]
public ToolEvent GetLatestToolEvent(string toolID)
{
return _scrapeDBRepository.GetLatestToolEvent(toolID);
}
[HttpGet("GetOutsAndScrapTotals")]
public OutsAndScrapTotal GetOutsAndScrapTotal(string startDate, string endDate)
{
return _scrapeDBRepository.GetOutsAndScrapTotals(startDate, endDate);
}
[HttpGet("GetQuarterStartDate")]
public DateTime GetQuarterStartDate()
{
return _scrapeDBRepository.GetQuarterStartDate();
}
}
}

View File

@ -53,8 +53,8 @@ namespace ReportingServices.Shared.HelperClasses
"SRP"
};
List<Reactor> reactors = ApiCaller.GetApi<List<Reactor>>(baseUrlScrapeDb + "Reactors").Result;
List<Reactor> reactors = new();
Dictionary<string, Task<int>> lastUpTransactions = new();
List<Task<List<ReactorEvent>>> toolEvents = new();
List<Task<ToolEvent>> cleanEvents = new();
List<Task<ToolEvent>> metrologyEvents = new();
@ -63,13 +63,20 @@ namespace ReportingServices.Shared.HelperClasses
Task<YieldInformation> task2 = null;
Task<QuarterlyTargets> targets = null;
Task<List<RDS>> rds = null;
Task<DateTime> task3 = null;
Task<OutsAndScrapTotal> task4 = null;
try
{
reactors = ApiCaller.GetApi<List<Reactor>>(baseUrlScrapeDb + "Reactors").Result;
foreach (Reactor reactor in reactors)
{
toolEvents.Add(ApiCaller.GetApi<List<ReactorEvent>>(baseUrlScrapeDb + "ReactorEvents?startDate=" + report.StartDate.ToString() +
"&endDate=" + DateTime.Now.ToString() + "&reactorNumber=" + reactor.ReactorNumber + "&reactorType=" + reactor.Type));
lastUpTransactions.Add(reactor.ReactorNumber.ToString(),
ApiCaller.GetApi<int>(baseUrlScrapeDb + "GetLastUpTransaction?reactorNumber=" + reactor.ReactorNumber));
}
foreach (string tool in cleanTools)
@ -84,8 +91,11 @@ namespace ReportingServices.Shared.HelperClasses
task1 = ApiCaller.GetApi<YieldInformation>(baseUrlScrapeDb + "ReactorOuts?startDate=" + report.StartDate.ToString() + "&endDate=" + DateTime.Now.ToString());
task2 = ApiCaller.GetApi<YieldInformation>(baseUrlScrapeDb + "ReactorOuts?startDate=" + report.StartDate.AddDays(-7).ToString() + "&endDate=" + report.StartDate.ToString());
task3 = ApiCaller.GetApi<DateTime>(baseUrlScrapeDb + "GetQuarterStartDate");
targets = ApiCaller.GetApi<QuarterlyTargets>(baseUrlScrapeDb + "Targets");
rds = ApiCaller.GetApi<List<RDS>>(baseUrlScrapeDb + "RDS?date=" + report.StartDate.ToString());
task4 = ApiCaller.GetApi<OutsAndScrapTotal>(baseUrlScrapeDb + "GetOutsAndScrapTotals?startDate=" + task3.Result + "&endDate=" + DateTime.Now.ToString());
}
catch (Exception ex)
{
@ -100,9 +110,13 @@ namespace ReportingServices.Shared.HelperClasses
foreach (var task in toolEvents)
{
report.ToolEvents.Add(new ToolEventView(task.Result,
report.StartDate.ToString(), DateTime.Now.ToString(), task.Result[0].REACT_NO,
reactors.FirstOrDefault(x => x.ReactorNumber == int.Parse(task.Result[0].REACT_NO)).Type));
ToolEventView toolEvent = new(task.Result,
report.StartDate.ToString(), DateTime.Now.ToString(), task.Result[0].REACT_NO,
reactors.FirstOrDefault(x => x.ReactorNumber == int.Parse(task.Result[0].REACT_NO)).Type);
toolEvent.SetDowntime(lastUpTransactions[toolEvent.Reactor].Result);
report.ToolEvents.Add(toolEvent);
}
report.ToolEvents = report.ToolEvents
@ -121,6 +135,11 @@ namespace ReportingServices.Shared.HelperClasses
report.CurrentWeek.SetYieldInformation(task1.Result, report.QuarterlyTargets);
report.PreviousWeek.SetYieldInformation(task2.Result, report.QuarterlyTargets);
report.QuarterStartDate = task3.Result;
report.CurrentWeek.QTDOutsAndScrap = task4.Result;
report.PreviousWeek.QTDOutsAndScrap = task4.Result;
}
catch (Exception ex)
{

View File

@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
namespace ReportingServices.Shared.Models.ProductionReport
{
public class OutsAndScrapTotal
{
[JsonPropertyName("Outs")]
public int Outs { get; set; }
[JsonPropertyName("CustomerScrap")]
public int CustomerScrap { get; set; }
[JsonPropertyName("ManufacturingScrap")]
public int ManufacturingScrap { get; set; }
[JsonPropertyName("ProductionScrap")]
public int ProductionScrap { get; set; }
}
}

View File

@ -1,6 +1,7 @@
using Microsoft.Data.SqlClient;
using ReportingServices.Shared.Models.PlanningReport;
using ReportingServices.Shared.Models.ProductionReport;
using System.Collections.Generic;
using System.Data;
namespace ReportingServices.Shared.Repositories
@ -333,7 +334,7 @@ namespace ReportingServices.Shared.Repositories
" (SELECT TOP 1 * FROM REACT_EVENT " +
" WHERE EVENT_DTM < @startDate " +
" AND REACT_NO = @reactorNumber ORDER BY EVENT_DTM DESC) AS tbl1 " +
"ORDER BY EVENT_DTM ASC;";
"ORDER BY EVENT_DTM ASC";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@startDate", startDate);
@ -374,7 +375,7 @@ namespace ReportingServices.Shared.Repositories
" TOOL_MODE_DESC " +
" FROM TOOL_LOG " +
" WHERE TOOL_ID = @toolID " +
"ORDER BY START_DTM DESC;";
"ORDER BY START_DTM DESC";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@toolID", toolID);
@ -397,5 +398,102 @@ namespace ReportingServices.Shared.Repositories
return evnt;
}
public int GetLastUpTransaction(string reactorNumber)
{
int lastTransaction = 0;
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT TOP 1 DATEDIFF(MINUTE,START_DTM,SYSDATETIME()) " +
" FROM REACT_MODE " +
" WHERE REACT_NO = @reactorNumber " +
" AND (MODE = 'UP' OR MODE = 'UP_WITH_INCREASED_SAMPLING') " +
"ORDER BY START_DTM DESC";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@reactorNumber", reactorNumber);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
lastTransaction = int.Parse(reader[0].ToString());
}
cmd.Dispose();
CloseConnection();
return lastTransaction;
}
public OutsAndScrapTotal GetOutsAndScrapTotals(string startDate, string endDate)
{
OutsAndScrapTotal totals = new();
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT SUM(WFRS_OUT) AS OUTS, " +
" SUM(CUST_TOT_REJ) AS CUST, " +
" SUM(LSL_TOT_REJ) AS MANU, " +
" SUM(TW_PROD) AS PROD " +
" FROM RDS " +
" WHERE DATE_OUT >= @startDate " +
" AND DATE_OUT <= @endDate";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("@startDate", startDate);
cmd.Parameters.AddWithValue("@endDate", endDate);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
totals = new()
{
Outs = int.Parse(reader[0].ToString()),
CustomerScrap = int.Parse(reader[1].ToString()),
ManufacturingScrap = int.Parse(reader[2].ToString()),
ProductionScrap = int.Parse(reader[3].ToString()),
};
}
cmd.Dispose();
CloseConnection();
return totals;
}
public DateTime GetQuarterStartDate()
{
DateTime date = new();
OpenConnection();
SqlCommand cmd = _connection.CreateCommand();
string query = "SELECT START_DT " +
" FROM FISCAL_QTR " +
" WHERE START_DT < SYSDATETIME() " +
" AND END_DT > SYSDATETIME()";
cmd.CommandText = query;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
date = DateTime.Parse(reader[0].ToString());
}
cmd.Dispose();
CloseConnection();
return date;
}
}
}

View File

@ -16,5 +16,8 @@ namespace ReportingServices.Shared.Repositories
public List<ReactorOutsByRDS> GetRDSRunBetweenDates(string startDate, string endDate);
public List<ReactorEvent> GetReactorEvents(string startDate, string endDate, string reactorNumber);
public ToolEvent GetLatestToolEvent(string toolID);
public int GetLastUpTransaction(string reactorNumber);
public OutsAndScrapTotal GetOutsAndScrapTotals(string startDate, string endDate);
public DateTime GetQuarterStartDate();
}
}

View File

@ -6,6 +6,7 @@ namespace ReportingServices.Shared.ViewModels.ProductionReport
public class DailyReport
{
public DateTime StartDate { get; set; }
public DateTime QuarterStartDate { get; set; }
public YieldStatistics CurrentWeek { get; set; }
public YieldStatistics PreviousWeek { get; set; }
public List<ToolEventView> ToolEvents { get; set; }

View File

@ -7,9 +7,9 @@ namespace ReportingServices.Shared.ViewModels.ProductionReport
{
public string Reactor { get; set; }
public string Type { get; set; }
public bool DownMoreThanTwelveHours { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public double Downtime { get; set; }
public bool IsInProduction { get; set; }
public List<ReactorEvent> Events { get; set; }
public ReactorEvent MostRecentEvent { get; set; }
@ -24,29 +24,15 @@ namespace ReportingServices.Shared.ViewModels.ProductionReport
Type = type;
MostRecentEvent = events[events.Count - 1];
IsInProduction = EventIsProduction(MostRecentEvent.REACT_MODE);
DownMoreThanTwelveHours = DetermineIfExtendedDowntime();
Uptime = DetermineToolUptimeData();
}
private bool DetermineIfExtendedDowntime()
public void SetDowntime(int timeSinceLastUpTransaction)
{
double numberOfHours = 0;
for (int i = Events.Count - 1; i >= 0; i--)
{
if (EventIsProduction(Events[i].REACT_MODE))
return false;
if (i == Events.Count - 1)
numberOfHours = (DateTime.Now - DateTime.Parse(Events[i].EVENT_DTM)).TotalHours;
else
numberOfHours += (DateTime.Parse(Events[i + 1].EVENT_DTM) - DateTime.Parse(Events[i].EVENT_DTM)).TotalHours;
if (numberOfHours > 12)
return true;
}
return false;
if (IsInProduction)
Downtime = 0;
else
Downtime = (double)timeSinceLastUpTransaction / 60;
}
public List<ToolUptimeData> DetermineToolUptimeData()

View File

@ -7,6 +7,7 @@ namespace ReportingServices.Shared.ViewModels.ProductionReport
public DateTime StartDate { get; set; }
public List<ReactorOutsByDay> OutsByDay { get; set; }
public List<ScrapByDay> ScrapByDay { get; set; }
public OutsAndScrapTotal QTDOutsAndScrap { get; set; }
public int DailyPlanWafers { get; set; }
public bool IsCurrentWeek { get; set; }

View File

@ -15,7 +15,7 @@ namespace ReportingServices.UI.Controllers
public ProductionReportController(ILogger<ProductionReportController> logger)
{
_logger = logger;
_baseDBUrl = "http://localhost:50201/api/";
_baseDBUrl = "https://localhost:7196/api/";
_logger.LogInformation("Base Database Address: {baseUrl}", _baseDBUrl);
}

View File

@ -17,8 +17,6 @@
ManualReportEntries rpt = Model.ManualReportEntries;
string myClass;
List<string> toolsExtendedDown = Model.ToolEvents.Where(x => x.DownMoreThanTwelveHours).Select(x => x.Reactor).ToList();
}
@{
@ -102,7 +100,7 @@
<br /><br />
<h5>Current Reactors Down(@Model.ToolEvents.Where(x => x.IsInProduction == false).Count()):</h5>
<div class="row">
<div class="col-lg-4">
<div class="col-lg-6">
@{
List<ToolEventView> asmTools = Model.ToolEvents.Where(x => x.IsInProduction == false && x.Type.Contains("ASM")).ToList();
}
@ -113,6 +111,7 @@
<th scope="col">Reactor</th>
<th scope="col">Owner</th>
<th scope="col">Issue</th>
<th scope="col">Downtime</th>
</tr>
</thead>
<tbody>
@ -127,10 +126,16 @@
else
owner = "Prod";
<tr>
if (tool.Downtime > 12)
myClass = "tableDowntime";
else
myClass = "";
<tr class="@myClass">
<td>@tool.Reactor</td>
<td>@owner</td>
<td>@tool.MostRecentEvent.COMMENT</td>
<td>@string.Format("{0:##,###.##}", tool.Downtime)</td>
</tr>
}
</tbody>
@ -138,7 +143,7 @@
</div>
</div>
<div class="row">
<div class="col-lg-4">
<div class="col-lg-6">
@{
List<ToolEventView> eppTools = Model.ToolEvents.Where(x => x.IsInProduction == false && x.Type.Contains("EPP")).ToList();
}
@ -149,6 +154,7 @@
<th scope="col">Reactor</th>
<th scope="col">Owner</th>
<th scope="col">Issue</th>
<th scope="col">Downtime</th>
</tr>
</thead>
<tbody>
@ -163,10 +169,16 @@
else
owner = "Prod";
<tr>
if (tool.Downtime > 12)
myClass = "tableDowntime";
else
myClass = "";
<tr class="@myClass">
<td>@tool.Reactor</td>
<td>@owner</td>
<td>@tool.MostRecentEvent.COMMENT</td>
<td>@string.Format("{0:##,###.##}", tool.Downtime)</td>
</tr>
}
</tbody>
@ -174,17 +186,18 @@
</div>
</div>
<div class="row">
<div class="col-lg-4">
<div class="col-lg-6">
@{
List<ToolEventView> htrTools = Model.ToolEvents.Where(x => x.IsInProduction == false && x.Type.Contains("HTR")).ToList();
}
EPP(@htrTools.Count())
HTR(@htrTools.Count())
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Reactor</th>
<th scope="col">Owner</th>
<th scope="col">Issue</th>
<th scope="col">Downtime</th>
</tr>
</thead>
<tbody>
@ -199,14 +212,21 @@
else
owner = "Prod";
<tr>
if (tool.Downtime > 12)
myClass = "tableDowntime";
else
myClass = "";
<tr class="@myClass">
<td>@tool.Reactor</td>
<td>@owner</td>
<td>@tool.MostRecentEvent.COMMENT</td>
<td>@string.Format("{0:##,###.##}", tool.Downtime)</td>
</tr>
}
</tbody>
</table>
<p> *Rows highlighted in orange have been down for more than 12 hours</p>
</div>
</div>
<ul>
@ -230,11 +250,6 @@
<li>EpiPro - @(string.Join(',', Model.DualLayerReactors["EPP"]))</li>
</ul>
</li>
<li>Engineering Focus Tools (Down > 12 hours)
<ul>
<li>@string.Join(",", toolsExtendedDown)</li>
</ul>
</li>
<li>Metrology Down (@Model.MetrologyEvents.Count()):
@if (@Model.MetrologyEvents.Count() > 0)
{

View File

@ -26,6 +26,7 @@
<th scope="col" class="text-center">@Model.StartDate.AddDays(i).ToString("MM/dd/yyyy")</th>
}
<th scope="col" rowspan="2" class="text-center align-middle">Weekly Total</th>
<th scope="col" rowspan="2" class="text-center align-middle">QTD Total</th>
<th scope="col" rowspan="2" class="text-center align-middle">Comment</th>
</tr>
<tr>
@ -49,6 +50,7 @@
<td class="text-center">@string.Format("{0:#,###}", Model.DailyPlanWafers)</td>
<td class="text-center">@string.Format("{0:#,###}", Model.DailyPlanWafers)</td>
<td class="text-center">@string.Format("{0:##,###}", Model.DailyPlanWafers * 7)</td>
<td></td>
<td>Number updated quarterly</td>
</tr>
<tr>
@ -70,6 +72,7 @@
}
}
<td class="text-center">@totalWafersOut</td>
<td class="text-center">@string.Format("{0:###,###}", Model.QTDOutsAndScrap.Outs)</td>
<td>Before Scrap</td>
</tr>
<tr>
@ -95,6 +98,7 @@
}
}
<td class="text-center">@totalYieldedWafersOut</td>
<td class="text-center">@string.Format("{0:###,###}", Model.QTDOutsAndScrap.Outs - Model.QTDOutsAndScrap.CustomerScrap - Model.QTDOutsAndScrap.ManufacturingScrap - Model.QTDOutsAndScrap.ProductionScrap)</td>
<td>After Scrap</td>
</tr>
<tr class="yield hidden">
@ -108,7 +112,7 @@
int averageYieldedOuts = yieldOutDays == 0 ? 0 : modifiedYieldedOuts / yieldOutDays;
}
<td scope="row" colspan="10" id="expandYield" class="text-center">Yielded Wafers Out Daily Average: @(averageYieldedOuts)</td>
<td scope="row" colspan="11" id="expandYield" class="text-center">Yielded Wafers Out Daily Average: @(averageYieldedOuts)</td>
</tr>
<tr class="yield hidden">
<td scope="row">Customer Scrap</td>
@ -128,6 +132,7 @@
}
}
<td class="text-center">@totalCustomerScrap</td>
<td class="text-center">@string.Format("{0:###,###}", Model.QTDOutsAndScrap.CustomerScrap)</td>
<td></td>
</tr>
<tr class="yield hidden">
@ -148,6 +153,7 @@
}
}
<td class="text-center">@totalManufacturingScrap</td>
<td class="text-center">@string.Format("{0:###,###}", Model.QTDOutsAndScrap.ManufacturingScrap)</td>
<td></td>
</tr>
<tr class="yield hidden">
@ -168,6 +174,7 @@
}
}
<td class="text-center">@totalProdScrap</td>
<td class="text-center">@string.Format("{0:###,###}", Model.QTDOutsAndScrap.ProductionScrap)</td>
<td></td>
</tr>
<tr class="yield hidden">
@ -188,6 +195,7 @@
}
}
<td class="text-center">@(string.Format("{0:P2}", (float)(totalWafersOut - totalCustomerScrap - totalManufacturingScrap) / (float)totalWafersOut))</td>
<td class="text-center">@string.Format("{0:P2}", (float)(Model.QTDOutsAndScrap.Outs - Model.QTDOutsAndScrap.ManufacturingScrap - Model.QTDOutsAndScrap.CustomerScrap) / (float)Model.QTDOutsAndScrap.Outs)</td>
<td>After Scrap</td>
</tr>
<tr>
@ -213,6 +221,7 @@
}
}
<td class="text-center">@deltaToCommit</td>
<td></td>
<td>Difference to commitment</td>
</tr>
<tr>
@ -238,6 +247,7 @@
}
}
<td class="text-center">@deltaToPlan</td>
<td></td>
<td>Difference to target</td>
</tr>
<tr>
@ -250,6 +260,7 @@
<td class="text-center">@string.Format("{0:#,###}", Model.DailyPlanWafers)</td>
<td class="text-center">@string.Format("{0:#,###}", Model.DailyPlanWafers)</td>
<td class="text-center">@string.Format("{0:##,###}", Model.DailyPlanWafers * 7)</td>
<td></td>
<td>Number updated weekly</td>
</tr>
</tbody>

View File

@ -1 +1 @@
[{"Date":"2023-01-09T00:00:00-07:00","ASM":8,"HTR":16},{"Date":"2023-01-10T00:00:00-07:00","ASM":8,"HTR":16},{"Date":"2023-01-11T00:00:00-07:00","ASM":8,"HTR":16}]
[{"Date":"2023-01-09T00:00:00-07:00","ASM":8,"HTR":16},{"Date":"2023-01-10T00:00:00-07:00","ASM":8,"HTR":16},{"Date":"2023-01-11T00:00:00-07:00","ASM":8,"HTR":16},{"Date":"2023-01-12T00:00:00-07:00","ASM":7,"HTR":16}]

View File

@ -99,4 +99,9 @@ body {
width: 100%;
margin-bottom: 35px;
padding-top: 10px;
}
.tableDowntime {
color: rgb(212, 111, 35);
background-color: rgba(212, 111, 35, 0.3);
}