| | |
| | | using Swashbuckle.Swagger; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Diagnostics; |
| | | using System.Linq; |
| | | using System.Reflection; |
| | | using System.Security.Cryptography; |
| | |
| | | /// <summary> |
| | | /// 根据配盘单生成出库任务 |
| | | /// </summary> |
| | | /// <param name="distributionCntr">配盘单</param> |
| | | /// <param name="distributionCntrs">配盘单</param> |
| | | /// <returns></returns> |
| | | internal static bool GenerateFromPicking(List<DistributionCntr> distributionCntr) |
| | | internal static bool GenerateFromPicking(List<DistributionCntr> distributionCntrs) |
| | | { |
| | | try |
| | | { |
| | | // 创建调度器 |
| | | var scheduler = new DoubleDeepOutboundScheduler(distributionCntr); |
| | | // 1. 初始化调度器和出库任务列表 |
| | | var scheduler = new DoubleDeepOutboundScheduler(distributionCntrs); |
| | | var outboundTasks = CreateOutboundTasks(distributionCntrs); |
| | | |
| | | var listOut = new List<Outbound>(); |
| | | foreach (var item in distributionCntr) |
| | | { |
| | | listOut.Add(new Outbound |
| | | { |
| | | locCode = item.S_LOC_CODE, |
| | | areaCode = item.S_AREA_CODE, |
| | | endArea = item.S_EXIT_AREA_CODE, |
| | | endBit = item.S_EXIT_LOC_CODE, |
| | | trayCode = item.S_CNTR_CODE, |
| | | taskType = "配盘出库" |
| | | }); |
| | | } |
| | | // 请求出库 |
| | | var tasks = scheduler.GenerateOutboundTasks(listOut); |
| | | // 2. 计算货位生成任务数据 |
| | | var tasks = scheduler.GenerateOutboundTasks(outboundTasks); |
| | | if (!tasks.Any()) return false; |
| | | |
| | | foreach (var item in tasks) |
| | | { |
| | | var wmsTask = new WMSTask(); |
| | | if (string.IsNullOrEmpty(item.S_OP_CODE)) |
| | | { |
| | | wmsTask = new WMSTask |
| | | { |
| | | S_CNTR_CODE = item.S_CNTR_CODE, |
| | | S_CODE = WMSHelper.GenerateTaskNo(), |
| | | S_START_LOC = item.S_START_LOC, |
| | | S_START_AREA = item.S_START_AREA, |
| | | S_END_LOC = item.S_END_LOC, |
| | | S_END_AREA = item.S_END_AREA, |
| | | S_START_WH = "CK001", |
| | | S_END_WH = "CK001", |
| | | N_B_STATE = 1, |
| | | S_B_STATE = "执行", |
| | | N_TYPE = 2, |
| | | S_TYPE = "配盘出库" |
| | | }; |
| | | if (!WMSHelper.CreateWmsTask(wmsTask)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | // 3. 创建WMS作业 |
| | | var mainTask = CreateMainWmsTask(tasks.Where(s=>s.S_TYPE == "配盘出库").First()); |
| | | if (!WMSHelper.CreateWmsTask(mainTask)) return false; |
| | | |
| | | if (item.S_END_AREA == "LXLKQ") |
| | | { |
| | | // 创建出库任务 |
| | | var res = TaskProcess.HYCreateTransport(item.S_START_LOC, item.S_END_LOC, item.S_TYPE, item.S_CNTR_CODE, wmsTask.S_CODE); |
| | | UpdateDistributionCntrState(1, 2, item.S_CNTR_CODE); |
| | | if (!res) |
| | | { |
| | | LogHelper.Info($"根据配盘单生成出库任务创建出库任务失败!!"); |
| | | return false; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //根据分拣货位去查询配置,如果分拣区没有空货位就去出库分拣暂存区 |
| | | var relevancys = Settings.OutRelevancys.Where(s => s.conLoc == item.S_END_LOC).FirstOrDefault(); |
| | | if (relevancys == null) |
| | | { |
| | | LogHelper.Info($"Settings未查询到集货位{item.S_END_LOC}对应的分拣位!", "杭氧"); |
| | | break; |
| | | } |
| | | var locList = LocationHelper.GetLocListEmptyFree(relevancys.sorLoc.ToList()); |
| | | if (locList.Any()) |
| | | { |
| | | // 创建出库任务 |
| | | var res = TaskProcess.HYCreateTransport(item.S_START_LOC, locList.FirstOrDefault().S_CODE, item.S_TYPE, item.S_CNTR_CODE, wmsTask.S_CODE); |
| | | UpdateDistributionCntrState(1, 2, item.S_CNTR_CODE); |
| | | if (!res) |
| | | { |
| | | LogHelper.Info($"根据配盘单生成出库任务创建出库任务失败!!"); |
| | | return false; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | var reservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "拣选缓存区").FirstOrDefault(); |
| | | var lxLocations = LocationHelper.GetLocAreaList(reservoirs.areaCode); |
| | | if (lxLocations.Any()) |
| | | { |
| | | // 创建出库任务 |
| | | var res = TaskProcess.HYCreateTransport(item.S_START_LOC, lxLocations.FirstOrDefault().S_CODE, "配盘缓存", item.S_CNTR_CODE, wmsTask.S_CODE); |
| | | UpdateDistributionCntrState(1, 2, item.S_CNTR_CODE); |
| | | if (!res) |
| | | { |
| | | LogHelper.Info($"根据配盘单生成出库任务创建出库任务失败!!"); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return true; |
| | | // 4. 生成WMS主任务 |
| | | return ProcessAllTransportTasks(tasks, mainTask.S_CODE); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | var st = new System.Diagnostics.StackTrace(ex, true); |
| | | var frame = st.GetFrame(0); // 获取第一个堆栈帧 |
| | | if (frame != null) |
| | | LogErrorWithStackTrace("根据配盘单生成出库任务失败", ex); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // --------------------- 辅助方法 --------------------- |
| | | |
| | | private static List<Outbound> CreateOutboundTasks(List<DistributionCntr> distributionCntrs) |
| | | { |
| | | return distributionCntrs.Select(item => new Outbound |
| | | { |
| | | locCode = item.S_LOC_CODE, |
| | | areaCode = item.S_AREA_CODE, |
| | | endArea = item.S_EXIT_AREA_CODE, |
| | | endBit = item.S_EXIT_LOC_CODE, |
| | | trayCode = item.S_CNTR_CODE, |
| | | taskType = "配盘出库" |
| | | }).ToList(); |
| | | } |
| | | |
| | | private static WMSTask CreateMainWmsTask(WCSTask firstTask) |
| | | { |
| | | return new WMSTask |
| | | { |
| | | S_CNTR_CODE = firstTask.S_CNTR_CODE, |
| | | S_CODE = WMSHelper.GenerateTaskNo(), |
| | | S_START_LOC = firstTask.S_START_LOC, |
| | | S_START_AREA = firstTask.S_START_AREA, |
| | | S_END_LOC = firstTask.S_END_LOC, |
| | | S_END_AREA = firstTask.S_END_AREA, |
| | | S_START_WH = "CK001", |
| | | S_END_WH = "CK001", |
| | | N_B_STATE = 1, |
| | | S_B_STATE = "执行", |
| | | N_TYPE = 2, |
| | | S_TYPE = "配盘出库" |
| | | }; |
| | | } |
| | | |
| | | private static bool ProcessAllTransportTasks(List<WCSTask> tasks, string wmsTaskCode) |
| | | { |
| | | foreach (var task in tasks.OrderBy(t => t.N_PRIORITY)) |
| | | { |
| | | if (IsLxLkqOrRelocationTask(task)) |
| | | { |
| | | LogHelper.Error($"根据配盘单生成出库任务失败{ex.Message}!!", ex); |
| | | LogHelper.Error($"文件名: {frame.GetFileName()}", ex); |
| | | LogHelper.Error($"行号: {frame.GetFileLineNumber()}", ex); |
| | | LogHelper.Error($"列号: {frame.GetFileColumnNumber()}", ex); |
| | | if (!ProcessLxLkqTransportTask(task, wmsTaskCode)) |
| | | return false; |
| | | } |
| | | else |
| | | { |
| | | if (!ProcessNormalTransportTask(task, wmsTaskCode)) |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | private static bool IsLxLkqOrRelocationTask(WCSTask task) |
| | | { |
| | | return task.S_START_AREA == "LXLKQ" || task.S_TYPE == "深位移库"; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 生成LXLKQ || 深位移库的配盘任务 |
| | | /// </summary> |
| | | /// <param name="task"></param> |
| | | /// <param name="wmsTaskCode"></param> |
| | | /// <returns></returns> |
| | | private static bool ProcessLxLkqTransportTask(WCSTask task, string wmsTaskCode) |
| | | { |
| | | bool success = false; |
| | | if (task.S_TYPE == "深位移库") |
| | | { |
| | | success = TaskProcess.HYCreateTransport( |
| | | task.S_START_LOC, |
| | | task.S_END_LOC, |
| | | task.S_TYPE, |
| | | task.S_CNTR_CODE, |
| | | wmsTaskCode, |
| | | task.N_PRIORITY); |
| | | return success; |
| | | } |
| | | var relevancy = Settings.OutRelevancys.FirstOrDefault(s => s.conLoc == task.S_END_LOC); |
| | | if (relevancy == null) |
| | | { |
| | | LogHelper.Info($"Settings未查询到集货位{task.S_END_LOC}对应的分拣位!", "杭氧"); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // 尝试使用分拣位 |
| | | var emptyLoc = LocationHelper.GetLocListEmptyFree(relevancy.sorLoc.ToList()).FirstOrDefault(); |
| | | if (emptyLoc != null) |
| | | { |
| | | success = TaskProcess.HYCreateTransport( |
| | | task.S_START_LOC, |
| | | emptyLoc.S_CODE, |
| | | task.S_TYPE, |
| | | task.S_CNTR_CODE, |
| | | wmsTaskCode, |
| | | task.N_PRIORITY); |
| | | if (success && task.S_TYPE != "深位移库") |
| | | { |
| | | UpdateDistributionCntrState(1, 2, task.S_CNTR_CODE); |
| | | } |
| | | } |
| | | return success; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 生成TPLKQ的配盘任务 |
| | | /// </summary> |
| | | /// <param name="task"></param> |
| | | /// <param name="wmsTaskCode"></param> |
| | | /// <returns></returns> |
| | | private static bool ProcessNormalTransportTask(WCSTask task, string wmsTaskCode) |
| | | { |
| | | var relevancy = Settings.OutRelevancys.FirstOrDefault(s => s.conLoc == task.S_END_LOC); |
| | | if (relevancy == null) |
| | | { |
| | | LogHelper.Info($"Settings未查询到集货位{task.S_END_LOC}对应的分拣位!", "杭氧"); |
| | | return false; |
| | | } |
| | | |
| | | // 尝试使用分拣位 |
| | | var emptyLoc = LocationHelper.GetLocListEmptyFree(relevancy.sorLoc.ToList()).FirstOrDefault(); |
| | | if (emptyLoc != null) |
| | | { |
| | | return CreateAndLogTransport( |
| | | task.S_START_LOC, |
| | | emptyLoc.S_CODE, |
| | | task.S_TYPE, |
| | | task.S_CNTR_CODE, |
| | | wmsTaskCode, |
| | | task.N_PRIORITY); |
| | | } |
| | | |
| | | // 尝试使用拣选缓存区 |
| | | var reservoir = Settings.ReservoirAreas.FirstOrDefault(s => s.areaName == "拣选缓存区"); |
| | | if (reservoir == null) return false; |
| | | |
| | | var lxLocation = LocationHelper.GetLocAreaList(reservoir.areaCode).FirstOrDefault(); |
| | | if (lxLocation == null) return false; |
| | | |
| | | return CreateAndLogTransport( |
| | | task.S_START_LOC, |
| | | lxLocation.S_CODE, |
| | | "配盘缓存", |
| | | task.S_CNTR_CODE, |
| | | wmsTaskCode, |
| | | task.N_PRIORITY); |
| | | } |
| | | |
| | | private static bool CreateAndLogTransport(string startLoc, string endLoc, string taskType, |
| | | string cntrCode, string wmsTaskCode, int priority) |
| | | { |
| | | var success = TaskProcess.HYCreateTransport( |
| | | startLoc, endLoc, taskType, cntrCode, wmsTaskCode, priority); |
| | | |
| | | if (success) |
| | | { |
| | | UpdateDistributionCntrState(1, 2, cntrCode); |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info("根据配盘单生成出库任务创建出库任务失败!!"); |
| | | } |
| | | |
| | | return success; |
| | | } |
| | | |
| | | private static void LogErrorWithStackTrace(string message, Exception ex) |
| | | { |
| | | var st = new StackTrace(ex, true); |
| | | var frame = st.GetFrame(0); |
| | | if (frame == null) return; |
| | | |
| | | LogHelper.Error($"{message}{ex.Message}!!", ex); |
| | | LogHelper.Error($"文件名: {frame.GetFileName()}", ex); |
| | | LogHelper.Error($"行号: {frame.GetFileLineNumber()}", ex); |
| | | LogHelper.Error($"列号: {frame.GetFileColumnNumber()}", ex); |
| | | } |
| | | |
| | | #endregion |