|
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();
|
/// <summary>
|
/// MES自动叫料接口
|
/// </summary>
|
/// <returns></returns>
|
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<PlanDistributionInfo>() { 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<MESResponse>() ?? throw new Exception("未获取到返回信息");
|
if (!mESResponse.Result)
|
{
|
throw new Exception($"MES配送出发接口调用报错,MES返回信息{DecodeUnicode(mESResponse.Msg)}");
|
}
|
_unitOfWorkManage.CommitTran();
|
PushTasksToWCS(new List<Dt_Task> { 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<PlanDistributionInfo>() { 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<MESResponse>() ?? throw new Exception("未获取到返回信息");
|
if (!mESResponse.Result)
|
{
|
throw new Exception($"MES配送出发接口调用报错,MES返回信息{DecodeUnicode(mESResponse.Msg)}");
|
}
|
_unitOfWorkManage.CommitTran();
|
PushTasksToWCS(new List<Dt_Task> { task });
|
return content.OK("叫料成功");
|
}
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// MES空托/余料呼叫接口
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent ReceiveReturnIssue(List<MESReturnIssueDTO> returnIssueDTOs)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
lock (lock_returnIssue)
|
{
|
if (returnIssueDTOs == null || returnIssueDTOs.Count <= 0)
|
{
|
return content.Error("传入信息不能为空");
|
}
|
//获取所有AGV点位
|
List<Dt_AGVStationInfo> 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<Dt_StockInfo> stockInfosOld = _stockRepository.StockInfoRepository.QueryData();
|
////空托
|
//foreach (var item in returnIssueDTOs.Where(x=>x.ReturnMaterial==null))
|
//{
|
|
//}
|
//退料
|
List<Dt_StockInfo> stockInfos=new List<Dt_StockInfo>();
|
List<Dt_Task> tasksNew = new List<Dt_Task>();
|
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;
|
}
|
}
|
}
|