From c598e4bf57de2b4703d6c0e4d0905c9159273d26 Mon Sep 17 00:00:00 2001 From: Rodney Chen <rodney.chen@hotmail.com> Date: 星期二, 06 八月 2024 10:16:18 +0800 Subject: [PATCH] 条码增加托盘批量过站逻辑和包装外箱过站逻辑 --- Tiger.Business.MES/Transaction/Position.cs | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 336 insertions(+), 9 deletions(-) diff --git a/Tiger.Business.MES/Transaction/Position.cs b/Tiger.Business.MES/Transaction/Position.cs index 4d046eb..4e11575 100644 --- a/Tiger.Business.MES/Transaction/Position.cs +++ b/Tiger.Business.MES/Transaction/Position.cs @@ -10,9 +10,7 @@ using System.Threading.Tasks; using Tiger.Model; using static Tiger.Business.Biz; -using Org.BouncyCastle.Ocsp; using Tiger.Model.Entitys.MES.Position; -using MailKit.Search; namespace Tiger.Business.MES.Transaction { @@ -41,6 +39,9 @@ //if (CurFactory.IsNullOrEmpty()) throw new InvalidDataException($"MES.Transaction.Position.FactoryNotExistsException", new Exception($"{postCode}|{CurWorkshop.FTY_CODE}")); if (CurFactory.IsNullOrEmpty()) throw new InvalidDataException($"宀椾綅[{postCode}]鎵�灞炵殑宸ュ巶[{CurWorkshop.FTY_CODE}]涓嶅瓨鍦紝璇峰厛璁剧疆鎵�灞炲伐鍘�", new Exception($"{postCode}|{CurWorkshop.FTY_CODE}")); + //鍔犺浇褰撳墠浜х嚎鐨勭彮鍒� + CurShiftSys = Biz.Db.Queryable<MES_SHIFT_SYS>().Where(q => q.SFTS_CODE == CurLine.SFTS_CODE).IncludesAllFirstLayer().IncludesAllSecondLayer(q => q.Shifts).First(); + return this; } @@ -51,14 +52,26 @@ public MES_WORKSHOP CurWorkshop { get; set; } public MES_LINE CurLine { get; set; } public MES_POSITION CurPosition { get; set; } + public MES_SHIFT_SYS CurShiftSys { get; set; } public WorkBatch CurBatch { get; set; } public IWorkBatch WorkBatch => CurBatch; - public MES_WIP_DATA CurWipSN { get; set; } - public MES_WIP_HIS CurWipSNHis { get; set; } + public List<MES_WIP_DATA> CurWipSNs { get; set; } + public string CurSN => CurWipSNs.First().TRAY_SN.IsNullOrEmpty() ? CurWipSNs.First().SN : CurWipSNs.First().TRAY_SN; + public List<MES_WIP_HIS> CurWipSNHiss { get; set; } + public Dictionary<string, object> Context { get; set; } = new(); public List<WorkStep> Steps { get; set; } = new(); - public bool IsFinishAllSteps => Steps.Any() && !Steps.Any(q => !q.IsFinished); - public int CurStep => Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).FirstOrDefault()?.Sequence ?? 0; + public WorkStep CurStep { get; set; } + public List<WorkStep> NextSteps { get; set; } = new(); + public bool IsFinishNodeSteps => !Steps.Any(q => q.Type == IWorkStep.Types.Node && !q.IsFinished); + public bool IsFinishAllSteps => !Steps.Any() || !Steps.Any(q => !q.IsFinished); + //public int CurStep => Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).FirstOrDefault()?.Sequence ?? 0; private DbClient CommitDB; + /// <summary> + /// 鏄惁闇�瑕佷复鏃跺瓨鍌ㄦ暟鎹簱鎻愪氦鎿嶄綔锛屽緟闇�瑕佺殑鏃跺�欏啀鎻愪氦 + /// </summary> + public bool NeedTemporaryStoreDBCommitAction { get; set; } = false; + protected List<Action> DBCommitList { get; set; } = new(); + #endregion Propertys & Variables #region Functions @@ -120,12 +133,326 @@ } /// <summary> - /// 閲嶇疆褰撳墠宸ユ + /// 鑾峰彇褰撳墠鏃堕棿鎵�灞炵殑鐝埗鐝鏃舵 /// </summary> - public void ResetSteps() + public ShiftPeriod GetShiftPeriodForNow() + { + var time = DateTime.Now.ToString("HHmm").ToInt32(); + foreach (var shift in CurShiftSys.Shifts) + { + var period = shift.Periods.Where(q => q.PRD_BEGIN <= time && time <= q.PRD_END).FirstOrDefault(); + if (!period.IsNullOrEmpty()) + { + var result = new ShiftPeriod(); + result.ShiftSys = CurShiftSys; + result.Shift = shift; + result.Period = period; + return result; + } + } + return null; + } + + /// <summary> + /// 閲嶇疆宸ュ簭鎿嶄綔 + /// </summary> + /// <returns></returns> + public ApiAction Reset() + { + var action = new ApiAction(); + + ResetNode(); + action.IsSuccessed = true; + action.LocaleMsg = new($"宸ュ簭鎿嶄綔宸查噸缃紝璇烽噸鏂版壂鎻忚繘绔欎骇鍝佹潯鐮�"); + action.LocaleMsg = new("MES.Transaction.Position.ResetNode"); + + return action; + } + + /// <summary> + /// 閲嶇疆褰撳墠宸ュ簭锛屾湁闇�瑕佸垯閲嶅啓姝ゆ柟娉� + /// </summary> + public virtual void ResetNode() { Steps.Clear(); - CurWipSN = null; + CurWipSNs = null; + CurWipSNHiss = null; + CurStep = null; + } + + /// <summary> + /// 鐢熸垚浼犲叆宸ユ鍚庣画鐨勮涓哄埌宸ユ鍒楄〃 + /// </summary> + /// <param name="parent"></param> + public void GenerateSteps(WorkStep parent) + { + //閫掑綊娣诲姞鎵�鏈夊伐姝� + AddNextActToSteps(parent); + //璋冩暣宸ユ鐨勫簭鍙� + //while (CurBatch.Edges.Any(q => Steps.First(s => s.NodeID == q.SRC_NODE).Sequence <= Steps.First(s => s.NodeID == q.TGT_NODE).Sequence)) + //{ + // var edges = CurBatch.Edges.Where(q => Steps.First(s => s.NodeID == q.SRC_NODE).Sequence >= Steps.First(s => s.NodeID == q.TGT_NODE).Sequence).ToList(); + // foreach (var edge in edges) + // { + // var source = Steps.First(s => s.NodeID == edge.SRC_NODE); + // var target = Steps.First(s => s.NodeID == edge.TGT_NODE); + // target.Sequence = source.Sequence + 1; + // } + //} + } + + /// <summary> + /// 娣诲姞鑺傜偣鐨勪笅涓�涓涓哄埌宸ユ鍒楄〃 + /// </summary> + /// <param name="parent"></param> + private void AddNextActToSteps(WorkStep parent) + { + var edges = CurBatch.Edges.Where(q => q.SRC_NODE == parent.NodeID && CurBatch.NodeActs.Any(a => a.NODE_ID == parent.Node.ID && a.ID == q.TGT_NODE)).ToList(); + foreach (var edge in edges) + { + var act = CurBatch.NodeActs.First(q => q.ID == edge.TGT_NODE); + if (Steps.Any(q => q.NodeID == act.ID)) + { + var next = Steps.First(q => q.NodeID == act.ID); + next.Sequence = next.Sequence > parent.Sequence ? next.Sequence : (parent.Sequence + 1); + next.PrepNodeIDs.Add(parent.NodeID); + next.PrepNodeIDs.AddRange(parent.PrepNodeIDs); + next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); + AddNextActToSteps(next); + } + else + { + var next = new WorkStep(IWorkStep.Types.Action, this) + { + Sequence = parent.Sequence + 1, + Node = parent.Node, + NodeAct = act, + Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID), + }; + next.Init(); + next.PrepNodeIDs.Add(parent.NodeID); + next.PrepNodeIDs.AddRange(parent.PrepNodeIDs); + next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); + Steps.Add(next); + AddNextActToSteps(next); + } + } + } + + /// <summary> + /// 鏍规嵁浼犲叆鐨勫伐姝ワ紝杩斿洖涓嬩竴姝ュ彲鎵ц鐨勫伐姝ュ垪琛� + /// </summary> + /// <param name="curStep"></param> + public List<WorkStep> GetNextSteps(WorkStep curStep) + { + var result = new List<WorkStep>(); + var nextSteps = Steps.Where(q => !q.IsFinished + && CurBatch.Edges.Any(e => e.SRC_NODE == curStep.NodeID && e.TGT_NODE == q.NodeID) + ).ToList(); + //灏濊瘯灏嗗綋鍓嶅伐姝ョ殑鍚庣画宸ユ娣诲姞鍒板彲浠ユ墽琛岀殑宸ユ鍒楄〃 + foreach (var step in nextSteps) + { + //鏌ユ壘鏈夋病鏈夊墠缃伐姝ユ湭瀹屾垚锛岃嫢鏈夊垯涓嶅厑璁哥户缁墽琛� + if (!Steps.Any(q => step.PrepNodeIDs.Any(id => id == q.NodeID && !q.IsFinished))) + { + result.Add(step); + } + } + //濡傛灉褰撳墠宸ユ娌℃湁鍙墽琛岀殑鍚庣画宸ユ锛屽垯鍦ㄥ墠缃伐姝ユ煡鎵捐繕鏈夋病鏈夊悗缁伐姝ユ病瀹屾垚鐨勫伐姝ワ紝鏈夊垯鎵ц + if (!result.Any() && Steps.Any()) + { + //鏌ユ壘鏈夋病鏈夊墠缃伐姝ユ湭瀹屾垚锛岃嫢鏈夊垯鍏堝畬鎴愭湭瀹屾垚鐨勫墠缃伐姝� + var prepIDs = curStep.PrepNodeIDs.Where(id => CurBatch.Edges.Any(e => e.SRC_NODE == id && Steps.Any(q => !q.IsFinished && e.TGT_NODE == q.NodeID))).ToList(); + var prepSteps = Steps.Where(q => prepIDs.Contains(q.NodeID)).OrderByDescending(q => q.Sequence).ToList(); + while (prepSteps.Any() && !result.Any()) + { + var prep = prepSteps.First(); + var prepNext = GetNextSteps(prep); + if (prepNext.Any()) + { + result = prepNext; + } + else + { + prepSteps.Remove(prep); + } + } + + } + return result.OrderBy(q => q.NodeAct.ACT_NAME).ToList(); + } + + /// <summary> + /// 寮�濮嬫墽琛屼笅涓�琛屼负宸ユ + /// </summary> + /// <param name="input"></param> + public ApiAction<SubmitOutput> BeginNextActionStep(SubmitInput input) + { + var result = new ApiAction<SubmitOutput>(new SubmitOutput()); + //璁剧疆鍚庣画鍙墽琛岀殑宸ユ鍒楄〃 + NextSteps = GetNextSteps(CurStep); + //灏濊瘯鏈夋病鏈夊彲浠ョ洿鎺ュ紑濮嬬殑鍚庣画宸ユ + foreach (var step in NextSteps) + { + //灏濊瘯鎵ц鍚庣画宸ユ + var canBegin = step.TryBegin(input); + //濡傛灉鍚庣画宸ユ鍙互鐩存帴寮�濮嬪垯鐩存帴鎵ц + if (canBegin.IsSuccessed) + { + //鏇存柊褰撳墠鎵ц宸ユ涓哄凡寮�濮嬪伐姝� + CurStep = step; + //鏇存柊鍚庣画鍙墽琛岀殑宸ユ鍒楄〃 + NextSteps = GetNextSteps(CurStep); + //杩斿洖缁撴灉鍒板鎴风 + result = canBegin; + result.Data.SetValue(CurBatch, CurStep, CurStep?.ID, IsFinishAllSteps); + + return result; + } + } + + //娌℃湁鍙互鐩存帴寮�濮嬬殑鍚庣画宸ユ锛屾牴鎹悗缁伐姝ヨ繑鍥濧piAction + result.Data.SetValue(CurBatch, CurStep, "", IsFinishAllSteps); + + //娌℃湁鍙互鐩存帴寮�濮嬬殑鍚庣画宸ユ锛屾牴鎹悗缁彲鎵ц宸ユ鍒楄〃杩斿洖鐩稿簲鐨勬搷浣滄彁绀� + if (NextSteps.Count == 1) + { + result.LocaleMsg = NextSteps.First().GetBeginMsg(); + } + else + { + result.LocaleMsg = new(T(L("MES.Transaction.Position.PleaseSelectNextStep"), input.Locale) + "\r\n" + + string.Join("\r\n", NextSteps.Select(q => " >> " + T(q.GetBeginMsg(), input.Locale)))); + } + return result; + } + + /// <summary> + /// 淇濆瓨宸ユ鐨勬暟鎹簱鎻愪氦鎿嶄綔鍒版暟鎹簱 + /// </summary> + protected void SaveStepsCommitActionToDB() + { + //淇濆瓨宸ユ鐨勬暟鎹簱鎻愪氦鎿嶄綔鍒版彁浜ゆ搷浣滃垪琛� + foreach (var step in Steps.OrderBy(q => q.Sequence)) + { + DBCommitList.Add(step.DBSubmitAction); + } + //濡傛灉涓嶉渶瑕佷复鏃跺瓨鍌ㄦ暟鎹簱鎻愪氦鎿嶄綔锛屽垯鎶婃彁浜ゆ搷浣滃垪琛ㄦ彁浜ゅ埌鏁版嵁搴� + if (!NeedTemporaryStoreDBCommitAction) + { + //鎭㈠涓存椂瀛樺偍鏍囪涓篺alse + NeedTemporaryStoreDBCommitAction = false; + + var dbTran = GetCommitDB().UseTran(() => + { + //鍦ㄥ悓涓�涓簨鍔′腑淇濆瓨鎵�鏈夊伐姝ョ殑鏁版嵁 + foreach (var action in DBCommitList) + { + action.Invoke(); + } + }); + if (dbTran.IsSuccess) + { + //淇濆瓨鎴愬姛鍒欐竻绌烘彁浜ゆ搷浣滃垪琛� + DBCommitList.Clear(); + } + else + { + //鎶涘嚭寮傚父 + throw dbTran.ErrorException; + } + } + } + + /// <summary> + /// 鑾峰彇鎵撳嵃鏍囩妯℃澘杩囩▼鍙橀噺鍊� + /// </summary> + /// <param name="labelPVs">杩囩▼鍙橀噺鍒楄〃</param> + /// <param name="label">鏍囩妯℃澘</param> + /// <returns></returns> + public BAS_LABEL_TEMP SetLabelVariables(List<BAS_LABEL_PV> labelPVs, BAS_LABEL_TEMP label) + { + foreach (var item in label.Variables) + { + switch (item.VAR_TYPE.GetEnum<BAS_LABEL_VAR.VAR_TYPEs>()) + { + case BAS_LABEL_VAR.VAR_TYPEs.Constant: + item.Value = item.VAR_VALUE; + break; + case BAS_LABEL_VAR.VAR_TYPEs.ProcessVariable: + item.Value = GetPrintProcessValue(labelPVs, item); + break; + case BAS_LABEL_VAR.VAR_TYPEs.DateVariable: + item.Value = DateTime.Now.ToString(item.VAR_VALUE); + break; + case BAS_LABEL_VAR.VAR_TYPEs.CustomVariable: + default: + item.Value = ""; + break; + } + } + return label; + } + + /// <summary> + /// 鑾峰彇鎵撳嵃鏍囩妯℃澘杩囩▼鍙橀噺鍊� + /// </summary> + /// <param name="labelPVs">杩囩▼鍙橀噺鍒楄〃</param> + /// <param name="lv">鏍囩妯℃澘鍙橀噺</param> + /// <returns></returns> + public string GetPrintProcessValue(List<BAS_LABEL_PV> labelPVs, BAS_LABEL_VAR lv) + { + var pv = labelPVs.FirstOrDefault(q => q.VAR_CODE == lv.VAR_VALUE); + if (!pv.IsNullOrEmpty()) + { + switch (pv.VAR_TYPE.GetEnum<BAS_LABEL_PV.VAR_TYPEs>()) + { + case BAS_LABEL_PV.VAR_TYPEs.ServerMethod: + { + switch (pv.VAR_METHOD) + { + case "GetSN": + return string.Join(",", CurWipSNs.Select(q => q.SN)); + case "GetTraySN": + return CurSN; + case "GetBAS_ITEM": + return WorkBatch.Product.ToJson(); + case "GetCustomer": + return WorkBatch.Batch.ToJson(); + case "GetVarByWo": + return GetLabelVarWo(lv); + default: + return ""; + } + } + case BAS_LABEL_PV.VAR_TYPEs.WebApiWebApi: + break; + case BAS_LABEL_PV.VAR_TYPEs.StoredProcedure: + break; + default: + break; + } + } + return ""; + } + /// <summary> + /// 鑾峰彇宸ュ崟缁存姢鐨勬ā鏉垮彉閲� + /// </summary> + /// <param name="labelId"></param> + /// <returns></returns> + private string GetLabelVarWo(BAS_LABEL_VAR lv) + { + string result = ""; + var labelVarwos = Biz.Db.Queryable<BAS_LABEL_VAR_WO>().Where(x => x.LABEL_ID == lv.LABEL_ID && x.VAR_NAME == lv.VAR_NAME).ToList(); + if (labelVarwos.Any(q => q.WORK_ORDER == WorkBatch.Batch.ORDER_NO)) + { + result = labelVarwos.First(q => q.WORK_ORDER == WorkBatch.Batch.ORDER_NO).VAR_VALUE; + } + else + { + result = labelVarwos.Count > 0 ? labelVarwos[0].DEFAULT_VALUE : ""; + } + return result; } #endregion Functions -- Gitblit v1.9.3