pengmn
2025-06-24 51141e4955e3021058664bea526f16b368738b3a
HH.WCS.Mobox3.HangYang/wms/WMSHelper.cs
@@ -235,7 +235,7 @@
            return db.Updateable<WMSTask>(a).UpdateColumns(it => new { it.S_END_LOC, it.T_MODIFY }).ExecuteCommand() > 0;
        }
        internal static void CreateSortingOrderDetail(string so_no)
@@ -544,6 +544,50 @@
        #region 杭氧WMS帮助方法
        /// <summary>
        /// 新增物料主数据
        /// </summary>
        /// <param name="materials"></param>
        /// <returns></returns>
        internal static bool CreateMaterialData(List<TN_Material> materials)
        {
            try
            {
                bool res = false;
                var db = new SqlHelper<object>().GetInstance();
                db.BeginTran();
                foreach (var material in materials)
                {
                    var _Material = db.Queryable<TN_Material>().Where(c => c.S_ITEM_CODE == material.S_ITEM_CODE).First();
                    if (_Material != null)
                    {
                        db.Updateable<TN_Material>(material).UpdateColumns(a => new { a.S_ITEM_NAME, a.S_ITEM_TYPE, a.S_ITEM_SPEC, a.S_MATERIAL, a.S_UOM, a.C_CLEAN, a.T_MODIFY }).ExecuteCommand();
                    }
                    else
                    {
                        db.Insertable(material).ExecuteCommand();
                    }
                }
                db.CommitTran();
                res = true;
                return res;
            }
            catch (Exception ex)
            {
                var sugarEx = ex as SqlSugar.SqlSugarException;
                if (sugarEx != null)
                {
                    LogHelper.Error($"创建入库单SQL错误: {sugarEx.Sql}", sugarEx, "杭氧");
                }
                else
                {
                    LogHelper.Error($"创建入库单失败:{ex.Message}", ex, "杭氧");
                }
                return false;
            }
        }
        /// <summary>
        /// 新增入库单
        /// </summary>
        /// <param name="order"></param>
@@ -557,8 +601,24 @@
                db.BeginTran();
                foreach (var orderItem in order)
                {
                    db.Insertable(orderItem).ExecuteCommand();
                    db.Insertable(orderItem.InOrderDetail).ExecuteCommand();
                    var _order = db.Queryable<InOrder>().Where(c => c.S_NO == orderItem.S_NO).First();
                    if (_order != null)
                    {
                        if (_order.N_B_STATE == 0)
                        {
                            db.Updateable<InOrder>(orderItem).UpdateColumns(a => new { a.S_OP_TYPE, a.S_BS_TYPE, a.S_NOTE, a.T_MODIFY }).ExecuteCommand();
                            foreach (var item in orderItem.InOrderDetail)
                            {
                                db.Updateable<InOrderDetail>(item).UpdateColumns(a => new { a.S_ITEM_CODE, a.S_ITEM_NAME, a.F_QTY }).ExecuteCommand();
                            }
                        }
                    }
                    else
                    {
                        db.Insertable(orderItem).ExecuteCommand();
                        db.Insertable(orderItem.InOrderDetail).ExecuteCommand();
                    }
                }
                db.CommitTran();
                res = true;
@@ -594,8 +654,26 @@
                db.BeginTran();
                foreach (var orderItem in order)
                {
                    db.Insertable(orderItem).ExecuteCommand();
                    db.Insertable(orderItem.OutOrderDetail).ExecuteCommand();
                    var _order = db.Queryable<OutOrder>().Where(c => c.S_NO == orderItem.S_NO).First();
                    if (_order != null)
                    {
                        if (_order.N_B_STATE == 0)
                        {
                            db.Updateable<OutOrder>(orderItem).UpdateColumns(a => new { a.S_OP_TYPE, a.S_BS_TYPE, a.S_NOTE, a.T_MODIFY }).ExecuteCommand();
                            foreach (var item in orderItem.OutOrderDetail)
                            {
                                db.Updateable<InOrderDetail>(item).UpdateColumns(a => new { a.S_ITEM_CODE, a.S_ITEM_NAME, a.F_QTY }).ExecuteCommand();
                            }
                        }
                    }
                    else
                    {
                        db.Insertable(orderItem).ExecuteCommand();
                        db.Insertable(orderItem.OutOrderDetail).ExecuteCommand();
                    }
                }
                db.CommitTran();
                res = true;
