using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Transactions; using Dapper; using Fab2ApprovalSystem.Misc; using Fab2ApprovalSystem.Models; using Fab2ApprovalSystem.ViewModels; namespace Fab2ApprovalSystem.DMO; public class MRB_DMO { private readonly AppSettings _AppSettings; private readonly WorkflowDMO wfDMO = new(); private readonly IDbConnection db = new SqlConnection(GlobalVars.DB_CONNECTION_STRING); public MRB_DMO(AppSettings appSettings) => _AppSettings = appSettings; internal MRB InsertMRB(MRB mrb) { DynamicParameters parameters = new(); parameters = new DynamicParameters(); parameters.Add("@MRBNumber", value: mrb.MRBNumber, dbType: DbType.Int32, direction: ParameterDirection.InputOutput); parameters.Add("@OriginatorID", mrb.OriginatorID); db.Execute("MRBInsertItem", parameters, commandType: CommandType.StoredProcedure); mrb.MRBNumber = parameters.Get("@MRBNumber"); return mrb; } internal void UpdateMRB(MRB mrb) { DynamicParameters parameters = new(); using (TransactionScope transanction = new()) { // Lot Disposition parameters = new DynamicParameters(); parameters.Add("@MRBNumber", mrb.MRBNumber); parameters.Add("@Title", mrb.Title); parameters.Add("@MRBRaisedAreaID", mrb.MRBRaisedAreaID); parameters.Add("@Owner", mrb.Owner); parameters.Add("@Tool", mrb.Tool); parameters.Add("@ToolCSV", mrb.ToolCSV); parameters.Add("@NumberOfLotsAffected", mrb.NumberOfLotsAffected); parameters.Add("@Process", mrb.Process); parameters.Add("@CANo", mrb.CANo); parameters.Add("@NumberOfWafersAffected", mrb.NumberOfWafersAffected); parameters.Add("@NumberOfDiesAffected", mrb.NumberOfDiesAffected); parameters.Add("@IssueDescription", mrb.IssueDescription); parameters.Add("@Notes", mrb.Notes); parameters.Add("@IssueDetectedDate", mrb.IssueDetectedDate); parameters.Add("@IssueStartDate", mrb.IssueStartDate); parameters.Add("@IssueEndDate", mrb.IssueEndDate); parameters.Add("@OwnerApprover", mrb.OwnerApprover); parameters.Add("@PEApprover", mrb.PEApprover); parameters.Add("@MFGEngineeringAppover", mrb.MfgEngineeringAppover); parameters.Add("@OtherApprovers", mrb.OtherApprovers); parameters.Add("@YEApprover", mrb.YEApprover); parameters.Add("@QualityApprovers", mrb.QualityApprovers); parameters.Add("@DetailsFolder", mrb.DetailsFolder); parameters.Add("@CustomerImpacted", mrb.CustomerImpacted); db.Execute("MRBUpdateItem", parameters, commandType: CommandType.StoredProcedure); List moduleIDs = mrb.ModuleIDs; if (moduleIDs != null) { parameters = new DynamicParameters(); parameters.Add("@MRBNumber", mrb.MRBNumber); db.Execute("MRBDeleteModulesByMRB", parameters, commandType: CommandType.StoredProcedure); foreach (int moduleID in moduleIDs) { parameters = new DynamicParameters(); parameters.Add("@MRBNumber", mrb.MRBNumber); parameters.Add("@ModuleID", moduleID); db.Execute("MRBInsertModulesByMRB", parameters, commandType: CommandType.StoredProcedure); } } List partGroupIDs = mrb.PartGroupIDs; if (partGroupIDs != null) { parameters = new DynamicParameters(); parameters.Add("@MRBNumber", mrb.MRBNumber); db.Execute("MRBDeletePartGroupsAffected", parameters, commandType: CommandType.StoredProcedure); foreach (int partGroupID in partGroupIDs) { parameters = new DynamicParameters(); parameters.Add("@MRBNumber", mrb.MRBNumber); parameters.Add("@PartGroupID", partGroupID); db.Execute("MRBInsertPartGroupsAffected", parameters, commandType: CommandType.StoredProcedure); } } List riskAssessmentIDs = mrb.RiskAssessmentIDs; if (riskAssessmentIDs != null) { parameters = new DynamicParameters(); parameters.Add("@MRBNumber", mrb.MRBNumber); db.Execute("MRBDeleteRiskAssessmentsByMRB", parameters, commandType: CommandType.StoredProcedure); foreach (int riskAssessmentID in riskAssessmentIDs) { parameters = new DynamicParameters(); parameters.Add("@MRBNumber", mrb.MRBNumber); parameters.Add("@RiskAssessmentID", riskAssessmentID); db.Execute("MRBInsertRiskAssessmentsByMRB", parameters, commandType: CommandType.StoredProcedure); } } //List dispositionIDs = mrb.DispositionIDs; //if (dispositionIDs != null) //{ // parameters = new DynamicParameters(); // parameters.Add("@MRBNumber", mrb.MRBNumber); // this.db.Execute("MRBDeleteDispositionsByMRB", parameters, commandType: CommandType.StoredProcedure); // foreach (int dispositionID in dispositionIDs) // { // parameters = new DynamicParameters(); // parameters.Add("@MRBNumber", mrb.MRBNumber); // parameters.Add("@DispositionID", dispositionID); // this.db.Execute("MRBInsertDispositionsByMRB", parameters, commandType: CommandType.StoredProcedure); // } //} transanction.Complete(); } } internal MRB GetMRBItem(int mrbNumber, out int isITAR, int userID) { //IsITAR // 0 = false // 1 = true // 2 = not required isITAR = 2; MRB mrbItem = new(); DynamicParameters parameters = new(); parameters.Add("@MRBNumber", value: mrbNumber); parameters.Add("@UserID", userID); parameters.Add("@IsITAR", value: isITAR, dbType: DbType.Int32, direction: ParameterDirection.InputOutput); using (var multipleResultItems = db.QueryMultiple("MRBGetItem", parameters, commandType: CommandType.StoredProcedure)) { mrbItem = multipleResultItems.Read().SingleOrDefault(); List partGroupIDs = multipleResultItems.Read().ToList(); if (mrbItem != null && partGroupIDs != null) { mrbItem.PartGroupIDs.AddRange(partGroupIDs); } List moduleIDs = multipleResultItems.Read().ToList(); if (mrbItem != null && moduleIDs != null) { mrbItem.ModuleIDs.AddRange(moduleIDs); } List dispositionIDs = multipleResultItems.Read().ToList(); if (mrbItem != null && dispositionIDs != null) { mrbItem.DispositionIDs.AddRange(dispositionIDs); } List riskAssessmentIDs = multipleResultItems.Read().ToList(); if (mrbItem != null && riskAssessmentIDs != null) { mrbItem.RiskAssessmentIDs.AddRange(riskAssessmentIDs); } isITAR = parameters.Get("@IsITAR"); } return mrbItem; } internal List GetModules() { List modules = db.Query("MRBGetModules", null, commandType: CommandType.StoredProcedure).ToList(); return modules; } internal List GetPartGroups() { List partGroup = db.Query("MRBGetPartGroups", null, commandType: CommandType.StoredProcedure).ToList(); return partGroup; } internal List GetRiskAssessments() { List riskAssessment = db.Query("MRBGetRiskAssessments", null, commandType: CommandType.StoredProcedure).ToList(); return riskAssessment; } internal void InsertDisposition(Disposition model) { DynamicParameters parameters = new(); parameters.Add("@DispositionID", model.DispositionID, DbType.Int32, direction: ParameterDirection.InputOutput); parameters.Add("@MRBNumber", model.MRBNumber); parameters.Add("@DispositionType", model.DispositionType); parameters.Add("@DispositionName", model.DispositionName); parameters.Add("@DispositionNotes", model.DispositionNotes); parameters.Add("@CloseToQDBOptionID", (model.CloseToQDBOption == null ? 0 : model.CloseToQDBOption.CloseToQDBOptionID)); db.Execute("MRBInsertDispositionBYMRB", parameters, commandType: CommandType.StoredProcedure); int id = parameters.Get("@DispositionID"); model.DispositionID = id; } internal IEnumerable GetDispositions(int mrbNumber) { //var disposition = this.db.Query("MRBGetDispositionsByMRB", new { @MRBNumber = mrbNumber }, commandType: CommandType.StoredProcedure).ToList(); // StringBuilder sql = new StringBuilder(); db.Open(); List disposition = db.Query ( "MRBGetDispositionsByMRB", (dispo, closeToQDBOption) => { dispo.CloseToQDBOption = closeToQDBOption; return dispo; }, new { @MRBNumber = mrbNumber }, commandType: CommandType.StoredProcedure, splitOn: "CloseToQDBOptionID" ).OrderBy(d => d.DispositionType).ToList(); return disposition; } /// internal void UpdateDisposition(Disposition model) { DynamicParameters parameters = new(); parameters.Add("@DispositionID", model.DispositionID); parameters.Add("@DispositionType", model.DispositionType); parameters.Add("@DispositionName", model.DispositionName); parameters.Add("@DispositionNotes", model.DispositionNotes); parameters.Add("@CloseToQDBOptionID", model.CloseToQDBOption.CloseToQDBOptionID); db.Execute("MRBUpdateDispositionByMRB", parameters, commandType: CommandType.StoredProcedure); } internal void UpdateLotDispoType(int mrbNumber, string lotNumber, char? dispoType) { DynamicParameters parameters = new(); parameters.Add("@MRBNumber", mrbNumber); parameters.Add("@LotNumber", lotNumber); parameters.Add("@DispoType", dispoType); db.Execute("MRBUpdateLotDispoType", parameters, commandType: CommandType.StoredProcedure); } internal void DeleteDisposition(Disposition model) { DynamicParameters parameters = new(); parameters.Add("@DispositionID", model.DispositionID); db.Execute("MRBDeleteDisposition", parameters, commandType: CommandType.StoredProcedure); } internal IEnumerable GetMRBLots(int mrbNumber) { DynamicParameters parameters = new(); parameters.Add("@MRBNumber", value: mrbNumber); List data = db.Query("MRBGetLots", parameters, commandType: CommandType.StoredProcedure).ToList(); return data; } internal IEnumerable GetMRBHoldFlagReport(int mrbNumber) { //db.Open(); string sql = "SELECT * FROM MRBHoldFlagReport WHERE MRBNumber = @MRBNumber ORDER BY LotNo"; List data = db.Query(sql, new { MRBNumber = mrbNumber }).ToList(); return data; } internal IEnumerable GetMRHoldFlagSentHistory(int mrbNumber) { //db.Open(); string sql = "SELECT * FROM MRBLotsToBeSentToSPN WHERE MRBNumber = @MRBNumber ORDER BY LotNumber"; List data = db.Query(sql, new { MRBNumber = mrbNumber }).ToList(); return data; } internal IEnumerable GetTools() => //return db.Query("SELECT DISTINCT RTRIM(WO_STATION_ID) AS ToolID from vFAB2SPN_WO_RECORD ORDER BY 1").ToList(); db.Query("SELECT 'NA', '1' UNION SELECT DISTINCT LTRIM(RTRIM(ToolID)),LTRIM(RTRIM(ToolID)) FROM [TEMIRWAP019].[SPNPDB].[dbo].[tblToolGroups2] ORDER BY 2").ToList(); internal MRB GetToolIssueStartEndDateData(int mrbNumber, IDbTransaction dbTrans = null) { var tempMRBInfo = db.Query( "SELECT ToolCSV, IssueStartDate, IssueEndDate FROM MRB WHERE MRBNumber = @mrbNo", new { mrbNo = mrbNumber }).First(); var tools = ((string)tempMRBInfo.ToolCSV).Split(','); DateTime? issueStartDate = tempMRBInfo.IssueStartDate; DateTime? issueEndDate = tempMRBInfo.IssueEndDate; if (issueStartDate.HasValue == false) throw new Exception("MRB Issue Start Date cannot be blank"); if (issueEndDate.HasValue == false) throw new Exception("MRB Issue End Date cannot be blank"); MRB mrbData = new() { MRBNumber = mrbNumber, ToolCSV = tempMRBInfo.ToolCSV, IssueStartDate = tempMRBInfo.IssueStartDate, IssueEndDate = tempMRBInfo.IssueEndDate }; return mrbData; } /// /// Update the first time the LotSplit Analysis was executed /// This will be used while running the Lot Split Analysis again in order to get the child lots /// that were not found during the first lot split analysis /// internal void UpdateLastLotSplitAnalysisTime(int mrbNumber) { DynamicParameters parameters = new(); parameters.Add("@MRBNumber", mrbNumber); db.Execute("MRBUpdateLastLotSplitAnalysisTime", parameters, commandType: CommandType.StoredProcedure); } internal bool InsertLotSplitsAffectedByIncident(int mrbNumber, string incidentLotNo, string toolCSV, DateTime? issueStartDate, DateTime? issueEndDate) { var analysisTime = DateTime.Now; // get mrb info //var mrbInfo = db.Query( // "SELECT ToolCSV, IssueStartDate, IssueEndDate FROM MRB WHERE MRBNumber = @mrbNo", // new { mrbNo = mrbNumber }).First(); //var tools = ((string)mrbInfo.ToolCSV).Split(','); //DateTime? issueStartDate = mrbInfo.IssueStartDate; //DateTime? issueEndDate = mrbInfo.IssueEndDate; //if (issueStartDate.HasValue == false) throw new Exception("MRB Issue Start Date cannot be blank"); //if (issueEndDate.HasValue == false) throw new Exception("MRB Issue End Date cannot be blank"); // search WO for MRB tools between incident start+end to find the earliest WO record for this lot and use the Out time DateTime? incidentTime = null; var tools = toolCSV.Split(','); if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") { incidentTime = db.Query( "SELECT MIN(OutTime) FROM WO_RECORD_MJ " + //"SELECT MIN(OutTime) FROM vFAB2SPN_WO_RECORD " + "WHERE WO_LOT_NO = @LotNo " + "AND WO_STATION_ID IN @Tools " + "AND (InTime BETWEEN @StartDate AND @EndDate " + "OR OutTime BETWEEN @StartDate AND @EndDate)", new { LotNo = incidentLotNo, Tools = tools, StartDate = issueStartDate.Value, EndDate = issueEndDate.Value }).FirstOrDefault(); if (incidentTime == null) return false; } else { incidentTime = db.Query( "SELECT MIN(OutTime) FROM vFAB2SPN_WO_RECORD " + "WHERE WO_LOT_NO = @LotNo " + "AND WO_STATION_ID IN @Tools " + "AND (InTime BETWEEN @StartDate AND @EndDate " + "OR OutTime BETWEEN @StartDate AND @EndDate)", new { LotNo = incidentLotNo, Tools = tools, StartDate = issueStartDate.Value, EndDate = issueEndDate.Value }).FirstOrDefault(); if (incidentTime == null) return false; } // run proc string parmsXML = new System.Xml.Linq.XElement("IssueStartDate", issueStartDate).ToString() + new System.Xml.Linq.XElement("IssueEndDate", issueEndDate).ToString() + //new System.Xml.Linq.XElement("ToolCSV", (string)mrbInfo.ToolCSV).ToString(); new System.Xml.Linq.XElement("ToolCSV", toolCSV).ToString(); IEnumerable analysisResults = null; if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") { analysisResults = db.Query( "AnalyzeLotAncestry_TEST", //"AnalyzeLotAncestry", new { LotNo = incidentLotNo, IncidentTime = incidentTime, LogIssueID = mrbNumber, LogDocumentType = (int)GlobalVars.DocumentType.MRB, LogParms = parmsXML, AnalysisType = "A" }, commandType: CommandType.StoredProcedure); } else { analysisResults = db.Query( "AnalyzeLotAncestry", new { LotNo = incidentLotNo, IncidentTime = incidentTime, LogIssueID = mrbNumber, LogDocumentType = (int)GlobalVars.DocumentType.MRB, LogParms = parmsXML, AnalysisType = "A" }, commandType: CommandType.StoredProcedure); } var dbTrans = db.BeginTransaction(); try { // insert lots foreach (var result in analysisResults) { if ((result.IsAffected.HasValue) && (result.IsAffected.Value)) { if (db.Query( "SELECT COUNT(*) FROM MRBLot WHERE LotNumber = @LotNo AND MRBNumber = @MRBNumber", new { LotNo = result.LotNo, MRBNumber = mrbNumber }, dbTrans).Single() == 0) { bool existingRowUpdated; Lot lot = new(); lot.MRBNumber = mrbNumber; lot.LotNumber = result.LotNo; lot.SourceLot = result.ParentLotNo; lot.SourceAction = result.ActionType; lot.SourceActionTime = result.ActionTime; MiscDMO.GetLotInformation(lot); if (string.Equals(lot.Status?.TrimEnd(), "Z", StringComparison.OrdinalIgnoreCase)) continue; // skip lots with Z status InsertLot(lot, false, out existingRowUpdated, dbTrans); // set special fields to show lot's source db.Execute( "UPDATE MRBLot " + "SET LotSplitAnalysisTime = @AnalysisTime, " + " SourceLot = @SourceLot, SourceAction = @SourceAction, SourceActionTime = @SourceActionTime " + "WHERE LotNumber = @LotNo AND MRBNumber = @MRBNumber", new { LotNo = result.LotNo, MRBNumber = mrbNumber, AnalysisTime = analysisTime, SourceLot = result.ParentLotNo, SourceAction = result.ActionType, SourceActionTime = result.ActionTime }, dbTrans); } } } // update source lot with analysis timestamp db.Execute( "UPDATE MRBLot SET LotSplitAnalysisTime = @AnalysisTime WHERE LotNumber = @LotNo AND MRBNumber = @MRBNumber", new { AnalysisTime = analysisTime, LotNo = incidentLotNo, MRBNumber = mrbNumber }, dbTrans); // Update the Parent Lot Numbers in table which stores the records to be sent to SPN db.Execute( "UPDATE MS SET ParentLotNumber = M.SourceLot " + "FROM MRBLotsToBeSentToSPN MS INNER JOIN MRBLot M " + "ON MS.MRBNumber = M.MRBNumber AND MS.LotNumber = M.LotNumber " + "WHERE MS.MRBNumber = @MRBNumber", new { MRBNumber = mrbNumber }, dbTrans); dbTrans.Commit(); return true; } catch { dbTrans.Rollback(); throw; } } /// internal bool IsLotSentToSPN(string lotNumber, int mrbNumber, IDbTransaction dbTrans) { DynamicParameters parameters = new(); parameters.Add("@LotNumber", lotNumber); parameters.Add("@MRBNumber", mrbNumber); parameters.Add("@LotSentToSPN", dbType: DbType.Boolean, direction: ParameterDirection.Output); db.Execute("MRBIsLotSentToSPN", parameters, commandType: CommandType.StoredProcedure, transaction: dbTrans); bool lotSentToSPN = parameters.Get("@LotSentToSPN"); return lotSentToSPN; } /// /// Get all Lots that are added to the MRB, to find any new splits /// since the last Lot Analysis or since the last time the lot was added to MRB /// internal IEnumerable GetLotsToFindNewChildLots(int mrbNumber) { DynamicParameters parameters = new(); parameters.Add("@MRBNumber", mrbNumber); IEnumerable mrbLot = db.Query( "SELECT MRBNumber, LotNumber, DispoType, IsDirty FROM MRBLotsToBeSentToSPN " + "WHERE MRBNumber = @MRBNumber ORDER BY LotNumber", //"WHERE IsDirty = 1 AND MRBNumber = @MRBNumber ORDER BY LotNumber", //"WHERE MRBNumber = @MRBNumber AND LotNumber LIKE 'A400612%' ORDER BY LotNumber", new { MRBNumber = mrbNumber }); return mrbLot; } /// /// This routine will get all the child lots that are not in the MRB system /// ====================================================================================== /// VERY IMPORTANT NOTE IN THE NEXT LINE /// This routine will get the lots that were SPLIT in SPN after the "First time the lot was Analysis time" /// ====================================================================================== /// This routine will then set the new Dispo Type for all these child Lots before sending it to SPN /// NOTE: the child lots will not be uploaded into the MRBLot table /// internal bool ChildLotsUpdateInSPNWithNewDispoType(Lot parentLot, MRB mrb) { //db.Open(); //var dbTrans = db.BeginTransaction(); var analysisTime = DateTime.Now; DateTime? incidentTime = null; //var tools = ((string)mrb.ToolCSV).Split(','); //This is the "time", when the lot was first uploaded into the system //Get the child lots that were split after this datetime incidentTime = db.Query( "SELECT InsertDateTimeStamp FROM MRBLot " + "WHERE MRBNumber = @MRBNumber AND LotNumber = @LotNumber", new { MRBNumber = parentLot.MRBNumber, LotNumber = parentLot.LotNumber }).FirstOrDefault(); if (incidentTime == null) return false; // run proc string parmsXML = new System.Xml.Linq.XElement("IssueStartDate", mrb.IssueStartDate).ToString() + new System.Xml.Linq.XElement("IssueEndDate", mrb.IssueEndDate).ToString() + new System.Xml.Linq.XElement("ToolCSV", mrb.ToolCSV).ToString(); List analysisResults; if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") { analysisResults = db.Query( "AnalyzeLotAncestry_TEST", //"AnalyzeLotAncestry", new { LotNo = parentLot.LotNumber, IncidentTime = incidentTime, LogIssueID = parentLot.MRBNumber, LogDocumentType = (int)GlobalVars.DocumentType.MRB, LogParms = parmsXML, AnalysisType = "S" }, commandType: CommandType.StoredProcedure).ToList(); } else { analysisResults = db.Query( "AnalyzeLotAncestry", new { LotNo = parentLot.LotNumber, IncidentTime = incidentTime, LogIssueID = parentLot.MRBNumber, LogDocumentType = (int)GlobalVars.DocumentType.MRB, LogParms = parmsXML, AnalysisType = "S" }, commandType: CommandType.StoredProcedure).ToList(); } if (db.State == ConnectionState.Closed) db.Open(); var dbTrans = db.BeginTransaction(); //var newAnalysisResults = from r in analysisResults // where r.IsAffected.HasValue && r.IsAffected == true // select r; IEnumerable newAnalysisResults = analysisResults.Where(r => r.IsAffected.HasValue && r.IsAffected == true).ToList(); try { // insert lots foreach (var result in newAnalysisResults) { if ((result.IsAffected.HasValue) && (result.IsAffected.Value)) { // do not include the lots that are present in the MRB System if ( (db.Query( "SELECT COUNT(*) FROM MRBLot WHERE LotNumber = @LotNo AND MRBNumber = @MRBNumber", new { LotNo = result.LotNo, MRBNumber = parentLot.MRBNumber }, dbTrans).Single() == 0) && // check for the lots in the MRBLotsToBeSentToSPN table, // that were record from the MRBLot record table (db.Query( "SELECT COUNT(*) FROM MRBLotsToBeSentToSPN WHERE LotNumber = @LotNo AND MRBNumber = @MRBNumber AND AddRemoveChangeMRBFlag = @AddRemoveChangeMRBFlag", new { LotNo = result.LotNo, MRBNumber = parentLot.MRBNumber, AddRemoveChangeMRBFlag = 'R' }, dbTrans).Single() == 0) ) { result.ParentLotNo = result.ParentLotNo == "" ? result.LotNo : result.ParentLotNo; bool existingRowUpdated; Lot lot = new(); lot.MRBNumber = parentLot.MRBNumber; lot.LotNumber = result.LotNo; lot.SourceLot = result.ParentLotNo; lot.SourceAction = result.ActionType; lot.SourceActionTime = result.ActionTime; MiscDMO.GetLotInformation(lot); if (string.Equals(lot.Status?.TrimEnd(), "Z", StringComparison.OrdinalIgnoreCase)) continue; // skip lots with Z status // check if // Insert INTo TABLE MRBLotsToBeSentToSPN // Do NOT Insert into the Lot table // Only insert into the MRBLotsToBeSentToSPN, which is the table that consist of Lot that needs to have an MRB Flag // Lot Dispo will pick up the MRB to associate the Lot Dispo with an MRB from this table and the MRBLot table InsertChildLot_NotInTheMRB(result.ParentLotNo, result.LotNo, parentLot.MRBNumber, parentLot.DispoType, parentLot.IsDirty, dbTrans); } } } dbTrans.Commit(); return true; } catch { dbTrans.Rollback(); throw; } } internal void InsertChildLot_NotInTheMRB(string parentLotNumber, string lotNumber, int mrbNumber, char? dispoType, bool parentIsDirty, IDbTransaction dbTransaction = null) { DynamicParameters parameters = new(); parameters.Add("@LotNumber", lotNumber); parameters.Add("@MRBNumber", mrbNumber); parameters.Add("@DispoType", dispoType); parameters.Add("@ParentIsDirty", parentIsDirty); parameters.Add("@ParentLotNumber", parentLotNumber); db.Execute("MRBInsertChildLot_NotInTheMRB", parameters, commandType: CommandType.StoredProcedure, transaction: dbTransaction); } internal bool DoesMRBLotExist(string lotNumber) { string tempLotNumber; if (lotNumber.IndexOf('/') >= 0) { tempLotNumber = lotNumber.Substring(0, lotNumber.IndexOf('/')); } else tempLotNumber = lotNumber; DynamicParameters parameters = new(); parameters.Add("@LotNumber", tempLotNumber); parameters.Add("@MRBLotCount", dbType: DbType.Int32, direction: ParameterDirection.Output); db.Execute("MRBLotExists", parameters, commandType: CommandType.StoredProcedure); int mrbLotCount = parameters.Get("@MRBLotCount"); return mrbLotCount > 0; } internal int InsertLot(Lot lot, bool getLotInfo, out bool existingRowUpdated, IDbTransaction dbTransaction = null) { if (getLotInfo) { char? dispoType = lot.DispoType; MiscDMO.GetLotInformation(lot); if (dispoType.HasValue) { lot.DispoType = dispoType; } } DynamicParameters parameters = new(); parameters.Add("@LotID", value: lot.LotID, dbType: DbType.Int32, direction: ParameterDirection.InputOutput); parameters.Add("@LotNumber", lot.LotNumber); parameters.Add("@Status", lot.Status); parameters.Add("@DispoType", lot.DispoType); parameters.Add("@DieLotNumber", lot.DieLotNumber); parameters.Add("@MRBNumber", lot.MRBNumber); parameters.Add("@Description", lot.Description); parameters.Add("@NewPartNo", lot.NewPartNo); parameters.Add("@WipPartNo", lot.WipPartNo); parameters.Add("@DiePartNo", lot.DiePartNo); parameters.Add("@ProductFamily", lot.ProductFamily); parameters.Add("@Gen", lot.Gen); parameters.Add("@Channel", lot.Channel); parameters.Add("@Hexsize", lot.Hexsize); parameters.Add("@Voltage", lot.Voltage); parameters.Add("@WaferCount", lot.WaferCount); parameters.Add("@DieCount", lot.DieCount); parameters.Add("@Location", lot.Location); parameters.Add("@TotalCost", lot.TotalCost); parameters.Add("@QualityCode", lot.QualityCode); parameters.Add("@ExistingRowUpdated", dbType: DbType.Boolean, direction: ParameterDirection.Output); db.Execute("MRBInsertLot", parameters, commandType: CommandType.StoredProcedure, transaction: dbTransaction); int lotID = parameters.Get("@LotID"); existingRowUpdated = parameters.Get("@ExistingRowUpdated"); return lotID; } internal void UpdateMRBLot(Lot lot) { db.Open(); var dbTrans = db.BeginTransaction(); try { DynamicParameters parameters = new(); parameters.Add("@LotID", lot.LotID); parameters.Add("@LotNumber", lot.LotNumber); parameters.Add("@DieLotNumber", lot.DieLotNumber); parameters.Add("@DispoType", lot.DispoType); parameters.Add("@IssueID", lot.MRBNumber); parameters.Add("@Description", lot.Description); parameters.Add("@NewPartNo", lot.NewPartNo); parameters.Add("@WipPartNo", lot.WipPartNo); parameters.Add("@DiePartNo", lot.DiePartNo); parameters.Add("@ProductFamily", lot.ProductFamily); parameters.Add("@Gen", lot.Gen); parameters.Add("@Channel", lot.Channel); parameters.Add("@Hexsize", lot.Hexsize); parameters.Add("@Voltage", lot.Voltage); parameters.Add("@WaferCount", lot.WaferCount); parameters.Add("@DieCount", lot.DieCount); parameters.Add("@Location", lot.Location); parameters.Add("@TotalCost", lot.TotalCost); db.Execute("MRBUpdateLot", parameters, commandType: CommandType.StoredProcedure, transaction: dbTrans); ////routine to cascade the "dispo type" to all the child lots in SPN (Lot that are not present in FAb App Sys,) //MRB mrbInfo = GetToolIssueStartEndDateData(lot.MRBNumber, dbTrans); //if (!mrbInfo.ToolCSV.ToUpper().Equals("NA")) //{ // bool existingLotUpdated; // Lot l = new Lot(); // l.LotNumber = lot.LotNumber; // if (lot.DispoType.ToString().Trim().Length == 1) // { // l.DispoType = lot.DispoType; // } // l.MRBNumber = lot.MRBNumber; // // check if the lot was sent to SPN // bool lotSentToSPN = IsLotSentToSPN(l.LotNumber, l.MRBNumber, dbTrans); // //only get the child lots if it has been sent to SPN to set the MRB Flag // if (lotSentToSPN) // { // if (!GetChildLotsFromSPNForDispoTypeUpdate(lot.MRBNumber, lot.LotNumber, mrbInfo.ToolCSV, mrbInfo.IssueStartDate, mrbInfo.IssueEndDate, lot.DispoType, dbTrans)) // { // //warnings.AppendFormat("Lot number {0} is not affected by these tools and issue start/end time.\n", l.LotNumber); // } // } //} dbTrans.Commit(); } catch { dbTrans.Rollback(); throw; } } internal void DeleteMRBLot(int lotID) { DynamicParameters parameters = new(); parameters.Add("@LotID", lotID); db.Execute("MRBDeleteLot", parameters, commandType: CommandType.StoredProcedure); } internal void DeleteAllMRBLot(int mrbNumber) { DynamicParameters parameters = new(); parameters.Add("@MRBNumber", mrbNumber); db.Execute("MRBDeleteAllLots", parameters, commandType: CommandType.StoredProcedure); } internal void DeleteMRB(int mrbNumber) { DynamicParameters parameters = new(); parameters.Add("@MRBNumber", mrbNumber); db.Execute("MRBDelete", parameters, commandType: CommandType.StoredProcedure); } internal IEnumerable GetMRBAttachments(int mrbNumber) { StringBuilder sql = new(); sql.Append("SELECT A.AttachmentID, A.MRBNumber, A.FileName, A.UserID, CONVERT(VARCHAR(10), A.UploadDate, 101) AS UploadDate, "); sql.Append("U.FirstName + ' ' + U.LastName AS FullName, A.Path "); sql.Append("FROM MRBAttachment A INNER JOIN Users U ON A.UserID = U.UserID "); sql.Append("WHERE MRBNumber = @MRBNumber "); List attachments = db.Query(sql.ToString(), new { MRBNumber = mrbNumber }).ToList(); return attachments; } public MRBAttachment GetMRBAttachment(int attachmentID) { StringBuilder sql = new(); sql.Append("SELECT A.AttachmentID, A.MRBNumber, A.FileName, A.UserID, CONVERT(VARCHAR(10), A.UploadDate, 101) AS UploadDate, "); sql.Append("U.FirstName + ' ' + U.LastName AS FullName, A.Path "); sql.Append("FROM MRBAttachment A INNER JOIN Users U ON A.UserID = U.UserID "); sql.Append("WHERE A.AttachmentID = @AttachmentID "); return db.Query(sql.ToString(), new { AttachmentID = attachmentID }).SingleOrDefault(); } //internal IEnumerable GetMRBAttachmentsByFilename(string fileName) //{ // StringBuilder sql = new StringBuilder(); // sql.Append("SELECT A.AttachmentID, A.MRBNumber, A.FileName, A.UserID, CONVERT(VARCHAR(10), A.UploadDate, 101) AS UploadDate, "); // sql.Append("U.FirstName + ' ' + U.LastName AS FullName "); // sql.Append("FROM MRBAttachment A INNER JOIN Users U ON A.UserID = U.UserID "); // sql.Append("WHERE A.Filename = @filename"); // var attachments = this.db.Query(sql.ToString(), new { filename = fileName }).ToList(); // return attachments; //} internal void DeleteMRBAttachment(int attachmentID) { DynamicParameters parameters = new(); parameters.Add("@AttachmentID", attachmentID); db.Execute("MRBDeleteAttachment", parameters, commandType: CommandType.StoredProcedure); } internal void InsertMRBAttachment(MRBAttachment attach) { DynamicParameters parameters = new(); parameters.Add("@MRBNumber", attach.MRBNumber); parameters.Add("@UserID", attach.UserID); parameters.Add("@FileName", attach.FileName); parameters.Add("@Path", attach.Path); db.Execute("MRBInsertAttachment", parameters, commandType: CommandType.StoredProcedure); } internal IEnumerable GetContainmentActions(int mrbNumber) { //db.Open(); //string sql = "SELECT * FROM MRBContainmentAction WHERE MRBNumber = " + mrbNumber; //var data = this.db.Query(sql).ToList(); DynamicParameters parameters = new(); parameters.Add("@MRBNumber", mrbNumber); List data = db.Query("MRBGetContainmentActions", parameters, commandType: CommandType.StoredProcedure).ToList(); return data; } internal void InsertContainmentAction(ContainmentActionObj model) { DynamicParameters parameters = new(); parameters.Add("@ContainmentActionID", model.ContainmentActionID, DbType.Int32, direction: ParameterDirection.InputOutput); parameters.Add("@MRBNumber", model.MRBNumber); parameters.Add("@ContainmentAction", model.ContainmentAction); //parameters.Add("@ResponsibilityOwner", model.ResponsibilityOwner); parameters.Add("@ResponsibilityOwnerID", model.ResponsibilityOwnerID); parameters.Add("@ECD", model.ECD); parameters.Add("@ImplementedDate", model.ImplementedDate); db.Execute("MRBInsertContainmentAction", parameters, commandType: CommandType.StoredProcedure); int id = parameters.Get("@ContainmentActionID"); model.ContainmentActionID = id; } public void UpdateContainmentAction(ContainmentActionObj model) { DynamicParameters parameters = new(); parameters.Add("@ContainmentActionID", model.ContainmentActionID); parameters.Add("@ContainmentAction", model.ContainmentAction); parameters.Add("@ResponsibilityOwnerID", model.ResponsibilityOwnerID); //parameters.Add("@ResponsibilityOwner", model.ResponsibilityOwner); parameters.Add("@ECD", model.ECD); parameters.Add("@ImplementedDate", model.ImplementedDate); db.Execute("MRBUpdateContainmentAction", parameters, commandType: CommandType.StoredProcedure); } internal void DeleteContainmentAction(ContainmentActionObj model) { DynamicParameters parameters = new(); parameters.Add("@ContainmentActionID", model.ContainmentActionID); db.Execute("MRBDeleteContainmentAction", parameters, commandType: CommandType.StoredProcedure); } internal void SubmitDocument(int mrbNumber, int userID) { string subRoles = wfDMO.GetSubRoleItems(mrbNumber, (int)GlobalVars.DocumentType.MRB); // bubble the error int appoverCount = 0; DynamicParameters parameters = new(); parameters.Add("@MRBNumber", mrbNumber); parameters.Add("@UserID", userID); parameters.Add("@DocumentTypeID", (int)GlobalVars.DocumentType.MRB); parameters.Add("@SubRoleCategoriesClause", subRoles); parameters.Add("@AppoverCount", appoverCount, dbType: DbType.Int32, direction: ParameterDirection.Output); db.Execute("MRBSubmitForApproval", parameters, commandType: CommandType.StoredProcedure); parameters.Get("@AppoverCount"); } internal void CloseDocument(int mrbNumber) => db.Execute("UPDATE MRB SET ApprovalStatus = " + (int)GlobalVars.ApprovalOption.Closed + ", CloseDate = GETDATE() WHERE MRBNumber = " + mrbNumber, commandType: CommandType.Text); internal void SetDispositionTypeForAllLots(int mrbNumber, string dispoType) => //var sql = "UPDATE MRBLot SET DispoType = '" + dispoType + "' WHERE MRBNumber = " + mrbNumber; //this.db.Execute(sql, commandType: CommandType.Text); db.Execute("MRBSetDispositionTypeForAllLots", new { @MRBNumber = mrbNumber, @DispoType = dispoType }, commandType: CommandType.StoredProcedure); internal void GetLotWaferDieCount(int mrbNumber, out int lotCount, out int waferCount, out int dieCount) { lotCount = 0; waferCount = 0; dieCount = 0; DynamicParameters parameters = new(); parameters.Add("@MRBNumber", mrbNumber); parameters.Add("@LotCount", lotCount, dbType: DbType.Int32, direction: ParameterDirection.Output); parameters.Add("@WaferCount", waferCount, dbType: DbType.Int32, direction: ParameterDirection.Output); parameters.Add("@DieCount", dieCount, dbType: DbType.Int32, direction: ParameterDirection.Output); db.Execute("MRBGetLotWaferDieCount", parameters, commandType: CommandType.StoredProcedure); lotCount = parameters.Get("@LotCount"); waferCount = parameters.Get("@WaferCount"); dieCount = parameters.Get("@DieCount"); } internal IEnumerable GetMRBHoldLots(int mrbNumber) { List data = db.Query("MRBGetMRBHoldLots", new { @MRBNumber = mrbNumber }, commandType: CommandType.StoredProcedure).ToList(); return data; } internal void LogHoldFlagSentToSPNHistory(int mrbNumber) => db.Execute("MRBLogHoldFlagSentToSPNHistory", new { @MRBNumber = mrbNumber }, commandType: CommandType.StoredProcedure); //internal IEnumerable GetSPN_MRB_HoldFlagLots(int mrbNumber) //{ // var disposition = this.db.Query("MRBGet_SPN_HoldLots", new { @MRBNumber = mrbNumber }, commandType: CommandType.StoredProcedure).ToList(); // return disposition; //} //internal void InsertSPN_MRB_HoldFlagLots(int mrbNumber) //{ // var disposition = this.db.Query("MRBInsertSPN_HoldFlagLots", new { @MRBNumber = mrbNumber }, commandType: CommandType.StoredProcedure).ToList(); // //return disposition; //} internal void InsertMRB_QDB_HoldFlag(string guid, string data, string operation) { string[] tempData = data.Split(new char[] { '~' }); DynamicParameters parameters = new(); parameters.Add("@GUID", guid); parameters.Add("@LotNumber", tempData[0].ToString()); parameters.Add("@MRBNumber", tempData[1].ToString()); parameters.Add("@IncludeChildLots", tempData[2].ToUpper() == "YES" ? 1 : 0); parameters.Add("@Operation", operation); db.Execute("MRBInsertQDB_HoldFlag", parameters, commandType: CommandType.StoredProcedure); } internal IEnumerable GetMRB_QDB_HoldFlags(string guid) { List data = db.Query("MRBGetMRB_QDB_HoldFlags", new { @Guid = guid }, commandType: CommandType.StoredProcedure).ToList(); return data; } internal void UpdateMRB_QDB_HoldFlag(string guid, bool successResult) { DynamicParameters parameters = new(); parameters.Add("@GUID", guid); parameters.Add("@SuccessResult", successResult); db.Execute("MRBUpdateQDB_HoldProcessedFlag", parameters, commandType: CommandType.StoredProcedure); } //internal IEnumerable GetLotsForMRBHoldFlags(string guid) //{ // var data = this.db.Query("MRBGetMRB_QDB_HoldFlags", new { @Guid = guid }, commandType: CommandType.StoredProcedure).ToList(); // return data; //} public IEnumerable GetUserList() { DynamicParameters parameters = new(); List userList = db.Query("_8DGetUserList", parameters, commandType: CommandType.StoredProcedure).ToList(); return userList; } public static string FormCSV(params object[] args) { bool first = true; StringBuilder sb = new(); foreach (object arg in args) { if (!first) sb.Append(","); string s = Convert.ToString(arg); s = s.Replace('\r', ' ').Replace('\n', ' ').Replace('"', ' '); if (s.Contains(',')) { sb.Append("\""); sb.Append(s); sb.Append("\""); } else { sb.Append(s); } first = false; } return sb.ToString(); } public string ImportRemoveQDBFlag(string operation, out string physicalPath, string userIdentityName, string a, string b, string c, string fullFileName, Stream stream) { IEnumerable lotDataList = null; var guid = Guid.NewGuid().ToString(); var fileExtension = Path.GetExtension(fullFileName); physicalPath = Path.Combine(_AppSettings.LotTempPipeLine, guid + "." + fileExtension); using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { stream.CopyTo(fileStream); } #if !NET8 ExcelData x = new ExcelData(physicalPath); lotDataList = x.ReadQDBFlagData(); foreach (string lotData in lotDataList) { InsertMRB_QDB_HoldFlag(guid, lotData, operation); } #endif FileInfo f = new(physicalPath); if (f.Exists) f.Delete(); //Send the data to SPN if (SendQDBFlagToSPN(guid, userIdentityName, a, b, c)) UpdateMRB_QDB_HoldFlag(guid, true); else { UpdateMRB_QDB_HoldFlag(guid, false); return "Problems while uploading to SPN"; } return string.Empty; } public bool BatchFTP(string sourceFile, string destFile, string ftpLogDirectory, string userIdentityName, string a, string b, string c) { FileInfo sourcefile = new(sourceFile); //FileInfo sourcefile = new FileInfo(@"C:\Websites\ECNViewerAckResultToSPN\S15122017102017.ecn"); try { //Functions.WriteEvent("HR Emp", "SPNData - Start Send(): FTPing " + sourceFile + " to SPN server.", System.Diagnostics.EventLogEntryType.Information); //System.Security.SecureString ss = new System.Security.SecureString(); //foreach (char c in credentialsStorage.Password) // ss.AppendChar(c); ProcessStartInfo psiFab1 = new(); Process procFab1 = new(); StringBuilder sb = new(); if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") { psiFab1.FileName = a; // Server.MapPath("/FTPBatch/" + @Functions.FTPSPNBatch_Test()); } else { psiFab1.FileName = b; // Server.MapPath("/FTPBatch/" + @Functions.FTPSPNBatch()); } psiFab1.Arguments = sourcefile.FullName + " " + destFile; psiFab1.RedirectStandardOutput = true; psiFab1.UseShellExecute = false; psiFab1.WorkingDirectory = c; // Server.MapPath("/FTPBatch/"); //credentialsStorage = MiscDMO.GetCredentialsInfo("TEMSA01EC", "LocalAdmin"); //psiFab1.UserName = credentialsStorage.UserName; //psiFab1.Password = ss; procFab1.StartInfo = psiFab1; procFab1.OutputDataReceived += (sender, args) => sb.AppendLine(args.Data); ; procFab1.Start(); procFab1.BeginOutputReadLine(); procFab1.WaitForExit(4000); File.WriteAllText(Path.Combine(ftpLogDirectory, sourcefile.Name + ".txt"), sb.ToString()); //procFab1.StartInfo = psiFab1; //procFab1.Start(); //Functions.WriteEvent("HR Emp", "SPNData - Finish FTPing to SPN server.", System.Diagnostics.EventLogEntryType.Information); return true; } catch (Exception e) { Functions.WriteEvent(_AppSettings, userIdentityName + "\r\n Approve\r\n" + e.Message.ToString(), EventLogEntryType.Error); return false; } } public bool SendQDBFlagToSPN(string guid, string userIdentityName, string a, string b, string c) { StringBuilder output = new(); try { IEnumerable data = GetMRB_QDB_HoldFlags(guid); foreach (string tempData in data) { //output = new StringBuilder(); output.Append(tempData.Trim() + Environment.NewLine); } try { if (output.Length > 0) { DateTime dt = DateTime.Now; string newsourceFileName = "S" + dt.Day.ToString("00") + dt.Month.ToString("00") + dt.Year.ToString("00") + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".mrb"; string newDestFileName = "S" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".mrb"; //string outputFile = @"C:\Websites\SPNLotHoldFlag\" + newsourceFileName; string outputFile = _AppSettings.HoldFlagDirectory + newsourceFileName; File.WriteAllText(outputFile, output.ToString()); #if (DEBUG) Thread.Sleep(1000); #endif try { //#if (!DEBUG) //FTPWrapper spfSPN = new FTPWrapper(outputFile, newDestFileName); //spfSPN.FTPToSPN(); if (BatchFTP(outputFile, newDestFileName, _AppSettings.SPNMRBHoldFlagFTPLogDirectory, userIdentityName, a, b, c)) { UpdateMRB_QDB_HoldFlag(guid, true); } else { UpdateMRB_QDB_HoldFlag(guid, false); } //#endif } catch (Exception e) { string exceptionString = e.Message.ToString().Trim().Length > 500 ? "MRB =" + guid.ToString() + " FTPToSPN(): FTP Upload Error " + e.Message.ToString().Substring(0, 250) : e.Message.ToString(); EventLogDMO.Add(new WinEventLog() { IssueID = -1, UserID = userIdentityName, DocumentType = "MRB", OperationType = "Error", Comments = exceptionString }); return false; } } return true; } catch (Exception e) { string exceptionString = e.Message.ToString().Trim().Length > 500 ? "MRB =" + guid.ToString() + " SPN Hold Flag(SendToSPN) " + e.Message.ToString().Substring(0, 250) : e.Message.ToString(); Functions.WriteEvent(_AppSettings, userIdentityName + "\r\n Approve\r\n" + e.Message.ToString(), EventLogEntryType.Error); EventLogDMO.Add(new WinEventLog() { IssueID = -1, UserID = userIdentityName, DocumentType = "MRB", OperationType = "Error", Comments = exceptionString }); return false; } } catch (Exception e) { string exceptionString = e.Message.ToString().Trim().Length > 500 ? "GUID =" + guid.ToString() + " SPN Hold Flag(SendToSPN) " + e.Message.ToString().Substring(0, 250) : e.Message.ToString(); Functions.WriteEvent(_AppSettings, userIdentityName + "\r\n Approve\r\n" + e.Message.ToString(), EventLogEntryType.Error); EventLogDMO.Add(new WinEventLog() { IssueID = -1, UserID = userIdentityName, DocumentType = "MRB", OperationType = "Error", Comments = exceptionString }); return false; } } public string ImportAddQDBFlag(string operation, out string physicalPath, string userIdentityName, string a, string b, string c, string fullFileName, Stream stream) { IEnumerable lotDataList = null; var guid = Guid.NewGuid().ToString(); var fileExtension = Path.GetExtension(fullFileName); physicalPath = Path.Combine(_AppSettings.LotTempPipeLine, guid + "." + fileExtension); using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { stream.CopyTo(fileStream); } #if !NET8 ExcelData x = new ExcelData(physicalPath); lotDataList = x.ReadQDBFlagData(); foreach (string lotData in lotDataList) { InsertMRB_QDB_HoldFlag(guid, lotData, operation); } #endif FileInfo f = new(physicalPath); if (f.Exists) f.Delete(); if (SendQDBFlagToSPN(guid, userIdentityName, a, b, c)) UpdateMRB_QDB_HoldFlag(guid, true); else { UpdateMRB_QDB_HoldFlag(guid, false); return "Problems while uploading to SPN"; } return string.Empty; } public void AttachSave(int mrbNumber, int userId, string fullFileName, Stream stream) { // Some browsers send file names with full path. // We are only interested in the file name. var fileName = Path.GetFileName(fullFileName); string physicalFileName; string physicalPath; // Check to see if this filename is in use var attachments = GetMRBAttachments(mrbNumber); if (attachments.Count() > 0) { if (attachments.Count(a => string.Equals(a.FileName, fileName, StringComparison.OrdinalIgnoreCase)) > 0) { // This filename is used on this MRB // So we want to delete those records so the new record replaces them foreach (var a in attachments) { DeleteMRBAttachment(a.AttachmentID); physicalFileName = a.Path; if (string.IsNullOrEmpty(physicalFileName)) physicalFileName = a.FileName; physicalPath = Path.Combine(_AppSettings.AttachmentFolder + "MRB", physicalFileName); if (File.Exists(physicalPath)) File.Delete(physicalPath); } } } physicalFileName = mrbNumber.ToString() + "_" + Guid.NewGuid().ToString() + Path.GetExtension(fileName); physicalPath = Path.Combine(_AppSettings.AttachmentFolder + "MRB", physicalFileName); using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { stream.CopyTo(fileStream); } MRBAttachment attach = new() { MRBNumber = mrbNumber, FileName = fileName, Path = physicalFileName, #if (DEBUG) UserID = 114, #endif #if (!DEBUG) UserID = userId, #endif }; InsertMRBAttachment(attach); } public string ExcelLotOpen(int mrbNumber, StringBuilder warnings, IEnumerable dispos, string userIdentityName, string lotTempPipeLine, string fullFileName, Stream stream) { var fileName = Path.GetFileName(fullFileName); var fileExtension = Path.GetExtension(fullFileName); string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); string physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); #if !NET8 IEnumerable lotNumbers; try { using (var fileStream = new FileStream(physicalPath, FileMode.Create, FileAccess.Write)) { stream.CopyTo(fileStream); } ExcelData x = new ExcelData(physicalPath); lotNumbers = x.ReadData(); } catch (Exception ex) { throw new Exception(String.Format("Invalid file format for {0}: {1}", fileName, ex.Message)); } // Get Tool, Issue Start and End Date MRB mrbInfo = GetToolIssueStartEndDateData(mrbNumber, null); foreach (var lotInfo in lotNumbers) { if (lotInfo.LotDispo.Length == 1) { if (dispos.Count(d => d.DispositionType.Trim().ToUpper() == lotInfo.LotDispo.Trim().ToUpper()) == 0) { throw new Exception(String.Format("Invalid lot disposition {0} for lot no {1}", lotInfo.LotDispo, lotInfo.LotNo)); } } } // RJK - 12/17 // Only find the child Splits when a Tool or a list of Tools is provided if (!mrbInfo.ToolCSV.ToUpper().Equals("NA")) { foreach (var lotInfo in lotNumbers) { bool existingLotUpdated; Lot l = new Lot(); l.LotNumber = lotInfo.LotNo; if (lotInfo.LotDispo.Length == 1) { l.DispoType = lotInfo.LotDispo[0]; } l.MRBNumber = mrbNumber; InsertLot(l, true, out existingLotUpdated); // cannot do the check below , because what if the parent lot had splits after the prior lot split analysis //if (!existingLotUpdated) //{ if (!InsertLotSplitsAffectedByIncident(mrbNumber, l.LotNumber, mrbInfo.ToolCSV, mrbInfo.IssueStartDate, mrbInfo.IssueEndDate)) { warnings.AppendFormat("Lot number {0} is not affected by these tools and issue start/end time.\n Uploaded without Lot Genealogy tracing", l.LotNumber); } //} } // Not required - Will be using each lot's Insert Date time stamp, // as lot could be added using search functionality // UpdateLastLotSplitAnalysisTime(mrbNumber); } else { // RJK - 12/17 // Only find the child Splits when a Tool or a list of Tools is provided foreach (var lotInfo in lotNumbers) { bool existingLotUpdated; Lot l = new Lot(); l.LotNumber = lotInfo.LotNo; if (lotInfo.LotDispo.Length == 1) { l.DispoType = lotInfo.LotDispo[0]; } l.MRBNumber = mrbNumber; // do not insert any new lots when importing from excel InsertLot(l, true, out existingLotUpdated); //UpdateLotDispoType(mrbNumber, l.LotNumber, l.DispoType); //if (!existingLotUpdated) //{ // if (!InsertLotSplitsAffectedByIncident(mrbNumber, l.LotNumber, mrbInfo.ToolCSV, mrbInfo.IssueStartDate, mrbInfo.IssueEndDate)) // { // warnings.AppendFormat("Lot number {0} is not affected by these tools and issue start/end time.\n", l.LotNumber); // } //} } } #endif FileInfo f = new(physicalPath); if (f.Exists) f.Delete(); return physicalPath; } }