Files
2026-09-02 16:31:50 +08:00

149 lines
6.9 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}
}
}