@@ -608,6 +686,105 @@
            }
        }
        /// <summary>
        /// 入库单取消
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        internal static bool CancelOrderIn(InOrder order)
        {
            try
            {
                bool res = false;
                var db = new SqlHelper<object>().GetInstance();
                db.BeginTran();
                var _order = db.Queryable<InOrder>().Where(c => c.S_NO == order.S_NO).First();
                if (_order != null)
                {
                    if (_order.N_B_STATE == 0)
                    {
                        foreach (var item in order.OrderDetail)
                        {
                            db.Deleteable<InOrderDetail>().Where(it => it.S_ITEM_CODE.Trim() == item.S_ITEM_CODE && it.S_BS_NO == order.S_BS_NO).ExecuteCommand();
                        }
                    }
                }
                var _orderItem = db.Queryable<InOrderDetail>().Where(c => c.S_BS_NO == order.S_BS_NO).First();
                if (_orderItem == null)
                {
                    db.Deleteable<InOrder>().Where(it => it.S_BS_NO == order.S_BS_NO).ExecuteCommand();
                }
                db.CommitTran();
                res = true;
                return res;
            }
            catch (Exception ex)
            {
                var sugarEx = ex as SqlSugar.SqlSugarException;
                if (sugarEx != null)
                {
                    LogHelper.Error($"取消入库单SQL错误: {sugarEx.Sql}", sugarEx, "杭氧");
                }
                else
                {
                    LogHelper.Error($"取消入库单失败:{ex.Message}", ex, "杭氧");
                }
                return false;
            }
        }
        /// <summary>
        /// 出库单取消
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        internal static bool CancelOrderOut(OutOrder order)
        {
            try
            {
                bool res = false;
                var db = new SqlHelper<object>().GetInstance();
                db.BeginTran();
                var _order = db.Queryable<OutOrder>().Where(c => c.S_NO == order.S_NO).First();
                if (_order != null)
                {
                    if (_order.N_B_STATE == 0)
                    {
                        foreach (var item in order.OrderDetail)
                        {
                            db.Deleteable<OutOrderDetail>().Where(it => it.S_ITEM_CODE.Trim() == item.S_ITEM_CODE && it.S_BS_NO == order.S_BS_NO).ExecuteCommand();
                        }
                    }
                }
                var _orderItem = db.Queryable<OutOrderDetail>().Where(c => c.S_BS_NO == order.S_BS_NO).First();
                if (_orderItem == null)
                {
                    db.Deleteable<OutOrder>().Where(it => it.S_BS_NO == order.S_BS_NO).ExecuteCommand();
                }
                db.CommitTran();
                res = true;
                return res;
            }
            catch (Exception ex)
            {
                var sugarEx = ex as SqlSugar.SqlSugarException;
                if (sugarEx != null)
                {
                    LogHelper.Error($"取消出库单SQL错误: {sugarEx.Sql}", sugarEx, "杭氧");
                }
                else
                {
                    LogHelper.Error($"取消出库单失败:{ex.Message}", ex, "杭氧");
                }
                return false;
            }
        }
        #endregion
        #region 杭氧特殊帮助方法
