| | |
| | | using Mapster; |
| | | using Masuit.Tools; |
| | | using Masuit.Tools.Models; |
| | | using Microsoft.EntityFrameworkCore; |
| | | using System.Linq; |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_DTO.MOM; |
| | | using WIDESEA_DTO.WMS; |
| | | using WIDESEA_IStorageBasicRepository; |
| | |
| | | using WIDESEA_StorageBasicRepository; |
| | | using WIDESEA_StorageTaskRepository; |
| | | using WIDESEA_StoragIntegrationServices; |
| | | using WIDESEAWCS_BasicInfoRepository; |
| | | |
| | | namespace WIDESEA_StorageOutTaskServices; |
| | | |
| | | public class Dt_TaskService : ServiceBase<Dt_Task, IDt_TaskRepository>, IDt_TaskService |
| | | public partial class Dt_TaskService : ServiceBase<Dt_Task, IDt_TaskRepository>, IDt_TaskService |
| | | { |
| | | private readonly LogFactory LogFactory = new LogFactory(); |
| | | private readonly IUnitOfWorkManage _unitOfWorkManage; |
| | |
| | | private readonly IDt_AreaInfoRepository _areaInfoRepository; //区域 |
| | | private readonly IAgingInOrOutInputService _agingInOrOutInputService; //静置\陈化 |
| | | private readonly IProductionRepository _productionRepository; //生产 |
| | | private readonly IDt_StationManagerRepository _stationManagerRepository; |
| | | |
| | | public Dt_TaskService(IDt_TaskRepository BaseDal, |
| | | IUnitOfWorkManage unitOfWorkManage, |
| | |
| | | IDt_AreaInfoRepository areaInfoRepository, |
| | | IAgingInOrOutInputService agingInOrOutInputService, |
| | | IStockInfoDetailRepository stockInfoDetailRepository, |
| | | IProductionRepository productionRepository) : base(BaseDal) |
| | | IProductionRepository productionRepository, |
| | | IDt_StationManagerRepository stationManagerRepository) : base(BaseDal) |
| | | { |
| | | _unitOfWorkManage = unitOfWorkManage; |
| | | _outOrderRepository = outOrderRepository; |
| | |
| | | _agingInOrOutInputService = agingInOrOutInputService; |
| | | _stockInfoDetailRepository = stockInfoDetailRepository; |
| | | _productionRepository = productionRepository; |
| | | _stationManagerRepository = stationManagerRepository; |
| | | } |
| | | |
| | | #region 外部接口方法 |
| | |
| | | //var process = await SqlSugarHelper.Db.Queryable<Dt_EquipmentProcess>() |
| | | // .FirstAsync(x => x.EquipmentName == task.Roadway); |
| | | //var info = JsonConvert.DeserializeObject<ResponseEqptRunDto>(process.ProcessValue); |
| | | |
| | | var agingOutputDto = MapToAgingOutputDto(stock); |
| | | content = await _agingInOrOutInputService.GetOCVOutputAsync(agingOutputDto); |
| | | ValidateResponse(content); |
| | | if (!task.Roadway.Contains("FR")) //非分容库区均上报MOM出入站 |
| | | { |
| | | var agingOutputDto = MapToAgingOutputDto(stock); |
| | | content = await _agingInOrOutInputService.GetOCVOutputAsync(agingOutputDto); |
| | | ValidateResponse(content); |
| | | } |
| | | } |
| | | |
| | | // 更新库存状态和任务状态 |
| | |
| | | { |
| | | throw new Exception("未找到对应的库区信息"); |
| | | } |
| | | |
| | | var parameterInfo = JsonConvert.DeserializeObject<List<ParameterInfo>>(stock.ParameterInfos).FirstOrDefault(y => y.Description.Contains("时间")); |
| | | if (parameterInfo == null) throw new Exception(""); |
| | | |
| | | var outHours = (DateTime.Now - stock.OutboundTime.Value).TotalHours; |
| | | var isNG = outHours > parameterInfo.LowerSpecificationsLimit.ToDouble() && outHours < parameterInfo.UpperSpecificationsLimit.ToDouble(); |
| | | |
| | | return new AgingOutputDto |
| | | { |
| | | OpFlag = 1, |
| | |
| | | SlotNo = x.OrderNo.ToInt32(), |
| | | SerialNo = x.SerialNumber, |
| | | SerialNoResult = true, |
| | | ParameterInfo = new List<ParameterInfo> { new ParameterInfo() { Value = (DateTime.Now - stock.CreateDate).TotalMinutes.ToString() } } |
| | | //ParameterInfo = info.ParameterInfo.Select(y => new ParameterInfo() |
| | | //{ |
| | | // LowerLomit = y.LowerControlLimit, |
| | | // UpperLimit = y.UpperControlLimit, |
| | | // ParameterResult = y.EquipmentAvailabilityFlag, |
| | | // ParameterCode = y.ParameterCode, |
| | | // ParameterDesc = y.Description, |
| | | // TargetValue = y.TargetValue, |
| | | // Value = (DateTime.Parse(stock.LinedProcessFeedbackTime, null, System.Globalization.DateTimeStyles.RoundtripKind).ToLocalTime() - stock.CreateDate).TotalMinutes.ToString(), |
| | | // DefectCode = y.UOMCode |
| | | //}).ToList() |
| | | ParameterInfo = new List<ParameterInfoOutput> { |
| | | new ParameterInfoOutput() { |
| | | Value = outHours.ToString(), |
| | | ParameterCode =parameterInfo.ParameterCode, |
| | | ParameterDesc = parameterInfo.Description, |
| | | ParameterResult = isNG.ToString(), |
| | | TargetValue = parameterInfo.TargetValue, |
| | | LowerLomit = parameterInfo.LowerSpecificationsLimit, |
| | | UpperLimit = parameterInfo.UpperSpecificationsLimit, |
| | | } |
| | | } |
| | | }).ToList() |
| | | }; |
| | | } |
| | |
| | | WebResponseContent content = new WebResponseContent(); |
| | | try |
| | | { |
| | | if (task.TaskType == (int)TaskInboundTypeEnum.InNG) |
| | | { |
| | | task.TaskState = (int)TaskInStatusEnum.SC_InFinish; |
| | | // 创建历史任务实例模型 |
| | | var taskHtyNG = CreateHistoricalTask(task); |
| | | |
| | | // 执行数据库事务 |
| | | await _unitOfWorkManage.UseTranAsync(async () => |
| | | { |
| | | |
| | | // 添加历史任务 |
| | | var isTaskHtyAdd = await _task_HtyRepository.AddDataAsync(taskHtyNG) > 0; |
| | | |
| | | // 删除任务数据 |
| | | var isTaskDelete = await Delete(task.TaskId); |
| | | if (!isTaskHtyAdd || !isTaskDelete) |
| | | throw new Exception("添加失败"); |
| | | }); |
| | | return content.OK("入库任务完成成功"); |
| | | } |
| | | |
| | | // 获取装箱信息和目标位置信息 |
| | | var boxing = await _boxingInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode); |
| | | var locationInf = await _locationRepository.QueryFirstAsync(x => x.LocationCode == task.TargetAddress); |
| | |
| | | //2024年11月16日:新增字段计算应出库时间 |
| | | stock.OutboundTime = Convert.ToDateTime(respone.LinedProcessFeedbackTime).AddHours(Convert.ToDouble(respone.SpecialParameterDuration)); |
| | | stock.ProductionLine = respone.ProductionLine; |
| | | stock.ParameterInfos = respone.ParameterInfos.ToJsonString(); |
| | | stock.StockStatus = 1; |
| | | |
| | | // 记录日志 |
| | | LogFactory.GetLog("任务完成").InfoFormat(true, "入库任务完成", $"货位地址:{task.TargetAddress},修改后货位数据:{locationInf}"); |
| | |
| | | return content.Error("任务不存在"); |
| | | } |
| | | LogFactory.GetLog("任务完成").InfoFormat(true, "验证任务是否存在", JsonConvert.SerializeObject(task)); |
| | | |
| | | if(task.TaskType == (int)TaskOutboundTypeEnum.InToOut) |
| | | { |
| | | return await CompleteInToOutTaskAsync(task); |
| | | } |
| | | |
| | | // 验证库存是否存在 |
| | | var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == input.PalletCode && x.IsFull); |
| | | if (stock != null) |
| | | { |
| | | // TODO质检回库 |
| | | } |
| | | |
| | | var area = await _areaInfoRepository.QueryFirstAsync(x => x.Spare1.Contains(input.Position)); |
| | | if (area == null) |
| | | return content.Error("改点位不在区域列表中存在"); |
| | |
| | | // 添加组盘信息 |
| | | // 将content.Data转换为ResultTrayCellsStatus对象 |
| | | var result = JsonConvert.DeserializeObject<ResultTrayCellsStatus>(content.Data.ToString()); |
| | | if (result.SerialNos.Count <= 0) |
| | | if (!result.Success) |
| | | return content.Error(result.MOMMessage); |
| | | |
| | | // 获取异常电芯 |
| | | var serialNosError = result.SerialNos.Where(x => x.SerialNoStatus != 1).ToList(); |
| | | if (serialNosError.Count > 0) |
| | | { |
| | | // TODO 创建任务送至NG排出口 |
| | | var efg = _stationManagerRepository.QueryData(x => x.stationType == 1 && x.stationChildCode == input.Position && x.stationArea == area.AreaCode).ToList(); |
| | | //List<string> NGStation = input.Position == "1088" ? new List<string>() { "1020" } : new List<string>() { "JZSC01" }; |
| | | if(efg.Count <= 0) |
| | | { |
| | | throw new Exception("未找到NG入库站台配置"); |
| | | } |
| | | List<string> NGStation = efg.Select(x => x.stationNGLocation).ToList(); |
| | | if (NGStation.Count <= 0) |
| | | { |
| | | NGStation = efg.Select(x => x.stationNGChildCode).ToList(); |
| | | } |
| | | content = await CreateNewTask(input, NGStation, 2); |
| | | return content.Error("存在异常电芯"); |
| | | } |
| | | |
| | | if (result.SerialNos.Count <= 0) |
| | | { |
| | | // Todo 空托盘入库逻辑 |
| | | content = await RequestTrayInTaskAsync(input); |
| | | return content; |
| | | } |
| | | |
| | | // TODO 获取本地料框属性与整盘电芯属性获取的值进行对比,如果一致则继续,否则返回错误信息 |
| | | //var productions = await _productionRepository.QueryDataAsync(x => result.TrayBarcodePropertys.Select(x => x.TrayBarcodeProperty).ToList().Contains(x.TrayBarcodeProperty)); |
| | |
| | | //// 调用GetProcessResponseAsync方法,获取工艺响应 |
| | | //var processResponse = await GetProcessResponseAsync(process, input.Position); |
| | | |
| | | List<string> strings = input.Position == "1088" ? new List<string>() { "CHSC01" } : new List<string>() { "JZSC01" }; |
| | | //List<string> strings = input.Position == "1088" ? new List<string>() { "CHSC01" } : new List<string>() { "JZSC01" }; |
| | | var stationManagers = _stationManagerRepository.QueryData(x => x.stationType == 1 && x.stationChildCode == input.Position && x.stationArea == area.AreaCode).ToList(); |
| | | if (stationManagers.Count <= 0) |
| | | { |
| | | throw new Exception("未找到NG入库站台配置"); |
| | | } |
| | | List<string> strings = stationManagers.Select(x=>x.Roadway).ToList(); |
| | | // 调用CreateNewTask方法,创建新任务 |
| | | content = await CreateNewTask(input, strings); |
| | | if (content.Status) |
| | |
| | | return content.OK(data: task); |
| | | } |
| | | |
| | | var stationManagers = _stationManagerRepository.QueryData(x => x.stationType == 1 && x.stationChildCode == input.Position).ToList(); |
| | | if (stationManagers.Count <= 0) |
| | | { |
| | | throw new Exception("未找到空托盘入库站台配置"); |
| | | } |
| | | |
| | | |
| | | // 获取目标地址 |
| | | List<string> strings = input.Position == "1016" ? new List<string>() { "CHSC01" } : new List<string>() { "JZSC01" }; |
| | | List<string> strings = stationManagers.Select(x => x.Roadway).ToList(); |
| | | |
| | | return await CreateNewTask(input, strings, 1); |
| | | //return await CreateNewTask(input, null, 1); |
| | | } |
| | | catch (Exception) |
| | | { |
| | |
| | | SerialNo = item.SerialNo |
| | | }).ToList() |
| | | }; |
| | | } |
| | | |
| | | // 获取工艺响应 |
| | | private async Task<List<Dt_EquipmentProcess>> GetProcessResponseAsync(ProcessApplyDto process, string position) |
| | | { |
| | | // 如果process为null,则返回null |
| | | if (process == null) return null; |
| | | |
| | | // 调用_processApplyService.GetProcessApplyAsync方法,获取工艺申请 |
| | | WebResponseContent content = await _processApplyService.GetProcessApplyAsync(process); |
| | | // 如果状态为false,则返回null |
| | | if (!content.Status) return null; |
| | | |
| | | // 将content.Data转换为ResultProcessApply对象 |
| | | var apply = JsonConvert.DeserializeObject<ResultProcessApply>(content.Data.ToString()); |
| | | // 根据position的值,返回不同的Dt_EquipmentProcess列表 |
| | | switch (position) |
| | | { |
| | | case "1088": |
| | | return SqlSugarHelper.Db.Queryable<Dt_EquipmentProcess>() |
| | | .Where(x => x.EquipmentType == "陈化" && x.WipOrderNo == apply.WipOrderNo || x.ProductDesc == apply.ProductNo) |
| | | .ToList(); |
| | | |
| | | case "1339": |
| | | case "1406": |
| | | return SqlSugarHelper.Db.Queryable<Dt_EquipmentProcess>() |
| | | .Where(x => x.EquipmentType == "静置" && x.WipOrderNo == apply.WipOrderNo || x.ProductDesc == apply.ProductNo) |
| | | .ToList(); |
| | | |
| | | default: |
| | | return new List<Dt_EquipmentProcess>(); |
| | | } |
| | | } |
| | | |
| | | #endregion 请求任务入库 |
| | |
| | | |
| | | #region 任务请求方法 |
| | | |
| | | /// <summary> |
| | | /// 更新现有任务 |
| | | /// </summary> |
| | | /// <param name="input">请求模型</param> |
| | | /// <param name="areaId">区域ID</param> |
| | | /// <param name="task">任务实例</param> |
| | | /// <param name="content">响应内容</param> |
| | | /// <returns></returns> |
| | | //private async Task<WebResponseContent> UpdateExistingTask(RequestTaskDto input, Dt_Task task) |
| | | //{ |
| | | // // 创建WebResponseContent对象 |
| | | // WebResponseContent content = new WebResponseContent(); |
| | | // // 定义变量 |
| | | // string toAddress; |
| | | // int taskState; |
| | | // string original = task.CurrentAddress; |
| | | // DtLocationInfo location = new DtLocationInfo(); |
| | | // int beforeStatus = 0; |
| | | |
| | | // // 处理入库任务 |
| | | // location = await GetLocationDistributeAsync(task.Roadway); |
| | | // toAddress = location.LocationCode; |
| | | // taskState = (int)TaskInStatusEnum.Line_InFinish; |
| | | // beforeStatus = location.LocationStatus; |
| | | |
| | | // // 更新货位信息 |
| | | // location.LocationStatus = (int)LocationEnum.Lock; |
| | | |
| | | // // 更新任务信息 |
| | | // task.CurrentAddress = input.Position; |
| | | // task.TargetAddress = toAddress; |
| | | // task.NextAddress = toAddress; |
| | | // task.TaskState = taskState; |
| | | |
| | | // // 开始事务 |
| | | // _unitOfWorkManage.BeginTran(); |
| | | // // 定义变量 |
| | | // bool isUpdateLo = true; |
| | | // bool isUpdateChange = true; |
| | | |
| | | // // 尝试更新任务 |
| | | // bool isResult = await BaseDal.UpdateDataAsync(task); |
| | | // bool isTaskDetail = await _taskExecuteDetailRepository.AddDetailAsync(task, false, TaskDescription.GetTaskUpdateDescription(task.PalletCode, original, input.Position, TaskInStatusEnum.Line_InFinish.GetIntegralRuleTypeEnumDesc())); |
| | | |
| | | // // 创建LocationChangeRecordDto对象 |
| | | // LocationChangeRecordDto changeRecordDto = new LocationChangeRecordDto() |
| | | // { |
| | | // // 设置变量 |
| | | // AfterStatus = location.LocationStatus, |
| | | // BeforeStatus = beforeStatus, |
| | | // TaskNum = task.TaskNum.Value, |
| | | // LocationId = location.Id, |
| | | // LocationCode = location.LocationCode, |
| | | // ChangeType = (int)StatusChangeTypeEnum.AutomaticStorage, |
| | | // }; |
| | | // // 更新位置状态 |
| | | // isUpdateChange = _locationStatusChangeRecordRepository.AddStatusChangeRecord(changeRecordDto); |
| | | // isUpdateLo = await _locationRepository.UpdateDataAsync(location); |
| | | |
| | | // if (isResult && isUpdateLo && isTaskDetail) |
| | | // { |
| | | // // 提交事务 |
| | | // _unitOfWorkManage.CommitTran(); |
| | | // content.OK(data: task); |
| | | // } |
| | | // else |
| | | // { |
| | | // // 回滚事务 |
| | | // _unitOfWorkManage.RollbackTran(); |
| | | // content.Error("更新任务失败"); |
| | | // } |
| | | // return content; |
| | | //} |
| | | |
| | | // 更新任务货位 |
| | | |
| | | private async Task<WebResponseContent> UpdateExistingTask(RequestTaskDto input, Dt_Task task) |
| | |
| | | var content = new WebResponseContent(); |
| | | |
| | | // 获取目标地址和更新任务状态 |
| | | var location = await GetLocationDistributeAsync(task.Roadway); |
| | | if (location == null) |
| | | if (task.TaskType == (int)TaskInboundTypeEnum.InNG) |
| | | { |
| | | return content.Error("无法获取货位信息"); |
| | | // TODO 根据巷道查找对应NG口,现在默认去静置堆垛机的异常口货位号 |
| | | task.CurrentAddress = input.Position; |
| | | task.TargetAddress = "002-021-000"; |
| | | task.NextAddress = "002-021-000"; |
| | | task.TaskState = (int)TaskInStatusEnum.Line_InFinish; |
| | | bool isResult = await BaseDal.UpdateDataAsync(task); |
| | | return content.OK(data: task); |
| | | } |
| | | else |
| | | { |
| | | var location = await GetLocationDistributeAsync(task.Roadway); |
| | | if (location == null) |
| | | { |
| | | return content.Error("无法获取货位信息"); |
| | | } |
| | | |
| | | string toAddress = location.LocationCode; |
| | | int taskState = (int)TaskInStatusEnum.Line_InFinish; |
| | | int beforeStatus = location.LocationStatus; |
| | | // 更新货位信息 |
| | | location.LocationStatus = (int)LocationEnum.Lock; |
| | | |
| | | // 更新任务信息 |
| | | MapTaskProperties(task, input, toAddress, taskState); |
| | | |
| | | // 开始事务 |
| | | var isResult = await UpdateTaskAsync(task, location, beforeStatus); |
| | | if (!isResult) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return content.Error("更新任务失败"); |
| | | } |
| | | |
| | | // 提交事务 |
| | | _unitOfWorkManage.CommitTran(); |
| | | return content.OK(data: task); |
| | | } |
| | | |
| | | string toAddress = location.LocationCode; |
| | | int taskState = (int)TaskInStatusEnum.Line_InFinish; |
| | | int beforeStatus = location.LocationStatus; |
| | | |
| | | // 更新货位信息 |
| | | location.LocationStatus = (int)LocationEnum.Lock; |
| | | |
| | | // 更新任务信息 |
| | | MapTaskProperties(task, input, toAddress, taskState); |
| | | |
| | | // 开始事务 |
| | | var isResult = await UpdateTaskAsync(task, location, beforeStatus); |
| | | if (!isResult) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return content.Error("更新任务失败"); |
| | | } |
| | | |
| | | // 提交事务 |
| | | _unitOfWorkManage.CommitTran(); |
| | | return content.OK(data: task); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | |
| | | // 获取目标地址 |
| | | //string ToAddress = await GetRoadWayAsync(process); |
| | | string ToAddress = await GetRoadWayAsync(input, process); |
| | | string ToAddress = string.Empty; |
| | | if (flag != 2) |
| | | ToAddress = await GetRoadWayAsync(input, process); |
| | | else |
| | | ToAddress = process[0]; |
| | | |
| | | // 创建新任务实例 |
| | | var task = new Dt_Task |
| | |
| | | PalletCode = input.PalletCode, |
| | | SourceAddress = input.Position, |
| | | TaskState = (int)TaskInStatusEnum.InNew, |
| | | TaskType = flag == 0 ? (int)TaskInboundTypeEnum.Inbound : (int)TaskInboundTypeEnum.InTray, |
| | | TaskType = flag == 0 ? (int)TaskInboundTypeEnum.Inbound : flag == 1 ? (int)TaskInboundTypeEnum.InTray : (int)TaskInboundTypeEnum.InNG, |
| | | TaskNum = await BaseDal.GetTaskNo(), |
| | | Creater = "Systeam" |
| | | }; |
| | |
| | | PalletCode = task.PalletCode, |
| | | RoadWay = task.Roadway, |
| | | SourceAddress = task.SourceAddress, |
| | | TargetAddress = task.Roadway, |
| | | TargetAddress = task.TargetAddress, |
| | | TaskState = task.TaskState.Value, |
| | | Id = 0, |
| | | TaskType = task.TaskType, |