using iWare_SCADA_BusinessLogical.Utils;
using iWare_SCADA_Model;
using System;
using System.Collections.Generic;
using System.Data.Entity.Validation;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace iWare_SCADA_BusinessLogical.BLL.Important
{
public class ReadQRcodeManager
{
///
/// 读取二维码时逻辑
/// 校验工件是否跳序,质量是否合格
///
public static void ReadQRcode(WorkPieceLog loginfo, LogType type, PLCService plcService, int? IsFeedback)
{//此处同时插入了WorkPieceLog,WorkPieceInfoLog表,并新增或修改WorkPieceInfo表
using (DbModel db = new DbModel())
{
try
{
bool isAddWorkPieceInfo = false;
if (loginfo.WorkPieceID.Length == 22)
{
WorkPieceInfo info = new WorkPieceInfo();
info = db.WorkPieceInfo.Where(o => o.WorkPieceID == loginfo.WorkPieceID).FirstOrDefault();
if (info == null || info.WorkPieceID.Length < 1)
{//插入WorkPieceInfo表
loginfo = CommonManager.Instance.GetWorkPieceID(loginfo, type);
info = EntityPropHelper.Mapper(loginfo);
//EntityPropHelper.CopyProp(loginfo, info, loginfo.GetWorkPieceInfoDict());
if (!loginfo.WorkingProcedure.Equals("OP05"))
{//当工件二维码第一次出现的工序不是OP05,则设置为可疑状态
info.QualityState = (int)QualityStateEnum.Suspected;
info.QualityErrorInfo = $"工件二维码第一次出现的工序{loginfo.MonitoringPoint}不是OP05,数据缺失,请确认情况并做相应处理!";
info.Remarks = $"工件二维码第一次出现的工序{loginfo.WorkingProcedure}不是OP05,数据缺失,请确认情况并做相应处理!";
}
else
{//OP05工序
info.QualityState = (int)QualityStateEnum.OK;//此处需要注意,判断所有工序质量,然后再赋值 //默认合格,OP05默认是合格
info.Remarks = "OP05新增工件信息";
}
info.WorkPieceinitOnlineTime = DateTimeHelper.GetDateTime();
info.WorkingProcedurePlan = ConfigHelper.GetConfigString("WorkingProcedureAllStr") ?? "OP05OP10OP20OP30OP35OP40OP50OP60OP70OP80";
info.CreatedUserName = loginfo.MonitoringPoint;
info.WorkingProcedureCurrent = loginfo.WorkingProcedure;//工序赋值
SystemBussinessHelper.SetWorkPieceInfoMiddleForCreatedUserName(ref info, loginfo.DataCapturePointCname);
info.CreatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
info = WorkPieceInfoManager.ParseQRCode(info);
isAddWorkPieceInfo = true;
}
else
{
//存在 表 WorkPieceInfo有,但是 WorkPieceProcess这个工序不存在的情况 【Editby shaocx,2024-09-06】
//if (info.WorkingProcedureCurrent.Equals("OP05"))
//{
// loginfo.Remarks = $"读取二维码{loginfo.WorkPieceID ?? "空"} OP05工序重复读取了";
// return;
//}
}
if ((loginfo.WorkingProcedure.Equals("OP05") && isAddWorkPieceInfo == false))
{//存在 表 WorkPieceInfo有,但是 WorkPieceProcess这个工序不存在的情况
//如果是OP05的,并且是 不需要新增 表WorkPieceInfo,那么就不需要更新表 WorkPieceInfo
}
else
{
info.WorkingProcedureStartTime = DateTimeHelper.GetDateTime();//
info.WorkingProcedureEndTime = null;
info.WorkPieceState = (int)WorkPieceState.WIP;
info.EquipmentID = loginfo.EquipmentID;
info.QualityStateUpdateUser = loginfo.UpdatedUserName;
info.QualityStateUpdateTime = loginfo.UpdatedTime.Value.LocalDateTime;
info.QualityStateUpdateMode = QualityStateUpdateMode.Auto.ToString();
info.UpdatedUserName = loginfo.MonitoringPoint;
SystemBussinessHelper.SetWorkPieceInfoMiddleForUpdateDataCapturePointCname(ref info, loginfo.DataCapturePointCname);
info.UpdatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
info.WorkPieceCurrentPosition = loginfo.WorkingProcedure;
info.WorkPieceCurrentPositionOrder = info.WorkingProcedurePlan.IndexOf(loginfo.WorkingProcedure) / 2;
info.WorkingProcedureCurrent = loginfo.WorkingProcedure;//工序赋值
info.Remarks = $"{info.WorkingProcedureCurrent}工件上线";
}
//修复下 op35 同一个件 下线时间跟下一个上线时间一模一样的问题 【Editby shaocx,2024-08-27】
var isNeedAddNewProcess = true;
//特殊处理OP05上线,因为他是根据文本列表内容上线的 【Editby shaocx,2024-09-03】
if (loginfo.WorkingProcedure.Equals("OP05"))
{
var op05Proccss = db.WorkPieceProcess.Where(o => o.WorkPieceID == loginfo.WorkPieceID && o.WorkingProcedureCurrent == loginfo.WorkingProcedure).FirstOrDefault();
if (op05Proccss != null)
{
isNeedAddNewProcess = false;//不需要新增了
}
}
else
{
var pro = db.WorkPieceProcess.Where(o => o.WorkPieceID == loginfo.WorkPieceID && !o.OperationType.Equals("SPC") && (o.EndTime == null || o.EndTime <= DateTime.MinValue)).OrderByDescending(o => o.StartTime).FirstOrDefault();
if (pro != null && pro.WorkPieceID.Length > 1)
{
if (pro.WorkingProcedureCurrent == loginfo.WorkingProcedure)
{//表示工序相同
isNeedAddNewProcess = false;
pro.Remarks = "又一次上线,更新结束时间";
}
else
{
pro.EndTime = DateTimeHelper.GetDateTime();
pro.UpdatedUserName = loginfo.MonitoringPoint;
pro.UpdateDataCapturePointCname = loginfo.DataCapturePointCname;
pro.UpdatedTime = DateTimeHelper.GetDateTime();
pro.Remarks = "又一次上线,更新结束时间";
}
}
}
if (isNeedAddNewProcess)
{
WorkPieceProcess process_70 = WorkPieceProcessHelper.CreateWorkPieceProcessForOP70(loginfo, db, info);
if (process_70 != null)
{//创建OP70工序,当没有70工序时,才创建 【Editby shaocx,2024-08-29】
db.WorkPieceProcess.Add(process_70);
}
//每次扫描上线都插入追溯表
WorkPieceProcess new_process = new WorkPieceProcess();
new_process = EntityPropHelper.Mapper(info);
QualityStateHelper.ResetQualityNoOkForNewProcess(ref new_process);
new_process.StartTime = DateTimeHelper.GetDateTime();
//不再默认赋值为合格 【Editby shaocx,2024-08-16】
//process.QualityState = info.QualityState.HasValue ? info.QualityState.Value : (int)QualityState.OK;//默认合格,已处理
new_process.QualityState = WorkPieceInfoManager.GetQualityStateValue(info.QualityState);
if (new_process.WorkingProcedureCurrent == WorkingProcedureForHMI.OP70.ToString())
{ //特殊处理OP70,因为OP70没有测量,默认合格 [Editby shaocx,2024-07-03]
new_process.QualityState = (int)QualityStateEnum.OK;//默认合格,OP70默认是合格
}
new_process.Id = Yitter.IdGenerator.YitIdHelper.NextId();
new_process.CreatedUserName = loginfo.MonitoringPoint;
new_process.DataCapturePointCname = loginfo.DataCapturePointCname;
new_process.CreatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
new_process.UpdatedUserName = loginfo.MonitoringPoint;
new_process.UpdateDataCapturePointCname = loginfo.DataCapturePointCname;
new_process.UpdatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
new_process.OperationType = OperationType.生产.ToString();
new_process.Remarks = "";
new_process.MyRemarks = "读码上线时,每次扫描上线都插入追溯表";
if (loginfo.WorkingProcedure.Equals("OP05"))
{//特殊处理OP05工序
new_process.EndTime = new_process.StartTime;
//如果已经存在其他工序,那么就必须要按照其他工序的时间往前推数据 【Editby shaocx,2024-09-05】
var op05OtherProccss = db.WorkPieceProcess.Where(o => o.WorkPieceID == loginfo.WorkPieceID).OrderBy(x => x.StartTime).FirstOrDefault();
if (op05OtherProccss != null)
{//说明有,那么时间就按照这个时间往前推
var _time = op05OtherProccss.StartTime.AddHours(-1);
new_process.StartTime = _time;
new_process.EndTime = _time;
new_process.CreatedTime = _time;
new_process.UpdatedTime = _time;
}
}
db.WorkPieceProcess.Add(new_process);
}
//db.Database.AutoTransactionsEnabled = false;// 同一个SaveChanges默认事务, 关闭默认事务:... 好像不能用啊,后面再研究吧
if (isAddWorkPieceInfo)
{
db.WorkPieceInfo.Add(info);
}
else
{//不确定info是直接会修改还是需要再次查询,待测试
//info.Remarks = "修改,具体修改逻辑待定";
}
#region 判断是否跳序,或质量不符合 然后反馈PLC
/*
if (IsFeedback.HasValue && IsFeedback.Value == (int)FeedbackMode.FeedbackPLC)
{
bool checkQualityInfoCompleteFlag = false;
bool plcFlag = true;//反馈给PLC的标记
string message = "";
checkQualityInfoCompleteFlag = WorkPieceInfoManager.CheckQualityInfoComplete(info, loginfo, type);
if (!checkQualityInfoCompleteFlag || info.QualityState != (int)QualityStateEnum.OK)
{
plcFlag = false;
message = !checkQualityInfoCompleteFlag ? "跳序," : "";
message += info.QualityState != (int)QualityStateEnum.OK ? "质量不符合" : "";
}
}
else
{//读码完成若工件质量不符合或发生跳序,不用管设备是否把工件放过去,数采系统都不变更当前工序,反馈设备PLC工件不符合,
//若工序后续收集点收到相关工件信息再变更当前工序, 但质量信息不变
info.WorkingProcedureCurrent = loginfo.WorkingProcedure;
}
//*/
#endregion
#region 更新设备实时表
bool isAddEquipmentCurrentMonitor = false;
EquipmentCurrentMonitor equinfo = new EquipmentCurrentMonitor();
equinfo = db.EquipmentCurrentMonitor.Where(o => o.EquipmentID == loginfo.EquipmentID).FirstOrDefault();
if (equinfo == null || equinfo.Id < 1)
{//没有工件信息,不做更新
Log4NetHelper.WriteErrorLog(type, $"设备{loginfo.EquipmentID} 告警监控{loginfo.WorkingProcedure} 没有获取到设备监控信息,现新增");
equinfo = EntityPropHelper.Mapper(loginfo);
equinfo.OnlineTime = DateTime.Now;
isAddEquipmentCurrentMonitor = true;
}
else
{//更新工件
equinfo.WorkPieceID = loginfo.WorkPieceID;
equinfo.UpdatedUserName = loginfo.MonitoringPoint;
equinfo.UpdatedTime = DateTime.Now;
equinfo.OnlineTime = DateTime.Now;
}
if (isAddEquipmentCurrentMonitor)
{
equinfo.Id = Yitter.IdGenerator.YitIdHelper.NextId();
db.EquipmentCurrentMonitor.Add(equinfo);
}
#endregion
//db.WorkPieceLog.Add(GetAddWorkPieceLog(loginfo));
db.WorkPieceInfoLog.Add(WorkPieceInfoManager.GetAddWorkPieceInfoLog(info));
//UpdateKnifeToolLift(db, loginfo);//更新刀具寿命信息
}
else
{
loginfo.Remarks = $"上线完成读取二维码{loginfo.WorkPieceID ?? "空"}异常";
Log4NetHelper.WriteErrorLog(type, $" {loginfo.WorkingProcedure}上线监控读码标记 读取工件码数据[{loginfo.WorkPieceID ?? "空"}]时异常:");
}
}
catch (Exception e)
{
loginfo.Remarks = $"读取二维码{loginfo.WorkPieceID ?? "空"}更新数据异常{e.Message}";
Log4NetHelper.WriteErrorLog(type, $" {loginfo.WorkingProcedure}上线监控读码标记 读取工件码数据[{loginfo.WorkPieceID ?? "空"}]时异常:", e);
}
finally
{
loginfo.Id = Yitter.IdGenerator.YitIdHelper.NextId();
db.WorkPieceLog.Add(loginfo);
//保存数据库的异常捕捉 [Editby shaocx,2024-08-29]
try
{
db.SaveChanges();
}
catch (DbEntityValidationException exception)
{
var errorMessages =
exception.EntityValidationErrors
.SelectMany(validationResult => validationResult.ValidationErrors)
.Select(m => m.ErrorMessage);
var fullErrorMessage = string.Join(", ", errorMessages);
var exceptionMessage = string.Concat(exception.Message, " 验证异常消息是:", fullErrorMessage);
Log4NetHelper.WriteErrorLog(type, $" {loginfo.WorkingProcedure}上线监控读码标记 读取工件码数据[{loginfo.WorkPieceID ?? "空"}],保存数据库时异常:" + exceptionMessage, exception);
throw new DbEntityValidationException(exceptionMessage, exception.EntityValidationErrors);
}
catch (Exception)
{
throw;
}
}
}
}
}
}