| | |
| | | using HH.WCS.Mobox3.NFLZ.core; |
| | | using HH.WCS.Mobox3.NFLZ.device; |
| | | using HH.WCS.Mobox3.NFLZ.dispatch; |
| | | using HH.WCS.Mobox3.NFLZ.models; |
| | | using HH.WCS.Mobox3.NFLZ.util; |
| | | using HH.WCS.Mobox3.NFLZ.wms; |
| | | using Newtonsoft.Json; |
| | | using Newtonsoft.Json.Linq; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Security.Cryptography; |
| | | using System.Xml.Linq; |
| | | using static HH.WCS.Mobox3.NFLZ.api.OtherModel; |
| | | using static HH.WCS.Mobox3.NFLZ.dispatch.NDCApi; |
| | | using static HH.WCS.Mobox3.NFLZ.wms.WMSHelper.AddChangeModel; |
| | | |
| | | namespace HH.WCS.Mobox3.NFLZ.process |
| | | { |
| | | internal class TaskProcess |
| | | { |
| | | private static HttpHelper httpHelper = new HttpHelper(); |
| | | #region 任务相关 |
| | | //--------------------------------------------------任务相关-------------------------------------------------- |
| | | /// <summary> |
| | |
| | | { |
| | | Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}"); |
| | | LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}"); |
| | | LocationHelper.UnBindingLoc(mst.S_START_LOC, mst.S_CNTR_CODE.Split(',').ToList()); |
| | | LocationHelper.UnBindingLoc(mst.S_START_LOC, mst.S_CNTR_CODE.Split(',').ToList(),mst.S_TYPE); |
| | | } |
| | | else |
| | | { |
| | | Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); |
| | | LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); |
| | | LocationHelper.BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList()); |
| | | LocationHelper.BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList(),mst.S_TYPE); |
| | | } |
| | | |
| | | } |
| | |
| | | /// <param name="extData"></param> |
| | | internal static void OperateReq(string no, int state, string forkliftNo, string extData) |
| | | { |
| | | if (state == 1101) |
| | | LogHelper.Info($"收到安全请求信号:{state},任务号:{no}"); |
| | | var mst = WCSHelper.GetTask(no); |
| | | if (mst != null) |
| | | { |
| | | //请求取货, |
| | | if (state == 1101) |
| | | { |
| | | //取货请求,允许进入取货,修改参数18为1101 |
| | | DeviceProcess.quliao(mst); |
| | | } |
| | | if (state == 1103) |
| | | { |
| | | DeviceProcess.Xieliao(mst); |
| | | } |
| | | if (state == 1102 || state == 1104) |
| | | { |
| | | sendSing(mst, state); |
| | | } |
| | | } |
| | | if (state == 1102) |
| | | } |
| | | |
| | | internal static void sendSing(WCSTask wmsTask, int state = 0) |
| | | { |
| | | LogHelper.Info($"收到任务{wmsTask.S_CODE}信号{state},类型{wmsTask.S_TYPE}"); |
| | | if(wmsTask.S_TYPE == "成品下线" || wmsTask.S_TYPE == "栈板上线") |
| | | { |
| | | //请求卸货, |
| | | //根据终点判断,是cb02的入口,判断内存中状态(要状态时间),允许卸货,通知agv改参数 |
| | | var dic = new Dictionary<string, string>(); |
| | | //< Req >< Order No = 'TN2302020002' ParamNo = '18' Param1 = '12' /></ Req > |
| | | dic.Add("No", no); |
| | | dic.Add("ParamNo", "8"); |
| | | dic.Add("Param1", "1"); |
| | | NDC.ChangeOrder(dic); |
| | | //改完参数车子就会自己卸货 |
| | | int devType = wmsTask.S_TYPE == "成品下线" ? 1 : 2; |
| | | var plc = Settings.deviceInfos.Where(a => a.deviceType == devType).FirstOrDefault(); |
| | | if (plc != null) |
| | | { |
| | | if (wmsTask.S_TYPE == "成品下线") |
| | | { |
| | | if (state == 1101) |
| | | { |
| | | PlcHelper.SendHex(plc.address, "3F00110D0A"); |
| | | } |
| | | if (state == 1102) |
| | | { |
| | | PlcHelper.SendHex(plc.address, "3F00100d0a"); |
| | | } |
| | | } |
| | | if (wmsTask.S_TYPE == "栈板上线") |
| | | { |
| | | if (state == 1103) |
| | | { |
| | | PlcHelper.SendHex(plc.address, "3F00210d0a"); |
| | | } |
| | | if (state == 1104 || state == -1) |
| | | { |
| | | PlcHelper.SendHex(plc.address, "3F00200d0a"); |
| | | } |
| | | } |
| | | |
| | | } |
| | | else LogHelper.Info("农夫林芝-L6输送线 未配置"); |
| | | } |
| | | if (state == 1103) |
| | | else |
| | | { |
| | | //大铁框叉走以后通知,我们要通知输送线 |
| | | LogHelper.Info($"{wmsTask.S_TYPE}写入复位信号"); |
| | | writeSignal(wmsTask, state); |
| | | } |
| | | } |
| | | |
| | | public static void writeSignal(WCSTask mst, int state = 0) |
| | | { |
| | | if (mst.S_TYPE.Contains("空托上线")) |
| | | { |
| | | LogHelper.Info($"{mst.S_TYPE}卸货完成,写入信号"); |
| | | if(state == 6) |
| | | { |
| | | //根据起点判断是A口还是B口 |
| | | var locCode = mst.S_END_LOC; |
| | | var devInfo = Settings.deviceInfos.Where(a => a.TN_Location.Contains(locCode)).FirstOrDefault(); |
| | | if (devInfo != null) |
| | | { |
| | | var signal = devInfo.TN_Location[0] == mst.S_END_LOC ? "3F 00 10 0D 0A" : "3F 00 20 0D 0A"; |
| | | if (PlcHelper.SendHex(devInfo.address, signal)) LogHelper.Info($"{mst.S_TYPE}任务卸货完成,写入信号:{signal},ip:{devInfo.address}"); |
| | | } |
| | | else LogHelper.Info($"设备未找到,货位号:{mst.S_END_LOC}"); |
| | | } |
| | | } |
| | | if (mst.S_TYPE.Contains("满托上线")) |
| | | { |
| | | LogHelper.Info($"{mst.S_TYPE}卸货完成,写入信号"); |
| | | var locCode = mst.S_END_LOC; |
| | | var devInfo = Settings.deviceInfos.Where(a => a.TN_Location.Contains(locCode)).FirstOrDefault(); |
| | | if (devInfo != null) |
| | | { |
| | | var signal = "3F 00 12 21 0D 0A"; |
| | | if (state == 1104) signal = "3F 00 10 20 0D 0A"; |
| | | if (PlcHelper.SendHex(devInfo.address, signal)) LogHelper.Info($"{mst.S_TYPE}任务卸货完成,写入信号:{signal},ip:{devInfo.address}"); |
| | | } |
| | | else LogHelper.Info($"设备未找到,货位号:{mst.S_END_LOC}"); |
| | | } |
| | | if (mst.S_TYPE.Contains("空托下线")) |
| | | { |
| | | LogHelper.Info($"{mst.S_TYPE}取货完成,写入信号"); |
| | | var locCode = mst.S_START_LOC; |
| | | var devInfo = Settings.deviceInfos.Where(a => a.TN_Location.Contains(locCode)).FirstOrDefault(); |
| | | if (devInfo != null) |
| | | { |
| | | var signal = "3F 00 12 21 0D 0A"; |
| | | if (state == 1102) signal = "3F 00 10 20 0D 0A"; |
| | | if (PlcHelper.SendHex(devInfo.address, signal)) LogHelper.Info($"{mst.S_TYPE}任务取货完成,写入信号:{signal},ip:{devInfo.address}"); |
| | | } |
| | | else LogHelper.Info($"设备未找到,货位号:{mst.S_END_LOC}"); |
| | | } |
| | | if (mst.S_TYPE.Contains("满托下线")) |
| | | { |
| | | LogHelper.Info($"{mst.S_TYPE}取货完成,写入信号"); |
| | | if(state == 4) |
| | | { |
| | | //根据起点判断是A口还是B口 |
| | | var locCode = mst.S_START_LOC; |
| | | var devInfo = Settings.deviceInfos.Where(a => a.TN_Location.Contains(locCode)).FirstOrDefault(); |
| | | if (devInfo != null) |
| | | { |
| | | var signal = devInfo.TN_Location[0] == mst.S_START_LOC ? "3F 00 10 0D 0A" : "3F 00 20 0D 0A"; |
| | | if (PlcHelper.SendHex(devInfo.address, signal)) LogHelper.Info($"{mst.S_TYPE}任务取货完成,写入信号:{signal},ip:{devInfo.address}"); |
| | | } |
| | | else LogHelper.Info($"设备未找到,货位号:{mst.S_START_LOC}"); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | internal static void ThirdReportStatus(WCSTask mst, int state, string forkliftNo) |
| | | { |
| | | if (state == 2) |
| | | { |
| | | TaskProcess.TASK_STATUSFunc(mst); |
| | | } |
| | | } |
| | | |
| | | #region 富勒流程处理 |
| | | /// <summary> |
| | | /// 任务完成状态回报--1.正常任务完成回报 2.移库任务完成回报 |
| | | /// </summary> |
| | | /// <param name="JsonData"></param> |
| | | /// <returns></returns> |
| | | internal static void TASK_STATUSFunc(WCSTask wmsTask) |
| | | { |
| | | string msg = ""; List<string> trayList = new List<string>(); |
| | | var req = new SimpleResult(); |
| | | var StartInfo = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_CODE == wmsTask.S_START_LOC.Trim()).First(); |
| | | var EndInfo = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_CODE == wmsTask.S_END_LOC.Trim()).First(); |
| | | List<string> taskTrayList = new List<string>(wmsTask.S_CNTR_CODE.Trim().Split(',')); |
| | | taskTrayList.ForEach(a => |
| | | { |
| | | if (!string.IsNullOrEmpty(a)) trayList.Add(a.Replace(",", "")); |
| | | }); |
| | | string[] trayInfo = trayList.ToArray(); |
| | | var url = Settings.thirdPartyUrls.Where(a => a.UrlNo == "2" && a.enable == 1).FirstOrDefault(); |
| | | if (wmsTask.S_TYPE.Contains("移库")) |
| | | { |
| | | //移库任务 完成回报 |
| | | var httpVerify = Settings.httpApiVerifys.Where(a => a.VerifyNo == "1" && a.Project == Settings.ProjectName && a.enable == 1).FirstOrDefault(); |
| | | if (httpVerify != null) |
| | | { |
| | | var startRow = StartInfo.S_ROW.Trim(); |
| | | var endRow = EndInfo.S_ROW.Trim(); |
| | | var FLStartRow = new SqlHelper<Object>().GetInstance().Queryable<RowComparsionTable>().Where(a => a.S_LJ_ROW == startRow).First(); |
| | | var FLEndRow = new SqlHelper<Object>().GetInstance().Queryable<RowComparsionTable>().Where(a => a.S_LJ_ROW == endRow).First(); |
| | | if (FLStartRow != null && FLEndRow != null) |
| | | { |
| | | string sendMsg = JsonConvert.SerializeObject(new |
| | | { |
| | | startAreaNo = FLStartRow.S_FL_ROW.Trim(), |
| | | endAreaNo = FLEndRow.S_FL_ROW.Trim(), |
| | | trayInfo = trayInfo, |
| | | repoNo = "LJ02" |
| | | }); |
| | | LogHelper.Info("sendMsg secusess:" + JsonConvert.SerializeObject(sendMsg)); |
| | | req = FuLeWebPost(sendMsg, "yikuTaskStatus ", url.Url);//YKRWSD AreaRowLockState |
| | | } |
| | | } |
| | | else |
| | | { |
| | | AnalysisCompleteModel model = new AnalysisCompleteModel(); |
| | | model.TrayInfo = trayInfo; |
| | | model.StartAreaNo = StartInfo.S_ROW.Trim().Replace("-XB", ""); |
| | | model.EndAreaNo = EndInfo.S_ROW.Trim().Replace("-XB", ""); |
| | | string sendMsg = JsonConvert.SerializeObject(model); |
| | | req = FuLeWebPost(sendMsg, "YKRWWC", url.Url);//YKRWWC YIKUTASK_STATUS |
| | | } |
| | | } |
| | | else if (wmsTask.S_TYPE.Contains("下线")) |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | string SrcNo = wmsTask.S_WORK_NO?.Trim(); |
| | | var workInfo = db.Queryable<LinZhiWorkOrder>().Where(a => a.S_WorkNo == SrcNo).First(); |
| | | if (workInfo != null) |
| | | { |
| | | if (workInfo.S_ORDER_TYPE.Trim() != "无码入库") |
| | | { |
| | | //产线下线 完成回报 |
| | | var httpVerify = Settings.httpApiVerifys.Where(a => a.VerifyNo == "2" && a.Project == Settings.ProjectName && a.enable == 1).FirstOrDefault(); |
| | | if (httpVerify != null) |
| | | { |
| | | var endRow = EndInfo.S_ROW.Trim(); |
| | | var FLEndRow = new SqlHelper<Object>().GetInstance().Queryable<RowComparsionTable>().Where(a => a.S_LJ_ROW == endRow).First(); |
| | | if (FLEndRow != null) |
| | | { |
| | | string sendMsg = JsonConvert.SerializeObject(new |
| | | { |
| | | trayInfo = trayInfo, |
| | | workNo = wmsTask.S_WORK_NO.Trim(), |
| | | repoNo = "LJ02", |
| | | areaLoca = FLEndRow.S_FL_ROW, |
| | | }); |
| | | LogHelper.Info("sendMsg secucess:" + JsonConvert.SerializeObject(sendMsg)); |
| | | req = FuLeWebPost(sendMsg, "proTaskStatus", url.Url); //AreaRowLockState |
| | | } |
| | | } |
| | | else |
| | | { |
| | | ProCompleteModel model = new ProCompleteModel(); |
| | | model.TrayInfo = trayInfo; |
| | | model.WorkNo = wmsTask.S_WORK_NO.Trim(); |
| | | model.AreaLoca = EndInfo.S_ROW.Trim().Replace("-XB", ""); |
| | | string sendMsg = JsonConvert.SerializeObject(model); |
| | | req = FuLeWebPost(sendMsg, "WGHB", url.Url);//WGHB PROTASK_STATUS |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (req != null && req.success) msg = $"TASK_STATUS:返回任务状态成功:{JsonConvert.SerializeObject(req)}!"; |
| | | else msg = $"TASK_STATUS:返回任务状态失败:{JsonConvert.SerializeObject(req)}!"; |
| | | LogHelper.Info(msg, "ThirdSystemLog"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 任务信息接口--汉和任务每个状态进行实时上传(包括任务创建时,上报 8) |
| | | /// </summary> |
| | | /// <param name="wmsTask"></param> |
| | | internal static void GeneralInterFaceFunc(WCSTask wmsTask, string taskStatus, string forkliftNo = "") |
| | | { |
| | | string msg = ""; |
| | | var req = new SimpleResult(); |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | ///同一条任务同种状态只上报一次 |
| | | ///查询任务动作表,有任务相同并且任务状态相同的,就不上报(任务状态为1还要查询车号是否存在) |
| | | bool flage = false; |
| | | var no = wmsTask.S_CODE; |
| | | var code = int.Parse(taskStatus); |
| | | if (taskStatus == "1") |
| | | { |
| | | if (forkliftNo != "0") |
| | | { |
| | | if (db.Queryable<TaskAction>().Count(a => a.S_TASK_CODE.Trim() == no.Trim() && a.N_ACTION_CODE == code) == 2) |
| | | { |
| | | wmsTask.S_EQ_NO = forkliftNo; |
| | | flage = true; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | flage = true; |
| | | } |
| | | |
| | | if (flage) |
| | | { |
| | | if (WCSHelper.CheckActionRecordExist(wmsTask.S_CODE, 4) && taskStatus == "7") taskStatus = "2"; |
| | | try |
| | | { |
| | | //获取上报接口的URL |
| | | var url = Settings.thirdPartyUrls.Where(a => a.UrlNo == "1" && a.enable == 1).FirstOrDefault(); |
| | | LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},获取URL:{url}", "ThirdSystemLog"); |
| | | //任务类型数据处理 |
| | | string taskType = ""; |
| | | var taskTypeInfo = db.Queryable<TaskTypeConvTable>().Where(a => a.taskTypeName == wmsTask.S_TYPE).First(); |
| | | if (taskTypeInfo != null) taskType = taskTypeInfo.taskType; |
| | | LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},任务类型数据处理:{taskType}", "ThirdSystemLog"); |
| | | |
| | | //托盘物料数据处理 |
| | | List<string> cntrList = new List<string>(wmsTask.S_CNTR_CODE.Split(','));//获取托盘数据 |
| | | string itemCode = "";//物料编码 |
| | | itemCode = GeneralInterFaceGetItemCodeFunc(wmsTask, db, cntrList, itemCode); |
| | | LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},物料编码:{itemCode}", "ThirdSystemLog"); |
| | | List<asnReferenceDModel> asnReferenceList = new List<asnReferenceDModel> { };//托码数组 |
| | | GeneralInterFaceGetTrayCodeFunc(wmsTask, db, asnReferenceList, cntrList); |
| | | LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},获取托盘数据:{JsonConvert.SerializeObject(asnReferenceList)}", "ThirdSystemLog"); |
| | | |
| | | //AGV设备信息处理 |
| | | string equipmentCode = ""; |
| | | string orgCode = ""; |
| | | string orgName = ""; |
| | | string proxyInterfaceCode = "0050"; |
| | | GeneralInterFaceGetAgvDeviceInfoFunc(wmsTask, db, ref equipmentCode, ref orgCode, ref orgName, ref proxyInterfaceCode); |
| | | LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},equipmentCode:{equipmentCode},orgCode:{orgCode},orgName:{orgName},proxyInterfaceCode:{proxyInterfaceCode}", "ThirdSystemLog"); |
| | | |
| | | LogHelper.Info($"wmstask.t_start_time:{wmsTask.T_START_TIME}"); |
| | | if (DateTime.MinValue == wmsTask.T_START_TIME) |
| | | { |
| | | wmsTask.T_START_TIME = null; |
| | | } |
| | | |
| | | DateTime dateTime = taskStatus == "1" ? Convert.ToDateTime(wmsTask.T_START_TIME).AddHours(-8) : taskStatus == "2" || taskStatus == "7" ? Convert.ToDateTime(wmsTask.T_END_TIME).AddHours(-8) : taskStatus == "8" ? Convert.ToDateTime(wmsTask.T_CREATE).AddHours(-8) : DateTime.UtcNow; |
| | | string createTime = GetTimeStamp(wmsTask.T_CREATE.AddHours(-8), 1, 2); |
| | | string startTime = ""; |
| | | //在C#中,使用DateTimeOffset.UtcNow.ToUnixTimeSeconds()方法获取Unix时间戳时,可能会多出一个毫秒。这是因为Unix时间戳是以秒为单位的,而DateTimeOffset.UtcNow返回的是UTC时间,其精度为100纳秒。 |
| | | if (wmsTask.S_WORK_MODE != "agv" && !string.IsNullOrEmpty(wmsTask.S_WORK_MODE)) startTime = wmsTask.S_WORK_MODE; |
| | | else |
| | | { |
| | | startTime = wmsTask.T_START_TIME == null ? null : GetTimeStamp(Convert.ToDateTime(wmsTask.T_START_TIME).AddHours(-8), 1, 2); |
| | | if (startTime != null) |
| | | { |
| | | wmsTask.S_WORK_MODE = startTime; |
| | | db.Updateable(wmsTask).UpdateColumns(a => new { a.S_WORK_MODE }).ExecuteCommand(); |
| | | } |
| | | } |
| | | |
| | | string endTime = wmsTask.T_END_TIME == null ? null : GetTimeStamp(Convert.ToDateTime(wmsTask.T_END_TIME).AddHours(-8), 1, 2); |
| | | string businessTime = taskStatus == "1" ? startTime : taskStatus == "2" || taskStatus == "7" ? endTime : taskStatus == "8" ? createTime : GetTimeStamp(dateTime, 1, 2); |
| | | string dt = wmsTask.T_START_TIME == null ? null : Convert.ToDateTime(wmsTask.T_START_TIME).AddHours(-8).ToString(); |
| | | string mill = wmsTask.T_START_TIME == null ? null : Convert.ToDateTime(wmsTask.T_START_TIME).AddHours(-8).Millisecond.ToString(); |
| | | LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},任务开始时间:{wmsTask.T_START_TIME},任务转换后时间:{dt},任务号毫秒时间:{mill},转换后时间:{startTime}", "ThirdSystemLog"); |
| | | |
| | | string sendMsg = JsonConvert.SerializeObject(new |
| | | { |
| | | taskCode = wmsTask.S_CODE,//任务编码 |
| | | taskStatus = taskStatus,//任务状态-任务创建成功传输 8 |
| | | taskType = taskType,//任务类型-需要根据 配置表数据进行转换,转换为MES的任务类型 |
| | | createTime = createTime,//需转换为 时间戳 wmsTask.T_CREATE |
| | | startTime = startTime,//需转换为 时间戳 wmsTask.T_START_TIME |
| | | endTime = endTime,//需转换为 时间戳 wmsTask.T_END_TIME |
| | | businessTime = businessTime,//当前任务时间-需转换为 时间戳 DateTime.Now |
| | | startAddress = wmsTask.S_START_LOC,//起点 |
| | | endAddress = wmsTask.S_END_LOC,//终点 |
| | | equipmentNo = wmsTask.S_EQ_NO,//车辆编号 |
| | | equipmentCode = equipmentCode,//车辆铭牌-需要根据 配置表数据,通过 车辆编号以及工厂编码 查询对应车辆铭牌 |
| | | orgCode = Settings.FactoryCode,//工厂编码 |
| | | orgName = Settings.FactoryName,//工厂名称 |
| | | sku = itemCode,//物料编码 |
| | | asnReferenceDList = asnReferenceList,//托码数组 此次叉车叉的托盘喷码, 一次叉辆车,有两个编码 产线下线且非无码模式时传输 |
| | | appliactionId = "MOBOX" |
| | | //proxyInterfaceCode = proxyInterfaceCode //接口唯一标识码 固定值:0050 |
| | | }); |
| | | //http://yst-open-zuul-qa.idc.yst.com.cn/proxy/v1/ |
| | | req = FuLeWebPost(sendMsg, "generalInterface", url.Url, true);//YKRWSD AreaRowLockState |
| | | |
| | | if (req != null && req.success) msg = $"GeneralInterFaceFunc:返回任务状态成功:{JsonConvert.SerializeObject(req)}!"; |
| | | else msg = $"GeneralInterFaceFunc:返回任务状态失败:{JsonConvert.SerializeObject(req)}!"; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | msg = $"GeneralInterFaceFunc Error:TaskInfo:{JsonConvert.SerializeObject(wmsTask)},TaskState:{taskStatus},ErrorMsg:{ex.Message}"; |
| | | } |
| | | } |
| | | |
| | | LogHelper.Info(msg, "ThirdSystemLog"); |
| | | } |
| | | public class ProCompleteModel |
| | | { |
| | | /// <summary> |
| | | /// 仓库编码 |
| | | /// </summary> |
| | | public string StockNo { get; set; } = "CK001"; |
| | | public string[] TrayInfo { get; set; } |
| | | public string WorkNo { get; set; } |
| | | public string AreaLoca { get; set; } |
| | | } |
| | | public class AnalysisCompleteModel |
| | | { |
| | | /// <summary> |
| | | /// 仓库编码 |
| | | /// </summary> |
| | | public string StockNo { get; set; } = "CK001"; |
| | | public string[] TrayInfo { get; set; } |
| | | public string StartAreaNo { get; set; } |
| | | public string EndAreaNo { get; set; } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 任务信息接口--获取物料编码 |
| | | /// </summary> |
| | | /// <param name="wmsTask"></param> |
| | | private static string GeneralInterFaceGetItemCodeFunc(WMSTask wmsTask, SqlSugarClient db, List<string> cntrList, string itemCode) |
| | | { |
| | | //if (cntrList.Count > 0) |
| | | //{ |
| | | // string SrcNo = wmsTask.S_SRC_NO?.Trim(); |
| | | // // 农夫网管下发的工单,物料获取方式 |
| | | // if (!string.IsNullOrEmpty(SrcNo) && wmsTask.S_TYPE.Contains("下线")) |
| | | // { |
| | | // var workInfo = db.Queryable<LinJiangWorkOrder>().Where(a => a.S_WorkNo == SrcNo).First(); |
| | | // if (workInfo != null) itemCode = workInfo.S_ItemCode; |
| | | // } |
| | | // // 其他的人工建立的工单,物料获取方式 |
| | | // else |
| | | // { |
| | | // var cntrItemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrList[0]).First(); |
| | | // if (cntrItemInfo != null) |
| | | // { |
| | | // //此处查询 物料表,仅限淳安获取MES物料使用,其他工厂可自行注释;因淳安入库物料是使用 物料名称+物料层数 拼接而成,因此需要 通过物料表转换为 MES 的物料编码 |
| | | // //var itemInfo = db.Queryable<ItemRel>().Where(a => a.S_ITEM_NAME == cntrItemInfo.S_ITEM_CODE).First(); |
| | | // //if (itemInfo != null) itemCode = itemInfo.S_ITEM_CODE; |
| | | // itemCode = cntrItemInfo.S_ITEM_CODE; |
| | | // } |
| | | // } |
| | | //} |
| | | // |
| | | return itemCode; |
| | | } |
| | | /// <summary> |
| | | /// 任务信息接口--获取托盘数据 |
| | | /// </summary> |
| | | /// <param name="wmsTask"></param> |
| | | private static void GeneralInterFaceGetTrayCodeFunc(WMSTask wmsTask, SqlSugarClient db, List<asnReferenceDModel> asnReferenceList, List<string> cntrList) |
| | | { |
| | | //string SrcNo = wmsTask.S_SRC_NO?.Trim(); |
| | | // |
| | | ////根据任务中存放的工单号,获取工单类型--因为淳安 满托下线任务包含 下线 值,因此多判断一步,减少工单表的查询 |
| | | //if (!string.IsNullOrEmpty(SrcNo) && wmsTask.S_TYPE.Contains("下线")) |
| | | //{ |
| | | // var workInfo = db.Queryable<LinJiangWorkOrder>().Where(a => a.S_WorkNo == SrcNo).First(); |
| | | // if (workInfo != null) |
| | | // { |
| | | // if (workInfo.S_ORDER_TYPE.Trim() != "无码入库") |
| | | // { |
| | | // |
| | | // if (cntrList.Count > 0) |
| | | // { |
| | | // cntrList.ForEach(a => |
| | | // { |
| | | // if (!string.IsNullOrEmpty(a)) |
| | | // asnReferenceList.Add(new asnReferenceDModel { asnReferenceD = a }); |
| | | // }); |
| | | // } |
| | | // } |
| | | // } |
| | | //} |
| | | } |
| | | /// <summary> |
| | | /// 任务信息接口--获取AGV设备信息数据 |
| | | /// </summary> |
| | | /// <param name="wmsTask"></param> |
| | | /// <param name="db"></param> |
| | | /// <param name="equipmentCode"></param> |
| | | /// <param name="orgCode"></param> |
| | | /// <param name="orgName"></param> |
| | | /// <param name="proxyInterfaceCode"></param> |
| | | private static void GeneralInterFaceGetAgvDeviceInfoFunc(WMSTask wmsTask, SqlSugarClient db, ref string equipmentCode, ref string orgCode, ref string orgName, ref string proxyInterfaceCode) |
| | | { |
| | | //if (!string.IsNullOrEmpty(wmsTask.S_AGV_NO)) |
| | | //{ |
| | | // var agvDeviceInfo = db.Queryable<AGVDeviceDataTable>().Where(a => a.equipmentNo == wmsTask.S_AGV_NO && a.orgCode == Settings.FactoryCode).First(); |
| | | // if (agvDeviceInfo != null) |
| | | // { |
| | | // equipmentCode = agvDeviceInfo.equipmentCode; |
| | | // orgCode = agvDeviceInfo.orgCode; |
| | | // orgName = agvDeviceInfo.orgName; |
| | | // proxyInterfaceCode = agvDeviceInfo.proxyInterfaceCode; |
| | | // } |
| | | //} |
| | | } |
| | | /// <summary> |
| | | /// 任务信息接口--获取时间戳 |
| | | /// </summary> |
| | | /// <param name="DataBitType">数据位数:值:32|64 含义:32位|64位</param> |
| | | /// <param name="TimeType">获取时间类型:值:1|2 含义:1-秒级 2-毫秒级</param> |
| | | /// <param name="TimeUtcType">获取时间Utc类型:值:1|2 含义:1-本地时间 2-Utc时间</param> |
| | | /// <returns></returns> |
| | | public static string GetTimeStamp(DateTime dateTime, int DataBitType, int TimeType) |
| | | { |
| | | string timeStamp = ""; |
| | | |
| | | //时间戳打印 |
| | | TimeSpan ts = dateTime - new DateTime(1970, 1, 1, 0, 0, 0, 0);//时间戳获取 |
| | | double tsTime = TimeType == 1 ? ts.TotalSeconds : ts.TotalMilliseconds;//秒级|毫秒级时间获取 |
| | | |
| | | string TimeTypeInfo = TimeType == 1 ? "秒级" : "毫秒级"; |
| | | timeStamp = DataBitType == 32 ? Convert.ToInt32(tsTime).ToString() : Convert.ToInt64(tsTime).ToString(); |
| | | |
| | | //double result = 0; |
| | | //result = DataBitType == 32 ? Convert.ToInt32(tsTime) : Convert.ToInt64(tsTime); |
| | | |
| | | return timeStamp; |
| | | } |
| | | |
| | | |
| | | public class asnReferenceDModel |
| | | { |
| | | public string asnReferenceD { get; set; } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 库位锁定解锁回报-移库任务锁定解锁库位 |
| | | /// </summary> |
| | | /// <param name="AreaRow">库位号-多个库位号用英文逗号隔开</param> |
| | | /// <param name="state">true-锁定库位 false-解锁库位</param> |
| | | internal static void AreaRowLockState(string AreaRow, bool state = true) |
| | | { |
| | | string msg = ""; List<string> areaList = new List<string>(); |
| | | var req = new SimpleResult(); |
| | | List<string> taskAreaList = new List<string>(AreaRow.Split(',')); |
| | | taskAreaList.ForEach(a => |
| | | { |
| | | if (!string.IsNullOrEmpty(a)) areaList.Add(a); |
| | | }); |
| | | string[] AreaInfo = areaList.ToArray(); |
| | | var url = Settings.thirdPartyUrls.Where(a => a.UrlNo == "2" && a.enable == 1).FirstOrDefault(); |
| | | var httpVerify = Settings.httpApiVerifys.Where(a => a.VerifyNo == "1" && a.Project == Settings.ProjectName && a.enable == 1).FirstOrDefault(); |
| | | if (httpVerify != null) |
| | | { |
| | | string sendMsg = JsonConvert.SerializeObject(new |
| | | { |
| | | areaNum = AreaInfo, |
| | | repoNo = "LJ02", |
| | | areaLock = state ? "1" : "2" |
| | | }); |
| | | LogHelper.Info("sendMsg:" + JsonConvert.SerializeObject(sendMsg)); |
| | | req = FuLeWebPost(sendMsg, "areaRowLockState", url.Url);//YKRWSD AreaRowLockState |
| | | } |
| | | else |
| | | { |
| | | AreaRowLockStateModel model = new AreaRowLockStateModel(); |
| | | model.AreaNum = AreaInfo; |
| | | model.AreaLock = state ? "1" : "2"; |
| | | string sendMsg = JsonConvert.SerializeObject(model); |
| | | req = FuLeWebPost(sendMsg, "YKRWSD", url.Url);//YKRWSD AreaRowLockState |
| | | } |
| | | |
| | | if (req != null && req.success) msg = $"YKRWSD:返回库位状态成功:{JsonConvert.SerializeObject(req)}!"; |
| | | else msg = $"YKRWSD:返回库位状态失败:{JsonConvert.SerializeObject(req)}!"; |
| | | LogHelper.Info(msg, "ThirdSystemLog"); |
| | | } |
| | | public class AreaRowLockStateModel |
| | | { |
| | | /// <summary> |
| | | /// 仓库编码 |
| | | /// </summary> |
| | | public string StockNo { get; set; } = "CK001"; |
| | | public string[] AreaNum { get; set; } |
| | | /// <summary> |
| | | /// 库位锁定状态--1-锁定 2-解锁 |
| | | /// </summary> |
| | | public string AreaLock { get; set; } |
| | | } |
| | | #endregion |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 任务拦截 |
| | | /// </summary> |
| | |
| | | /// <exception cref="NotImplementedException"></exception> |
| | | public static void EmptyTask(WCSTask mst) |
| | | { |
| | | ////瓶盖注塑机空托上线,若急产急用库区没有多余的空托,则在非急产急用空托区拿空托 |
| | | //var db = new SqlHelper<object>().GetInstance(); |
| | | //Location startLoca = null; |
| | | //bool result = false; |
| | | // |
| | | //if (mst.S_TYPE.Contains("满托下线")) |
| | | //{ |
| | | // LogHelper.Info($"空托任务生成处理,任务类型:{mst.S_TYPE}"); |
| | | // startLoca = getMStartLoc1(db, startLoca, "瓶坯"); |
| | | // #region |
| | | // |
| | | // if (startLoca != null) |
| | | // { |
| | | // LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca)); |
| | | // var startArea = startLoca.S_AREA_CODE; |
| | | // string taskType = ""; |
| | | // if (mst.S_TYPE == "注塑即产满托下线(瓶坯)") taskType = "注塑即产空托上线(瓶坯)"; |
| | | // if (mst.S_TYPE == "注塑库存满托下线(瓶坯)") taskType = "注塑库存空托上线(瓶坯)"; |
| | | // int startLayer = startLoca.N_CURRENT_NUM; |
| | | // var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_LOC_CODE).First(); |
| | | // if (cntrInfo != null) |
| | | // { |
| | | // string cntr = cntrInfo.S_CNTR_CODE; |
| | | // result = IntensiveArea.LinJiangCreateTransport(startArea, startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, cntr, 1, 1, mst.S_SRC_SYS, startLoca.N_ROW, 1, 1); |
| | | // if (result) LogHelper.Info($"{taskType}:{mst.S_SRC_SYS} 当前位置{mst.S_START_LOC} 任务创建成功", "注塑机空托上线"); |
| | | // } |
| | | // else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_LOC_CODE}"); |
| | | // } |
| | | //} |
| | | // |
| | | //if (mst.S_TYPE.Contains("空托下线")) |
| | | //{ |
| | | // LogHelper.Info($"满托任务生成处理,任务类型:{mst.S_TYPE}"); |
| | | // string startArea = ""; |
| | | // bool flage = false; |
| | | // string jbw = ""; |
| | | // string mk = ""; |
| | | // string machine = ""; |
| | | // LinjiangBCPWorkOrder bcpW = null; |
| | | // if (mst.S_TYPE.Contains("瓶坯")) |
| | | // { |
| | | // jbw = "瓶坯接驳位"; |
| | | // mk = "瓶坯满托出库接驳位"; |
| | | // machine = "瓶坯翻斗机"; |
| | | // bcpW = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("农夫临江-瓶坯翻斗机")).First(); |
| | | // } |
| | | // else |
| | | // { |
| | | // jbw = "瓶盖接驳位"; |
| | | // mk = "瓶盖满托"; |
| | | // bcpW = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("农夫临江-瓶盖翻斗机")).First(); |
| | | // } |
| | | // |
| | | // if (bcpW.S_UsingNow == "Y") |
| | | // { |
| | | // LogHelper.Info("即产即用工单"); |
| | | // //即产即用在起点为线边 |
| | | // var bcpInfo = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == jbw && a.Enable == "1").FirstOrDefault(); |
| | | // if (bcpInfo != null) |
| | | // { |
| | | // startArea = bcpInfo.AreaNo; |
| | | // } |
| | | // } |
| | | // else |
| | | // { |
| | | // LogHelper.Info("非即产即用工单"); |
| | | // //非即产即用起点为库区 |
| | | // var bcpInfo = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == mk && a.Enable == "1").FirstOrDefault(); |
| | | // if (bcpInfo != null) |
| | | // { |
| | | // startArea = bcpInfo.AreaNo; |
| | | // } |
| | | // } |
| | | // |
| | | // if (bcpW.S_UsingNow == "Y") |
| | | // { |
| | | // bool action = false; |
| | | // if (jbw == "瓶坯接驳位") |
| | | // { |
| | | // flage = true; |
| | | // action = DeviceProcess.queryBCPFDJRow(db, ref startLoca); |
| | | // } |
| | | // LogHelper.Info($"即产即用库区查找"); |
| | | // if (startLoca == null) |
| | | // { |
| | | // startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea, machine); |
| | | // //startLoca = db.Queryable<Location>().Where(a => a.S_AREA_CODE == startArea && a.N_CURRENT_NUM != 0 && a.S_LOCK_STATE == "无").First(); |
| | | // //startLoca = TempleteOverExtendService.GetLocation(startArea, workInfo.S_ItemCode, "", false); |
| | | // if (startLoca == null) |
| | | // { |
| | | // flage = false; |
| | | // if (jbw == "瓶坯接驳位") |
| | | // { |
| | | // LogHelper.Info($"即产即用库区未找到满托,去满托库区查找"); |
| | | // |
| | | // //即产即用库区无满托,去非即产即用库区查询 |
| | | // LogHelper.Info($"mk:{mk}"); |
| | | // startArea = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == mk && a.Enable == "1").FirstOrDefault().AreaNo; |
| | | // LogHelper.Info($"startArea:{startArea}"); |
| | | // //startLoca = TempleteOverExtendService.GetLocation(startArea, workInfo.S_ItemCode, "", false, true, true); |
| | | // startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea); |
| | | // } |
| | | // } |
| | | // else |
| | | // { |
| | | // if (action) |
| | | // { |
| | | // CPXXTable table = new CPXXTable |
| | | // { |
| | | // S_AREA_CODE = startArea, |
| | | // S_ROW = startLoca.N_ROW, |
| | | // S_TASK_TYPE = "瓶坯注塑机" |
| | | // }; |
| | | // db.Insertable(table).ExecuteCommand(); |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // else |
| | | // { |
| | | // startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea); |
| | | // } |
| | | // |
| | | // if (startLoca != null) |
| | | // { |
| | | // LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca)); |
| | | // string taskType = ""; |
| | | // if (mst.S_TYPE == "翻斗机即产空托下线(瓶坯)") taskType = "翻斗机即产满托上线(瓶坯)"; |
| | | // if (mst.S_TYPE == "翻斗机库存空托下线(瓶坯)") taskType = "翻斗机库存满托上线(瓶坯)"; |
| | | // if (mst.S_TYPE == "翻斗机即产空托下线(瓶盖)") taskType = "翻斗机即产满托上线(瓶盖)"; |
| | | // if (mst.S_TYPE == "翻斗机库存空托下线(瓶盖)") taskType = "翻斗机库存满托上线(瓶盖)"; |
| | | // int startLayer = startLoca.N_CURRENT_NUM; |
| | | // var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_LOC_CODE).First(); |
| | | // if (cntrInfo != null) |
| | | // { |
| | | // string cntr = cntrInfo.S_CNTR_CODE; |
| | | // if (flage) |
| | | // { |
| | | // result = TaskHelper.LinJiangCreateTask("", startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, 1, cntr, mst.S_SRC_SYS); |
| | | // if (result) |
| | | // { |
| | | // LocationHelper.LockLoc(startLoca.S_LOC_CODE, "出库锁"); |
| | | // LocationHelper.LockLoc(mst.S_START_LOC, "入库锁"); |
| | | // var rowInfo = db.Queryable<RowLock>().Where(a => a.S_AREA_CODE == startArea && a.N_ROW == startLoca.N_ROW).First(); |
| | | // if (rowInfo != null) |
| | | // { |
| | | // rowInfo.S_LOCK_STATE = "即产出库锁"; |
| | | // db.Updateable(rowInfo).UpdateColumns(a => new { a.S_LOCK_STATE }).ExecuteCommand(); |
| | | // } |
| | | // } |
| | | // } |
| | | // else |
| | | // { |
| | | // int pri = 1; |
| | | // if (taskType.Contains("瓶盖")) pri = 10; |
| | | // result = IntensiveArea.LinJiangCreateTransport(startArea, startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, cntr, 1, 1, mst.S_SRC_SYS, startLoca.N_ROW, 1, pri); |
| | | // } |
| | | // if (result) LogHelper.Info($"{taskType}:{mst.S_SRC_SYS} 当前位置{mst.S_START_LOC} 任务创建成功", "翻斗机满托上线"); |
| | | // } |
| | | // else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_LOC_CODE}"); |
| | | // } |
| | | //} |
| | | //瓶盖注塑机空托上线,若急产急用库区没有多余的空托,则在非急产急用空托区拿空托 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | Location startLoca = null; |
| | | |
| | | if (mst.S_TYPE.Contains("满托下线")) |
| | | { |
| | | LogHelper.Info($"空托任务生成处理,任务类型:{mst.S_TYPE}"); |
| | | string areaName = mst.S_TYPE.Contains("库存") ? "瓶坯非即产空框" : "瓶坯即产空框"; |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).First(); |
| | | if(areaInfo != null) |
| | | { |
| | | startLoca = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").OrderBy(a => a.N_ROW).First(); |
| | | if (startLoca != null) |
| | | { |
| | | LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca)); |
| | | string taskType = ""; |
| | | if (mst.S_TYPE == "注塑即产满托下线(瓶坯)") taskType = "注塑即产空托上线(瓶坯)"; |
| | | if (mst.S_TYPE == "注塑库存满托下线(瓶坯)") taskType = "注塑库存空托上线(瓶坯)"; |
| | | var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_CODE).First(); |
| | | if (cntrInfo != null) |
| | | { |
| | | WMSHelper.CreateOpTask(startLoca.S_CODE, mst.S_START_LOC, "出库", taskType, cntrInfo.S_CNTR_CODE); |
| | | } |
| | | else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_CODE}"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"瓶坯空托未配置"); |
| | | } |
| | | } |
| | | |
| | | if (mst.S_TYPE.Contains("空托下线")) |
| | | { |
| | | LogHelper.Info($"满托任务生成处理,任务类型:{mst.S_TYPE}"); |
| | | string startArea = ""; |
| | | LinZhiBCPWorkOrder bcpW = null; |
| | | bcpW = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_WorkNo == mst.S_WORK_NO && a.S_WorkState == "执行中").First(); |
| | | LogHelper.Info($"满托任务生成处理,工单:{JsonConvert.SerializeObject(bcpW)}"); |
| | | if (mst.S_TYPE.Contains("瓶盖")) |
| | | { |
| | | //瓶盖无即产即用和非即产即用 |
| | | var bcpInfo = Settings.areaInfos.Where(a => a.areaName == "瓶盖非即产满框" && a.enable == 1).FirstOrDefault(); |
| | | if (bcpInfo != null) |
| | | { |
| | | startLoca = DeviceProcess.getFDSXArea(db, bcpW, bcpInfo.areaCode); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (bcpW.S_UsingNow == "Y") |
| | | { |
| | | LogHelper.Info($"瓶坯即产满框 查找"); |
| | | startArea = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产满框" && a.enable == 1).FirstOrDefault().areaCode; |
| | | startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea); |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"瓶坯翻斗机非即产满框 查找"); |
| | | string areaName = bcpW.S_PLineNo.Split('-')[1].Substring(0, 1) + "号瓶坯翻斗机非即产满框"; |
| | | startArea = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).FirstOrDefault().areaCode; |
| | | startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea); |
| | | } |
| | | } |
| | | |
| | | if (startLoca != null) |
| | | { |
| | | LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca)); |
| | | string taskType = ""; |
| | | if (mst.S_TYPE == "翻斗机即产空托下线(瓶坯)") taskType = "翻斗机即产满托上线(瓶坯)"; |
| | | if (mst.S_TYPE == "翻斗机库存空托下线(瓶坯)") taskType = "翻斗机库存满托上线(瓶坯)"; |
| | | if (mst.S_TYPE == "翻斗机库存空托下线(瓶盖)") taskType = "翻斗机库存满托上线(瓶盖)"; |
| | | var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_CODE).First(); |
| | | if (cntrInfo != null) |
| | | { |
| | | WMSHelper.CreateOpTask(startLoca.S_CODE, mst.S_START_LOC, "出库", taskType, cntrInfo.S_CNTR_CODE,"","",bcpW.S_WorkNo); |
| | | } |
| | | else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_CODE}"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static void claimGoodsTime(WCSTask mst, int state) |
| | |
| | | internal static bool SendTask(WCSTask mst) |
| | | { |
| | | var result = false; |
| | | var start = "0"; var end = "0"; |
| | | var taskType = mst.S_TYPE.Trim(); |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | if (mst.N_B_STATE == 0) |
| | | { |
| | | //if (mst.S_SCHEDULE_TYPE == "NDC") { |
| | | // start = LocationHelper.GetAgvSite(mst.S_START_LOC); |
| | | // end = LocationHelper.GetAgvSite(mst.S_END_LOC); |
| | | // |
| | | // |
| | | // Console.WriteLine($"SendTask {mst.S_CODE}"); |
| | | // Console.WriteLine("start=" + start); |
| | | // Console.WriteLine("end= " + end); |
| | | // var dic = new Dictionary<string, string>(); |
| | | // dic.Add("Pri", mst.N_PRIORITY.ToString()); |
| | | // dic.Add("From", start.ToString()); |
| | | // dic.Add("To", end.ToString()); |
| | | // dic.Add("No", mst.S_CODE.Trim());// dic.Add("Ext1", "1"); dic.Add("Ext2", "CALLADDAGV"); dic.Add("N_CNTR_COUNT", ""); |
| | | // var res = NDC.AddNewOrder(1, dic); |
| | | // if (res != null && (res.Res.ErrCode == 0 || res.Res.ErrCode == 50009)) { |
| | | // //推送成功,修改任务优先级 |
| | | mst.N_B_STATE = 1; |
| | | WCSHelper.UpdateStatus(mst, "已推送"); |
| | | result = true; |
| | | // } |
| | | // } |
| | | // else if (mst.S_SCHEDULE_TYPE == "WCS") { |
| | | // //调第三方接口 |
| | | // var model = new HanAo.TaskInfoModel |
| | | // { |
| | | // requestPk = mst.S_CODE, |
| | | // frmPos = mst.S_START_LOC, |
| | | // toPos = mst.S_END_LOC, |
| | | // trkType = mst.S_OP_NAME == "入库" ? "1" : "2", |
| | | // contNo = mst.S_CNTR_CODE |
| | | // }; |
| | | // //if (HanAo.CreateOrder(model)) { |
| | | // mst.N_B_STATE = 1; |
| | | // WCSHelper.UpdateStatus(mst); |
| | | // //} |
| | | // } |
| | | try |
| | | { |
| | | int TsNo = 1;//下发任务类型:默认-1 坯盖-6 成品任务-5 |
| | | var Extend1 = "0";//取货站点 |
| | | var Extend2 = "0";//卸货站点 |
| | | string Extend3 = "";//功能码 16进制转10进制 |
| | | string Extend4 = "";//坯盖:托盘类型 即产即用1,非即产即用2 不区分为1 成品:取卸货层数(先单独转换为16进制,再拼接转换为10进制) |
| | | string Extend5 = "";//物料高度(品相) 根据工单物料到物料表获取下发TS的物料高度 |
| | | string Extend6 = "";//托盘版型 备注:小板 1,集化板 2,小板超托 3,集化板超托 4 根据工单版型转换为对应的值 |
| | | string Extend7 = "";//起点列 |
| | | string Extend8 = "";//终点列 |
| | | int startLayer = mst.N_START_LAYER;// 起点取货层数 |
| | | int endLayer = mst.N_END_LAYER;// 终点卸货层数 |
| | | string workNo = mst.S_WORK_NO;// 工单号 |
| | | string trayType = mst.S_NOTE;//托盘类型-根据各自现场情况获取 |
| | | var taskType = mst.S_TYPE;// 任务类型 |
| | | |
| | | // 获取起终点的AGV站点 查询 扩展货位表 S_PICKUP_POINT-点位层数 S_LOC_CODE-货位编码 GetAgvSite-标准获取扩展货位表数据的方法 |
| | | //Extend1 = LocationHelper.GetAgvSite(mst.S_START_LOC, startLayer.ToString()); |
| | | //Extend2 = LocationHelper.GetAgvSite(mst.S_END_LOC, endLayer.ToString()); |
| | | //二期成品任务类型(将 成品车间 任务类型加入到此数组中,即可根据 任务类型 区分车间,并获取对应的TS参数) |
| | | string[] ConveryTaskList = new string[] { "成品下线", "栈板上线", "零头下线" }; |
| | | if (ConveryTaskList.Contains(taskType) || taskType.Contains("移库")) |
| | | { |
| | | TsNo = 5; |
| | | |
| | | if (taskType.Contains("栈板上线")) |
| | | { |
| | | Extend1 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_START_LOC && a.N_LAYER == mst.N_START_LAYER).First().S_AGV_SITE; |
| | | Extend2 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC && a.N_LAYER == mst.N_END_LAYER).First().S_AGV_SITE; |
| | | |
| | | var startLoc = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_START_LOC).First(); |
| | | var endLoc = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC).First(); |
| | | int startCol = int.Parse(startLoc.N_COL.ToString()); |
| | | int endCol = int.Parse(endLoc.N_COL.ToString()); |
| | | Extend7 = (startCol - 1).ToString(); |
| | | Extend8 = (endCol - 1).ToString(); |
| | | } |
| | | else |
| | | { |
| | | // 成品任务下发参数获取 |
| | | |
| | | var startLoc = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_START_LOC).First(); |
| | | var endLoc = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC).First(); |
| | | int startCol = int.Parse(startLoc.N_COL.ToString()); |
| | | int endCol = int.Parse(endLoc.N_COL.ToString()); |
| | | var startLocInfo = db.Queryable<SegmentTable>().Where(a => a.S_AREA_CODE == startLoc.S_AREA_CODE && a.N_ROW == startLoc.S_ROW && a.S_START_COL <= startCol && a.S_END_COL >= startCol).First(); |
| | | var endLocInfo = db.Queryable<SegmentTable>().Where(a => a.S_AREA_CODE == endLoc.S_AREA_CODE && a.N_ROW == endLoc.S_ROW && a.S_START_COL <= endCol && a.S_END_COL >= endCol).First(); |
| | | |
| | | if (startLocInfo != null) |
| | | { |
| | | Extend1 = mst.N_START_LAYER == 1 ? startLocInfo.S_First_Bit : startLocInfo.S_Second_Bit; |
| | | if (trayType.Contains("集化板")) Extend1 = Extend1 + 2; |
| | | |
| | | Extend7 = (startCol - startLocInfo.S_START_COL).ToString(); |
| | | } |
| | | else LogHelper.Info($"任务异常:{mst.S_CODE},自由线段表无可用起点货位数据。起点货位编码:{mst.S_START_LOC}"); |
| | | if (endLocInfo != null) |
| | | { |
| | | Extend2 = mst.N_END_LAYER == 1 ? endLocInfo.S_First_Bit : endLocInfo.S_Second_Bit; |
| | | Extend8 = (endCol - endLocInfo.S_START_COL).ToString(); |
| | | } |
| | | else LogHelper.Info($"任务异常:{mst.S_CODE},自由线段表无可用终点货位数据。终点货位编码:{mst.S_END_LOC}"); |
| | | |
| | | // 其他功能码可以根据任务类型自行添加(此处仅示例 移库 功能码获取方式,如果有更好的方式,可以自行修改) |
| | | if (taskType.Contains("移库")) Extend3 = Convert.ToInt32("20", 16).ToString(); |
| | | |
| | | } |
| | | |
| | | // 获取成品工单数据(查询 成品工单表) |
| | | if (taskType.Contains("移库")) |
| | | { |
| | | var workInfo = db.Queryable<YiKuWorkOrder>().Where(a => a.S_WorkNo == workNo).First(); |
| | | if (workInfo != null) |
| | | { |
| | | LogHelper.Info($"{workInfo.S_ORDER_TYPE}"); |
| | | // 获取下发TS物料层数数据(查询 物料表) |
| | | if (workInfo.S_ORDER_TYPE.Contains("移库")) |
| | | { |
| | | LogHelper.Info($"物料编码:{mst.S_ITEM_CODE},栈板类型:{trayType},物料规格:{workInfo.S_ItemLayer}"); |
| | | var itemInfo1 = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == mst.S_ITEM_CODE && a.S_TRAY_TYPE == trayType && a.S_ITEM_MODEL == workInfo.S_ItemLayer).First(); |
| | | if (itemInfo1 != null) |
| | | { |
| | | Extend5 = itemInfo1.S_ITEM_LAYER; |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"物料表未维护信息,物料编码:{mst.S_ITEM_CODE},栈板类型:{trayType},物料规格:{workInfo.S_ItemLayer}"); |
| | | } |
| | | //if (workInfo.S_ORDER_TYPE == "无码入库" && endLayer == 1) Extend5 = ""; |
| | | } |
| | | |
| | | // 根据工单中托盘类型转换为对应的下发TS参数数据 |
| | | LogHelper.Info($"S_TRAY_TYPE:{trayType}"); |
| | | LogHelper.Info($"Extend5:{Extend5}"); |
| | | int x = 0; |
| | | if (trayType == "小板") x = 1; |
| | | if (trayType == "集化板") x = 2; |
| | | if (trayType == "小板超托") x = 3; |
| | | if (trayType == "集化板超托") x = 4; |
| | | |
| | | Extend6 = x.ToString(); |
| | | |
| | | } |
| | | } |
| | | else |
| | | { |
| | | var workInfo = db.Queryable<LinZhiWorkOrder>().Where(a => a.S_WorkNo == workNo).First(); |
| | | if (workInfo != null) |
| | | { |
| | | LogHelper.Info($"{workInfo.S_ORDER_TYPE}"); |
| | | // 获取下发TS物料层数数据(查询 物料表) |
| | | if (workInfo.S_ORDER_TYPE.Contains("下线") || workInfo.S_ORDER_TYPE == "无码入库") |
| | | { |
| | | var itemInfo1 = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == workInfo.S_ItemCode && a.S_TRAY_TYPE == trayType && a.S_ITEM_MODEL == workInfo.S_ItemLayer).First(); |
| | | if (itemInfo1 != null) |
| | | { |
| | | Extend5 = itemInfo1.S_ITEM_LAYER; |
| | | } |
| | | //if (workInfo.S_ORDER_TYPE == "无码入库" && endLayer == 1) Extend5 = ""; |
| | | } |
| | | |
| | | // 根据工单中托盘类型转换为对应的下发TS参数数据 |
| | | LogHelper.Info($"S_TRAY_TYPE:{trayType}"); |
| | | int x = 0; |
| | | if (trayType == "小板") x = 1; |
| | | if (trayType == "集化板") x = 2; |
| | | if (trayType == "小板超托") x = 3; |
| | | if (trayType == "集化板超托") x = 4; |
| | | |
| | | Extend6 = x.ToString(); |
| | | |
| | | } |
| | | } |
| | | |
| | | // 获取 任务参数4 DATA 数据 |
| | | string startLayerValue = Convert.ToString(startLayer, 16).ToUpper(); |
| | | string endLayerValue = Convert.ToString(endLayer, 16).ToUpper(); |
| | | //Extend4 = Convert.ToInt32(startLayerValue + endLayerValue, 16).ToString(); |
| | | Extend4 = ((startLayer * 16) + endLayer).ToString(); |
| | | } |
| | | else |
| | | { |
| | | TsNo = 1; |
| | | // 坯盖任务下发参数获取 |
| | | // 获取起终点的AGV站点 |
| | | Extend1 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_START_LOC).First().S_AGV_SITE; |
| | | Extend2 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC).First().S_AGV_SITE; |
| | | if (mst.N_START_LAYER > 1) |
| | | { |
| | | Extend1 = db.Queryable<LocationExt>().Where(a => a.S_LOC_CODE == mst.S_START_LOC && a.N_LAYER == mst.N_START_LAYER).First().S_AGV_SITE; |
| | | } |
| | | if (mst.N_END_LAYER > 1) |
| | | { |
| | | Extend2 = db.Queryable<LocationExt>().Where(a => a.S_LOC_CODE == mst.S_END_LOC && a.N_LAYER == mst.N_END_LAYER).First().S_AGV_SITE; |
| | | } |
| | | if(mst.S_TYPE == "瓶坯非急产补满框" || mst.S_TYPE == "瓶盖非急产补满框" || mst.S_TYPE == "瓶坯非急产补空框" || mst.S_TYPE == "瓶盖非急产补空框" || mst.S_TYPE == "注塑即产满托下线(瓶坯)") |
| | | { |
| | | Extend2 = Settings.dXSites.Where(it => it.loc == mst.S_END_LOC).First().site.ToString(); |
| | | } |
| | | |
| | | Extend3 = "0"; |
| | | // 获取 任务参数4 DATA 数据 |
| | | string startLayerValue = Convert.ToString(startLayer, 16).ToUpper(); |
| | | string endLayerValue = Convert.ToString(endLayer, 16).ToUpper(); |
| | | //Extend4 = Convert.ToInt32(startLayerValue + endLayerValue, 16).ToString(); |
| | | Extend4 = ((startLayer * 16) + endLayer).ToString(); |
| | | //Extend4 = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_WorkNo == workNo).First().S_UsingNow == "N" ? "2" : "1"; |
| | | |
| | | //瓶坯注塑机站点根据配置文件获取 |
| | | if (taskType.Contains("注塑") && taskType.Contains("瓶坯")) |
| | | { |
| | | var devInfo = Settings.deviceInfos.Where(a => (a.TN_Location.Contains(mst.S_START_LOC) || a.TN_Location.Contains(mst.S_END_LOC)) && a.enable == 1).FirstOrDefault(); |
| | | string machine = (devInfo.TN_Location[0] == mst.S_START_LOC || devInfo.TN_Location[0] == mst.S_END_LOC) ? "A" : "B"; |
| | | string machineTwo = devInfo.deviceName.Split('-')[1] + machine; |
| | | LogHelper.Info($"机台:{machineTwo}"); |
| | | var siteInfo = Settings.pPZSJSites.Where(a => a.siteName == machineTwo && a.enable == 1).FirstOrDefault(); |
| | | if (siteInfo != null) |
| | | { |
| | | if (taskType.Contains("空托上线")) |
| | | { |
| | | //改变终点站点 |
| | | Extend2 = siteInfo.site[1]; |
| | | } |
| | | else |
| | | { |
| | | //改变起点站点 |
| | | Extend1 = siteInfo.site[0]; |
| | | } |
| | | } |
| | | else LogHelper.Info("配置文件未配置瓶坯注塑机站点"); |
| | | } |
| | | } |
| | | |
| | | Console.WriteLine($"[SendTask]:TaskNo={mst.S_CODE.Trim()},start={Extend1},end={Extend2}"); |
| | | LogHelper.Info($"[SendTask]:TaskNo={mst.S_CODE.Trim()},start={Extend1},end={Extend2}"); |
| | | bool action = true; |
| | | //var dic = new Dictionary<string, string>(); |
| | | ////var dic1 = new Dictionary<string, string>(); |
| | | ////dic.Add("Pri", mst.N_PRIORITY.ToString()); |
| | | ////dic.Add("No", mst.S_CODE.Trim()); |
| | | //dic.Add("From", Extend1); |
| | | //dic.Add("To", Extend2); |
| | | //dic.Add("Func", Extend3); |
| | | //dic.Add("Data", Extend4); |
| | | // |
| | | //if (ConveryTaskList.Contains(taskType) || taskType.Contains("移库")) |
| | | //{ |
| | | // dic.Add("ItemHeight", Extend5); |
| | | // dic.Add("CntrType", Extend6); |
| | | // dic.Add("FromCol", Extend7); |
| | | // dic.Add("ToCol", Extend8); |
| | | // if (taskType.Contains("移库") || taskType.Contains("成品下线") || taskType.Contains("零头下线")) |
| | | // { |
| | | // LogHelper.Info($"移库:Extend5:{Extend5},Extend6:{Extend6},Extend7:{Extend7},Extend8:{Extend8},"); |
| | | // if (Extend5 == "" || Extend6 == "" || Extend7 == "" || Extend8 == "") |
| | | // { |
| | | // action = false; |
| | | // } |
| | | // } |
| | | //} |
| | | var dic = new List<param> |
| | | { |
| | | new param() { name = "From", value = Extend1 }, |
| | | new param() { name = "To", value = Extend2 }, |
| | | new param() { name = "Func", value = Extend3 }, |
| | | new param() { name = "Data", value = Extend4 } |
| | | }; |
| | | if (ConveryTaskList.Contains(taskType) || taskType.Contains("移库")) |
| | | { |
| | | dic.Add(new param(){name = "ItemHeight", value = Extend5}); |
| | | dic.Add(new param(){name = "CntrType", value = Extend6}); |
| | | dic.Add(new param(){name = "FromCol", value = Extend7}); |
| | | dic.Add(new param(){name = "ToCol", value = Extend8}); |
| | | if (taskType.Contains("移库") || taskType.Contains("成品下线") || taskType.Contains("零头下线")) |
| | | { |
| | | LogHelper.Info($"移库:Extend5:{Extend5},Extend6:{Extend6},Extend7:{Extend7},Extend8:{Extend8},"); |
| | | if (Extend5 == "" || Extend6 == "" || Extend7 == "" || Extend8 == "") |
| | | { |
| | | action = false; |
| | | } |
| | | } |
| | | } |
| | | if (action) |
| | | { |
| | | var res = new AgvApiResult(); |
| | | //res = NDC.AddNewOrderNew(TsNo,mst.N_PRIORITY,mst.S_CODE, dic); |
| | | res = NDCApi.AddOrderNew(TsNo, mst.N_PRIORITY, mst.S_CODE,dic); |
| | | |
| | | if (res != null && (res.err_code == 0 || res.err_code == 50009)) |
| | | { |
| | | mst.N_B_STATE = 1; |
| | | WCSHelper.UpdateStatus(mst, "已推送"); |
| | | result = true; |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Error($"SendTaskStandard Error:{ex.Message}", ex); |
| | | } |
| | | |
| | | //mst.N_B_STATE = 1; |
| | | //WCSHelper.UpdateStatus(mst, "已推送"); |
| | | //result = true; |
| | | } |
| | | return result; |
| | | } |
| | |
| | | /// 半成品出入库 |
| | | /// </summary> |
| | | /// <param name="db"></param> |
| | | /// <param name="action">true:入库 false:出库</param> |
| | | /// <param name="startCode"></param> |
| | | /// <param name="action"></param> |
| | | /// <param name="areaName"></param> |
| | | /// <param name="itemCode"></param> |
| | | /// <returns></returns> |
| | | public static Location BCPInOrOut(SqlSugarClient db, bool action, string startCode = "", string areaName = "", LinZhiBCPWorkOrder workInfo = null) |
| | | public static Location BCPInOrOut(SqlSugarClient db, bool action, string areaName,string itemCode) |
| | | { |
| | | Location result = null; |
| | | if (action) |
| | | { |
| | | var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startCode).First(); |
| | | var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First(); |
| | | if (itemInfo != null) |
| | | //瓶盖库区,两层密集型库区 空满在同一个库区,需要区分不同排 |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName.Contains(areaName) && a.enable == 1).OrderByDescending(a => a.pri).ToList(); |
| | | if (areaInfo.Count > 0) |
| | | { |
| | | //瓶盖库区,两层密集型库区 空满在同一个库区,需要区分不同排 |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).First(); |
| | | if (areaInfo != null) |
| | | foreach(var it in areaInfo) |
| | | { |
| | | //库区货位约定:列号越小越靠里 |
| | | LogHelper.Info($"入库算法01:area:{areaInfo.areaCode},itemCode:{itemInfo.S_ITEM_CODE},itemBatch:{itemInfo.S_BATCH_NO}", "WMSAlgoRithm"); |
| | | LogHelper.Info($"入库算法01:area:{it.areaCode},itemCode:{itemCode}"); |
| | | try |
| | | { |
| | | if (result == null) |
| | | { |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL) |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == it.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL) |
| | | .PartitionBy(a => a.N_ROW).Take(1) |
| | | .ToList(); |
| | | if (locInfo.Count > 0) |
| | | { |
| | | LogHelper.Info($"入库算法02:查询到可入货位的数量为:{locInfo.Count}"); |
| | | foreach (var a in locInfo) |
| | | { |
| | | string itemCode = ""; |
| | | var endCntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First(); |
| | | if (endCntrInfo != null) |
| | | { |
| | | var endItemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == endCntrInfo.S_CNTR_CODE).First(); |
| | | if (endItemInfo != null) |
| | | { |
| | | itemCode = endItemInfo.S_ITEM_CODE; |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"终点货位未绑定物料信息"); |
| | | continue; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"终点货位未绑定托盘信息"); |
| | | continue; |
| | | } |
| | | |
| | | LogHelper.Info($"入库算法03:查询货位:{a.S_CODE},锁状态:{a.S_LOCK_STATE},当前数量:{a.N_CURRENT_NUM}"); |
| | | //去掉当前货位有锁,或者为空托的货位 |
| | | if (a.S_LOCK_STATE == "无") |
| | | { |
| | | string endItemCode = ""; |
| | | var endCntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First(); |
| | | if (endCntrInfo != null) |
| | | { |
| | | var endItemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == endCntrInfo.S_CNTR_CODE).First(); |
| | | if (endItemInfo != null) |
| | | { |
| | | endItemCode = endItemInfo.S_ITEM_CODE; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"终点货位未绑定托盘信息"); |
| | | continue; |
| | | } |
| | | LogHelper.Info($"入库算法04:查询到当前货位绑定的物料编码为:{endItemCode}"); |
| | | //判断是否和当前货位的物料编码相同 |
| | | if (itemCode == itemInfo.S_ITEM_CODE) |
| | | if (itemCode == endItemCode) |
| | | { |
| | | //查询当前排是否可入(判断是是否有入库锁和出库锁) |
| | | var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First(); |
| | |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"入库算法05:查询到当前排有锁,排号:{a.N_ROW}"); |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"入库算法02:未查询到可入货位"); |
| | | } |
| | | if (result == null) |
| | | { |
| | |
| | | #region 查找所有数量是空的排 |
| | | LogHelper.Info($"入库算法06:无可用货位,获取空排货位。", "WMSAlgoRithm"); |
| | | //2.0 简化查询只查每一排第一列 |
| | | var list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode).OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList(); |
| | | var list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == it.areaCode).OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList(); |
| | | //2.1 选一个空排 |
| | | if (list.Count > 0) |
| | | { |
| | |
| | | } |
| | | } |
| | | } |
| | | else LogHelper.Info($"未获取到空排,库区编码:{areaInfo.areaCode}"); |
| | | else LogHelper.Info($"未获取到空排,库区编码:{it.areaCode}"); |
| | | #endregion |
| | | } |
| | | |
| | | if(result != null) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | |
| | | LogHelper.Error("GetLocationIn:" + ex.Message, ex); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"入库任务 瓶盖库区未配置"); |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"入库任务 起点货位未绑定物料信息"); |
| | | LogHelper.Info($"入库任务:{areaName}未配置"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string itemCode = ""; |
| | | if (string.IsNullOrEmpty(startCode)) |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName.Contains(areaName) && a.enable == 1).OrderByDescending(a => a.pri).ToList(); |
| | | if(areaInfo.Count > 0) |
| | | { |
| | | var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startCode).First(); |
| | | var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First(); |
| | | if(itemInfo != null) |
| | | foreach(var it in areaInfo) |
| | | { |
| | | itemCode = itemInfo.S_ITEM_CODE; |
| | | LogHelper.Info($"出库算法01:area:{it.areaName},itemCode:{itemCode}"); |
| | | var locList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == it.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).Includes(a => a.LocCntrRel).ToList(); |
| | | if (locList.Count > 0) |
| | | { |
| | | LogHelper.Info($"出库算法02:查询到可出货位数量:{locList.Count}"); |
| | | foreach (var a in locList) |
| | | { |
| | | LogHelper.Info($"出库算法03:查询货位:{a.S_CODE},锁状态:{a.S_LOCK_STATE}"); |
| | | if (a.S_LOCK_STATE == "无") |
| | | { |
| | | var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First(); |
| | | if (cntrInfo != null) |
| | | { |
| | | LogHelper.Info($"出库算法04:当前货位绑定的托盘码为:{cntrInfo.S_CNTR_CODE}"); |
| | | string endItemCode = ""; |
| | | var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First(); |
| | | if (itemInfo != null && itemInfo.S_ITEM_CODE == itemCode) |
| | | { |
| | | endItemCode = itemInfo.S_ITEM_CODE; |
| | | } |
| | | if (endItemCode == itemCode) |
| | | { |
| | | //判断当前排有无锁 |
| | | var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == it.areaCode && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First(); |
| | | if (lockInfo == null) |
| | | { |
| | | result = a; |
| | | break; |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"出库算法05:当前排有锁,货位号:{lockInfo.S_CODE}"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if(result != null) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"出库算法01:{areaName}未配置"); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | internal static Location getMStartLoc(SqlSugarClient db, string usingNow) |
| | | { |
| | | Location result = null; |
| | | if(usingNow == "Y") |
| | | { |
| | | //即产即用 |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产空框" && a.enable == 1).FirstOrDefault(); |
| | | if (areaInfo != null) |
| | | { |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First(); |
| | | if (locInfo != null) |
| | | { |
| | | result = locInfo; |
| | | } |
| | | } |
| | | if (workInfo != null) |
| | | else |
| | | { |
| | | itemCode = workInfo.S_ItemCode; |
| | | LogHelper.Info("瓶坯即产空框未配置"); |
| | | } |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).FirstOrDefault(); |
| | | if(areaInfo != null) |
| | | } |
| | | else |
| | | { |
| | | //非即产即用 |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产空框" && a.enable == 1).FirstOrDefault(); |
| | | if (areaInfo != null) |
| | | { |
| | | var locList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).Includes(a => a.LocCntrRel).ToList(); |
| | | if(locList.Count > 0) |
| | | { |
| | | foreach(var a in locList) |
| | | { |
| | | if(a.S_LOCK_STATE == "无") |
| | | int row = a.N_ROW; |
| | | var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_ROW == row && b.S_LOCK_STATE.Contains("锁")).First(); |
| | | if(lockInfo == null) |
| | | { |
| | | var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First(); |
| | | if(cntrInfo != null) |
| | | { |
| | | var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First(); |
| | | if(itemInfo != null && itemInfo.S_ITEM_CODE == itemCode) |
| | | { |
| | | //判断当前排有无锁 |
| | | var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First(); |
| | | if(lockInfo == null) |
| | | { |
| | | result = a; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | result = a; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"{areaName}未配置"); |
| | | LogHelper.Info("瓶坯非即产空框未配置"); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | internal static Location getMStartLoc(SqlSugarClient db) |
| | | { |
| | | Location result = null; |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯注塑机空托" && a.enable == 1).FirstOrDefault(); |
| | | if(areaInfo != null) |
| | | { |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First(); |
| | | if(locInfo != null) |
| | | { |
| | | result = locInfo; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info("瓶坯注塑机空托未配置"); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | |
| | | /// <param name="taskName"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="NotImplementedException"></exception> |
| | | internal static Location BCPFullOut(SqlSugarClient db, string taskName, string S_START_LOC) |
| | | internal static Location BCPFullOut(SqlSugarClient db, string taskName, string itemCode) |
| | | { |
| | | Location result = null; |
| | | |
| | | LogHelper.Info($"瓶坯注塑满托下线:类型:{taskName},物料编码:{itemCode}"); |
| | | if (taskName.Contains("即产")) |
| | | { |
| | | //即产即用工单,下线到即产即用库区 |
| | | //即产即用库区有两个线边库,如果即产即用A库区满,则放到即产即用B库区,若即产即用库区都满,则放到瓶坯库区 |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产即用A" && a.enable == 1).FirstOrDefault(); |
| | | //注塑机急产即用下线,首先下线到即产即用满框线边,满眶线边满了,下到即产即用满框缓存区,满框缓存区满了,下到入库接驳堆叠位 |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产满框" && a.enable == 1).FirstOrDefault(); |
| | | if(areaInfo != null) |
| | | { |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First(); |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_ROW).First(); |
| | | if(locInfo != null) |
| | | { |
| | | result = locInfo; |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"瓶坯注塑满托下线:瓶坯即产满框 未配置"); |
| | | } |
| | | if (result == null) |
| | | { |
| | | result = TaskProcess.BCPInOrOut(db, true, S_START_LOC, "瓶坯即产即用B"); |
| | | result = TaskProcess.BCPInOrOut(db, true, "瓶坯即产满框缓存", itemCode); |
| | | } |
| | | if(result == null) |
| | | { |
| | | result = TaskProcess.BCPInOrOut(db, true, S_START_LOC,"瓶坯库区"); |
| | | result = getJBLoc(db, result); |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | //非即产即用工单,下线到非即产即用库区 |
| | | //非即产即用库区只有一个线边库,如果线边库满,则放到瓶坯库区 |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产即用" && a.enable == 1).FirstOrDefault(); |
| | | if (areaInfo != null) |
| | | { |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First(); |
| | | if (locInfo != null) |
| | | { |
| | | result = locInfo; |
| | | } |
| | | result = getJBLoc(db, result); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | } |
| | | if (result == null) |
| | | private static Location getJBLoc(SqlSugarClient db, Location result) |
| | | { |
| | | //注塑机非即产即用下线,下到入库接驳堆叠位 |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯入库接驳" && a.enable == 1).FirstOrDefault(); |
| | | if (areaInfo != null) |
| | | { |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First(); |
| | | if (locInfo != null) |
| | | { |
| | | result = TaskProcess.BCPInOrOut(db, true, S_START_LOC, "瓶坯库区"); |
| | | result = locInfo; |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info("瓶坯注塑满托下线:瓶坯入库接驳位暂时未查询到可用货位"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"瓶坯注塑满托下线:瓶坯入库接驳 未配置"); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | |
| | | internal static Location BCPEmptyOut(SqlSugarClient db, string taskName) |
| | | { |
| | | Location result = null; |
| | | //翻斗机库存空托下线(瓶盖) |
| | | string endAreaName = taskName.Contains("瓶盖") ? "瓶盖空托" : "瓶坯空托"; |
| | | |
| | | string endAreaName = taskName.Contains("瓶盖") ? "瓶盖非即产空框" : taskName.Contains("库存") ? "瓶坯非即产空框" : "瓶坯即产空框"; |
| | | var areaInfo = Settings.areaInfos.Where(a => a.areaName == endAreaName && a.enable == 1).FirstOrDefault(); |
| | | if(areaInfo != null) |
| | | if (areaInfo != null) |
| | | { |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First(); |
| | | if(locInfo != null) |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_ROW).First(); |
| | | if (locInfo != null) |
| | | { |
| | | result = locInfo; |
| | | } |
| | |
| | | { |
| | | LogHelper.Info($"{endAreaName}未配置"); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// FuLeWebPost |
| | | /// </summary> |
| | | /// <param name="param">发送内容</param> |
| | | /// <param name="postName">接口名称</param> |
| | | /// <param name="Par1">扩展参数</param> |
| | | /// <returns></returns> |
| | | public static SimpleResult FuLeWebPost(string param, string postName, string Par1 = "", bool extend = false) |
| | | { |
| | | string msg = ""; string feedback = ""; |
| | | SimpleResult result = new SimpleResult(); |
| | | try |
| | | { |
| | | string webAPIUrl = ""; |
| | | var httpVerify = new Settings.httpApiVerify(); |
| | | if (extend) httpVerify = Settings.httpApiVerifys.Where(a => a.VerifyNo == "2" && a.Project == Settings.ProjectName && a.enable == 1).FirstOrDefault(); |
| | | else httpVerify = Settings.httpApiVerifys.Where(a => a.VerifyNo == "1" && a.Project == Settings.ProjectName && a.enable == 1).FirstOrDefault(); |
| | | if (httpVerify != null) |
| | | { |
| | | //采用接口加密方式进行传输 |
| | | webAPIUrl = $"{Par1}{postName}"; |
| | | string TokenMsg = ""; |
| | | string timestamp = DateTime.Now.ToString("s").Replace("T", " "); |
| | | TokenMsg = httpVerify.Extend[0] + "from" + httpVerify.Extend[1] + "timestamp" + timestamp; |
| | | LogHelper.Info($"【FuLe Post {postName}】:加密前明文:{TokenMsg}", "ThirdSystemLog"); |
| | | string TokenMsgEncrypt = CryptoDecryptHelper.GetMd5FromString(TokenMsg); |
| | | LogHelper.Info($"【FuLe Post {postName}】:加密后密文:{TokenMsgEncrypt}", "ThirdSystemLog"); |
| | | feedback = httpHelper.WebPost(webAPIUrl, param, "application/json", TokenMsgEncrypt, timestamp,"", extend); |
| | | } |
| | | else |
| | | { |
| | | //标准传输方式传输 |
| | | webAPIUrl = $"{Par1}{postName}" + "&warehouseId=FLUXWMSDB"; |
| | | feedback = httpHelper.WebPost(webAPIUrl, param); |
| | | } |
| | | |
| | | if (!string.IsNullOrEmpty(feedback)) |
| | | { |
| | | LogHelper.Info(JsonConvert.SerializeObject(feedback)); |
| | | msg = $"【FuLe Post {postName}】WebUrl={webAPIUrl};param={param} ;return={feedback}"; |
| | | var req = JsonConvert.DeserializeObject<SimpleResult>(feedback); |
| | | if (req.success) |
| | | { |
| | | result.success = true; |
| | | msg = $"【FuLe Post {postName}】success!;WebUrl={webAPIUrl};param={param};return={feedback}"; |
| | | } |
| | | else |
| | | { |
| | | if (!string.IsNullOrEmpty(req.errMsg)) msg = $"【FuLe Post {postName}】fail!err={req.errMsg};WebUrl={webAPIUrl} ;param={param};return={feedback}"; |
| | | else msg = $"【FuLe Post {postName}】fail!err={req.message};WebUrl={webAPIUrl} ;param={param};return={feedback}"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string errMsg = "can't find the address"; |
| | | msg = $"【FuLe Post {postName}】fail!err={errMsg};WebUrl={webAPIUrl} ;param={param}"; |
| | | } |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var RepeatUrl = db.Queryable<HttpRepeatSend>().Where(a => a.SendMsg == param && a.UrlName == postName && a.Url == Par1).First(); |
| | | if (result.success) |
| | | { |
| | | if (RepeatUrl != null) db.Deleteable<HttpRepeatSend>().Where(a => a.SendMsg == param && a.UrlName == postName && a.Url == Par1).ExecuteCommand(); |
| | | } |
| | | else |
| | | { |
| | | if (RepeatUrl == null) |
| | | { |
| | | var RepeatInfo = new HttpRepeatSend() |
| | | { |
| | | SendMsg = param, |
| | | UrlName = postName, |
| | | Url = Par1, |
| | | SendNum = 5 |
| | | }; |
| | | db.Insertable(RepeatInfo).ExecuteCommand(); |
| | | } |
| | | else |
| | | { |
| | | if (RepeatUrl.SendNum == 1) db.Deleteable<HttpRepeatSend>().Where(a => a.SendMsg == param && a.UrlName == postName && a.Url == Par1).ExecuteCommand(); |
| | | else |
| | | { |
| | | RepeatUrl.SendNum = RepeatUrl.SendNum - 1; |
| | | db.Updateable(RepeatUrl).UpdateColumns(a => new { a.SendNum }).ExecuteCommand(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | msg = $"【FuLe Post {postName}】fail!err={ex.Message}"; |
| | | } |
| | | LogHelper.Info(msg, "ThirdSystemLog"); |
| | | return result; |
| | | } |
| | | /// <summary> |
| | | /// 接口状态回报处理 |
| | | /// </summary> |
| | | public class SimpleResult |
| | | { |
| | | public bool success { get; set; } |
| | | public int errCode { get; set; } |
| | | public string errMsg { get; set; } = ""; |
| | | |
| | | /// <summary> |
| | | /// 淳安二期-响应数据 |
| | | /// </summary> |
| | | public Object data { get; set; } |
| | | /// <summary> |
| | | /// 淳安二期-响应编码 |
| | | /// </summary> |
| | | public string code { get; set; } |
| | | /// <summary> |
| | | /// 淳安二期-响应信息 |
| | | /// </summary> |
| | | public string message { get; set; } |
| | | /// <summary> |
| | | /// 淳安二期-响应信息类型 |
| | | /// </summary> |
| | | public string messageType { get; set; } |
| | | /// <summary> |
| | | /// 淳安二期-异常 |
| | | /// </summary> |
| | | public Exception exception { get; set; } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 任务信息接口--获取AGV设备信息数据 |
| | | /// </summary> |
| | | /// <param name="wmsTask"></param> |
| | | /// <param name="db"></param> |
| | | /// <param name="equipmentCode"></param> |
| | | /// <param name="orgCode"></param> |
| | | /// <param name="orgName"></param> |
| | | /// <param name="proxyInterfaceCode"></param> |
| | | private static void GeneralInterFaceGetAgvDeviceInfoFunc(WCSTask wmsTask, SqlSugarClient db, ref string equipmentCode, ref string orgCode, ref string orgName, ref string proxyInterfaceCode) |
| | | { |
| | | if (!string.IsNullOrEmpty(wmsTask.S_EQ_NO)) |
| | | { |
| | | var agvDeviceInfo = db.Queryable<AGVDeviceDataTable>().Where(a => a.equipmentNo == wmsTask.S_EQ_NO && a.orgCode == Settings.FactoryCode).First(); |
| | | if (agvDeviceInfo != null) |
| | | { |
| | | equipmentCode = agvDeviceInfo.equipmentCode; |
| | | orgCode = agvDeviceInfo.orgCode; |
| | | orgName = agvDeviceInfo.orgName; |
| | | proxyInterfaceCode = agvDeviceInfo.proxyInterfaceCode; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 任务信息接口--获取托盘数据 |
| | | /// </summary> |
| | | /// <param name="wmsTask"></param> |
| | | private static void GeneralInterFaceGetTrayCodeFunc(WCSTask wmsTask, SqlSugarClient db, List<asnReferenceDModel> asnReferenceList, List<string> cntrList) |
| | | { |
| | | //string SrcNo = wmsTask.S_SRC_NO?.Trim(); |
| | | // |
| | | ////根据任务中存放的工单号,获取工单类型--因为淳安 满托下线任务包含 下线 值,因此多判断一步,减少工单表的查询 |
| | | //if (!string.IsNullOrEmpty(SrcNo) && wmsTask.S_TYPE.Contains("下线")) |
| | | //{ |
| | | // var workInfo = db.Queryable<LinZhiWorkOrder>().Where(a => a.S_WorkNo == SrcNo).First(); |
| | | // if (workInfo != null) |
| | | // { |
| | | // if (workInfo.S_ORDER_TYPE.Trim() != "无码入库") |
| | | // { |
| | | // |
| | | // if (cntrList.Count > 0) |
| | | // { |
| | | // cntrList.ForEach(a => |
| | | // { |
| | | // if (!string.IsNullOrEmpty(a)) |
| | | // asnReferenceList.Add(new asnReferenceDModel { asnReferenceD = a }); |
| | | // }); |
| | | // } |
| | | // } |
| | | // } |
| | | //} |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 任务信息接口--获取物料编码 |
| | | /// </summary> |
| | | /// <param name="wmsTask"></param> |
| | | private static string GeneralInterFaceGetItemCodeFunc(WCSTask wmsTask, SqlSugarClient db, List<string> cntrList, string itemCode) |
| | | { |
| | | if (cntrList.Count > 0) |
| | | { |
| | | //string SrcNo = wmsTask.S_SRC_NO?.Trim(); |
| | | //// 农夫网管下发的工单,物料获取方式 |
| | | //if (!string.IsNullOrEmpty(SrcNo) && wmsTask.S_TYPE.Contains("下线")) |
| | | //{ |
| | | // var workInfo = db.Queryable<LinZhiWorkOrder>().Where(a => a.S_WorkNo == SrcNo).First(); |
| | | // if (workInfo != null) itemCode = workInfo.S_ItemCode; |
| | | //} |
| | | //// 其他的人工建立的工单,物料获取方式 |
| | | //else |
| | | //{ |
| | | // var cntrItemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrList[0]).First(); |
| | | // if (cntrItemInfo != null) |
| | | // { |
| | | // //此处查询 物料表,仅限淳安获取MES物料使用,其他工厂可自行注释;因淳安入库物料是使用 物料名称+物料层数 拼接而成,因此需要 通过物料表转换为 MES 的物料编码 |
| | | // //var itemInfo = db.Queryable<ItemRel>().Where(a => a.S_ITEM_NAME == cntrItemInfo.S_ITEM_CODE).First(); |
| | | // //if (itemInfo != null) itemCode = itemInfo.S_ITEM_CODE; |
| | | // itemCode = cntrItemInfo.S_ITEM_CODE; |
| | | // } |
| | | //} |
| | | } |
| | | |
| | | return itemCode; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 绑定货位容器表 |
| | | /// </summary> |
| | | /// <param name="cntr"></param> |
| | | /// <returns></returns> |
| | | internal static bool BindLocCntr(string loc, string cntr, string itemCode, string batchNo, string deviceName = "", string itemlayer = "") |
| | | { |
| | | LogHelper.Info($"绑定货位容器表,loc:{loc},cntr:{cntr}"); |
| | | bool result = true; |
| | | List<string> list = new List<string>(cntr.Split(',')); |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | list.ForEach(it => |
| | | { |
| | | if (!string.IsNullOrEmpty(it)) |
| | | { |
| | | string cntrCode = it.Trim(); |
| | | var Cntr = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == loc && a.S_CNTR_CODE == cntrCode).First(); |
| | | if (Cntr == null) |
| | | { |
| | | var cir = new LocCntrRel { S_LOC_CODE = loc, S_CNTR_CODE = cntrCode, S_SRC = deviceName }; |
| | | if (db.Insertable<LocCntrRel>(cir).ExecuteCommand() > 0) LogHelper.Info($"货位容器表绑定成功,货位号:{loc},托盘号:{cntrCode}"); |
| | | BindCntrItem(cntrCode, itemCode, batchNo, itemlayer); |
| | | } |
| | | } |
| | | }); |
| | | //1.0 查货位容器表 |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 绑定容器物料表 |
| | | /// </summary> |
| | | /// <param name="itemCode"></param> |
| | | /// <param name="batchNo"></param> |
| | | /// <param name="qty"></param> |
| | | /// <returns></returns> |
| | | internal static bool BindCntrItem(string trayCode, string itemCode, string batchNo, string itemlayer = "") |
| | | { |
| | | LogHelper.Info($"绑定容器物料表,trayCode:{trayCode}"); |
| | | var res = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | try |
| | | { |
| | | db.BeginTran(); |
| | | //db.Updateable(cntr).UpdateColumns(it => new { it.S_DEST }).ExecuteCommand(); |
| | | //1.将原有容器物料信息删除 |
| | | //db.Deleteable<CntrItemRel>().Where(it => it.S_CNTR_CODE == cntr.S_CNTR_CODE.Trim()).ExecuteCommand(); |
| | | //2.插入新的容器物料信息(容器号不变) |
| | | var info = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE.Trim() == trayCode.Trim()).First(); |
| | | if (info == null) |
| | | { |
| | | var cir = new CntrItemRel { S_CNTR_CODE = trayCode, S_BATCH_NO = batchNo, S_ITEM_CODE = itemCode, S_ITEM_MODEL = itemlayer }; |
| | | if (db.Insertable<CntrItemRel>(cir).ExecuteCommand() > 0) LogHelper.Info($"容器物料表绑定成功,托盘号:{trayCode},物料编码:{itemCode},物料层数:{itemlayer}"); |
| | | } |
| | | |
| | | |
| | | db.Ado.CommitTran(); |
| | | res = true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info($"ex:{ex}"); |
| | | db.Ado.RollbackTran(); |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 标准出入库处理 |
| | | /// </summary> |
| | | /// <param name="bit">起点点位 或 终点点位</param> |
| | | /// <param name="taskType">任务类型</param> |
| | | /// <param name="trayCode">托盘编码</param> |
| | | /// <param name="areaCode">库区编码</param> |
| | | /// <param name="itemCode">物料编码</param> |
| | | /// <param name="batchNo">批次号</param> |
| | | /// <param name="itemLayer">物料层数</param> |
| | | /// <param name="itemTrayType">物料托盘类型</param> |
| | | /// <param name="actionType">动作类型 True-入库 False-出库</param> |
| | | /// <returns></returns> |
| | | internal static bool LinZhiPlcTask(string bit, string taskType, string trayCode, string areaCode, string itemCode, string batchNo, string itemLayer, string itemTrayType, string deviceName, bool actionType, string workNo = "") |
| | | { |
| | | var result = false; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | if (actionType) |
| | | { |
| | | LogHelper.Info($"成品入库算法匹配终点,产线号={deviceName},库区={areaCode},物料编码={itemCode},批次号={batchNo}", "输送线"); |
| | | //1.任务创建:锁定起点,终点,终点排号-排锁定表(任务完成解锁), |
| | | // 任务数据携带-托盘码(便于回报)--两个托盘码存入任务表 WMSTask 的 托盘字段 S_CNTRS |
| | | // 物料层数(NDC下发必要参数) --起点层数 N_START_LAYER :默认为1 |
| | | // --终点层数 N_END_LAYER :获取 货位表-终点货位信息 N_CAPACITY + 1 |
| | | //2.插入 当前排号、产线号 至 自动移库中间表,等待工单完成即进行 自动移库 |
| | | var info = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == itemCode && a.S_TRAY_TYPE == itemTrayType).First(); |
| | | if (info != null) |
| | | { |
| | | var endLocation = GetLocationIn(areaCode, itemCode, batchNo); |
| | | if (endLocation != null) |
| | | { |
| | | var layer = endLocation.N_CURRENT_NUM + 1; |
| | | //DaMingShanAnalysisMoveLib model = new DaMingShanAnalysisMoveLib { RowNo = endLocation.N_ROW, Batch = batchNo, DeviceName = deviceName }; |
| | | //WCSHelper.DaMingShanInsertAnalysisMoveLib(model); |
| | | result = LinZhiCreateTransport(areaCode, bit, endLocation.S_CODE, taskType, trayCode, 1, layer, deviceName, endLocation.S_ROW, 1, 1, itemTrayType, workNo, batchNo, itemCode); |
| | | } |
| | | //else //Console.WriteLine($"MoboxHelperCreateTask: 未找到终点货位"); |
| | | } |
| | | else LogHelper.Info($"物料表未匹配到物料信息,物料编码:{itemCode},托盘类型:{itemTrayType}"); |
| | | } |
| | | else |
| | | { |
| | | //Location startLocation = null; |
| | | //string cntrs = ""; |
| | | //if (taskType == "栈板上线") |
| | | //{ |
| | | // startLocation = GetLocationOutByRow(areaCode, itemTrayType); |
| | | // cntrs = startLocation.LocCntrRel.S_CNTR_CODE; |
| | | //} |
| | | //else |
| | | //{ |
| | | // startLocation = GetLocationOut(areaCode, itemCode, batchNo, itemLayer); |
| | | //} |
| | | //if (startLocation != null) |
| | | //{ |
| | | // var startLayer = startLocation.N_LAYER; |
| | | // var taskNo = DateTime.Now.Ticks.ToString(); |
| | | // //临江只需要一个一拿 |
| | | // //var carryCount = startLocation.N_CURRENT_NUM > 3 ? startLocation.N_CURRENT_NUM - 3 : startLocation.N_CURRENT_NUM; |
| | | // //出库要从起点获取托盘 |
| | | // if (cntrs != "") |
| | | // { |
| | | // var cntrList = LocationHelper.GetLocCntr(startLocation.S_LOC_CODE); |
| | | // //临江一个托盘为 一个 货位当前容量 |
| | | // if (cntrList.Count == startLocation.N_CURRENT_NUM) |
| | | // { |
| | | // var trayInfo = cntrList.OrderByDescending(a => a.T_CREATE).Skip(1).ToList(); |
| | | // trayInfo.ForEach(a => |
| | | // { |
| | | // cntrs = cntrs + "," + a.S_CNTR_CODE.Trim(); |
| | | // }); |
| | | // LogHelper.Info($"cntr:{cntrs}"); |
| | | // result = LinJiangCreateTransport(areaCode, startLocation.S_LOC_CODE, bit, taskType, cntrs, startLayer, 1, deviceName, startLocation.N_ROW, 1, 1, itemTrayType); |
| | | // } |
| | | // else |
| | | // { |
| | | // Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】"); |
| | | // LogHelper.Info($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】"); |
| | | // } |
| | | // } |
| | | //} |
| | | //else LogHelper.Info($"对应成品空托库区未找到合适空托,库区编码:{areaCode},托盘类型:{itemTrayType}"); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建搬运任务 |
| | | /// </summary> |
| | | /// <param name="start"></param> |
| | | /// <param name="end"></param> |
| | | /// <param name="taskType"></param> |
| | | /// <param name="cntrs"></param> |
| | | /// <param name="startLayer"></param> |
| | | /// <param name="endLayer"></param> |
| | | /// <param name="trayCarryCount"></param> |
| | | /// <param name="priority"></param> |
| | | /// <returns></returns> |
| | | public static bool LinZhiCreateTransport(string areaCode, string start, string end, string taskType, string cntrs, int startLayer, int endLayer, string deviceName, string row, int trayCarryCount = 1, int priority = 1, string trayType = "", string workNo = "", string batch = "", string itemcode = "") |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var result = false; |
| | | var taskNo = DateTime.Now.Ticks.ToString(); |
| | | //var res = TaskHelper.LinJiangCreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, cntrs, deviceName, trayCarryCount, startLayer, endLayer, trayType, workNo, batch, itemcode); |
| | | var res = WMSHelper.CreateOpTask(start, end, "入库", taskType, cntrs, trayType, workNo,itemcode); |
| | | if (res) |
| | | { |
| | | try |
| | | { |
| | | LogHelper.Info($"{taskType}任务创建成功,起点:{start},终点:{end},托盘号:{cntrs},排号:{row},库区编码:{areaCode}"); |
| | | result = true; |
| | | //任务创建成功,起点货位出库锁定,终点货位入库锁定 |
| | | LocationHelper.LockLoc(start, 2); |
| | | LocationHelper.LockLoc(end, 1); |
| | | |
| | | //排锁定 |
| | | var Sinfo = db.Queryable<Location>().Where(a => a.S_CODE == start).First(); |
| | | var Einfo = db.Queryable<Location>().Where(a => a.S_CODE == end).First(); |
| | | if (Sinfo != null && Einfo != null) |
| | | { |
| | | string startRow = string.IsNullOrEmpty(Sinfo.S_ROW) ? "" : Sinfo.S_ROW.Trim(); |
| | | string sArea = string.IsNullOrEmpty(Sinfo.S_AREA_CODE) ? "" : Sinfo.S_AREA_CODE; |
| | | string endRow = string.IsNullOrEmpty(Einfo.S_ROW) ? "" : Einfo.S_ROW.Trim(); |
| | | string eArea = string.IsNullOrEmpty(Einfo.S_AREA_CODE) ? "" : Einfo.S_AREA_CODE; |
| | | LockRow(startRow, endRow, sArea, eArea, taskType, taskNo); |
| | | |
| | | if (taskType == "成品下线") |
| | | { |
| | | //生产下线任务生成成功,删除设备下线时间数据 |
| | | db.Deleteable<LinZhiDeviceState>().Where(a => a.DeviceName.Trim() == deviceName).ExecuteCommand(); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Error(ex.Message, ex); |
| | | } |
| | | |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 任务创建时锁定排 |
| | | /// </summary> |
| | | /// <param name="startRow"></param> |
| | | /// <param name="endRow"></param> |
| | | public static void LockRow(string startRow, string endRow, string SArea, string EArea, string taskType, string taskNo) |
| | | { |
| | | string startRowXB = startRow + ""; |
| | | string endRowXB = endRow + ""; |
| | | string SAreaXB = SArea + ""; |
| | | string EAreaXB = EArea + ""; |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | string LockRow = ""; |
| | | var Srow = db.Queryable<RowLock>().Where(a => a.S_ROW == startRow && a.S_AREA_CODE == SArea).First(); |
| | | if (Srow != null && !Srow.S_LOCK_STATE.Trim().Contains("锁")) |
| | | { |
| | | Srow.S_LOCK_STATE = "出库锁"; |
| | | db.Updateable(Srow).UpdateColumns(it => new { it.S_LOCK_STATE }).ExecuteCommand(); |
| | | LogHelper.Info($"任务创建成功:TaskNo:{taskNo}.出库锁定:起点库区:{SArea},起点排:{startRow}", "WMSAlgoRithm"); |
| | | LockRow = LockRow + Srow.S_ROW.Trim().Replace("-XB", "") + ","; |
| | | } |
| | | var Erow = db.Queryable<RowLock>().Where(a => a.S_ROW == endRow && a.S_AREA_CODE == EArea).First(); |
| | | if (Erow != null && !Erow.S_LOCK_STATE.Trim().Contains("锁")) |
| | | { |
| | | Erow.S_LOCK_STATE = "入库锁"; |
| | | db.Updateable(Erow).UpdateColumns(it => new { it.S_LOCK_STATE }).ExecuteCommand(); |
| | | LogHelper.Info($"任务创建成功:TaskNo:{taskNo}.入库锁定:起点库区:{EArea},起点排:{endRow}", "WMSAlgoRithm"); |
| | | LockRow = LockRow + Erow.S_ROW.Trim().Replace("-XB", "") + ","; |
| | | } |
| | | if (!string.IsNullOrEmpty(LockRow) && taskType.Contains("移库")) TaskProcess.AreaRowLockState(LockRow);//移库任务 回报富勒库位锁定 |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据库区和物料获取入库的货位(堆叠先考虑标准的,容量都是一样的,例如均州都是3+3;不考虑峨眉山非标2+2和2+1同时存在) |
| | | /// </summary> |
| | | /// <param name="area"></param> |
| | | /// <param name="itemCode">如果itemCode是空表示空容器</param> |
| | | /// <param name="standardCarryQty">标准搬运数量</param> |
| | | /// <returns></returns> |
| | | public static Location GetLocationIn(string area, string itemCode, string itemBatch) |
| | | { |
| | | //库区货位约定:列号越小越靠里 |
| | | LogHelper.Info($"入库算法01:area:{area},itemCode:{itemCode},itemBatch:{itemBatch}", "WMSAlgoRithm"); |
| | | Location result = null; |
| | | //itemCode = itemCode + itemLayer; |
| | | try |
| | | { |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | |
| | | //成品入库算法,下线的排优先查询之前下线的排 |
| | | bool action = queryRow(db, area, itemCode, itemBatch, ref result); |
| | | if (result == null) |
| | | { |
| | | //1.0 获取每一排最大的列 |
| | | //1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除 |
| | | var listMaxCol = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.S_ROW).ToList(); |
| | | //1.1 查到所有有容器的排 |
| | | var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area).Includes(a => a.LocCntrRel).OrderBy(a => a.S_ROW).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList(); |
| | | if (list.Count > 0) |
| | | { |
| | | LogHelper.Info($"入库算法03:查到所有有容器的排.数量:{list.Count}", "WMSAlgoRithm"); |
| | | for (int i = list.Count - 1; i >= 0; i--) |
| | | { |
| | | //排除已经锁定的货位 和 放满了且是最大列的货位 N_CAPACITY-货位最大容量 |
| | | //排除已锁定的排 |
| | | LogHelper.Info($"入库算法04-{i}:[判断当前排是否允许使用].排号:{list[i].S_ROW.Trim()},列号:{list[i].N_COL}," + |
| | | $"货位编码:{list[i].S_CODE.Trim()},货位状态:{list[i].S_LOCK_STATE.Trim()},当前数量:{list[i].N_CURRENT_NUM},最大数量:{list[i].N_CAPACITY}", "WMSAlgoRithm"); |
| | | var rowInfo = db.Queryable<RowLock>().Where(a => a.S_AREA_CODE == area && a.S_ROW == list[i].S_ROW.Trim()).First(); |
| | | LogHelper.Info($"排号:{list[i].S_ROW},锁状态:{rowInfo.S_LOCK_STATE}"); |
| | | |
| | | //判断当前库区当前排是否有货位有锁 |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.S_ROW == list[i].S_ROW && a.S_LOCK_STATE != "无").First(); |
| | | if (locInfo != null || rowInfo.S_LOCK_STATE.Trim() != "无" || list[i].S_LOCK_STATE.Trim() != "无" || (list[i].N_CURRENT_NUM == list[i].N_CAPACITY && listMaxCol.Count(a => a.S_CODE == list[i].S_CODE) > 0)) |
| | | { |
| | | LogHelper.Info($"入库算法04-{i}:[排除已经锁定的货位和放满了且是最大列的货位].排号:{list[i].S_ROW},排状态:{rowInfo.S_LOCK_STATE.Trim()},货位当前数量:{list[i].N_CURRENT_NUM}", "WMSAlgoRithm"); |
| | | list.Remove(list[i]); |
| | | } |
| | | } |
| | | if (list.Count > 0) |
| | | { |
| | | //1.3 遍历判断物料类型是否相同 |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | //todo 还需要判断锁 |
| | | #region 空容器或者满容器判断 ,如果是空容器 容器物料信息为空 |
| | | if (list[i].LocCntrRel != null) |
| | | { |
| | | LogHelper.Info("入库算法04:根据物料获取可用货位。itemCode=" + itemCode, "WMSAlgoRithm"); |
| | | queryItemInfo(db, list[i], area, itemCode, itemBatch, ref result); |
| | | if (result != null) |
| | | { |
| | | if (action) |
| | | { |
| | | //将当前货位排和列插入中间表 |
| | | CPXXTable table = new CPXXTable |
| | | { |
| | | S_AREA_CODE = area, |
| | | S_ROW = list[i].S_ROW, |
| | | S_TASK_TYPE = "成品", |
| | | |
| | | }; |
| | | db.Insertable(table).ExecuteCommand(); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | else LogHelper.Info("入库算法05:货位容器物料信息为空", "WMSAlgoRithm"); |
| | | #endregion |
| | | } |
| | | } |
| | | } |
| | | if (result == null) |
| | | { |
| | | //todo 还需要判断锁 |
| | | #region 查找所有数量是空的排 |
| | | LogHelper.Info($"入库算法06:无可用货位,获取空排货位。", "WMSAlgoRithm"); |
| | | //2.0 简化查询只查每一排第一列 |
| | | list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList(); |
| | | //2.1 选一个空排 |
| | | if (list.Count > 0) |
| | | { |
| | | LogHelper.Info($"入库算法06:无可用货位,获取空排货位数量为:{list.Count}。", "WMSAlgoRithm"); |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | LogHelper.Info($"入库算法07:获取空排货位:货位编码:{list[i].S_CODE.Trim()},当前数量:{list[i].N_CURRENT_NUM},排号:{list[i].N_ROW},库区编码:{list[i].S_AREA_CODE.Trim()}", "WMSAlgoRithm"); |
| | | if (list[i].S_LOCK_STATE.Trim().Contains("无")) |
| | | { |
| | | //二次校验当前排所有货位都是空的,防止系统数据错乱 |
| | | string row = list[i].S_ROW.Trim(); |
| | | string areaCode = list[i].S_AREA_CODE.Trim(); |
| | | var rowLock = db.Queryable<RowLock>().Where(a => a.S_ROW == row && a.S_LOCK_STATE.Contains("锁")).First(); |
| | | if (rowLock == null) |
| | | { |
| | | //var rowSumInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First(); |
| | | //if (rowSumInfo.sum == 0) |
| | | //{ |
| | | //三次校验 当前排所对应的另一版位的排为空排 |
| | | //bool DxEmptyCont = JYThreeDxEmptyFunc(area, db, row); |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_ROW == row).Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First(); |
| | | if (locInfo != null) |
| | | { |
| | | LogHelper.Info($"{locInfo.sum},row:{row}"); |
| | | if (locInfo.sum == 0) |
| | | { |
| | | //空排 |
| | | result = list[i]; |
| | | |
| | | if (action) |
| | | { |
| | | //将当前货位排和列插入中间表 |
| | | CPXXTable table = new CPXXTable |
| | | { |
| | | S_AREA_CODE = area, |
| | | S_ROW = list[i].S_ROW, |
| | | //S_TASK_TYPE = "成品", |
| | | |
| | | }; |
| | | db.Insertable(table).ExecuteCommand(); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | else LogHelper.Info("未找到该排"); |
| | | } |
| | | else LogHelper.Info("排锁已上锁"); |
| | | } |
| | | } |
| | | } |
| | | else LogHelper.Info($"未获取到空排,库区编码:{area}"); |
| | | #endregion |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace); |
| | | LogHelper.Error("GetLocationIn:" + ex.Message, ex); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private static bool queryRow(SqlSugarClient db, string area, string itemCode, string itemBatch, ref Location result) |
| | | { |
| | | bool action = false; |
| | | LogHelper.Info("成品下线查询优先下线排表"); |
| | | try |
| | | { |
| | | //1、查询中间表是否有值,有值,则查询中间表指定排的可用货位,当中间表指定排查不到可用货位的时候,进入算法 |
| | | //2、若没值,进入算法,查询到可用货位,将可用货位的排记录到中间表 |
| | | //var cpxxInfo = db.Queryable<CPXXTable>().Where(a => a.S_TASK_TYPE == "成品").First(); |
| | | var cpxxInfo = db.Queryable<CPXXTable>().Where(a => a.S_TASK_TYPE == "成品").First(); |
| | | if (cpxxInfo != null) |
| | | { |
| | | LogHelper.Info($"当前库区编码:{cpxxInfo.S_AREA_CODE},排号:{cpxxInfo.S_ROW}"); |
| | | //查询当前排是否有排锁 |
| | | var rowInfo = db.Queryable<RowLock>().Where(a => a.S_AREA_CODE == cpxxInfo.S_AREA_CODE && a.S_ROW == cpxxInfo.S_ROW).First(); |
| | | if (rowInfo != null) |
| | | { |
| | | LogHelper.Info($"锁状态:{rowInfo.S_LOCK_STATE}"); |
| | | if (rowInfo.S_LOCK_STATE == "无") |
| | | { |
| | | LogHelper.Info($"aaa"); |
| | | //查询当前排是否有货位锁 |
| | | var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == cpxxInfo.S_AREA_CODE && a.S_ROW == cpxxInfo.S_ROW && a.S_LOCK_STATE != "无").First(); |
| | | if (locInfo == null) |
| | | { |
| | | LogHelper.Info($"bbb"); |
| | | //查询当前排最大排是否为满货位 |
| | | var locInfo1 = db.Queryable<Location>().Where(a => a.S_AREA_CODE == cpxxInfo.S_AREA_CODE && a.S_ROW == cpxxInfo.S_ROW).OrderByDescending(a => a.N_COL).First(); |
| | | if (locInfo1 != null && locInfo1.N_CURRENT_NUM != locInfo1.N_CAPACITY) |
| | | { |
| | | LogHelper.Info($"ccc"); |
| | | //查询当前排最大的可用货位 并判断是否是最大列 |
| | | var endLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == cpxxInfo.S_AREA_CODE && a.S_ROW == cpxxInfo.S_ROW && a.N_CURRENT_NUM > 0).OrderByDescending(a => a.N_COL).Includes(a => a.LocCntrRel).First(); |
| | | if (endLoc != null) |
| | | { |
| | | LogHelper.Info($"ddd"); |
| | | queryItemInfo(db, endLoc, area, itemCode, itemBatch, ref result); |
| | | if (result == null) |
| | | { |
| | | LogHelper.Info($"fff"); |
| | | //清除中间表信息 |
| | | db.Deleteable<CPXXTable>().Where(a => a.S_ROW == cpxxInfo.S_ROW).ExecuteCommand(); |
| | | action = true; |
| | | } |
| | | else |
| | | { |
| | | //判断当前货位是否有卸货完成之前的任务 |
| | | string loc = result.S_CODE; |
| | | var taskInfo = db.Queryable<WMSTask>().Where(a => a.S_END_LOC == loc && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "卸货完成").First(); |
| | | LogHelper.Info("是否有当前货位任务:" + JsonConvert.SerializeObject(taskInfo)); |
| | | if (taskInfo != null) result = null; |
| | | |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //清除中间表信息 |
| | | db.Deleteable<CPXXTable>().Where(a => a.S_ROW == cpxxInfo.S_ROW).ExecuteCommand(); |
| | | action = true; |
| | | } |
| | | } |
| | | } |
| | | else if (rowInfo.S_LOCK_STATE == "锁定") |
| | | { |
| | | //清除中间表信息 |
| | | db.Deleteable<CPXXTable>().Where(a => a.S_ROW == cpxxInfo.S_ROW).ExecuteCommand(); |
| | | action = true; |
| | | LogHelper.Info($"queryRow:该排有锁,库区编码:{cpxxInfo.S_AREA_CODE},排号:{cpxxInfo.S_ROW},锁状态:{rowInfo.S_LOCK_STATE}"); |
| | | } |
| | | else |
| | | { |
| | | LogHelper.Info($"queryRow:该排有锁,库区编码:{cpxxInfo.S_AREA_CODE},排号:{cpxxInfo.S_ROW},锁状态:{rowInfo.S_LOCK_STATE}"); |
| | | } |
| | | |
| | | } |
| | | else LogHelper.Info($"queryRow:该排未找库区编码:{cpxxInfo.S_AREA_CODE},排号:{cpxxInfo.S_ROW}"); |
| | | } |
| | | else action = true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Error("queryRow:" + ex.Message, ex); |
| | | } |
| | | |
| | | return action; |
| | | } |
| | | |
| | | private static void queryItemInfo(SqlSugarClient db, Location loc, string area, string itemCode, string itemBatch, ref Location result) |
| | | { |
| | | string cntrCode = loc.LocCntrRel.S_CNTR_CODE; |
| | | var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrCode).First(); |
| | | |
| | | if ((itemCode != null && itemInfo != null && itemInfo.S_ITEM_CODE.Trim() == itemCode) || (itemCode == null && itemInfo == null)) |
| | | { |
| | | LogHelper.Info("物料编码匹配成功"); |
| | | LogHelper.Info($"{itemInfo.S_BATCH_NO}"); |
| | | //相同物料 相同批次 |
| | | if (itemInfo.S_BATCH_NO.Trim() == itemBatch.Trim()) |
| | | { |
| | | LogHelper.Info("批次号匹配成功"); |
| | | //当前数量小于当前容量 |
| | | if (loc.N_CURRENT_NUM < loc.N_CAPACITY) |
| | | { |
| | | string locCode = loc.S_CODE.Trim(); |
| | | var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == locCode).ToList(); |
| | | if (trayInfo.Count() % 2 == 0) |
| | | { |
| | | result = loc; |
| | | string code11 = result.S_CODE; |
| | | var taskINfo = db.Queryable<WMSTask>().Where(a => a.S_END_LOC == code11 && a.S_B_STATE == "取货完成").First(); |
| | | if (taskINfo != null) |
| | | { |
| | | result = null; |
| | | } |
| | | |
| | | LogHelper.Info($"入库算法05:当前货位可用,获取当前货位。当前货位:{loc.S_CODE.Trim()}.", "WMSAlgoRithm"); |
| | | } |
| | | else |
| | | { |
| | | //1.33 不满足则选择后一列,后一列肯定是空货位 |
| | | result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == loc.N_ROW && a.N_COL > loc.N_COL).OrderBy(a => a.N_COL).First(); |
| | | if (result.S_LOCK_STATE != "无") result = null; |
| | | LogHelper.Info($"入库算法05:当前货位托盘数量可求余2,获取后一列货位。当前货位:{loc.S_CODE.Trim()},托盘数量:{trayInfo.Count()}.", "WMSAlgoRithm"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //当前货位满了,比他col大一位的货位,后一列肯定是空货位 |
| | | result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == loc.N_ROW && a.N_COL > loc.N_COL).OrderBy(a => a.N_COL).First(); |
| | | //if (result.S_LOCK_STATE != "无") result = null; |
| | | LogHelper.Info($"入库算法05:当前货位已满,获取后一列空位。当前货位:{loc.S_CODE.Trim()}.", "WMSAlgoRithm"); |
| | | } |
| | | } |
| | | //相同物料 不同批次号 ,需间隔一个货位 col-1 |
| | | else |
| | | { |
| | | result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == loc.N_ROW && a.N_COL - 1 > loc.N_COL).OrderBy(a => a.N_COL).First(); |
| | | //if (result.S_LOCK_STATE != "无") result = null; |
| | | LogHelper.Info($"入库算法05:相同物料 不同批次号 ,需间隔一个货位,当前货位:{loc.S_CODE.Trim()}.", "WMSAlgoRithm"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | } |