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 deviceRunTime_Srm1;
public static TimeSpan deviceRunTime_Srm2;
/// 设备等待时间
/// 设备等待时间
///
public static TimeSpan deviceWaitTime;
public static TimeSpan deviceWaitTime_Srm1;
public static TimeSpan deviceWaitTime_Srm2;
/// 设备报警时间
/// 设备报警时间
///
public static TimeSpan deviceAlarmTime;
public static TimeSpan deviceAlarmTime_Srm1;
public static TimeSpan deviceAlarmTime_Srm2;
/// 设备使用率
/// 设备使用率
///
public static TimeSpan deviceUsageRate;
/// 设备运行计时器
/// 设备运行计时器
///
Stopwatch deviceSw = new Stopwatch();
Stopwatch deviceSw_Srm1 = new Stopwatch();
Stopwatch deviceSw_Srm2 = new Stopwatch();
/// 上一次设备运行状态
/// 上一次设备运行状态
///
public string lastStatus = "等待";
public string lastStatus_Srm1 = "等待";
public string lastStatus_Srm2 = "等待";
/// 上一次小时数--每隔一小时保存一次设备状态时间
/// 上一次小时数--每隔一小时保存一次设备状态时间
///
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();// 设备运行计算器开始记时
deviceSw_Srm1.Start();// 设备运行计算器开始记时
deviceSw_Srm2.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】
DeviceGeneralInfoHelper.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;//过期时间小于一个月的库存数据
}
DeviceGeneralInfoHelper.HandlerDeviceGeneralInfoForDetail(1, enterTaskCount, outTaskCount, stockUsingCount, outTimeStockCount,
mod, lastHour, todayTime,
deviceSw_Srm1, deviceRunTime_Srm1, deviceAlarmTime_Srm1, deviceWaitTime_Srm1
);
DeviceGeneralInfoHelper.HandlerDeviceGeneralInfoForDetail(2, enterTaskCount, outTaskCount, stockUsingCount, outTimeStockCount,
mod, lastHour, todayTime,
deviceSw_Srm2, deviceRunTime_Srm2, deviceAlarmTime_Srm2, deviceWaitTime_Srm2
);
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
#region 统计设备运行效率(详细) 【Editby shaocx,2025-09-19】
//1号堆垛机
if (deviceListInfo.srm1.isAlarm == true)
{
if (lastStatus_Srm1 != "报警")
{
setDeviceStatusTimeForDetail(1, lastStatus_Srm1, "报警");
}
}
else
{
if (deviceListInfo.srm1.status == "空闲")
{
if (lastStatus_Srm1 != "等待")
{
setDeviceStatusTimeForDetail(1, lastStatus_Srm1, "等待");
}
}
else
{
if (lastStatus_Srm1 != "运行")
{
setDeviceStatusTimeForDetail(1, lastStatus_Srm1, "运行");
}
}
}
//2号堆垛机
if (deviceListInfo.srm2.isAlarm == true)
{
if (lastStatus_Srm2 != "报警")
{
setDeviceStatusTimeForDetail(2, lastStatus_Srm2, "报警");
}
}
else
{
if (deviceListInfo.srm2.status == "空闲")
{
if (lastStatus_Srm2 != "等待")
{
setDeviceStatusTimeForDetail(2, lastStatus_Srm2, "等待");
}
}
else
{
if (lastStatus_Srm2 != "运行")
{
setDeviceStatusTimeForDetail(2, lastStatus_Srm2, "运行");
}
}
}
#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)
{
}
}
/// 设备状态变化的时候 保存状态时间(明细)
/// 设备状态变化的时候 保存状态时间
///
///
private void setDeviceStatusTimeForDetail(int srmNo, string lastStatuss, string nowStatus)
{
try
{
switch (lastStatuss)
{
case "等待":
if (srmNo == 1)
{
deviceWaitTime_Srm1 += deviceSw_Srm1.Elapsed;
}
else
{
deviceWaitTime_Srm2 += deviceSw_Srm2.Elapsed;
}
break;
case "运行":
if (srmNo == 1)
{
deviceRunTime_Srm1 += deviceSw_Srm1.Elapsed;
}
else
{
deviceRunTime_Srm2 += deviceSw_Srm2.Elapsed;
}
break;
case "报警":
if (srmNo == 1)
{
deviceAlarmTime_Srm1 += deviceSw_Srm1.Elapsed;
}
else
{
deviceAlarmTime_Srm2 += deviceSw_Srm2.Elapsed;
}
break;
}
if (srmNo == 1)
{
deviceSw_Srm1.Restart();
lastStatus_Srm1 = nowStatus;
}
else
{
deviceSw_Srm2.Restart();
lastStatus_Srm2 = nowStatus;
}
}
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】
DeviceGeneralInfoHelper.CommonCalcWaitTime(ref creatTodayDeviceInfo);
creatTodayDeviceInfo.createTime = DateTime.Now;
mod.deviceGeneralInfo.Add(creatTodayDeviceInfo);
mod.SaveChanges();
//计时复位
}
}
DeviceGeneralInfoHelper.deviceInfoInitForDetails(1, todayTime, lastHour, deviceAlarmTime_Srm1, deviceRunTime_Srm1, deviceWaitTime_Srm1);
DeviceGeneralInfoHelper.deviceInfoInitForDetails(2, todayTime, lastHour, deviceAlarmTime_Srm2, deviceRunTime_Srm2, deviceWaitTime_Srm2);
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;
}
#endregion
private void lbl_Msg_containerIsFull_Click(object sender, EventArgs e)
{
}
}
public class resultInfo
{
public bool result { get; set; }
public string msg { get; set; }
}
}