using Newtonsoft.Json.Serialization; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.APIEnum; using WIDESEA_Common.CommonEnum; using WIDESEA_Common.LocationEnum; using WIDESEA_Common.OtherEnum; using WIDESEA_Common.StockEnum; using WIDESEA_Common.TaskEnum; using WIDESEA_Common.WareHouseEnum; using WIDESEA_Core; using WIDESEA_Core.BaseServices; using WIDESEA_Core.Enums; using WIDESEA_Core.Helper; using WIDESEA_DTO; using WIDESEA_DTO.ERP; using WIDESEA_ITaskInfoRepository; using WIDESEA_ITaskInfoService; using WIDESEA_Model.Models; using WIDESEA_Common.OrderEnum; using System.Diagnostics.Metrics; using System.Reflection.Metadata; using WIDESEA_DTO.Task; using WIDESEA_DTO.Stock; using SqlSugar; using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; using WIDESEA_DTO.MES; using WIDESEA_External.Model; using System.Text.Json; using System.Text.RegularExpressions; using WIDESEA_Common.MaterielEnum; using MailKit.Search; namespace WIDESEA_TaskInfoService { public partial class TaskService { static object lock_autoIssue = new object(); static object lock_manualIssue = new object(); static object lock_returnIssue = new object(); /// /// MES自动叫料接口 /// /// public WebResponseContent ReceiveAutoIssue(MESAutoIssueDTO autoIssueDTO) { WebResponseContent content = new WebResponseContent(); try { lock (lock_autoIssue) { if (autoIssueDTO == null) { return content.Error("传入信息不能为空"); } //获取对应单据 Dt_OutMESOrder? outMESOrder = _outboundRepository.OutMESOrderRepository.QueryFirst(x => x.OutDetailId == autoIssueDTO.OutDetailId); if (outMESOrder == null) { return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{autoIssueDTO.OutDetailId}不存在"); } if (outMESOrder.OutMESOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt()) { return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{outMESOrder.ProductOrderNo}工单已出库完成"); } //获取周转位置编号 Dt_AGVStationInfo? stationInfo = _basicRepository.AGVStationInfoRepository.QueryFirst(x => x.MESPointCode == autoIssueDTO.PointCode); if (stationInfo == null) { return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{autoIssueDTO.PointCode}不存在"); } if (autoIssueDTO.IsEmptyPallet > 0) { return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{autoIssueDTO.PointCode}存在空托"); } Dt_Task? task = BaseDal.QueryData(x => x.OrderNo == outMESOrder.OutMESOrderNo && x.TaskStatus == TaskStatusEnum.CallPending.ObjToInt()).OrderByDescending(x => x.Grade).ThenBy(x => x.TaskNum).FirstOrDefault(); //获取任务 if (task == null) { return content.Error($"未找到领料计划编号{outMESOrder.ProductOrderNo}可配送任务"); } //获取任务出库详情 Dt_OutStockLockInfo outStockLockInfo = _outboundRepository.OutStockLockInfoRepository.QueryFirst(x => x.TaskNum == task.TaskNum); //调用MES配送出发指令 PlanDistributionInfo planDistribution = new PlanDistributionInfo() { DispatchPlanMaterialId = autoIssueDTO.OutDetailId, InvItemCode = task.MaterielCode, Quantity = outStockLockInfo.AssignQuantity, SendOutTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), ArrivalTime = DateTime.Now.AddMinutes(15).ToString("yyyy-MM-dd HH:mm:ss") }; MESDispatchModel dispatchModel = new MESDispatchModel() { PRO_DispachPlanDistributionInfos = new List() { planDistribution } }; _unitOfWorkManage.BeginTran(); task.TaskStatus = TaskStatusEnum.New.ObjToInt(); task.TargetAddress = autoIssueDTO.PointCode.StartsWith("YS") ? stationInfo.AGVStationCode : autoIssueDTO.PointCode; BaseDal.UpdateData(task); MESResponse mESResponse = _invokeMESService.MESDispatchUp(dispatchModel).DeserializeObject() ?? throw new Exception("未获取到返回信息"); if (!mESResponse.Result) { throw new Exception($"MES配送出发接口调用报错,MES返回信息{DecodeUnicode(mESResponse.Msg)}"); } _unitOfWorkManage.CommitTran(); PushTasksToWCS(new List { task }); return content.OK("叫料成功"); } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); content.Error(ex.Message); } return content; } //将Unicode解析成中文 public static string DecodeUnicode(string input) { return Regex.Replace(input, @"\\u([0-9a-fA-F]{4})", match => { return ((char)Convert.ToInt32(match.Groups[1].Value, 16)).ToString(); }); } public WebResponseContent ReceiveManualIssue(MESManualIssueDTO manualIssueDTO) { WebResponseContent content = new WebResponseContent(); try { lock (lock_manualIssue) { if (manualIssueDTO == null) { return content.Error("传入信息不能为空"); } //获取对应单据 Dt_OutMESOrder? outMESOrder = _outboundRepository.OutMESOrderRepository.QueryFirst(x => x.OutDetailId == manualIssueDTO.OutDetailId); if (outMESOrder == null) { return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{manualIssueDTO.OutDetailId}不存在"); } if (outMESOrder.OutMESOrderStatus == OutOrderStatusEnum.关闭.ObjToInt()) { return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{outMESOrder.ProductOrderNo}工单已关闭"); } //获取周转位置编号 Dt_AGVStationInfo? stationInfo = _basicRepository.AGVStationInfoRepository.QueryFirst(x => x.MESPointCode == manualIssueDTO.PointCode); if (stationInfo == null) { return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{manualIssueDTO.PointCode}不存在"); } Dt_Task? task = BaseDal.QueryData(x => x.OrderNo == outMESOrder.OutMESOrderNo && x.TaskStatus == TaskStatusEnum.CallPending.ObjToInt()).OrderByDescending(x => x.Grade).ThenBy(x => x.TaskNum).FirstOrDefault(); //获取任务 if (task == null) { return content.Error($"未找到领料计划编号{outMESOrder.ProductOrderNo}可配送任务"); } //获取任务出库详情 Dt_OutStockLockInfo outStockLockInfo = _outboundRepository.OutStockLockInfoRepository.QueryFirst(x => x.TaskNum == task.TaskNum); //调用MES配送出发指令 PlanDistributionInfo planDistribution = new PlanDistributionInfo() { DispatchPlanMaterialId = manualIssueDTO.OutDetailId, InvItemCode = task.MaterielCode, Quantity = outStockLockInfo.AssignQuantity, SendOutTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), ArrivalTime = DateTime.Now.AddMinutes(15).ToString("yyyy-MM-dd HH:mm:ss") }; MESDispatchModel dispatchModel = new MESDispatchModel() { PRO_DispachPlanDistributionInfos = new List() { planDistribution } }; _unitOfWorkManage.BeginTran(); task.TaskStatus = TaskStatusEnum.New.ObjToInt(); task.TargetAddress = manualIssueDTO.PointCode.StartsWith("YS") ? stationInfo.AGVStationCode : manualIssueDTO.PointCode; BaseDal.UpdateData(task); MESResponse mESResponse = _invokeMESService.MESDispatchUp(dispatchModel).DeserializeObject() ?? throw new Exception("未获取到返回信息"); if (!mESResponse.Result) { throw new Exception($"MES配送出发接口调用报错,MES返回信息{DecodeUnicode(mESResponse.Msg)}"); } _unitOfWorkManage.CommitTran(); PushTasksToWCS(new List { task }); return content.OK("叫料成功"); } } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// MES空托/余料呼叫接口 /// /// public WebResponseContent ReceiveReturnIssue(List returnIssueDTOs) { WebResponseContent content = new WebResponseContent(); try { lock (lock_returnIssue) { if (returnIssueDTOs == null || returnIssueDTOs.Count <= 0) { return content.Error("传入信息不能为空"); } //获取所有AGV点位 List aGVStationInfos = _basicRepository.AGVStationInfoRepository.QueryData(x => !string.IsNullOrEmpty(x.MESPointCode)); MESReturnIssueDTO? returnIssueDTO = returnIssueDTOs.FirstOrDefault(x => !aGVStationInfos.Select(x => x.MESPointCode).Contains(x.PointCode)); if (returnIssueDTO != null) { return content.Error($"周转位{nameof(MESReturnIssueDTO.PointCode)}{returnIssueDTO.PointCode}不存在"); } //获取所有库存 List stockInfosOld = _stockRepository.StockInfoRepository.QueryData(); ////空托 //foreach (var item in returnIssueDTOs.Where(x=>x.ReturnMaterial==null)) //{ //} //退料 List stockInfos=new List(); List tasksNew = new List(); foreach (var item in returnIssueDTOs.Where(x => x.ReturnMaterial != null)) { MESReturnMaterial? returnMaterial = item.ReturnMaterial; if (returnMaterial.BarCode.IsNullOrEmpty()) { return content.Error($"退料传入条码不能为空"); } Dt_AGVStationInfo aGVStationInfo = aGVStationInfos.FirstOrDefault(x => x.MESPointCode == item.PointCode); Dt_MaterielInfo? materielInfo = _basicRepository.MaterielInfoRepository.QueryFirst(x => x.MaterielCode == returnMaterial.MaterialCode); if (materielInfo == null) { return content.Error($"未找到条码{returnMaterial.BarCode}物料信息"); } //判断 if (returnMaterial.Thickness <= 0 && materielInfo.WarehouseId==WarehouseEnum.LLDYL.ObjToInt()) { return content.Error($"物料{returnMaterial.MaterialCode}条码{returnMaterial.BarCode}直径不能小于0"); } if (returnMaterial.Wide <= 0 && materielInfo.WarehouseId == WarehouseEnum.LLDYL.ObjToInt()) { return content.Error($"物料{returnMaterial.MaterialCode}条码{returnMaterial.BarCode}直径不能小于0"); } Dt_StockInfo? stockInfoOld = stockInfosOld.FirstOrDefault(x => x.PalletCode == returnMaterial.BarCode); if (stockInfoOld != null) { return content.Error($"条码{returnMaterial.BarCode}信息已存在"); } //生成库存组盘信息 Dt_StockInfo stockInfo = new Dt_StockInfo() { MaterielInvOrgId = materielInfo.MaterielInvOrgId, PalletCode = returnMaterial.BarCode, LocationCode = "", PalletType = 1, WarehouseId = materielInfo.WarehouseId, StockAttribute = materielInfo.MaterielSourceType, StockStatus = StockStatusEmun.MES余料退库.ObjToInt(), MaterielSpec = materielInfo.MaterielSpec, BatchNo = returnMaterial.MaterialLot, Unit = materielInfo.MaterielUnit, MaterielThickness = returnMaterial.Thickness, MaterielWide = returnMaterial.Wide, MaterielWeight = returnMaterial.Weight, MaterielCode = materielInfo.MaterielCode, StockLength = returnMaterial.ReturnQuantity, OrderNo = returnMaterial.ReturnOrderNo, MaterielName = materielInfo.MaterielName, IsFull = WhetherEnum.True.ObjToInt(), IsPick = returnMaterial.Whether == 0 ? WhetherEnum.True.ObjToInt() : WhetherEnum.False.ObjToInt(), Remark = StockStatusEmun.MES余料退库.ToString() }; if (stockInfo.MaterielWide > 1200) { stockInfo.PalletType = 2; } stockInfos.Add(stockInfo); //生成余料退料任务 Dt_Task newTask = new Dt_Task() { CurrentAddress = item.PointCode.StartsWith("YS") ? aGVStationInfo.AGVStationCode : item.PointCode, Grade = 0, NextAddress = "", PalletCode = stockInfo.PalletCode, Roadway = "", SourceAddress = item.PointCode.StartsWith("YS") ? aGVStationInfo.AGVStationCode : item.PointCode, TargetAddress = "", TaskStatus = TaskStatusEnum.New.ObjToInt(), WarehouseId = materielInfo.WarehouseId, PalletType = stockInfo.PalletType, MaterielCode=stockInfo.MaterielCode, Quantity=stockInfo.StockLength, OrderNo=stockInfo.OrderNo, TaskLength = (int)stockInfo.MaterielWide, GroupId= item.IssueId, WorkCentreCode=item.MakeCode }; TaskTypeEnum taskTypeEnum = aGVStationInfo.StationArea switch { nameof(StationAreaEnum.一楼印刷) => TaskTypeEnum.PrintYLBackInbound, _ => throw new Exception("未找到对应任务") }; newTask.TaskType = taskTypeEnum.ObjToInt(); tasksNew.Add(newTask); } _unitOfWorkManage.BeginTran(); BaseDal.AddData(tasksNew); _stockRepository.StockInfoRepository.AddData(stockInfos); _unitOfWorkManage.CommitTran(); //推送任务 PushTasksToWCS(tasksNew); content.OK("呼叫成功"); } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); content.Error(ex.Message); } return content; } } }