using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.ServiceModel; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using wcftest.orm; using logtxtWrite; using wcftest.wcfApi; using wcftest.wcf; using wcftest.EnumDefine; using System.Data.Entity.Validation; using wcftest.sapEntity; using wcftest.sendToSap; using Newtonsoft.Json; using System.Diagnostics; using wcftest.sql; using System.Data.Entity.Migrations; using System.Data.Entity; using wcftest.BussinessExtension.Handle; using wcftest.BussinessExtension; using wcftest.EnumDefine.Position; using wcftest.BussinessExtension.Common; using wcftest.orm_test; using wcftest.EnumDefine.Sys; namespace wcftest { //库存表 ExtendField03可用分拣-ContainerNo库存锁定-ExtendField02 出库数量 public partial class Form1 : Form { #region 大叠盘机和小叠盘机满空托标记 [EditBy shaocx,2022-03-08] /// /// 大叠盘机满空托标记,true:已满,false:未满 /// public static bool IsFull_BigFoldingPlate = false; /// /// 小叠盘机满空托标记,true:已满,false:未满 /// public static bool IsFull_SmallFoldingPlate = false; #endregion /// /// wcf服务变量 /// ServiceHost myWcf; /// /// 自动执行任务线程,任务确认线程,检测叠盘机入口是否空,出口是否满线程 /// Thread autoTaskThreadForOutStoreArea,//自动入库线程 autoTaskThreadForInStoreArea,//自动入库线程 autoTaskThreadForMoveStoreArea,//自动入库线程 writeOutTaskThread,//自动出库线程 finishConfirmThread,//完成确认线程 sendSpaThread,//发生SAP确认(24小时内) containerIsFullThread,//检测需入口要空托盘和出口空托盘满 deviceInfos,//设备信息 Colors,//状态指示灯 writeTaskTread;//写入任务表线程 /// 设备运行时间 /// 设备运行时间 /// public static TimeSpan deviceRunTime; /// 设备等待时间 /// 设备等待时间 /// public static TimeSpan deviceWaitTime; /// 设备报警时间 /// 设备报警时间 /// public static TimeSpan deviceAlarmTime; /// 设备使用率 /// 设备使用率 /// public static TimeSpan deviceUsageRate; /// 设备运行计时器 /// 设备运行计时器 /// Stopwatch deviceSw = new Stopwatch(); /// 上一次设备运行状态 /// 上一次设备运行状态 /// public string lastStatus = "等待"; /// 上一次小时数--每隔一小时保存一次设备状态时间 /// 上一次小时数--每隔一小时保存一次设备状态时间 /// int lastHour = 0; public static string lastPlateCode = "0"; public static string lastPosition = "0"; /// wcf服务 /// wcf服务 /// public static wcfApi.ControlCenterWcfServiceClient wcsApi = new wcfApi.ControlCenterWcfServiceClient(); // 获取 设备信息 ControlCenterWcfServiceClient device = new ControlCenterWcfServiceClient(); /// 线程锁防止并发 /// //线程锁防止并发 /// public static Mutex single = new Mutex(); /// 是否是虚拟仿真模式 /// 是否是虚拟仿真模式 /// //bool IsVirtualMode = true; public static bool IsVirtualMode = ConfigHelper.GetConfigBool("IsVirtualMode");//修改为配置文件 【EditBy shaocx,2022-01-27】 bool allowGetDeviceInfo = true;//允许获取设备开关 bool opentask = true;//打开线程 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //检测是否已经开启 #region 只允许单启动和绑定电脑 Process current = Process.GetCurrentProcess(); Process[] processes = Process.GetProcessesByName(current.ProcessName); foreach (Process process in processes) { if (process.Id != current.Id) { if (process.MainModule.FileName == current.MainModule.FileName) { MessageBox.Show("不允许重复开启!"); Environment.Exit(0); return; } } } //string computerName = Environment.GetEnvironmentVariable("ComputerName");//获取电脑用户名 //if (computerName != "DESKTOP-0IQRMAE" && computerName != "XMZ2" && computerName != "XMZ1") //{ // MessageBox.Show("非法主机!"); // Environment.Exit(0); //} #endregion Control.CheckForIllegalCrossThreadCalls = false; myWcf = new ServiceHost(typeof(wcftest.wcf.apitest)); myWcf.Open();//开启wcf服务 if (opentask == true) { //自动入库执行任务线程 autoTaskThreadForOutStoreArea = new Thread(autoSendTaskForOutStoreArea); autoTaskThreadForOutStoreArea.Start(); autoTaskThreadForInStoreArea = new Thread(autoSendTaskForInStoreArea); autoTaskThreadForInStoreArea.Start(); autoTaskThreadForMoveStoreArea = new Thread(autoSendTaskForMoveStoreArea); autoTaskThreadForMoveStoreArea.Start(); //写出库任务线程 writeOutTaskThread = new Thread(writeOutTask); writeOutTaskThread.Start(); //写入库任务 writeTaskTread = new Thread(writeInTask); writeTaskTread.Start(); //确认任务 finishConfirmThread = new Thread(finishConfirm); finishConfirmThread.Start(); //检测需入口要空托盘和出口空托盘满 containerIsFullThread = new Thread(containerIsFull); containerIsFullThread.Start(); //读取SAP发送数据 sendSpaThread = new Thread(sendSapInfo); sendSpaThread.Start(); Colors = new Thread(changeColor); Colors.Start(); } // 获取设备信息 deviceInfoInit(); if (IsVirtualMode) { this.BackColor = Color.Pink; label11.Text = "虚拟模式,不可用于生产!"; } new Thread(DeleteData).Start();//定时清理日志 new Thread(DeleteData_Base_ProductPosition).Start();//定时清理暂存区 new Thread(AutoMoveForArea1).Start();//闲时移库-库区1 new Thread(AutoMoveForArea2).Start();//闲时移库-库区2 new Thread(doNoBillForAddOutInStockTask).Start();//处理 新增无单入库的入库记录 } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { try { //时间计算,这块去掉 【Editby shaocx,2024-12-30】 /* using (dbModel mod = new dbModel()) { DateTime todayTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));//今天凌晨时间 deviceGeneralInfo todayDeviceInfo = mod.deviceGeneralInfo.FirstOrDefault(x => x.createTime > todayTime); todayDeviceInfo.deviceWaitTime = deviceWaitTime.Hours * 60M + deviceWaitTime.Minutes; todayDeviceInfo.deviceRunTime = deviceRunTime.Hours * 60M + deviceRunTime.Minutes; todayDeviceInfo.deviceAlarmTime = deviceAlarmTime.Hours * 60M + deviceAlarmTime.Minutes; mod.SaveChanges(); // if (myWcf != null) myWcf.Close();//关闭wcf服务线程 // Environment.Exit(0);//退出本进程所有线程 } //*/ } catch (Exception ex) { } // if (myWcf != null) myWcf.Close();//关闭wcf服务线程 Environment.Exit(0);//退出本进程所有线程 } #region 处理【“未下发”,“下发中”的任务】 /// 处理【“未下发”,“下发中”的任务】,出库区域专用 /// 处理【“未下发”,“下发中”的任务】,出库区域专用 /// private void autoSendTaskForOutStoreArea() { while (true) { Thread.Sleep(2000); try { //读取任务列表Task_Queue using (dbModel mod = new dbModel()) { //出库区任务类型 var q_TaskType_常规出库 = ((int)TaskTypeEnum.常规出库).ToString(); var q_TaskType_出库叠盘 = ((int)TaskTypeEnum.出库叠盘).ToString(); var q_TaskType_余料回库 = ((int)TaskTypeEnum.余料回库).ToString(); var q_TaskType_满空托回库 = ((int)TaskTypeEnum.满空托回库).ToString(); //判断是否有闲时移库任务在执行 [EditBy shaocx,2022-09-22] var isExistRuningTask = FreeTimeMoveLocationTaskHandler.IsExistRuningTask(mod); if (isExistRuningTask) { var q_TaskType_move = ((int)TaskTypeEnum.移库).ToString(); this.lbl_Msg_autoSendTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前存在闲时移库任务在执行中,不允许下发其他任务,只允许下发移库任务!"; //更新所有 未下发的任务,除了移库任务 List updateList = mod.Task_Queue.Where(x => (x.TaskStatus == "未下发") && ( x.TaskType == q_TaskType_常规出库 || x.TaskType == q_TaskType_出库叠盘 || x.TaskType == q_TaskType_余料回库 || x.TaskType == q_TaskType_满空托回库 )).ToList(); if (updateList != null && updateList.Count > 0) { foreach (var item in updateList) { item.Remark = "当前存在闲时移库任务在执行中,暂停下发该任务"; } mod.SaveChanges(); } continue; } //1、优先下发 回库任务 [EditBy shaocx,2022-07-26] var q_TaskType1 = ((int)TaskTypeEnum.余料回库).ToString(); var q_TaskType2 = ((int)TaskTypeEnum.满空托回库).ToString(); var q_TaskType3 = ((int)TaskTypeEnum.出库叠盘).ToString(); List taskDispost1 = mod.Task_Queue.Where(x => (x.TaskStatus == "未下发" || x.TaskStatus == "下发中") && (x.TaskType == q_TaskType1 || x.TaskType == q_TaskType2 || x.TaskType == q_TaskType3) ).OrderByDescending(x => x.OrderNumber).ThenBy(x => x.CreateDate).ToList(); if (taskDispost1 != null && taskDispost1.Count > 0) { common_autoSendTask(taskDispost1, mod, false); } //2、其次做 常规出库任务 var q_TaskType4 = ((int)TaskTypeEnum.常规出库).ToString(); taskDispost1 = new List(); taskDispost1 = mod.Task_Queue.Where(x => (x.TaskStatus == "未下发" || x.TaskStatus == "下发中") && (x.TaskType == q_TaskType4) && x.DoCount == 1 // 1号堆垛机 ).OrderByDescending(x => x.OrderNumber).ThenBy(x => x.CreateDate).ToList(); if (taskDispost1 != null && taskDispost1.Count > 0) { var isPass = validate常规出库(mod, 1); if (isPass) { common_autoSendTask(taskDispost1, mod, true); } } taskDispost1 = new List(); taskDispost1 = mod.Task_Queue.Where(x => (x.TaskStatus == "未下发" || x.TaskStatus == "下发中") && (x.TaskType == q_TaskType4) && x.DoCount == 2 //2号堆垛机 ).OrderByDescending(x => x.OrderNumber).ThenBy(x => x.CreateDate).ToList(); if (taskDispost1 != null && taskDispost1.Count > 0) { var isPass = validate常规出库(mod, 2); if (isPass) { common_autoSendTask(taskDispost1, mod, true); } } //this.lbl_Msg_autoSendTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "执行完毕一轮"; } } catch (Exception ex) { this.lbl_Msg_autoSendTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "异常:" + ex.Message; Log4NetHelper.WriteErrorLog(LogType.AutoSendTaskForOutStoreArea, "异常:" + ex.Message, ex); } } } /// 处理【“未下发”,“下发中”的任务】,入库区域专用 /// 处理【“未下发”,“下发中”的任务】,入库区域专用 /// private void autoSendTaskForInStoreArea() { while (true) { Thread.Sleep(2000); try { //读取任务列表Task_Queue using (dbModel mod = new dbModel()) { //入库区任务类型 var q_TaskType_入库拆盘 = ((int)TaskTypeEnum.入库拆盘).ToString(); var q_TaskType_常规入库 = ((int)TaskTypeEnum.常规入库).ToString(); var q_TaskType_组盘出库 = ((int)TaskTypeEnum.组盘出库).ToString(); var q_TaskType_空托出库 = ((int)TaskTypeEnum.空托出库).ToString(); //判断是否有闲时移库任务在执行 [EditBy shaocx,2022-09-22] var isExistRuningTask = FreeTimeMoveLocationTaskHandler.IsExistRuningTask(mod); if (isExistRuningTask) { var q_TaskType_move = ((int)TaskTypeEnum.移库).ToString(); this.lbl_Msg_autoSendTaskForInStoreArea.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前存在闲时移库任务在执行中,不允许下发其他任务,只允许下发移库任务!"; //更新所有 未下发的任务,除了移库任务 List updateList = mod.Task_Queue.Where(x => (x.TaskStatus == "未下发") && ( x.TaskType == q_TaskType_入库拆盘 || x.TaskType == q_TaskType_常规入库 || x.TaskType == q_TaskType_组盘出库 || x.TaskType == q_TaskType_空托出库 )).ToList(); if (updateList != null && updateList.Count > 0) { foreach (var item in updateList) { item.Remark = "当前存在闲时移库任务在执行中,暂停下发该任务"; } mod.SaveChanges(); } continue; } //3、最后做别的任务 List taskDispost2 = mod.Task_Queue.Where(x => (x.TaskStatus == "未下发" || x.TaskStatus == "下发中") && ( x.TaskType == q_TaskType_入库拆盘 || x.TaskType == q_TaskType_常规入库 || x.TaskType == q_TaskType_组盘出库 || x.TaskType == q_TaskType_空托出库 ) ).OrderByDescending(x => x.OrderNumber).ThenBy(x => x.CreateDate).ToList(); if (taskDispost2.Count < 1) continue; common_autoSendTask(taskDispost2, mod, false); this.lbl_Msg_autoSendTaskForInStoreArea.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "执行完毕一轮"; } } catch (Exception ex) { this.lbl_Msg_autoSendTaskForInStoreArea.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "异常:" + ex.Message; Log4NetHelper.WriteErrorLog(LogType.AutoSendTaskForInStoreArea, "异常:" + ex.Message, ex); } } } /// 处理【“未下发”,“下发中”的任务】,移库区域专用 /// 处理【“未下发”,“下发中”的任务】,移库区域专用 /// private void autoSendTaskForMoveStoreArea() { while (true) { Thread.Sleep(2000); try { //throw new Exception("报错了");//测试 //读取任务列表Task_Queue using (dbModel mod = new dbModel()) { var q_TaskType_move = ((int)TaskTypeEnum.移库).ToString(); List taskDispost_move = mod.Task_Queue.Where(x => (x.TaskStatus == "未下发" || x.TaskStatus == "下发中") && (x.TaskType == q_TaskType_move) ).OrderByDescending(x => x.OrderNumber).ThenBy(x => x.CreateDate).ToList(); if (taskDispost_move.Count < 1) continue; common_autoSendTask(taskDispost_move, mod, false); } this.lbl_Msg_autoSendTaskForMoveStoreArea.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "执行完毕一轮"; } catch (Exception ex) { this.lbl_Msg_autoSendTaskForMoveStoreArea.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "异常:" + ex.Message; Log4NetHelper.WriteErrorLog(LogType.AutoSendTaskForMoveStoreArea, "异常:" + ex.Message, ex); } } } /// 处理【“未下发”,“下发中”的任务】 /// 处理【“未下发”,“下发中”的任务】 /// private void common_autoSendTask(List taskDispost, dbModel mod, bool is常规出库) { try { int handlerNum = 0; foreach (var item in taskDispost) { handlerNum++; if (is常规出库 && handlerNum > 2) { this.lbl_Msg_autoSendTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + " ,常规出库,本次循环处理的的任务超过2条,先暂停下发常规出库任务"; break;//如果是常规出库,并且下发给wcs任务失败,就跳出循环。要求是必须出库任务按照时间来出库,不能跳任务 【EditBy shaocx,2022-07-28】 } int taskId = item.Task_Id; taskId = ExtendHelper.ConvertPlcNO(item.Task_Id);//修复 【EditBy shaocx,2022-04-18】 string sourcePlce = item.FromPositionName; string toPlace = item.ToPositionName; int TaskType = Convert.ToInt32(item.TaskType); int containerType = Convert.ToInt32(item.PlateType); int storageno = Convert.ToInt32(item.DoCount);//DoCount字段当库区用 后期更改 int height = 0;// direction字段当高度用 后期更改 string containerName = item.PlateCode; //发送wcs 任务 SendTask(taskId,sourcePlce,toPlace,taskType,containerType,storageno,height) 设备报警失败返回0,1任务完成,2外形检测不通过 #region 增加校验 【Editby shaocx,2024-09-10】 //不能加这个验证,他入库是根据 后面的高度检测来的 【Editby shaocx,2024-09-11】 /* if (item.TaskType == ((int)TaskTypeEnum.常规入库).ToString()) { if (storageno == 0) { Log4NetHelper.WriteErrorLog(LogType.IssueTask, "自动发送任务,传递参数,PLC任务号:" + taskId + ",sourcePlce:" + sourcePlce + ",toPlace:" + toPlace + ",TaskType:" + TaskType + ",containerType:" + containerType + ",storageno:" + storageno + ",height:" + height + ",containerName:" + containerName); throw new Exception("常规入库,storageno=0"); } } //*/ #endregion bool result; wcftest.wcfApi.FunModel fm = null; //模拟 if (IsVirtualMode) { result = true;//模拟环境下,改为true 【EditBy shaocx,2022-06-20】 VirtualModeHelper.ThrowExceptionWhenVirtualMode(IsVirtualMode); fm = new FunModel() { result = true, }; } else { //调用新的接口,返回wcs返回的错误消息 //result = wcsApi.SendTask(taskId, sourcePlce, toPlace, TaskType, containerType, storageno, height, containerName); fm = wcsApi.SendTaskWithMsg(taskId, sourcePlce, toPlace, TaskType, containerType, storageno, height, containerName, item.Task_Id); result = fm.result; //logtxt.txtWrite("类名:Form1/函数名:autoSendTask自动发送任务,传递参数,PLC任务号:" + taskId + ",sourcePlce:" + sourcePlce + ",toPlace:" + toPlace // + ",TaskType:" + TaskType + ",containerType:" + containerType + ",storageno:" + storageno // + ",height:" + height + ",containerName:" + containerName, // 2); Log4NetHelper.WriteInfoLog(LogType.IssueTask, "自动发送任务,传递参数,PLC任务号:" + taskId + ",sourcePlce:" + sourcePlce + ",toPlace:" + toPlace + ",TaskType:" + TaskType + ",containerType:" + containerType + ",storageno:" + storageno + ",height:" + height + ",containerName:" + containerName); } if (result == true) { item.TaskStatus = "已下发"; item.PlcTaskNo = taskId;//保存下PLC的任务号 [EditBy shaocx,2022-04-18] item.ExpandFields = taskId.ToString();//同时用这个字段保存下PLC的任务号 [EditBy shaocx,2022-04-18] item.Remark = ""; mod.SaveChanges(); //设置优先级 【EditBy shaocx,2022-07-06】 if (item.OrderNumber != null && Convert.ToInt32(item.OrderNumber) > 0) {//只有当大于0的时候,才会主动触发优先级 WcsWcfApiHelper.SetMainTaskPriority(wcsApi, taskId.ToString(), item.OrderNumber, item.Task_Id); } } else {//下发失败 Log4NetHelper.WriteInfoLog(LogType.IssueTask, "下发任务,WCS返回false,Task_Id:" + item.Task_Id + ",PLC任务号:" + taskId + ",IsVirtualMode:" + IsVirtualMode); //logtxt.txtWrite("类名:Form1/函数名:autoSendTask自动发送任务,返回false,Task_Id:" + item.Task_Id + ",PLC任务号:" + taskId + ",IsVirtualMode:" + IsVirtualMode, //2); item.PlcTaskNo = taskId;//保存下PLC的任务号 [EditBy shaocx,2022-04-18] item.ExpandFields = taskId.ToString();//同时用这个字段保存下PLC的任务号 [EditBy shaocx,2022-04-18] item.Remark = fm.errMsg; mod.SaveChanges(); if (is常规出库) { break;//如果是常规出库,并且下发给wcs任务失败,就跳出循环。要求是必须出库任务按照时间来出库,不能跳任务 【EditBy shaocx,2022-07-28】 } } } } catch (Exception ex) { //logtxt.txtWrite("类名:Form1/函数名:autoSendTask自动发送任务/ " + ex.Message + "出错行号" + (string)ex.StackTrace + ",异常:" + JsonConvert.SerializeObject(ex), // 2); Log4NetHelper.WriteErrorLog(LogType.IssueTask, "异常:" + ex.Message, ex); throw ex; } } /// /// 验证常规出库任务 【Editby shaocx,2024】 /// /// /// /// private bool validate常规出库(dbModel mod, int doCount) { var q_TaskType4 = ((int)TaskTypeEnum.常规出库).ToString(); var ooListNum = mod.Task_Queue.Where(x => (x.TaskStatus == "已下发") && (x.TaskType == q_TaskType4) && x.DoCount == doCount // 某号堆垛机 ).OrderByDescending(x => x.OrderNumber).ThenBy(x => x.CreateDate).Count(); if (ooListNum > 2) { this.lbl_Msg_autoSendTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + " " + doCount.ToString() + "号堆垛机,常规出库,已下发的任务超过2条,先暂停下发常规出库任务"; return false; } return true; } #endregion /// 处理“待下架”的表单,创建出库任务 /// 处理“待下架”的表单,创建出库任务 /// private void writeOutTask() { //ExtendField02 出库数量 ContainerNo=1 锁定(正在出库) ExtendField03=1允许分拣 Remark 移动类型 while (true) { Thread.Sleep(3000); try { using (dbModel mod = new dbModel()) { //判断是否有闲时移库任务在执行 [EditBy shaocx,2022-09-22] var isExistRuningTask = FreeTimeMoveLocationTaskHandler.IsExistRuningTask(mod); if (isExistRuningTask) { this.lbl_Msg_writeOutTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前存在闲时移库任务在执行中,不允许下发其他任务,只允许下发移库任务!"; continue;//继续下一个循环 } int alack = 0;//缺货条数 //查找出库单 var queryStatus = Sale_Order_StatusEnum.待下架.ToString(); //按照任务优先级的降序排序 【Editby shaocx,2024-02-27】 List saleOrderList = mod.Sale_Order.Where(x => x.StatusText == queryStatus).OrderByDescending(x => x.PriorityNo).ToList(); //List saleOrderList = mod.Sale_Order.Where(x => x.StatusText == "待下架").OrderByDescending(x => x.PriorityNo).ToList(); if (saleOrderList.Count > 0) { //出库单里的明细 //一次获取所有库存 Thread.Sleep(3000);//增加延迟 防止主表信息写进去,明细还没写进去 #region 事务处理 【EditBy shaocx,2022-10-16】 using (var trans = mod.Database.BeginTransaction()) { try { string last_toplace = "";//记录本次循环上一个的目标点 【EditBy shaocx,2022-10-15】 foreach (var sale in saleOrderList) { #region 单个循环处理 List saleList = mod.Sale_OrderList.Where(x => x.Order_Id == sale.Order_Id && x.ExtendField03 == "待下架" && x.QuantityOrder > 0).ToList(); if (saleList.Count < 1) { //sale.StatusText = "查找明细出错"; sale.StatusText = Sale_Order_StatusEnum.错误.ToString(); sale.StatusID = Convert.ToByte(Sale_Order_StatusEnum.错误); sale.Remark = "查找明细出错,没有找到出库明细"; mod.SaveChanges(); continue; } List stockALL = mod.vvBase_ProductPosition.Where(x => x.ProductStorage > 0).ToList();//将读取库存信息放到循环里面 List stockALL_No收货暂存区 = stockALL.Where(x => x.PositionName != SysGlole.PositionName_SHZCQ).ToList();//非收货暂存区的库存列表 //验证指定库位号出库 var errMsg = ""; var validateResult = BussinessExtension.BussinessExtension.ValidateSale_OrderForPointPositionName(mod, stockALL_No收货暂存区, sale, saleList, ref errMsg); if (validateResult == false) { //sale.StatusText = errMsg; sale.StatusText = Sale_Order_StatusEnum.错误.ToString(); sale.StatusID = Convert.ToByte(Sale_Order_StatusEnum.错误); sale.Remark = errMsg; mod.SaveChanges(); continue; } Sale_Order_History sale_Order_History = null; lackOrder lackTop = new lackOrder();//缺货表 List lacks = new List(); //if (sale.OrderType == "SAP生产订单") if (sale.OrderType == SysGlole.SAP_ORDER_TEXT) { #region 获取缺料主表数据 try { int outNumber = sale.OutNumber == null ? 0 : Convert.ToInt32(sale.OutNumber); int materialCount = sale.MaterialCount == null ? 0 : Convert.ToInt32(sale.MaterialCount); if (outNumber <= 0) { this.lbl_Msg_writeOutTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "SAP生产订单!"; continue; } int finishQty = sale.Client_Id == null ? 0 : Convert.ToInt32(sale.Client_Id); string trackNum = sale.TrackingNumber == null ? "" : sale.TrackingNumber; lackTop.workCode = sale.OrderCode;//生产单号 lackTop.trackCode = trackNum; lackTop.totalCount = sale.MaterialCount == null ? 0 : (int)sale.MaterialCount; lackTop.counting = outNumber;//本次出库套数 lackTop.finishCount = finishQty;//完成 //增加出库套数记录表 [EditBy shaocx,2022-10-16] sale_Order_History = Sale_Order_HistoryHandler.AddSale_Order_History(sale, mod, "", ""); mod.SaveChanges();//保存数据,让对象Sale_Order_History的ID有值 【EditBy shaocx,2022-10-16】 } catch (Exception ex) { textBox6.Text = "缺料主表 数据转换失败\r\n" + textBox6.Text; logtxt.txtWrite("类名:Form1/函数名:writeOutTask锁定库位失败/库位号: " + ex.ToString(), 2); } #endregion } else//手动出库,311和暂存区发料是跟设备没关系的 { string moveType = saleList[0].ExtendField01 == null ? "" : saleList[0].ExtendField01; string moveTypeSap = ConvertMoveType(moveType); if (moveType == "暂存区发料到生产订单261") { List resultSap = new List();//出库实体集合 // List modifyStatus = new List();//扣减暂存区集合 #region 暂存区发料到生产订单261 foreach (var item in saleList) { GIMaterialEntity newSap = new GIMaterialEntity(); string trackNumber = item.TrackingNumber == null ? "" : item.TrackingNumber; string materailCode = item.ProductCode.Trim();//产品编号 newSap.WorkOrder = item.StoreOrderId + "#0#0";//生产订单 //如果库存数据没有跟踪号261不加E特殊类型符号 if (string.IsNullOrEmpty(trackNumber)) { newSap.MoveType = moveTypeSap;//移动类型 } else { newSap.MoveType = moveTypeSap + "E";//移动类型 } //如果填了销售订单 if (!string.IsNullOrEmpty(item.PackageName)) { newSap.SalesOrder = item.PackageName;//销售订单 newSap.SalesOrderItem = item.NumberOfGiftBags;//销售项号 } newSap.Plant = "3TG1";//工厂 newSap.MaterialCode = materailCode;//产品编号 newSap.StorageLocation = "G021";//库区 newSap.Quantity = (decimal)item.QuantityOrder;//出库数量 resultSap.Add(newSap); } if (resultSap.Count > 0) { //apitest wcfapi = new apitest(); string moveInfo = JsonConvert.SerializeObject(resultSap); //json序列化 //向SAP发送出库确认 returnInfo result = JsonConvert.DeserializeObject(SAPHelper.StockOutConfirm(null, moveInfo)); if (result.result)//如果sap返回true 表示接受成功 { //sale.StatusText = "已分配"; sale.StatusText = Sale_Order_StatusEnum.已分配.ToString(); sale.StatusID = Convert.ToByte(Sale_Order_StatusEnum.已分配); #region 扣减暂存区数量 foreach (var item in saleList)//扣减暂存区数量 { string trackNumber = item.TrackingNumber == null ? "" : item.TrackingNumber; string materailCode = item.ProductCode.Trim();//产品编号 List zcq_ProductPosition = mod.Base_ProductPosition.Where(x => x.PositionName == SysGlole.PositionName_SHZCQ //增加收货暂存区的筛选 【Editby shaocx,2022-03-08】 && x.ExtendField04 == trackNumber && x.ProductCode == materailCode && x.ProductStorage > 0).OrderBy(x => x.ProductStorage).ToList(); bool subOK = false;//记录扣减是否完成 decimal outQuantity = 0M;// 库存相加临时变量 foreach (var itemSub in zcq_ProductPosition) { //把等于的数据优先处理 if (itemSub.ProductStorage == item.QuantityOrder) { mod.Base_ProductPosition.Remove(itemSub); //增加出入库记录 【EditBy shaocx,2022-03-07】 OutInStockTaskHandler.AddOutInStockTask22(sale.Creator, mod, OutInStockTaskName.清库任务, itemSub.ProductStorage, itemSub, "自动下发出库任务,手动出库,库存数等于要出库的数,清空库存", sale.OrderCode); subOK = true; break; } } if (!subOK) { #region 没有等于的累加扣减 foreach (var itemSub in zcq_ProductPosition) { outQuantity += (decimal)itemSub.ProductStorage;//先加后判断 if (item.QuantityOrder > outQuantity)//累加库存数量小于出库数量 前库存数据都删除 { mod.Base_ProductPosition.Remove(itemSub); //增加出入库记录 【EditBy shaocx,2022-03-07】 OutInStockTaskHandler.AddOutInStockTask22(sale.Creator, mod, OutInStockTaskName.清库任务, itemSub.ProductStorage, itemSub, "自动下发出库任务,手动出库,1累加库存数量小于出库数量 前库存数据都删除,清空库存", sale.OrderCode); } else { if (item.QuantityOrder == outQuantity) { mod.Base_ProductPosition.Remove(itemSub); //增加出入库记录 【EditBy shaocx,2022-03-07】 OutInStockTaskHandler.AddOutInStockTask22(sale.Creator, mod, OutInStockTaskName.清库任务, itemSub.ProductStorage, itemSub, "自动下发出库任务,手动出库,2累加库存数量小于出库数量 前库存数据都删除,清空库存", sale.OrderCode); } else//如果累计综合不等于那就是大于出库数量,这时不能删除这个库存,而是把超出的数量保存到最后一条数据里 { //itemSub.ProductStorage = outQuantity - item.QuantityOrder; //原来的代码 decimal? finallyQty = outQuantity - item.QuantityOrder; decimal? changeQty = itemSub.ProductStorage - finallyQty; itemSub.ProductStorage = finallyQty; //原来的代码 //增加出入库记录 【EditBy shaocx,2022-03-07】 OutInStockTaskHandler.AddOutInStockTask22(sale.Creator, mod, OutInStockTaskName.出库任务, changeQty, itemSub, "自动下发出库任务,手动出库,2累加库存数量小于出库数量 前库存数据都删除,清空库存", sale.OrderCode); } break; } } #endregion } mod.SaveChanges(); } #endregion } } #endregion continue; } } #region 出库任务 if (saleList.Count > 0) { string isEnableSrmOne = "3";//一号堆垛机是否能用 string isEnableSrmTwo = "3";//二号堆垛机是否能用 // #region 读取堆垛机是否禁用 List srmIsOk = mod.Base_Equipment.Where(x => x.DeviceType == "堆垛机").ToList(); #region 判断堆垛机是否禁用 来设置库区 if (srmIsOk != null) { #region 查询堆垛机是否可用 foreach (var item in srmIsOk) { if (item.DeviceCode == "1") { if (item.Enable == 1) { isEnableSrmOne = "1"; } } if (item.DeviceCode == "2") { if (item.Enable == 1) { isEnableSrmTwo = "2"; } } } #endregion } else { logtxt.txtWrite("类名:Form1/函数名:writeOutTask出库写入任务异常/堆垛机全部被禁用 ", 2); // return ""; } #endregion int outTaskSaleNum = 0;//记录出库子表中有几个已分配出库,然后做比对后改出库主表状态 List taskList = new List(); foreach (var item in saleList) { #region 计算库存 decimal outQty = 0M;//需要出货的数量临时变量 decimal exitQty = item.QuantityOrder == null ? 0M : (decimal)item.QuantityOrder; if (exitQty == 0) { continue; } List products = new List();//当前库存 #region 寻找库存 //按跟踪号查找 ContainerNo = "1";//库位锁定 if (item.TrackingNumber != null) { products = stockALL_No收货暂存区.Where(x => x.ExtendField04 == item.TrackingNumber && x.ContainerNo != "1" && x.ProductCode == item.ProductCode && x.IsLocked == (int)IsLockedEnum.未锁定 && x.PositionName != "收货暂存区" && (x.AreaCode == isEnableSrmOne || x.AreaCode == isEnableSrmTwo)) //排序改为 限用日期 升序排序 【Editby shaocx,2024-06-22】 //.OrderBy(x => x.InStorageDate).ToList(); .OrderBy(x => x.LimitDate).ToList(); } //2021-6-19 修改为 picklist 有跟踪号的只能找跟踪号的,没跟踪号只能找没跟踪号 else { int prodectId = Convert.ToInt32(item.Product_Id); products = stockALL_No收货暂存区.Where(x => x.Product_Id == prodectId && x.PositionName != "收货暂存区" && (x.ExtendField04 == "" || x.ExtendField04 == null) && x.ContainerNo != "1" && x.IsLocked == (int)IsLockedEnum.未锁定 && (x.AreaCode == isEnableSrmOne || x.AreaCode == isEnableSrmTwo)) //排序改为 限用日期 升序排序 【Editby shaocx,2024-06-22】 //.OrderBy(x => x.InStorageDate).ToList(); .OrderBy(x => x.LimitDate).ToList(); } #region 增加指定库位号的过滤 【EditBy shaocx,2022-06-15】 //增加指定库位号的过滤 【EditBy shaocx,2022-06-15】 if (!string.IsNullOrEmpty(sale.AuditRemark)) { products = products.Where(x => x.PositionName == sale.AuditRemark).ToList(); } #endregion if (products.Count < 1) { alack++; item.ExtendField03 = "缺货中"; //if (sale.OrderType == "SAP生产订单" && lackTop != null) if (sale.OrderType == SysGlole.SAP_ORDER_TEXT && lackTop != null) { #region 写入缺料报表 #region 寻找暂存区数量 List stroe = new List(); string trankNum = item.TrackingNumber; string materalNo = item.ProductCode; decimal tempoaray = 0M;//暂存区数量 if (item.TrackingNumber != null) { stroe = stockALL.Where(x => x.ExtendField04 == trankNum && x.ProductCode == materalNo && x.PositionName == "收货暂存区").ToList(); } else { stroe = stockALL.Where(x => (x.ExtendField04 == null || x.ExtendField04 == "") && x.ProductCode == materalNo && x.PositionName == "收货暂存区").ToList(); } if (stroe != null) { tempoaray = (decimal)stroe.Sum(x => x.ProductStorage); } #endregion lackOrderList lackList = new lackOrderList(); // lackList.lackId = lackTop.lackId;//主表ID lackList.saleCode = item.SaleCode;//销售单号 lackList.saleCodeItem = item.ExtendField06;//销售项号 lackList.materailCode = item.ProductCode;//物料编号 lackList.materailName = item.ProductName;//物料名称 lackList.lackQuantity = (decimal)item.QuantityOrder;//缺料数量 lackList.temporaryQuantity = tempoaray;//暂存区数量 lackList.storageQuantity = outQty;//库存数量 lackList.storageUnit = item.SmallUnit;//库存单位 lacks.Add(lackList); //新增 出库订单分批出库历史记录明细表 【EditBy shaocx,2022-10-16】 Sale_Order_HistoryHandler.AddSale_Order_History_ItemsForLack(sale, item, sale_Order_History, lackList, mod, "缺料", ""); #endregion } continue;//如果都找不到 ,标记此条未缺货中 } #endregion //按出库数量计算 需要多少个相关库位 validQuantity quantityOrder #region 一个库位刚好等于出库数量的 //for (int i = 0; i < products.Count; i++)//如果库存数量刚好等于要出货的数量 直接出,不然下个循环 库存依次相加当大于等于出库量 出库之和 //{ // if (item.QuantityOrder == (decimal)products[i].ProductStorage) // { // address.Add(products[i]); // item.ExtendField03 = "已分配"; // break; // } //} #endregion List curStoreList = new List();//记录找到的出库对象集合,准备要出库的 #region 计算总共需要的库存数 for (int j = 0; j < products.Count; j++) { outQty += (decimal)products[j].ProductStorage; curStoreList.Add(products[j]); if (outQty >= item.QuantityOrder) { break;//什么时候大于了就退出 } } #endregion #region 缺料出货 if (outQty < item.QuantityOrder) {//缺货,如果发现库存数量要小于需求数量,就认为缺货 if (outQty > 0) { item.ExtendField03 = "部分缺货"; } else { item.ExtendField03 = "缺货中"; } //if (sale.OrderType == "SAP生产订单" && lackTop != null) if (sale.OrderType == SysGlole.SAP_ORDER_TEXT && lackTop != null) { #region 写入缺料报表 List lack = new List(); string trankNum = item.TrackingNumber; string materalNo = item.ProductCode; decimal tempoaray = 0M;//库存数量 #region 寻找暂存区数量 if (item.TrackingNumber != null) { lack = stockALL.Where(x => x.ExtendField04 == trankNum && x.ProductCode == materalNo && x.PositionName == "收货暂存区").ToList(); } else { lack = stockALL.Where(x => (x.ExtendField04 == null || x.ExtendField04 == "") && x.ProductCode == materalNo && x.PositionName == "收货暂存区").ToList(); } tempoaray = lack == null ? 0M : (decimal)lack.Sum(x => x.ProductStorage); #endregion lackOrderList lackList = new lackOrderList(); // lackList.lackId = lackTop.lackId;//主表ID lackList.saleCode = item.SaleCode == null ? "" : item.SaleCode;//销售单号 lackList.saleCodeItem = item.ExtendField06 == null ? "" : item.ExtendField06;//销售项号 lackList.materailCode = item.ProductCode;//物料编号 lackList.materailName = item.ProductName == null ? "" : item.ProductName;//物料名称 lackList.lackQuantity = (decimal)item.QuantityOrder - outQty; //缺料数量 lackList.temporaryQuantity = tempoaray;//暂存区数量 lackList.storageQuantity = 0M;//库存数量 lackList.storageUnit = item.SmallUnit == null ? "" : item.SmallUnit;//库存单位 lacks.Add(lackList); //新增 出库订单分批出库历史记录明细表 【EditBy shaocx,2022-10-16】 Sale_Order_HistoryHandler.AddSale_Order_History_ItemsForLack(sale, item, sale_Order_History, lackList, mod, "缺料", ""); #endregion } // continue;//如果数量小于出库数量的 也标记缺货中 客户要新建单子,出库数量不能大于库存量 } else {//不缺货 item.ExtendField03 = "已分配"; //新增 出库订单分批出库历史记录明细表 【EditBy shaocx,2022-10-16】 Sale_Order_HistoryHandler.AddSale_Order_History_ItemsForNoLack(sale, item, sale_Order_History, mod, "不缺料", ""); } #endregion #region 写入任务表 for (int k = 0; k < curStoreList.Count; k++) { // 出口 //大 空托盘满 回库 1017 //小 空托盘满 回库 1018 //整托出库口 1001 //分拣不助力 1003 //分拣助力 1008 string toPlace = "";//目标地址临时变量 #region 计算目标地址 if (sale.OrderExit != null)//如果指定出口就去一号口 { #region 指定出库口的情况 if (sale.OrderExit == 1) {//指定去1号口 toPlace = "1001"; } else { if (sale.OrderExit == 2) {//指定去2号口 toPlace = "1003"; } else {//指定去3号口 toPlace = "1008"; } } #endregion } else { #region 不指定出库口的情况 string positionName = curStoreList[k].PositionName; List checkExit = mod.Base_ProductPosition.Where(x => x.PositionName == positionName).ToList(); if (checkExit.Count > 1)//大于1说明是一个托盘里有两种物料 必须去分拣区 { if (curStoreList[k].IsBoosterArm == 1)//如果需要助力臂 { toPlace = "1008"; } else { //toPlace = "1003"; //按照规则选择出库口 【Editby shaocx,2022-06-09】 toPlace = BussinessExtension.BussinessExtension.GetOut(mod, last_toplace); } } else { if (checkExit[0].ProductStorage > item.QuantityOrder)//如果库存数量大于出库数量 说明还需要回去要去分拣区 { if (curStoreList[k].IsBoosterArm == 1)//如果需要助力臂 { toPlace = "1008"; } else { //toPlace = "1003"; //按照规则选择出库口 【Editby shaocx,2022-06-09】 toPlace = BussinessExtension.BussinessExtension.GetOut(mod, last_toplace); } } else { if (curStoreList[k].IsBoosterArm == 1)//如果需要助力臂 { toPlace = "1008"; } else { toPlace = "1001";//如果等于出库数量就去1号口 } } } #endregion } #endregion last_toplace = toPlace;//记录本次循环上一个的目标点 【EditBy shaocx,2022-10-15】 string sourcePlace = curStoreList[k].PositionName.Split('-')[1] + "-" + curStoreList[k].PositionName.Split('-')[2] + "-" + curStoreList[k].PositionName.Split('-')[3];//源地址转换 int areaCode = Convert.ToInt32(curStoreList[k].PositionName.Split('-')[0]); Task_Queue addTask = new Task_Queue(); addTask.BillCode = sale.OrderCode;//来源单号 addTask.TaskType = ((int)TaskTypeEnum.常规出库).ToString(); addTask.PlateType = curStoreList[k].PlateType;//器具种类-大托盘小托盘 addTask.PlateCode = curStoreList[k].PlateCode;//母托盘编号 addTask.Bill_Id = (int)sale.Order_Id;// 单据id addTask.OrderNumber = sale.PriorityNo;//任务执行优先级 addTask.TaskStatus = "未下发";//任务状态 addTask.FromPositionName = sourcePlace;//起始地址 addTask.ToPositionName = toPlace;//目标地址 addTask.DoCount = areaCode;//库区 addTask.Direction = areaCode == 1 ? "2" : "4";//出库不需要托盘高度 addTask.CreateDate = DateTime.Now; addTask.Creator = sale.Creator; addTask.UserProduct_Id = 1007;//账套id 老谢bug addTask.IsDoing = (int)item.OrderList_Id;//记录出库明细表ID,出库确认用(只有出库用) taskList.Add(addTask);//添加到集合 循环外合并相同起始位任务 Base_ProductPosition exitProduct = mod.Base_ProductPosition.Find(curStoreList[k].ProductPosition_Id); #region 写入出库数量 if (toPlace == "1003" || toPlace == "1008" || toPlace == "1001") { if ((k + 1) == curStoreList.Count) { //如有是最后一个托盘 且去分拣区的 出库数量有可能大于出库数量 //托盘库存数量加上要出库数量 减去所有出库托盘上的数量 等于 本托盘上的要出库的数量 //显示在分拣上页面上告诉操作人员拿走多少物料 if ((decimal)curStoreList[k].ProductStorage > exitQty) { // item.QuantityOrder 出库数量 exitProduct.ExtendField02 = exitQty.ToString(); exitProduct.Remark = item.ExtendField01;//移动类型 } else { exitProduct.ExtendField02 = curStoreList[k].ProductStorage.ToString(); exitQty -= (decimal)curStoreList[k].ProductStorage; exitProduct.Remark = item.ExtendField01;//移动类型 } } else { //如果不是最后一个托盘 肯定托盘里有多种物料 那么出库数量就是托盘里物料的数量 exitProduct.ExtendField02 = ((decimal)curStoreList[k].ProductStorage).ToString(); //增加下面一行代码,解决 显示要分拣数量老是是托盘库存的问题 【EditBy shaocx,2022-06-08】 exitQty -= (decimal)curStoreList[k].ProductStorage; } exitProduct.ContainerNo = "1";//库位锁定 //增加物料锁定和解锁的时间和备注记录 [EditBy shaocx,2023-07-26] exitProduct.DoContainerNoTime = DateTime.Now; exitProduct.OpRemark = "处理待下架的表单,创建出库任务,锁定物料"; } #endregion // mod.SaveChanges(); } #endregion item.ValidQuantity -= (decimal)item.QuantityOrder;//修改未出数量 item.QuantityOrder = 0; //本次出库数量归零 // mod.SaveChanges(); #endregion } var mergeTask = taskList.GroupBy(x => x.FromPositionName);//起始位相同的任务合并 foreach (var merge in mergeTask) { mod.Task_Queue.Add(merge.ToList()[0]); string positionName = merge.ToList()[0].DoCount + "-" + merge.ToList()[0].FromPositionName; Base_Position BasePosition = mod.Base_Position.FirstOrDefault(x => x.PositionName == positionName); if (BasePosition != null) { BasePosition.IsLocked = 1; BasePosition.Remark = "订单出库-找到库存时,库位锁定!"; } else { logtxt.txtWrite("类名:Form1/函数名:writeOutTask锁定库位失败/库位号: " + positionName, 2); } } #region 更改主表状态 if (outTaskSaleNum == saleList.Count) { int num = sale.OutNumber == null ? 0 : Convert.ToInt32(sale.OutNumber); sale.Client_Id = sale.Client_Id == null ? 0 : sale.Client_Id; sale.Client_Id += num; //sale.StatusText = "已分配"; sale.StatusText = Sale_Order_StatusEnum.已分配.ToString(); sale.StatusID = Convert.ToByte(Sale_Order_StatusEnum.已分配); //sale.StatusID = 7; sale.OutNumber = 0; //sale.ExtendField03 = (byte)7; } if (outTaskSaleNum == 0) { int num = sale.OutNumber == null ? 0 : Convert.ToInt32(sale.OutNumber); sale.Client_Id = sale.Client_Id == null ? 0 : sale.Client_Id; sale.Client_Id += num; //sale.StatusText = "部分分配"; sale.StatusText = Sale_Order_StatusEnum.部分分配.ToString(); sale.StatusID = Convert.ToByte(Sale_Order_StatusEnum.部分分配); //sale.StatusID = 1; sale.OutNumber = 0; // sale.ExtendField03 = (byte)5; outNumber } if (alack > 0) { //sale.StatusText = "缺货中"; sale.StatusText = Sale_Order_StatusEnum.缺货中.ToString(); sale.StatusID = Convert.ToByte(Sale_Order_StatusEnum.缺货中); //sale.StatusID = 1; sale.OutNumber = 0; } #endregion int ressuleMost = mod.SaveChanges();//多次保存 for (int i = 0; i < 10; i++) { if (ressuleMost == 0) { ressuleMost = mod.SaveChanges(); } else { break; } } #region 如果缺料明细数量大于0,就写入缺料报表 if (lacks.Count > 0) { try { mod.lackOrder.Add(lackTop);//加入主表 int result = mod.SaveChanges(); if (result == 1) { foreach (var LackItem in lacks) { LackItem.lackId = lackTop.lackId; mod.lackOrderList.Add(LackItem); } } int lackNum = mod.SaveChanges(); } catch (Exception ex) { logtxt.txtWrite("类名:Form1/函数名:writeOutTask写入缺料报表异常/ " + ex.Message + "出错行号" + (string)ex.StackTrace, 2); } } #endregion } #endregion #endregion } trans.Commit();//提交事务 } catch (Exception) { trans.Rollback();//回滚事务 throw; } } #endregion } this.lbl_Msg_writeOutTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + " 正常循环一次!"; } } catch (Exception ex) { //logtxt.txtWrite("类名:Form1/函数名:writeOutTask出库写入任务异常/ " + ex.Message + "出错行号" + (string)ex.StackTrace, 2); Log4NetHelper.WriteErrorLog(LogType.WriteOutTask, "出库写入任务异常:" + ex.Message, ex); this.lbl_Msg_writeOutTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + " 异常!:" + ex.Message; } } } /// 码盘上架写入任务列表 /// 码盘上架写入任务列表 /// private void writeInTask() { var _taskType = TaskTypeEnum.常规入库; while (true) { Thread.Sleep(5000);//原先2秒,现在增加到5秒一次 [EditBy shaocx,2022-05-06] this.lbl_Msg_writeInTask.Text = ""; try { using (dbModel mod = new dbModel()) { //判断是否有闲时移库任务在执行 [EditBy shaocx,2022-09-22] var isExistRuningTask = FreeTimeMoveLocationTaskHandler.IsExistRuningTask(mod); if (isExistRuningTask) { this.lbl_Msg_writeInTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前存在闲时移库任务在执行中,不允许下发其他任务,只允许下发移库任务!"; continue; } Purchase_Shelve shelveTask = mod.Purchase_Shelve.FirstOrDefault(x => x.OnShelveStatus == "待上架"); if (shelveTask != null) { string PlateCode = shelveTask.PlateCode;//母托盘编号 if (lastPlateCode == PlateCode)//并发物理防御 (码盘上架产生两条入库任务 怀疑是EF没保存成功导致) { shelveTask.OnShelveStatus = "上架完成_同一托盘号连续上架"; mod.SaveChanges(); continue; } //增加判断是否上一个任务就是这个托盘号的入库 [EditBy shaocx,2022-05-06] var q_taskType = ((int)_taskType).ToString(); var db_Exist = mod.Task_Queue.Where(x => x.PlateCode == PlateCode && x.TaskType == q_taskType && x.BillCode == shelveTask.ShelveCode).FirstOrDefault(); if (db_Exist != null) { this.lbl_Msg_writeInTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + ",任务表Task_Queue已经存在同托盘号,同单据编号,同任务类型的任务,不允许再重复建Task_Queue任务,托盘号:" + PlateCode + ",单据编号:" + shelveTask.ShelveCode + ",任务类型是" + _taskType.ToString(); continue; } Base_Plate ContinerType = mod.Base_Plate.FirstOrDefault(x => x.PlateCode == PlateCode); string containerType = "";//托盘类型 #region 通过托盘号分辨托盘类型 if (ContinerType == null) { shelveTask.OnShelveStatus = "无此托盘号"; mod.SaveChanges(); continue; } else { if (ContinerType.PlateType == "smallContiner") { containerType = "1"; } else { containerType = "2"; } } #endregion shelveTask.OnShelveStatus = "上架中"; shelveTask.ModifyDate = DateTime.Now;//增加修改时间 [EditBy shaocx,2022-05-06] shelveTask.Modifier = "WCS"; //int shelveId = (int)shelveTask.Shelve_Id;//出库主表ID string sourcePlace = containerType == "1" ? "1021" : "1026";//输送线编号 小的是1021,大的是1026 #region 写入任务表 Task_Queue addTask = new Task_Queue(); addTask.BillCode = shelveTask.ShelveCode;//来源单号 addTask.TaskType = ((int)_taskType).ToString(); addTask.PlateType = containerType;//器具种类-大托盘小托盘 addTask.PlateCode = PlateCode;//母托盘编号 addTask.Bill_Id = shelveTask.Shelve_Id;// 单据id addTask.OrderNumber = 0;//任务执行优先级 addTask.TaskStatus = "下发中";//任务状态 addTask.FromPositionName = sourcePlace;//起始地址 addTask.ToPositionName = "";//目标地址给空返回测量高度后重新写入 addTask.Direction = "";//托盘高度给空返回测量高度后重新写入 addTask.DoCount = 0;//库区给空返回测量高度后重新写入 addTask.CreateDate = DateTime.Now; addTask.Creator = shelveTask.Creator; addTask.UserProduct_Id = 1007;//账套id 老谢bug mod.Task_Queue.Add(addTask); //数据库保存 int i = mod.SaveChanges(); if (i <= 1) { logtxt.txtWrite("类名:Form1/函数名:writeTask码盘上架保存修改状态失败,会产生并发 ", 1); this.lbl_Msg_writeInTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + ",数据库保存[失败!!!],托盘号:" + PlateCode + ",单据编号:" + shelveTask.ShelveCode + ",任务类型是" + _taskType.ToString(); } else { this.lbl_Msg_writeInTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + ",数据库保存[成功],托盘号:" + PlateCode + ",单据编号:" + shelveTask.ShelveCode + ",任务类型是" + _taskType.ToString(); lastPlateCode = PlateCode;//记录本次托盘号,下一次比对 防止并发 } #endregion } } } catch (Exception ex) { //logtxt.txtWrite("类名:Form1/函数名:writeTask码盘上架写入任务异常/ " + ex.Message + "出错行号" + (string)ex.StackTrace + ",异常堆栈:" + JsonConvert.SerializeObject(ex), 2); Log4NetHelper.WriteErrorLog(LogType.WriteInTask, "入库写入任务异常:" + ex.Message, ex); this.lbl_Msg_writeInTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + ",出现异常:" + ex.Message; } } } /// 检测入口拆盘机是否空,出口叠盘机是否满 /// 检测入口拆盘机是否空,出口叠盘机是否满 /// private void containerIsFull() { //GetCheckIsNeedOrSendContainer() // 入口, //小 库里出来到 1020 //大 库里出来到 1025 //上架小 1021 //上架大 1026 //出口 //大 空托盘满 回库 1017 //小 空托盘满 回库 1018 //整托出库口 1001 //分拣不助力 1003 //分拣助力 1008 while (true) { wcftest.wcfApi.BackData resultDate = new BackData(); resultDate = GetBackDataFromWCS(); Thread.Sleep(2000); try { bool isInMoreHighPosition = false; if (resultDate == null) { this.tb_Msg_containerIsFull.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "调用wcs设备状态信息返回resultDate为NULL"; continue; } this.tb_Msg_containerIsFull.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "调用wcs设备状态信息返回resultDate.Type:" + resultDate.Type + ",resultDate.DevId:" + resultDate.DevId + ",(resultDate.DevId 4是大盘拆盘机,5是小盘拆盘机,6是大盘叠盘机,7是小盘叠盘机)" + "(resultDate.Type 0不需要操作,1是入口需要空托盘,2是出库空托盘满了要回库 ),resultDate.Id:" + resultDate.Id; if (resultDate.Type == 1 || resultDate.Type == 2)//等于0不需要操作,1是入口需要空托盘,2是出库空托盘满了要回库 { using (dbModel mod = new dbModel()) { //判断是否有闲时移库任务在执行 [EditBy shaocx,2022-09-22] var isExistRuningTask = FreeTimeMoveLocationTaskHandler.IsExistRuningTask(mod); if (isExistRuningTask) { this.tb_Msg_containerIsFull.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前存在闲时移库任务在执行中,不允许下发其他任务,只允许下发移库任务!"; continue; } //读取数据库的叠盘机和拆盘机信号, 任务没前信号会一直给所以要做比对 ContainerIsFullOrEmpty lastTaskSql = mod.ContainerIsFullOrEmpty.Find(1);//1就是第一条数据 string sourcePlace = "";//输送线编号 int containerTypeId = 0; string toPlace = ""; int areaNo = 0; #region 空托盘满入库 var findEmptyReason = ""; if (resultDate.Type == 2)//等于2是空托盘满入库 { #region 使用事务 [EditBy shaocx,2022-09-22] using (var trans = mod.Database.BeginTransaction()) { try { #region 处理 空托盘满入库 if (resultDate.DevId == (int)DeviceId.大盘叠盘机) { IsFull_BigFoldingPlate = true; if (lastTaskSql.DieBig == resultDate.Id) { this.tb_Msg_containerIsFull.Text += " \r\n ,【报警】" + "大叠盘任务id重复:" + resultDate.Id; logtxt.txtWrite("类名:Form1/函数名:callContainer 大叠盘任务id重复:" + resultDate.Id, 2); continue; } lastTaskSql.DieBig = resultDate.Id; sourcePlace = "1017"; containerTypeId = 2; toPlace = FindEmptyLocationHandler.findStorage(mod, "", true, ref isInMoreHighPosition, ref findEmptyReason, 2, 2, 4, 0);//分配大库位 areaNo = 2;//大库区 } else { IsFull_SmallFoldingPlate = true; if (lastTaskSql.DieSmall == resultDate.Id) { logtxt.txtWrite("类名:Form1/函数名:callContainer 小叠盘任务id重复:" + resultDate.Id, 2); this.tb_Msg_containerIsFull.Text += " \r\n ,【报警】" + "小叠盘任务id重复:" + resultDate.Id; continue; } lastTaskSql.DieSmall = resultDate.Id; sourcePlace = "1018"; containerTypeId = 1; toPlace = FindEmptyLocationHandler.findStorage(mod, "", true, ref isInMoreHighPosition, ref findEmptyReason, 1, 1, 2, 0);//分配小库位 // toPlace=mod areaNo = 1;//小库区 } // (任务id-起始位-目标位-托盘类型(大小)-任务类型) if (toPlace == "") { //listInfo.Items.Add("满托回库,库位已满" ); //listInfo.Refresh(); //logtxt.txtWrite("类名:taskApi,函数名:callContainer 库位满了" + containerTypeId.ToString(), 0); //不做日记 一但库位满会产生大量垃圾日志 this.tb_Msg_containerIsFull.Text += " \r\n ,【报警】" + " 获取托盘满回库的库位toPlace为空,原因:" + findEmptyReason; continue; } var isExistNoFinishedTaskFor满空托回库 = BussinessExtension.BussinessExtension.IsExistNoFinishedTaskFor满空托回库(mod, sourcePlace); if (isExistNoFinishedTaskFor满空托回库) { this.tb_Msg_containerIsFull.Text += " \r\n ,【报警】" + " 已经存在未结束的满空托回库的任务,来源位:" + sourcePlace; continue; } Task_Queue CallContainerTaks = new Task_Queue(); CallContainerTaks.TaskType = ((int)TaskTypeEnum.满空托回库).ToString();//任务类型 CallContainerTaks.OrderNumber = 0;//任务权重 CallContainerTaks.TaskStatus = "未下发";//任务状态 CallContainerTaks.PlateType = containerTypeId == 1 ? ((int)Sys_containerType.小托盘).ToString() : ((int)Sys_containerType.大托盘).ToString();//托盘类型 CallContainerTaks.FromPositionName = sourcePlace; CallContainerTaks.ToPositionName = toPlace; CallContainerTaks.CreateDate = DateTime.Now; CallContainerTaks.Creator = "系统"; CallContainerTaks.DoCount = areaNo;//库区 CallContainerTaks.UserProduct_Id = 1007;//账套id 老谢bug //更新数量为0 【EditBy shaocx,2022-03-12】 Base_EquipmentHandler.FoldingPlateMachine_UpdateCurQuantityZero(mod, Convert.ToInt32(CallContainerTaks.PlateType)); //垃圾值都赋值0 转到autoTask()里有说明 string height = ""; if (areaNo == 1) { height = "2"; } else { height = "4"; } CallContainerTaks.Direction = height;//托盘高度 mod.Task_Queue.Add(CallContainerTaks);//满空托回库任务 int num = mod.SaveChanges(); if (num > 0) { trans.Commit(); } else { throw new Exception("寻找满空托回库,保存数据失败"); } #endregion } catch (Exception) { trans.Rollback(); throw; } } #endregion } #endregion #region 需要空托盘 else//等于1是需要空托盘 { #region 使用事务 [EditBy shaocx,2022-09-22] using (var trans = mod.Database.BeginTransaction()) { try { if (resultDate.DevId == (int)DeviceId.大盘拆盘机) { if (lastTaskSql.ChaiBig == resultDate.Id) { logtxt.txtWrite("类名:Form1/函数名:callContainer 大拆盘机任务id重复:" + resultDate.Id, 2); this.tb_Msg_containerIsFull.Text += " \r\n ,【报警】" + "大拆盘机任务id重复:" + resultDate.Id; continue; } lastTaskSql.ChaiBig = resultDate.Id; areaNo = 2;//库区 toPlace = "1025";//入口大拆盘机输送线地址 containerTypeId = 2;//2是大托盘 } else { if (lastTaskSql.ChaiSmall == resultDate.Id) { logtxt.txtWrite("类名:Form1/函数名:callContainer 小拆盘机任务id重复:" + resultDate.Id, 2); this.tb_Msg_containerIsFull.Text += " \r\n ,【报警】" + "小拆盘机任务id重复:" + resultDate.Id; continue; } lastTaskSql.ChaiSmall = resultDate.Id; areaNo = 1;//小库区 toPlace = "1020";//入口小拆盘机输送线地址 containerTypeId = 1;//1是小托盘 } // (任务id-起始位-目标位-托盘类型(大小)-任务类型) sourcePlace = findEmptyContainer(mod, areaNo.ToString());//找库存空托盘 1号库区放小托盘,2号库区放大托盘 if (sourcePlace == "") { logtxt.txtWrite("类名:Form1/函数名:containerIsFull找不到库位", 2); this.tb_Msg_containerIsFull.Text += " \r\n ,【报警】" + "找不到库位"; continue; } sourcePlace = sourcePlace.Split('-')[1] + "-" + sourcePlace.Split('-')[2] + "-" + sourcePlace.Split('-')[3]; var isExistNoFinishedTaskFor空托出库 = BussinessExtension.BussinessExtension.IsExistNoFinishedTaskFor空托出库(mod, toPlace); if (isExistNoFinishedTaskFor空托出库) { this.tb_Msg_containerIsFull.Text += " \r\n ,【报警】" + " 已经存在未结束的空托出库的任务,目标位:" + toPlace; continue; } Task_Queue outEmptyContainer = new Task_Queue(); outEmptyContainer.TaskType = ((int)TaskTypeEnum.空托出库).ToString();//任务类型 outEmptyContainer.OrderNumber = 0;//任务权重 outEmptyContainer.TaskStatus = "未下发";//任务状态 outEmptyContainer.PlateType = containerTypeId == 1 ? ((int)Sys_containerType.小托盘).ToString() : ((int)Sys_containerType.大托盘).ToString();//托盘类型 outEmptyContainer.FromPositionName = sourcePlace; outEmptyContainer.ToPositionName = toPlace; outEmptyContainer.CreateDate = DateTime.Now; outEmptyContainer.Creator = "系统"; outEmptyContainer.DoCount = areaNo;//库区 outEmptyContainer.UserProduct_Id = 1007;//账套id 老谢bug垃圾值必须给 //垃圾值都赋值0 这是WCS协议 string height = ""; if (areaNo == 1) { height = "2"; } else { height = "4"; } outEmptyContainer.Direction = height;//托盘高度 mod.Task_Queue.Add(outEmptyContainer); int num = mod.SaveChanges(); if (num > 0) { trans.Commit(); } else { throw new Exception("寻找库里空托盘,保存数据失败"); } } catch (Exception ex) { trans.Rollback(); throw; } } #endregion logtxt.txtWrite("类名:from1 ,函数名:callContainer 拆盘任务发送成功 containerType:" + containerTypeId.ToString(), 0); this.tb_Msg_containerIsFull.Text += " \r\n ,【成功】" + "拆盘任务发送成功 containerType:" + containerTypeId.ToString(); } #endregion } } } catch (Exception ex) { //logtxt.txtWrite("类名:Form1/函数名:callContainer 空托盘出库或满托回库异常" + ex.Message + "出错行号" + (string)ex.StackTrace, 2); Log4NetHelper.WriteErrorLog(LogType.ContainerIsFull, "异常:" + ex.Message, ex); this.lbl_Msg_containerIsFull.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "异常:" + ex.Message; } } } #region 任务完成处理线程 /// 任务完成 /// 任务完成 /// private void finishConfirm() { while (true) { Thread.Sleep(2000); try { using (dbModel mod = new dbModel()) { List confirmList = mod.Task_Queue.Where(x => x.TaskStatus == "已下发").ToList(); if (confirmList != null && confirmList.Count > 0) { try { finishConfirmHandler(mod, confirmList);//有错误就抛出异常 } catch (Exception) { throw; } } else { this.lbl_Msg_FinishConfirm.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "没有要处理的任务..."; } } } catch (Exception ex) { logtxt.txtWrite("类名:Form1/函数名:finishConfirm 处理任务完成产生异常" + "出错行号" + ex.StackTrace.ToString(), 2); this.lbl_Msg_FinishConfirm.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "出现异常:" + ex.Message; } } } /// /// 任务完成处理类 /// /// private void finishConfirmHandler(dbModel mod, List confirmList) { foreach (var item in confirmList) { //使用事务 using (DbContextTransaction tran = mod.Database.BeginTransaction()) { try { single_finishConfirmHandler(mod, item); tran.Commit(); this.lbl_Msg_FinishConfirm.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "事务提交,处理正常...,PLC任务号:" + item.PlcTaskNo + ",任务号:" + item.Task_Id + ",任务类型:" + item.TaskType; } catch (Exception ex) { tran.Rollback(); this.lbl_Msg_FinishConfirm.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "事务回滚:" + ex.Message + ",处理失败...,PLC任务号:" + item.PlcTaskNo + ",任务号:" + item.Task_Id + ",任务类型:" + item.TaskType; logtxt.txtWrite("类名:Form1/函数名:finishConfirmHandler 处理任务完成产生异常" + "出错行号" + ex.StackTrace.ToString() + ",异常堆栈:" + JsonConvert.SerializeObject(ex), 2); } } } } /// /// 任务完成处理类【单个】 /// /// private void single_finishConfirmHandler(dbModel mod, Task_Queue item) { try { //注释以下内容!!!!! 【EditBy shaocx,2022-05-27】 /* //检测任务有没有产生异常 异常超过3此 改为异常状态下次不执行 if (item.ModifyID > 3) { item.TaskStatus = "任务异常"; mod.SaveChanges(); continue; } //*/ // 任务执行中, //任务完成, //尺寸超高 int result = 0; #region 跟WCS获取任务执行情况 if (IsVirtualMode) { result = 1;//模拟环境下,改为 1(任务完成) 【EditBy shaocx,2022-06-20】 VirtualModeHelper.ThrowExceptionWhenVirtualMode(IsVirtualMode); } else { try { //修复 【EditBy shaocx,2022-04-18】 int plcTaskNo = 0; if (item.PlcTaskNo != null && Convert.ToInt32(item.PlcTaskNo) > 0) { plcTaskNo = Convert.ToInt32(item.PlcTaskNo); } else { //感觉这里有问题。 //plcTaskNo = ExtendHelper.ConvertPlcNO(item.Task_Id); //抛异常 【Editby shaocx,2023-03-18】 throw new Exception("任务表的PlcTaskNo值不符合!任务号:" + item.Task_Id); } //result = wcsApi.GetTaskIsFinishOrCheckOk(item.Task_Id); int wmsTaskId = item.Task_Id;//使用最新参数,任务表的ID查询wcs任务 【EditBy shaocx,2022-09-28】 //int wmsTaskId = 0;//暂时写先死为0,先跑一段时间,等之前任务都清理了,再改回 【EditBy shaocx,2022-09-22】 result = wcsApi.GetTaskIsFinishOrCheckOk(plcTaskNo, wmsTaskId);//访问WCS的任务状态 logtxt.txtWrite("类名:Form1/函数名:finishConfirm 查询任务完成wcsApi.GetTaskIsFinishOrCheckOk,任务ID:" + item.Task_Id + ",PLC任务号:" + plcTaskNo + ",返回结果:" + result, 2); } catch (Exception ex) { logtxt.txtWrite("类名:Form1/函数名:finishConfirm 查询任务完成产生异常" + ex.Message + "出错行号" + (string)ex.StackTrace, 2); throw ex;//抛出异常 【EditBy shaocx,2022-05-28】 } } #endregion if (result == (int)taskInfo.任务执行中) { } else if (result == (int)taskInfo.任务完成) { #region 常规入库确认 if (item.TaskType == ((int)TaskTypeEnum.常规入库).ToString()) { writeProductPositionFor常规入库(mod, item, (item.Bill_Id == null ? 0 : Convert.ToInt32(item.Bill_Id)), item.ToPositionName, (int)item.DoCount, item.PlateType); item.TaskStatus = "完成"; } #endregion #region 满空托回库任务确认 if (item.TaskType == ((int)TaskTypeEnum.满空托回库).ToString()) { Base_ProductPosition EmptyContainer = new Base_ProductPosition(); EmptyContainer.ProductStorage = item.PlateType == "1" ? 10 : 8;//当前数量 EmptyContainer.PlateType = item.PlateType;//托盘类型 EmptyContainer.AreaCode = item.DoCount.ToString();//库区 EmptyContainer.ExtendField01 = ((int)ContainerOrProduct.空托盘).ToString();//标志为空托盘, //////////////以下为不为空字段 EmptyContainer.ClassName = TaskTypeEnum.满空托回库.ToString(); EmptyContainer.StorageName = "立体库"; EmptyContainer.PositionName = item.DoCount.ToString() + "-" + item.ToPositionName;//库位地址 var msg = ""; var isRight = ExtendHelper.ValidateIsRightForPositionName(EmptyContainer.PositionName, ref msg); if (!isRight) { throw new Exception("满空托回库(任务确认):" + msg); } EmptyContainer.ProductCode = "0";//物料编号 EmptyContainer.ProductName = "0";//物料名称 EmptyContainer.InStorageDate = DateTime.Now; /////------以下为垃圾字段 EmptyContainer.MainID = 0; EmptyContainer.DetailID = 0; EmptyContainer.Storage_Id = 87; EmptyContainer.Product_Id = 50126; EmptyContainer.ProductModel = "0"; EmptyContainer.ConsignorCode = "GX30"; EmptyContainer.ConsignorName = "广州西门子"; EmptyContainer.Consignor_Id = 30; EmptyContainer.UserProduct_Id = 1007; EmptyContainer.ExtendField02 = ((int)usable.不可用).ToString();//出库数量给默认值 /////////////////// mod.Base_ProductPosition.Add(EmptyContainer); //空托处理,不需要记录出入库记录 【EditBy shaocx,2022-03-07】 item.TaskStatus = "完成"; Base_Position position = mod.Base_Position.Where(x => x.AreaCode == item.DoCount.ToString() && x.PositionName == item.DoCount.ToString() + "-" + item.ToPositionName).FirstOrDefault(); //position.IsFreeze = 1;//标志有货 position.IsFreeze = (int)IsFreezeEnum.有货; position.Remark = "满空托回库任务确认-解锁库位!"; position.IsLocked = 0;//解除货位锁定 //position.PositionType = 6;//货位类型 常规库位,暂存区,空托盘 position.PositionType = (int)PositionType.空托盘; //使用枚举 【EditBy shaocx,2022-03-06】 logtxt.txtWrite("类名:Form1/函数名:finishConfirm满托回库完成 托盘类型" + item.PlateType, 0); } #endregion #region 入库拆盘任务确认 if (item.TaskType == ((int)TaskTypeEnum.入库拆盘).ToString()) { item.TaskStatus = "完成"; } #endregion #region 空托出库 if (item.TaskType == ((int)TaskTypeEnum.空托出库).ToString()) { item.TaskStatus = "完成"; List emptyContainer = mod.Base_ProductPosition.Where(x => x.AreaCode == item.DoCount.ToString() && x.PositionName == (item.DoCount.ToString() + "-" + item.FromPositionName)).ToList(); foreach (var clearPosition in emptyContainer) { mod.Base_ProductPosition.Remove(clearPosition);//空托出库完成删了这条记录 //空托出库不需要记录出入库记录 } Base_Position emptyPosition = mod.Base_Position.Where(x => x.AreaCode == item.DoCount.ToString() && x.PositionName == item.DoCount.ToString() + "-" + item.FromPositionName).FirstOrDefault(); //出库完了释放库位 //emptyPosition.IsFreeze = 0;//标志无货 emptyPosition.IsFreeze = (int)IsFreezeEnum.无货;//标志无货 emptyPosition.IsLocked = 0;//标志未锁定、 emptyPosition.Remark = "空托出库任务确认-解锁库位!"; } #endregion #region 常规出库 if (item.TaskType == ((int)TaskTypeEnum.常规出库).ToString()) { item.TaskStatus = "完成"; string PositionName = (item.DoCount + "-" + item.FromPositionName); List sortingMake = mod.Base_ProductPosition.Where(x => x.PositionName == PositionName).ToList(); if (sortingMake.Count > 0) { foreach (var SortingItem in sortingMake) { SortingItem.ExtendField03 = "1";//可用分拣 } } //修改 #region 修改出库单状态 if (item.ToPositionName == "1001" || item.ToPositionName == "1003" || item.ToPositionName == "1008") { Sale_Order sale = mod.Sale_Order.Find(item.Bill_Id); if (sale != null) { //出库单里的明细 List saleList = mod.Sale_OrderList.Where(x => x.Order_Id == sale.Order_Id).ToList(); int OrderIsFinish = 0; #region 检查出库单关联的出库任务是否全部完成, foreach (var exitConfirm in saleList) { List exitTaskList = mod.Task_Queue.Where(x => x.IsDoing == exitConfirm.OrderList_Id).ToList(); int OrderListIsFinish = 0; for (int i = 0; i < exitTaskList.Count; i++) { if (exitTaskList[i].TaskStatus != "完成") { OrderListIsFinish++; } } if (OrderListIsFinish == exitTaskList.Count) { OrderIsFinish++; exitConfirm.ExtendField03 = "完成"; } if (OrderListIsFinish > 0 && OrderListIsFinish < exitTaskList.Count) { exitConfirm.ExtendField03 = "部分完成"; } } if (OrderIsFinish == saleList.Count) { //sale.StatusID = 4; //sale.StatusText = "完成"; sale.StatusID = Convert.ToByte(Sale_Order_StatusEnum.完成); sale.StatusText = Sale_Order_StatusEnum.完成.ToString(); } if (OrderIsFinish > 0 && OrderIsFinish == saleList.Count) { //sale.StatusID = 6; //sale.StatusText = "部分完成"; sale.StatusID = Convert.ToByte(Sale_Order_StatusEnum.部分完成); sale.StatusText = Sale_Order_StatusEnum.部分完成.ToString(); } #endregion } } #endregion } #endregion #region 出库叠盘 if (item.TaskType == ((int)TaskTypeEnum.出库叠盘).ToString()) { item.TaskStatus = "完成"; //Base_ProductPosition emptyContainer = mod.Base_ProductPosition.Where(x => x.AreaCode == item.DoCount.ToString() && // x.PositionName == item.FromPositionName).FirstOrDefault(); //mod.Base_ProductPosition.Remove(emptyContainer);//空托出库完成删了这条记录 Task_Queue backTask = mod.Task_Queue.Where(x => x.PlateCode == item.PlateCode && x.TaskType == "4").OrderByDescending(x => x.CreateDate).FirstOrDefault(); Base_Position emptyPosition = mod.Base_Position.Where(x => x.AreaCode == item.DoCount.ToString() && x.PositionName == item.DoCount.ToString() + "-" + backTask.FromPositionName).FirstOrDefault(); //出库完了释放库位 //emptyPosition.IsFreeze = 0;//标志无货 emptyPosition.IsFreeze = (int)IsFreezeEnum.无货;//标志无货 emptyPosition.IsLocked = 0;//标志未锁定 emptyPosition.Remark = "出库叠盘任务确认-解锁库位!"; } #endregion #region 余料回库 if (item.TaskType == ((int)TaskTypeEnum.余料回库).ToString()) { item.TaskStatus = "完成"; if (item.CreateID == null) {//表示是 真正的余料回库 #region 余料回库 List returnProductPosition = mod.Base_ProductPosition.Where(x => x.AreaCode == item.DoCount.ToString() && x.PositionName == item.DoCount.ToString() + "-" + item.ToPositionName).ToList(); //ContainerNo=0 库存解锁,任务合并的时候这个字段设置为1 if (returnProductPosition.Count > 0) { foreach (var returnItem in returnProductPosition) {// returnItem.ContainerNo = "0";//是否锁定 //增加物料锁定和解锁的时间和备注记录 [EditBy shaocx,2023-07-26] returnItem.DoContainerNoTime = DateTime.Now; returnItem.OpRemark = "任务完成线程处理之余料回库,解绑物料锁定"; returnItem.ExtendField03 = "0";//不可分拣 returnItem.ExtendField02 = "0";//分拣数量 } } Base_Position emptyPosition = mod.Base_Position.FirstOrDefault(x => x.AreaCode == item.DoCount.ToString() && x.PositionName == item.DoCount.ToString() + "-" + item.ToPositionName); //余料回库了释放库位 //emptyPosition.IsFreeze = 1;//标志有货 emptyPosition.IsFreeze = (int)IsFreezeEnum.有货;//标志有货 emptyPosition.IsLocked = 0;//标志未锁定 emptyPosition.Remark = "余料回库任务确认-解锁库位!"; #endregion } else {//表示是 空托盘入库,是从出库口1001人工入库的! Base_ProductPosition addPPForEmptyContainer = new Base_ProductPosition(); addPPForEmptyContainer.ProductStorage = item.PlateType == "1" ? 10 : 8;//当前数量 addPPForEmptyContainer.PlateType = item.PlateType;//托盘类型 addPPForEmptyContainer.AreaCode = item.DoCount.ToString();//库区 addPPForEmptyContainer.ExtendField01 = ((int)ContainerOrProduct.空托盘).ToString();//标志为空托盘, //////////////以下为不为空字段 addPPForEmptyContainer.ClassName = TaskTypeEnum.满空托回库.ToString(); addPPForEmptyContainer.StorageName = "立体库"; addPPForEmptyContainer.PositionName = item.DoCount.ToString() + "-" + item.ToPositionName;//库位地址 var msg = ""; var isRight = ExtendHelper.ValidateIsRightForPositionName(addPPForEmptyContainer.PositionName, ref msg); if (!isRight) { throw new Exception("满空托回库:" + msg); } addPPForEmptyContainer.ProductCode = "0";//物料编号 addPPForEmptyContainer.ProductName = "0";//物料名称 addPPForEmptyContainer.InStorageDate = DateTime.Now; /////------以下为垃圾字段 addPPForEmptyContainer.MainID = 0; addPPForEmptyContainer.DetailID = 0; addPPForEmptyContainer.Storage_Id = 87; addPPForEmptyContainer.Product_Id = 50126; addPPForEmptyContainer.ProductModel = "0"; addPPForEmptyContainer.ConsignorCode = "GX30"; addPPForEmptyContainer.ConsignorName = "广州西门子"; addPPForEmptyContainer.Consignor_Id = 30; addPPForEmptyContainer.UserProduct_Id = 1007; addPPForEmptyContainer.ExtendField02 = ((int)usable.不可用).ToString();//出库数量给默认值 /////////////////// mod.Base_ProductPosition.Add(addPPForEmptyContainer); //余料回库,因为之前在分拣确认时,就已经记录了出入库记录,因此这里就不需要记录出入库记录了 【EditBy shaocx,2022-03-07】 item.TaskStatus = "完成"; Base_Position position = mod.Base_Position.Where(x => x.AreaCode == item.DoCount.ToString() && x.PositionName == item.DoCount.ToString() + "-" + item.ToPositionName).FirstOrDefault(); //position.IsFreeze = 1;//标志有货 position.IsFreeze = (int)IsFreezeEnum.有货;//标志有货 position.IsLocked = 0;//解除货位锁定 position.Remark = "满空托回库确认-解锁库位!"; //position.PositionType = 6;//货位类型 常规库位,暂存区,空托盘 position.PositionType = (int)PositionType.空托盘; //使用枚举 【EditBy shaocx,2022-03-06】 logtxt.txtWrite("类名:Form1/函数名:finishConfirm满托回库完成 托盘类型" + item.PlateType, 0); } } #endregion #region 组盘出库 if (item.TaskType == ((int)TaskTypeEnum.组盘出库).ToString()) {//拼盘出库 item.TaskStatus = "完成"; Base_Position Positions = mod.Base_Position.FirstOrDefault(x => x.PositionName == item.DoCount + "-" + item.FromPositionName); if (Positions != null) { Positions.IsLocked = 0; Positions.Remark = "组盘出库任务确认-解锁库位!"; //Positions.IsFreeze = 0; Positions.IsFreeze = (int)IsFreezeEnum.无货; Positions.PositionType = 0; } } #endregion #region 移库 if (item.TaskType == ((int)TaskTypeEnum.移库).ToString()) { string toPositionName = item.DoCount + "-" + item.ToPositionName; string fromPositionName = item.DoCount + "-" + item.FromPositionName; List movePosition = mod.Base_ProductPosition.Where(x => x.PositionName == fromPositionName).ToList(); Base_Position fromPosition = mod.Base_Position.FirstOrDefault(x => x.PositionName == fromPositionName); Base_Position toPosition = mod.Base_Position.FirstOrDefault(x => x.PositionName == toPositionName); if (movePosition.Count > 0 && fromPosition != null && toPosition != null) {//转移库存 foreach (var itemMoveStock in movePosition) { //增加出入库记录 【EditBy shaocx,2022-10-18】,注意要放到最前面才可以 OutInStockTaskHandler.AddOutInStockTask22("系统", mod, OutInStockTaskName.移库任务, -itemMoveStock.ProductStorage, itemMoveStock, "移库任务-移出", itemMoveStock.PositionName); OutInStockTaskHandler.AddOutInStockTask22("系统", mod, OutInStockTaskName.移库任务, itemMoveStock.ProductStorage, itemMoveStock, "移库任务-移入", toPositionName); itemMoveStock.PositionName = toPositionName; } //fromPosition.IsFreeze = 0;//是否有货 fromPosition.IsFreeze = (int)IsFreezeEnum.无货;//是否有货 fromPosition.IsLocked = 0;//是否锁定 PositionType fromPosition.Remark = "移库任务确认-解锁库位!"; fromPosition.PositionType = 0;//货位类型 1是货物 6 是空托盘 //toPosition.PositionType = 1;//货位类型 1是货物 6 是空托盘 toPosition.PositionType = (int)PositionType.常规货位; //使用枚举 【EditBy shaocx,2022-03-06】 //toPosition.IsFreeze = 1; toPosition.IsFreeze = (int)IsFreezeEnum.有货; toPosition.IsLocked = 0; toPosition.Remark = "移库任务确认-解锁库位!"; toPosition.PositionLength = fromPosition.PositionLength;//托盘空间占用比 fromPosition.PositionLength = 0; fromPosition.IsLocked = 0; //获取闲时移库的明细数据,判断其转移类型 【EditBy shaocx,2022-09-26】 var freeTimeMoveLocationTaskDetail = mod.Wms_FreeTimeMoveLocationTaskDetails.Where(x => x.Task_Id == item.Task_Id).FirstOrDefault(); if (freeTimeMoveLocationTaskDetail != null) { if (freeTimeMoveLocationTaskDetail.MoveRemark == (AutoMoveLocationReasonEnum.高库位去合适库位).ToString()) { foreach (var itemMoveStock in movePosition) { itemMoveStock.IsInMoreHighPosition = 0;//配置为 适配库位 } } } int resule = mod.SaveChanges(); if (resule < 1)//保存失败再保存一次 { resule = mod.SaveChanges(); if (resule < 1) { item.TaskStatus = "确认异常"; } else { item.TaskStatus = "完成"; } } else { item.TaskStatus = "完成"; } } else { item.TaskStatus = "确认异常"; } } #endregion } else if (result == (int)taskInfo.尺寸超高) {//BillCode #region MyRegion FindEmptyLocationHandler.changPlateCode(); logtxt.txtWrite("类名:Form1/函数名:finishConfirm 确认任务尺寸超高/ 任务id" + item.Task_Id + "wcf返回值" + result, 2); mod.Task_Queue.Remove(item); int shelveId = item.Bill_Id == null ? 0 : Convert.ToInt32(item.Bill_Id);//码盘上架ID Purchase_Shelve shelve = mod.Purchase_Shelve.Find(shelveId); // List shelveList = mod.Purchase_ShelveList.Where(x => x.Shelve_Id == shelveId).ToList(); if (shelve != null) { shelve.OnShelveStatus = "尺寸异常"; } mod.SaveChanges(); #endregion } else if (result == (int)taskInfo.找不到库位) {//BillCode #region MyRegion 找库位失败已经 任务状态和上架状态已经处理完了 FindEmptyLocationHandler.changPlateCode();//上一个托盘号 logtxt.txtWrite("类名:Form1/函数名:finishConfirm 确认任务找不到库位/ 任务id" + item.Task_Id + "wcf返回值" + result, 2); // mod.Task_Queue.Remove(item); //int shelveId = Convert.ToInt32(item.Bill_Id);//码盘上架ID //Purchase_Shelve shelve = mod.Purchase_Shelve.Find(shelveId); //if (shelve != null) //{ // shelve.OnShelveStatus = "找不到库位"; //} //mod.SaveChanges(); #endregion } } catch (Exception ex) {//ModifyID logtxt.txtWrite("类名:Form1/函数名:finishConfirm 查询任务完成产生异常" + ex.Message + "出错行号" + (string)ex.StackTrace, 2); throw;//抛出异常 } mod.SaveChanges(); } #endregion #region 定时删除数据 /// /// 定时删除数据 /// public void DeleteData() { while (true) { try { int days = 180; LogTextHelper.BatchDeleteLog(@"d:\\Log4Net_siemensSapService", days);//增加 Log4Net_siemensSapService 文件夹 [EditBy shaocx,2022-10-12] LogTextHelper.BatchDeleteLog(@"d:\\Log4Net", days);//增加Log4Net文件夹 [EditBy shaocx,2022-09-22] LogTextHelper.BatchDeleteLog(@"d:\\log_MySAP", 30); LogTextHelper.BatchDeleteLog(@"d:\\log_ShuYing", 30); LogTextHelper.BatchDeleteLog(@"c:\\Siemens\\SAP_LOG", 30); //增加 WCS日志的删除 [EditBy shaocx,2022-10-22] LogTextHelper.BatchDeleteLog(@"c:\\CCSLog", 30); LogTextHelper.BatchDeleteLog(@"c:\\DevLog", 30); LogTextHelper.BatchDeleteLog(@"c:\\WCSLog", 30); this.lbl_DeleteData.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "清理成功..."; } catch (Exception ex) { //SystemWarningMsg._lbl_Alert_DeleteData = "出现异常:" + ex.Message; // Log4NetHelper.WriteErrorLog(iWareCommon.Utils.LogType.CCWCFService, "定时删除数据 出现异常", ex); this.lbl_DeleteData.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "清理异常..." + ex.Message; } finally { Thread.Sleep(8 * 60 * 60 * 1000);//每天8小时一次 } } } /// /// 定时删除 收货暂存区 无效 数据 /// public void DeleteData_Base_ProductPosition() { while (true) { try { if (DateTime.Now.Hour == 4 || DateTime.Now.Hour == 6) //if (true)//暂时 测试 { //定时删除6个月之前的 using (dbModel emd = new dbModel()) { var qureyTime = DateTime.Now.AddMonths(-6); var removeList = emd.Base_ProductPosition.Where(x => x.PositionName == SysGlole.PositionName_SHZCQ && x.InStorageDate <= qureyTime).Take(1000).ToList(); if (removeList != null && removeList.Count > 0) { emd.Base_ProductPosition.RemoveRange(removeList); emd.SaveChanges(); } } this.lbl_Msg_DeleteData_Base_ProductPosition.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "清理成功..."; } } catch (Exception ex) { //SystemWarningMsg._lbl_Alert_DeleteData = "出现异常:" + ex.Message; // Log4NetHelper.WriteErrorLog(iWareCommon.Utils.LogType.CCWCFService, "定时删除数据 出现异常", ex); this.lbl_Msg_DeleteData_Base_ProductPosition.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "清理异常..." + ex.Message; } finally { Thread.Sleep(20 * 60 * 1000);//每天20分钟一次 //Thread.Sleep(3 * 1000);//每天3分钟一次 //暂时 测试 } } } #endregion #region 闲时移库 /// /// 闲时移库-库区1 /// public void AutoMoveForArea1() { var areaCode = "1"; while (true) { try { using (dbModel mod = new dbModel()) { var task = AutoMoveLocationHandler.GetCurExcuteFreeTimeMoveLocationTask(mod); if (task != null) { bool validateResult = AutoMoveLocationHandler.IsNeedCreateNewMoveTask(mod, areaCode); if (validateResult == false) { this.lbl_Msg_AutoMoveForArea1.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前库区还有未结束的移库任务,不允许创建新的移库任务.."; continue; } var result = AutoMoveLocationHandler.DoForHighLocation(mod, areaCode, task); if (result == false) { AutoMoveLocationHandler.DoForAutoBalance(mod, areaCode, task); } this.lbl_Msg_AutoMoveForArea1.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "一次闲时移库循环结束.."; } else { this.lbl_Msg_AutoMoveForArea1.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前无要执行的闲时移库"; } } } catch (Exception ex) { this.lbl_Msg_AutoMoveForArea1.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "异常..." + ex.Message; Log4NetHelper.WriteErrorLog(LogType.FreeTimeMoveLocation, "库区1闲时移库异常:" + ex.Message, ex); } finally { Thread.Sleep(10 * 1000);//每10秒一次 } } } /// /// 闲时移库-库区2 /// public void AutoMoveForArea2() { var areaCode = "2"; while (true) { try { using (dbModel mod = new dbModel()) { var task = AutoMoveLocationHandler.GetCurExcuteFreeTimeMoveLocationTask(mod); if (task != null) { bool validateResult = AutoMoveLocationHandler.IsNeedCreateNewMoveTask(mod, areaCode); if (validateResult == false) { this.lbl_Msg_AutoMoveForArea1.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前库区还有未结束的移库任务,不允许创建新的移库任务.."; continue; } var result = AutoMoveLocationHandler.DoForHighLocation(mod, areaCode, task); if (result == false) { AutoMoveLocationHandler.DoForAutoBalance(mod, areaCode, task); } this.lbl_Msg_AutoMoveForArea2.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "一次闲时移库循环结束.."; } else { this.lbl_Msg_AutoMoveForArea2.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "当前无要执行的闲时移库"; } } } catch (Exception ex) { this.lbl_Msg_AutoMoveForArea2.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "异常..." + ex.Message; Log4NetHelper.WriteErrorLog(LogType.FreeTimeMoveLocation, "库区2闲时移库异常:" + ex.Message, ex); } finally { Thread.Sleep(10 * 1000);//每10秒一次 } } } #endregion #region 处理 新增无单入库的入库记录 private void doNoBillForAddOutInStockTask() { while (true) { Thread.Sleep(3000); try { using (dbModel mod = new dbModel()) { var queryClassName = "无单入库扫描"; List ppList = mod.Base_ProductPosition.Where(x => x.PositionName == SysGlole.PositionName_SHZCQ && x.ClassName == queryClassName && (x.isHasInRecordForNoBill == null || x.isHasInRecordForNoBill == 0) ).ToList(); if (ppList != null && ppList.Count > 0) { foreach (var item in ppList) { //增加出入库记录 【EditBy shaocx,2022-10-18】 OutInStockTaskHandler.AddOutInStockTask22(item.Creator, mod, OutInStockTaskName.收货任务, item.ProductStorage, item, "无单收货-收货,收货暂存区,增加库存", item.PoCode); item.isHasInRecordForNoBill = 1; mod.SaveChanges(); } } this.lbl_Msg_doNoBillForAddOutInStockTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + " 正常循环一次!"; } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(LogType.DoNoBillForAddOutInStockTask, "处理 新增无单入库的入库记录 异常:" + ex.Message, ex); this.lbl_Msg_doNoBillForAddOutInStockTask.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + " 异常!:" + ex.Message; } } } #endregion /// 循环给SAP发生数据确认 /// 循环给SAP发生数据确认 /// private void sendSapInfo() { while (true) { Thread.Sleep(2000); // DateTime yesterdayTime = DateTime.Now.AddDays(-1.0);//注意:这里只查1天前的数据? try { using (dbModel mod = new dbModel()) { //改为查询所有 //List sapInfoList = mod.SapSendInfo.Where(x => x.isFinish == 0 && x.creatTime > yesterdayTime).ToList(); List sapInfoList = mod.SapSendInfo.Where(x => x.isFinish == 0).ToList(); if (sapInfoList.Count > 0) { apitest wcfapi = new apitest(); foreach (var item in sapInfoList) { //判断如果重发了5次之后,就不允许再发了 【EditBy shaocx,2022-09-23】 if (item.sendCount > 5) { item.isFinish = 1; item.Remark = "重发次数超过5次,自动标记完成"; mod.SaveChanges(); continue; } //向sap发送出库任务 //if (item.moveType == 1) if (item.moveType == (int)MoveTypeForSapSend.出库) { string result = SAPHelper.StockOutConfirm(item, item.SendSapData);//发送出库确认 resultInfo resultData = JsonConvert.DeserializeObject(result); if (resultData.result)//成功标记完成 { item.voucherCode = item.RetMsg = resultData.msg; item.isFinish = 1; } else { if (resultData.msg == "失败") { item.isFinish = 1; item.voucherCode = item.RetMsg = resultData.msg; } else { item.sendCount = item.sendCount + 1;//增加次数 } } } //向sap发送移库任务 //else if (item.moveType == 2) else if (item.moveType == (int)MoveTypeForSapSend.移库) { string result = SAPHelper.moveStockConfirm(item, item.SendSapData);//发送移库确认 resultInfo resultData = JsonConvert.DeserializeObject(result); if (resultData.result)//成功标记完成 { item.voucherCode = item.RetMsg = resultData.msg; item.isFinish = 1; } else { if (resultData.msg == "失败") { item.isFinish = 1; item.voucherCode = item.RetMsg = resultData.msg; } else { item.sendCount = item.sendCount + 1;//增加次数 } } } int isSendSueeccd = mod.SaveChanges(); if (isSendSueeccd == 0) { logtxt.txtWrite("SAP发送成功保存失败 ID:" + item.id, 2); this.lbl_sendSapInfo.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "保存数据失败:" + item.id; } else { this.lbl_sendSapInfo.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "SAP发送成功:" + item.id; } } } } } catch (Exception ex) { this.lbl_sendSapInfo.Text = DateTimeHelper.ConvertToStringForOnlyShowTime(DateTime.Now) + "SAP发送异常:" + ex.Message; logtxt.txtWrite("SAP发送成功保存失败 " + ex.StackTrace.ToString(), 2); } } } #region 辅助 /// 返回设备名称和报警信息 /// 返回设备名称和报警信息 /// /// /// /// /// public string[] alarmName(int deviceType, int alarmNumber, int deviceNumber) { string[] name = { "", "" }; try { name[0] = Enum.GetName(typeof(DeviceId), deviceNumber); switch (deviceType) { case 0: name[1] = Enum.GetName(typeof(ESrmAlarm), alarmNumber); break; case 1: name[1] = Enum.GetName(typeof(EConveyorAlarm), alarmNumber); break; case 2: name[1] = Enum.GetName(typeof(ERgvAlarm), alarmNumber); break; case 3: name[1] = Enum.GetName(typeof(EChaiDeiAlerm), alarmNumber); break; default: name[0] = "设备号错误"; name[1] = "设备号错误"; break; } } catch (Exception) { name[0] = "转换失败"; name[1] = "转换失败"; } return name; } /// 把前端移动类型描述转换成sap格式 /// 把前端移动类型描述转换成sap格式 /// /// 移动类型描述 /// 返回SAP格式 public string ConvertMoveType(string stringMove) { switch (stringMove.Trim()) { case "发料到成本中心201": return "201"; case "发料到生产订单261": return "261"; case "发料到销售订单231": return "231"; case "暂存区发料到生产订单261": return "261"; case "311立库到平库": return "311"; default: return ""; } } /// 运行状态指示灯 /// 运行状态指示灯 /// public void changeColor() { bool isChange = true; while (true) { textBox7.Text = lastPlateCode; Thread.Sleep(1000); if (isChange) { label11.BackColor = Color.Yellow; } else { label11.BackColor = Color.Pink; } isChange = !isChange; } } /// 找库里的空托盘 /// 找库里的空托盘 /// /// 库区 /// 找到的库位 private string findEmptyContainer(dbModel mod, string areaNo) { string sourcePlace = ""; if (single.WaitOne())//增加线程锁防止并发 { try { //vvBase_ProductPosition 库存和库位视图表 //ExtendField01 有货是0 空托盘是1 //ExtendField02 不可用是0 可用是1 vvBase_ProductPosition emptyContainer = mod.vvBase_ProductPosition.Where(x => x.ExtendField01 == ((int)ContainerOrProduct.空托盘).ToString() && x.AreaCode == areaNo && x.IsLocked == (int)IsLockedEnum.未锁定).FirstOrDefault(); // Base_ProductPosition emptyContainer = mod.Base_ProductPosition.Where(x => x.ExtendField01 == ((int)ContainerOrProduct.空托盘) //.ToString() && x.ExtendField02 == ((int)usable.可用).ToString() && x.AreaCode == areaNo).FirstOrDefault(); if (emptyContainer != null) { //找到库位地址准备锁定 Base_Position lockPosition = mod.Base_Position.Where(x => x.AreaCode == areaNo && x.PositionName == emptyContainer.PositionName).FirstOrDefault(); sourcePlace = emptyContainer.PositionName; lockPosition.IsLocked = (int)IsLockedEnum.锁定; int i = mod.SaveChanges(); if (i == 0) { throw new Exception("找到库里的空托盘,但是锁定库位数据失败!" + lockPosition.PositionName + ",库区:" + lockPosition.AreaCode); } } } catch (Exception ex) { logtxt.txtWrite("类名:Form1/函数名:findEmptyContainer/寻找库里空托盘 产生异常 库区=" + areaNo.ToString() + "-出错信息" + ex.Message + "-出错行号" + (string)ex.StackTrace, 2); throw ex; } finally { single.ReleaseMutex(); }//一轮结束 } return sourcePlace; } /// 写入库存 /// 写入库存,保存不成功抛出异常 /// /// 上架ID /// 目的地址 /// 库区 private void writeProductPositionFor常规入库(dbModel mod, Task_Queue task, int ShelveId, string toPlace, int areaCode, string continerType) { if (single.WaitOne())//增加线程锁防止并发 { try { var _PositionName = areaCode.ToString() + "-" + toPlace; var msg = ""; var isRight = ExtendHelper.ValidateIsRightForPositionName(_PositionName, ref msg); if (!isRight) { throw new Exception("常规入库:" + msg); } Purchase_Shelve shelve = mod.Purchase_Shelve.Where(x => x.Shelve_Id == ShelveId).FirstOrDefault(); if (shelve != null) { List shelvelist = mod.Purchase_ShelveList.Where(x => x.Shelve_Id == ShelveId).ToList(); if (shelvelist.Count > 0) { if (shelve.ShelveType == ShelveTypeEnum.拼盘上架.ToString()) { ExtendHelper.RemoveProductPositionForPinPan(mod, shelve.PlateCode, shelve.Creator); } foreach (var item in shelvelist) { //OutInStockTask _outInStockTask = new OutInStockTask(); //_outInStockTask.taskName = "入库任务"; //_outInStockTask.orderCode = shelve.ShelveCode; //_outInStockTask.trackNumber = item.TrackingNumber; //_outInStockTask.materialNumber = item.ProductCode; //_outInStockTask.materialName = item.ProductName;//物料名称 //_outInStockTask.unit = item.SmallUnit;//库存单位 //_outInStockTask.quantity = (Decimal)item.Quantity; //_outInStockTask.creatDate = DateTime.Now; ////增加字段 【EditBy shaocx,2022-03-06】 //_outInStockTask.PositionName = _PositionName; //decimal cghw_ProductStorage = 0; //decimal zcq__ProductStorage = 0; //BussinessExtension.BussinessExtension.GetCurrentProductStorage(mod, _outInStockTask.materialNumber, out cghw_ProductStorage, out zcq__ProductStorage); //_outInStockTask.CGHW_ProductStorage = cghw_ProductStorage; //_outInStockTask.ZCG_ProductStorage = zcq__ProductStorage; //mod.OutInStockTask.Add(_outInStockTask);//增加入库记录 OutInStockTaskHandler.AddOutInStockTask(shelve.PlateCode, mod, OutInStockTaskName.入库任务, shelve.ShelveCode, item.TrackingNumber, item.ProductCode, item.ProductName, item.SmallUnit, (Decimal)item.Quantity, _PositionName, "入库任务完成", task.Creator); Base_ProductPosition addPP = new Base_ProductPosition(); //注意:这里处理支持二维码的方式 【Editby shaocx,2023-11-5】 var isQrCode = false; if (!string.IsNullOrEmpty(item.ExtendField06) && item.ExtendField06.Length > 15) { isQrCode = true; addPP.qrCode_guid = item.ExtendField06; } addPP.BarCode = addPP.ExtendField06 = item.ExtendField06; addPP.IsQrCode = isQrCode; addPP.BillCode = ShelveId.ToString();//码盘单号 addPP.OrignStorage = (Decimal)item.Quantity; //原始数量 addPP.ProductStorage = (Decimal)item.Quantity;//当前数量 addPP.IsBoosterArm = item.IsBoosterArm == null ? (byte)0 : (byte)item.IsBoosterArm;// 是否需要助力; addPP.PlateCode = shelve.PlateCode;//母托盘号 addPP.PlateType = continerType;//托盘类型 addPP.AreaCode = areaCode.ToString();//库区 addPP.ExtendField01 = ((int)ContainerOrProduct.货物).ToString();//标志为货物, addPP.ExtendField02 = "0";//预出库数量,给个默认值 addPP.SmallUnit = item.SmallUnit;//库存单位 ////////以下数据空不可为空 库存视图关系字段 addPP.ClassName = TaskTypeEnum.常规入库.ToString(); addPP.StorageName = "立体库"; //ProductPosition.PositionName = areaCode.ToString() + "-" + toPlace;//库位地址 addPP.PositionName = _PositionName;//库位地址 //ProductCode 字段是必需的。 //ProductName 字段是必需的。 if (string.IsNullOrEmpty(item.ProductCode)) { addPP.ProductCode = "虚拟物料编号"; } else { addPP.ProductCode = item.ProductCode;//物料编号 } if (string.IsNullOrEmpty(item.ProductName)) { addPP.ProductName = "虚拟物料名称";//物料名称 } else { addPP.ProductName = item.ProductName;//物料名称 } //productPosition.InStorageDate = DateTime.Now;//入库时间 addPP.InStorageDate = ExtendHelper.GetInStorageDate(shelve, item);//入库时间 addPP.UserProduct_Id = 1007; if (item.Product_Id != null) { addPP.Product_Id = (int)item.Product_Id;//产品ID } else { addPP.Product_Id = 0; } addPP.PoCode = item.PoCode;//采购单号 addPP.ItemNumber = item.ExtendField09;//采购项号 addPP.ExtendField04 = item.TrackingNumber;//跟踪号 addPP.SaleCode = item.SaleCode == null ? "" : item.SaleCode;// 销售单号 addPP.ExtendField08 = item.ExtendField08 == null ? "" : item.ExtendField08;// 销售项号 addPP.LimitDate = item.LimitDate;//限用日期 addPP.ContainerNo = "0";// //增加物料锁定和解锁的时间和备注记录 [EditBy shaocx,2023-07-26] addPP.DoContainerNoTime = DateTime.Now; addPP.OpRemark = "常规入库操作,初始化库存,解绑物料锁定"; ////----------以下垃圾值 addPP.MainID = 0; addPP.DetailID = 0; addPP.Storage_Id = 87; addPP.ProductModel = "0"; addPP.ConsignorCode = "GX30"; addPP.ConsignorName = "广州西门子"; addPP.Consignor_Id = 30; //记录 物料高度和逻辑高度 【EditBy shaocx,2022-08-25】 addPP.LogicHeight = task.LogicHeight; addPP.PhysicsHeight = task.PhysicsHeight; //记录 是否入的是匹配自己高度的更高库位,这些库位需要移库的 【EditBy shaocx,2022-09-19】 addPP.IsInMoreHighPosition = task.IsInMoreHighPosition; mod.Base_ProductPosition.Add(addPP); //上面已有增加入库记录的方法了 【EditBy shaocx,2022-03-07】 //有个问题:入库任务完成,收货暂存区的物料不删除吗??【EditBy shaocx,2024-09-08】 var find_PositionName = SysGlole.PositionName_SHZCQ; var shzcObj = mod.Base_ProductPosition.Where(x => x.ExtendField06 == addPP.ExtendField06 && x.PositionName == find_PositionName).FirstOrDefault(); if (shzcObj != null) { mod.Base_ProductPosition.Remove(shzcObj); } } shelve.OnShelveStatus = "上架完成"; Base_Position position = mod.Base_Position.Where(x => x.AreaCode == areaCode.ToString() && x.PositionName == areaCode + "-" + toPlace).FirstOrDefault(); //position.IsFreeze = 1;//标志有货 position.IsFreeze = (int)IsFreezeEnum.有货;//标志有货 position.IsLocked = 0;//解除货位锁定 position.Remark = "常规入库任务确认-解锁库位!"; //position.PositionType = 1;//常规货位 position.PositionType = (int)PositionType.常规货位; //使用枚举 【EditBy shaocx,2022-03-06】 position.PositionLength = Convert.ToDecimal(shelve.Provider_Id);//库位白百分比 int changeCount = mod.SaveChanges(); if (changeCount <= 0) {//保存失败 logtxt.txtWrite("类名:form1/函数名:writeProductPosition/保存数据失败 码盘上架单号=" + ShelveId.ToString(), 2); throw new Exception("写入库存,保存数据失败"); } } else { logtxt.txtWrite("类名:form1/函数名:writeProductPosition/码盘单号无效 码盘上架单号=" + ShelveId.ToString(), 2); } } else { logtxt.txtWrite("类名:form1/函数名:writeProductPosition/码盘单号无效 码盘上架单号=" + ShelveId.ToString(), 2); } } catch (Exception ex) { logtxt.txtWrite("类名:Form1/函数名:writeProductPosition/写入库存产生异常 码盘上架单号=" + ShelveId.ToString() + "-出错信息" + ex.Message + "-出错行号" + (string)ex.StackTrace + ",我记录的异常堆栈:" + JsonConvert.SerializeObject(ex) , 2); throw; } finally { single.ReleaseMutex(); }//一轮结束 } } /// 托盘高度转换 /// 托盘高度转换 /// /// 码盘主表ID /// 选择的高度 /// 托盘类型 /// 库区 /// //private int getHeight(int shelveid, string height, int ContainerType, out int areaCode) //{// getHeight(shelveId, shelveTask.ProviderShortName, containerType, out areaCode) // int result = 0; // try // { // #region 大托盘 // if (ContainerType == 2) // { // if (height == "600以下") // { // result = 1; // } // else if (height == "600-750") // { // result = 2; // } // else if (height == "750-1150") // { // result = 3; // } // else if (height == "1150-1350") // { // result = 4; // } // areaCode = 2; // return result; // } // #endregion // #region 小托盘 // else // { // if (height == "1350-1850") // { // areaCode = 1; // return 2; // } // using (dbModel mod = new dbModel()) // { // //找到物料编号 用来分别哪个哪个巷道物料多 // Purchase_ShelveList shelveList = mod.Purchase_ShelveList.Where(x => x.Shelve_Id == shelveid).FirstOrDefault(); // if (shelveList == null) // { // areaCode = 0; // return 0; // } // string productNo = shelveList.ProductCode; // //分析哪个巷道物料多 // var productOne = mod.Base_ProductPosition.Where(x => x.AreaCode == "1" && x.ProductCode == productNo).ToList();//.Sum(x => x.ProductStorage); // var productTwo = mod.Base_ProductPosition.Where(x => x.AreaCode == "2" && x.ProductCode == productNo).ToList();// Sum(x => x.ProductStorage); // #region 判断各巷道数量 // if (productOne.Count == 0) // { // areaCode = 1; // if (height == "600" || height == "600-750" || height == "750-975") // { // result = 1; // } // else // { // result = 2; // } // return result; // } // else // { // if (productTwo.Count == 0) // { // areaCode = 2; // if (height == "600") // { // result = 1; // } // else if (height == "600-750") // { // result = 2; // } // else if (height == "750-975" || height == "975-1150") // { // result = 3; // } // else // { // result = 4; // } // return result; // } // else // { // decimal oneQty = (decimal)productOne.Sum(x => x.ProductStorage); // decimal twoQty = (decimal)productTwo.Sum(x => x.ProductStorage); // #region 根据数量判断 // if (oneQty <= twoQty) // { // areaCode = 1; // if (height == "600" || height == "600-750" || height == "750-975") // { // result = 1; // } // else // { // result = 2; // } // return result; // } // else // { // areaCode = 2; // if (height == "600") // { // result = 1; // } // else if (height == "600-750") // { // result = 2; // } // else if (height == "750-975" || height == "975-1150") // { // result = 3; // } // else // { // result = 4; // } // return result; // } // #endregion // } // #endregion // } // } // } // #endregion // } // catch (Exception) // { // areaCode = 0; // return 0; // } // #region old // //if (height == "975以下" || height == "600以下") // //{ // // result = 1; // //} // //else if (height == "975-1850" || height == "600-750") // //{ // // result = 2; // //} // //else if (height == "750-1150") // //{ // // result = 3; // //} // //else if (height == "1150-1350") // //{ // // result = 4; // //} // #endregion //} #endregion #region 测试代码 #region 模拟wcf private static BackData GetCheckIsNeedOrSendContainer() { wcftest.wcfApi.BackData resultDate = new BackData(); resultDate.Type = 0; resultDate.DevId = 0; return resultDate; } #endregion /// //入库尺寸检测正常后找库位 /// 接口测试 /// /// /// private void button2_Click(object sender, EventArgs e) { apitest wcfapi = new apitest(); int taskID = Convert.ToInt32(textBox5.Text); int continerType = comboBox2.SelectedIndex + 1; int height = comboBox1.SelectedIndex + 1; //string result = wcfapi.getToPlace(taskID, continerType, height); //listInfo.Items.Add("收到的目标位置是: " + result); //listInfo.Refresh(); } int aaa = 0;//临时用 #endregion /// 撤销SAP /// 撤销 /// /// /// private void button4_Click(object sender, EventArgs e) { //apitest wcfapi = new apitest(); //string result = wcfapi.reverser(textBox2.Text.Trim()); } /// 大屏展示信息 /// 大屏展示信息 /// public void deviceInfo() { while (true) { Thread.Sleep(3000); try { string srm1Msg = ""; string rgv1Msg = ""; string srm2Msg = ""; string rgv2Msg = ""; string contMsg = ""; string[] containers = new string[19]; deviceSw.Start();// 设备运行计算器开始记时 #region 获取设备信息 if (allowGetDeviceInfo == true) { var srm1Info = device.GetStackInfo("Srm1", out srm1Msg); var srm2Info = device.GetStackInfo("Srm2", out srm2Msg); var rgv1Info = device.GetRGVInfo("Rgv1", out rgv1Msg); var rgv2Info = device.GetRGVInfo("Rgv2", out rgv2Msg); var contInfo = device.GetConveyorInfo("Line1021", out contMsg); if (srm1Info != null && srm2Info != null && rgv1Info != null && rgv2Info != null) { //RGV1赋值 deviceListInfo.rgv1.goods = rgv1Info.Loaded; //bool是否有货 deviceListInfo.rgv1.position = rgv1Info.RgvPosition;//位置 deviceListInfo.rgv1.status = rgv1Info.State;//状态 deviceListInfo.rgv1.isAlarm = rgv1Info.Alarm == "正常" ? false : true;//状态 totalInfo.list22[0] = rgv1Info.State;//状态 //RGV2赋值 deviceListInfo.rgv2.goods = rgv2Info.Loaded; //bool是否有货 deviceListInfo.rgv2.position = rgv2Info.RgvPosition;//位置 deviceListInfo.rgv2.status = rgv2Info.State;//状态 deviceListInfo.rgv2.isAlarm = rgv2Info.Alarm == "正常" ? false : true;//状态 totalInfo.list22[1] = rgv2Info.State;//状态 //堆垛机1赋值 deviceListInfo.srm1.goods = srm1Info.LiftFull; //bool是否有货 deviceListInfo.srm1.position = Convert.ToInt32(srm1Info.PosXmm);//位置 deviceListInfo.srm1.status = srm1Info.State;//状态 deviceListInfo.srm1.isAlarm = srm1Info.Alarm;//是否报警 totalInfo.list22[2] = srm1Info.State;//状态 //堆垛机2赋值 deviceListInfo.srm2.goods = srm2Info.LiftFull; //bool是否有货 deviceListInfo.srm2.position = Convert.ToInt32(srm2Info.PosXmm);//位置 deviceListInfo.srm2.status = srm2Info.State;//状态 deviceListInfo.srm2.isAlarm = srm2Info.Alarm;//是否报警 totalInfo.list22[3] = srm2Info.State;//状态 } } //*/ #endregion DateTime today = DateTime.Now; int year = today.Year; int month = today.Month + 1; if (month > 12) { month = 1; year++; } DateTime outtime = new DateTime(year, month, today.Day);//提前一月的时间 DateTime todayTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));//今天凌晨时间 using (dbModel mod = new dbModel()) { #region 获取入库任务数量,出库任务数量,已使用的库存数两,过期数量小于一个月的数量 //获取今天入库任务数量 List enterTaskCount = mod.Task_Queue.Where(x => x.CreateDate > todayTime && x.TaskType == "1").ToList(); //获取出库任务数量 List outTaskCount = mod.Task_Queue.Where(x => x.CreateDate > todayTime && x.TaskType == "4").ToList(); //获取当前已使用的库位数量 List stockUsingCount = mod.Base_Position.Where(x => x.IsFreeze == 1 || x.IsLocked == 1).ToList(); //获取过期时间小于一个月的库存数据 List outTimeStockCount = mod.Base_ProductPosition.Where(x => x.ClassName == "常规入库" && x.LimitDate < outtime).ToList(); if (enterTaskCount != null) { totalInfo.list11[0] = enterTaskCount.Count; } if (outTaskCount != null) { totalInfo.list11[1] = outTaskCount.Count; } totalInfo.list11[2] = 1152; totalInfo.list11[3] = 1152 - stockUsingCount.Count(); if (lastHour != today.Hour) { //每隔一小时保存一次设备状态时间 lastHour = today.Hour; deviceGeneralInfo todayDeviceInfo = new deviceGeneralInfo(); todayDeviceInfo = mod.deviceGeneralInfo.FirstOrDefault(x => x.createTime > todayTime); if (todayDeviceInfo == null) { todayDeviceInfo = new deviceGeneralInfo(); todayDeviceInfo.createTime = DateTime.Now; mod.deviceGeneralInfo.Add(todayDeviceInfo); //计时复位 deviceSw.Reset(); deviceAlarmTime = deviceSw.Elapsed; deviceRunTime = deviceSw.Elapsed; deviceWaitTime = deviceSw.Elapsed; } else { todayDeviceInfo.deviceRunTime = deviceRunTime.TotalMinutes > 0 ? Convert.ToDecimal(deviceRunTime.TotalMinutes) : 0M; todayDeviceInfo.deviceAlarmTime = deviceAlarmTime.TotalMinutes > 0 ? Convert.ToDecimal(deviceAlarmTime.TotalMinutes) : 0M; //重新计算设备等待时间 【Editby shaocx,2024-12-30】 CommonCalcWaitTime(ref todayDeviceInfo); todayDeviceInfo.taskEnterCount = enterTaskCount.Count;//入库任务数 todayDeviceInfo.taskOutCount = outTaskCount.Count;//出库任务数 //更改数量 【Editby shaocx,2024-11-22】 decimal cout = stockUsingCount.Count / 1152M * 100; todayDeviceInfo.stockProportion = Convert.ToInt32(cout);//已使用的库位 todayDeviceInfo.outDate = outTimeStockCount.Count;//过期时间小于一个月的库存数据 } int chang = mod.SaveChanges(); } #endregion } #region 统计设备运行效率 if (deviceListInfo.srm1.isAlarm == true || deviceListInfo.srm2.isAlarm == true || deviceListInfo.rgv1.isAlarm == true || deviceListInfo.rgv2.isAlarm == true) { if (lastStatus != "报警") { setDeviceStatusTime(lastStatus, "报警"); } } else { if (deviceListInfo.srm1.status == "空闲" && deviceListInfo.srm2.status == "空闲" && deviceListInfo.rgv1.status == "空闲" && deviceListInfo.rgv2.status == "空闲") { if (lastStatus != "等待") { setDeviceStatusTime(lastStatus, "等待"); } } else { if (lastStatus != "运行") { setDeviceStatusTime(lastStatus, "运行"); } } } #endregion } catch (Exception ex) { textBox6.Text = "获取设备信息请检查第 " + ex.StackTrace + "行\r\n" + textBox6.Text; } } } /// 设备状态变化的时候 保存状态时间 /// 设备状态变化的时候 保存状态时间 /// /// private void setDeviceStatusTime(string lastStatuss, string nowStatus) { try { switch (lastStatuss) { case "等待": deviceWaitTime += deviceSw.Elapsed; deviceSw.Restart(); lastStatus = nowStatus; break; case "运行": deviceRunTime += deviceSw.Elapsed; deviceSw.Restart(); lastStatus = nowStatus; break; case "报警": deviceAlarmTime += deviceSw.Elapsed; deviceSw.Restart(); lastStatus = nowStatus; break; } } catch (Exception) { } } /// 大屏信息初始化 /// 大屏信息初始化 /// public void deviceInfoInit() { try { DateTime todayTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));//今天凌晨时间 DateTime today = DateTime.Now; lastHour = today.Hour; using (dbModel mod = new dbModel()) { deviceGeneralInfo todayDeviceInfo = mod.deviceGeneralInfo.FirstOrDefault(x => x.createTime > todayTime); if (todayDeviceInfo != null) { TimeSpan alarmTime = new TimeSpan(Convert.ToInt32(Math.Floor((decimal)todayDeviceInfo.deviceAlarmTime / 60M)), Convert.ToInt32((decimal)todayDeviceInfo.deviceAlarmTime % 60), 0); deviceAlarmTime = alarmTime; TimeSpan runTime = new TimeSpan(Convert.ToInt32(Math.Floor((decimal)todayDeviceInfo.deviceRunTime / 60M)), Convert.ToInt32((decimal)todayDeviceInfo.deviceRunTime % 60), 0); deviceRunTime = runTime; TimeSpan waitTime = new TimeSpan(Convert.ToInt32(Math.Floor((decimal)todayDeviceInfo.deviceWaitTime / 60M)), Convert.ToInt32((decimal)todayDeviceInfo.deviceWaitTime % 60), 0); deviceWaitTime = waitTime; } else { deviceGeneralInfo creatTodayDeviceInfo = new deviceGeneralInfo(); //设备报警时间 creatTodayDeviceInfo.deviceAlarmTime = Convert.ToDecimal(deviceAlarmTime.Hours * 60M) + deviceAlarmTime.Minutes;//单位分钟 //设备运行时间 creatTodayDeviceInfo.deviceRunTime = Convert.ToDecimal(deviceRunTime.Hours * 60M) + deviceRunTime.Minutes;//单位分钟 //设备等待时间 //creatTodayDeviceInfo.deviceWaitTime = Convert.ToDecimal(deviceWaitTime.Hours * 60M) + deviceWaitTime.Minutes;//单位分钟 //重新计算设备等待时间 【Editby shaocx,2024-12-30】 CommonCalcWaitTime(ref todayDeviceInfo); creatTodayDeviceInfo.createTime = DateTime.Now; mod.deviceGeneralInfo.Add(creatTodayDeviceInfo); mod.SaveChanges(); //计时复位 } } deviceInfos = new Thread(deviceInfo); deviceInfos.Start(); } catch (Exception ex) { } } #region 无用 /// /// /// /// /// private void button1_Click(object sender, EventArgs e) { try { int orderid = 0; bool io = Int32.TryParse(textBox1.Text.Trim(), out orderid); if (io) { using (dbModel mod = new dbModel()) { Sale_Order order = mod.Sale_Order.FirstOrDefault(x => x.Order_Id == orderid); List orderList = mod.Sale_OrderList.Where(x => x.Order_Id == orderid).ToList(); } } } catch (Exception) { } } /// 获取PO 反推跟踪号 /// 获取PO /// /// /// private void button6_Click_2(object sender, EventArgs e) {//getPoList try { using (dbModel mod = new dbModel()) { string[] aax = { "8660-3005972284-002000", "11222-3005972207-001000", "11223-4507863055-00030", "11217-4507863055-00040", "11216-4507863055-00050" }; string lastTracknum = ""; for (int i = 0; i < aax.Length; i++) { string[] stringinfo = aax[i].Split('-'); string trackingNum = stringinfo[0]; string saleOrder = stringinfo[1]; string saleItemNumber = stringinfo[2]; #region 反推picklist 里的跟踪号 if (saleOrder != "" && lastTracknum != trackingNum) { if (trackingNum != "") { //明细加跟踪号 List sendPicklistTrackNumber = mod.Sale_OrderList.Where(x => x.SaleCode == saleOrder && x.ExtendField06 == saleItemNumber && x.TrackingNumber == "").ToList(); lastTracknum = trackingNum; if (sendPicklistTrackNumber.Count > 0) { var orderTrack = sendPicklistTrackNumber.GroupBy(x => x.Order_Id); var orders = mod.Sale_Order.ToList();//一次读取不然出库单多的时候会卡死 2021-8-16 修改 if (orderTrack != null) { foreach (var itemOrder in orderTrack) { long orderId = itemOrder.ToList()[0].Order_Id; Sale_Order addTrack = orders.FirstOrDefault(x => x.Order_Id == orderId); //if (addTrack != null && addTrack.OrderType == "SAP生产订单" && addTrack.StatusText == "新建") //if (addTrack != null && addTrack.OrderType == SysGlole.SAP_ORDER_TEXT && addTrack.StatusText == "新建") if (addTrack != null && addTrack.OrderType == SysGlole.SAP_ORDER_TEXT && addTrack.StatusText == Sale_Order_StatusEnum.新建.ToString()) { addTrack.TrackingNumber = trackingNum; foreach (var itemList in itemOrder) { itemList.TrackingNumber = trackingNum; } } } } } int results = mod.SaveChanges(); for (int h = 0; h < 10; h++) { if (results < 1) { results = mod.SaveChanges(); } else { break; } } } } #endregion } } } catch (Exception) { } } private void button1_Click_2(object sender, EventArgs e) { try { using (dbModel mod = new dbModel()) { List sunStock = mod.vvBase_ProductPosition.Where(x => x.ClassName == "常规入库" && x.ProductStorage > 0).ToList(); List yanzheng = sunStock.Where(x => x.ProductCode == "A7EQD-5141153925").ToList(); foreach (var item in yanzheng) { item.ExtendField04 = ""; List yanzheng1 = sunStock.Where(x => x.ProductCode == "A7EQD-5141153925" && x.ContainerNo != "1").ToList(); } int isod = mod.SaveChanges(); List yanzheng2 = sunStock.Where(x => x.ProductCode == "A7EQD-5141153925" && x.ContainerNo != "1").ToList(); } } catch (Exception ex) { } } /// 无用 /// 无用 /// /// public void trackNum(string info) { string[] infos = info.Split('-'); string saleOrder = infos[0]; string saleItemNumber = infos[1]; string trackingNum = infos[2]; using (dbModel mod = new dbModel()) { if (saleOrder != "") { if (trackingNum != "") { List sendPicklistTrackNumber = mod.Sale_OrderList.Where(x => x.SaleCode == saleOrder && x.ExtendField06 == saleItemNumber).ToList(); if (sendPicklistTrackNumber.Count > 0) { foreach (var itemSendTrackNumber in sendPicklistTrackNumber) { itemSendTrackNumber.TrackingNumber = trackingNum; } } var orderTrack = sendPicklistTrackNumber.GroupBy(x => x.Order_Id); if (orderTrack != null) { foreach (var item in orderTrack) { long orderId = item.ToList()[0].Order_Id; Sale_Order addTrack = mod.Sale_Order.Find(orderId); if (addTrack != null) { addTrack.TrackingNumber = trackingNum; } } } int result = mod.SaveChanges(); MessageBox.Show("保存成功: " + result); } } } } #endregion private void button3_Click(object sender, EventArgs e) { lastPlateCode = "0"; } private void button5_Click(object sender, EventArgs e) { TestForm frm = new TestForm(); frm.ShowDialog(); } #region 公共方法 /// /// 通过WCS获取当前的设备数据 /// /// private static BackData GetBackDataFromWCS() { wcftest.wcfApi.BackData resultDate = new BackData(); try { if (IsVirtualMode) { resultDate = GetCheckIsNeedOrSendContainer(); VirtualModeHelper.ThrowExceptionWhenVirtualMode(IsVirtualMode); } else { try { //检测是否需要空托盘 resultDate = wcsApi.GetCheckIsNeedOrSendContainer(); } catch (Exception ex) { logtxt.txtWrite("类名:Form1/函数名:检测是否需要空托盘" + ex.Message + "出错行号" + (string)ex.StackTrace, 2); } } } catch (Exception) { throw; } return resultDate; } private void CommonCalcWaitTime(ref deviceGeneralInfo todayDeviceInfo) { //重新计算设备等待时间 【Editby shaocx,2024-12-30】 todayDeviceInfo.deviceWaitTime = 1440 - (todayDeviceInfo.deviceRunTime + todayDeviceInfo.deviceAlarmTime); } private void CommonCalcWaitTime(ref deviceGeneralInfoForDetail todayDeviceInfo) { //重新计算设备等待时间 【Editby shaocx,2024-12-30】 todayDeviceInfo.deviceWaitTime = 1440 - (todayDeviceInfo.deviceRunTime + todayDeviceInfo.deviceAlarmTime); } #endregion private void lbl_Msg_containerIsFull_Click(object sender, EventArgs e) { } } public class resultInfo { public bool result { get; set; } public string msg { get; set; } } }