using JSMachine.WMS.App.Dto; using JSMachine.WMS.App.Dto.Enum; using JSMachine.WMS.App.IService; using JSMachine.WMS.Business.StockIn.IService; using JSMachine.WMS.Business.StockOut.IService; using JSMachine.WMS.Domain.Entity; using JSMachine.WMS.Infrastructure; using JSMachine.WMS.Job.Enum; using JSMachine.WMS.Job.JobAttributes; using Quartz; using SqlSugar; namespace JSMachine.WMS.Job.Job { [DisallowConcurrentExecution] [PersistJobDataAfterExecution] [Job(Name = nameof(ErpTaskJob) , Group = nameof(ErpTaskJob) + "_Group" , Description = "Erp任务作业" , ScheduleType = ScheduleType.Simple , IntervalMilliSeconds = 2000 , RepeatCount = 0 , StartTimeStr = null)] public class ErpTaskJob : IJob { private static readonly IERPTaskService ERPTaskService = GlobalServericeProvidor.GetService(); private static readonly IStockInService IStockInService = GlobalServericeProvidor.GetService(); private static readonly IStockOutService IStockOutService = GlobalServericeProvidor.GetService(); private static readonly IAGVTaskService AGVTaskService = GlobalServericeProvidor.GetService(); private static readonly IStorageRackService StorageRackService = GlobalServericeProvidor.GetService(); public async Task Execute(IJobExecutionContext context) { //1.读取状态为初始化的erptask //2.任务类型为入库 //2.1 计算目标库位 //2.2 目标库位为1楼,直接生成AgvTask(起点为入库提交的库位,终点为目标库位) //2.3 目标库位为2楼,生成两个Agv任务:TaskOne(起点为入库提交的库位,终点一楼提升机入口) TaskTwo(起点为二楼提升机出口,终点为目标库位) //3.任务类型为出库 //3.1 物料在1楼,直接生成AgvTask(起点为物料所在的库位,终点为出货码头) //3.2 物料在2楼,生成两个Agv任务:TaskOne(起点为物料所在的库位,终点为二楼提升机入口) TaskTwo(起点到一楼提升机出口,终点为出货码头) ERPTaskDto erpTaskStockIn = await ERPTaskService .GetSingalByExpression(p => p.CreationTime > DateTime.Now.AddDays(-1) && p.TaskStatus == TaskStatusEnum.Initial && (p.TaskType == TaskTypeEnum.PdaIn || p.TaskType == TaskTypeEnum.TailIn), p => p.CreationTime, OrderByType.Asc); List erpTaskStockOuts = await ERPTaskService .GetListByExpression(p => p.CreationTime > DateTime.Now.AddDays(-1) && (p.TaskStatus == TaskStatusEnum.Initial || p.TaskStatus == TaskStatusEnum.InExecution) && (p.TaskType == TaskTypeEnum.SaleOut || p.TaskType == TaskTypeEnum.ProductionOut) ); if (!erpTaskStockOuts.IsNullOrEmpty()) { foreach (var erpTaskStockOut in erpTaskStockOuts) { await CreateAgvTask_SaleOut(erpTaskStockOut); Thread.Sleep(2000); } } if (erpTaskStockIn != null) { await CreateAgvTask_StockIn(erpTaskStockIn); } } private async Task CreateAgvTask_StockIn(ERPTaskDto erpTask) { int taskNum = await AGVTaskService.Count(p => p.CreationTime >= DateTime.Now.Date && p.Floor == FloorEnum.FirstFloor && (p.TaskStatus == TaskStatusEnum.InExecution) && p.TaskType == TaskTypeEnum.PdaIn); //一楼只有4个agv小车,因此当待完成的任务已经有4个以上的时候不再生成新的任务 if (taskNum >= 4) { await ERPTaskService.UpdateTaskMsg(erpTask.Id, "当前所有小车都有任务,等待空余车辆"); return; } bool bRet = await IStockInService.CreateAgvTaskFirstFloor(erpTask); if (bRet) { erpTask.TaskStatus = TaskStatusEnum.InExecution; erpTask.TaskMsg = "开始生成子任务"; erpTask.LastModifiedTime = DateTime.Now; await ERPTaskService.EditSingalWithSpecificCols(erpTask, ["TaskStatus", "TaskMsg", "LastModifiedTime"]); } } /// /// 销售出库,生成agvTask /// /// /// public async Task CreateAgvTask_SaleOut(ERPTaskDto erpTask) { //查询ErpTask关联的所有agvTask(二楼), //agvTask出库总数量,是否大于等于erpTask出库数量 //是 ErpTask状态完成 //否 生成一个agvTask var sumNum = 0; //已生成的数量 //不论agv任务什么状态,除了取消的任务,其余的都应该扣减,否则会导致少扣减,实际多出库(就算任务执行失败,后续通过PDA报警,人工处理也为成功状态) List agvTaskList = await AGVTaskService.GetListByExpression(p => p.CreationTime >= DateTime.Now.AddDays(-1) && p.ErpTaskId == erpTask.Id && p.TaskType == erpTask.TaskType && p.TaskStatus != TaskStatusEnum.Cancelled); if (!agvTaskList.IsNullOrEmpty()) { var groupAgvTaskList = agvTaskList.GroupBy(p => p.BarCode); foreach (var groupAgvTask in groupAgvTaskList) { sumNum += groupAgvTask.FirstOrDefault().MateriaNum; } } //需求数量<=已生成数量 ErpTask状态改为结束 if ( ((erpTask.ErpOrderNum - erpTask.ErpCancelNum) <= sumNum) || ((erpTask.ErpOrderNum - erpTask.ErpCancelNum) == erpTask.AlreadyUploadNum) ) { erpTask.TaskStatus = TaskStatusEnum.Completed; await ERPTaskService.UpdateTaskStatus(erpTask); } else { bool result = await IStockOutService.CreateAgvTaskSecondFloor_SaleOut(erpTask); if (result) { erpTask.TaskStatus = TaskStatusEnum.InExecution; await ERPTaskService.UpdateTaskStatus(erpTask); } } } } }