增加工艺路线必须要有结束节点,及其流程相应优化
增加工单批次自动关单
增加判断条码是未投入生产还是已经完工产出
| | |
| | | var db = Biz.Db; |
| | | var dbTran = db.UseTran(() => |
| | | { |
| | | db.Updateable(_wo, input.UserId).UpdateColumns(x => new { x.STATUS, x.ROUTE_STATUS }).ExecuteCommand(); |
| | | db.Updateable(_wo, input.UserId).UpdateColumns(x => new { x.STATUS, x.ROUTE_STATUS, x.UPDATE_USER, x.UPDATE_TIME }).ExecuteCommand(); |
| | | }); |
| | | if (!dbTran.IsSuccess) |
| | | { |
| | |
| | | //如果是下发 |
| | | if (input.Status == BIZ_MES_WO_BATCH.STATUSs.Release.GetValue()) |
| | | { |
| | | db.Updateable(_woBatch, input.UserId).UpdateColumns(x => new { x.STATUS, x.RELEASE_USER, x.RELEASE_TIME, x.ACT_LINE }).ExecuteCommand(); |
| | | db.Updateable(_woBatch, input.UserId).UpdateColumns(x => new { x.STATUS, x.RELEASE_USER, x.RELEASE_TIME, x.ACT_LINE, x.UPDATE_USER, x.UPDATE_TIME }).ExecuteCommand(); |
| | | } |
| | | else |
| | | { |
| | | db.Updateable(_woBatch, input.UserId).UpdateColumns(x => new { x.STATUS }).ExecuteCommand(); |
| | | db.Updateable(_woBatch, input.UserId).UpdateColumns(x => new { x.STATUS, x.UPDATE_USER, x.UPDATE_TIME }).ExecuteCommand(); |
| | | } |
| | | }); |
| | | if (!dbTran.IsSuccess) |
| | |
| | | |
| | | public void Update() |
| | | { |
| | | 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.BATCH_NO == Batch.BATCH_NO).First(); |
| | | if (WoContext.WoBatchDic.ContainsKey(Batch.BATCH_NO)) |
| | | var wo = Biz.Db.Queryable<BIZ_MES_WO>().Where(q => q.ORDER_NO == OrderNo).IncludesAllFirstLayer().First(); |
| | | var batch = Biz.Db.Queryable<BIZ_MES_WO_BATCH>().Where(q => q.BATCH_NO == Batch.BATCH_NO).First(); |
| | | if (WoContext.WoBatchDic.ContainsKey(batch.BATCH_NO)) |
| | | { |
| | | if (WO.STATUS > BIZ_MES_WO.STATUSs.Working.GetValue() || Batch.STATUS > BIZ_MES_WO_BATCH.STATUSs.Working.GetValue()) |
| | | if (wo.STATUS > BIZ_MES_WO.STATUSs.Working.GetValue() || batch.STATUS > BIZ_MES_WO_BATCH.STATUSs.Working.GetValue()) |
| | | { |
| | | WoContext.WoBatchDic.Remove(Batch.BATCH_NO); |
| | | } |
| | | else if(wo.UPDATE_TIME > WO.UPDATE_TIME || batch.UPDATE_TIME > Batch.UPDATE_TIME) |
| | | { |
| | | GetBatchInfo(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | GetBatchInfo(); |
| | | WoContext.WoBatchDic.Add(Batch.BATCH_NO, this); |
| | | WoContext.WoBatchDic.Add(batch.BATCH_NO, this); |
| | | } |
| | | WO = wo; |
| | | Batch = batch; |
| | | } |
| | | |
| | | private void GetBatchInfo() |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加节点的下一个行为到工步列表 |
| | | /// 递归遍历工序节点,给下级工序节点排序和整理前置工序 |
| | | /// </summary> |
| | | /// <param name="parent"></param> |
| | | private void NodeSorting(MES_WO_NODE parent) |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 检查工单是否完工,已完工则修改相应状态并记录到数据库 |
| | | /// </summary> |
| | | /// <param name="user"></param> |
| | | /// <returns></returns> |
| | | public async Task<bool> CheckIsComplete(string user) |
| | | { |
| | | var woSNs = Biz.Db.Queryable<BIZ_MES_WO_SN>().Where(q => q.WORK_ORDER == OrderNo).ToList(); |
| | | |
| | | //判断当前工单批次是否已完工 |
| | | if (!woSNs.Any(q => q.BATCH_NO == Batch.BATCH_NO && q.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue()) && |
| | | woSNs.Count(q => q.BATCH_NO == Batch.BATCH_NO && q.STATUS == BIZ_MES_WO_SN.STATUSs.Finished.GetValue()) == Batch.PLAN_QTY) |
| | | { |
| | | Batch.STATUS = BIZ_MES_WO_BATCH.STATUSs.Closed.GetValue(); |
| | | Batch.ACT_END_TIME = DateTime.Now; |
| | | } |
| | | |
| | | //判断当前工单是否已完工 |
| | | if (!woSNs.Any(q => q.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue()) && |
| | | woSNs.Count(q => q.STATUS == BIZ_MES_WO_SN.STATUSs.Finished.GetValue()) == WO.PLAN_QTY) |
| | | { |
| | | WO.STATUS = BIZ_MES_WO.STATUSs.Closed.GetValue(); |
| | | WO.ACT_END_TIME = DateTime.Now; |
| | | } |
| | | |
| | | //保存数据库 |
| | | 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_END_TIME }).ExecuteCommand(); |
| | | db.Updateable(Batch, user).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS, q.ACT_END_TIME }).ExecuteCommand(); |
| | | }); |
| | | if (!dbTran.IsSuccess) |
| | | { |
| | | //throw dbTran.ErrorException; |
| | | Logger.Default.Fatal(dbTran.ErrorException, $"检查工单批次[{Batch.BATCH_NO}]是否完工异常"); |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据岗位编码判断是不是首站 |
| | | /// </summary> |
| | | /// <param name="postCode"></param> |
| | |
| | | } |
| | | |
| | | //如果当前工序有必须执行的后续工序,则报错 |
| | | if (nextNodes.Any(q => NodeSets.Any(s => s.NODE_ID == q.ID && s.IS_ACTIVE == "Y" && s.CAN_SKIP != "Y"))) |
| | | if (nextNodes.Any(q => q.OPER_CODE != "EndNode" && NodeSets.Any(s => s.NODE_ID == q.ID && s.IS_ACTIVE == "Y" && s.CAN_SKIP != "Y"))) |
| | | { |
| | | action.IsSuccessed = false; |
| | | action.Data.SetValue(this, null); |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加节点的下一个可执行节点 |
| | | /// 获取节点的下一个可执行节点(排除有前置工序未完成的节点) |
| | | /// </summary> |
| | | /// <param name="parent"></param> |
| | | /// <param name="wipSN">当前的条码过站记录,需要导航查询生产过程记录信息</param> |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据传入的条码返回下一站可进入进入的目标工序 |
| | | /// 根据传入的条码返回下一站可进入的目标工序 |
| | | /// </summary> |
| | | /// <param name="wipSN">当前的条码过站记录,需要导航查询生产过程记录和生产不良记录信息</param> |
| | | /// <returns></returns> |
| | |
| | | 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 && q.BATCH_NO == s.BATCH_NO)) |
| | | .ByAuth(input.AuthOption).Where((q, s) => s.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue()) |
| | | .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()) |
| | | if (wosns.Any(q => q.SN.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue())) |
| | | { |
| | | if (wosns.First().Batch.ACT_LINE != CurLine.LINE_CODE) |
| | | var curSNs = wosns.Where(q => q.SN.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue()); |
| | | if (curSNs.First().Batch.ACT_LINE != CurLine.LINE_CODE) |
| | | { |
| | | action.Data.ShortMsg = new("产线错误", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{0}]已在产线[{1}]投入生产,请在正确岗位扫描"); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotCorrectLine", input.SN, wosns.First().Batch.ACT_LINE); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotCorrectLine", input.SN, curSNs.First().Batch.ACT_LINE); |
| | | } |
| | | else |
| | | { |
| | | if (CurBatch?.Batch?.ORDER_NO != wosns.First().Batch.ORDER_NO) |
| | | if (CurBatch?.Batch?.ORDER_NO != curSNs.First().Batch.ORDER_NO) |
| | | { |
| | | //条码已绑定的工单不等于当前工单则重新选择工单 |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosns.First().Batch.ORDER_NO }, wosns.First().Batch.BATCH_NO); |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = curSNs.First().Batch.ORDER_NO }, curSNs.First().Batch.BATCH_NO); |
| | | if (!result.IsSuccessed) |
| | | { |
| | | action.Data.ShortMsg = new("工单异常", ShortMessage.Types.Error); |
| | |
| | | //有当前工单且不是投入,则提示条码未投入生产,请先去首站扫描 |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("未投入生产", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{input.SN}]尚未投入生产,请先去首站扫描", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.CollectNode.Submit.NotInputException", input.SN); |
| | | var lastSn = wosns.OrderByDescending(q => q.SN.UPDATE_TIME).FirstOrDefault(); |
| | | if (!lastSn.IsNullOrEmpty()) |
| | | { |
| | | action.Data.ShortMsg = new($"产品{lastSn.SN.STATUS.GetEnumDesc<BIZ_MES_WO_SN.STATUSs>()}", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"进站扫描错误,条码[{0}]{1}", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.CollectNode.Submit.NotInputException", input.SN); |
| | | } |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("未投入生产", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{input.SN}]尚未投入生产,请先去首站扫描", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.CollectNode.Submit.NotInputException", input.SN); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action, string locale) |
| | | { |
| | | var operInfo = SetOperNodeInfo(CurOperInfo(locale)); |
| | | Action endAction = null; |
| | | |
| | | //如果当前条码已经走到流程终点则记录条码完工 |
| | | if (action.Data.OperInfo.IsReachedEndNode) |
| | | { |
| | | //更新工单条码明细信息 |
| | | var woSNs = CurBatch.WoSNs.Where(q => CurWipSNs.Any(w => q.WIP_ID == w.ID)).ToList(); |
| | | foreach (var woSN in woSNs) |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | } |
| | | var curNode = CurBatch.Nodes.First(q => q.OPER_CODE == "EndNode"); |
| | | //条码完工 |
| | | foreach (var wipSN in CurWipSNs) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | } |
| | | |
| | | var wipHiss = new List<MES_WIP_HIS>(); |
| | | foreach (var wipSN in CurWipSNs) |
| | | { |
| | | var his = new MES_WIP_HIS(wipSN, $"工单[{wipSN.WORK_ORDER}]条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]过站工序[{wipSN.NODE_NAME}]成功"); |
| | | wipSN.History.Add(his); |
| | | wipHiss.Add(his); |
| | | } |
| | | |
| | | //创建变量克隆对象用于传入DBSubmitAction中保存当前需要暂存的数据值 |
| | | var _woSns = woSNs.Clone(); |
| | | var _wipSns = CurWipSNs.Clone(); |
| | | var _wipHiss = wipHiss.Clone(); |
| | | //保存数据 |
| | | endAction = () => |
| | | { |
| | | //使用统一的事务DB对象 |
| | | var db = GetCommitDB(); |
| | | //数据保存逻辑 |
| | | db.Storageable(_woSns, UserCode).ExecuteCommand(); |
| | | db.Storageable(_wipSns, UserCode).ExecuteCommand(); |
| | | db.Storageable(_wipHiss, UserCode).ExecuteCommand(); |
| | | }; |
| | | } |
| | | |
| | | //保存数据库 |
| | | SaveStepsCommitActionToDB(); |
| | | SaveStepsCommitActionToDB(endAction); |
| | | |
| | | //保存成功,返回过站消息 |
| | | CurOperInfo(locale).InputQty += CurWipSNs.Count; |
| | | action.Data.OperInfo = SetOperNodeInfo(CurOperInfo(locale)); |
| | | action.Data.OperInfo = operInfo; |
| | | action.Data.ShortMsg = new(CurWipSNs.Any(q => q.DFT_FLAG == "Y") ? "不良过站" : "良品过站", 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>()); |
| | | |
| | | |
| | | |
| | | //如果当前条码已经完工,检查当前工单批次和工单是否完工 |
| | | if (action.Data.OperInfo.IsReachedEndNode) |
| | | { |
| | | CurBatch.CheckIsComplete(UserCode); |
| | | } |
| | | |
| | | //重置工序 |
| | | ResetNode(); |
| | | return action; |
| | |
| | | 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 && q.BATCH_NO == s.BATCH_NO)) |
| | | .ByAuth(input.AuthOption).Where((q, s) => s.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue()) |
| | | .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()) |
| | | if (wosns.Any(q => q.SN.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue())) |
| | | { |
| | | if (wosns.Count > 1 && wosns.Any(q => q.SN.TRAY_SN != q.SN.OUTER_SN)) |
| | | var curSNs = wosns.Where(q => q.SN.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue()); |
| | | if (curSNs.Count() > 1 && curSNs.Any(q => q.SN.TRAY_SN != q.SN.OUTER_SN)) |
| | | { |
| | | action.Data.ShortMsg = new("请扫描产品", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.OnlyMinPackage", input.SN); |
| | | return action; |
| | | } |
| | | if (Context.ContainsKey("CurPackage") && !Context["CurPackage"].IsNullOrEmpty() && (Context["CurPackage"] as WipPkg).WorkBatch != wosns.First().Batch.BATCH_NO) |
| | | if (Context.ContainsKey("CurPackage") && !Context["CurPackage"].IsNullOrEmpty() && (Context["CurPackage"] as WipPkg).WorkBatch != curSNs.First().Batch.BATCH_NO) |
| | | { |
| | | action.Data.ShortMsg = new("工单批次错误", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"正在包装工单批次[{0}]的产品,请先完成当前包装后再扫描其他批次[{1}]的产品[{2}]"); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.BatchError", (Context["CurPackage"] as WipPkg).WorkBatch, wosns.First().Batch.BATCH_NO, input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.BatchError", (Context["CurPackage"] as WipPkg).WorkBatch, curSNs.First().Batch.BATCH_NO, input.SN); |
| | | return action; |
| | | } |
| | | if (wosns.First().Batch.ACT_LINE != CurLine.LINE_CODE) |
| | | if (curSNs.First().Batch.ACT_LINE != CurLine.LINE_CODE) |
| | | { |
| | | action.Data.ShortMsg = new("产线投产错误", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{0}]已在产线[{1}]投入生产,请在正确岗位扫描"); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotCorrectLine", input.SN, wosns.First().Batch.ACT_LINE); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotCorrectLine", input.SN, curSNs.First().Batch.ACT_LINE); |
| | | } |
| | | else |
| | | { |
| | | if (CurBatch?.Batch?.ORDER_NO != wosns.First().Batch.ORDER_NO) |
| | | if (CurBatch?.Batch?.ORDER_NO != curSNs.First().Batch.ORDER_NO) |
| | | { |
| | | //条码已绑定的工单不等于当前工单则重新选择工单 |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosns.First().Batch.ORDER_NO }, wosns.First().Batch.BATCH_NO); |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = curSNs.First().Batch.ORDER_NO }, curSNs.First().Batch.BATCH_NO); |
| | | if (!result.IsSuccessed) |
| | | { |
| | | action.Data.ShortMsg = new("工单异常", ShortMessage.Types.Error); |
| | |
| | | //有当前工单且不是投入,则提示条码未投入生产,请先去首站扫描 |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("未投入生产", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{input.SN}]尚未投入生产,请先去首站扫描", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotInputException", input.SN); |
| | | var lastSn = wosns.OrderByDescending(q => q.SN.UPDATE_TIME).FirstOrDefault(); |
| | | if (!lastSn.IsNullOrEmpty()) |
| | | { |
| | | action.Data.ShortMsg = new($"产品{lastSn.SN.STATUS.GetEnumDesc<BIZ_MES_WO_SN.STATUSs>()}", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"进站扫描错误,条码[{0}]{1}", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotInputException", input.SN); |
| | | } |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("未投入生产", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{input.SN}]尚未投入生产,请先去首站扫描", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotInputException", input.SN); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | case 2: |
| | | //action.LocaleMsg = new($"请执行第二步"); |
| | | action.LocaleMsg = new("MES.Transaction.CollectNode.第二步操作提示"); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.第二步操作提示"); |
| | | break; |
| | | default: |
| | | break; |
| | |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action, string locale) |
| | | { |
| | | var operInfo = SetOperNodeInfo(CurOperInfo(locale)); |
| | | Action endAction = null; |
| | | |
| | | //如果当前条码已经走到流程终点则记录条码完工 |
| | | if (action.Data.OperInfo.IsReachedEndNode) |
| | | { |
| | | //更新工单条码明细信息 |
| | | var woSNs = CurBatch.WoSNs.Where(q => CurWipSNs.Any(w => q.WIP_ID == w.ID)).ToList(); |
| | | foreach (var woSN in woSNs) |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | } |
| | | var curNode = CurBatch.Nodes.First(q => q.OPER_CODE == "EndNode"); |
| | | //条码完工 |
| | | foreach (var wipSN in CurWipSNs) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | } |
| | | |
| | | var wipHiss = new List<MES_WIP_HIS>(); |
| | | foreach (var wipSN in CurWipSNs) |
| | | { |
| | | var his = new MES_WIP_HIS(wipSN, $"工单[{wipSN.WORK_ORDER}]条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]过站工序[{wipSN.NODE_NAME}]成功"); |
| | | wipSN.History.Add(his); |
| | | wipHiss.Add(his); |
| | | } |
| | | |
| | | //创建变量克隆对象用于传入DBSubmitAction中保存当前需要暂存的数据值 |
| | | var _woSns = woSNs.Clone(); |
| | | var _wipSns = CurWipSNs.Clone(); |
| | | var _wipHiss = wipHiss.Clone(); |
| | | //保存数据 |
| | | endAction = () => |
| | | { |
| | | //使用统一的事务DB对象 |
| | | var db = GetCommitDB(); |
| | | //数据保存逻辑 |
| | | db.Storageable(_woSns, UserCode).ExecuteCommand(); |
| | | db.Storageable(_wipSns, UserCode).ExecuteCommand(); |
| | | db.Storageable(_wipHiss, UserCode).ExecuteCommand(); |
| | | }; |
| | | } |
| | | |
| | | //保存数据库 |
| | | SaveStepsCommitActionToDB(); |
| | | |
| | | //保存成功,返回过站消息 |
| | | CurOperInfo(locale).InputQty += CurWipSNs.Count; |
| | | action.Data.Data = new PackingActionOutput() { PkgInfo = Context.ContainsKey("CurPackage") ? Context["CurPackage"] as WipPkg : null }; |
| | | action.Data.OperInfo = SetOperNodeInfo(CurOperInfo(locale)); |
| | | action.Data.OperInfo = operInfo; |
| | | action.Data.ShortMsg = new(CurWipSNs.Any(q => q.DFT_FLAG == "Y") ? "不良过站" : "良品过站", 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>()); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.ScanSn.PassSuccess", CurWipSNs.First().WORK_ORDER, CurSN, CurWipSNs.First().POST_CODE, CurWipSNs.First().NODE_NAME, CurWipSNs.First().STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()); |
| | | |
| | | //重置工序 |
| | | ResetNode(); |
| | |
| | | if (CurWipSNs.Any()) |
| | | { |
| | | info.CurNode = CurWipSNs.First().NODE_NAME; |
| | | info.NextNode = string.Join(",", CurBatch.GetNextNodes(CurWipSNs.First()).Select(q => q.NODE_NAME)); |
| | | var nextNodes = CurBatch.GetNextNodes(CurWipSNs.First()); |
| | | info.NextNode = string.Join(",", nextNodes.Select(q => q.NODE_NAME)); |
| | | if (nextNodes.Count == 1 && nextNodes.Single().OPER_CODE == "EndNode") |
| | | { |
| | | info.IsReachedEndNode = true; |
| | | } |
| | | } |
| | | else |
| | | { |
| | |
| | | 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 && q.BATCH_NO == s.BATCH_NO)) |
| | | .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(); |
| | | .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()) |
| | | if (wosns.Any(q => q.SN.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue())) |
| | | { |
| | | if (wosns.First().Batch.ACT_LINE != CurLine.LINE_CODE) |
| | | var curSNs = wosns.Where(q => q.SN.STATUS < BIZ_MES_WO_SN.STATUSs.Finished.GetValue()); |
| | | if (curSNs.First().Batch.ACT_LINE != CurLine.LINE_CODE) |
| | | { |
| | | action.Data.ShortMsg = new("产线错误", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{0}]已在产线[{1}]投入生产,请在正确岗位扫描"); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotCorrectLine", input.SN, wosns.First().Batch.ACT_LINE); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.Submit.NotCorrectLine", input.SN, curSNs.First().Batch.ACT_LINE); |
| | | } |
| | | else |
| | | { |
| | | if (CurBatch?.Batch?.ORDER_NO != wosns.First().Batch.ORDER_NO) |
| | | if (CurBatch?.Batch?.ORDER_NO != curSNs.First().Batch.ORDER_NO) |
| | | { |
| | | //条码已绑定的工单不等于当前工单则重新选择工单 |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosns.First().Batch.ORDER_NO }, wosns.First().Batch.BATCH_NO); |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = curSNs.First().Batch.ORDER_NO }, curSNs.First().Batch.BATCH_NO); |
| | | if (!result.IsSuccessed) |
| | | { |
| | | action.Data.ShortMsg = new("工单异常", ShortMessage.Types.Error); |
| | |
| | | //有当前工单且不是投入,则提示条码未投入生产,请先去首站扫描 |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("未投入生产", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{input.SN}]尚未投入生产,请先去首站扫描", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.TestNode.Submit.NotInputException", input.SN); |
| | | var lastSn = wosns.OrderByDescending(q => q.SN.UPDATE_TIME).FirstOrDefault(); |
| | | if (!lastSn.IsNullOrEmpty()) |
| | | { |
| | | action.Data.ShortMsg = new($"产品{lastSn.SN.STATUS.GetEnumDesc<BIZ_MES_WO_SN.STATUSs>()}", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"进站扫描错误,条码[{0}]{1}", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.TestNode.Submit.NotInputException", input.SN); |
| | | } |
| | | else |
| | | { |
| | | action.Data.ShortMsg = new("未投入生产", ShortMessage.Types.Error); |
| | | action.Data.OperInfo = new(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"条码[{input.SN}]尚未投入生产,请先去首站扫描", input.SN); |
| | | action.LocaleMsg = new("MES.Transaction.TestNode.Submit.NotInputException", input.SN); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action, string locale) |
| | | { |
| | | var operInfo = SetOperNodeInfo(CurOperInfo(locale)); |
| | | Action endAction = null; |
| | | |
| | | //如果当前条码已经走到流程终点则记录条码完工 |
| | | if (action.Data.OperInfo.IsReachedEndNode) |
| | | { |
| | | //更新工单条码明细信息 |
| | | var woSNs = CurBatch.WoSNs.Where(q => CurWipSNs.Any(w => q.WIP_ID == w.ID)).ToList(); |
| | | foreach (var woSN in woSNs) |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | } |
| | | var curNode = CurBatch.Nodes.First(q => q.OPER_CODE == "EndNode"); |
| | | //条码完工 |
| | | foreach (var wipSN in CurWipSNs) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | } |
| | | |
| | | var wipHiss = new List<MES_WIP_HIS>(); |
| | | foreach (var wipSN in CurWipSNs) |
| | | { |
| | | var his = new MES_WIP_HIS(wipSN, $"工单[{wipSN.WORK_ORDER}]条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]过站工序[{wipSN.NODE_NAME}]成功"); |
| | | wipSN.History.Add(his); |
| | | wipHiss.Add(his); |
| | | } |
| | | |
| | | //创建变量克隆对象用于传入DBSubmitAction中保存当前需要暂存的数据值 |
| | | var _woSns = woSNs.Clone(); |
| | | var _wipSns = CurWipSNs.Clone(); |
| | | var _wipHiss = wipHiss.Clone(); |
| | | //保存数据 |
| | | endAction = () => |
| | | { |
| | | //使用统一的事务DB对象 |
| | | var db = GetCommitDB(); |
| | | //数据保存逻辑 |
| | | db.Storageable(_woSns, UserCode).ExecuteCommand(); |
| | | db.Storageable(_wipSns, UserCode).ExecuteCommand(); |
| | | db.Storageable(_wipHiss, UserCode).ExecuteCommand(); |
| | | }; |
| | | } |
| | | |
| | | //保存数据库 |
| | | SaveStepsCommitActionToDB(); |
| | | |
| | | //保存成功,返回过站消息 |
| | | CurOperInfo(locale).InputQty += CurWipSNs.Count; |
| | | action.Data.OperInfo = SetOperNodeInfo(CurOperInfo(locale)); |
| | | action.Data.OperInfo = operInfo; |
| | | action.Data.ShortMsg = new(CurWipSNs.Any(q => q.DFT_FLAG == "Y") ? "不良过站" : "良品过站", 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>()); |
| | | action.LocaleMsg = new("MES.Transaction.TestNode.ScanSn.PassSuccess", CurWipSNs.First().WORK_ORDER, CurSN, CurWipSNs.First().POST_CODE, CurWipSNs.First().NODE_NAME, CurWipSNs.First().STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()); |
| | | |
| | | //重置工序 |
| | | ResetNode(); |
| | |
| | | using Newtonsoft.Json; |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using Newtonsoft.Json; |
| | | using Rhea.Common; |
| | | using System; |
| | | using Tiger.Model; |
| | |
| | | /// <returns></returns> |
| | | public bool StartWorking(string user); |
| | | /// <summary> |
| | | /// 检查工单是否完工,已完工则修改相应状态并记录到数据库 |
| | | /// </summary> |
| | | /// <param name="user"></param> |
| | | /// <returns></returns> |
| | | public Task<bool> CheckIsComplete(string user); |
| | | /// <summary> |
| | | /// 根据岗位编码判断是不是首站 |
| | | /// </summary> |
| | | /// <param name="postCode"></param> |
| | |
| | | [DisplayName("物料编码")] |
| | | public string ITEM_CODE { get; set; } |
| | | /// <summary> |
| | | /// 状态(0NotInput未投入|1Inputed已投入|2Finished已完工) |
| | | /// 状态(0NotInput未投入|1Inputed已投入|2Finished已完工|3Scrap已报废) |
| | | /// </summary> |
| | | [DisplayName("状态(0NotInput未投入|1Inputed已投入|2Finished已完工)")] |
| | | [DisplayName("状态(0NotInput未投入|1Inputed已投入|2Finished已完工|3Scrap已报废)")] |
| | | public int STATUS { get; set; } |
| | | /// <summary> |
| | | /// 备注 |
| | |
| | | */ |
| | | |
| | | /// <summary> |
| | | /// 枚举:状态(0NotInput未投入|1Inputed已投入|2Finished已完工) |
| | | /// 枚举:状态(0NotInput未投入|1Inputed已投入|2Finished已完工|3Scrap已报废) |
| | | /// </summary> |
| | | public enum STATUSs |
| | | { |
| | |
| | | Inputed = 1, |
| | | [Description("已完工")] |
| | | Finished = 2, |
| | | [Description("已报废")] |
| | | Scrap = 3, |
| | | } |
| | | #endregion |
| | | |
| | |
| | | /// </summary> |
| | | public string SN { get; set; } |
| | | /// <summary> |
| | | /// 数量 |
| | | /// </summary> |
| | | public string Qty { get; set; } |
| | | /// <summary> |
| | | /// 当前操作提交的不良代码,没有则留空 |
| | | /// </summary> |
| | | public string DFT_CODE { get; set; } |
| | |
| | | /// 当前操作需要提交的数据 |
| | | /// </summary> |
| | | public string Data { get; set; } |
| | | /// <summary> |
| | | /// 数量 |
| | | /// </summary> |
| | | public string Qty { get; set; } |
| | | } |
| | | |
| | | public class SubmitOutput |
| | |
| | | { |
| | | public string NextNode { get; set; } = " — "; |
| | | public string CurNode { get; set; } = " — "; |
| | | public bool IsReachedEndNode { get; set; } = false; |
| | | public int InputQty { get; set; } = 0; |
| | | public List<WorkStepInfo> StepsInfo { get; set; } = new List<WorkStepInfo>(); |
| | | } |