From 10484ca8bec527805b7eca4be75bd21fc86b4c50 Mon Sep 17 00:00:00 2001 From: Sai Date: Mon, 25 Dec 2023 17:16:26 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=96=B0=E5=A2=9ERPT004=20=E7=B7=9A?= =?UTF-8?q?=E9=A0=AD=E7=9C=8B=E7=89=88=202.=20=E9=81=8E=E7=AB=99=E6=94=B9?= =?UTF-8?q?=E7=94=A8=E6=96=B0=E7=89=88=E9=81=8E=E7=AB=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/PCSController.cs | 2 +- .../Controllers/RPTController.cs | 76 +- AMESCoreStudio.Web/HttpApis/AMES/IRPT.cs | 13 + AMESCoreStudio.Web/Views/RPT/RPT004.cshtml | 231 ++ .../Controllers/BLL/BarCodeCheckController.cs | 2619 ----------------- .../BLL/BarCodeCheckNewController.cs | 2507 ++++++++++++++++ .../Controllers/BLL/RPTController.cs | 121 +- .../DTO/AMES/BarcodeItemKPDto.cs | 16 +- .../DTO/AMES/RPT004VIiewDto.cs | 83 + .../DTO/BLL/BarCodeCheckDto.cs | 52 +- 10 files changed, 3070 insertions(+), 2650 deletions(-) create mode 100644 AMESCoreStudio.Web/Views/RPT/RPT004.cshtml delete mode 100644 AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckController.cs create mode 100644 AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckNewController.cs create mode 100644 AMESCoreStudio.WebApi/DTO/AMES/RPT004VIiewDto.cs diff --git a/AMESCoreStudio.Web/Controllers/PCSController.cs b/AMESCoreStudio.Web/Controllers/PCSController.cs index 2d5ab495..3c560285 100644 --- a/AMESCoreStudio.Web/Controllers/PCSController.cs +++ b/AMESCoreStudio.Web/Controllers/PCSController.cs @@ -4664,7 +4664,7 @@ namespace AMESCoreStudio.Web.Controllers // 工單資料 var result_barcodestation = await _pcsApi.GetBarcodeStationByBarCodeID(result_barcodeinfo.BarcodeID); - foreach (var wipID in result_barcodestation.Select(s => s.WipID).Distinct()) + foreach (var wipID in result_barcodestation.OrderBy(o => o.CreateDate).Select(s => s.WipID).Distinct()) { var result_wipinfo = await _pcsApi.GetWipInfo(wipID); foreach (var wipinfo in result_wipinfo) diff --git a/AMESCoreStudio.Web/Controllers/RPTController.cs b/AMESCoreStudio.Web/Controllers/RPTController.cs index 91c2c91e..c8194842 100644 --- a/AMESCoreStudio.Web/Controllers/RPTController.cs +++ b/AMESCoreStudio.Web/Controllers/RPTController.cs @@ -1,26 +1,21 @@ -using Microsoft.AspNetCore.Mvc; -using AspNetCore.Reporting; -using Microsoft.AspNetCore.Hosting; -using System.Collections.Generic; -using System.Threading.Tasks; -using System; -using System.Data; -using Oracle.EntityFrameworkCore; -using Oracle.ManagedDataAccess.Client; -using AMESCoreStudio.WebApi.Models.BAS; -using AMESCoreStudio.CommonTools.Result; +using AMESCoreStudio.CommonTools.Result; using AMESCoreStudio.Web.Models; -using AMESCoreStudio.WebApi.DTO.AMES; -using DocumentFormat.OpenXml.Math; using AMESCoreStudio.Web.ViewModels.PCS; -using Microsoft.AspNetCore.Http; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using AMESCoreStudio.Web.ViewModels.RPT; -using AMESCoreStudio.WebApi.Models.AMES; +using AMESCoreStudio.WebApi.DTO.AMES; using AMESCoreStudio.WebApi.Enum; +using AMESCoreStudio.WebApi.Models.AMES; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Data; using System.Linq; +using System.Threading.Tasks; // For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860 @@ -32,14 +27,16 @@ namespace AMESCoreStudio.Web.Controllers public readonly IRPT _rptApi; public readonly IPCS _pcsApi; public readonly IESUN _esunApi; + public readonly IBAS _basApi; - public RPTController(IWebHostEnvironment environment, IRPT rptApi, IPCS pcsApi, IESUN esunApi) + public RPTController(IWebHostEnvironment environment, IRPT rptApi, IPCS pcsApi, IESUN esunApi, IBAS basApi) { this.environment = environment; System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); _rptApi = rptApi; _pcsApi = pcsApi; _esunApi = esunApi; + _basApi = basApi; } public async Task RPT001() @@ -1750,6 +1747,47 @@ namespace AMESCoreStudio.Web.Controllers } #endregion + #region RPT004 線頭看板 + + /// + /// 生產單位 + /// + /// true:Add全部選項 + /// + private async Task GetFactoryUnit(bool SelectAll = true) + { + var result = await _basApi.GetFactoryUnits(); + + var FactoryUnit = new List(); + + if (SelectAll) + FactoryUnit.Add(new SelectListItem("全部", "")); + + for (int i = 0; i < result.Count; i++) + { + FactoryUnit.Add(new SelectListItem(result[i].UnitName, result[i].UnitNo.ToString())); + } + + ViewBag.FactoryUnitList = FactoryUnit; + } + + public async Task RPT004() + { + var model = new RPT004ViewDto(); + await GetFactoryUnit(false); + return View(model); + } + + [HttpPost] + public async Task RPT004(RPT004ViewDto model) + { + await GetFactoryUnit(false); + model = await _rptApi.GetRPT004View(model.unitNo, model.lineId); + return View(model); + } + + #endregion + #region RPT005 昶亨工單查詢 public async Task RPT005(string id) @@ -1806,7 +1844,7 @@ namespace AMESCoreStudio.Web.Controllers model.wipBoard = await _esunApi.GetWipBoard(model.wipInfo.WipNO); if (model.wipBoard != null) { - + } model.wipSystem = await _esunApi.GetWipSystem(model.wipInfo.WipNO); diff --git a/AMESCoreStudio.Web/HttpApis/AMES/IRPT.cs b/AMESCoreStudio.Web/HttpApis/AMES/IRPT.cs index dbd3617c..372855f7 100644 --- a/AMESCoreStudio.Web/HttpApis/AMES/IRPT.cs +++ b/AMESCoreStudio.Web/HttpApis/AMES/IRPT.cs @@ -85,5 +85,18 @@ namespace AMESCoreStudio.Web ITask> GetQcRatesQuery(string year = null, string month = null, string qcRateType = null, string productType = null, int page = 0, int limit = 10); #endregion + + #region RPT004 看板資料 + + /// + /// 線頭看板 + /// + /// 生產製程 + /// 線別ID + /// + [WebApiClient.Attributes.HttpGet("api/RPT/GetRPT004View")] + ITask GetRPT004View(string unitNo, int lineId); + + #endregion } } diff --git a/AMESCoreStudio.Web/Views/RPT/RPT004.cshtml b/AMESCoreStudio.Web/Views/RPT/RPT004.cshtml new file mode 100644 index 00000000..d611b71c --- /dev/null +++ b/AMESCoreStudio.Web/Views/RPT/RPT004.cshtml @@ -0,0 +1,231 @@ +@model AMESCoreStudio.WebApi.DTO.AMES.RPT004ViewDto + +@{ + ViewData["Title"] = "線頭看板"; + Layout = "~/Views/Shared/_AMESLayout.cshtml"; +} + + + +
+
+
+
+
+
+ +
+ +
+ +
+ +
+ +
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+ + +
+
+ + +
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+

應投入數量

+ +
+
+
+
+ @Model.requiredQty +

pcs

+
+
+
+
+
+
+
+
+

實際投入數量

+ +
+
+
+
+ @Model.actualQty +

pcs

+
+
+
+
+
+
+
+
+

生產效率

+ +
+
+
+
+ @Model.efficiency +

%

