using JNPF.Common.Core.Manager; using JNPF.Common.Dtos.VisualDev; using JNPF.Common.Extension; using JNPF.Common.Security; using JNPF.EventBus; using JNPF.FriendlyException; using JNPF.Systems.Interfaces.System; using Mapster; using Microsoft.AspNetCore.Mvc; using SqlSugar; using Tnb.BasicData.Entities; using Tnb.WarehouseMgr.Entities; using Tnb.WarehouseMgr.Entities.Consts; using Tnb.WarehouseMgr.Entities.Dto; using Tnb.WarehouseMgr.Entities.Dto.Inputs; using Tnb.WarehouseMgr.Entities.Enums; using Tnb.WarehouseMgr.Interfaces; namespace Tnb.WarehouseMgr { /// /// 机器人回调服务类 /// public class WmsRobotCallbackService : BaseWareHouseService { private readonly IWmsCarryBindService _wmsCarryBindService; private readonly ISqlSugarClient _db; private readonly IUserManager _userManager; private readonly IWareHouseService _warehouseService; private readonly IBillRullService _billRullService; private readonly IWmsKittingInStkService _wmsKittingInStkService; public WmsRobotCallbackService( IWmsCarryBindService wmsCarryBindService, ISqlSugarRepository repository, IUserManager userManager, IWareHouseService warehouseService, IBillRullService billRullService, IWmsKittingInStkService wmsKittingInStkService, IEventPublisher publisher ) { _wmsCarryBindService = wmsCarryBindService; _db = repository.AsSugarClient(); _userManager = userManager; _warehouseService = warehouseService; _billRullService = billRullService; _wmsKittingInStkService = wmsKittingInStkService; } /// /// 机器人完成任务后回调接口 /// /// /// [HttpPost] public async Task RobotCallback(RobotCallBackInput input) { WmsCarryH carry = await _db.Queryable().SingleAsync(it => it.id == input.carry_id); WmsCarryH subCarry = await _db.Queryable().SingleAsync(it => it.id == input.membercarry_id); if (carry != null && subCarry != null) { VisualDevModelDataCrInput visualDevModelCrInput = new() { data = new Dictionary() }; visualDevModelCrInput.data[nameof(WmsCarrybindH.carry_id)] = input.carry_id; visualDevModelCrInput.data[nameof(WmsCarrybindH.carry_code)] = input.carry_code; visualDevModelCrInput.data[nameof(WmsCarrybindH.membercarry_id)] = input.membercarry_id; visualDevModelCrInput.data[nameof(WmsCarrybindH.membercarry_code)] = input.membercarry_code; visualDevModelCrInput.data[nameof(WmsCarrybindH.type)] = 0; visualDevModelCrInput.data[nameof(WmsCarrybindH.carrystd_id)] = carry.carrystd_id; visualDevModelCrInput.data[nameof(WmsCarrybindH.create_id)] = _userManager.UserId; visualDevModelCrInput.data[nameof(WmsCarrybindH.create_time)] = DateTime.Now; visualDevModelCrInput.data[nameof(WmsCarrybindH.loc)] = input.loc; await _wmsCarryBindService.CarryBind(visualDevModelCrInput); carry.collocation_scheme_id = subCarry.collocation_scheme_id; carry.collocation_scheme_code = subCarry.collocation_scheme_code; carry.carry_status = ((int)EnumCarryStatus.齐套).ToString(); _ = await _db.Updateable(carry).UpdateColumns(it => new { it.collocation_scheme_id, it.collocation_scheme_code, it.carry_status }).ExecuteCommandAsync(); if (input.isLast) { WmsKittingoutH kittingout = await _db.Queryable().FirstAsync(it => it.collocation_scheme_id == carry.collocation_scheme_id && it.status == WmsWareHouseConst.BILLSTATUS_CALLED_ID); if (kittingout != null) { await Publish(nameof(IWmskittingOutService.KittingOutByAdd)); await Publish(nameof(IWmskittingOutService.KittingOutByIsToBeShipped)); visualDevModelCrInput.data = new Dictionary { [nameof(InStockStrategyQuery.warehouse_id)] = kittingout.warehouse_id, [nameof(WmsKittingInstock.carry_id)] = input.carry_id, [nameof(WmsKittingInstock.carry_code)] = input.carry_code, [nameof(WmsKittingInstock.collocation_scheme_id)] = carry!.collocation_scheme_id!, [nameof(WmsKittingInstock.collocation_scheme_code)] = carry!.collocation_scheme_code!, [nameof(WmsKittingInstock.seq)] = kittingout.seq, [nameof(WmsKittingInstock.biz_type)] = WmsWareHouseConst.BIZTYPE_WMSKITTINGINSTK_ID, [nameof(WmsKittingInstock.status)] = WmsWareHouseConst.BILLSTATUS_ADD_ID, [nameof(WmsKittingInstock.create_id)] = _userManager.UserId, [nameof(WmsKittingInstock.create_time)] = DateTime.Now, [nameof(WmsKittingInstock.location_id)] = carry!.location_id!, [nameof(WmsKittingInstock.bill_code)] = _billRullService.GetBillNumber("WmsKittingInStk").GetAwaiter().GetResult(), [nameof(WmsKittingInstock.source_id)] = kittingout.id, [nameof(WmsKittingInstock.source_code)] = kittingout.bill_code }; BasLocation? location = await _db.Queryable().SingleAsync(it => it.id == kittingout.location_id); if (kittingout.location_id.IsNullOrWhiteSpace() || (location != null && location.is_type.ToEnum() == EnumLocationType.存储库位)) { //入库 await _wmsKittingInStkService.KittingInStk(visualDevModelCrInput); } else { if (location != null && location.is_use == ((int)EnumCarryStatus.空闲).ToString() && location.is_lock == 0) { //出库 WmsPointH sPoint = await _db.Queryable().FirstAsync(it => it.location_id == carry.location_id); WmsPointH ePoint = await _db.Queryable().FirstAsync(it => it.location_id == kittingout.location_id); if (sPoint != null && ePoint != null) { var kittingOutObj = new { requireId = kittingout.id, requireCode = kittingout.bill_code }; List preTasks = await _genPreTask(sPoint, ePoint, carry, kittingOutObj); List carryCodes = await _db.Queryable().Where(it => it.carry_id == carry.id).ToListAsync(); List pretaskCodes = new(); foreach (WmsPretaskH pt in preTasks) { List partCodes = carryCodes.FindAll(x => x.carry_id == pt.carry_id).Distinct().ToList(); List curPreTaskCodes = partCodes.Adapt>(); curPreTaskCodes.ForEach(x => { x.id = SnowflakeIdHelper.NextId(); x.bill_id = pt.id; x.create_time = DateTime.Now; }); pretaskCodes.AddRange(curPreTaskCodes); } _ = await _warehouseService.GenPreTask(preTasks, pretaskCodes); kittingout.status = WmsWareHouseConst.BILLSTATUS_ON_ID; _ = await _db.Updateable(kittingout).UpdateColumns(it => it.status).ExecuteCommandAsync(); GenPreTaskUpInput genPreTaskAfterUpInput = new() { CarryIds = preTasks.Select(x => x.carry_id).ToList(), LocationIds = new List { carry.location_id! } }; await _warehouseService.GenInStockTaskHandleAfter(genPreTaskAfterUpInput, it => new WmsCarryH { is_lock = 1 }, it => new BasLocation { is_lock = 1 }); await InvokeGenPretaskExcute(); } } else { //入库 await _wmsKittingInStkService.KittingInStk(visualDevModelCrInput); } } } } } } private async Task> _genPreTask(WmsPointH sPoint, WmsPointH ePoint, WmsCarryH carry, dynamic KittingOutObj) { List preTasks = new(); List points = await _warehouseService.PathAlgorithms(sPoint.id, ePoint.id); //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) if (points.Count <= 2) { throw new AppFriendlyException($"sPoint {sPoint.point_code} ePoint{ePoint.point_code}该路径不存在", 500); } if (points?.Count > 0) { preTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it => { WmsPointH? sPoint = it.FirstOrDefault(); WmsPointH? ePoint = it.LastOrDefault(); WmsPretaskH preTask = new() { org_id = _userManager.User.OrganizeId, startlocation_id = sPoint?.location_id!, startlocation_code = sPoint?.location_code!, endlocation_id = ePoint?.location_id!, endlocation_code = ePoint?.location_code!, start_floor = sPoint?.floor.ToString(), end_floor = ePoint?.floor.ToString(), bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(), status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID, biz_type = WmsWareHouseConst.BIZTYPE_WMSKITTINGOUTSTK_ID, task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID, carry_id = carry.id!, carry_code = carry.carry_code!, area_id = sPoint?.area_id!, area_code = it.Key, require_id = KittingOutObj.requireId, require_code = KittingOutObj.requireCode, create_id = _userManager.UserId, create_time = DateTime.Now }; return preTask; }).ToList(); } return preTasks; } } }