¶Ô±ÈÐÂÎļþ |
| | |
| | | using Tiger.Model; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq.Expressions; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using Rhea.Common; |
| | | using System.Linq; |
| | | using Tiger.IBusiness; |
| | | using Tiger.Model.Entitys.MES.Position; |
| | | using Tiger.Business.MES; |
| | | |
| | | namespace Tiger.Business |
| | | { |
| | | /// <summary> |
| | | /// ç产ä¸çå·¥åæ¹æ¬¡ |
| | | /// </summary> |
| | | public partial class WorkBatch : IWorkBatch, IDisposable |
| | | { |
| | | public WorkBatch(string order) |
| | | { |
| | | OrderNo = order; |
| | | } |
| | | #region Propertys & Variables |
| | | public string OrderNo { get; set; } |
| | | public string LineCode { get; set; } |
| | | public BIZ_MES_WO WO { get; set; } |
| | | public BAS_ITEM Product { get; set; } |
| | | public BIZ_MES_WO_BATCH Batch { get; set; } |
| | | public BAS_CUSTOMER Customer { get; set; } |
| | | public List<BIZ_MES_WO_SN> WoSNs { get; set; } |
| | | public List<MES_WO_EDGE> Edges { get; set; } |
| | | public List<MES_WO_NODE> Nodes { get; set; } |
| | | public List<MES_WO_OPER> NodeSets { get; set; } |
| | | public List<MES_WO_NODE_ACT> NodeActs { get; set; } |
| | | public List<MES_WO_ACTION> ActionSets { get; set; } |
| | | public List<MES_WO_NODE_POST> NodePosts { get; set; } |
| | | public List<MES_WO_NODE_DFTG> NodeDftgs { get; set; } |
| | | public List<BAS_DEFECT_GRP> DefectGroups { get; set; } |
| | | public List<BAS_DEFECT> Defects => DefectGroups.SelectMany(q => q.Defects).ToList(); |
| | | /// <summary> |
| | | /// äºå¡é |
| | | /// </summary> |
| | | public object TransLock { get; } |
| | | #endregion |
| | | |
| | | #region Functions |
| | | /// <summary> |
| | | /// åå§åå·¥åèµæ |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public WorkBatch Init(string lineCode) |
| | | { |
| | | LineCode = lineCode; |
| | | GetBatchInfo(); |
| | | return this; |
| | | } |
| | | |
| | | public void Update() |
| | | { |
| | | if (!WoContext.WoBatchDic.ContainsKey(Batch.BATCH_NO)) |
| | | { |
| | | GetBatchInfo(); |
| | | WoContext.WoBatchDic.Add(Batch.BATCH_NO, this); |
| | | } |
| | | } |
| | | |
| | | private void GetBatchInfo() |
| | | { |
| | | WO = Biz.Db.Queryable<BIZ_MES_WO>().Where(q => q.ORDER_NO == OrderNo).IncludesAllFirstLayer().First(); |
| | | Product = Biz.Db.Queryable<BAS_ITEM>().Where(q => q.ITEM_CODE == WO.ITEM_CODE && q.AUTH_ORG == WO.AUTH_ORG).IncludesAllFirstLayer().First(); |
| | | Batch = Biz.Db.Queryable<BIZ_MES_WO_BATCH>().Where(q => q.ORDER_NO == OrderNo && q.ACT_LINE == LineCode && |
| | | (q.STATUS == BIZ_MES_WO_BATCH.STATUSs.Release.GetValue() || q.STATUS == BIZ_MES_WO_BATCH.STATUSs.Working.GetValue())).First(); |
| | | Customer = Biz.Db.Queryable<BAS_CUSTOMER>().Where(q => q.CUST_CODE == WO.CUST_CODE).First(); |
| | | WoSNs = Biz.Db.Queryable<BIZ_MES_WO_SN>().Where(q => q.WORK_ORDER == OrderNo).ToList(); |
| | | Edges = Biz.Db.Queryable<MES_WO_EDGE>().Where(q => q.WORK_ORDER == OrderNo).ToList(); |
| | | Nodes = Biz.Db.Queryable<MES_WO_NODE>().Where(q => q.WORK_ORDER == OrderNo).IncludesAllFirstLayer().ToList(); |
| | | NodeSets = Biz.Db.Queryable<MES_WO_OPER>().Where(q => q.WORK_ORDER == OrderNo).ToList(); |
| | | NodeActs = Biz.Db.Queryable<MES_WO_NODE_ACT>().Where(q => q.WORK_ORDER == OrderNo).IncludesAllFirstLayer().ToList(); |
| | | ActionSets = Biz.Db.Queryable<MES_WO_ACTION>().Where(q => q.WORK_ORDER == OrderNo).ToList(); |
| | | NodePosts = Biz.Db.Queryable<MES_WO_NODE_POST>().Where(q => q.WORK_ORDER == OrderNo).ToList(); |
| | | NodeDftgs = Biz.Db.Queryable<MES_WO_NODE_DFTG>().Where(q => q.WORK_ORDER == OrderNo).ToList(); |
| | | DefectGroups = Biz.Db.Queryable<BAS_DEFECT_GRP>().IncludesAllFirstLayer().ToList(); |
| | | |
| | | //å·¥åºèç¹æåº |
| | | var first = Nodes.First(q => q.IS_FIRST_NODE == "Y"); |
| | | first.Sequence = 1; |
| | | NodeSorting(first); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ·»å èç¹çä¸ä¸ä¸ªè¡ä¸ºå°å·¥æ¥å表 |
| | | /// </summary> |
| | | /// <param name="parent"></param> |
| | | private void NodeSorting(MES_WO_NODE parent) |
| | | { |
| | | var edges = Edges.Where(q => q.SRC_NODE == parent.ID && Nodes.Any(a => a.ID == q.TGT_NODE)).ToList(); |
| | | foreach (var edge in edges) |
| | | { |
| | | var next = Nodes.First(q => q.ID == edge.TGT_NODE); |
| | | //æé¤ç»´ä¿®å·¥åº |
| | | if (next.Operation.OPER_TYPE != MES_OPERATION.OPER_TYPEs.Repair.GetValue()) |
| | | { |
| | | next.Sequence = next.Sequence > parent.Sequence ? next.Sequence : (parent.Sequence + 1); |
| | | //妿ç¶èç¹å¯ç¨ä¸ä¸å¯è·³ç«ï¼åæ·»å 为ä¸ä¸ä¸ªå·¥åºçåç½®å·¥åº |
| | | var setting = NodeSets.FirstOrDefault(q => q.NODE_ID == parent.ID); |
| | | if (!setting.IsNullOrEmpty() && setting.IS_ACTIVE == "Y" && setting.CAN_SKIP != "Y") |
| | | { |
| | | next.PrepNodeIDs.Add(parent.ID); |
| | | } |
| | | //ç»§æ¿ç¶ç»ç¹çåç½®å·¥åº |
| | | next.PrepNodeIDs.AddRange(parent.PrepNodeIDs); |
| | | next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); |
| | | NodeSorting(next); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ£æ¥å·¥åå¨å½åå·¥åºèç¹æ¯å¦å¯ä»¥ç产 |
| | | /// </summary> |
| | | /// <param name="curNode"></param> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> CheckCanProduce(MES_WO_NODE curNode) |
| | | { |
| | | var action = new ApiAction<SubmitOutput>(new SubmitOutput(), true); |
| | | |
| | | WO = Biz.Db.Queryable<BIZ_MES_WO>().Where(q => q.ORDER_NO == OrderNo).IncludesAllFirstLayer().First(); |
| | | Batch = Biz.Db.Queryable<BIZ_MES_WO_BATCH>().Where(q => q.ORDER_NO == OrderNo && q.ACT_LINE == LineCode).First(); |
| | | //å·¥åæ¹æ¬¡ç¶æä¸æ¯å·²ä¸åæè
ç产ä¸ï¼åä¸å
许ç产 |
| | | if (Batch.STATUS != BIZ_MES_WO_BATCH.STATUSs.Release.GetValue() && Batch.STATUS != BIZ_MES_WO_BATCH.STATUSs.Working.GetValue()) |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | //action.LocaleMsg = new($"å·¥åæ¹æ¬¡[{Batch.BATCH_NO}]ç¶æ[{Batch.STATUS.GetEnum<BIZ_MES_WO_BATCH.STATUSs>().GetName()}]䏿¯å
许ç产çç¶æï¼è¯·æ«æå
许ç产çäº§åæ¡ç "); |
| | | action.LocaleMsg = new("MES.WorkBatch.WoBatchStatusCanNotWork", Batch.BATCH_NO, Batch.STATUS.GetEnum<BIZ_MES_WO_BATCH.STATUSs>().GetName()); |
| | | } |
| | | //å·¥åç¶æä¸æ¯å·²ä¸åæè
ç产ä¸ï¼åä¸å
许ç产 |
| | | if (WO.STATUS != BIZ_MES_WO.STATUSs.Release.GetValue() && WO.STATUS != BIZ_MES_WO.STATUSs.Working.GetValue()) |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | //action.LocaleMsg = new($"å·¥å[{WO.ORDER_NO}]ç¶æ[{Batch.STATUS.GetEnum<BIZ_MES_WO.STATUSs>().GetName()}]䏿¯å
许ç产çç¶æï¼è¯·æ«æå
许ç产çäº§åæ¡ç "); |
| | | action.LocaleMsg = new("MES.WorkBatch.WoStatusCanNotWork", WO.ORDER_NO, Batch.STATUS.GetEnum<BIZ_MES_WO.STATUSs>().GetName()); |
| | | } |
| | | //å·¥åæ¹æ¬¡æå
¥æ°éå廿¥åºæ°é妿大äºçäºè®¡åæ°éï¼åä¸å
许ç产 |
| | | //if (curNode.IS_INPUT == "Y" && Batch.INPUT_QTY - Batch.SCRAP_QTY >= Batch.PLAN_QTY) |
| | | if (curNode.IS_INPUT == "Y" && WoSNs.Count(q => q.BATCH_NO == Batch.BATCH_NO) - Batch.SCRAP_QTY >= Batch.PLAN_QTY) |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | //action.LocaleMsg = new($"å·¥åæ¹æ¬¡[{0}]å·²æå
¥ {1}ï¼å
¶ä¸æ¥åº {2}ï¼ä»¥æ»¡è¶³è®¡åæ°é[{3}]ï¼æ éç»§ç»æå
¥"); |
| | | action.LocaleMsg = new("MES.WorkBatch.BatchInputEnough", Batch.BATCH_NO, WoSNs.Count(q => q.BATCH_NO == Batch.BATCH_NO), Batch.SCRAP_QTY, Batch.PLAN_QTY); |
| | | } |
| | | //å·¥åæå
¥æ°éå廿¥åºæ°é妿大äºçäºè®¡åæ°éï¼åä¸å
许ç产 |
| | | if (curNode.IS_INPUT == "Y" && WoSNs.Count(q => q.WORK_ORDER == WO.ORDER_NO) - WO.SCRAP_QTY >= WO.PLAN_QTY) |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | //action.LocaleMsg = new($"å·¥å[{0}]å·²æå
¥ {1}ï¼å
¶ä¸æ¥åº {2}ï¼ä»¥æ»¡è¶³è®¡åæ°é[{3}]ï¼æ éç»§ç»æå
¥"); |
| | | action.LocaleMsg = new("MES.WorkBatch.WoInputEnough", WO.ORDER_NO, WoSNs.Count(q => q.WORK_ORDER == WO.ORDER_NO), WO.SCRAP_QTY, WO.PLAN_QTY); |
| | | } |
| | | |
| | | return action; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å·¥åå¼å·¥ |
| | | /// </summary> |
| | | /// <param name="user"></param> |
| | | /// <returns></returns> |
| | | public bool StartWorking(string user) |
| | | { |
| | | if (Batch.STATUS == BIZ_MES_WO_BATCH.STATUSs.Release.GetValue() || Batch.STATUS == BIZ_MES_WO_BATCH.STATUSs.Paused.GetValue()) |
| | | { |
| | | WO.STATUS = BIZ_MES_WO.STATUSs.Working.GetValue(); |
| | | WO.ACT_START_TIME = WO.ACT_START_TIME < new DateTime(2000, 1, 1) ? DateTime.Now : WO.ACT_START_TIME; |
| | | Batch.STATUS = BIZ_MES_WO_BATCH.STATUSs.Working.GetValue(); |
| | | Batch.ACT_START_TIME = WO.ACT_START_TIME < new DateTime(2000, 1, 1) ? DateTime.Now : WO.ACT_START_TIME; |
| | | //ä¿åæ°æ®åº |
| | | var db = Biz.Db; |
| | | var dbTran = db.UseTran(() => |
| | | { |
| | | db.Updateable(WO, user).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS, q.ACT_START_TIME }).ExecuteCommand(); |
| | | db.Updateable(Batch, user).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS, q.ACT_START_TIME }).ExecuteCommand(); |
| | | }); |
| | | if (!dbTran.IsSuccess) |
| | | { |
| | | //throw dbTran.ErrorException; |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å·¥åæå |
| | | /// </summary> |
| | | /// <param name="user"></param> |
| | | /// <returns></returns> |
| | | public bool PausedWorking(string user) |
| | | { |
| | | if (Batch.STATUS == BIZ_MES_WO_BATCH.STATUSs.Working.GetValue()) |
| | | { |
| | | WO.STATUS = BIZ_MES_WO.STATUSs.Paused.GetValue(); |
| | | Batch.STATUS = BIZ_MES_WO_BATCH.STATUSs.Paused.GetValue(); |
| | | //ä¿åæ°æ®åº |
| | | var db = Biz.Db; |
| | | var dbTran = db.UseTran(() => |
| | | { |
| | | db.Updateable(WO, user).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS }).ExecuteCommand(); |
| | | db.Updateable(Batch, user).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS }).ExecuteCommand(); |
| | | }); |
| | | if (!dbTran.IsSuccess) |
| | | { |
| | | //throw dbTran.ErrorException; |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®å²ä½ç¼ç 夿æ¯ä¸æ¯é¦ç« |
| | | /// </summary> |
| | | /// <param name="postCode"></param> |
| | | /// <returns></returns> |
| | | public bool IsFirstNode(string postCode) |
| | | { |
| | | return Nodes.Any(q => q.IS_FIRST_NODE == "Y" && NodePosts.Any(p => p.NODE_ID == q.ID && p.POST_CODE == postCode)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®å²ä½ç¼ç è¿åå·¥åºèç¹ |
| | | /// </summary> |
| | | /// <param name="postCode"></param> |
| | | /// <returns></returns> |
| | | public MES_WO_NODE GetNode(string postCode) |
| | | { |
| | | return Nodes.FirstOrDefault(q => NodePosts.Any(p => p.NODE_ID == q.ID && p.POST_CODE == postCode)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®ä¼ å
¥çæ¡ç è¿ç«ä¿¡æ¯åä¸ä¸ç«çç®æ å·¥åºï¼å¤ææ¡ç æ¯å¦è½è¿å
¥ä¸ä¸ç« |
| | | /// </summary> |
| | | /// <param name="input">æ¬æ¬¡æäº¤çæ°æ®</param> |
| | | /// <param name="wipSN">å½åçæ¡ç è¿ç«è®°å½ï¼éè¦å¯¼èªæ¥è¯¢ç产è¿ç¨è®°å½ä¿¡æ¯</param> |
| | | /// <param name="nextNode">è¦è¿å
¥çç®æ å·¥åº</param> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> CanGotoNext(SubmitInput input, MES_WIP_DATA wipSN, MES_WO_NODE nextNode) |
| | | { |
| | | var action = new ApiAction<SubmitOutput>(new SubmitOutput()); |
| | | |
| | | //æ¡ç 卿¬å·¥åç¬¬ä¸æ¬¡è¿ç« |
| | | if (wipSN.NODE_ID.IsNullOrEmpty()) |
| | | { |
| | | if (nextNode.IS_FIRST_NODE == "Y") |
| | | { |
| | | action.IsSuccessed = true; |
| | | return action; |
| | | } |
| | | else |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | var nextList = Nodes.Where(q => q.IS_FIRST_NODE == "Y"); |
| | | action.LocaleMsg = new("MES.WorkBatch.GotoNextNodeException", input.SN, nextNode.NODE_NAME, string.Join(", ", nextList.Select(q => q.NODE_NAME + (q.CAN_SKIP == "Y" ? $"({Biz.T(Biz.L("MES.WorkBatch.Optional"), input.Locale)})" : "")))); |
| | | return action; |
| | | } |
| | | } |
| | | //æ¡ç å·²æè¿ç«è®°å½ |
| | | else |
| | | { |
| | | var curNode = Nodes.First(q => q.ID == wipSN.NODE_ID); |
| | | var curSetting = NodeSets.FirstOrDefault(q => q.NODE_ID == curNode.ID); |
| | | var nextSetting = NodeSets.FirstOrDefault(q => q.NODE_ID == nextNode.ID); |
| | | //è¿å
¥ç»´ä¿®ï¼å¦æç®æ å·¥åºæ¯ç»´ä¿®å·¥åºå夿å½åæ¡ç 卿¬å·¥åææªç»´ä¿®çä¸è¯è®°å½ä¸å½åå·¥åºèç¹æè¿çº¿å°ç»´ä¿®å·¥åºï¼åå
许è¿å
¥ç»´ä¿®å·¥åº |
| | | if (nextNode.Operation.OPER_TYPE == MES_OPERATION.OPER_TYPEs.Repair.GetValue() |
| | | && wipSN.Defects.Any(q => q.WORK_ORDER == WO.ORDER_NO && q.STATUS < MES_WIP_DFT.STATUSs.Resolved.GetValue()) |
| | | && Edges.Any(q => q.SRC_NODE == curNode.ID && q.TGT_NODE == nextNode.ID)) |
| | | { |
| | | action.IsSuccessed = true; |
| | | return action; |
| | | } |
| | | //ç»´ä¿®åæµï¼å¦ææ¡ç çå½åå·¥åºæ¯ç»´ä¿®å·¥åºï¼å认为æ¯ç»´ä¿®åæµ |
| | | else if (curNode.Operation.OPER_TYPE == MES_OPERATION.OPER_TYPEs.Repair.GetValue()) |
| | | { |
| | | //æ¥æ¾ææå¯ä»¥åæµçå·¥åº |
| | | var reflowNodes = Nodes.Where(q => Edges.Any(e => e.SRC_NODE == curNode.ID && e.TGT_NODE == q.ID) |
| | | && NodeSets.Any(s => s.NODE_ID == q.ID && s.IS_ACTIVE == "Y")).ToList(); |
| | | |
| | | //å¯åæµçå·¥åºå
å«ç®æ å·¥åºä¸æ¡ç å¨ç»´ä¿®ç«éæ©ç念工åºä¸ºç©ºæè
çäºç®æ å·¥åºï¼åå
许è¿ç« |
| | | if (reflowNodes.Any(q => q.ID == nextNode.ID) && (wipSN.REFLOW_NODE.IsNullOrEmpty() || wipSN.REFLOW_NODE == nextNode.NODE_NAME)) |
| | | { |
| | | action.IsSuccessed = true; |
| | | return action; |
| | | } |
| | | else |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | var nextList = reflowNodes.Where(q => wipSN.REFLOW_NODE.IsNullOrEmpty() || wipSN.REFLOW_NODE == q.NODE_NAME); |
| | | action.LocaleMsg = new("MES.WorkBatch.ReflowToNodeException", nextNode.NODE_NAME, input.SN, curNode.NODE_NAME, string.Join(", ", nextList.Select(q => q.NODE_NAME + (q.CAN_SKIP == "Y" ? $"({Biz.T(Biz.L("MES.WorkBatch.Optional"), input.Locale)})" : "")))); |
| | | return action; |
| | | } |
| | | } |
| | | //ä¸è¯åå
¥ç«ï¼å¦æäº§åæä¸è¯è®°å½ä¸ç®æ å·¥åºä¸æ¯ç»´ä¿®å·¥åºä¸ä¸å
许ä¸è¯åå
¥ç«ï¼åæ¥é |
| | | else if (wipSN.Defects.Any(q => q.WORK_ORDER == WO.ORDER_NO && q.STATUS < MES_WIP_DFT.STATUSs.Resolved.GetValue()) |
| | | && nextSetting.ALLOW_DFT_IN != "Y" && nextNode.Operation.OPER_TYPE != MES_OPERATION.OPER_TYPEs.Repair.GetValue()) |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | action.LocaleMsg = new("MES.WorkBatch.PleaseGotoRepair", curNode.NODE_NAME, input.SN); |
| | | return action; |
| | | } |
| | | //æ£å¸¸å·¥åºè¿ç« |
| | | else |
| | | { |
| | | //æ·»å æ¡ç å½åå·¥åºçä¸ä¸ä¸ªå¯æ§è¡å·¥åº |
| | | var nextNodes = GetNextNodes(curNode, wipSN); |
| | | //妿ä¸ä¸ä¸ªå¯æ§è¡å·¥åºå
å«ç®æ å·¥åºåå
许è¿ç« |
| | | if (nextNodes.Any(q => q.ID == nextNode.ID)) |
| | | { |
| | | action.IsSuccessed = true; |
| | | return action; |
| | | } |
| | | |
| | | //妿å½åå·¥åºæå¿
é¡»æ§è¡çåç»å·¥åºï¼åæ¥é |
| | | if (nextNodes.Any(q => NodeSets.Any(s => s.NODE_ID == q.ID && s.IS_ACTIVE == "Y" && s.CAN_SKIP != "Y"))) |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | var nextList = nextNodes.Where(q => NodeSets.Any(s => s.NODE_ID == q.ID && s.IS_ACTIVE == "Y" && s.CAN_SKIP != "Y")); |
| | | action.LocaleMsg = new("MES.WorkBatch.GotoNextNodeException", input.SN, nextNode.NODE_NAME, string.Join(", ", nextList.Select(q => q.NODE_NAME + (q.CAN_SKIP == "Y" ? $"({Biz.T(Biz.L("MES.WorkBatch.Optional"), input.Locale)})" : "")))); |
| | | return action; |
| | | } |
| | | //妿å½åå·¥åºæ²¡æå¿
é¡»æ§è¡çåç»å·¥åºï¼åå¨åç½®å·¥åºæ¥æ¾è¿ææ²¡æåç»å·¥åºæ²¡å®æçå·¥åºï¼æåå°è¯æ§è¡ |
| | | else |
| | | { |
| | | //å¨åç½®å·¥åºæ¥æ¾è¿ææ²¡æåç»å·¥åºæ²¡å®æçåç½®å·¥åº |
| | | var prepIDs = curNode.PrepNodeIDs.Where(id => |
| | | Edges.Any(e => e.SRC_NODE == id && !wipSN.History.Any(h => h.WORK_ORDER == WO.ORDER_NO && h.NODE_ID == e.TGT_NODE && h.IsFinished)) |
| | | ).ToList(); |
| | | foreach (var prepID in prepIDs) |
| | | { |
| | | //妿è¿çº¿çç®æ å·¥åºçå置工åºé½å·²å®æï¼åæè¿çº¿çç®æ å·¥åºæ·»å å°å¯æ§è¡å·¥åºå表 |
| | | var prep = Nodes.First(q => q.ID == prepID); |
| | | var next = GetNextNodes(prep, wipSN); |
| | | nextNodes.AddRange(next); |
| | | } |
| | | |
| | | //妿ä¸ä¸ä¸ªå¯æ§è¡å·¥åºå
å«ç®æ å·¥åºåå
许è¿ç« |
| | | if (nextNodes.Any(q => q.ID == nextNode.ID)) |
| | | { |
| | | action.IsSuccessed = true; |
| | | return action; |
| | | } |
| | | else |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | | var nextList = nextNodes.Where(q => NodeSets.Any(s => s.NODE_ID == q.ID && s.IS_ACTIVE == "Y")); |
| | | action.LocaleMsg = new("MES.WorkBatch.GotoNextNodeException", input.SN, nextNode.NODE_NAME, string.Join(", ", nextList.Select(q => q.NODE_NAME + (q.CAN_SKIP == "Y" ? $"({Biz.T(Biz.L("MES.WorkBatch.Optional"), input.Locale)})" : "")))); |
| | | return action; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return action; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ·»å èç¹çä¸ä¸ä¸ªå¯æ§è¡èç¹ |
| | | /// </summary> |
| | | /// <param name="parent"></param> |
| | | /// <param name="wipSN">å½åçæ¡ç è¿ç«è®°å½ï¼éè¦å¯¼èªæ¥è¯¢ç产è¿ç¨è®°å½ä¿¡æ¯</param> |
| | | private List<MES_WO_NODE> GetNextNodes(MES_WO_NODE parent, MES_WIP_DATA wipSN) |
| | | { |
| | | var result = new List<MES_WO_NODE>(); |
| | | var nextNodes = Nodes.Where(q => q.Operation.OPER_TYPE != MES_OPERATION.OPER_TYPEs.Repair.GetValue() |
| | | && Edges.Any(e => e.SRC_NODE == parent.ID && e.TGT_NODE == q.ID) |
| | | && !wipSN.History.Any(h => h.WORK_ORDER == WO.ORDER_NO && h.NODE_ID == q.ID && h.IsFinished) |
| | | ).ToList(); |
| | | //å°è¯å°å½åå·¥åºçåç»å·¥åºæ·»å å°å¯ä»¥æ§è¡çå·¥åºå表 |
| | | foreach (var next in nextNodes) |
| | | { |
| | | //æ¥æ¾ææ²¡æåç½®å·¥åºæ¾ä¸å°å·²è¯åè¿ç«çåå²è®°å½ï¼è¥æåä¸å
è®¸ç»§ç»æ§è¡ |
| | | if (!next.PrepNodeIDs.Any(id => !wipSN.History.Any(h => h.WORK_ORDER == WO.ORDER_NO && h.NODE_ID == id && h.IsFinished)) || parent.IS_FIRST_NODE == "Y") |
| | | { |
| | | var setting = NodeSets.FirstOrDefault(q => q.NODE_ID == next.ID); |
| | | //åç»å·¥åºæ¯å¯ç¨çï¼åæ·»å |
| | | if (!result.Any(q => q.ID == next.ID) && setting.IS_ACTIVE == "Y") |
| | | { |
| | | result.Add(next); |
| | | } |
| | | //åç»å·¥åºæ¯ä¸å¯ç¨æè
å¯è·³ç«ï¼åç»§ç»æ·»å å
¶åç»å·¥åº |
| | | if (!setting.IsNullOrEmpty() && (setting.IS_ACTIVE != "Y" || setting.CAN_SKIP == "Y")) |
| | | { |
| | | result.AddRange(GetNextNodes(next, wipSN)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®ä¼ å
¥çæ¡ç è¿åä¸ä¸ç«å¯è¿å
¥è¿å
¥çç®æ å·¥åº |
| | | /// </summary> |
| | | /// <param name="wipSN">å½åçæ¡ç è¿ç«è®°å½ï¼éè¦å¯¼èªæ¥è¯¢ç产è¿ç¨è®°å½åç产ä¸è¯è®°å½ä¿¡æ¯</param> |
| | | /// <returns></returns> |
| | | public List<MES_WO_NODE> GetNextNodes(MES_WIP_DATA wipSN) |
| | | { |
| | | var result = new List<MES_WO_NODE>(); |
| | | |
| | | //æ¡ç 卿¬å·¥åç¬¬ä¸æ¬¡è¿ç« |
| | | if (wipSN.NODE_ID.IsNullOrEmpty()) |
| | | { |
| | | result.AddRange(Nodes.Where(q => q.IS_FIRST_NODE == "Y")); |
| | | } |
| | | //æ¡ç å·²æè¿ç«è®°å½ |
| | | else |
| | | { |
| | | var curNode = Nodes.First(q => q.ID == wipSN.NODE_ID); |
| | | //æ¡ç å¨ç»´ä¿®å·¥åºï¼è¿åå¯åæµå·¥åº |
| | | if (curNode.Operation.OPER_TYPE == MES_OPERATION.OPER_TYPEs.Repair.GetValue()) |
| | | { |
| | | //æ¥æ¾ææå¯ä»¥åæµçå·¥åº |
| | | var reflowNodes = Nodes.Where(q => Edges.Any(e => e.SRC_NODE == curNode.ID && e.TGT_NODE == q.ID) |
| | | && NodeSets.Any(s => s.NODE_ID == q.ID && s.IS_ACTIVE == "Y")).ToList(); |
| | | result.AddRange(reflowNodes.Where(q => wipSN.REFLOW_NODE.IsNullOrEmpty() || wipSN.REFLOW_NODE == q.NODE_NAME)); |
| | | } |
| | | else |
| | | { |
| | | //å¾ä¸æ¥æ¾æ¡ç å½åå·¥åºçä¸ä¸ä¸ªå¯æ§è¡å·¥åº |
| | | var nextNodes = GetNextNodes(curNode, wipSN); |
| | | //妿å½åå·¥åºæ²¡æå¿
é¡»æ§è¡çåç»å·¥åºï¼åå°è¯å¨åç½®å·¥åºæ¥æ¾è¿ææ²¡æåç»å·¥åºæ²¡å®æçå·¥åºï¼æåå å
¥ |
| | | if (!nextNodes.Any(q => NodeSets.Any(s => s.NODE_ID == q.ID && s.IS_ACTIVE == "Y" && s.CAN_SKIP != "Y"))) |
| | | { |
| | | //å¨åç½®å·¥åºæ¥æ¾è¿ææ²¡æåç»å·¥åºæ²¡å®æçåç½®å·¥åº |
| | | var prepIDs = curNode.PrepNodeIDs.Where(id => |
| | | Edges.Any(e => e.SRC_NODE == id && !wipSN.History.Any(h => h.WORK_ORDER == WO.ORDER_NO && h.NODE_ID == e.TGT_NODE && h.IsFinished)) |
| | | ).ToList(); |
| | | foreach (var prepID in prepIDs) |
| | | { |
| | | //妿è¿çº¿çç®æ å·¥åºçå置工åºé½å·²å®æï¼åæè¿çº¿çç®æ å·¥åºæ·»å å°å¯æ§è¡å·¥åºå表 |
| | | var prep = Nodes.First(q => q.ID == prepID); |
| | | var next = GetNextNodes(prep, wipSN); |
| | | nextNodes.AddRange(next); |
| | | } |
| | | } |
| | | result.AddRange(nextNodes); |
| | | //妿å½åæ¡ç æ¯ä¸è¯ååªè¿åå
许ä¸è¯è¿ç«çå·¥åºåå·¥åºè¿æ¥çç»´ä¿®å·¥åº |
| | | if (wipSN.Defects.Any(q => q.WORK_ORDER == WO.ORDER_NO && q.STATUS < MES_WIP_DFT.STATUSs.Resolved.GetValue())) |
| | | { |
| | | result.RemoveAll(q => NodeSets.Any(s => s.NODE_ID == q.ID && s.ALLOW_DFT_IN != "Y")); |
| | | //å å
¥å·¥åºè¿æ¥çç»´ä¿®å·¥åº |
| | | var repairNodes = Nodes.Where(q => Edges.Any(e => e.SRC_NODE == curNode.ID && e.TGT_NODE == q.ID) && q.Operation.OPER_TYPE == MES_OPERATION.OPER_TYPEs.Repair.GetValue()); |
| | | result.AddRange(repairNodes); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®å²ä½ç¼ç è¿åå·¥åºä¸è¯ä»£ç |
| | | /// </summary> |
| | | /// <param name="postCode"></param> |
| | | /// <returns></returns> |
| | | public List<DefectOutput> GetNodeDefects(string postCode) |
| | | { |
| | | var result = new List<DefectOutput>(); |
| | | var groups = DefectGroups.Where((b, s) => NodeDftgs.Any(d => d.NODE_ID == GetNode(postCode).ID && d.DFTG_CODE == b.DFTG_CODE)).ToList(); |
| | | foreach (var group in groups) |
| | | { |
| | | result.AddRange(group.Defects.Select(q => new DefectOutput |
| | | { |
| | | DFTG_CODE = q.DFTG_CODE, |
| | | DFTG_NAME = group.DFTG_NAME, |
| | | DFT_CODE = q.DFT_CODE, |
| | | DFT_NAME = q.DFT_NAME, |
| | | DFT_LEVEL = q.DFT_LEVEL, |
| | | })); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | /// <summary> |
| | | /// å
³éå·¥å |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public bool Close() |
| | | { |
| | | Dispose(); |
| | | return true; |
| | | } |
| | | public virtual void Dispose() |
| | | { |
| | | WoContext.WoBatchDic.Remove(OrderNo); |
| | | } |
| | | } |
| | | } |