diff --git a/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckController.cs b/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckController.cs index 7f0304c0..e0c1a157 100644 --- a/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckController.cs +++ b/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckController.cs @@ -23,7 +23,7 @@ namespace AMESCoreStudio.WebApi.Controllers.AMES /// [Route("api/[controller]")] [ApiController] - public class BarCodeCheckController : ControllerBase + public class BarCodeCheck1Controller : ControllerBase { private readonly AMESContext _context; private readonly IConfiguration _config; @@ -32,7 +32,7 @@ namespace AMESCoreStudio.WebApi.Controllers.AMES /// /// /// - public BarCodeCheckController(AMESContext context, IConfiguration config) + public BarCodeCheck1Controller(AMESContext context, IConfiguration config) { _config = config; _context = context; diff --git a/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckNewController.cs b/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckNewController.cs new file mode 100644 index 00000000..6225557b --- /dev/null +++ b/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckNewController.cs @@ -0,0 +1,2587 @@ +using AMESCoreStudio.CommonTools.Result; +using AMESCoreStudio.WebApi.Controllers.BLL; +using AMESCoreStudio.WebApi.DTO.AMES; +using AMESCoreStudio.WebApi.Enum; +using AMESCoreStudio.WebApi.Models.AMES; +using AMESCoreStudio.WebApi.Models.BAS; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace AMESCoreStudio.WebApi.Controllers.AMES +{ + /// + /// 過站判斷 + /// + [Route("api/[controller]")] + [ApiController] + public class BarCodeCheckController : ControllerBase + { + private readonly AMESContext _context; + private readonly IConfiguration _config; + + /// + /// + /// + /// + public BarCodeCheckController(AMESContext context, IConfiguration config) + { + _config = config; + _context = context; + } + + #region 過站判斷 + /// + /// 過站判斷 + /// + /// + /// + [HttpPost("PassIngByCheck")] + public async Task>> CheckBarCodeCheck([FromBody] BarCodeCheckDto barCodeCheckDto) + { + ResultModel resultModel = new ResultModel { Success = false }; + try + { + // 確認過站欄位是否填寫 + resultModel.Msg = CheckBarCodeInputData(barCodeCheckDto); + if (!string.IsNullOrWhiteSpace(resultModel.Msg)) + return resultModel; + + // 抓取過站需要訊息及資料轉換 + var data = await PassIngDataTuck(barCodeCheckDto); + + // 確認資料正確 + resultModel.Msg = await CheckPassIngDataCorrect(data); + if (!string.IsNullOrWhiteSpace(resultModel.Msg)) + return resultModel; + + #region 宣告參數 + // 存放要更新BarCodeItem + var update_BarCodeItem = new List(); + var insert_BarCodeItemChange = new List(); + #endregion + + #region 判斷工單狀態 + + resultModel = await CheckWipNoSationAsync(wipNo: data.wipNo, unitNo: data.unitNo + , flowRuleID: data.flowRule, line: data.line, stationID: data.stationID, barCodeNo: data.barcode); + if (!resultModel.Success) + return resultModel; + + #endregion + + #region 判斷序號區間 + + resultModel = await CheckBarCodeByWipNo(wipNo: data.wipNo, barcode: data.barcode); + if (!resultModel.Success) + return resultModel; + + #endregion + + #region 判斷序號狀態 + + resultModel = await GetCheckBarCodeStation(barCode: data.barcodeID, barCodeNo: data.barcode); + if (!resultModel.Success) + return resultModel; + + #endregion + + #region 判斷序號流程 + + resultModel = await CheckBarCodeFlowAsync(wipId: data.wipID, barCode: data.barcodeID + , barCodeNo: data.barcode, stationID: data.stationID); + if (!resultModel.Success) + return resultModel; + + #endregion + + #region 燒機判斷 + + // Station_Type = B 燒機站 + if (data.stations_TypeNo == "B") + { + resultModel = await GetCheckBurn(data.wipNo, data.barcodeID, data.stationID, data.ruleStatus); + if (!resultModel.Success) + return resultModel; + else if (resultModel.Msg == "BurnIn") + data.burnIn = true; + } + #endregion + + #region 治具判斷 + + if (data.outfits.Count != 0) + { + resultModel = CheckBarCodeOutfitAsync(data.outfits); + if (!resultModel.Success) + return resultModel; + } + + #endregion + + #region 判斷T3掃毒 + + if (data.stations_Name.ToUpper() == "T3") + { + resultModel = await CheckAntivirus(data.wipNo, data.itemNo); + if (!resultModel.Success) + return resultModel; + } + + #endregion + + #region KeyParts 判斷 + + // 排除刷不良代碼 + if (data.inputItems.Where(w => !w.inputType.ToUpper().StartsWith("NG")).Any()) + { + // + var WipKps = _context.WipKps.Where(w => w.WipNo == data.wipNo).OrderBy(o => o.KpSeq).ToList(); + if (WipKps.Count == 0) + { + resultModel.Msg = "工單號碼【" + data.wipNo + "】找不到相關Key Parts設定"; + resultModel.Success = false; + return resultModel; + } + + // 一般過站 + if (data.barcodeType != "S") + { + var barcodeItemKPDto = new BarcodeItemKPDto + { + wipNo = data.wipNo, + wipId = data.wipID, + barCode = data.barcodeID, + barCodeNo = data.barcode, + unitNo = data.unitNo, + ststionUnitNo = data.stations_UnitNo, + inputKP = data.inputItems.Where(w => !w.inputType.ToUpper().StartsWith("NG")).ToList() + }; + + var resultModelKeyParts = await CheckBarCodeKeyPartsData(barcodeItemKPDto); + if (!resultModelKeyParts.Success) + { + resultModel.Success = false; + resultModel.Msg = resultModelKeyParts.Msg; + return resultModel; + } + + } + // 維修過站 + else if (data.barcodeType == "S") + { + // 用BarCodeID And WipID 取BarCodeItem + var q_BarCodeItem = await _context.BarcodeItems.Where(w => w.BarcodeID == data.barcodeID).ToListAsync(); + + foreach (var KPs in data.inputItems) + { + // 用舊組件序號比對 + var barCodeItem = q_BarCodeItem.Where(w => w.PartNo == KPs.oldInputData).FirstOrDefault(); + + if (barCodeItem != null) + { + var q_Kp = WipKps.Where(w => w.KpNo.ToUpper() == barCodeItem.ItemNo.ToUpper()).FirstOrDefault(); + if (q_Kp != null) + { + resultModel.Msg += await CheckKeyPartsCorrect(q_Kp, KPs); + } + + barCodeItem.WipID = data.wipID; + barCodeItem.PartNo = KPs.inputData; + barCodeItem.UpdateDate = DateTime.Now; + update_BarCodeItem.Add(barCodeItem); + + insert_BarCodeItemChange.Add(new BarcodeItemChange + { + WipID = data.wipID, + StationID = data.stationID, + BarcodeID = data.barcodeID, + ItemNo = barCodeItem.ItemNo, + PartNoOld = KPs.oldInputData, + ChangeType = "RP", + KpItemNo = KPs.inputData, + CreateUserID = data.userID + }); + } + else + { + resultModel.Msg = $"內部條碼【{data.barcode}】找不到已綁定Kp序號【{KPs.oldInputData}】"; + } + } + + if (!string.IsNullOrWhiteSpace(resultModel.Msg)) + { + resultModel.Success = false; + return resultModel; + } + + // 將InputItem清空 + data.inputItems = new List(); + } + } + #endregion + + #region 判斷為CHECK站.組件是否都有資料 + + // 判斷作業站是否為CHECK站 Station_Type == C + if (data.stations_TypeNo == "C") + { + // 過站輸入組件數量 + var inputKPQty = data.inputItems.Where(w => !w.inputData.Contains("$")).Count(); + + // 已記錄組件數量 + var BarCodeItems = _context.BarcodeItems.Where(w => w.BarcodeID == data.barcodeID && w.WipID == data.wipID); + var Stations = _context.Stationses.Where(w => w.UnitNo == data.stations_UnitNo); + var BarCodeItemsQty = BarCodeItems.Where(w => Stations.Any(s => s.StationID == w.StationID)).Count(); + + // WipKp DB 設定綁定組件數量 + 製程判斷 + var wipKpQty = _context.WipKps.Where(w => w.WipNo == data.wipNo + && w.UnitNo == data.stations_UnitNo + ).Count(); + + if (wipKpQty != inputKPQty + BarCodeItemsQty) + { + resultModel.Success = false; + resultModel.Msg = "組件資料筆數不符,請確認"; + return resultModel; + } + } + + #endregion + + #region 內部序號輸入後新增 or 更新 + + var result_CUTableMsg = await CU_Tables(data); + if (!string.IsNullOrWhiteSpace(result_CUTableMsg)) + { + resultModel.Msg = "內部序號【" + barCodeCheckDto.barcode + "】 過站失敗,錯誤訊息:
"; + resultModel.Msg += result_CUTableMsg; + resultModel.Success = false; + return resultModel; + } + + #endregion + + #region 維修組件更換 + + if (update_BarCodeItem.Count() != 0) + { + await UpdateBarCodeItemChange(update_BarCodeItem, insert_BarCodeItemChange); + } + + #endregion + + #region 燒機In 修改狀態 + if (data.burnIn) + { + resultModel.Msg = $"內部序號【{data.barcode}】 燒機In 完成!"; + } + else + { + resultModel.Msg = $"內部序號【{data.barcode}】 過站完成!"; + } + #endregion + + resultModel.Success = true; + return resultModel; + + } + catch (Exception ex) + { + resultModel.Success = false; + resultModel.Msg = ex.Message; + return resultModel; + } + } + #endregion + + #region FQC抽驗過站 + /// + /// FQC抽驗過站 + /// + /// 入庫單號 + /// 順序 + /// UserID + /// + [HttpGet("PassIngByFQC")] + public async Task>> PassingByFQC(string inhouseNo, int seqID, int userID) + { + ResultModel resultModel = new ResultModel { Success = false }; + var InhouseMaster = _context.FqcInhouseMasters.Where(w => w.InhouseNo == inhouseNo && w.SeqID == seqID) + .FirstOrDefault(); + try + { + if (InhouseMaster != null) + { + // 判斷是否有設定FQC站 Station_Type == F + var WipInfo = _context.WipInfos.Where(w => w.WipNO == InhouseMaster.WipNo).FirstOrDefault(); + var RuleStations = _context.RuleStations.Where(w => w.FlowRuleID == WipInfo.FlowRuleID && + w.Station.TypeNo == "F").ToList(); + // 有設定FQC站別 + if (RuleStations.Any()) + { + var RuleStation = RuleStations.FirstOrDefault(); + // 取FQC抽驗單號 + var InhouseDetail = await _context.FqcInhouseDetails.Where(w => w.InhouseNo == inhouseNo && w.SeqID == seqID) + .ToListAsync(); + BarCodeCheckDtoForDBData data = new BarCodeCheckDtoForDBData(); + data.line = -1; + data.ruleStatus = "P"; + data.stationID = RuleStation.Station.StationID; + data.userID = userID; + data.barcodeType = "M"; + // 生產單位_簡碼 + data.factoryUnit_UnitCode = _context.FactoryUnits.Where(w => w.UnitNo == WipInfo.UnitNO).FirstOrDefault().UnitCode ?? ""; + foreach (var item in InhouseDetail) + { + // 用箱號抽驗 + if (item.SerialType == "B") + { + var BarcodeNo = await _context.BarcodeInfoes.Where(w => w.BoxNo == item.SerialNo).ToListAsync(); + foreach (var barcode in BarcodeNo) + { + data.unitNo = WipInfo.UnitNO; + data.wipID = barcode.WipID; + data.barcode = barcode.BarcodeNo; + data.barcodeID = barcode.BarcodeID; + data.extNo = barcode.ExtraBarcodeNo; + data.flowRule = WipInfo.FlowRuleID; + data.wipNo = WipInfo.WipNO; + + var result_CUTableMsg = await CU_Tables(data); + if (string.IsNullOrWhiteSpace(result_CUTableMsg)) + { + resultModel.Success = true; + resultModel.Msg = "FQC過站完成"; + } + else + { + resultModel.Msg = result_CUTableMsg; + } + } + } + } + } + else + { + resultModel.Msg = $"該筆工單號碼【{InhouseMaster.WipNo}】,無設定FQC站別"; + } + } + else + { + resultModel.Msg = "找不到該筆FQC單號"; + } + return resultModel; + } + catch (Exception ex) + { + resultModel.Msg = ex.Message; + resultModel.Success = false; + return resultModel; + } + } + #endregion + + #region 判斷過站完成新增or更新 Table + /// + /// 判斷過站完成新增or更新 Table + /// + /// + /// + private async Task CU_Tables(BarCodeCheckDtoForDBData data) + { + #region 先取得各個Table ID + + Helper helper = new Helper(_context); + int BarCodeId = 0; + List BarCodeItemId = new List(); + List BarCodeOutfitId = new List(); + int NgId = 0; + List ComponentId = new List(); + + // BarCodeInfo ID + if (data.barcodeID == 0) + { + BarCodeId = helper.GetIDKey("BARCODE_ID").Result; + data.barcodeID = BarCodeId; + } + + // 組件料號 + foreach (var item in data.inputItems.Where(w => !w.inputData.Contains("$"))) + { + BarCodeItemId.Add(helper.GetIDKey("BARCODEITEM_ID").Result); + } + + // 治具編號 + foreach (var item in data.outfits) + { + BarCodeOutfitId.Add(helper.GetIDKey("BARCODE_OUTFIT_ID").Result); + } + + // 不良代碼 + if (data.inputItems.Where(w => w.inputData.Contains("$")).Any()) + { + NgId = helper.GetIDKey("NG_ID").Result; + foreach (var item in data.inputItems.Where(w => w.inputData.Contains("$"))) + { + ComponentId.Add(helper.GetIDKey("COMPONENT_ID").Result); + } + } + + #endregion + + string Msg = string.Empty; + + using (var tran = _context.Database.BeginTransaction()) + { + try + { + if (!data.burnIn) + { + // 條碼主檔 + Msg = Table_BarcodeInfo(data, BarCodeId); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"BarcodeInfo_Error:{Msg}"); + } + + // 條碼紀錄 + Msg = Table_BarcodeWip(data); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"BarcodeWip_Error:{Msg}"); + } + + // 工單各站數量資料檔 + Msg = Table_WipStation(data); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"WipStation_Error:{Msg}"); + } + + // 各班別數量資料檔 + Msg = Table_WipClass(data); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"WipClass_Error:{Msg}"); + } + + // 工單各站數量資料檔 – By TIME + Msg = Table_WipTime(data); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"WipTime_Error:{Msg}"); + } + + // 條碼過站資料檔 + Msg = Table_BarcodeStation(data); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"BarcodeStation_Error:{Msg}"); + } + + // 組件資料 + Msg = Table_BarcodeItem(data, BarCodeItemId); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"BarcodeItem_Error:{Msg}"); + } + + // 條碼治具 + Msg = Table_BarcodeOutfit(data, BarCodeOutfitId); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"BarcodeOutfit_Error:{Msg}"); + } + + // 設備資料檔 使用次數 + Msg = await Table_OutfitInfo(data); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"OutfitInfo_Error:{Msg}"); + } + + // 不良資料檔 + Msg = Table_NgInfo(data, NgId, ComponentId); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"NgInfo_Error:{Msg}"); + } + + // 判斷是否為第一站 + if (await CheckNowFirstStation(data.wipID, data.stationID) == "Y") + { + // 在BarStation 確認該筆工單ID只有一筆當第一次投入 + var CheckBarcodeStation = await _context.BarcodeStation.Where(w => w.BarcodeID == data.barcodeID && + w.WipID == data.wipID) + .ToListAsync(); + if (CheckBarcodeStation.Count() == 1) + { + // 有資料加1 後續判斷第一次過站 + string updateSql = $@" UPDATE JHAMES.WIP_INFO SET COMPLETE_QTY = COMPLETE_QTY + 1 + WHERE WIP_ID = {data.wipID}"; + // 執行原生 SQL + _context.Database.ExecuteSqlRaw(updateSql); + } + } + + // 判斷下一站為完工站 + if (CheckNextStopCloseStation(data.flowRule, data.stationID, data.ruleStatus).Result.Success) + { + await CheckWipNoBarCodeAllClost(data.wipID); + } + } + + // 燒入資料檔 + Msg = await Table_BurnInfo(data); + if (!string.IsNullOrWhiteSpace(Msg)) + { + throw new Exception($"BurnInfo_Error:{Msg}"); + } + + // 判斷是否有DB更新錯誤 + if (string.IsNullOrWhiteSpace(Msg)) + { + await tran.CommitAsync(); + } + else + { + await tran.RollbackAsync(); + } + } + + catch (Exception ex) + { + Msg = "過站新增系統錯誤:" + ex.Message; + await tran.RollbackAsync(); + } + } + + return Msg; + } + + /// + /// BarcodeInfo-條碼資料檔 + /// + /// model資料 + /// BarCodeId 0=(修改) !=0(新增) + /// + private string Table_BarcodeInfo(BarCodeCheckDtoForDBData data, int id) + { + // 查看是否有資料 + var barcodeInfo = _context.BarcodeInfoes.Where(w => w.BarcodeID == data.barcodeID).FirstOrDefault(); + + // 新增 + if (barcodeInfo == null) + { + barcodeInfo = new BarcodeInfo + { + BarcodeID = id, + BarcodeNo = data.barcode, + StationID = data.stationID, + LocationID = -1, + WipID = data.wipID, + RuleStatus = data.ruleStatus, + StatusID = 1, + SysType = "S", + StatusNo = data.factoryUnit_UnitCode, + CreateUserID = data.userID + }; + } + // 更新 + else + { + barcodeInfo.StationID = data.stationID; + barcodeInfo.RuleStatus = data.ruleStatus; + barcodeInfo.StatusNo = data.factoryUnit_UnitCode; + barcodeInfo.WipID = data.wipID; + barcodeInfo.StatusID = 1; + barcodeInfo.UpdateDate = DateTime.Now; + if (!string.IsNullOrWhiteSpace(data.extNo)) + barcodeInfo.ExtraBarcodeNo = data.extNo; + } + + // 判斷該站別是否為最後一站 + if (CheckNextStopCloseStation(data.flowRule, data.stationID, data.ruleStatus).Result.Success) + { + barcodeInfo.StatusID = -1; + } + + try + { + // 新增 + if (id != 0) + { + _context.BarcodeInfoes.Add(barcodeInfo); + } + // 更新 + else + { + _context.Entry(barcodeInfo).State = EntityState.Modified; + //設置容器空間某一個模型的某一個欄位 不提交到資料庫 + _context.Entry(barcodeInfo).Property("CreateDate").IsModified = false; + _context.Entry(barcodeInfo).Property("CreateUserID").IsModified = false; + } + _context.SaveChanges(); + } + catch (Exception ex) + { + return ex.InnerException.Message + "
"; + } + + return ""; + } + + /// + /// BarcodeStation-條碼過站資料檔 + /// + /// + /// + private string Table_BarcodeStation(BarCodeCheckDtoForDBData data) + { + // 新增 BarCodeStation + BarcodeStation barcodeStation = new BarcodeStation + { + BarcodeID = data.barcodeID, + WipID = data.wipID, + StationID = data.stationID, + RuleStatus = data.ruleStatus, //F 不良 + InputDate = DateTime.Now, + LineId = data.line, + CreateUserID = data.userID, + FlowRuleID = data.flowRule + }; + + try + { + _context.BarcodeStation.Add(barcodeStation); + _context.SaveChanges(); + } + catch (Exception ex) + { + return ex.InnerException.Message; + } + return ""; + } + + /// + /// BarcodeItem-組件资料 + /// + /// + /// BarcodeItemID 陣列 + /// + private string Table_BarcodeItem(BarCodeCheckDtoForDBData data, List id) + { + var KeyPartsItem = data.inputItems.Where(w => !w.inputData.Contains("$")).ToList(); + var barcodeItem = new List(); + // 新增 BarCodeStation + for (int i = 0; i < KeyPartsItem.Count; i++) + { + barcodeItem.Add(new BarcodeItem + { + BarcodeItemID = id[i], + BarcodeID = data.barcodeID, + WipID = data.wipID, + StationID = data.stationID, + ItemNo = KeyPartsItem[i].inputType, + PartNo = KeyPartsItem[i].inputData, + SysType = "S", + CreateUserID = data.userID, + CreateDate = DateTime.Now, + UpdateDate = DateTime.Now, + KpItemNo = KeyPartsItem[i].kpItemNo + }); + } + + if (barcodeItem.Count != 0) + { + try + { + _context.BarcodeItems.AddRange(barcodeItem); + _context.SaveChanges(); + } + catch (Exception ex) + { + return ex.InnerException.Message; + } + } + + return ""; + } + + /// + /// BarCodeOutfit-治具資料 + /// + /// + /// BarCodeOutfit ID List + /// + private string Table_BarcodeOutfit(BarCodeCheckDtoForDBData data, List id) + { + var OutfitsItem = data.outfits; + var barcodeOutfit = new List(); + // 新增 BarCodeStation + for (int i = 0; i < OutfitsItem.Count; i++) + { + barcodeOutfit.Add(new BarcodeOutfit + { + BarcodeOutfitID = id[i], + BarcodeNo = data.barcode, + WipNo = data.wipNo, + OutfitNo = OutfitsItem[i].inputData, + StationID = data.stationID, + CreateUserID = data.userID, + CreateDate = DateTime.Now, + UpdateUserID = data.userID, + UpdateDate = DateTime.Now + }); + } + + if (barcodeOutfit.Count != 0) + { + try + { + _context.BarcodeOutfits.AddRange(barcodeOutfit); + _context.SaveChanges(); + } + catch (Exception ex) + { + return ex.InnerException.Message; + } + } + return ""; + } + + /// + /// OutfitInfo-設備資料檔 使用次數 + /// + /// + /// + private async Task Table_OutfitInfo(BarCodeCheckDtoForDBData data) + { + OutfitInfoesController outfitInfoesController = new OutfitInfoesController(_context); + var OutfitsItem = data.outfits.Where(w => !string.IsNullOrWhiteSpace(w.inputData)).ToList(); + foreach (var item in OutfitsItem) + { + var outfitInfo = _context.OutfitInfoes.Where(w => w.OutfitNo == item.inputData.ToUpper()).FirstOrDefault(); + #region 治具 + if (outfitInfo != null) + { + outfitInfo.UseTimes += 1; + outfitInfo.TotalTimes += 1; + outfitInfo.UpdateDate = DateTime.Now; + + try + { + _context.Entry(outfitInfo).State = EntityState.Modified; + await _context.SaveChangesAsync(); + } + catch (Exception ex) + { + return ex.InnerException.Message; + } + WipAlarmsController wipAlarmsController = new WipAlarmsController(_context); + var wipAlarms = await wipAlarmsController.GetWipAlarmByOutfit(data.wipNo, item.inputData.Trim().ToUpper()); + // 判斷確認治具編號是否已到預警提醒 + if (outfitInfoesController.GetOutfitInfoByAlertTimes(item.inputData.Trim().ToUpper()).Result.Value == "Y") + { + if (!wipAlarms.Value.Where(w => w.AlarmTypeID == (int)EnumWipAlarm.EnumTypeId.OutfitAlert).Any()) + { + string MailGroup = "OUTFIT_ALARM"; + string Subject = $"[AMES系統通知] 治具編號:{item.inputData.Trim().ToUpper()},預警提前通知"; + string Body = ""; + + await new MailController(_context, _config).PostMail(Subject, Body, MailGroup, "", false); + + WipAlarm wipAlarm = new WipAlarm(); + wipAlarm.AlarmTypeID = (int)EnumWipAlarm.EnumTypeId.OutfitAlert; + wipAlarm.WipNO = data.wipNo; + wipAlarm.AlarmParam = item.inputData.ToUpper(); + wipAlarm.AlarmValue = "1"; + wipAlarm.AlarmDesc = Subject; + wipAlarm.AlarmDateTime = DateTime.Now; + + await wipAlarmsController.PostWipAlarm(wipAlarm); + } + } + } + #endregion + //// 確認治具編號使用次數已經超過預計次數 + //if (outfitInfoesController.GetOutfitInfoByOverUseTimes("").Result.Value == "Y") + //{ + + //} + } + return ""; + } + + /// + /// BurnInfo-燒入資料檔 + /// + /// + /// + private async Task Table_BurnInfo(BarCodeCheckDtoForDBData data) + { + // 判斷作業站是否為燒機站 Station_Type == B + if (data.stations_TypeNo == "B") + { + // 判斷是否有燒機時間 + WipBoardController wipBoardController = new WipBoardController(_context); + var wipBoardTime = await wipBoardController.GetWipBoardToBITime(data.wipNo); + WipSystemController wipSystemController = new WipSystemController(_context); + var wipSystemTime = await wipSystemController.GetWipSystemToBITime(data.wipNo); + decimal PlanHour = 0; + if (wipBoardTime.Value > 0) + PlanHour = (decimal)wipBoardTime.Value; + else + PlanHour = (decimal)wipSystemTime.Value; + + // 確認有燒機資訊 + var burnInfos = await _context.BurnInfos.Where(w => w.BarcodeID == data.barcodeID && + w.FinishTime == null) + .FirstOrDefaultAsync(); + try + { + // 新增 + if (burnInfos == null) + { + Helper helper = new Helper(_context); + // 新增 BarCodeStation + var burnInfo = new BurnInfo + { + BurnID = await helper.GetIDKey("BURN_ID"), + BarcodeID = data.barcodeID, + WipNo = data.wipNo, + BurnPlanHour = PlanHour, + StartTime = DateTime.Now, + ScheduleFinishTime = DateTime.Now.AddMinutes((double)PlanHour * 60), + InUserID = data.userID, + Status = 0, + CreateUserID = data.userID, + UpdateUserID = data.userID + }; + _context.BurnInfos.Add(burnInfo); + } + else + { + burnInfos.Status = 1; + burnInfos.FinishTime = DateTime.Now; + burnInfos.OutUserID = data.userID; + burnInfos.UpdateDate = DateTime.Now; + burnInfos.UpdateUserID = data.userID; + + _context.Entry(burnInfos).State = EntityState.Modified; + //設置容器空間某一個模型的某一個欄位 不提交到資料庫 + _context.Entry(burnInfos).Property("CreateDate").IsModified = false; + _context.Entry(burnInfos).Property("CreateUserID").IsModified = false; + } + await _context.SaveChangesAsync(); + } + catch (Exception ex) + { + return ex.InnerException.Message; + } + } + return ""; + } + + /// + /// NgInfo-測試不良基本資料檔 + /// + /// + /// Db ID + /// Db ID + /// + private string Table_NgInfo(BarCodeCheckDtoForDBData data, int ngId, List componentId) + { + var NgItem = data.inputItems.Where(w => w.inputData.Contains("$")).ToList(); + + try + { + // 新增 NgInfo + if (NgItem.Count != 0) + { + NgInfo ngInfo = new NgInfo + { + NgID = ngId, + TypeNo = data.stations_TestType, + OperatorID = 0, + FixtureNo = "NA", + BarcodeID = data.barcodeID, + ReasonNo = NgItem[0].inputData.Replace("$", ""), + ProgramNo = "N/A", + MachineNo = "N/A", + StationId = data.stationID, + WipId = data.wipID, + CreateUserID = data.userID, + UpdateUserID = data.userID + }; + _context.NgInfos.Add(ngInfo); + + var ngComponent = new List(); + for (int i = 0; i < NgItem.Count; i++) + { + ngComponent.Add(new NgComponent + { + NgID = ngId, + ComponentID = componentId[i], + LocationNo = string.IsNullOrWhiteSpace(NgItem[i].oldInputData) ? "N/A" : NgItem[i].oldInputData, + NgNo = NgItem[i].inputData.Replace("$", ""), + CreateUserID = data.userID, + UpdateUserID = data.userID + }); + + + // 累計預警 + WipAlarmsController wipAlarmsController = new WipAlarmsController(_context); + wipAlarmsController.PostWipAlarm4ErrorCode(data.wipNo, NgItem[i].inputData.Replace("$", "")).Wait(); + } + _context.NgComponents.AddRange(ngComponent); + _context.SaveChanges(); + } + } + catch (Exception ex) + { + return ex.InnerException.Message; + } + return ""; + } + + /// + /// BarcodeWip-檔案用途 條碼工單資料檔 + /// + /// + /// + private string Table_BarcodeWip(BarCodeCheckDtoForDBData data) + { + var barcodeWip = _context.BarcodeWips.Where(w => w.BarcodeID == data.barcodeID && + w.WipID == data.wipID).FirstOrDefault(); + try + { + // 新增 + if (barcodeWip == null) + { + barcodeWip = new BarcodeWip + { + BarcodeID = data.barcodeID, + WipID = data.wipID, + CreateUserID = data.userID + }; + _context.BarcodeWips.Add(barcodeWip); + } + // 更新 + else + { + barcodeWip.UpdateDate = DateTime.Now; + _context.Attach(barcodeWip); + _context.Entry(barcodeWip).Property(p => p.UpdateDate).IsModified = true; + } + _context.SaveChangesAsync(); + } + catch (Exception ex) + { + return ex.InnerException.Message + "
"; + } + return ""; + } + + /// + /// WipStation + /// + /// + private string Table_WipStation(BarCodeCheckDtoForDBData data) + { + var BarcodeStation = _context.BarcodeStation.Where(w => w.BarcodeID == data.barcodeID && + w.WipID == data.wipID && w.StationID == data.stationID && + w.FlowRuleID == data.flowRule).Any(); + var today = DateTime.Now.ToString("yyyy/MM/dd"); + // 判斷是否有資料 + var wipStations = _context.WipStations.Where(w => w.WipID == data.wipID && w.StationID == data.stationID && + w.RuleStatus == data.ruleStatus).ToList(); + wipStations = wipStations.Where(w => w.CreateDate.ToString("yyyy/MM/dd") == today).ToList(); + try + { + // 新增 + if (wipStations.Count() == 0) + { + var firstCnt = 1; + // 有過站資料不能第一次 + if (BarcodeStation) + firstCnt = 0; + + _context.WipStations.Add(new WipStation + { + WipID = data.wipID, + RuleStatus = data.ruleStatus, + StationID = data.stationID, + FirstCnt = firstCnt, + PassCnt = 1, + CreateUserID = data.userID + }); + _context.SaveChangesAsync(); + } + // 更新 + else + { + + // 有資料加1 後續判斷第一次過站 + string updateSql = @" UPDATE JHAMES.WIP_STATION SET PASS_CNT = PASS_CNT + 1 , + UPDATE_DATE = SYSDATE"; + if (!BarcodeStation) + { + updateSql += " , FIRST_CNT = FIRST_CNT + 1 "; + } + updateSql += $@" WHERE WIP_ID = '{data.wipID}' + AND STATION_ID = '{data.stationID}' + AND RULE_STATUS = '{data.ruleStatus}' + AND TO_CHAR(CREATE_DATE , 'YYYY/MM/DD') = '{today}' "; + // 執行原生 SQL + _context.Database.ExecuteSqlRaw(updateSql); + } + } + catch (Exception ex) + { + return ex.InnerException.Message + "
"; + } + return ""; + } + + /// + /// WipClass-各班別數量資料檔 + /// + /// + private string Table_WipClass(BarCodeCheckDtoForDBData data) + { + var BarcodeStation = _context.BarcodeStation.Where(w => w.BarcodeID == data.barcodeID && + w.WipID == data.wipID && w.StationID == data.stationID && + w.FlowRuleID == data.flowRule).Any(); + var today = DateTime.Now.ToString("yyyy/MM/dd"); + // 取ClassID + int ClassID = -1; + var ClassInfo = _context.ClassInfoes.Where(w => w.UnitNo == data.unitNo).ToList(); + + ClassInfo = ClassInfo.Where(w => DateTime.Parse(today + " " + w.BeginTime) <= DateTime.Now && + DateTime.Now <= DateTime.Parse(today + " " + w.EndTime)).ToList(); + if (ClassInfo.Count() != 0) + { + ClassID = ClassInfo.FirstOrDefault().ClassID; + } + + // 判斷是否有資料 + var wipClasses = _context.WipClass.Where(w => w.WipID == data.wipID && w.StationID == data.stationID && + w.RuleStatus == data.ruleStatus && w.ClassID == ClassID).ToList(); + + wipClasses = wipClasses.Where(w => w.CreateDate.ToString("yyyy/MM/dd") == today).ToList(); + + try + { + // 新增 + if (wipClasses.Count() == 0) + { + var firstCnt = 1; + // 有過站資料不能第一次 + if (BarcodeStation) + firstCnt = 0; + _context.WipClass.Add(new WipClass + { + WipID = data.wipID, + RuleStatus = data.ruleStatus, + StationID = data.stationID, + ClassID = ClassID, + FirstCnt = firstCnt, + PassCnt = 1, + CreateUserID = data.userID + }); + _context.SaveChanges(); + } + // 更新 + else + { + // 有資料加1 後續判斷第一次過站 + string updateSql = @" UPDATE JHAMES.WIP_CLASS SET PASS_CNT = PASS_CNT + 1 , + UPDATE_DATE = SYSDATE"; + if (!BarcodeStation) + { + updateSql += " , FIRST_CNT = FIRST_CNT + 1 "; + } + updateSql += $@" WHERE WIP_ID = '{data.wipID}' + AND STATION_ID = '{data.stationID}' + AND RULE_STATUS = '{data.ruleStatus}' + AND CLASS_ID = {ClassID} + AND TO_CHAR(CREATE_DATE , 'YYYY/MM/DD') = '{today}' "; + // 執行原生 SQL + _context.Database.ExecuteSqlRaw(updateSql); + } + } + catch (Exception ex) + { + return ex.InnerException.Message + "
"; + } + return ""; + } + + /// + /// WipTime-工單各站數量資料檔 – By TIME + /// + /// + private string Table_WipTime(BarCodeCheckDtoForDBData data) + { + // 有資料加1 後續判斷第一次過站 + var BarcodeStation = _context.BarcodeStation.Where(w => w.BarcodeID == data.barcodeID && + w.WipID == data.wipID && w.StationID == data.stationID && + w.FlowRuleID == data.flowRule).Any(); + + var today = DateTime.Now.ToString("yyyy/MM/dd"); + // 取SegmentID + int SegmentID = -1; + var timeSegment = _context.TimeSegments.ToList(); + + timeSegment = timeSegment.Where(w => DateTime.Parse(today + " " + w.StartTime) <= DateTime.Now && + DateTime.Now <= DateTime.Parse(today + " " + w.EndTime)).ToList(); + if (timeSegment.Count() != 0) + { + SegmentID = timeSegment.FirstOrDefault().SegmentID; + } + + // 判斷是否有資料 + var wipTimes = _context.WipTimes.Where(w => w.WipID == data.wipID && w.StationID == data.stationID && + w.RuleStatus == data.ruleStatus && w.SegmentID == SegmentID).ToList(); + + + wipTimes = wipTimes.Where(w => w.CreateDate.ToString("yyyy/MM/dd") == today).ToList(); + try + { + // 新增 + if (wipTimes.Count() == 0) + { + var firstCnt = 1; + // 有過站資料不能第一次 + if (BarcodeStation) + firstCnt = 0; + + _context.WipTimes.Add(new WipTime + { + WipID = data.wipID, + RuleStatus = data.ruleStatus, + StationID = data.stationID, + SegmentID = SegmentID, + FirstCnt = firstCnt, + PassCnt = 1, + CreateUserID = data.userID + }); + _context.SaveChanges(); + } + // 更新 + else + { + // 有資料加1 後續判斷第一次過站 + string updateSql = @" UPDATE JHAMES.WIP_TIME SET PASS_CNT = PASS_CNT + 1 , + UPDATE_DATE = SYSDATE"; + if (!BarcodeStation) + { + updateSql += " , FIRST_CNT = FIRST_CNT + 1 "; + } + updateSql += $@" WHERE WIP_ID = '{data.wipID}' + AND STATION_ID = '{data.stationID}' + AND RULE_STATUS = '{data.ruleStatus}' + AND SEGMENT_ID = {SegmentID} + AND TO_CHAR(CREATE_DATE , 'YYYY/MM/DD') = '{today}' "; + // 執行原生 SQL + _context.Database.ExecuteSqlRaw(updateSql); + } + + } + catch (Exception ex) + { + return ex.InnerException.Message + "
"; + } + return ""; + } + + /// + /// WipKp-工單keyParts 長度更新 + /// + /// + /// + private string Table_WipKps(List data, int userId) + { + try + { + // 查看是否有資料 + foreach (var item in data) + { + var wipKp = _context.WipKps.Where(w => w.WipKpID == item.WipKpID).FirstOrDefault(); + if (wipKp != null) + { + wipKp.Length = item.Length; + wipKp.UpdateUserID = userId; + wipKp.UpdateDate = DateTime.Now; + _context.Entry(wipKp).State = EntityState.Modified; + //設置容器空間某一個模型的某一個欄位 不提交到資料庫 + _context.Entry(wipKp).Property("CreateDate").IsModified = false; + _context.Entry(wipKp).Property("CreateUserID").IsModified = false; + _context.SaveChangesAsync(); + } + } + } + catch (Exception ex) + { + return ex.InnerException.Message; + } + return ""; + } + + #endregion + + /// + /// 判斷工單狀態 + /// + /// 工單號碼 + /// 生產單位 + /// 線別 + /// 流程 + /// 作業站ID + /// + [HttpGet("CheckWipNoSation")] + public IActionResult GetCheckWipNoSation(string wipno, string unitno, int line, int flowrule, int stationID) + { + var result = CheckWipNoSationAsync(wipNo: wipno, unitNo: unitno, flowRuleID: flowrule, line: line, stationID: stationID); + return Ok(result.Result); + } + + /// + /// 內部序號查詢工單號碼 + /// + /// 內部序號 + /// Success:true or false + [HttpGet("BarCodeFromWip")] + public async Task CheckBarCodeFromWip(string barcode) + { + ResultModel resultModel = new ResultModel { Success = false }; + if (barcode.Length <= 4) + { + resultModel.Msg = "內部序號小於4個字數"; + return resultModel; + } + + // 內部序號扣除流水號 查詢 + var SerialNumber = await GetWipNoSerialNumber(""); + IQueryable q = _context.WipBarcodes.Where(w => w.StartNO.Substring(0, (barcode.Length - SerialNumber)) == (barcode.Substring(0, (barcode.Length - SerialNumber)))); + if (!q.Any()) + { + resultModel.Msg = "找不到內部序號【" + barcode + "】 對應相關工單號碼"; + return resultModel; + } + else + { + try + { + var No = int.Parse(barcode.Substring(barcode.Length - SerialNumber, SerialNumber)); + foreach (var item in q) + { + int StartNo = int.Parse(item.StartNO.Substring(item.StartNO.Length - SerialNumber, SerialNumber)); + int EndNo = int.Parse(item.EndNO.Substring(item.EndNO.Length - SerialNumber, SerialNumber)); + if (StartNo <= No && No <= EndNo) + { + resultModel.Success = true; + resultModel.Msg = q.Select(s => s.WipNO).FirstOrDefault(); + return resultModel; + } + } + resultModel.Msg = "工單號碼【" + q.Select(s => s.WipNO).FirstOrDefault() + "】 找不到範圍內的內部序號"; + } + catch (Exception ex) + { + resultModel.Msg = ex.Message; + } + } + + return resultModel; + } + + /// + /// 查詢序號是否有在該工單 條碼區間內 + /// + /// 內部序號 + /// 工單號碼 + [HttpGet("CheckBarCodeByWipNo")] + public async Task> CheckBarCodeByWipNo(string barcode, string wipNo) + { + ResultModel resultModel = new ResultModel { Success = false }; + if (barcode.Length <= 4) + { + resultModel.Msg = "內部序號小於4個字數"; + return resultModel; + } + + // 內部序號扣除流水號 查詢 + var q = await _context.WipBarcodes.Where(w => w.WipNO == wipNo).ToListAsync(); + if (!q.Any()) + { + resultModel.Msg = "找不到工單號碼【" + wipNo + "】 有設定條碼區間"; + return resultModel; + } + else + { + try + { + // 刷入資料 = 條碼起始 或 條碼結束 都符合條碼區間 + if (q.Where(w => w.StartNO == barcode || w.EndNO == barcode).Any()) + { + resultModel.Success = true; + return resultModel; + } + + // 取工單號碼最大工單數量 + int snLen = await GetWipNoSerialNumber(wipNo); + // 93200036400001 9320003640001 + var No = int.Parse(barcode.Substring(barcode.Length - snLen, snLen)); + foreach (var item in q.Where(w => w.StartNO.Substring(0, barcode.Length - snLen) == barcode.Substring(0, barcode.Length - snLen) + && w.StartNO.Length == barcode.Length)) + { + int StartNo = int.Parse(item.StartNO.Substring(item.StartNO.Length - snLen, snLen)); + int EndNo = int.Parse(item.EndNO.Substring(item.EndNO.Length - snLen, snLen)); + if (StartNo <= No && No <= EndNo) + { + resultModel.Success = true; + return resultModel; + } + } + resultModel.Msg = "工單號碼【" + wipNo + "】 找不到範圍內的內部序號【" + barcode + "】"; + } + catch (Exception ex) + { + resultModel.Msg = ex.Message; + } + } + return resultModel; + } + + /// + /// 內部序號是否鎖定 + /// + /// 內部序號ID + /// 內部序號 + /// Success:true or false + [HttpGet("BarCodeLock")] + public async Task> CheckBarCodeLockAsync(int barCode, string barCodeNo) + { + ResultModel resultModel = new ResultModel { Success = false }; + if (barCodeNo.Length <= 4) + { + resultModel.Msg = "內部序號小於4個字數"; + return resultModel; + } + + // 第一次投入 沒有資料 不用判斷 + if (barCode == 0) + { + resultModel.Success = true; + return resultModel; + } + + var BarCodeLock = _context.BarcodeLocks.Where(w => w.BarcodeID == barCode && w.LockStatus == 0).FirstOrDefaultAsync(); + if (await BarCodeLock != null) + { + resultModel.Msg = $"內部序號【{barCodeNo}】在當前站別被鎖定,不可過站"; + return resultModel; + } + + resultModel.Success = true; + return resultModel; + } + + /// + /// 內部序號是否報廢 + /// + /// 內部序號ID + /// 內部序號 + /// Success:true or false + [HttpGet("BarCodeScrapped")] + public async Task> CheckBarCodeScrappedAsync(int barCode, string barCodeNo) + { + ResultModel resultModel = new ResultModel { Success = false }; + if (barCodeNo.Length <= 4) + { + resultModel.Msg = "內部序號小於4個字數"; + return resultModel; + } + + var BarCodeInfo = await _context.BarcodeInfoes.Where(w => w.BarcodeID == barCode).FirstOrDefaultAsync(); + if (BarCodeInfo != null) + { + if (BarCodeInfo.RuleStatus == "S") + { + resultModel.Msg = $"內部序號【{barCodeNo}】已報廢, 不可繼續過站!"; + return resultModel; + } + if (BarCodeInfo.RuleStatus == "C") + { + resultModel.Msg = $"內部序號【{barCodeNo}】已轉出, 不可繼續過站!"; + return resultModel; + } + } + + resultModel.Success = true; + return resultModel; + } + + /// + /// 確認內部條碼流動 + /// + /// 工單號碼ID + /// 內部條碼ID + /// 內部條碼 + /// 作業站編號 + /// + [HttpGet("BarCodeFlow")] + private async Task> CheckBarCodeFlowAsync(int wipId, int barCode, string barCodeNo, int stationID) + { + ResultModel resultModel = new ResultModel { Success = false }; + var WipInfo = await _context.WipInfos.Where(w => w.WipID == wipId).FirstOrDefaultAsync(); + + // 取工單號碼開立的 WipID、生產單位 + var WipInfos = await _context.WipInfos.Where(w => w.WipNO == WipInfo.WipNO).Select(s => new { s.WipID, s.UnitNO }).ToListAsync(); + + // 取內部序號過站紀錄 + var BarCodeStations = await _context.BarcodeStation.Where(w => w.BarcodeID == barCode).ToListAsync(); + + // 判斷需要前製程是否已經投入 + if (WipInfo.InputFlag == "Y") + { + // 有BarCodeID + if (barCode != 0) + { + // 判斷是否有前製程過站資料 + // SMT(S)->DIP(D) + if (WipInfo.UnitNO == "D") + { + int? WipID = WipInfos.Where(w => w.UnitNO == "S").Select(s => s.WipID).FirstOrDefault(); + if (WipID == null) + { + resultModel.Msg = $"該工單號碼【{WipInfo.WipNO}】的前製程生產單位尚未建立工單基本資料"; + return resultModel; + } + + if (!BarCodeStations.Where(w => w.BarcodeID == barCode && w.WipID == WipID && w.RuleStatus == "P").Any()) + { + resultModel.Msg = $"該內部序號【{barCodeNo}】前製程生產單位尚未有過站紀錄"; + return resultModel; + } + } + // 組裝(B)->系統測試(T)->成品包裝(P) + else if (WipInfo.UnitNO == "T") + { + int? WipID = WipInfos.Where(w => w.UnitNO == "B").Select(s => s.WipID).FirstOrDefault(); + if (WipID == null) + { + resultModel.Msg = $"該工單號碼【{WipInfo.WipNO}】的前製程生產單位尚未建立工單基本資料"; + return resultModel; + } + + if (!BarCodeStations.Where(w => w.BarcodeID == barCode && w.WipID == WipID && w.RuleStatus == "P").Any()) + { + resultModel.Msg = $"該內部序號【{barCodeNo}】前製程生產單位尚未有過站紀錄"; + return resultModel; + } + } + else if (WipInfo.UnitNO == "P") + { + int? WipID = WipInfos.Where(w => w.UnitNO == "T").Select(s => s.WipID).FirstOrDefault(); + if (WipID == null) + { + resultModel.Msg = $"該工單號碼【{WipInfo.WipNO}】的前製程生產單位尚未建立工單基本資料"; + return resultModel; + } + + if (!BarCodeStations.Where(w => w.BarcodeID == barCode && w.WipID == WipID && w.RuleStatus == "P").Any()) + { + resultModel.Msg = $"該內部序號【{barCodeNo}】前製程生產單位尚未有過站紀錄"; + return resultModel; + } + } + } + // 沒有BarCodeID + else + { + if (WipInfo.UnitNO != "S" && WipInfo.UnitNO != "B") + { + resultModel.Msg = $"該工單號碼【{WipInfo.WipNO}】前製程式尚未投產"; + return resultModel; + } + } + } + #region 判斷作業站順序 + + // 判斷序號目前是否有重複過站 + var BarcodeInfo = await _context.BarcodeInfoes.Where(w => w.BarcodeID == barCode && w.StationID == stationID).FirstOrDefaultAsync(); + if (BarcodeInfo != null) + { + resultModel.Msg = $"該內部序號【{barCodeNo}】已刷過此站"; + return resultModel; + } + + resultModel = (ResultModel)await GetBarCodeLastStopRuleStationID(wipId, barCode, stationID, WipInfo.FlowRuleID); + if (!resultModel.Success) + return resultModel; + + #endregion + resultModel.Success = true; + return resultModel; + } + + /// + /// 確認工單狀態 + /// + /// 工單號碼 + /// 生產單位 + /// 流程 + /// 線別 + /// 作業站 + /// 生產條碼 + /// + private async Task> CheckWipNoSationAsync(string wipNo, string unitNo, int flowRuleID, int line, int stationID = 0, string barCodeNo = "") + { + ResultModel resultModel = new ResultModel() { Success = false }; + var WipInfo = await _context.WipInfos.Where(w => w.WipNO == wipNo).ToListAsync(); + + if (WipInfo.Count() == 0) + { + resultModel.Msg = "找不到工單號碼【" + wipNo + "】"; + return resultModel; + } + + if (!WipInfo.Where(w => w.UnitNO == unitNo).Any()) + { + resultModel.Msg = "工單號碼【" + wipNo + ",尚未設定此生產單位"; + return resultModel; + } + + if (!WipInfo.Where(w => w.UnitNO == unitNo && w.LineID == line).Any()) + { + resultModel.Msg = "工單號碼【" + wipNo + "】,尚未設定此線別"; + return resultModel; + } + + if (!WipInfo.Where(w => w.UnitNO == unitNo && w.LineID == line && w.FlowRuleID == flowRuleID).Any()) + { + resultModel.Msg = "工單號碼【" + wipNo + "】,尚未設定此流程站"; + return resultModel; + } + + // 抓單筆資料 + var item = WipInfo.Where(w => w.UnitNO == unitNo && w.LineID == line).FirstOrDefault(); + + if (item.StatusNO == "E") + { + resultModel.Msg = $"工單號碼【{item.WipNO}】,該工單已經投入完工,請切換工單"; + return resultModel; + } + + if (item.StatusNO == "C") + { + resultModel.Msg = $"工單號碼【{item.WipNO}】,該工單已刪除,請切換工單"; + return resultModel; + } + + // 判斷是否是投入站 + var RuleStation = await _context.RuleStations.Where(w => w.FlowRuleID == flowRuleID && w.StationID == stationID) + .FirstOrDefaultAsync(); + if (RuleStation != null) + { + if (RuleStation.Sequence == 1) + { + var LineInfo = await _context.LineInfoes.Where(w => w.WipNo == item.WipID && w.LineID == item.LineID).FirstOrDefaultAsync(); + if (LineInfo == null) + { + //resultModel.Msg = $"工單號碼【{item.WipNO}】,工單尚未開線,不可過站"; + //return resultModel; + + //因維修後投入站 不須重開線 + if (!await _context.BarcodeInfoes.Where(w => w.WipID == item.WipID && w.BarcodeNo == barCodeNo).AnyAsync()) + { + resultModel.Msg = $"工單號碼【{item.WipNO}】,工單尚未開線,不可過站"; + return resultModel; + } + } + } + } + + // 已投入數量>=工單數量 + if (await CheckNowFirstStation(item.WipID, stationID) == "Y") + { + if (item.CompleteQTY >= item.PlanQTY) + { + //因維修後投入站 不須判斷投入數量 + if (!await _context.BarcodeInfoes.Where(w => w.WipID == item.WipID && w.BarcodeNo == barCodeNo).AnyAsync()) + { + resultModel.Msg = $"工單號碼【{item.WipNO}】,已投入數量>=工單數量,請在確認"; + return resultModel; + } + } + } + + // 該筆工單號碼鎖定 + var WipLock = await _context.WipLocks.Where(w => w.WipNO == item.WipNO && w.LockStatus == "0").ToListAsync(); + if (WipLock.Where(w => w.StationID == 0).Any()) + { + resultModel.Msg = $"工單號碼【{item.WipNO}】,已被鎖定,不可過站"; + return resultModel; + } + + // StationID = 0 代表批次鎖定 + else if (WipLock.Where(w => w.StationID == stationID).Any()) + { + resultModel.Msg = $"工單號碼【{item.WipNO}】,工單在當前站別被鎖定,不可過站"; + return resultModel; + } + + resultModel.Success = true; + return resultModel; + } + + /// + /// 判斷序號狀態 + /// + /// 內部序號ID + /// 內部序號 + /// + [HttpGet("CheckBarCodeStation")] + public async Task> GetCheckBarCodeStation(int barCode, string barCodeNo) + { + ResultModel resultModel = new ResultModel(); + + #region 內部序號是否被鎖定 + resultModel = await CheckBarCodeLockAsync(barCode, barCodeNo); + if (!resultModel.Success) + return resultModel; + #endregion + + #region 內部序號是否被報廢 + resultModel = await CheckBarCodeScrappedAsync(barCode, barCodeNo); + if (!resultModel.Success) + return resultModel; + #endregion + + return resultModel; + } + + /// + /// 燒機判斷 + /// + /// 工單號碼 + /// 內部序號ID + /// 作業站ID + /// 過站狀態Pass Fail + /// + private async Task> GetCheckBurn(string wipNo, int barcodeID, int stationID, string ruleStatus) + { + ResultModel resultModel = new ResultModel() { Success = false }; + // 判斷是否有燒機時間 + var wipBoard = await _context.WipBoards.Where(w => w.WipNo == wipNo).FirstOrDefaultAsync(); + var wipSystem = await _context.WipSystems.Where(w => w.WipNo == wipNo).FirstOrDefaultAsync(); + var wipBoardTime = 0.0; + var wipSystemTime = 0.0; + + if (wipBoard != null) + { + try + { + if (!string.IsNullOrWhiteSpace(wipBoard.BiTime)) + wipBoardTime = double.Parse(wipBoard.BiTime); + + } + catch + { + wipBoardTime = -1; + } + } + + if (wipSystem != null) + { + try + { + if (!string.IsNullOrWhiteSpace(wipSystem.BiTime)) + wipSystemTime = double.Parse(wipSystem.BiTime); + + } + catch + { + wipSystemTime = -1; + } + } + + if (wipBoardTime <= 0 && wipSystemTime <= 0) + { + resultModel.Msg = "請確認燒機時間是否有填寫或者格式有誤"; + return resultModel; + } + + // 判斷燒機時間是否足夠 + var burnInfo = await _context.BurnInfos.Where(w => w.BarcodeID == barcodeID).ToListAsync(); + if (burnInfo.Count() != 0) + { + // 取實際燒機完成時間 空白資料 + var item = burnInfo.Where(w => string.IsNullOrWhiteSpace(w.FinishTime.ToString())).FirstOrDefault(); + if (item != null) + { + // 現在時間 < 預計排程時間 + if (DateTime.Now < item.ScheduleFinishTime) + { + resultModel.Msg = "燒機排程完成時間【" + item.ScheduleFinishTime + "】尚未到達"; + return resultModel; + } + } + else // 燒機資料都有填入實際燒機時間 + { + resultModel.Msg = "BurnIn"; + } + } + else + // 沒有BurnInfo = Burn In + { + resultModel.Msg = "BurnIn"; + } + resultModel.Success = true; + return resultModel; + } + + /// + /// 確認組件狀態 + /// + /// + [HttpGet("BarCodeKP")] + private async Task> CheckBarCodeKeyPartsData([FromQuery] BarcodeItemKPDto data) + { + ResultModel resultModel = new ResultModel { Success = false }; + // 更新WipKp字元長度 + var UpdateWipKpLength = new List(); + try + { + // 抓 工單key Parts資料 + var wipKps = _context.WipKps.Where(w => w.WipNo == data.wipNo && w.UnitNo == data.ststionUnitNo) + .OrderBy(o => o.KpSeq).ToList(); + if (wipKps.Count != 0) + { + // 取料號組件資料 + var BarCodeItems = _context.BarcodeItems.Where(w => w.BarcodeID == data.barCode && + w.S.UnitNo == data.ststionUnitNo && + w.WipID == data.wipId).ToList(); + + // 當前組件數量+已存料號組件數量 > 工單綁定組件數量 + if (data.inputKP.Count + BarCodeItems.Count > wipKps.Count) + { + resultModel.Msg = "組件數量已刷超過設定數量,請確認"; + return resultModel; + } + + #region 比對組件資料 + + var CheckMsg = string.Empty; + int x = BarCodeItems.Count; + + // 紀錄刷入KP不可重複序號,後續判斷刷入KP有重複 + var CheckInputKp = new List(); + + for (int i = 0; i < data.inputKP.Count; i++) + { + // 按照順序 + var wipKpsItem = wipKps[x + i]; + var dataItem = data.inputKP[i]; + // 有KpNo以KpNo為主 + if (!string.IsNullOrWhiteSpace(dataItem.inputType)) + { + wipKpsItem = wipKps.Where(w => w.KpNo.ToUpper() == dataItem.inputType.ToUpper()).FirstOrDefault(); + + if (wipKpsItem == null) + { + wipKpsItem = wipKps[x + i]; + } + } + + CheckMsg += await CheckKeyPartsCorrect(wipKpsItem, dataItem); + } + + // 有錯誤訊息 + if (!string.IsNullOrWhiteSpace(CheckMsg)) + { + resultModel.Msg = CheckMsg; + return resultModel; + } + + // 刷入KP有重複 + var RepeatKp = CheckInputKp + .GroupBy(g => g.inputData) + .Where(group => group.Count() > 1) + .Select(group => group.Key); + + if (RepeatKp.Count() != 0) + { + resultModel.Msg = $"刷入組件序號有重複【{string.Join(',', RepeatKp)}】
"; + return resultModel; + } + + #endregion + } + + // 確認沒問題後 + resultModel.Data = UpdateWipKpLength; + resultModel.Success = true; + return resultModel; + } + catch (Exception ex) + { + resultModel.Success = false; + resultModel.Msg = ex.Message; + return resultModel; + } + } + + /// + /// 確認治具狀態 + /// + /// + private ResultModel CheckBarCodeOutfitAsync([FromQuery] List outfit) + { + ResultModel resultModel = new ResultModel { Success = false }; + + #region 判斷是否有治具編號 + + OutfitInfoesController outfitInfoesController = new OutfitInfoesController(_context); + OutfitCommodityInfoesController outfitCommodityInfoesController = new OutfitCommodityInfoesController(_context); + foreach (var outfitNo in outfit) + { + var q = outfitInfoesController.GetOutfitInfoByOutfitNo(outfitNo.inputData.ToUpper()).Result; + + if (q.Value == null) + { + resultModel.Msg = "中央治具找不到該治具編號【" + outfitNo.inputData + "】"; + return resultModel; + } + + // 判斷治具種類 + var q1 = outfitCommodityInfoesController.GetOutfitCommodityInfo().Result; + if (!q1.Value.Where(w => w.CommodityID == q.Value.CommodityID && w.CommodityNo == outfitNo.PartNo).Any()) + { + resultModel.Msg = "刷入治具編號【" + outfitNo.inputData + "】總類不一致,請確認"; + return resultModel; + } + } + + #endregion + + resultModel.Success = true; + return resultModel; + } + + /// + /// 取得上一個作業站RuleStationID + /// + /// 工單ID + /// BarCodeID + /// 目前作業站ID + /// 工單流程ID + /// true:false + private async Task GetBarCodeLastStopRuleStationID(int wipID, int barCodeID, int stationID, int flowRuleID) + { + ResultModel resultModel = new ResultModel { Success = false }; + + // 用作業站抓 有設定下一站為該站的資料 + var Rules = await _context.Ruleses.Where(w => w.FlowRuleID == flowRuleID).ToListAsync(); + // 取得目前BarCodeInfo 站別 + var BarCodeInfo = await _context.BarcodeInfoes.Where(w => w.BarcodeID == barCodeID).FirstOrDefaultAsync(); + + if (Rules.Count() == 0) + { + resultModel.Msg = "找不到該筆工單流程之流程設定相關資料,請確認"; + return resultModel; + } + else + { + // 有過站紀錄 + if (BarCodeInfo != null) + { + // 如果BarCodeInfo 結案,判斷當下作業站是否第一站 + if (BarCodeInfo.StatusID == -1) + { + if (BarCodeInfo.WipID == wipID) + { + resultModel.Msg = "該內部序號在目前生產製程已完工,請確認"; + return resultModel; + } + + if (!Rules.Where(w => w.StationID == stationID && w.RuleSeq == 1 && w.RuleStatus == "P").Any()) + { + resultModel.Msg = "目前作業站不是第一站,請確認"; + return resultModel; + } + resultModel.Success = true; + return resultModel; + } + + if (BarCodeInfo.WipID != wipID) + { + resultModel.Msg = $"前一製程還未結束,請確認"; + return resultModel; + } + + // 目前BarCodeInfo StationID 取得相對應下個流程StationID + var rulesByBarCodeInfoStationID = Rules.Where(w => w.StationID == BarCodeInfo.StationID).ToList(); + + // 當下個流程 != 目前過站流程 + if (rulesByBarCodeInfoStationID.Where(w => w.NextStationID == stationID && w.RuleStatus == BarCodeInfo.RuleStatus).Count() == 0) + { + var Nextstation = rulesByBarCodeInfoStationID.Where(w => w.RuleStatus == BarCodeInfo.RuleStatus).ToList(); + var StationName = Nextstation.Select(s => s.NextStation.StationName).ToArray(); + resultModel.Msg = "該內部序號下一個作業站應該是:" + string.Join('、', StationName) + " ,請確認"; + return resultModel; + } + } + // 沒有過站紀錄 判斷是否為投入站 + else + { + if (!Rules.Where(w => w.StationID == stationID && w.RuleSeq == 1 && w.RuleStatus == "P").Any()) + { + resultModel.Msg = "該內部序號尚未投入,請確認"; + return resultModel; + } + } + } + resultModel.Success = true; + return resultModel; + } + + /// + /// 確認下一站為完工 + /// + /// 流程ID + /// 作業站ID + /// 過站狀態 Pass or Fail + /// Success(true)是 (false)不是 + [HttpGet("CheckNextStopCloseStation")] + public async Task> CheckNextStopCloseStation(int flowRuleId, int stationID, string ruleStatus) + { + ResultModel resultModel = new ResultModel { Success = false }; + + // 取得流程 + var ruleStations = await _context.RuleStations.Where(w => w.FlowRuleID == flowRuleId).ToListAsync(); + if (ruleStations.Any()) + { + // 在RuleStation 找不到該作業站 + if (!ruleStations.Where(w => w.StationID == stationID).Any()) + return resultModel; + + var rules = await _context.Ruleses.Where(w => w.FlowRuleID == flowRuleId).ToListAsync(); + + // 當下一站SatationID= 1000 代表完工站 + if (rules.Where(w => w.StationID == stationID && w.NextStationID == 1000 && w.RuleStatus == ruleStatus).Any()) + { + resultModel.Success = true; + return resultModel; + } + } + return resultModel; + } + + /// + /// 確認目前該站是否為第一站 + /// + /// 工單號碼ID + /// 作業站ID + /// Y:是 N:不是 + private async Task CheckNowFirstStation(int wipId, int stationID) + { + var WipInfo = await _context.WipInfos.Where(w => w.WipID == wipId).FirstOrDefaultAsync(); + + if (WipInfo != null) + { + // 取得流程 + var ruleStations = await _context.RuleStations.Where(w => w.FlowRuleID == WipInfo.FlowRuleID).ToListAsync(); + if (ruleStations.Count() != 0) + { + // 用目前站別判斷順序是不是 1 + if (ruleStations.Where(w => w.StationID == stationID && w.Sequence == 1 && w.StationType == "M").Any()) + return "Y"; + } + } + return "N"; + } + + /// + /// 判斷生產中工單是否已經全部完工 自動更新 + /// + /// 工單ID + /// + [HttpGet("CheckWipNoBarCodeAllClost")] + public async Task CheckWipNoBarCodeAllClost(int wipId) + { + var wipInfo = await _context.WipInfos.Where(w => w.WipID == wipId).FirstOrDefaultAsync(); + + if (wipInfo != null) + { + // 取Rules 最後一站為完工站的Station及狀態 + var rules = await _context.Ruleses.Where(w => w.FlowRuleID == wipInfo.FlowRuleID).ToListAsync(); + var lastStation = rules.Where(w => w.NextStationID == 1000).Select(s => new { s.StationID, s.RuleStatus }).ToList(); + + var barcodeStations = await _context.BarcodeStation.Where(w => w.WipID == wipId).ToListAsync(); + + // ByLastStation Count = 工單數 (完工) + var closeWipQty = 0; + foreach (var item in lastStation) + { + closeWipQty += barcodeStations.Where(w => item.StationID == w.StationID && item.RuleStatus == w.RuleStatus) + .Select(s => s.BarcodeID).Distinct().Count(); + } + + if (wipInfo.PlanQTY == closeWipQty) + { + WipInfosController wipInfosController = new WipInfosController(_context); + var result = await wipInfosController.PutWipinfoToStatusNO(wipId, "E"); + // 呼叫CTO + string getUrl = $"https://nportal.avalue.com.tw/avaluecto/ctoamesmodone.aspx?orderno={wipInfo.WipNO}"; + await MakeGetRequest(getUrl); + } + } + return ""; + } + + /// + /// 無序號工單批次作業 + /// + /// + /// + [HttpGet("CreateBarcodeInfobyPCS038")] + public async Task CreateBarcodeInfobyPCS038(int WipID) + { + ResultModel resultModel = new ResultModel { Success = true }; + + var wipinfo = await _context.WipInfos.Where(w => w.WipID == WipID).FirstOrDefaultAsync(); + if (wipinfo != null) + { + var wipbarcode = await _context.WipBarcodes.Where(w => w.WipNO == wipinfo.WipNO).ToListAsync(); + string resultMsg = ""; + if (wipbarcode.Count() != 0) + { + // 取BarCodeID + Helper helper = new Helper(_context); + foreach (var item in wipbarcode) + { + string start = item.StartNO; + string end = item.EndNO; + + // 取得流水號的長度 + int serialLength = start.Length - 4; + + // 將起始跟結束序號的流水號轉換為數字 + int startSerial = int.Parse(start.Substring(start.Length - 4)); + int endSerial = int.Parse(end.Substring(end.Length - 4)); + + // 進行序號展開 + for (int i = startSerial; i <= endSerial; i++) + { + string serial = i.ToString().PadLeft(4, '0'); + string code = start.Substring(0, start.Length - 4); + + string barcode = code + serial; + BarCodeCheckDtoForDBData data = new BarCodeCheckDtoForDBData(); + data.unitNo = wipinfo.UnitNO; + data.wipID = WipID; + data.barcode = barcode; + data.barcodeID = 0; + data.extNo = ""; + data.flowRule = wipinfo.FlowRuleID; + data.wipNo = wipinfo.WipNO; + var Msg = Table_BarcodeInfo(data, await helper.GetIDKey("BARCODE_ID")); + + if (string.IsNullOrWhiteSpace(Msg)) + { + resultMsg += $"{code + serial} 內部條碼:產生成功!!!" + "
"; + } + else + { + resultMsg += $"{code + serial} 內部條碼:產生失敗!!!原因:" + Msg + "
"; + } + } + + resultModel.Success = true; + } + } + else + { + resultModel.Success = false; + resultModel.Msg = "工單資料沒有設定生產序號區間"; + } + } + else + { + resultModel.Success = false; + resultModel.Msg = "查無工單"; + } + return resultModel; + } + + /// + /// 確認治具是否已達到預警提前次數 + /// + /// + private void CheckOutfitAlert(string WipNo) + { + + } + + /// + /// 確認過站基本欄位是否填寫 + /// + /// + /// + private string CheckBarCodeInputData(BarCodeCheckDto barCodeCheckDto) + { + string Msg = string.Empty; + if (string.IsNullOrWhiteSpace(barCodeCheckDto.wipNo)) + Msg += "請輸入工單號碼,"; + + if (string.IsNullOrWhiteSpace(barCodeCheckDto.barcode)) + Msg += "請輸入內部條碼,"; + + if (string.IsNullOrWhiteSpace(barCodeCheckDto.unitNo)) + Msg += "請輸入生產單位,"; + + if (barCodeCheckDto.stationID == 0) + Msg += "請輸入作業站代碼,"; + + if (barCodeCheckDto.line == 0) + Msg += "請輸入線別代碼,"; + + // 判斷User存在 + if (barCodeCheckDto.userID != 0) + { + if (_context.UserInfoes.Where(w => w.UserID == barCodeCheckDto.userID).Count() == 0) + Msg += $"找不到UserID【{barCodeCheckDto.userID}】資料,"; + } + + if (!string.IsNullOrWhiteSpace(Msg)) + Msg = Msg.Substring(0, Msg.Length - 1); + + return Msg; + } + + /// + /// 過站相關資訊 寫入 + /// + /// + /// + private async Task PassIngDataTuck(BarCodeCheckDto barCodeCheckDto) + { + var result = new BarCodeCheckDtoForDBData(); + + result.wipNo = barCodeCheckDto.wipNo.Trim().ToUpper(); + result.barcode = barCodeCheckDto.barcode.Trim().ToUpper(); + result.barcodeType = barCodeCheckDto.barcodeType; + result.unitNo = barCodeCheckDto.unitNo; + result.stationID = barCodeCheckDto.stationID; + result.line = barCodeCheckDto.line; + result.userID = barCodeCheckDto.userID; + + #region 相關資料 Null給空白 + // KP||NG Input + if (barCodeCheckDto.inputItems == null) + result.inputItems = new List(); + else + result.inputItems = barCodeCheckDto.inputItems.Where(w => !string.IsNullOrWhiteSpace(w.inputType)).ToList(); + + // 治具 Input + if (barCodeCheckDto.outfits == null) + result.outfits = new List(); + else + result.outfits = barCodeCheckDto.outfits.Where(w => !string.IsNullOrWhiteSpace(w.inputData)).ToList(); + + #endregion + + // 工單資料 + var WipInfo = await _context.WipInfos.Where(w => w.WipNO == barCodeCheckDto.wipNo && + w.UnitNO == barCodeCheckDto.unitNo && + w.LineID == barCodeCheckDto.line).FirstOrDefaultAsync(); + if (WipInfo != null) + { + result.wipID = WipInfo.WipID; + result.flowRule = WipInfo.FlowRuleID; + } + + // 料號 + var WipAtt = await _context.WipAtts.Where(w => w.WipNO == barCodeCheckDto.wipNo.Trim().ToUpper()).FirstOrDefaultAsync(); + if (WipAtt != null) + { + result.itemNo = WipAtt.ItemNO; + var MaterialItem = await _context.MaterialItems.Where(w => w.ItemNo == result.itemNo).FirstOrDefaultAsync(); + if (MaterialItem != null) + { + // 料號ID + result.item = MaterialItem.ItemID; + } + } + + // 工作站 + var Station = await _context.Stationses.Where(w => w.StationID == result.stationID).FirstOrDefaultAsync(); + if (Station != null) + { + result.stations_TestType = Station.TestType; + result.stations_TypeNo = Station.TypeNo; + result.stations_UnitNo = Station.UnitNo; + result.stations_Name = Station.StationName; + } + + // 生產單位_簡碼 + var FactoryUnit = await _context.FactoryUnits.Where(w => w.UnitNo == result.unitNo).FirstOrDefaultAsync(); + if (FactoryUnit != null) + { + result.factoryUnit_UnitCode = FactoryUnit.UnitCode; + } + + // 判斷序號為出貨條碼,並轉成內部條碼 + var BarCodeInfo = await _context.BarcodeInfoes.Where(w => w.ExtraBarcodeNo == barCodeCheckDto.barcode.Trim()).FirstOrDefaultAsync(); + if (BarCodeInfo != null) + { + result.extNo = BarCodeInfo.ExtraBarcodeNo; + result.barcode = BarCodeInfo.BarcodeNo; + } + + // 抓BarCode ID + BarCodeInfo = await _context.BarcodeInfoes.Where(w => w.BarcodeNo == result.barcode).FirstOrDefaultAsync(); + if (BarCodeInfo != null) + { + result.barcodeID = BarCodeInfo.BarcodeID; + } + + // 過站狀態 + if (result.inputItems.Where(w => w.inputData.Contains("$")).Any()) + result.ruleStatus = "F"; + else + result.ruleStatus = "P"; + + return result; + } + + /// + /// 確認過站資料是否正確 + /// + /// + /// + private async Task CheckPassIngDataCorrect(BarCodeCheckDtoForDBData data) + { + string Msg = string.Empty; + + if (data.wipID == 0) + Msg += $"找不到工單號碼【{data.wipNo}】相關工單資料,請確認,"; + + if (data.flowRule == 0) + Msg += $"工單號碼【{data.wipNo}】尚未設定流程,請確認,"; + + // 抓流程順序資料 + var ruleStations = await _context.RuleStations.Where(w => w.FlowRuleID == data.flowRule).ToListAsync(); + if (ruleStations.Count() == 0) + { + Msg += $"該工單號碼【{data.wipNo}】的流程編號尚未設定流程"; + } + else + { + if (!ruleStations.Where(w => w.StationID == data.stationID).Any()) + { + Msg += $"該工單號碼【{data.wipNo}】的流程未設定此作業站"; + } + } + + // 判斷有無不良代碼 + if (data.inputItems.Where(w => w.inputData.Contains("$")).Any()) + { + var NgItem = data.inputItems.Where(w => w.inputData.Contains("$")).ToList(); + IQueryable q = _context.NGReasons; + foreach (var item in NgItem.Select(s => s.inputData)) + { + if (!q.Where(w => w.NGReasonNo.Trim().ToUpper() == item.Replace("$", "").Trim().ToUpper() + && w.Status == "A").Any()) + { + Msg += $"查無不良代碼【{item.Replace("$", "").Trim().ToUpper()}】,請確認,"; + } + } + } + + // 維修過站資料判斷 + if (data.barcodeType == "S") + { + // 確認新舊組件序號是否都有值 + if (data.inputItems.Where(w => w.inputType.ToUpper() != "NG" && + (string.IsNullOrWhiteSpace(w.inputData) || string.IsNullOrWhiteSpace(w.oldInputData))).Any()) + { + Msg += "工單號碼【" + data.wipNo + "】維修過站資料有缺新舊組件序號,請確認,"; + } + } + + if (!string.IsNullOrWhiteSpace(Msg)) + Msg = Msg.Substring(0, Msg.Length - 1); + + return Msg; + } + + /// + /// KeyPart 細項判斷確認 + /// + /// 工單組件資料 + /// 過站刷入組件資料 + /// + private async Task CheckKeyPartsCorrect(WipKp wipKp, BarCodeCheckDto.inputItem inputItem) + { + string CheckMsg = string.Empty; + #region 比對序號長度是否正確 + + if (wipKp.Length != null) + { + if (wipKp.Length != inputItem.inputData.Length && wipKp.Length != 0) + CheckMsg += "組件序號【" + inputItem.inputData + "】 與組件名稱【" + wipKp.KpName + "】長度不符合
"; + } + + #endregion + + #region 前置碼正確 + + if (!string.IsNullOrWhiteSpace(wipKp.Title)) + { + if (!inputItem.inputData.ToUpper().StartsWith(wipKp.Title.ToUpper())) + CheckMsg += "組件序號【" + inputItem.inputData + "】 與組件名稱【" + wipKp.Title + "】前置碼不符合
"; + } + #endregion + + #region 組件代碼-組件序號是否重複 + + // 抓C_SFIS_KEYPARTS (安勤轉拋) + if (await _context.CSfisKeyparts.Where(w => w.Partbarcode.ToUpper() == inputItem.inputData).AnyAsync()) + { + CheckMsg += "組件名稱【" + wipKp.KpName + "】已有相同組件序號【" + inputItem.inputData + "】安勤轉拋KeyParts紀錄
"; + } + + if (await _context.BarcodeItems.Where(w => w.ItemNo.ToUpper() == wipKp.KpNo.ToUpper() && w.PartNo == inputItem.inputData).AnyAsync()) + { + CheckMsg += "組件名稱【" + wipKp.KpName + "】已有相同組件序號【" + inputItem.inputData + "】紀錄
"; + } + + #endregion + + #region 判斷組件序號是否在製狀態 + + if (wipKp.KpNo.ToUpper() == "04") + { + if (await _context.BarcodeInfoes.Where(w => w.BarcodeNo == inputItem.inputData.ToUpper().Trim() && w.StatusID != -1).AnyAsync()) + { + CheckMsg += "組件序號【" + inputItem.inputData + "】 目前是在製狀態
"; + } + } + + #endregion + + #region 安勤不需要判斷MAC區間 + //if (wipKp.KpNo.ToUpper().StartsWith("MAC")) + //{ + // var wipMAC = await _context.WipMACs.Where(w => w.WipNO == wipKp.WipNo).ToListAsync(); + // if (wipMAC.Count() == 0) + // { + // CheckMsg += "工單號碼【" + wipKp.WipNo + "】 找不到綁定MAC區間
"; + // } + // else + // { + // // 判斷是否符合區間 + // if (inputItem.inputData.Length != 12 && inputItem.inputData.Length != 6) + // { + // CheckMsg += "組件序號【" + inputItem.inputData + "】 綁定MAC不足12碼或6碼
"; + // } + // else + // { + // // 長度12碼 判斷前置碼 + // if (inputItem.inputData.Length == 12) + // { + // if (!wipMAC.Where(w => inputItem.inputData.StartsWith(w.Title)).Any()) + // { + // CheckMsg += $"組件序號【{inputItem.inputData}】與MAC【{string.Join('、', wipMAC.Select(s => s.Title).ToList())}】前置碼不符合
"; + // } + // } + // // 長度6碼 抓WIPMAC 前6碼補足 12碼 + // else if (inputItem.inputData.Length == 6) + // { + // var wipMacItem = wipMAC.FirstOrDefault(); + // inputItem.inputData = wipMacItem.Title + inputItem.inputData; + // } + + // var InputMacTitle = inputItem.inputData.Substring(0, 6).ToUpper(); + // var InputMacNo = Convert.ToInt32(inputItem.inputData.Substring(6, 6), 16); + // if (!wipMAC.Where(w => Convert.ToInt32(w.StartNO, 16) <= InputMacNo && + // InputMacNo <= Convert.ToInt32(w.EndNO, 16) && + // w.Title == InputMacTitle).Any()) + // { + // CheckMsg += "組件序號【" + inputItem.inputData + "】 與工單設定MAC區間不符合
"; + // } + // } + // } + //} + + #endregion + + #region 判斷出貨序號 + + // 當KP_NAME是 EXT_NO 判斷組件-出貨序號 是否有在區間 + if (wipKp.KpNo.ToUpper() == "95") + { + WipBarcodeOtherController wipBarcodeOtherController = new WipBarcodeOtherController(_context); + var WipBarCodeOther = await wipBarcodeOtherController.CheckWipBarcodeOtherByNo(wipKp.WipNo, inputItem.inputData); + if (WipBarCodeOther.Value.Count() == 0) + { + CheckMsg += "組件序號【" + inputItem.inputData + "】 與工單設定出貨序號區間不符合
"; + } + } + + #endregion + + return CheckMsg; + } + + /// + /// 更新 組件替換資料 + /// + /// 料號組件資料 + /// 料號組件更換資料 + /// + private async Task UpdateBarCodeItemChange(List barcodeItems, List barcodeItemChanges) + { + string Msg = string.Empty; + using (var tran = _context.Database.BeginTransaction()) + { + try + { + // 更新料號組件 + foreach (var item in barcodeItems) + { + _context.Entry(item).State = EntityState.Modified; + await _context.SaveChangesAsync(); + } + + // 新增料號組件更換資料 + foreach (var item in barcodeItemChanges) + { + Helper helper = new Helper(_context); + item.BarcodeItemChangeID = await helper.GetIDKey("BARCODE_ITEM_CHANGE"); + _context.BarcodeItemChanges.Add(item); + + await _context.SaveChangesAsync(); + } + await tran.CommitAsync(); + } + catch (Exception ex) + { + Msg = $"過站新增系統錯誤:{ex.Message}"; + await tran.RollbackAsync(); + } + } + return Msg; + } + + /// + /// 取該筆工單流水碼 + /// + /// 工單號碼 + /// + private async Task GetWipNoSerialNumber(string wipNo) + { + int snLen = 4; + try + { + var result_WipInfo = await _context.WipInfos.Where(w => w.WipNO == wipNo.Trim().ToUpper()).ToListAsync(); + // 取工單號碼最大工單數量 + snLen = result_WipInfo.Max(m => m.PlanQTY).ToString().Length; + // 長度最小取4碼 + if (snLen <= 4) snLen = 4; + } + catch + { + return snLen; + } + return snLen; + } + + /// + /// 確認是否有掃毒 + /// + /// 工單號碼 + /// 工單料號 + /// + private async Task> CheckAntivirus(string wipNo, string itemNo) + { + ResultModel resultModel = new ResultModel { Success = false }; + + var wipSystem = _context.WipSystems.Where(w => w.WipNo == wipNo).FirstOrDefault(); + // 找不到工程資料 不須判斷 + if (wipSystem == null) + { + resultModel.Success = true; + return resultModel; + } + + // 是否掃毒 != Y + if (wipSystem.Antivirus != "Y") + { + resultModel.Success = true; + return resultModel; + } + else + { + TestLogController testLogController = new TestLogController(_context, _config); + var resultAntivirus = testLogController.GetSacnvirus(wipNo).Result; + if (resultAntivirus.Count() != 0) + { + resultModel.Success = true; + return resultModel; + } + else + { + string MailGroup = "PE_SCANV"; + string Subject = $"[AMES系統通知] 工單號碼【{wipNo}】,未執行掃毒,請確認"; + string Body = $"工單號碼【{wipNo}】,未執行掃毒,請確認"; + await new MailController(_context, _config).PostMail(Subject, Body, MailGroup, "", false); + + WipAlarm wipAlarm = new WipAlarm(); + wipAlarm.AlarmTypeID = (int)EnumWipAlarm.EnumTypeId.Antivirus; + wipAlarm.WipNO = wipNo; + wipAlarm.AlarmParam = itemNo; + wipAlarm.AlarmValue = "1"; + wipAlarm.AlarmDesc = Subject; + wipAlarm.AlarmDateTime = DateTime.Now; + + Helper helper = new Helper(_context); + wipAlarm.WipAlarmID = helper.GetIDKey("WIP_ALARMID").Result; + + _context.WipAlarms.Add(wipAlarm); + _context.SaveChanges(); + + resultModel.Success = false; + resultModel.Msg = "未執行掃毒,請確認"; + return resultModel; + } + } + } + + /// + /// 執行Get Https網址 + /// + /// 呼叫網址 + /// + private async Task MakeGetRequest(string targetUrl) + { + using (HttpClient httpClient = new HttpClient()) + { + // 執行GET請求 + HttpResponseMessage response = await httpClient.GetAsync(targetUrl); + } + } + } +} +