149 lines
6.9 KiB
C#
149 lines
6.9 KiB
C#
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);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|