Files

149 lines
6.9 KiB
C#
Raw Permalink Normal View History

2026-09-02 16:31:50 +08:00
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<IERPTaskService>();
private static readonly IStockInService IStockInService = GlobalServericeProvidor.GetService<IStockInService>();
private static readonly IStockOutService IStockOutService = GlobalServericeProvidor.GetService<IStockOutService>();
private static readonly IAGVTaskService AGVTaskService = GlobalServericeProvidor.GetService<IAGVTaskService>();
private static readonly IStorageRackService StorageRackService = GlobalServericeProvidor.GetService<IStorageRackService>();
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<ERPTaskDto> 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"]);
}
}
/// <summary>
/// 销售出库,生成agvTask
/// </summary>
/// <param name="erpTask"></param>
/// <returns></returns>
public async Task CreateAgvTask_SaleOut(ERPTaskDto erpTask)
{
//查询ErpTask关联的所有agvTask(二楼),
//agvTask出库总数量,是否大于等于erpTask出库数量
//是 ErpTask状态完成
//否 生成一个agvTask
var sumNum = 0; //已生成的数量
//不论agv任务什么状态,除了取消的任务,其余的都应该扣减,否则会导致少扣减,实际多出库(就算任务执行失败,后续通过PDA报警,人工处理也为成功状态)
List<AGVTaskDto> 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);
}
}
}
}
}