+
+
+
+
+
+
+
+
+@section Scripts { + +} \ No newline at end of file diff --git a/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckController.cs b/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckController.cs deleted file mode 100644 index f7d07aab..00000000 --- a/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckController.cs +++ /dev/null @@ -1,2619 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using AMESCoreStudio.WebApi; -using AMESCoreStudio.WebApi.Models.AMES; -using AMESCoreStudio.CommonTools.Result; -using AMESCoreStudio.WebApi.Controllers.BAS; -using AMESCoreStudio.WebApi.DTO.AMES; -using AMESCoreStudio.WebApi.Controllers.BLL; -using AMESCoreStudio.WebApi.Enum; -using Microsoft.Extensions.Configuration; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using static AMESCoreStudio.WebApi.DTO.AMES.BarCodeCheckDto; - -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 - { - // KP||NG Input - if (barCodeCheckDto.inputItems == null) - barCodeCheckDto.inputItems = new List(); - else - barCodeCheckDto.inputItems = barCodeCheckDto.inputItems.Where(w => !string.IsNullOrWhiteSpace(w.inputType)).ToList(); - - // 治具 Input - if (barCodeCheckDto.outfits == null) - barCodeCheckDto.outfits = new List(); - else - barCodeCheckDto.outfits = barCodeCheckDto.outfits.Where(w => !string.IsNullOrWhiteSpace(w.inputData)).ToList(); - - #region 欄位資料空值判斷 - if (string.IsNullOrWhiteSpace(barCodeCheckDto.wipNo)) - { - resultModel.Msg = "請輸入工單號碼"; - return Ok(resultModel); - } - - if (string.IsNullOrWhiteSpace(barCodeCheckDto.barcode)) - { - resultModel.Msg = "請輸入內部條碼"; - return Ok(resultModel); - } - - if (string.IsNullOrWhiteSpace(barCodeCheckDto.unitNo)) - { - resultModel.Msg = "請輸入生產單位"; - return Ok(resultModel); - } - - if (barCodeCheckDto.stationID == 0) - { - resultModel.Msg = "請輸入作業站代碼"; - return Ok(resultModel); - } - - if (barCodeCheckDto.line == 0) - { - resultModel.Msg = "請輸入線別代碼"; - return Ok(resultModel); - } - #endregion - - #region 宣告各個Controller - WipInfosController wipInfosController = new WipInfosController(_context); - WipMACController wipMACController = new WipMACController(_context); - WipBarcodeOtherController wipBarcodeOtherController = new WipBarcodeOtherController(_context); - BarcodeItemsController barcodeItemsController = new BarcodeItemsController(_context); - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - BarcodeItemChangesController barcodeItemChangesController = new BarcodeItemChangesController(_context); - RuleStationsController ruleStationsController = new RuleStationsController(_context); - MaterialKpController materialKpController = new MaterialKpController(_context); - #endregion - - #region 宣告參數 - // 料號ID - int itemID = 0; - // 料號 - string item = string.Empty; - // 存放要更新BarCodeItem - var update_BarCodeItem = new List(); - var insert_BarCodeItemChange = new List(); - // Burn In - bool burnIn = false; - #endregion - - #region 判斷UserID - if (barCodeCheckDto.userID != 0) - { - if (_context.UserInfoes.Where(w => w.UserID == barCodeCheckDto.userID).Count() == 0) - { - resultModel.Success = false; - resultModel.Msg = "找不到UserID【" + barCodeCheckDto.userID + "】資料"; - return resultModel; - } - } - #endregion - - #region 判斷序號為出貨條碼,並轉成內部條碼 - var ByExtraNo = await barcodeInfoesController.GetBarcodeInfoesByExtraNo(barCodeCheckDto.barcode); - if (ByExtraNo.Value.Count() != 0) - { - barCodeCheckDto.extNo = barCodeCheckDto.barcode; - barCodeCheckDto.barcode = ByExtraNo.Value.FirstOrDefault().BarcodeNo; - } - #endregion - - // 抓流程ID - var q_wipinfo = await wipInfosController.GetWipInfoByWipNo(barCodeCheckDto.wipNo); - barCodeCheckDto.flowRule = q_wipinfo.Value.Where(w => w.UnitNO == barCodeCheckDto.unitNo).FirstOrDefault().FlowRuleID; - - #region 判斷工單狀態 - resultModel = (ResultModel)await CheckWipNoSationAsync(wipNo: barCodeCheckDto.wipNo, unitNo: barCodeCheckDto.unitNo - , flowRuleID: barCodeCheckDto.flowRule, line: barCodeCheckDto.line, stationID: barCodeCheckDto.stationID, barCodeNo: barCodeCheckDto.barcode); - - if (!resultModel.Success) - return resultModel; - #endregion - - #region 判斷序號區間 - - resultModel = await CheckBarCodeByWipNo(wipNo: barCodeCheckDto.wipNo, barcode: barCodeCheckDto.barcode); - if (!resultModel.Success) - return resultModel; - - #endregion - - #region 判斷序號狀態 - resultModel = (ResultModel)await GetCheckBarCodeStation(wipno: barCodeCheckDto.wipNo, barcode: barCodeCheckDto.barcode); - if (!resultModel.Success) - return resultModel; - #endregion - - #region 判斷序號流程 - resultModel = (ResultModel)await CheckBarCodeFlowAsync(wipno: barCodeCheckDto.wipNo, barcode: barCodeCheckDto.barcode - , unitno: barCodeCheckDto.unitNo, stationID: barCodeCheckDto.stationID); - - if (!resultModel.Success) - return resultModel; - #endregion - - barCodeCheckDto.wipID = q_wipinfo.Value.Where(w => w.UnitNO == barCodeCheckDto.unitNo).FirstOrDefault().WipID; - barCodeCheckDto.flowRule = q_wipinfo.Value.Where(w => w.UnitNO == barCodeCheckDto.unitNo).FirstOrDefault().FlowRuleID; - barCodeCheckDto.barcodeID = BarCodeToID(barCodeCheckDto.barcode).Result; - item = q_wipinfo.Value.FirstOrDefault().GetWipAtt.ItemNO; - itemID = ItemNoToItemID(item).Result; - - //// 抓RulseStationID - //var q_rulestation = await ruleStationsController.GetRuleStationByFlow(barCodeCheckDto.flowRule, 0, 0); - //barCodeCheckDto.ruleStationID = q_rulestation.Value.Where(w => w.StationID == barCodeCheckDto.station).FirstOrDefault().RuleStationID; - - #region 燒機判斷 - resultModel = (ResultModel)await GetCheckBurn(barCodeCheckDto.wipNo, barCodeCheckDto.barcodeID, barCodeCheckDto.stationID); - if (!resultModel.Success) - return resultModel; - else if (resultModel.Msg == "BurnIn") - burnIn = true; - #endregion - - StationsesController stationsesController = new StationsesController(_context); - var station = await stationsesController.GetStations(barCodeCheckDto.stationID); - - #region KeyParts 判斷 - // 不是維修跑KeyParts判斷 - if (barCodeCheckDto.barcodeType != "S") - { - if (barCodeCheckDto.inputItems.Where(w => !w.inputType.ToUpper().StartsWith("NG")).Any()) - { - - var barcodeItemKPDto = new BarcodeItemKPDto - { - WipNo = barCodeCheckDto.wipNo, - barcode = barCodeCheckDto.barcode, - unitNo = barCodeCheckDto.unitNo, - ststionUnitNo = station.Value.Where(w => w.StationID == barCodeCheckDto.stationID).FirstOrDefault().UnitNo, - inputKP = barCodeCheckDto.inputItems.Where(w => !w.inputType.ToUpper().StartsWith("NG")).ToList() - }; - - var resultKeyParts = await CheckBarCodeKPAsync(barcodeItemKPDto); - if (!resultKeyParts.Success) - return (ResultModel)resultKeyParts; - } - } - #endregion - - #region 治具判斷 - var resultOutfit = await CheckBarCodeOutfitAsync(barCodeCheckDto.outfits); - if (!resultOutfit.Success) - return (ResultModel)resultOutfit; - #endregion - - #region 判斷T3掃毒 - - if (station.Value.Count() != 0) - { - if (station.Value.FirstOrDefault().StationName.Trim().ToUpper() == "T3") - { - var resultAntivirus = CheckAntivirus(barCodeCheckDto.wipNo, item); - if (!resultAntivirus.Success) - return (ResultModel)resultAntivirus; - } - } - - #endregion - - // 維修過站 組件需獨立判斷 - if (barCodeCheckDto.barcodeType == "S") - { - // 確認新舊組件序號是否都有值 - if (barCodeCheckDto.inputItems.Where(w => w.inputType.ToUpper() != "NG" && - (string.IsNullOrWhiteSpace(w.inputData) || string.IsNullOrWhiteSpace(w.oldInputData))).Any()) - { - resultModel.Msg = "工單號碼【" + barCodeCheckDto.wipNo + "】維修過站資料有缺新舊組件序號,請確認"; - resultModel.Success = false; - return resultModel; - } - - // 用BarCodeID And WipID 取BarCodeItem - - var q_BarCodeItem = await barcodeItemsController.GetBarcodeItemByBarCodeID(barCodeCheckDto.barcodeID); - q_BarCodeItem = q_BarCodeItem.Value.Where(w => w.WipID == barCodeCheckDto.wipID).ToList(); - - foreach (var KPs in barCodeCheckDto.inputItems) - { - // 用舊組件序號比對 - var barCodeItem = q_BarCodeItem.Value.Where(w => w.PartNo == KPs.oldInputData).FirstOrDefault(); - - if (barCodeItem != null) - { - - var MaterialKps = (await materialKpController.GetMaterialKpByItemID(itemID)).ToList(); - MaterialKps = MaterialKps.OrderBy(o => o.KpSeq).ToList(); - if (MaterialKps.Count == 0) - { - resultModel.Msg = "工單號碼【" + barCodeCheckDto.wipNo + "】找不到相關Key Parts對應"; - } - else - { - var q_Kp = MaterialKps.Where(w => w.KpNo.ToUpper() == barCodeItem.ItemNo.ToUpper()).FirstOrDefault(); - if (q_Kp != null) - { - #region 比對序號長度是否正確 - if (!string.IsNullOrWhiteSpace(q_Kp.Length.ToString())) - { - if (q_Kp.Length != KPs.inputData.Length && q_Kp.Length != 0) - resultModel.Msg += "組件序號【" + KPs.inputData + "】 與組件名稱【" + q_Kp.KpName + "】長度不符合
"; - } - #endregion - - #region 前置碼正確 - if (!string.IsNullOrWhiteSpace(q_Kp.Title)) - { - if (!KPs.inputData.ToUpper().StartsWith(q_Kp.Title.ToUpper())) - resultModel.Msg += "組件序號【" + KPs.inputData + "】 與組件名稱【" + q_Kp.Title + "】前置碼不符合
"; - } - #endregion - - #region 組件代碼-組件序號是否重複 - //WINDOWS驗證-取得安勤 + 昶亨的KP SN - #region 取消 - #endregion - //改抓C_SFIS_KEYPARTS (安勤轉拋) - #region - if (await _context.CSfisKeyparts.Where(w => w.Partbarcode.ToUpper() == KPs.inputData).AnyAsync()) - { - resultModel.Msg += "組件名稱【" + q_Kp.KpName + "】已有相同組件序號【" + KPs.inputData + "】安勤轉拋KeyParts紀錄
"; - } - #endregion - - var checkDataRedundancy = await barcodeItemsController.GetBarcodeItemByDataRedundancy(q_Kp.KpNo, KPs.inputData); - if (checkDataRedundancy.Value.Count() != 0) - { - resultModel.Msg += "組件名稱【" + q_Kp.KpName + "】已有相同組件序號【" + KPs.inputData + "】紀錄
"; - } - #endregion - - #region 判斷組件序號是否在製狀態 - if (q_Kp.KpNo.ToUpper() == "04") - { - - var BarCodeInfo = await barcodeInfoesController.GetBarcodeInfoesByNo(KPs.inputData); - if (BarCodeInfo.Value.Where(w => w.StatusID != -1).Any()) - { - resultModel.Msg += "組件序號【" + KPs.inputData + "】 目前是在製狀態
"; - } - } - #endregion - - #region 判斷MAC區間 - // 安勤不需要判斷MAC區間 - //if (q_Kp.KpNo.ToUpper() == "MAC") - //{ - - // var wipMAC = await wipMACController.GetWipMAC(barCodeCheckDto.wipNo); - // if (wipMAC.Value == null) - // { - // resultModel.Msg += "工單號碼【" + barCodeCheckDto.wipNo + "】 找不到綁定MAC區間
"; - // } - // else - // { - // // 判斷MAC前置碼是否一樣 - // if (!KPs.inputData.StartsWith(wipMAC.Value.Title)) - // { - // resultModel.Msg += "組件序號【" + KPs.inputData + "】 與MAC【" + wipMAC.Value.Title + "】前置碼不符合
"; - // } - // else - // { - // // 判斷是否符合區間 - // if (KPs.inputData.Length == 12) - // { - // if (!(Convert.ToInt32(wipMAC.Value.StartNO, 16) <= Convert.ToInt32(KPs.inputData.Substring(6, 6), 16) - // && Convert.ToInt32(KPs.inputData.Substring(6, 6), 16) <= Convert.ToInt32(wipMAC.Value.EndNO, 16))) - // { - // resultModel.Msg += "組件序號【" + KPs.inputData + "】 與工單設定MAC區間不符合
"; - // } - // } - // } - // } - //} - #endregion - - #region 判斷出貨序號 - // 當KP_NAME是 EXT_NO 判斷組件-出貨序號 是否有在區間 - if (q_Kp.KpNo.ToUpper() == "95") - { - - var WipBarCodeOther = await wipBarcodeOtherController.CheckWipBarcodeOtherByNo(barCodeCheckDto.wipNo, KPs.inputData); - if (WipBarCodeOther.Value.Count() == 0) - { - resultModel.Msg += "組件序號【" + KPs.inputData + "】 與工單設定出貨序號區間不符合
"; - } - else - { - //resultModel.Data = new List { KPs.inputData }; - //resultModel.Msg = "EXT_NO"; - } - } - #endregion - } - } - - barCodeItem.PartNo = KPs.inputData; - barCodeItem.UpdateDate = DateTime.Now; - update_BarCodeItem.Add(barCodeItem); - - insert_BarCodeItemChange.Add(new BarcodeItemChange - { - WipID = barCodeCheckDto.wipID, - StationID = barCodeCheckDto.stationID, - BarcodeID = barCodeCheckDto.barcodeID, - ItemNo = barCodeItem.ItemNo, - PartNoOld = KPs.oldInputData, - ChangeType = "RP", - KpItemNo = KPs.inputData, - CreateUserID = barCodeCheckDto.userID - }); - } - else - { - resultModel.Msg = $"內部條碼【{barCodeCheckDto.barcode}】找不到已綁定Kp序號【{KPs.oldInputData}】"; - } - } - - if (!string.IsNullOrWhiteSpace(resultModel.Msg)) - { - resultModel.Success = false; - return resultModel; - } - // 將InputItem清空 - barCodeCheckDto.inputItems = new List(); - } - - //var NextStopCloseStation = await CheckNextStopCloseStation(barCodeCheckDto.wipNo, barCodeCheckDto.unitNo, barCodeCheckDto.station); - - #region 判斷為CHECK站.組件是否都有資料 - // 判斷作業站是否為CHECK站 Station_Type == C - - if (station.Value.Where(w => w.TypeNo == "C").Any()) - //if (CheckNextStopCloseStation(barCodeCheckDto.wipNo, barCodeCheckDto.unitNo, barCodeCheckDto.station).Result.Success) - { - // 過站輸入組件數量 - var inputKPQty = barCodeCheckDto.inputItems.Where(w => !w.inputData.Contains("$")).Count(); - - // 已記錄組件數量 - var BarCodeItems = _context.BarcodeItems.Where(w => w.BarcodeID == barCodeCheckDto.barcodeID && w.WipID == barCodeCheckDto.wipID); - var Stations = _context.Stationses.Where(w => w.UnitNo == station.Value.FirstOrDefault().UnitNo); - - - var BarCodeItemsQty = BarCodeItems.Where(w => Stations.Any(s => s.StationID == w.StationID)).Count(); - - // WipKp DB 設定綁定組件數量 + 製程判斷 - var wipKpQty = _context.WipKps.Where(w => w.WipNo == barCodeCheckDto.wipNo - && w.UnitNo == station.Value.FirstOrDefault().UnitNo - ).Count(); - - if (wipKpQty != inputKPQty + BarCodeItemsQty) - { - resultModel.Success = false; - resultModel.Msg = "組件資料筆數不符,請確認"; - return resultModel; - } - } - #endregion - - #region 判斷下一站為完工時.治具是否都有資料 - //// 過站輸入組件數量 - //var inputKPQty = barCodeCheckDto.outfits.Count(); - - //// 已記錄組件數量 - //var BarCodeItemsQty = _context.BarcodeOutfits.Where(w => w.BarcodeID == barCodeCheckDto.barcodeID - // && w.WipID == barCodeCheckDto.wipID).Count(); - //// WipKp DB 設定綁定組件數量 - //var wipKpQty = _context.WipKps.Where(w => w.WipNo == barCodeCheckDto.wipNo - // && w.UnitNo == barCodeCheckDto.unitNo).Count(); - - //if (wipKpQty != inputKPQty + BarCodeItemsQty) - //{ - // resultModel.Success = false; - // resultModel.Msg = "該作業站為流程最後最後一站,組件資料筆數不符,請確認"; - // return resultModel; - //} - #endregion - - // 過站判斷正常 往下處理Table - - #region 內部序號輸入後新增 or 更新 - if (barCodeCheckDto.inputItems.Where(w => w.inputData.Contains("$")).Count() != 0) - barCodeCheckDto.ruleStatus = "F"; - else - barCodeCheckDto.ruleStatus = "P"; - - var result_CUTableMsg = await CU_Tables(barCodeCheckDto, burnIn); - if (!string.IsNullOrWhiteSpace(result_CUTableMsg)) - { - resultModel.Msg = "內部序號【" + barCodeCheckDto.barcode + "】 過站失敗,錯誤訊息:
"; - resultModel.Msg += result_CUTableMsg; - resultModel.Success = false; - return resultModel; - } - - // 維修組件更換 - foreach (var item_barCodeItem in update_BarCodeItem) - { - await barcodeItemsController.PutBarcodeItems(item_barCodeItem.BarcodeItemID, item_barCodeItem); - } - - foreach (var item_barCodeItemChange in insert_BarCodeItemChange) - { - await barcodeItemChangesController.PostBarcodeItemChanges(item_barCodeItemChange); - } - - // 燒機In 修改狀態 - if (burnIn) - { - resultModel.Msg = "內部序號【" + barCodeCheckDto.barcode + "】 燒機In 完成!"; - } - else - { - resultModel.Msg = "內部序號【" + barCodeCheckDto.barcode + "】 過站完成!"; - } - - // IPQC 任務性 - IPQCTaskNoticeController iPQCTaskNoticeController = new IPQCTaskNoticeController(_context, _config); - await iPQCTaskNoticeController.CheckIPQCTaskNotice(barCodeCheckDto.wipNo, item, barCodeCheckDto.stationID); - - resultModel.Success = true; - return resultModel; - #endregion - } - 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 = await _context.FqcInhouseMasters.Where(w => w.InhouseNo == inhouseNo && w.SeqID == seqID) - .FirstOrDefaultAsync(); - if (InhouseMaster != null) - { - RuleStationsController ruleStationsController = new RuleStationsController(_context); - var CheckFQC = await ruleStationsController.GetRuleStationByWipNoCheckFQC(InhouseMaster.WipNo); - // 有設定FQC站別 - if (CheckFQC.Value.Data.Count() != 0) - { - var RuleStation = CheckFQC.Value.Data.FirstOrDefault(); - // 取FQC抽驗單號 - var InhouseDetail = await _context.FqcInhouseDetails.Where(w => w.InhouseNo == inhouseNo && w.SeqID == seqID) - .ToListAsync(); - BarCodeCheckDto barCodeCheckDto = new BarCodeCheckDto(); - barCodeCheckDto.line = -1; - barCodeCheckDto.ruleStatus = "P"; - barCodeCheckDto.stationID = RuleStation.Station.StationID; - barCodeCheckDto.userID = userID; - barCodeCheckDto.barcodeType = "M"; - 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) - { - barCodeCheckDto.unitNo = _context.WipInfos.Where(w => w.WipID == barcode.WipID).FirstOrDefault().UnitNO; - barCodeCheckDto.wipID = barcode.WipID; - barCodeCheckDto.barcode = barcode.BarcodeNo; - barCodeCheckDto.barcodeID = barcode.BarcodeID; - barCodeCheckDto.extNo = barcode.ExtraBarcodeNo; - barCodeCheckDto.flowRule = _context.WipInfos.Where(w => w.WipID == barcode.WipID).FirstOrDefault().FlowRuleID; - barCodeCheckDto.wipNo = _context.WipInfos.Where(w => w.WipID == barcode.WipID).FirstOrDefault().WipNO; - - var result_CUTableMsg = await CU_Tables(barCodeCheckDto, false); - if (string.IsNullOrWhiteSpace(result_CUTableMsg)) - { - resultModel.Success = true; - resultModel.Msg = "FQC過站完成"; - } - else - { - resultModel.Msg = result_CUTableMsg; - } - } - } // 條碼 - else - { - var BarcodeNo = await _context.BarcodeInfoes.Where(w => w.BarcodeNo == item.SerialNo).FirstOrDefaultAsync(); - if (BarcodeNo != null) - { - barCodeCheckDto.unitNo = _context.WipInfos.Where(w => w.WipID == BarcodeNo.WipID).FirstOrDefault().UnitNO; - barCodeCheckDto.wipID = BarcodeNo.WipID; - barCodeCheckDto.barcode = BarcodeNo.BarcodeNo; - barCodeCheckDto.barcodeID = BarcodeNo.BarcodeID; - barCodeCheckDto.extNo = BarcodeNo.ExtraBarcodeNo; - barCodeCheckDto.flowRule = _context.WipInfos.Where(w => w.WipID == BarcodeNo.WipID).FirstOrDefault().FlowRuleID; - } - - var result_CUTableMsg = await CU_Tables(barCodeCheckDto, false); - 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; - } - #endregion - - #region 判斷過站完成新增or更新 Table - /// - /// 判斷過站完成新增or更新 Table - /// - /// - /// T:燒機In - /// - private async Task CU_Tables(BarCodeCheckDto barCodeCheckDto, bool burnIn) - { - string Msg = string.Empty; - using (var tran = _context.Database.BeginTransaction()) - { - try - { - if (!burnIn) - { - // 條碼主檔 - var result_BarcodeInfo = Table_BarcodeInfo(barCodeCheckDto).Result; - if (result_BarcodeInfo.Success) - { - // 將BarCodeID補上 - if (barCodeCheckDto.barcodeID == 0) - barCodeCheckDto.barcodeID = result_BarcodeInfo.Data.FirstOrDefault().BarcodeID; - } - else - { - Msg += "BarcodeInfo_Error:" + result_BarcodeInfo.Msg + "
"; - } - - // 條碼紀錄 - var result_BarcodeWip = await Table_BarcodeWip(barCodeCheckDto); - if (!result_BarcodeWip.Success) - { - Msg += "BarcodeWip_Error:" + result_BarcodeWip.Msg + "
"; - } - - // 工單各站數量資料檔 - var result_WipStation = await Table_WipStation(barCodeCheckDto); - if (!string.IsNullOrWhiteSpace(result_WipStation)) - { - Msg += "WipStation_Error:" + result_WipStation + "
"; - } - - // 各班別數量資料檔 - var result_WipClass = await Table_WipClass(barCodeCheckDto); - if (!string.IsNullOrWhiteSpace(result_WipClass)) - { - Msg += "WipClass_Error:" + result_WipClass + "
"; - } - - // 工單各站數量資料檔 – By TIME - var result_WipTime = await Table_WipTime(barCodeCheckDto); - if (!string.IsNullOrWhiteSpace(result_WipTime)) - { - Msg += "WipTime_Error:" + result_WipTime + "
"; - } - - // 條碼過站資料檔 - var result_BarcodeStation = Table_BarcodeStation(barCodeCheckDto).Result; - if (!result_BarcodeStation.Success) - { - Msg += "BarcodeStation_Error:" + result_BarcodeStation.Msg + "
"; - } - - // 組件资料 - var result_BarcodeItem = Table_BarcodeItem(barCodeCheckDto).Result; - if (!result_BarcodeItem.Success) - { - Msg += "BarcodeItem_Error:" + result_BarcodeItem.Msg + "
"; - } - - // 條碼治具 - var result_BarcodeOutfit = Table_BarcodeOutfit(barCodeCheckDto).Result; - if (!result_BarcodeOutfit.Success) - { - Msg += "BarcodeOutfit_Error:" + result_BarcodeOutfit.Msg + "
"; - } - - // 設備資料檔 使用次數 - var result_OutfitInfo = Table_OutfitInfo(barCodeCheckDto).Result; - if (!result_OutfitInfo.Success) - { - Msg += "OutfitInfo_Error:" + result_OutfitInfo.Msg + "
"; - } - - // 不良資料檔 - var result_NgInfo = Table_NgInfo(barCodeCheckDto).Result; - if (!result_NgInfo.Success) - { - Msg += "NgInfo_Error:" + result_NgInfo.Msg + "
"; - } - - // 判斷是否為第一站 - if (CheckNowFirstStation(barCodeCheckDto.wipNo, barCodeCheckDto.unitNo, barCodeCheckDto.stationID) == "Y") - { - WipInfosController wipInfosController = new WipInfosController(_context); - var result_wipInfos = await wipInfosController.PutWipinfoByCompleteQTY(barCodeCheckDto.wipID); - if (!result_wipInfos.Success) - { - Msg += "wipInfos_Error:" + result_wipInfos.Msg + "
"; - } - } - - if (barCodeCheckDto.ruleStatus == "P") - { - // 判斷下一站為完工站 - if (CheckNextStopCloseStation(barCodeCheckDto.wipNo, barCodeCheckDto.unitNo, barCodeCheckDto.stationID).Result.Success) - { - var result_wipInfoAllClost = await CheckWipNoBarCodeAllClost(barCodeCheckDto.wipNo, barCodeCheckDto.unitNo, barCodeCheckDto.stationID); - if (!result_wipInfoAllClost.Success) - { - Msg += "wipInfosAllClost_Error:" + result_wipInfoAllClost.Msg + "
"; - } - } - } - } - - // 燒入資料檔 - var result_BurnInfo = Table_BurnInfo(barCodeCheckDto).Result; - if (!result_BurnInfo.Success) - { - Msg += "BurnInfo_Error:" + result_BurnInfo.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-條碼資料檔 - /// - /// - /// - private async Task> Table_BarcodeInfo(BarCodeCheckDto barCodeCheckDto) - { - // 抓取生產單位的狀態代碼 - FactoryUnitsController factoryUnitsController = new FactoryUnitsController(_context); - string StatusNo = factoryUnitsController.GetFactoryUnit(barCodeCheckDto.unitNo).Result.Value.FirstOrDefault().UnitCode; - - // 查看是否有資料 - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - var barcodeInfo = barcodeInfoesController.GetBarcodeInfoes(barCodeCheckDto.barcodeID) - .Result.Value.FirstOrDefault(); - - // 新增 - if (barcodeInfo == null) - { - barcodeInfo = new BarcodeInfo - { - BarcodeNo = barCodeCheckDto.barcode, - StationID = barCodeCheckDto.stationID, - LocationID = -1, - WipID = barCodeCheckDto.wipID, - RuleStatus = barCodeCheckDto.ruleStatus, - StatusID = 1, - SysType = "S", - StatusNo = StatusNo, - CreateUserID = barCodeCheckDto.userID - }; - - if (barCodeCheckDto.ruleStatus == "P") - { - if (CheckNextStopCloseStation(barCodeCheckDto.wipNo, barCodeCheckDto.unitNo, barCodeCheckDto.stationID).Result.Success) - { - barcodeInfo.StatusID = -1; - } - } - - return await barcodeInfoesController.PostBarcodeInfoes(barcodeInfo); - } - // 更新 - else - { - barcodeInfo.StationID = barCodeCheckDto.stationID; - barcodeInfo.RuleStatus = barCodeCheckDto.ruleStatus; - barcodeInfo.StatusNo = StatusNo; - barcodeInfo.WipID = barCodeCheckDto.wipID; - barcodeInfo.StatusID = 1; - if (!string.IsNullOrWhiteSpace(barCodeCheckDto.extNo)) - barcodeInfo.ExtraBarcodeNo = barCodeCheckDto.extNo; - - if (barCodeCheckDto.ruleStatus == "P") - { - if (CheckNextStopCloseStation(barCodeCheckDto.wipNo, barCodeCheckDto.unitNo, barCodeCheckDto.stationID).Result.Success) - { - barcodeInfo.StatusID = -1; - } - } - return await barcodeInfoesController.PutBarcodeInfoes(barcodeInfo); - } - } - - /// - /// BarcodeStation-條碼過站資料檔 - /// - /// - /// - private async Task> Table_BarcodeStation(BarCodeCheckDto barCodeCheckDto) - { - BarcodeStationController barcodeStationController = new BarcodeStationController(_context); - // 新增 BarCodeStation - BarcodeStation barcodeStation = new BarcodeStation - { - BarcodeID = barCodeCheckDto.barcodeID, - WipID = barCodeCheckDto.wipID, - StationID = barCodeCheckDto.stationID, - RuleStatus = barCodeCheckDto.ruleStatus, //F 不良 - InputDate = DateTime.Now, - LineId = barCodeCheckDto.line, - CreateUserID = barCodeCheckDto.userID, - FlowRuleID = barCodeCheckDto.flowRule - }; - return await barcodeStationController.PostBarcodeStation(barcodeStation); - } - - /// - /// BarcodeItem-組件资料 - /// - /// - /// - private async Task> Table_BarcodeItem(BarCodeCheckDto barCodeCheckDto) - { - BarcodeItemsController barcodeItemsController = new BarcodeItemsController(_context); - var KeyPartsItem = barCodeCheckDto.inputItems.Where(w => !w.inputData.Contains("$")).ToList(); - var result = new ResultModel() { Success = true }; - // 新增 BarCodeStation - for (int i = 0; i < KeyPartsItem.Count(); i++) - { - var barcodeItem = new BarcodeItem - { - BarcodeID = barCodeCheckDto.barcodeID, - WipID = barCodeCheckDto.wipID, - StationID = barCodeCheckDto.stationID, - ItemNo = KeyPartsItem[i].inputType, - PartNo = KeyPartsItem[i].inputData, - SysType = "S", - CreateUserID = barCodeCheckDto.userID, - CreateDate = DateTime.Now, - UpdateDate = DateTime.Now, - KpItemNo = KeyPartsItem[i].kpItemNo - }; - result = await barcodeItemsController.PostBarcodeItems(barcodeItem); - if (!result.Success) - return result; - } - - return result; - } - - /// - /// BarcodeOutfit-治具資料 - /// - /// - /// - private async Task> Table_BarcodeOutfit(BarCodeCheckDto barCodeCheckDto) - { - BarcodeOutfitController barcodeOutfitController = new BarcodeOutfitController(_context); - var OutfitsItem = barCodeCheckDto.outfits; - var result = new ResultModel() { Success = true }; - // 新增 BarCodeStation - foreach (var item in OutfitsItem) - { - var barcodeOutfit = new BarcodeOutfit - { - BarcodeNo = barCodeCheckDto.barcode, - WipNo = barCodeCheckDto.wipNo, - OutfitNo = item.inputData, - StationID = barCodeCheckDto.stationID, - CreateUserID = barCodeCheckDto.userID, - CreateDate = DateTime.Now, - UpdateUserID = barCodeCheckDto.userID, - UpdateDate = DateTime.Now - }; - result = await barcodeOutfitController.PostBarcodeOutfit(barcodeOutfit); - if (!result.Success) - return result; - } - - return result; - } - - /// - /// OutfitInfo-設備資料檔 使用次數 - /// - /// - /// - private async Task> Table_OutfitInfo(BarCodeCheckDto barCodeCheckDto) - { - OutfitInfoesController outfitInfoesController = new OutfitInfoesController(_context); - var OutfitsItem = barCodeCheckDto.outfits; - var result = new ResultModel() { Success = true }; - // 新增 BarCodeStation - foreach (var item in OutfitsItem.Where(w => !string.IsNullOrWhiteSpace(w.inputData))) - { - var outfitInfo = await outfitInfoesController.GetOutfitInfoByOutfitNo(item.inputData.ToUpper()); - if (outfitInfo.Value != null) - { - outfitInfo.Value.UseTimes += 1; - outfitInfo.Value.TotalTimes += 1; - outfitInfo.Value.UpdateDate = DateTime.Now; - - result = await outfitInfoesController.PutOutfitInfo(outfitInfo.Value.OutfitID, outfitInfo.Value); - if (!result.Success) - return result; - } - - WipAlarmsController wipAlarmsController = new WipAlarmsController(_context); - var wipAlarms = await wipAlarmsController.GetWipAlarmByOutfit(barCodeCheckDto.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 = barCodeCheckDto.wipNo; - wipAlarm.AlarmParam = item.inputData.ToUpper(); - wipAlarm.AlarmValue = "1"; - wipAlarm.AlarmDesc = Subject; - wipAlarm.AlarmDateTime = DateTime.Now; - - await wipAlarmsController.PostWipAlarm(wipAlarm); - } - } - //// 確認治具編號使用次數已經超過預計次數 - //if (outfitInfoesController.GetOutfitInfoByOverUseTimes("").Result.Value == "Y") - //{ - - //} - } - - return result; - } - - /// - /// BurnInfo-燒入資料檔 - /// - /// - /// - private async Task> Table_BurnInfo(BarCodeCheckDto model) - { - var result = new ResultModel() { Success = true }; - - // 判斷作業站是否為燒機站 Station_Type == B - StationsesController stationsesController = new StationsesController(_context); - var station = await stationsesController.GetStations(model.stationID); - if (station.Value.Where(w => w.TypeNo == "B").Any()) - { - - // 判斷是否有燒機時間 - WipBoardController wipBoardController = new WipBoardController(_context); - var wipBoardTime = wipBoardController.GetWipBoardToBITime(model.wipNo).Result.Value; - WipSystemController wipSystemController = new WipSystemController(_context); - var wipSystemTime = wipSystemController.GetWipSystemToBITime(model.wipNo).Result.Value; - decimal PlanHour = 0; - if (wipBoardTime > 0) - PlanHour = (decimal)wipBoardTime; - else - PlanHour = (decimal)wipSystemTime; - - BurnInfoeController burnInfoeController = new BurnInfoeController(_context); - // 判斷燒機時間是否足夠 - var burnInfos = await burnInfoeController.GetBurnInfosByBarcodeID(model.barcodeID); - if (burnInfos.Value.Count() != 0) - { - // 取實際燒機完成時間 空白資料 - var item = burnInfos.Value.Where(w => string.IsNullOrWhiteSpace(w.FinishTime.ToString())).FirstOrDefault(); - if (item != null) - { - item.FinishTime = DateTime.Now; - item.OutUserID = model.userID; - item.UpdateDate = DateTime.Now; - item.UpdateUserID = model.userID; - result = await burnInfoeController.PutBurnInfo(item); - } - else // 新增一筆 - { - // 新增 BarCodeStation - var burnInfo = new BurnInfo - { - BarcodeID = model.barcodeID, - WipNo = model.wipNo, - BurnPlanHour = PlanHour, - StartTime = DateTime.Now, - ScheduleFinishTime = DateTime.Now.AddMinutes((double)PlanHour * 60), - InUserID = model.userID, - Status = 0, - CreateUserID = model.userID, - UpdateUserID = model.userID - }; - result = await burnInfoeController.PostBurnInfo(burnInfo); - } - } - else - { - // 新增 BarCodeStation - var burnInfo = new BurnInfo - { - BarcodeID = model.barcodeID, - WipNo = model.wipNo, - BurnPlanHour = PlanHour, - StartTime = DateTime.Now, - ScheduleFinishTime = DateTime.Now.AddMinutes((double)PlanHour * 60), - InUserID = 0, - Status = 0, - CreateUserID = model.userID, - UpdateUserID = model.userID - }; - result = await burnInfoeController.PostBurnInfo(burnInfo); - } - } - return result; - } - - - /// - /// NgInfo-測試不良基本資料檔 - /// - /// - /// - private async Task> Table_NgInfo(BarCodeCheckDto barCodeCheckDto) - { - NgInfoController ngInfoController = new NgInfoController(_context); - NgComponentsController ngComponentsController = new NgComponentsController(_context); - var NgItem = barCodeCheckDto.inputItems.Where(w => w.inputData.Contains("$")).ToList(); - var result = new ResultModel() { Success = true }; - var result_NgComponent = new ResultModel(); - - // 新增 NgInfo - if (NgItem.Count != 0) - { - // 判斷是否不良代碼 - 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()) - { - result.Success = false; - result.Msg = $"查無不良代碼【{item.Replace("$", "").Trim().ToUpper()}】"; - return result; - } - } - - - - NgInfo ngInfo = new NgInfo - { - TypeNo = _context.Stationses.Where(w => w.StationID == barCodeCheckDto.stationID).FirstOrDefault().TestType, - OperatorID = 0, - FixtureNo = "NA", - BarcodeID = barCodeCheckDto.barcodeID, - ReasonNo = NgItem[0].inputData.Replace("$", ""), - ProgramNo = "N/A", - MachineNo = "N/A", - StationId = barCodeCheckDto.stationID, - WipId = barCodeCheckDto.wipID, - CreateUserID = barCodeCheckDto.userID, - UpdateUserID = barCodeCheckDto.userID - }; - result = await ngInfoController.PostNgInfo(ngInfo); - - if (!result.Success) - return result; - - foreach (var NGNo in NgItem) - { - NgComponent ngComponent = new NgComponent - { - NgID = result.Data.FirstOrDefault().NgID, - LocationNo = string.IsNullOrWhiteSpace(NGNo.oldInputData) ? "N/A" : NGNo.oldInputData, - NgNo = NGNo.inputData.Replace("$", ""), - CreateUserID = barCodeCheckDto.userID, - UpdateUserID = barCodeCheckDto.userID - }; - result_NgComponent = await ngComponentsController.PostNgComponent(ngComponent); - - // NgComponent 錯誤 - if (!result_NgComponent.Success) - { - result.Success = false; - result.Msg = result_NgComponent.Msg; - return result; - } - - // 累計預警 - WipAlarmsController wipAlarmsController = new WipAlarmsController(_context); - await wipAlarmsController.PostWipAlarm4ErrorCode(barCodeCheckDto.wipNo, NGNo.inputData.Replace("$", "")); - } - } - return result; - } - - - - /// - /// BarcodeWip-檔案用途 條碼工單資料檔 - /// - /// - /// - private async Task> Table_BarcodeWip(BarCodeCheckDto barCodeCheckDto) - { - BarcodeWipController barcodeWipController = new BarcodeWipController(_context); - - var barcodeWip = barcodeWipController.GetBarcodeWipByTwoKey(barCodeCheckDto.barcodeID, barCodeCheckDto.wipID).Result.Value; - - if (barcodeWip == null) - { - barcodeWip = new BarcodeWip - { - BarcodeID = barCodeCheckDto.barcodeID, - WipID = barCodeCheckDto.wipID, - CreateUserID = barCodeCheckDto.userID - }; - - return await barcodeWipController.PostBarcodeWip(barcodeWip); - } - else - { - return await barcodeWipController.PutBarcodeWip(barcodeWip); - } - } - - /// - /// WipStation - /// - /// - private async Task Table_WipStation(BarCodeCheckDto 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 - }); - await _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 async Task Table_WipClass(BarCodeCheckDto 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 - }); - await _context.SaveChangesAsync(); - } - // 更新 - 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 - await _context.Database.ExecuteSqlRawAsync(updateSql); - } - } - catch (Exception ex) - { - return ex.InnerException.Message + "
"; - } - return ""; - } - - /// - /// WipTime-工單各站數量資料檔 – By TIME - /// - /// - private async Task Table_WipTime(BarCodeCheckDto 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 - }); - await _context.SaveChangesAsync(); - } - // 更新 - 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 - await _context.Database.ExecuteSqlRawAsync(updateSql); - } - - } - 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 IResultModel CheckBarCodeFromWip(string barcode) - { - ResultModel resultModel = new ResultModel { Success = false }; - if (barcode.Length <= 4) - { - resultModel.Msg = "內部序號小於4個字數"; - return resultModel; - } - - WipInfosController wipInfosController = new WipInfosController(_context); - // 內部序號扣除流水號 查詢 - IQueryable q = _context.WipBarcodes.Where(w => w.StartNO.Substring(0, (barcode.Length - 4)) == (barcode.Substring(0, (barcode.Length - 4)))); - if (!q.Any()) - { - resultModel.Msg = "找不到內部序號【" + barcode + "】 對應相關工單號碼"; - return resultModel; - } - else - { - try - { - var No = int.Parse(barcode.Substring(barcode.Length - 4, 4)); - foreach (var item in q) - { - int StartNo = int.Parse(item.StartNO.Substring(item.StartNO.Length - 4, 4)); - int EndNo = int.Parse(item.EndNO.Substring(item.EndNO.Length - 4, 4)); - 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; - } - - // 93200036400001 9320003640001 - var No = int.Parse(barcode.Substring(barcode.Length - 4, 4)); - foreach (var item in q.Where(w => w.StartNO.Substring(0, barcode.Length - 4) == barcode.Substring(0, barcode.Length - 4) - && w.StartNO.Length == barcode.Length)) - { - int StartNo = int.Parse(item.StartNO.Substring(item.StartNO.Length - 4, 4)); - int EndNo = int.Parse(item.EndNO.Substring(item.EndNO.Length - 4, 4)); - if (StartNo <= No && No <= EndNo) - { - resultModel.Success = true; - return resultModel; - } - } - resultModel.Msg = "工單號碼【" + wipNo + "】 找不到範圍內的內部序號【" + barcode + "】"; - } - catch (Exception ex) - { - resultModel.Msg = ex.Message; - } - } - - return resultModel; - } - - /// - /// 內部序號查詢目前生產單位 - /// - /// 內部序號 - /// Success:true or false - [HttpGet("BarCodeToUnit")] - public async Task GetBarCodeToUnitAsync(string barcode) - { - ResultModel resultModel = new ResultModel { Success = false }; - if (barcode.Length <= 4) - { - resultModel.Msg = "內部序號小於4個字數"; - return resultModel; - } - - int BarCodeID = BarCodeToID(barcode).Result; - - if (BarCodeID == 0) - { - resultModel.Msg = "找不到內部序號【" + barcode + "】 對應BarCodeID"; - return resultModel; - } - - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - var q = await barcodeInfoesController.GetBarcodeInfoes(BarCodeID); - resultModel.Msg = "內部序號【" + barcode + "】目前在" + - q.Value.Select(s => s.GetWipInfo.GetFactoryUnit.UnitName).FirstOrDefault(); - - resultModel.Success = true; - return resultModel; - } - - /// - /// 內部序號查詢目前站別 - /// - /// 內部序號 - /// Success:true or false - [HttpGet("BarCodeToStation")] - public async Task GetBarCodeToStationAsync(string barcode) - { - ResultModel resultModel = new ResultModel { Success = false }; - if (barcode.Length <= 4) - { - resultModel.Msg = "內部序號小於4個字數"; - return resultModel; - } - - int BarCodeID = BarCodeToID(barcode).Result; - - if (BarCodeID == 0) - { - resultModel.Msg = "找不到內部序號【" + barcode + "】 對應BarCodeID"; - return resultModel; - } - - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - var q = await barcodeInfoesController.GetBarcodeInfoes(BarCodeID); - resultModel.Msg = "內部序號【" + barcode + "】目前在" + - q.Value.Select(s => s.GetStation.StationName).FirstOrDefault(); - - resultModel.Success = true; - return resultModel; - } - - /// - /// 內部序號是否鎖定 - /// - /// 內部序號 - /// Success:true or false - [HttpGet("BarCodeLock")] - public async Task CheckBarCodeLockAsync(string barcode) - { - ResultModel resultModel = new ResultModel { Success = false }; - if (barcode.Length <= 4) - { - resultModel.Msg = "內部序號小於4個字數"; - return resultModel; - } - - int BarCodeID = BarCodeToID(barcode).Result; - - if (BarCodeID == 0) - { - //resultModel.Msg = "找不到內部序號【" + barcode + "】 對應BarCodeID"; - resultModel.Success = true; - return resultModel; - } - - BarcodeLockController barcodeLockController = new BarcodeLockController(_context); - var q = await barcodeLockController.GetBarcodeLockByBarCodeID(BarCodeID); - if (q.Value.Where(w => w.LockStatus == 0).Any()) - { - resultModel.Msg = "內部序號【" + barcode + "】在當前站別被鎖定,不可過站"; - return resultModel; - } - - resultModel.Success = true; - return resultModel; - } - - /// - /// 內部序號是否報廢 - /// - /// 內部序號 - /// Success:true or false - [HttpGet("BarCodeScrapped")] - public async Task CheckBarCodeScrappedAsync(string barcode) - { - ResultModel resultModel = new ResultModel { Success = false }; - if (barcode.Length <= 4) - { - resultModel.Msg = "內部序號小於4個字數"; - return resultModel; - } - - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - var q = await barcodeInfoesController.GetBarcodeInfoesByNo(barcode); - if (q.Value.Count() == 0) - { - resultModel.Success = true; - resultModel.Msg = "找不到內部序號【" + barcode + "】 對應BarCodeID"; - return resultModel; - } - else if (q.Value.Any(w => w.RuleStatus == "S")) - { - resultModel.Msg = "內部序號【" + barcode + "】已報廢或轉賣, 不可繼續過站!"; - return resultModel; - - } - - resultModel.Success = true; - return resultModel; - } - - /// - /// 確認內部條碼流動 - /// - /// 工單號碼 - /// 內部條碼 - /// 生產單位編號 - /// 作業站編號 - /// - [HttpGet("BarCodeFlow")] - public async Task CheckBarCodeFlowAsync(string wipno, string barcode, string unitno, int stationID) - { - ResultModel resultModel = new ResultModel { Success = false }; - WipInfosController wipInfosController = new WipInfosController(_context); - var q = await wipInfosController.GetWipInfoByWipNo(wipno); - - // 找該筆工單號碼的生產單位代號 - var q1 = q.Value.Where(w => w.UnitNO == unitno).FirstOrDefault(); - - // 取工單號碼開立的 WipID、生產單位 - var wipinfo = q.Value.Select(s => new { s.WipID, s.UnitNO }).ToList(); - - // 取BarCodeID - int BarCodeID = await BarCodeToID(barcode); - - // 取內部序號過站紀錄 - BarcodeStationController barcodeStationController = new BarcodeStationController(_context); - var BarCodeStations = await barcodeStationController.GetBarcodeStationByBarCodeID(BarCodeID); - BarCodeStations = BarCodeStations.Value.ToList(); - - // 判斷需要前製程是否已經投入 - if (q1.InputFlag == "Y") - { - // 有BarCodeID - if (BarCodeID != 0) - { - // 判斷是否有前製程過站資料 - // SMT(S)->DIP(D) - if (unitno == "D") - { - int? WipID = wipinfo.Where(w => w.UnitNO == "S").Select(s => s.WipID).FirstOrDefault(); - if (WipID == null) - { - resultModel.Msg = "該工單號碼【" + wipno + "】的前製程生產單位尚未建立工單基本資料"; - return resultModel; - } - - if (!BarCodeStations.Value.Where(w => w.BarcodeID == BarCodeID && w.WipID == WipID && w.RuleStatus == "P").Any()) - { - resultModel.Msg = "該內部序號【" + barcode + "】前製程生產單位尚未有過站紀錄"; - return resultModel; - } - } - // 組裝(B)->系統測試(T)->成品包裝(P) - else if (unitno == "T") - { - int? WipID = wipinfo.Where(w => w.UnitNO == "B").Select(s => s.WipID).FirstOrDefault(); - if (WipID == null) - { - resultModel.Msg = "該工單號碼【" + wipno + "】的前製程生產單位尚未建立工單基本資料"; - return resultModel; - } - - if (!BarCodeStations.Value.Where(w => w.BarcodeID == BarCodeID && w.WipID == WipID && w.RuleStatus == "P").Any()) - { - resultModel.Msg = "該內部序號【" + barcode + "】前製程生產單位尚未有過站紀錄"; - return resultModel; - } - } - else if (unitno == "P") - { - int? WipID = wipinfo.Where(w => w.UnitNO == "T").Select(s => s.WipID).FirstOrDefault(); - if (WipID == null) - { - resultModel.Msg = "該工單號碼【" + wipno + "】的前製程生產單位尚未建立工單基本資料"; - return resultModel; - } - - if (!BarCodeStations.Value.Where(w => w.BarcodeID == BarCodeID && w.WipID == WipID && w.RuleStatus == "P").Any()) - { - resultModel.Msg = "該內部序號【" + barcode + "】前製程生產單位尚未有過站紀錄"; - return resultModel; - } - } - } - // 沒有BarCodeID - else - { - if (unitno != "S" && unitno != "B") - { - resultModel.Msg = "該工單號碼【" + wipno + "】前製程式尚未投產"; - return resultModel; - } - } - } - - #region 判斷作業站順序 - // 抓流程順序資料 - RuleStationsController ruleStationsController = new RuleStationsController(_context); - var ruleStations = await ruleStationsController.GetRuleStationByFlow(q1.FlowRuleID, 0); - if (ruleStations.Value.Count() == 0) - { - resultModel.Msg = "該工單號碼【" + wipno + "】的流程編號尚未設定流程"; - return resultModel; - } - - // 該作業站 RuleStationID - int? RuleStationID = ruleStations.Value.Where(w => w.StationID == stationID).Select(s => s.RuleStationID).FirstOrDefault(); - if (RuleStationID == null || RuleStationID == 0) - { - resultModel.Msg = "該工單號碼【" + wipno + "】的流程未設定此作業站"; - return resultModel; - } - - // 判斷序號目前是否有重複過站 - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - var BarcodeInfos = await barcodeInfoesController.GetBarcodeInfoesByNo(barcode); - BarcodeInfos = BarcodeInfos.Value.ToList(); - if (BarcodeInfos.Value.Where(w => w.StationID == stationID).Any()) - { - resultModel.Msg = "該內部序號【" + barcode + "】已刷過此站"; - return resultModel; - } - - // 取目前工單ID - int wipID = q1.WipID; - int flowRuleID = q1.FlowRuleID; - - resultModel = (ResultModel)await GetBarCodeLastStopRuleStationID(wipID, BarCodeID, stationID, 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(); - - resultModel.Success = false; - - WipInfosController wipInfosController = new WipInfosController(_context); - - var q = await wipInfosController.GetWipInfoByWipNo(wipNo); - if (q.Value.Count() == 0) - { - resultModel.Msg = "找不到工單號碼【" + wipNo + "】"; - return resultModel; - } - - var WipNoItem = q.Value.Where(w => w.WipNO == wipNo && w.UnitNO == unitNo).ToList(); - if (WipNoItem.Count == 0) - { - resultModel.Msg = "工單號碼【" + wipNo + ",尚未設定此生產單位"; - return resultModel; - } - - if (!WipNoItem.Where(w => w.FlowRuleID == flowRuleID).Any()) - { - resultModel.Msg = "工單號碼【" + wipNo + "】,尚未設定此流程站"; - return resultModel; - } - - - if (!WipNoItem.Where(w => w.LineID == line).Any()) - { - resultModel.Msg = "工單號碼【" + wipNo + "】,尚未設定此線別"; - return resultModel; - } - - if (WipNoItem.Where(w => w.StatusNO == "E").Any()) - { - resultModel.Msg = "工單號碼【" + wipNo + "】,該工單已經投入完工,請切換工單"; - return resultModel; - } - - if (WipNoItem.Where(w => w.StatusNO == "C").Any()) - { - resultModel.Msg = "工單號碼【" + wipNo + "】,該工單已刪除,請切換工單"; - return resultModel; - } - - // 判斷是否是投入站 - var RuleStation = await _context.RuleStations.Where(w => w.FlowRuleID == flowRuleID && w.StationID == stationID) - .FirstOrDefaultAsync(); - if (RuleStation != null) - { - if (RuleStation.Sequence == 1) - { - int WipID = WipNoItem.FirstOrDefault().WipID; - LineInfoesController lineInfoesController = new LineInfoesController(_context); - var q2 = await lineInfoesController.GetLineInfoByWipID(WipID); - if (!q2.Value.Where(w => w.LineID == line).Any()) - { - resultModel.Msg = "工單號碼【" + wipNo + "】,工單尚未開線,不可過站"; - return resultModel; - } - } - } - - // 已投入數量>=工單數量 - if (CheckNowFirstStation(wipNo, unitNo, stationID) == "Y") - { - var FirstWipInfo = WipNoItem.FirstOrDefault(); - if (FirstWipInfo.CompleteQTY >= FirstWipInfo.PlanQTY) - { - //因維修後投入站 不須判斷投入數量 - if (!await _context.BarcodeInfoes.Where(w => w.WipID == WipNoItem.FirstOrDefault().WipID && w.BarcodeNo == barCodeNo).AnyAsync()) - { - resultModel.Msg = "工單號碼【" + wipNo + "】,已投入數量>=工單數量,請在確認"; - return resultModel; - } - } - } - - // 該筆工單號碼鎖定 - WipLockController wipLockController = new WipLockController(_context); - var q3 = await wipLockController.GetWipLockByWipNO(wipNo); - if (q3.Data.Where(w => w.LockStatus == "0" && w.StationID == 0).Any()) - { - resultModel.Msg = "工單號碼【" + wipNo + "】,已被鎖定,不可過站"; - return resultModel; - } - // StationID = 0 代表批次鎖定 - else if (q3.Data.Where(w => w.LockStatus == "0" && w.StationID == stationID).Any()) - { - resultModel.Msg = "工單號碼【" + wipNo + "】,工單在當前站別被鎖定,不可過站"; - return resultModel; - } - resultModel.Success = true; - return resultModel; - } - - /// - /// 判斷序號狀態 - /// - /// 工單號碼 - /// 內部序號 - /// - [HttpGet("CheckBarCodeStation")] - public async Task GetCheckBarCodeStation(string wipno, string barcode) - { - ResultModel resultModel = new ResultModel(); - - #region 內部序號是否被鎖定 - resultModel = (ResultModel)await CheckBarCodeLockAsync(barcode); - if (!resultModel.Success) - return resultModel; - #endregion - - #region 內部序號是否被報廢 - resultModel = (ResultModel)await CheckBarCodeScrappedAsync(barcode); - if (!resultModel.Success) - return resultModel; - #endregion - - #region 找尋內部序號(工單號碼) 並與接收工單號碼是否一致 - //resultModel = (ResultModel)CheckBarCodeFromWip(barcode); - //if (!resultModel.Success) - // return resultModel; - //else if (resultModel.Msg != wipno.ToUpper()) - //{ - // resultModel.Msg = "工單號碼【" + wipno + "】與內部序號所帶出工單號碼【" + resultModel.Msg + "】不一致"; - // resultModel.Success = false; - // return resultModel; - //} - #endregion - - return resultModel; - } - - /// - /// 燒機判斷 - /// - /// 工單號碼 - /// 內部序號ID - /// 作業站ID - /// - private async Task GetCheckBurn(string wipno, int barcodeID, int stationID) - { - ResultModel resultModel = new ResultModel(); - - // 判斷作業站是否為燒機站 - StationsesController stationsesController = new StationsesController(_context); - var station = await stationsesController.GetStations(stationID); - // Station_Type = B 燒機站 - if (station.Value.Where(w => w.TypeNo == "B").Any()) - { - // 判斷是否有燒機時間 - WipBoardController wipBoardController = new WipBoardController(_context); - var wipBoardTime = wipBoardController.GetWipBoardToBITime(wipno).Result.Value; - WipSystemController wipSystemController = new WipSystemController(_context); - var wipSystemTime = wipSystemController.GetWipSystemToBITime(wipno).Result.Value; - if (wipBoardTime <= 0 && wipSystemTime <= 0) - { - resultModel.Success = false; - resultModel.Msg = "請確認燒機時間是否有填寫或者格式有誤"; - return resultModel; - } - - // 判斷燒機時間是否足夠 - BurnInfoeController burnInfoeController = new BurnInfoeController(_context); - var burnInfo = await burnInfoeController.GetBurnInfosByBarcodeID(barcodeID); - if (burnInfo.Value.Count() != 0) - { - // 取實際燒機完成時間 空白資料 - var item = burnInfo.Value.Where(w => string.IsNullOrWhiteSpace(w.FinishTime.ToString())).FirstOrDefault(); - if (item != null) - { - // 現在時間 < 預計排程時間 - if (DateTime.Now < item.ScheduleFinishTime) - { - resultModel.Success = false; - resultModel.Msg = "燒機排程完成時間【" + item.ScheduleFinishTime + "】尚未到達"; - return resultModel; - } - } - else // 燒機資料都有填入實際燒機時間 - { - resultModel.Msg = "BurnIn"; - } - } - else - // 沒有BurnInfo = Burn In - { - resultModel.Msg = "BurnIn"; - } - resultModel.Success = true; - return resultModel; - } - else - { - resultModel.Success = true; - return resultModel; - } - } - - /// - /// 確認組件狀態 - /// - /// - [HttpGet("BarCodeKP")] - public async Task CheckBarCodeKPAsync([FromQuery] BarcodeItemKPDto barcodeItemKPDto) - { - ResultModel resultModel = new ResultModel { Success = false }; - try - { - #region 判斷是否有工單 - WipInfosController wipInfosController = new WipInfosController(_context); - var wipinfo = await wipInfosController.GetWipInfoByWipNo(barcodeItemKPDto.WipNo); - wipinfo = wipinfo.Value.Where(w => w.UnitNO == barcodeItemKPDto.unitNo).ToList(); - if (wipinfo.Value.Count() == 0) - { - resultModel.Msg = "找不到工單號碼【" + barcodeItemKPDto.WipNo + "】"; - return resultModel; - } - #endregion - - #region 判斷是否有輸入工單料號 - WipAttsController wipAttsController = new WipAttsController(_context); - string ItemNo = (await wipAttsController.GetWipAtt(wipinfo.Value.FirstOrDefault().WipNO)).Value.ItemNO; - if (string.IsNullOrWhiteSpace(ItemNo)) - { - resultModel.Msg = "工單號碼【" + barcodeItemKPDto.WipNo + "】,找不到料號名稱"; - return resultModel; - } - #endregion - - #region 判斷工單料號是否有在料號基本檔 - MaterialItemController materialItemController = new MaterialItemController(_context); - var MaterialItem = await materialItemController.GetMaterialItemByItemNO(ItemNo); - if (MaterialItem == null) - { - resultModel.Msg = "料號【" + ItemNo + "】,在料號基本資料檔找不到"; - return resultModel; - } - #endregion - - #region 確認是否有設定key Parts資料 - WipKpsController wipKpsController = new WipKpsController(_context); - var wipKps = (await wipKpsController.GetWipKpByWipNo(barcodeItemKPDto.WipNo)).Value.ToList(); - wipKps = wipKps.Where(w => w.UnitNo == barcodeItemKPDto.ststionUnitNo).OrderBy(o => o.KpSeq).ToList(); - if (wipKps.Count != 0) - { - #region 判斷內部序號是否有過站紀錄 - var BarCodeID = await BarCodeToID(barcodeItemKPDto.barcode); - //if (BarCodeID == 0) - //{ - // resultModel.Msg = "內部序號【" + BarCodeID + "】,在條碼資料檔找不到"; - // return resultModel; - //} - #endregion - - #region 判斷組件序號是否有紀錄 - BarcodeItemsController barcodeItemsController = new BarcodeItemsController(_context); - var BarCodeItems = (await barcodeItemsController.GetBarcodeItemByBarCodeID(BarCodeID)).Value.ToList(); - BarCodeItems = BarCodeItems.Where(w => w.S.UnitNo == barcodeItemKPDto.ststionUnitNo && w.WipID == wipinfo.Value.FirstOrDefault().WipID).ToList(); - #endregion - - // 計算過站時刷的組件數量與已經存BarCodeItems - var KPQty = barcodeItemKPDto.inputKP.Count + BarCodeItems.Count; - #region 刷入組件數量超過 - if (KPQty > wipKps.Count) - { - resultModel.Msg = "組件數量已刷超過設定數量,請確認"; - return resultModel; - } - #endregion - - #region 比對組件資料 - var CheckMsg = string.Empty; - int x = BarCodeItems.Count; - - for (int i = 0; i < barcodeItemKPDto.inputKP.Count; i++) - { - - // 按照順序 - var wipKpsItem = wipKps[x + i]; - var barcodeKPDtoItem = barcodeItemKPDto.inputKP[i]; - // 有KpNo以KpNo為主 - if (!string.IsNullOrWhiteSpace(barcodeKPDtoItem.inputType)) - { - wipKpsItem = wipKps.Where(w => w.KpNo.ToUpper() == barcodeKPDtoItem.inputType.ToUpper()).FirstOrDefault(); - - if (wipKpsItem == null) - { - wipKpsItem = wipKps[x + i]; - } - } - - #region 比對序號長度是否正確 - if (!string.IsNullOrWhiteSpace(wipKpsItem.Length.ToString())) - { - if (wipKpsItem.Length != barcodeKPDtoItem.inputData.Length && wipKpsItem.Length != 0) - CheckMsg += "組件序號【" + barcodeKPDtoItem.inputData + "】 與組件名稱【" + wipKpsItem.KpName + "】長度不符合
"; - } - #endregion - - #region 前置碼正確 - if (!string.IsNullOrWhiteSpace(wipKpsItem.Title)) - { - if (!barcodeKPDtoItem.inputData.ToUpper().StartsWith(wipKpsItem.Title.ToUpper())) - CheckMsg += "組件序號【" + barcodeKPDtoItem.inputData + "】 與組件名稱【" + wipKpsItem.Title + "】前置碼不符合
"; - } - #endregion - - #region 組件代碼-組件序號是否重複 - //WINDOWS驗證-取得安勤 + 昶亨的KP SN - #region 取消 - #endregion - //改抓C_SFIS_KEYPARTS (安勤轉拋) - #region - if (await _context.CSfisKeyparts.Where(w => w.Partbarcode.ToUpper() == barcodeKPDtoItem.inputData).AnyAsync()) - { - CheckMsg += "組件名稱【" + wipKpsItem.KpName + "】已有相同組件序號【" + barcodeKPDtoItem.inputData + "】安勤轉拋KeyParts紀錄
"; - } - #endregion - - var checkDataRedundancy = await barcodeItemsController.GetBarcodeItemByDataRedundancy(wipKpsItem.KpNo, barcodeKPDtoItem.inputData); - if (checkDataRedundancy.Value.Count() != 0) - { - CheckMsg += "組件名稱【" + wipKpsItem.KpName + "】已有相同組件序號【" + barcodeKPDtoItem.inputData + "】紀錄
"; - } - #endregion - - #region 判斷組件序號是否在製狀態 - if (wipKpsItem.KpNo.ToUpper() == "04") - { - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - var BarCodeInfo = await barcodeInfoesController.GetBarcodeInfoesByNo(barcodeKPDtoItem.inputData); - if (BarCodeInfo.Value.Where(w => w.StatusID != -1).Any()) - { - CheckMsg += "組件序號【" + barcodeKPDtoItem.inputData + "】 目前是在製狀態
"; - } - } - #endregion - - #region 判斷MAC區間 - // 安勤不需要判斷MAC區間 - //if (wipKpsItem.KpNo.ToUpper() == "MAC") - //{ - // WipMACController wipMACController = new WipMACController(_context); - // var wipMAC = await wipMACController.GetWipMAC(barcodeItemKPDto.WipNo); - // if (wipMAC.Value == null) - // { - // CheckMsg += "工單號碼【" + barcodeItemKPDto.WipNo + "】 找不到綁定MAC區間
"; - // } - // else - // { - // // 判斷MAC前置碼是否一樣 - // if (!barcodeKPDtoItem.inputData.StartsWith(wipMAC.Value.Title)) - // { - // CheckMsg += "組件序號【" + barcodeKPDtoItem.inputData + "】 與MAC【" + wipMAC.Value.Title + "】前置碼不符合
"; - // } - // else - // { - // // 判斷是否符合區間 - // if (barcodeKPDtoItem.inputData.Length == 12) - // { - // if (!(Convert.ToInt32(wipMAC.Value.StartNO, 16) <= Convert.ToInt32(barcodeKPDtoItem.inputData.Substring(6, 6), 16) - // && Convert.ToInt32(barcodeKPDtoItem.inputData.Substring(6, 6), 16) <= Convert.ToInt32(wipMAC.Value.EndNO, 16))) - // { - // CheckMsg += "組件序號【" + barcodeKPDtoItem.inputData + "】 與工單設定MAC區間不符合
"; - // } - // } - // } - // } - //} - #endregion - - #region 判斷出貨序號 - // 當KP_NAME是 EXT_NO 判斷組件-出貨序號 是否有在區間 - if (wipKpsItem.KpNo.ToUpper() == "95") - { - WipBarcodeOtherController wipBarcodeOtherController = new WipBarcodeOtherController(_context); - var WipBarCodeOther = await wipBarcodeOtherController.CheckWipBarcodeOtherByNo(barcodeItemKPDto.WipNo, barcodeKPDtoItem.inputData); - if (WipBarCodeOther.Value.Count() == 0) - { - CheckMsg += "組件序號【" + barcodeKPDtoItem.inputData + "】 與工單設定出貨序號區間不符合
"; - } - else - { - resultModel.Data = new List { barcodeKPDtoItem.inputData }; - resultModel.Msg = barcodeKPDtoItem.inputData; - } - } - #endregion - } - - if (!string.IsNullOrWhiteSpace(CheckMsg)) - { - resultModel.Msg = CheckMsg; - return resultModel; - } - #endregion - } - #endregion - resultModel.Success = true; - return resultModel; - } - catch (Exception ex) - { - resultModel.Success = false; - resultModel.Msg = ex.Message; - return resultModel; - } - } - - /// - /// 確認治具狀態 - /// - /// - //[HttpGet("BarCodeOutfit")] - private async Task 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 = await outfitInfoesController.GetOutfitInfoByOutfitNo(outfitNo.inputData.ToUpper()); - - if (q.Value == null) - { - resultModel.Msg = "中央治具找不到該治具編號【" + outfitNo.inputData + "】"; - return resultModel; - } - - // 判斷治具種類 - var q1 = await outfitCommodityInfoesController.GetOutfitCommodityInfo(); - 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; - } - - /// - /// 確認組件數量正確 - /// - /// 工單號碼 - /// 內部條碼 - /// 生產單位 - /// - [HttpGet("CheckBarCodeKPQty")] - public async Task CheckBarCodeKPQtyAsync(string wipno, string barcode, string unitno) - { - ResultModel resultModel = new ResultModel { Success = false }; - - #region 判斷是否有工單 - WipInfosController wipInfosController = new WipInfosController(_context); - var q = await wipInfosController.GetWipInfoByWipNo(wipno); - q = q.Value.Where(w => w.UnitNO == unitno).ToList(); - if (q.Value.Count() == 0) - { - resultModel.Msg = "找不到工單號碼【" + wipno + "】"; - return resultModel; - } - #endregion - - #region 判斷是否有輸入工單料號 - WipAttsController wipAttsController = new WipAttsController(_context); - string ItemNo = (await wipAttsController.GetWipAtt(q.Value.FirstOrDefault().WipNO)).Value.ItemNO; - if (string.IsNullOrWhiteSpace(ItemNo)) - { - resultModel.Msg = "工單號碼【" + wipno + "】,找不到料號名稱"; - return resultModel; - } - #endregion - - #region 判斷工單料號是否有在料號基本檔 - MaterialItemController materialItemController = new MaterialItemController(_context); - var MaterialItem = await materialItemController.GetMaterialItemByItemNO(ItemNo); - if (MaterialItem == null) - { - resultModel.Msg = "料號【" + ItemNo + "】,在料號基本資料檔找不到"; - return resultModel; - } - #endregion - - #region 確認是否有設定key Parts資料 - MaterialKpController materialKpController = new MaterialKpController(_context); - var MaterialKps = (await materialKpController.GetMaterialKpByItemID(MaterialItem.ItemID)).ToList(); - MaterialKps = MaterialKps.Where(w => w.StationType == unitno).ToList(); - if (MaterialKps.Count != 0) - { - #region 判斷內部序號是否有過站紀錄 - var BarCodeID = await BarCodeToID(barcode); - //if (BarCodeID == 0) - //{ - // resultModel.Msg = "內部序號【" + barcode + "】,在條碼資料檔找不到"; - // return resultModel; - //} - #endregion - - #region 判斷組件序號是否有紀錄 - BarcodeItemsController barcodeItemsController = new BarcodeItemsController(_context); - var BarCodeItems = (await barcodeItemsController.GetBarcodeItems(BarCodeID)).Value.ToList(); - BarCodeItems = BarCodeItems.Where(w => w.WipID == q.Value.FirstOrDefault().WipID).ToList(); - if (BarCodeItems.Count == 0) - { - resultModel.Msg = "內部序號【" + barcode + "】,在條碼組件件資料檔找不到"; - return resultModel; - } - #endregion - - #region 判斷組件數量是否正確 - // 先把出貨序號拿掉 - MaterialKps = MaterialKps.Where(w => w.KpName.ToUpper() != "EXT_NO").ToList(); - if (MaterialKps.Count != BarCodeItems.Count) - { - resultModel.Msg = "組件對應數量【" + MaterialKps.Count + "】不等於條碼組件數量【" + BarCodeItems.Count + "】"; - return resultModel; - } - #endregion - } - #endregion - - resultModel.Success = true; - return resultModel; - } - - /// - /// 內部序號找BarCodeID - /// - /// 內部條碼 - /// 0:找不到 - private async Task BarCodeToID(string BarCode) - { - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - var q = await barcodeInfoesController.GetBarcodeInfoesByNo(BarCode); - if (!q.Value.Any()) - return 0; - else - return q.Value.FirstOrDefault().BarcodeID; - - } - - /// - /// 料號找料號ID - /// - /// 料號 - /// 0:找不到 - private async Task ItemNoToItemID(string ItemNo) - { - MaterialItemController materialItemController = new MaterialItemController(_context); - var q = await materialItemController.GetMaterialItemByItemNO(ItemNo); - if (q == null) - return 0; - else - return q.ItemID; - - } - - /// - /// 取得上一個作業站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 }; - - // 用作業站抓 有設定下一站為該站的資料 - RulesController rulesController = new RulesController(_context); - var rules = await rulesController.GetRulesByFlowRuleID(flowRuleID); - // 取得目前BarCodeInfo 站別 - BarcodeInfoesController barcodeInfoesController = new BarcodeInfoesController(_context); - var barcodeInfo = barcodeInfoesController.GetBarcodeInfoes(barCodeID).Result.Value.FirstOrDefault(); - - if (rules.Value.Count() == 0) - { - resultModel.Msg = "找不到該筆工單流程之流程設定相關資料,請確認"; - return resultModel; - } - //else if (barcodeInfo == null) - //{ - // resultModel.Msg = "該內部序號尚未投入,請確認"; - // return resultModel; - //} - else - { - // 有過站紀錄 - if (barcodeInfo != null) - { - // 如果BarCodeInfo 結案,判斷當下作業站是否第一站 - if (barcodeInfo.StatusID == -1) - { - if (barcodeInfo.WipID == wipID) - { - resultModel.Msg = "該內部序號在目前生產製程已完工,請確認"; - return resultModel; - } - - if (!rules.Value.Where(w => w.StationID == stationID && w.RuleSeq == 1 && w.RuleStatus == "P").Any()) - { - resultModel.Msg = "目前作業站不是第一站,請確認"; - return resultModel; - } - resultModel.Success = true; - return resultModel; - } - - // 目前BarCodeInfo StationID 取得相對應下個流程StationID - var rulesByBarCodeInfoStationID = rules.Value.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.Value.Where(w => w.StationID == stationID && w.RuleSeq == 1 && w.RuleStatus == "P").Any()) - { - resultModel.Msg = "該內部序號尚未投入,請確認"; - return resultModel; - } - } - } - - //if (rules.Value.Count() != 0) - //{ - // // 抓有設定下一站=目前作業站的上一站 - // var nowruleSations = rules.Value.Select(s => new { s.StationID, s.RuleStatus }).ToList(); - // // 取得目前BarCode 最新過站資料 - - // if (nowruleSations.Where(w => w.StationID == barcodeInfo.StationID - // && w.RuleStatus == barcodeInfo.RuleStatus).Count() == 0) - // { - // resultModel.Msg = "找不到上一個作業站過站紀錄,請確認"; - // return resultModel; - // } - //} - - resultModel.Success = true; - return resultModel; - } - - /// - /// 確認下一站為完工 - /// - /// 工單號碼 - /// 生產單位ID - /// 作業站ID - /// Success(true)是 (false)不是 - [HttpGet("CheckNextStopCloseStation")] - public async Task CheckNextStopCloseStation(string wipno, string unitNo, int stationID) - { - ResultModel resultModel = new ResultModel { Success = false }; - WipInfosController wipInfosController = new WipInfosController(_context); - var q = wipInfosController.GetWipInfoByWipNo(wipno); - - if (!q.Result.Value.Where(w => w.UnitNO == unitNo).Any()) - { - return resultModel; - } - - var q1 = q.Result.Value.Where(w => w.UnitNO == unitNo).FirstOrDefault(); - // 取得流程 - RuleStationsController ruleStationsController = new RuleStationsController(_context); - var ruleStations = await ruleStationsController.GetRuleStationByFlow(q1.FlowRuleID, 0); - if (ruleStations.Value.Count() != 0) - { - // 在RuleStation 找不到該作業站 - if (!ruleStations.Value.Any(a => a.StationID == stationID)) - return resultModel; - - //int rulestationID = ruleStations.Value.Where(w => w.StationID == stationID).FirstOrDefault().RuleStationID; - - RulesController rulesController = new RulesController(_context); - var rules = await rulesController.GetRulesByFlowRuleID(q1.FlowRuleID); - - // 當下一站SatationID= 1000 代表完工站 - if (rules.Value.Where(w => w.StationID == stationID && w.NextStationID == 1000).Any()) - { - resultModel.Success = true; - return resultModel; - } - } - return resultModel; - } - - /// - /// 確認目前該站是否為第一站 - /// - /// 工單號碼 - /// 生產單位ID - /// 作業站ID - /// Y:是 N:不是 - //[HttpGet("CheckNowFirstStation")] - private string CheckNowFirstStation(string wipno, string unitNo, int stationID) - { - - WipInfosController wipInfosController = new WipInfosController(_context); - var q = _context.WipInfos.Where(w => w.WipNO == wipno && w.UnitNO == unitNo).FirstOrDefault(); - - if (q != null) - { - // 取得流程 - RuleStationsController ruleStationsController = new RuleStationsController(_context); - var ruleStations = ruleStationsController.GetRuleStationByFlow(q.FlowRuleID, 0).Result.Value.ToList(); - if (ruleStations.Count() != 0) - { - - // 用目前站別判斷順序是不是 1 - if (ruleStations.Where(w => w.StationID == stationID && w.Sequence == 1 && w.StationType == "M").Any()) - return "Y"; - } - } - return "N"; - } - - /// - /// 判斷生產中工單是否已經全部完工 自動更新 - /// - /// 工單號碼 - /// 生產單位ID - /// StationID - /// - [HttpGet("CheckWipNoBarCodeAllClost")] - public async Task CheckWipNoBarCodeAllClost(string wipno, string unitNo, int stationID) - { - ResultModel resultModel = new ResultModel { Success = true }; - WipInfosController wipInfosController = new WipInfosController(_context); - var wipInfo = wipInfosController.GetWipInfoByWipNo(wipno).Result.Value.FirstOrDefault(w => w.UnitNO == unitNo); - - if (wipInfo != null) - { - int wipID = wipInfo.WipID; - - // 取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; - // 比對過站Station完工跟工單數一樣 = 完工 - 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) - { - var result = await wipInfosController.PutWipinfoToStatusNO(wipID, "E"); - if (!result.Success) - { - resultModel.Success = false; - resultModel.Msg = result.Msg; - return resultModel; - } - - resultModel.Success = true; - resultModel.Msg = "完工"; - } - } - return resultModel; - } - - /// - /// 確認是否有掃毒 - /// - /// 工單號碼 - /// 工單料號 - /// - private IResultModel 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}】,未執行掃毒,請確認"; - 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; - } - } - } - - } -} diff --git a/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckNewController.cs b/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckNewController.cs new file mode 100644 index 00000000..ec0cae61 --- /dev/null +++ b/AMESCoreStudio.WebApi/Controllers/BLL/BarCodeCheckNewController.cs @@ -0,0 +1,2507 @@ +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.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 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.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.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.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}"); + } + + //// 過站為PASS狀態 + //if (data.ruleStatus == "P") + //{ + // 判斷是否為第一站 + 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.unitNo) + .OrderBy(o => o.KpSeq).ToList(); + if (wipKps.Count != 0) + { + // 取料號組件資料 + var BarCodeItems = _context.BarcodeItems.Where(w => w.BarcodeID == data.barCode && + w.S.UnitNo == data.unitNo && + 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"); + } + } + 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; + } + + // 生產單位_簡碼 + 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().ToUpper()).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 組件代碼-組件序號是否重複 + + //WINDOWS驗證-取得安勤 + 昶亨的KP SN + #region 取消 + #endregion + //改抓C_SFIS_KEYPARTS (安勤轉拋) + #region + if (await _context.CSfisKeyparts.Where(w => w.Partbarcode.ToUpper() == inputItem.inputData).AnyAsync()) + { + CheckMsg += "組件名稱【" + wipKp.KpName + "】已有相同組件序號【" + inputItem.inputData + "】安勤轉拋KeyParts紀錄
"; + } + #endregion + + 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區間 + + // 安勤不需要判斷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; + } + } +} + diff --git a/AMESCoreStudio.WebApi/Controllers/BLL/RPTController.cs b/AMESCoreStudio.WebApi/Controllers/BLL/RPTController.cs index e1ab93bc..a89073f3 100644 --- a/AMESCoreStudio.WebApi/Controllers/BLL/RPTController.cs +++ b/AMESCoreStudio.WebApi/Controllers/BLL/RPTController.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Threading.Tasks; using Dapper; using AMESCoreStudio.WebApi.Extensions; +using AMESCoreStudio.WebApi.Controllers.QASRV; namespace AMESCoreStudio.WebApi.Controllers.BLL { @@ -686,7 +687,7 @@ namespace AMESCoreStudio.WebApi.Controllers.BLL } return 0.0; } - } + } #endregion } @@ -1908,5 +1909,123 @@ namespace AMESCoreStudio.WebApi.Controllers.BLL return result; } + + #region RPT004 線頭看板 + + /// + /// 線頭看板 + /// + /// 生產製程 + /// 線別ID + /// + [HttpGet("GetRPT004View")] + public async Task GetRPT004View(string unitNo, int lineId = 0) + { + var result = new RPT004ViewDto(); + result.lineId = lineId; + result.unitNo = unitNo; + var query = @$" SELECT * + FROM ( SELECT + W.WIP_NO , W.WIP_ID , W.UNIT_NO , W.PLAN_QTY , W.COMPLETE_QTY , + A.ITEM_NO , L.LINE_ID , L.LINE_DESC , S.STATION_NAME , B.STATION_ID , B.INPUT_DATE, + ROW_NUMBER() OVER( PARTITION BY + W.WIP_NO , W.WIP_ID , W.UNIT_NO , W.PLAN_QTY , W.COMPLETE_QTY , + A.ITEM_NO , L.LINE_ID , L.LINE_DESC ORDER BY B.INPUT_DATE ASC) AS RN + FROM JHAMES.LINE_INFO L + INNER JOIN JHAMES.WIP_INFO W ON L.WIP_ID = W.WIP_ID + INNER JOIN JHAMES.WIP_ATT A ON W.WIP_NO = A.WIP_NO + INNER JOIN JHAMES.BARCODE_STATION B ON B.WIP_ID = L.WIP_ID + INNER JOIN JHAMES.STATIONS S ON S.STATION_ID = B.STATION_ID) + WHERE RN = 1 + AND UNIT_NO = :unitNo + AND LINE_ID = :lineId "; + + DynamicParameters p = new DynamicParameters(); + p.Add("unitNo", unitNo); + p.Add("lineId", lineId, DbType.Int32); + + try + { + var q = await _context.Database.DapperQueryAsync(query, p); + if (q.Any()) + { + result.wipNo = q.FirstOrDefault().WIP_NO; + result.product = q.FirstOrDefault().ITEM_NO; + result.wipNoQty = (int)q.FirstOrDefault().PLAN_QTY; + result.cumulativeQty = (int)q.FirstOrDefault().COMPLETE_QTY; + result.lineName = q.FirstOrDefault().LINE_DESC; + result.stationName = q.FirstOrDefault().STATION_NAME; + + var wipId = (int)q.FirstOrDefault().WIP_ID; + var stationId = (int)q.FirstOrDefault().STATION_ID; + + // 取今日投入數量及開工時間 + query = @$" SELECT MIN(INPUT_DATE) INPUT_DATE , COUNT(*) QTY FROM + JHAMES.BARCODE_STATION + WHERE WIP_ID=:wipId + AND STATION_ID=:stationId + AND TRUNC(INPUT_DATE) >= TRUNC(SYSDATE) + --AND TRUNC(INPUT_DATE) >= TRUNC(TO_DATE('2023-08-01', 'YYYY-MM-DD'))"; + + p = new DynamicParameters(); + p.Add("wipId", wipId); + p.Add("stationId", stationId, DbType.Int32); + var q1 = await _context.Database.DapperQueryAsync(query, p); + if (q1.Any(w => w.INPUT_DATE != null)) + { + result.actualQty = (int)q1.FirstOrDefault().QTY; + result.wipNoStrDate = ((DateTime)q1.FirstOrDefault().INPUT_DATE).ToString("yyyy/MM/dd HH:mm:ss"); + + // 實際投入數量 > 累計投入數量 + if (result.actualQty > result.cumulativeQty) + result.actualQty = result.cumulativeQty; + + // 計算作業時間 + DateTime str = Convert.ToDateTime(result.wipNoStrDate); + DateTime end = DateTime.Now; + TimeSpan ts = end.Subtract(str); + var WorkTime = (double)Math.Abs(Math.Round(ts.TotalMinutes, 2)); + + // 中午休息時間 + if (str < Convert.ToDateTime("12:20:00") && Convert.ToDateTime("12:40:00") < end) + WorkTime -= 60; + + // 早上休息時間 + if (str < Convert.ToDateTime("09:52:00") && Convert.ToDateTime("09:53:00") < end) + WorkTime -= 10; + + // 下午休息時間 + if (str < Convert.ToDateTime("14:52:00") && Convert.ToDateTime("14:53:00") < end) + WorkTime -= 10; + + // 計算效率 + var standardWorkTimes = await _context.StandardWorkTimes.Where(w => w.UnitNo == result.unitNo && + w.ItemNo == result.product).FirstOrDefaultAsync(); + if (standardWorkTimes != null) + { + result.workTime = (double)standardWorkTimes.TotalCT; + } + + + // 標準總工時 = 標準工時 * 實際投入數量 + var allWorkTime = result.workTime * result.actualQty; + result.efficiency = Math.Round((allWorkTime / WorkTime * 100), 2); + + result.requiredQty = (int)Math.Round((WorkTime / result.workTime), 0); + + // 標準工時等於0 應投入數改0 + if (result.workTime <= 0) + result.requiredQty = 0; + } + } + } + catch + { + return result; + } + return result; + } + + #endregion } } diff --git a/AMESCoreStudio.WebApi/DTO/AMES/BarcodeItemKPDto.cs b/AMESCoreStudio.WebApi/DTO/AMES/BarcodeItemKPDto.cs index 8616c91e..df28a280 100644 --- a/AMESCoreStudio.WebApi/DTO/AMES/BarcodeItemKPDto.cs +++ b/AMESCoreStudio.WebApi/DTO/AMES/BarcodeItemKPDto.cs @@ -14,12 +14,22 @@ namespace AMESCoreStudio.WebApi.DTO.AMES /// /// 工單號碼 /// - public string WipNo { get; set; } + public string wipNo { get; set; } /// - /// 條碼 + /// 工單號碼ID /// - public string barcode { get; set; } + public int wipId { get; set; } + + /// + /// 內部條碼ID + /// + public int barCode { get; set; } + + /// + /// 內部條碼No + /// + public string barCodeNo { get; set; } /// /// 工單-生產單位 diff --git a/AMESCoreStudio.WebApi/DTO/AMES/RPT004VIiewDto.cs b/AMESCoreStudio.WebApi/DTO/AMES/RPT004VIiewDto.cs new file mode 100644 index 00000000..2b323b6b --- /dev/null +++ b/AMESCoreStudio.WebApi/DTO/AMES/RPT004VIiewDto.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +#nullable disable + +namespace AMESCoreStudio.WebApi.DTO.AMES +{ + public partial class RPT004ViewDto + { + public RPT004ViewDto() + { + + } + + /// + /// 生產製程 + /// + public string unitNo { get; set; } + + /// + /// 生產線別 + /// + public int lineId { get; set; } = 0; + + /// + /// 生產線別名稱 + /// + public string lineName { get; set; } + + /// + /// 目前站別名稱 + /// + public string stationName { get; set; } + + /// + /// 當前工單 + /// + public string wipNo { get; set; } + + /// + /// 工程編號 + /// + public string product { get; set; } + + /// + /// 計畫產量 + /// + public int wipNoQty { get; set; } = 0; + + /// + /// 開工時間 + /// + public string wipNoStrDate { get; set; } = DateTime.Now.ToString("yyyy/MM/dd HH:mm"); + + /// + /// 標準工時 + /// + public double workTime { get; set; } = 0.0; + + /// + /// 應投入數量 + /// + public int requiredQty { get; set; } = 0; + + /// + /// 實際投入數量(當天) + /// + public int actualQty { get; set; } = 0; + + /// + /// 累計投入數量 + /// + public int cumulativeQty { get; set; } = 0; + + /// + /// 生產效率 + /// + public double efficiency { get; set; } = 0; + + } +} diff --git a/AMESCoreStudio.WebApi/DTO/BLL/BarCodeCheckDto.cs b/AMESCoreStudio.WebApi/DTO/BLL/BarCodeCheckDto.cs index 2318d6a8..b95cbc29 100644 --- a/AMESCoreStudio.WebApi/DTO/BLL/BarCodeCheckDto.cs +++ b/AMESCoreStudio.WebApi/DTO/BLL/BarCodeCheckDto.cs @@ -57,7 +57,7 @@ namespace AMESCoreStudio.WebApi.DTO.AMES public string ruleStatus { get; set; } = "P"; /// - /// 生產單位 + /// 生產單位-製程 /// [DataMember] public string unitNo { get; set; } @@ -69,12 +69,11 @@ namespace AMESCoreStudio.WebApi.DTO.AMES public int flowRule { get; set; } = 0; /// - /// 作業站 + /// 作業站ID /// [DataMember] public int stationID { get; set; } = 0; - /// /// 線別站 /// @@ -113,27 +112,27 @@ namespace AMESCoreStudio.WebApi.DTO.AMES public class inputItem { /// - /// 刷入類型 NG or KP(Item_No) + /// 刷入類型 NG(不良) or KP(Item_No) /// [DataMember] public string inputType { get; set; } /// - /// 刷入組件資料或不良代碼 + /// KP:組件料號,NG:不良代碼 /// [DataMember] public string inputData { get { return InputData; } set { InputData = string.IsNullOrWhiteSpace(value) ? "" : value.Trim().ToUpper(); } } private string InputData; /// - /// 組件:舊組件序號 NG:異常位置 + /// KP:舊組件序號,NG:異常位置 /// [DataMember] public string oldInputData { get { return OldInputData; } set { OldInputData = string.IsNullOrWhiteSpace(value) ? "" : value.Trim().ToUpper(); } } private string OldInputData; /// - /// 組件:組件料號 NG: + /// KP:組件料號,NG: /// [DataMember] public string kpItemNo { get { return KpItemNo; } set { KpItemNo = string.IsNullOrWhiteSpace(value) ? "" : value.Trim().ToUpper(); } } @@ -158,4 +157,43 @@ namespace AMESCoreStudio.WebApi.DTO.AMES public string PartNo { get; set; } = string.Empty; } } + + public class BarCodeCheckDtoForDBData : BarCodeCheckDto + { + /// + /// 料號ID + /// + [DataMember] + public int item { get; set; } = 0; + + /// + /// 料號No + /// + [DataMember] + public string itemNo { get; set; } = string.Empty; + + /// + /// Burn In 燒機完成狀態 + /// + [DataMember] + public bool burnIn { get; set; } = false; + + /// + /// 工作站_測試類別 + /// + [DataMember] + public string stations_TestType { get; set; } = string.Empty; + + /// + /// 工作站_工作站類別 + /// + [DataMember] + public string stations_TypeNo { get; set; } = string.Empty; + + /// + /// 生產單位_簡碼 + /// + [DataMember] + public string factoryUnit_UnitCode { get; set; } = string.Empty; + } }