@@ -1064,16 +1241,17 @@
                // 阶段1: 标记未来需要保留的货位
                MarkReservedLocations(outbound);
                var tasks = new List<WCSTask>();
                var outboundLocCodes = outbound.Select(o => o.locCode).ToHashSet();
                foreach (var outboundItem in outbound)
                {
                    // 1. 查找目标货位
                    var targetLoc = FindTargetLocation(outboundItem.locCode);
                    if (targetLoc == null) continue;
                    var wmsTask = WMSHelper.GetWmsTaskList("执行", outboundItem.trayCode);
                    if (wmsTask == null)
                    if (wmsTask != null)
                    {
                        //LogHelper.Info($"未查询到在执行中的作业:{outboundItem.trayCode}!", "杭氧");
                        outboundItem.opCode = "";
                        outboundItem.opCode = wmsTask.S_CODE;
                    }
                    // 2. 处理双深位逻辑(第1排或第4排)
@@ -1087,36 +1265,46 @@
                            //如果货位已满,则生成移库任务
                            if (outerLoc.N_CURRENT_NUM == outerLoc.N_CAPACITY)
                            {
                                // 优先移到深位,其次外侧
                                var bestTarget = FindBestRelocationTarget(outerLoc);
                                if (bestTarget != null)
                                if (outboundLocCodes.Contains(outerLoc.S_CODE))
                                {
                                    //计算到了外侧把外侧的货位锁定
                                    _allLocations
                                .Where(x => x.S_CODE == outerLoc.S_CODE)
                                .ToList()
                                .ForEach(x => x.N_LOCK_STATE = 3);
                                    var trayCode = ContainerHelper.GetLocCntr(outerLoc.S_CODE);
                                    tasks.Add(new WCSTask
                                    {
                                        S_CODE = GenerateTaskNo(),
                                        S_START_AREA = outerLoc.S_AREA_CODE,
                                        S_END_AREA = bestTarget.S_AREA_CODE,
                                        S_START_LOC = outerLoc.S_CODE,
                                        S_END_LOC = bestTarget.S_CODE,
                                        S_TYPE = "深位移库",
                                        S_OP_CODE = wmsTask.S_CODE,
                                        N_PRIORITY = 1,
                                        N_SCHEDULE_TYPE = 1,
                                        N_B_STATE = 0,
                                        S_B_STATE = WCSTask.GetStateStr(0),
                                        S_CNTR_CODE = trayCode.S_CNTR_CODE,
                                        N_START_LAYER = 1,
                                        N_END_LAYER = 1,
                                        N_CNTR_COUNT = 1
                                    });
                                    // 方案1:合并任务(直接出库外侧货位)
                                    tasks.Add(CreateOutboundTask(outerLoc,
                                        outbound.First(o => o.locCode == outerLoc.S_CODE), "1"));
                                }
                                else continue;
                                else
                                {
                                    // 优先移到深位,其次外侧
                                    var bestTarget = FindBestRelocationTarget(outerLoc);
                                    if (bestTarget != null)
                                    {
                                        //计算到了外侧把外侧的货位锁定
                                        _allLocations
                                        .Where(x => x.S_CODE == outerLoc.S_CODE)
                                        .ToList()
                                        .ForEach(x => x.N_LOCK_STATE = 3);
                                        var trayCode = ContainerHelper.GetLocCntr(outerLoc.S_CODE);
                                        tasks.Add(new WCSTask
                                        {
                                            S_CODE = GenerateTaskNo(),
                                            S_START_AREA = outerLoc.S_AREA_CODE,
                                            S_END_AREA = bestTarget.S_AREA_CODE,
                                            S_START_LOC = outerLoc.S_CODE,
                                            S_END_LOC = bestTarget.S_CODE,
                                            S_TYPE = "深位移库",
                                            S_OP_CODE = outboundItem.opCode,
                                            N_PRIORITY = 1,
                                            N_SCHEDULE_TYPE = 1,
                                            N_B_STATE = 0,
                                            S_B_STATE = WCSTask.GetStateStr(0),
                                            S_CNTR_CODE = trayCode.S_CNTR_CODE,
                                            N_START_LAYER = 1,
                                            N_END_LAYER = 1,
                                            N_CNTR_COUNT = 1
                                        });
                                    }
                                    else continue;
                                }
                            }
                        }
                        else
@@ -1168,7 +1356,7 @@
                      .FirstOrDefault();
            }
            private WCSTask CreateOutboundTask(Location loc, Outbound outbound) =>
            private WCSTask CreateOutboundTask(Location loc, Outbound outbound, string priority = "") =>
                new WCSTask
                {
                    S_CODE = GenerateTaskNo(),
@@ -1178,7 +1366,7 @@
                    S_END_LOC = outbound.endBit,
                    S_TYPE = outbound.taskType,
                    S_OP_CODE = outbound.opCode,
                    N_PRIORITY = 0,
                    N_PRIORITY = string.IsNullOrEmpty(priority) ? 0 : int.Parse(priority),
                    N_SCHEDULE_TYPE = 1,
                    N_B_STATE = 0,
                    S_B_STATE = WCSTask.GetStateStr(0),
@@ -1228,6 +1416,9 @@
            }
        }
        /// <summary>
        /// 空托出库封装算法
        /// </summary>
        public class EmptyPalletOutboundScheduler
        {
            private readonly List<Location> _allLocations;