| | |
| | | //先判断当前工单不为空且当前岗位在当前工单是不是首站,如果是则不允许变更当前工单,尝试把条码绑定到当前工单 |
| | | if (!CurBatch.IsNullOrEmpty() && CurBatch.IsFirstNode(PostCode)) |
| | | { |
| | | //更新CurBatch |
| | | CurBatch?.Update(); |
| | | //提交数据 |
| | | action = NodeSubmit(action, input); |
| | | //更新工序信息 |
| | | if (!action.IsSuccessed) |
| | | { |
| | | var info = WoContext.GetSnOperInfo(input.SN).Data; |
| | | info.InputQty = OperInfoDic[CurBatch.Batch.BATCH_NO].InputQty; |
| | | info.InputQty = CurOperInfo(input.Locale).InputQty; |
| | | action.Data.OperInfo = info; |
| | | } |
| | | else if (!IsFinishAllSteps) |
| | | { |
| | | action.Data.OperInfo = SetOperNodeInfo(OperInfoDic[CurBatch.Batch.BATCH_NO], input.Locale); |
| | | action.Data.OperInfo = SetOperNodeInfo(CurOperInfo(input.Locale)); |
| | | } |
| | | } |
| | | //当前岗位在当前工单不是首站,则查找条码已绑定的工单当作当前工单 |
| | | else |
| | | { |
| | | var wosns = Biz.Db.Queryable<BIZ_MES_WO_BATCH, BIZ_MES_WO_SN>((q, s) => new JoinQueryInfos(JoinType.Inner, q.ORDER_NO == s.WORK_ORDER)) |
| | | .ByAuth(input.AuthOption).Where((q, s) => s.SN == input.SN || s.TRAY_SN == input.SN).Select((q, s) => new { Batch = q, SN = s }).ToList(); |
| | | .ByAuth(input.AuthOption).Where((q, s) => s.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue()) |
| | | .Where((q, s) => s.SN == input.SN || s.FLOW_SN == input.SN || s.TRAY_SN == input.SN).Select((q, s) => new { Batch = q, SN = s }).ToList(); |
| | | |
| | | //查找到条码已绑定的工单 |
| | | if (!wosns.IsNullOrEmpty()) |
| | |
| | | return action; |
| | | } |
| | | } |
| | | //更新CurBatch |
| | | CurBatch?.Update(); |
| | | //条码过站 |
| | | action = NodeSubmit(action, input); |
| | | if (!action.IsSuccessed && !CurWipSNs.Any()) |
| | | { |
| | | var info = WoContext.GetSnOperInfo(input.SN).Data; |
| | | info.InputQty = OperInfoDic[CurBatch.Batch.BATCH_NO].InputQty; |
| | | info.InputQty = CurOperInfo(input.Locale).InputQty; |
| | | action.Data.OperInfo = info; |
| | | } |
| | | else if (!IsFinishAllSteps) |
| | | { |
| | | action.Data.OperInfo = SetOperNodeInfo(OperInfoDic[CurBatch.Batch.BATCH_NO], input.Locale); |
| | | action.Data.OperInfo = SetOperNodeInfo(CurOperInfo(input.Locale)); |
| | | } |
| | | } |
| | | } |
| | |
| | | //完成工序节点工步后,开始执行当前工序的行为工步 |
| | | else if (IsFinishNodeSteps && !IsFinishAllSteps) |
| | | { |
| | | //更新CurBatch |
| | | CurBatch?.Update(); |
| | | |
| | | var submitStep = Steps.Where(q => q.ID == input.CurStepID && !q.IsFinished).FirstOrDefault(); |
| | | //如果客户端返回的当前工步ID找不到未完成的行为工步,则直接开始下一个行为工步 |
| | | if (submitStep.IsNullOrEmpty()) |
| | | { |
| | | action = BeginNextActionStep(input); |
| | | action.Data.OperInfo = OperInfoDic[CurBatch.Batch.BATCH_NO]; |
| | | } |
| | | else |
| | | { |
| | | var result = submitStep.Submit(input); |
| | | action = submitStep.Submit(input); |
| | | //如果当前工步已完成,开始执行下一工步 |
| | | if (result.IsSuccessed && submitStep.IsFinished) |
| | | if (action.IsSuccessed && submitStep.IsFinished) |
| | | { |
| | | result = BeginNextActionStep(input); |
| | | action = BeginNextActionStep(input); |
| | | } |
| | | //如果当前工步未完成 |
| | | else |
| | |
| | | //行为执行出错,工步被重置 |
| | | if (Steps.IsNullOrEmpty()) |
| | | { |
| | | result.LocaleMsg = new(Biz.T(result.LocaleMsg, input.Locale) + Biz.T(Biz.L("MES.Transaction.Position.RescanSN"), input.Locale)); |
| | | action.LocaleMsg = new(Biz.T(action.LocaleMsg, input.Locale) + Biz.T(Biz.L("MES.Transaction.Position.RescanSN"), input.Locale)); |
| | | } |
| | | else |
| | | { |
| | | result.Data.SetValue(CurBatch, CurStep, CurStep?.ID, IsFinishAllSteps); |
| | | action.Data.SetValue(CurBatch, CurStep, CurStep?.ID, IsFinishAllSteps); |
| | | } |
| | | } |
| | | //如果所有工步都完成 |
| | | if (IsFinishAllSteps) |
| | | { |
| | | result = DoIfFinishAllSteps(result, input.Locale); |
| | | } |
| | | else |
| | | { |
| | | result.Data.OperInfo = OperInfoDic[CurBatch.Batch.BATCH_NO]; |
| | | } |
| | | return result; |
| | | } |
| | | //如果所有工步都完成 |
| | | if (IsFinishAllSteps) |
| | | { |
| | | action = DoIfFinishAllSteps(action, input.Locale); |
| | | } |
| | | else |
| | | { |
| | | action.Data.OperInfo = CurOperInfo(input.Locale); |
| | | } |
| | | } |
| | | //没有可执行的工步 |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("重置扫描", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = OperInfoDic.ContainsKey(CurBatch?.Batch?.BATCH_NO ?? "") ? OperInfoDic[CurBatch.Batch.BATCH_NO] : new(); |
| | | action.Data.OperInfo = CurOperInfo(input.Locale); |
| | | ResetNode(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"岗位[{CurPosition.POST_CODE}]工步执行异常,请重新扫描产品条码", CurPosition.POST_CODE); |
| | |
| | | catch (Exception ex) |
| | | { |
| | | action.Data.ShortMsg = new("工序异常", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = OperInfoDic.ContainsKey(CurBatch?.Batch?.BATCH_NO ?? "") ? OperInfoDic[CurBatch.Batch.BATCH_NO] : new(); |
| | | action.Data.OperInfo = CurOperInfo(input.Locale); |
| | | //action.CatchExceptionWithLog(ex, $"测试工序:提交操作数据异常"); |
| | | action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.TestNode.SubmitException")); |
| | | } |
| | |
| | | var curNode = CurBatch.GetNode(PostCode); |
| | | try |
| | | { |
| | | //判断工单实时状态判断是否可以生产 |
| | | var woStatus = CurBatch.CheckCanProduce(curNode); |
| | | if (!woStatus.IsSuccessed) |
| | | { |
| | | woStatus.Data.ShortMsg = new("工单异常", ShortMessage.Types.Error); |
| | | return woStatus; |
| | | } |
| | | |
| | | var wipSNs = Biz.Db.Queryable<MES_WIP_DATA>().IncludesAllFirstLayer().Where(q => (q.SN == input.SN || q.TRAY_SN == input.SN) && q.WORK_ORDER == CurBatch.WO.ORDER_NO).ToList(); |
| | | if (wipSNs.IsNullOrEmpty()) |
| | | { |
| | | var wipSN = new MES_WIP_DATA() |
| | | { |
| | | SN = input.SN, |
| | | FLOW_SN = input.SN, |
| | | STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(), |
| | | ITEM_CODE = CurBatch.WO.ITEM_CODE, |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | FTY_CODE = CurFactory.FTY_CODE, |
| | | WS_CODE = CurWorkshop.WS_CODE, |
| | | LINE_CODE = CurLine.LINE_CODE, |
| | | POST_CODE = CurPosition.POST_CODE, |
| | | HOLD_FLAG = "N", |
| | | REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N", |
| | | FINISHED_FLAG = "N", |
| | | INV_FLAG = "N", |
| | | DFT_FLAG = "N", |
| | | DFT_COUNT = 0, |
| | | }; |
| | | wipSNs.Add(wipSN); |
| | | } |
| | | |
| | | //如果条码不是当前工单或者产线的则报错 |
| | | if (wipSNs.Any(q => q.WORK_ORDER != CurBatch.WO.ORDER_NO || q.LINE_CODE != CurLine.LINE_CODE)) |
| | | { |
| | | if (wipSNs.First().LINE_CODE == CurLine.LINE_CODE) |
| | | { |
| | | action.Data.ShortMsg = new("工单错误", ShortMessage.Types.Error); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"产品[{CurSN}]不属于当前工单,请切换到工单[{wipSNs.First().WORK_ORDER}]后再扫描"); |
| | | action.LocaleMsg = new("MES.Transaction.TestNode.NodeSubmit.WoError", CurSN, wipSNs.First().WORK_ORDER); |
| | | return action; |
| | | } |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("产线错误", ShortMessage.Types.Error); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"产品[{CurSN}]已在产线[{wipSNs.First().LINE_CODE}]投产,请到产线[{wipSNs.First().LINE_CODE}]扫描"); |
| | | action.LocaleMsg = new("MES.Transaction.TestNode.NodeSubmit.LineError", CurSN, wipSNs.First().LINE_CODE); |
| | | return action; |
| | | } |
| | | } |
| | | |
| | | //非法过站防呆:进入工序时要增加判断条码是否按流程过站 |
| | | var canGotoNext = CurBatch.CanGotoNext(input, wipSNs.First(), curNode); |
| | | if (!canGotoNext.IsSuccessed) |
| | | { |
| | | woStatus.Data.ShortMsg = new("进站错误", ShortMessage.Types.Error); |
| | | return canGotoNext; |
| | | } |
| | | |
| | | //当工步列表为空,则执行当前工序的必要逻辑当作第一个工序节点,完成后按需求创建后续的工步列表 |
| | | if (Steps.IsNullOrEmpty()) |
| | | { |
| | | BeginAt = DateTime.Now; |
| | | //判断工单实时状态判断是否可以生产 |
| | | var woStatus = CurBatch.CheckCanProduce(curNode); |
| | | if (!woStatus.IsSuccessed) |
| | | { |
| | | woStatus.Data.ShortMsg = new("工单异常", ShortMessage.Types.Error); |
| | | return woStatus; |
| | | } |
| | | |
| | | var wipSNs = Biz.Db.Queryable<MES_WIP_DATA>().IncludesAllFirstLayer().Where(q => q.SN == input.SN || q.FLOW_SN == input.SN || q.TRAY_SN == input.SN).ToList(); |
| | | if (wipSNs.IsNullOrEmpty()) |
| | | { |
| | | var wipSN = new MES_WIP_DATA() |
| | | { |
| | | SN = input.SN, |
| | | FLOW_SN = input.SN, |
| | | STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(), |
| | | ITEM_CODE = CurBatch.WO.ITEM_CODE, |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | FTY_CODE = CurFactory.FTY_CODE, |
| | | WS_CODE = CurWorkshop.WS_CODE, |
| | | LINE_CODE = CurLine.LINE_CODE, |
| | | POST_CODE = CurPosition.POST_CODE, |
| | | HOLD_FLAG = "N", |
| | | REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N", |
| | | FINISHED_FLAG = "N", |
| | | INV_FLAG = "N", |
| | | DFT_FLAG = "N", |
| | | DFT_COUNT = 0, |
| | | }; |
| | | wipSNs.Add(wipSN); |
| | | } |
| | | |
| | | //如果条码不是当前工单或者产线的则报错 |
| | | if (wipSNs.Any(q => q.WORK_ORDER != CurBatch.WO.ORDER_NO || q.LINE_CODE != CurLine.LINE_CODE)) |
| | | { |
| | | if (wipSNs.First().LINE_CODE == CurLine.LINE_CODE) |
| | | { |
| | | action.Data.ShortMsg = new("工单错误", ShortMessage.Types.Error); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"产品[{CurSN}]不属于当前工单,请切换到工单[{wipSNs.First().WORK_ORDER}]后再扫描"); |
| | | action.LocaleMsg = new("MES.Transaction.TestNode.NodeSubmit.WoError", input.SN, wipSNs.First().WORK_ORDER); |
| | | return action; |
| | | } |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("产线错误", ShortMessage.Types.Error); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"产品[{CurSN}]已在产线[{wipSNs.First().LINE_CODE}]投产,请到产线[{wipSNs.First().LINE_CODE}]扫描"); |
| | | action.LocaleMsg = new("MES.Transaction.TestNode.NodeSubmit.LineError", input.SN, wipSNs.First().LINE_CODE); |
| | | return action; |
| | | } |
| | | } |
| | | |
| | | //非法过站防呆:进入工序时要增加判断条码是否按流程过站 |
| | | var canGotoNext = CurBatch.CanGotoNext(input, wipSNs.First(), curNode); |
| | | if (!canGotoNext.IsSuccessed) |
| | | { |
| | | woStatus.Data.ShortMsg = new("进站错误", ShortMessage.Types.Error); |
| | | return canGotoNext; |
| | | } |
| | | |
| | | //绑定条码到工单 |
| | | foreach (var wipSN in wipSNs) |
| | | { |
| | |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | WIP_ID = wipSN.ID, |
| | | SN = wipSN.SN, |
| | | FLOW_SN = wipSN.SN, |
| | | TRAY_SN = wipSN.TRAY_SN, |
| | | STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(), |
| | | }); |
| | |
| | | |
| | | //初始化工步列表 |
| | | Steps.Clear(); |
| | | var curStep = new Biz.WorkStep(IWorkStep.NodeTypes.Node, this) |
| | | var curStep = new WorkStep(IWorkStep.NodeTypes.Node, this) |
| | | { |
| | | Name = "扫描产品", |
| | | Sequence = Steps.Count + 1, |
| | |
| | | } |
| | | |
| | | //完成第一个工序节点工步 |
| | | curStep.IsFinished = true; |
| | | curStep.Status = StepStatus.Finished; |
| | | CurStep = curStep; |
| | | } |
| | |
| | | { |
| | | var curStep = Steps.Where(q => q.NodeType == IWorkStep.NodeTypes.Node && !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | |
| | | //完成当前工序节点工步 |
| | | curStep.Status = StepStatus.Finished; |
| | | CurStep = curStep; |
| | | //根据工序节点工步的序号处理相应工步的处理逻辑 |
| | | switch (curStep.Sequence) |
| | | { |
| | | case 2: |
| | | { |
| | | //第二工步的处理逻辑 |
| | | |
| | | |
| | | //完成当前工序节点工步 |
| | | curStep.IsFinished = true; |
| | | curStep.Status = StepStatus.Finished; |
| | | CurStep = curStep; |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | //未完成所有工步 |
| | |
| | | SaveStepsCommitActionToDB(); |
| | | |
| | | //保存成功,返回过站消息 |
| | | OperInfoDic[CurBatch.Batch.BATCH_NO].InputQty += CurWipSNs.Count; |
| | | action.Data.OperInfo = SetOperNodeInfo(OperInfoDic[CurBatch.Batch.BATCH_NO], locale); |
| | | CurOperInfo(locale).InputQty += CurWipSNs.Count; |
| | | action.Data.OperInfo = SetOperNodeInfo(CurOperInfo(locale)); |
| | | action.Data.ShortMsg = new("过站成功", ShortMessage.Types.Success); |
| | | //action.LocaleMsg = new($"工单[{CurWipSN.WORK_ORDER}]的条码[{CurWipSN.SN}]在岗位[{CurWipSN.POST_CODE}]工序[{CurWipSN.NODE_NAME}]过站成功,状态[{CurWipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()}]"); |
| | | action.LocaleMsg = new("MES.Transaction.CollectNode.ScanSn.PassSuccess", CurWipSNs.First().WORK_ORDER, CurSN, CurWipSNs.First().POST_CODE, CurWipSNs.First().NODE_NAME, CurWipSNs.First().STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()); |