| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | |
| | | using HH.WCS.Mobox3.DSZSH.Consts; |
| | | using HH.WCS.Mobox3.DSZSH.Helpers; |
| | | using HH.WCS.Mobox3.DSZSH.Helpers.Model; |
| | | using HH.WCS.Mobox3.DSZSH.Models; |
| | | |
| | | using Newtonsoft.Json; |
| | | |
| | | namespace HH.WCS.Mobox3.DSZSH.ServiceCore { |
| | | /// <summary> |
| | | /// 定时轮询任务:出库业务核心 |
| | | /// </summary> |
| | | public class OutboundCore { |
| | | /// <summary> |
| | | /// 后台轮询出库单/出库明细单,生成出库任务表 |
| | | /// </summary> |
| | | public static void CheckOutboundOrder() { |
| | | public static void CheckOrderState() { |
| | | var db = DbHelper.GetDbClient(); |
| | | |
| | | try { |
| | | // 查找所有的 等待出库 的 出库单,按 先创建先处理 排序 |
| | | var orders = db.Queryable<TN_Outbound_Order>() |
| | | .Where(o => o.N_B_STATE == 0) |
| | | .OrderBy(o => o.T_CREATE) |
| | | .Mapper( |
| | | o => o.Details, // 将子表数据映射到主表的 Details 属性 |
| | | o => o.S_NO, // 主表关联字段 |
| | | d => d.S_NO // 子表关联字段 |
| | | ) |
| | | .ToList(); |
| | | var order = db.Queryable<TN_Outbound_Order>() |
| | | .Where(c => c.N_B_STATE == SpotStateCode.已执行待生成任务) |
| | | .OrderBy(c => c.T_CREATE, SqlSugar.OrderByType.Asc).First(); |
| | | |
| | | if (orders.Count == 0) { |
| | | LogHelper.Info("轮询 | 当前没有等待执行的出库单"); |
| | | if (order == null) { |
| | | LogHelper.Info("轮询--出库--暂无待执行的Order"); |
| | | return; |
| | | } |
| | | |
| | | var lastDetail = db.Queryable<TN_Outbound_Detail>() |
| | | .First(d => d.S_OO_NO == order.S_NO && d.N_B_STATE == SpotStateCode.任务执行中); |
| | | |
| | | if (lastDetail != null) { |
| | | LogHelper.Info($"轮询--出库--上一个任务仍在进行中:" + JsonConvert.SerializeObject(lastDetail)); |
| | | return; |
| | | } |
| | | |
| | | var detail = db.Queryable<TN_Outbound_Detail>() |
| | | .Where(d => d.S_OO_NO == order.S_NO && d.N_B_STATE == SpotStateCode.已执行待生成任务) |
| | | .OrderBy(d => d.T_CREATE, SqlSugar.OrderByType.Asc).First(); |
| | | |
| | | if (detail == null) { |
| | | //order.N_B_STATE = SpotStateCode.任务执行中; |
| | | |
| | | LogHelper.Info($"轮询--出库--当前Order '{order.S_NO}' 暂无待执行的任务"); |
| | | return; |
| | | } |
| | | |
| | | var startLocCntrRel = db.Queryable<TN_Loc_Container>() |
| | | .Where(c => c.S_CNTR_CODE == detail.S_CNTR_CODE) |
| | | .First(); |
| | | |
| | | if (startLocCntrRel == null) { |
| | | LogHelper.Info($"轮询--出库:没有找到合适的起点货位!"); |
| | | return; |
| | | } |
| | | |
| | | var endLoc = db.Queryable<TN_Location>() |
| | | .Where(l => l.S_AREA_CODE == detail.S_END_AREA) |
| | | .Where(ExprHelper.LocIsFree) |
| | | .Where(ExprHelper.LocIsEmpty).First(); |
| | | |
| | | if (endLoc == null) { |
| | | LogHelper.Info($"轮询--出库:没有找到合适的终点货位!S_NO为 '{detail.S_OO_NO}',要求Area为 '{detail.S_END_AREA}'"); |
| | | return; |
| | | } |
| | | |
| | | using (var tran = db.Ado.UseTran()) { |
| | | detail.N_B_STATE = SpotStateCode.任务执行中; |
| | | if (db.Updateable<TN_Outbound_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) { |
| | | tran.RollbackTran(); |
| | | LogHelper.Info($"轮询--出库--修改明细表状态为完成失败!"); |
| | | } |
| | | |
| | | foreach (var o in orders) { |
| | | foreach (var d in o.Details) { |
| | | for (int i = 0; i < d.N_QTY; i++) { |
| | | var task = new TN_Outbound_Task { |
| | | S_CG_ID = d.S_CG_ID, |
| | | S_END_AREA = d.S_END_AREA, |
| | | N_FORCE = o.N_FORCE, |
| | | S_BATCH_NO = d.S_BATCH_NO, |
| | | N_STATE = 0 |
| | | }; |
| | | if (db.Insertable<TN_Outbound_Task>(task).ExecuteCommand() <= 0) { |
| | | tran.RollbackTran(); |
| | | LogHelper.Info("插入任务出错"); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | d.N_B_STATE = 1; |
| | | if (db.Updateable<TN_Outbound_Detail>(d).UpdateColumns(c => c.N_B_STATE).ExecuteCommand() > 0) { |
| | | LogHelper.Info("更新 N_B_STATE 成功"); |
| | | } |
| | | else { |
| | | tran.RollbackTran(); |
| | | |
| | | LogHelper.Info("更新 N_B_STATE 失败"); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | o.N_B_STATE = 1; |
| | | if (db.Updateable<TN_Outbound_Order>(o).UpdateColumns(c => c.N_B_STATE).ExecuteCommand() > 0) { |
| | | LogHelper.Info("更新 N_B_STATE 成功"); |
| | | } |
| | | else { |
| | | tran.RollbackTran(); |
| | | |
| | | LogHelper.Info("更新 N_B_STATE 失败"); |
| | | return; |
| | | } |
| | | if (!TaskHelper.LogCreateTask(startLocCntrRel.S_LOC_CODE, startLocCntrRel.S_CNTR_CODE, |
| | | endLoc.S_CODE, TaskName.成品胶出库)) { |
| | | tran.RollbackTran(); |
| | | } |
| | | |
| | | tran.CommitTran(); |
| | |
| | | } |
| | | catch (Exception ex) { |
| | | LogHelper.InfoEx(ex); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 轮询出库 |
| | | /// </summary> |
| | | public static void CheckOutboundTask() { |
| | | public static void UpdateTaskState(int spotStateCode) { |
| | | |
| | | var db = DbHelper.GetDbClient(); |
| | | |
| | | try { |
| | | var task = db.Queryable<TN_Outbound_Task>() |
| | | .Where(t => t.N_STATE == 0).First(); |
| | | var detail = db.Queryable<TN_Outbound_Detail>() |
| | | .First(d => d.N_B_STATE == SpotStateCode.任务执行中); |
| | | |
| | | if (task == null) { |
| | | LogHelper.Info("轮询 | 出库任务队列 暂无待执行的任务"); |
| | | if (detail == null) { |
| | | LogHelper.Info("出库--AGV取货--查询Detail:当前没有 执行中 的Detail表!"); |
| | | return; |
| | | } |
| | | |
| | | using (var tran = db.Ado.UseTran()) { |
| | | detail.N_B_STATE = spotStateCode; |
| | | if (db.Updateable<TN_Outbound_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) { |
| | | tran.RollbackTran(); |
| | | LogHelper.Info("出库--AGV取货:修改Detail状态 N_B_STATE 为 3任务执行完成 失败!"); |
| | | return; |
| | | } |
| | | |
| | | var headTask = task; |
| | | if (headTask.N_STATE != 0) { |
| | | LogHelper.Info("轮询 | 出库任务队列 队头任务尚未完成"); |
| | | return; |
| | | } |
| | | var finishedCount = db.Queryable<TN_Outbound_Detail>().Count(d => d.S_OO_NO == detail.S_OO_NO && d.N_B_STATE == 3); |
| | | var allCount = db.Queryable<TN_Outbound_Detail>().Count(d => d.S_OO_NO == detail.S_OO_NO); |
| | | |
| | | var locCntr = db.Queryable<TN_Location, TN_Loc_Container, TN_CG_Detail> |
| | | ((l, c, d) => l.S_CODE == c.S_LOC_CODE && c.S_CNTR_CODE == d.S_CNTR_CODE) |
| | | // 筛选要求的物料编码和批次号 |
| | | .Where((l, c, d) => d.S_CG_ID == headTask.S_CG_ID && d.S_BATCH_NO == headTask.S_BATCH_NO) |
| | | // 如果不是强制出库,物料状态必须必须合格 |
| | | // 否则,只要不是正在检验的物料即可 |
| | | .Where((l, c, d) => (headTask.N_FORCE == 0 && d.N_ITEM_STATE == 0 && d.S_ITEM_STATE == "合格") |
| | | || (headTask.N_FORCE != 0 && d.N_ITEM_STATE != 3 && d.S_ITEM_STATE != "正在检验")) |
| | | // 物料状态对应的数字,越小越优先 |
| | | .OrderBy((l, c, d) => d.N_ITEM_STATE) |
| | | .OrderBy(l => l.N_LAYER) |
| | | .Select((l, c) => new { Location = l, Container = c }).First(); |
| | | |
| | | if (locCntr == null) { |
| | | LogHelper.Info("轮询 | 不存在符合条件的物料货位"); |
| | | return; |
| | | } |
| | | LogHelper.Info($"出库--AGV取货--统计任务已完成:{finishedCount} / {allCount}"); |
| | | |
| | | var endLoc = db.Queryable<TN_Location>() |
| | | .Where(l => l.S_AREA_CODE == headTask.S_END_AREA) |
| | | .Where(ExprHelper.LocIsFree) |
| | | .Where(ExprHelper.LocIsEmpty) |
| | | .OrderBy(l => l.S_CODE) |
| | | .First(); |
| | | if (finishedCount == allCount) { // 当前出库单下的所有明细单,任务都已经完成 |
| | | |
| | | if (endLoc == null) { |
| | | LogHelper.Info("轮询 | 不存在符合条件的出库终点库位"); |
| | | return; |
| | | } |
| | | if (db.Updateable<TN_Outbound_Order>().SetColumns(it => it.N_B_STATE == SpotStateCode.任务执行完成) |
| | | .Where(it => it.S_NO == detail.S_OO_NO) |
| | | .ExecuteCommand() <= 0) { |
| | | |
| | | using (var tran = db.Ado.UseTran()) { |
| | | if (TaskHelper.LogCreateTask(locCntr.Location.S_CODE, locCntr.Container.S_CNTR_CODE, endLoc.S_CODE, TaskName.成品胶出库)) { |
| | | task.N_STATE = 1; |
| | | if (db.Updateable<TN_Outbound_Task>(task).UpdateColumns(c => c.N_STATE).ExecuteCommand() <= 0) { |
| | | tran.RollbackTran(); |
| | | LogHelper.Info("修改出库任务状态错误"); |
| | | } |
| | | else { |
| | | tran.CommitTran(); |
| | | LogHelper.Info("修改出库任务状态成功"); |
| | | } |
| | | tran.RollbackTran(); |
| | | LogHelper.Info("出库--AGV取货--所有任务完成时:修改Order状态 N_B_STATE 为 3任务执行完成 失败!"); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) { |
| | | LogHelper.InfoEx(ex); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// |
| | | /// </summary> |
| | | /// <param name="state"></param> |
| | | public static void UpdateTaskState(int state = 2) { |
| | | |
| | | tran.CommitTran(); |
| | | } |
| | | } |
| | | |
| | | } |