From f4cf422a831454c97667fc2cac15dba5894a9a5b Mon Sep 17 00:00:00 2001 From: majian <780924089@qq.com> Date: Fri, 12 Jul 2024 15:11:11 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=B5=E6=A2=AF=E6=8E=A7=E5=88=B6bug?= =?UTF-8?q?=E5=A4=84=E7=90=86=20=E5=8C=85=E6=9D=90=E5=87=BA=E5=BA=93?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tnb.ProductionMgr/RedisBackGround.cs | 70 +++++- .../Consts/WmsWareHouseConst.cs | 4 + .../Entity/WmsPackOutstockD.cs | 27 +++ .../IWareHouseService.cs | 6 + .../IWmsPackInstockService.cs | 11 + .../IWmsPackOutstockService.cs | 13 ++ .../Tnb.WarehouseMgr/BaseWareHouseService.cs | 1 + .../Tnb.WarehouseMgr/DevServBase`1.cs | 17 +- .../Tnb.WarehouseMgr/DeviceProviderService.cs | 2 +- .../Tnb.WarehouseMgr/ErpToWmsService.cs | 16 +- .../Tnb.WarehouseMgr/WareHouseService.cs | 39 +++- .../WmsMaterialTransferService.cs | 12 +- .../Tnb.WarehouseMgr/WmsPackInstockService.cs | 2 +- .../WmsPackOutstockService.cs | 217 +++++++----------- .../Configurations/ConnectionStrings.json | 2 +- 15 files changed, 283 insertions(+), 156 deletions(-) create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsPackInstockService.cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsPackOutstockService.cs diff --git a/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs b/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs index 80297514..0e379bf7 100644 --- a/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs +++ b/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs @@ -43,6 +43,7 @@ using Tnb.ProductionMgr.Entities; using Tnb.ProductionMgr.Entities.Dto; using Tnb.ProductionMgr.Entities.Enums; using Tnb.ProductionMgr.Interfaces; +using Tnb.WarehouseMgr; using Tnb.WarehouseMgr.Entities; using Tnb.WarehouseMgr.Entities.Configs; using Tnb.WarehouseMgr.Entities.Consts; @@ -78,6 +79,9 @@ namespace Tnb.ProductionMgr private static Timer? Floor2timer移走上升降区未生成预任务且满托的料架; private static Timer? Floor2timer移走下升降区未生成预任务且空托的料架; + // 四楼包材自动到二楼包材库 + private static Timer? PackOutstockServicetimer; + public SemaphoreSlim s_taskCheckGet = new(1); public SemaphoreSlim s_taskScan = new(1); public SemaphoreSlim s_taskSSXcode = new(1); @@ -89,6 +93,7 @@ namespace Tnb.ProductionMgr public SemaphoreSlim s_task送满托到下升降区 = new(1); public SemaphoreSlim s_task移走上升降区未生成预任务且满托的料架 = new(1); public SemaphoreSlim s_task移走下升降区未生成预任务且空托的料架 = new(1); + public SemaphoreSlim s_taskPackOutstockService = new(1); private StackExRedisHelper _redisData; private readonly IPrdInstockService _prdInstockService; @@ -104,6 +109,7 @@ namespace Tnb.ProductionMgr private ISqlSugarClient db_Floor2timer送满托到下升降区; private ISqlSugarClient db_Floor2timer移走上升降区未生成预任务且满托的料架; private ISqlSugarClient db_Floor2timer移走下升降区未生成预任务且空托的料架; + private ISqlSugarClient db_PackOutstockService; private readonly IWmsPDAScanInStockService _wmsPDAScanInStock; private readonly IUserManager _userManager; private readonly IBillRullService _billRullService; @@ -111,6 +117,7 @@ namespace Tnb.ProductionMgr private readonly IWmsCarryBindService _wmsCarryBindService; private readonly IWmsCarryUnbindService _wmsCarryUnbindService; private readonly IWmsEmptyOutstockService _wmsEmptyOutstockService; + private readonly IWmsPackOutstockService _wmsPackOutstockService; private readonly ElevatorControlConfiguration _eleCtlCfg = App.Configuration.Build(); @@ -127,7 +134,7 @@ namespace Tnb.ProductionMgr #region 构造函数 public RedisBackGround(StackExRedisHelper redisData, IPrdInstockService prdInstockService, ISqlSugarRepository repository, IWmsPDAScanInStockService wmsPDAScanInStock , IUserManager userManager, IBillRullService billRullService, IWareHouseService wareHouseService, IWmsCarryBindService wmsCarryBindService, - IWmsCarryUnbindService wmsCarryUnbindService, IWmsEmptyOutstockService wmsEmptyOutstockService) + IWmsCarryUnbindService wmsCarryUnbindService, IWmsEmptyOutstockService wmsEmptyOutstockService, IWmsPackOutstockService wmsPackOutstockService) { _redisData = redisData; _prdInstockService = prdInstockService; @@ -139,6 +146,7 @@ namespace Tnb.ProductionMgr _wmsCarryBindService = wmsCarryBindService; _wmsEmptyOutstockService = wmsEmptyOutstockService; _wmsCarryUnbindService = wmsCarryUnbindService; + _wmsPackOutstockService = wmsPackOutstockService; db_CheckGettimer = repository.CopyNew(); db_Scantimer = repository.CopyNew(); @@ -151,7 +159,7 @@ namespace Tnb.ProductionMgr db_Floor2timer送满托到下升降区 = repository.CopyNew(); db_Floor2timer移走上升降区未生成预任务且满托的料架 = repository.CopyNew(); db_Floor2timer移走下升降区未生成预任务且空托的料架 = repository.CopyNew(); - + db_PackOutstockService = repository.CopyNew(); } #endregion @@ -912,7 +920,7 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA List WmsMaterialTransfers = db_Floor2UpMachinecodetimer.Queryable() .InnerJoin((a, b) => a.id == b.bill_id) .Where((a, b) => a.warehouse_instock == "33780009364245" && a.warehouse_outstock == "2" && a.remainbindracknum > 0 - && b.carry_code == barcode).ToList(); + && b.carry_code == barcode && a.status != WmsWareHouseConst.BILLSTATUS_COMPLETE_ID).ToList(); if (WmsMaterialTransfers.Count() == 0) { @@ -1187,7 +1195,8 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA catch (Exception ex) { Console.WriteLine("【上升降机】" + ex.Message); - LoggerFloor2RackDelivery.LogError($"【送空托到上升降区】 数据库连接异常:{ex}"); + LoggerFloor2RackDelivery.LogError($"【送空托到上升降区】 {ex.Message}"); + LoggerFloor2RackDelivery.LogError($"【送空托到上升降区】 {ex.StackTrace}"); // 数据库连接断开时会报错 try { await db_Floor2timer送空托到上升降区.Ado.RollbackTranAsync(); } catch { }; } @@ -1355,7 +1364,8 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA catch (Exception ex) { Console.WriteLine("【上升降机】" + ex.Message); - LoggerFloor2RackDelivery.LogError($"【送满托到下升降区】 数据库连接异常:{ex}"); + LoggerFloor2RackDelivery.LogError($"【送满托到下升降区】 {ex.Message}"); + LoggerFloor2RackDelivery.LogError($"【送满托到下升降区】 {ex.StackTrace}"); // 数据库连接断开时会报错 try { await db_Floor2timer送满托到下升降区.Ado.RollbackTranAsync(); } catch { }; } @@ -1470,7 +1480,8 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA catch (Exception ex) { Console.WriteLine("【上升降机】" + ex.Message); - LoggerFloor2RackDelivery.LogError($"【移走上升降区未生成预任务且满托的料架】 数据库连接异常:{ex}"); + LoggerFloor2RackDelivery.LogError($"【移走上升降区未生成预任务且满托的料架】{ex.Message}"); + LoggerFloor2RackDelivery.LogError($"【移走上升降区未生成预任务且满托的料架】{ex.StackTrace}"); // 数据库连接断开时会报错 try { await db_Floor2timer移走上升降区未生成预任务且满托的料架.Ado.RollbackTranAsync(); } catch { }; } @@ -1580,8 +1591,7 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA LoggerFloor2RackDelivery.LogInformation($"【移走下升降区空托的料架】 开始执行预任务生成: 料架区为{wmsMechanicalArmH.name}{wmsMechanicalArmH.stackingposition} 料架为{wmsMechanicalArmH.rackcode}"); - WmsMaterialTransfer wmsMaterialTransfer = await db_Floor2timer移走下升降区未生成预任务且空托的料架.Queryable().Where(r => r.bill_code == wmsMechanicalArmH.outbill).FirstAsync(); - bool result = await createPretask(wmsMechanicalArmH.location_id, endLocation.id, wmsMechanicalArmH.rackid, wmsMechanicalArmH.rackcode, LoggerFloor2RackDelivery, db_Floor2timer移走下升降区未生成预任务且空托的料架, true, wmsMaterialTransfer.id); + bool result = await createPretask(wmsMechanicalArmH.location_id, endLocation.id, wmsMechanicalArmH.rackid, wmsMechanicalArmH.rackcode, LoggerFloor2RackDelivery, db_Floor2timer移走下升降区未生成预任务且空托的料架, true); if (!result) { LoggerFloor2RackDelivery.LogInformation($"【移走下升降区空托的料架】 未成功生成预任务 起点{wmsMechanicalArmH.location_code} 终点{endLocation.location_code} 料架 {wmsMechanicalArmH.rackcode}"); @@ -1600,8 +1610,9 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA } catch (Exception ex) { - Console.WriteLine("【上升降机】" + ex.Message); - LoggerFloor2RackDelivery.LogError($"【移走下升降区空托的料架】 数据库连接异常:{ex}"); + Console.WriteLine("【移走下升降区空托的料架】" + ex.Message); + LoggerFloor2RackDelivery.LogError($"【移走下升降区空托的料架】{ex.Message}"); + LoggerFloor2RackDelivery.LogError($"【移走下升降区空托的料架】{ex.StackTrace}"); // 数据库连接断开时会报错 try { await db_Floor2timer移走下升降区未生成预任务且空托的料架.Ado.RollbackTranAsync(); } catch { }; } @@ -1653,6 +1664,41 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA return false; } + /// + /// 四楼包材自动到二楼包材库 + /// + /// + public async void PackOutstockService(object? args) + { + if (s_taskPackOutstockService.CurrentCount == 0) + return; + await s_taskPackOutstockService.WaitAsync(); + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + try + { + Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 开始执行四楼包材自动到二楼包材库"); + LoggerTimer.LogInformation($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 开始执行四楼包材自动到二楼包材库"); + + await _wmsPackOutstockService.Distribute(); + } + catch (Exception ex) + { + Console.WriteLine("【四楼包材自动到二楼包材库】" + ex.Message); + LoggerFloor2RackDelivery.LogError($"【四楼包材自动到二楼包材库】{ex.Message}"); + LoggerFloor2RackDelivery.LogError($"【四楼包材自动到二楼包材库】{ex.StackTrace}"); + } + finally + { + s_taskPackOutstockService.Release(); + + stopwatch.Stop(); + Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 结束四楼包材自动到二楼包材库 {stopwatch.ElapsedMilliseconds} ms"); + LoggerTimer.LogInformation($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 结束执行四楼包材自动到二楼包材库 {stopwatch.ElapsedMilliseconds} ms"); + } + } + + #region 内存测试 public async Task GetBoolTag(string DevName, string field) @@ -1795,7 +1841,9 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA Floor2timer移走下升降区未生成预任务且空托的料架 = new Timer(移走下升降区未生成预任务且空托的料架, null, TimeSpan.Zero, TimeSpan.FromSeconds(30)); GenTaskExecutetimer = new Timer(GenTaskExecute, null, TimeSpan.Zero, TimeSpan.FromSeconds(30)); - + + PackOutstockServicetimer = new Timer(PackOutstockService, null, TimeSpan.Zero, TimeSpan.FromSeconds(60)); + return Task.CompletedTask; } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs index 2714e0e4..305aeb52 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs @@ -92,6 +92,10 @@ /// public const string WMS_PRETASK_H_ENCODE = "PreTaskGen"; /// + /// 包材出库流水号 + /// + public const string WMS_PACKOUTSTOCK_H_ENCODE = "WMSPACKOUTSTOCK"; + /// /// 采购收料物料流水号 /// public const string WMS_PURCHASE_MAT_ENCODE = "PurchaseMat"; diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsPackOutstockD.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsPackOutstockD.cs index ce546d9c..c8517367 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsPackOutstockD.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsPackOutstockD.cs @@ -114,4 +114,31 @@ public partial class WmsPackOutstockD : BaseEntity /// public string? qc_res { get; set; } + /// + /// 载具id + /// + public string? carry_id { get; set; } + + /// + /// 载具编码 + /// + public string? carry_code { get; set; } + + /// + /// 起点id + /// + public string? startlocation_id { get; set; } + /// + /// 起点编码 + /// + public string? startlocation_code { get; set; } + /// + /// 终点id + /// + public string? endlocation_id { get; set; } + /// + /// 终点编码 + /// + public string? endlocation_code { get; set; } + } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs index 522afbca..daf50c8c 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs @@ -21,6 +21,12 @@ namespace Tnb.WarehouseMgr.Interfaces /// Task> InStockStrategy([FromQuery] InStockStrategyQuery input); /// + /// 包材库2楼入库策略 + /// + /// + /// + Task> BCKF2InStockStrategy([FromQuery] InStockStrategyQuery input); + /// /// 出库策略 /// /// diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsPackInstockService.cs b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsPackInstockService.cs new file mode 100644 index 00000000..0cb33ed6 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsPackInstockService.cs @@ -0,0 +1,11 @@ +using JNPF.Common.Dtos.VisualDev; +using Tnb.WarehouseMgr.Entities.Dto.Inputs; +using Tnb.WarehouseMgr.Entities.Dto.Outputs; + +namespace Tnb.WarehouseMgr.Interfaces +{ + public interface IWmsPackInstockService + { + + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsPackOutstockService.cs b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsPackOutstockService.cs new file mode 100644 index 00000000..17eb2842 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsPackOutstockService.cs @@ -0,0 +1,13 @@ +using JNPF.Common.Dtos.VisualDev; +using Tnb.WarehouseMgr.Entities; +using Tnb.WarehouseMgr.Entities.Dto; +using Tnb.WarehouseMgr.Entities.Dto.Inputs; +using Tnb.WarehouseMgr.Entities.Dto.Outputs; + +namespace Tnb.WarehouseMgr.Interfaces +{ + public interface IWmsPackOutstockService + { + public Task Distribute(); + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs index 6ca2a4ad..4b50ce85 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs @@ -47,6 +47,7 @@ namespace Tnb.WarehouseMgr public static SemaphoreSlim s_taskExecuteSemaphore = new(1); public static SemaphoreSlim s_elevatorStatusSemaphore = new(1); + protected static Dictionary _s_eleUseStatusDic; protected IEventPublisher? EventPublisher { set; get; } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/DevServBase`1.cs b/WarehouseMgr/Tnb.WarehouseMgr/DevServBase`1.cs index c2e188f2..e2216879 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/DevServBase`1.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/DevServBase`1.cs @@ -20,7 +20,18 @@ namespace Tnb.WarehouseMgr private static readonly Lazy initializationTask; private static SqlSugarScope context; private readonly ISqlSugarClient _db; - public static Dictionary s_eleUseStatusDic = new(); + public Dictionary s_eleUseStatusDic + { + get + { + if (context == null) + return null; + if (_s_eleUseStatusDic == null) + _s_eleUseStatusDic = context.Queryable().ToList().ToDictionary(x => x.elevator_id, x => x.is_use); + + return _s_eleUseStatusDic; + } + } public static Dictionary s_loadedStatusDic = new(); static DevServBase() @@ -48,9 +59,9 @@ namespace Tnb.WarehouseMgr context = new(cfg); s_elevatorMap = await context.Queryable().ToDictionaryAsync(x => x.elevator_id, x => x.elevator_code); - s_eleUseStatusDic = context.Queryable().ToList().ToDictionary(x => x.elevator_id, x => x.is_use); + //s_eleUseStatusDic = context.Queryable().ToList().ToDictionary(x => x.elevator_id, x => x.is_use); - if (s_eleUseStatusDic.Count < 1) + //if (s_eleUseStatusDic.Count < 1) { foreach (var (k, _) in s_elevatorMap) { diff --git a/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs b/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs index 3316e062..abfccc2d 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs @@ -196,7 +196,7 @@ namespace Tnb.WarehouseMgr if (sysStatus.ToEnum() == EnumSysStatus.正常状态 && runStatus.ToEnum() == EnumRunStatus.停梯 && doorStatus == (int)EnumDoorStatus.开门到位保持) { - Logger.Information($"【LoadConfirm】 {devName}取货成功"); + Logger.Information($"【LoadConfirm】 {devName}取货确认成功"); return await ToApiResult(HttpStatusCode.OK, "成功"); } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs b/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs index 329764aa..44e36ab6 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs @@ -332,7 +332,7 @@ namespace Tnb.WarehouseMgr int count = input.details.Where(r => string.IsNullOrEmpty(r.station_code)).Count(); if (count > 0) { - _LoggerErp2Mes.LogWarning($@"表体存在未填写工位的明细!"); + _LoggerErp2Mes.LogWarning($@"【MaterialTransfer】表体存在未填写工位的明细!"); throw new AppFriendlyException($@"表体存在未填写工位的明细!", 500); } @@ -352,13 +352,25 @@ namespace Tnb.WarehouseMgr int count = input.details.Where(r => string.IsNullOrEmpty(r.station_code)).Count(); if (count > 0) { - _LoggerErp2Mes.LogWarning($@"表体存在未填写工位的明细!"); + _LoggerErp2Mes.LogWarning($@"【MaterialTransfer】表体存在未填写工位的明细!"); throw new AppFriendlyException($@"表体存在未填写工位的明细!", 500); } transfer_type = WmsWareHouseConst.MATERIALTRANSFER_QTCRK_CODE; } + + var wmsMaterialTransferdsDistinct = input.details.Select(r => new + { + material_id = r.material_code, + code_batch = r.code_batch, + }).Distinct(); + if (wmsMaterialTransferdsDistinct.Count() < input.details.Count) + { + _LoggerErp2Mes.LogWarning($@"【MaterialTransfer】表体存在物料和批号重复的明细!"); + throw new AppFriendlyException($@"表体存在物料和批号重复的明细!", 500); + } + try { await db.Ado.BeginTranAsync(); diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs index b380ca96..dd4f9bea 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs @@ -232,6 +232,38 @@ namespace Tnb.WarehouseMgr return items.Take(input.Size).ToList(); } + /// + /// 包材库2楼入库策略 + /// + /// + [HttpGet] + public async Task> BCKF2InStockStrategy([FromQuery] InStockStrategyQuery input) + { + List items = new(); + try + { + WmsInstockPolicies policy = await _db.CopyNew().Queryable().Where(it => it.status == 1).FirstAsync(); + if (policy == null) + { + throw new AppFriendlyException("没有可用的策略", 500); + } + + Expression> whereExp = Expressionable.Create() + .And(it => it.wh_id == input.warehouse_id) + .And(it => it.is_lock == 0) + .And(it => it.is_type == ((int)EnumLocationType.出入库位).ToString()) + .And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString()) + .ToExpression(); + items = await _db.CopyNew().Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync(); + } + catch (Exception) + { + throw; + } + return items.Take(input.Size).ToList(); + } + + /// /// 是否为一楼出库工位 /// @@ -424,7 +456,6 @@ namespace Tnb.WarehouseMgr return input.Size > 0 ? items.Take(input.Size).ToList() : items; } - /// /// 缓存仓出库策略 /// @@ -1816,8 +1847,10 @@ namespace Tnb.WarehouseMgr create_time = DateTime.Now }; List elevatorQueue = await _db.Queryable().Where(it => it.distask_id == disTaskId && it.task_status == "执行中").ToListAsync(); - - if ((elevatorQueue.IsNull() || elevatorQueue.Count < 1) && floorN != eleStatusMulti.curFloorNo) + + Logger.Information($"【CallingLanding】 电梯{devName}状态为{s_eleUseStatusDic[devId]}"); + Logger.Information($"【CallingLanding】 电梯{devName} 任务id{disTaskId} 执行中的队列数量为{elevatorQueue.Count}"); + if ((elevatorQueue.IsNull() || elevatorQueue.Count < 1) && floorN != eleStatusMulti.curFloorNo && s_eleUseStatusDic[devId] == (int)EnumElevatorUseStatus.空闲) { Logger.Information($"【CallingLanding】 判断当前电梯{devName.Match(@"\d+")}#梯 无任务在做执行呼梯"); diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsMaterialTransferService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsMaterialTransferService.cs index afded80b..6ad17597 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsMaterialTransferService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsMaterialTransferService.cs @@ -668,6 +668,17 @@ namespace Tnb.WarehouseMgr throw new AppFriendlyException($@"转库单{wmsMaterialTransfer.bill_code}表体存在未填写工位的明细!", 500); } + var wmsMaterialTransferdsDistinct = wmsMaterialTransferds.Select(r => new + { + material_id = r.material_id, + code_batch = r.code_batch, + }).Distinct(); + if (wmsMaterialTransferdsDistinct.Count() < wmsMaterialTransferds.Count) + { + Logger.LogWarning($@"转库单{wmsMaterialTransfer.bill_code}表体存在物料和批号重复的明细!"); + throw new AppFriendlyException($@"转库单{wmsMaterialTransfer.bill_code}表体存在物料和批号重复的明细!", 500); + } + // 转库单载具子表 List wmsMaterialTransferCarrys = new List(); @@ -979,7 +990,6 @@ namespace Tnb.WarehouseMgr } } - async Task RackInstock_到暂存仓(MaterialTransferRackInstockInput input, WmsCarryH wmsCarryH) { try diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsPackInstockService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsPackInstockService.cs index 4344e0aa..b7961927 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsPackInstockService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsPackInstockService.cs @@ -34,7 +34,7 @@ namespace Tnb.WarehouseMgr { [OverideVisualDev(ModuleConsts.MODULE_WMSPACKINSTOCK_ID)] [ServiceModule(BizTypeId)] - public class WmsPackInstockService : BaseWareHouseService, IWmsPrdReturnService + public class WmsPackInstockService : BaseWareHouseService, IWmsPackInstockService { private const string BizTypeId = WmsWareHouseConst.BIZTYPE_WMSPACKINSTOCK_ID; private readonly ISqlSugarClient _db; diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsPackOutstockService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsPackOutstockService.cs index 376d6d78..9b936443 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsPackOutstockService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsPackOutstockService.cs @@ -1,4 +1,6 @@ -using System.Security.Cryptography.X509Certificates; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using Aspose.Cells; using JNPF.Common.Core.Manager; using JNPF.Common.Dtos.VisualDev; using JNPF.Common.Enums; @@ -11,6 +13,7 @@ using JNPF.VisualDev.Entitys; using JNPF.VisualDev.Interfaces; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.CodeAnalysis; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using NPOI.POIFS.Storage; @@ -31,7 +34,7 @@ namespace Tnb.WarehouseMgr { [OverideVisualDev(ModuleConsts.MODULE_WMSPACKOUTSTOCK_ID)] [ServiceModule(BizTypeId)] - public class WmsPackOutstockService : BaseWareHouseService, IWmsPrdReturnService + public class WmsPackOutstockService : BaseWareHouseService, IWmsPackOutstockService { private const string BizTypeId = WmsWareHouseConst.BIZTYPE_WMSPACKOUTSTOCK_ID; private readonly ISqlSugarClient _db; @@ -72,78 +75,16 @@ namespace Tnb.WarehouseMgr try { - // TODO 二楼工位放货完成后更新出库明细的实际出库数量 - //if (input.wmsDistaskH.start_floor == 2 && input.wmsDistaskH.end_floor == 2) - { - WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == input.wmsDistaskH.carry_id).FirstAsync(); - await _db.Updateable().SetColumns(r => r.prqty == r.prqty + wmsCarryCode.codeqty).Where(r => r.id == input.wmsDistaskH.require_id).ExecuteCommandAsync(); - - CarryCodeUnbindInput carryCodeUnbindInput = new CarryCodeUnbindInput(); - carryCodeUnbindInput.carry_id = input.wmsDistaskH.carry_id; - await _wmsCarryUnbindService.CarryCodeUnbind(carryCodeUnbindInput, _db); - } - - await _db.Ado.CommitTranAsync(); + await _db.Updateable().SetColumns(r => r.line_status == WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).Where(r => r.id == input.wmsDistaskH.require_id).ExecuteCommandAsync(); } catch (Exception ex) { Logger.LogError("【WmsPackOutStockService ModifyAsync】" + ex.Message); Logger.LogError("【WmsPackOutStockService ModifyAsync】" + ex.StackTrace); - await _db.Ado.RollbackTranAsync(); } } - - /// - /// 获取物料库存 - /// - /// - /// - /// - [HttpPost, NonUnify, AllowAnonymous] - public async Task MaterialInventory(MaterialTransferGetMaterialInventoryInput input) - { - try - { - if (input.palletCount <= 0) - { - throw new AppFriendlyException("托盘数必须大于0", 500); - } - if (string.IsNullOrEmpty(input.material_id)) - { - throw new AppFriendlyException("物料id不可为空", 500); - } - if (string.IsNullOrEmpty(input.code_batch)) - { - throw new AppFriendlyException("批号不可为空", 500); - } - - //入库取终点 //出库起点 - OutStockStrategyQuery inStockStrategyInput = new() - { - warehouse_id = WmsWareHouseConst.WAREHOUSE_BCK_ID, - material_id = input.material_id, - code_batch = input.code_batch, - Size = input.palletCount - }; - List items = await _wareHouseService.OutStockStrategyYCL(inStockStrategyInput); - - decimal qty = _db.Queryable().Where(r => items.Select(a => a.id).Contains(r.carry_id) && r.material_id == input.material_id && r.code_batch == input.code_batch).Sum(r => r.codeqty); - - JObject keyValuePairs = new JObject(); - keyValuePairs["realPalletCount"] = items.Count; - keyValuePairs["realInvQty"] = qty; - - return await ToApiResult(HttpStatusCode.OK, "成功", keyValuePairs); - } - catch (Exception ex) - { - await _db.Ado.RollbackTranAsync(); - return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message); - } - } - /// /// 按托下发 /// @@ -151,90 +92,102 @@ namespace Tnb.WarehouseMgr /// /// [HttpPost, NonUnify, AllowAnonymous] - public async Task Distribute(MaterialTransferDistributeInput input) + public async Task Distribute() { - Logger.LogInformation($"【Distribute】 包材出库下发"); + Logger.LogInformation($"【WmsPackOutstockService-Distribute】 包材出库自动下发"); try { - if (string.IsNullOrEmpty(input.source_id)) + OutStockStrategyQuery outStockStrategyInput = new() { - throw new AppFriendlyException("来源单据id不可为空", 500); - } - if (input.palletCount <= 0) + warehouse_id = WmsWareHouseConst.WAREHOUSE_BCK_ID + }; + List carrys = await _wareHouseService.OutStockStrategyYCL(outStockStrategyInput); + if (carrys.Count == 0) { - throw new AppFriendlyException("托盘数必须大于0", 500); - } - if (input.qty <= 0) - { - throw new AppFriendlyException("数量必须大于0", 500); - } - if (string.IsNullOrEmpty(input.code_batch)) - { - throw new AppFriendlyException("批号不可为空", 500); + throw new Exception("【WmsPackOutstockService-Distribute】四楼包材库没有可用的托盘"); } - WmsPackOutstockD wmsPackOutstockD = await _db.Queryable().FirstAsync(it => it.id == input.source_id); - WmsPackOutstockH wmsPackOutstockH = await _db.Queryable().FirstAsync(it => it.id == wmsPackOutstockD.bill_id); - if (wmsPackOutstockD.prqty == wmsPackOutstockD.qty) + InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_F2BCQ_ID, Size = carrys.Count }; + List endLocations = await _wareHouseService.BCKF2InStockStrategy(inStockStrategyInput); + if (endLocations.Count == 0) { - throw new AppFriendlyException("已下发数量已达到出库数量", 500); + throw new AppFriendlyException("【WmsPackOutstockService-Distribute】没有可用的入库库位", 500); } + int 可移转托数 = carrys.Count; + // 如果四楼包材库的可出库托数大于二楼包材库的可入库库位数量,则只入库二楼包材库的可入库库位数量 + if (carrys.Count > endLocations.Count) + { + 可移转托数 = endLocations.Count; + } + + Logger.Information($"【WmsPackOutstockService-Distribute】 四楼包材库的可出库托数为 {carrys.Count} 二楼包材库的可入库库位数量为 {endLocations.Count} 可移转托数为{可移转托数}"); + + // 生成包材出库记录 + + carrys = carrys.Take(可移转托数).ToList(); + + string bill_code = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PACKOUTSTOCK_H_ENCODE); + + WmsPackOutstockH wmsPackOutstockH = new WmsPackOutstockH(); + List wmsCarryCodes = _db.Queryable().Where(r => carrys.Select(r => r.id).Contains(r.carry_id)).ToList(); + + wmsPackOutstockH.org_id = WmsWareHouseConst.AdministratorOrgId; + wmsPackOutstockH.bill_code = bill_code; + wmsPackOutstockH.warehouse_id = WmsWareHouseConst.WAREHOUSE_BCK_ID; + wmsPackOutstockH.create_id = WmsWareHouseConst.AdministratorUserId; + wmsPackOutstockH.create_time = DateTime.Now; + await s_packOutstockSemaphore.WaitAsync(); await _db.Ado.BeginTranAsync(); - //入库取终点 //出库起点 - OutStockStrategyQuery outStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_BCK_ID, material_id = wmsPackOutstockD.material_id, code_batch = input.code_batch, Size = input.palletCount }; - List items = await _wareHouseService.OutStockStrategyYCL(outStockStrategyInput); + List wmsPackOutstockDs = new List(); - if (items.Count == 0) + await _db.Insertable(wmsPackOutstockH).ExecuteCommandAsync(); + + int locationIndex = 0; + for (int i = 0; i < 可移转托数; i++) { - throw new AppFriendlyException($@"没有可以出库的载具", 500); - } - - decimal qty = _db.Queryable().Where(r => items.Select(a => a.id).Contains(r.carry_id) && r.material_id == wmsPackOutstockD.material_id && r.code_batch == input.code_batch).Sum(r => r.codeqty); - - // 暂定PDA上查询到的物料批次和库存数量与提交时获取的不一致时,需要前台重新获取库存接口 - if (input.palletCount != items.Count || input.qty != qty) - { - throw new AppFriendlyException($@"当前实际托盘数量为{input.palletCount} 实际库存数量为{qty},与前台数据不一致,请重新获取库存", HttpStatusCode.InternalServerError); - } - - InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_F2BCQ_ID, Size = input.palletCount }; - List endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput); - if (endLocations.Count == 0) - { - throw new AppFriendlyException("没有可用的入库库位", 500); - } - - if (endLocations.Count() < input.palletCount) - { - throw new AppFriendlyException($@"可用的终点库位数量为{endLocations.Count()}个 下发数量为{input.palletCount}个 请检查终点库位的锁定和占用状态", 500); - } - - foreach (var wmsCarryH in items) - { - WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == wmsCarryH.id).FirstAsync(); - BasLocation startLocation = await _db.Queryable().Where(r => r.id == wmsCarryH.location_id).FirstAsync(); - - InStockStrategyQuery _inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_F2BCQ_ID, Size = 1 }; - List _endLocations = await _wareHouseService.InStockStrategy(_inStockStrategyInput); - - BasLocation endLocation = _endLocations.First(); - if (endLocation == null) + WmsCarryH wmsCarryH = carrys[i]; + WmsCarryCode wmsCarryCode = wmsCarryCodes.Where(r => r.carry_id == wmsCarryH.id).First(); + if (wmsCarryCode == null) { - throw new AppFriendlyException($@"没有可用的终点库位!请检查终点库位的锁定和占用状态", 500); + Logger.Information($"【WmsPackOutstockService-Distribute】载具{wmsCarryH.carry_code}没有绑定物料"); + continue; } + WmsPackOutstockD wmsPackOutstockD = new WmsPackOutstockD(); + wmsPackOutstockD.bill_id = wmsPackOutstockH.id; + wmsPackOutstockD.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID; + wmsPackOutstockD.material_id = wmsCarryCode.material_id; + wmsPackOutstockD.material_code = wmsCarryCode.material_code; + wmsPackOutstockD.material_specification = wmsCarryCode.material_specification; + wmsPackOutstockD.unit_id = wmsCarryCode.unit_id; + wmsPackOutstockD.qty = wmsCarryCode.codeqty; + wmsPackOutstockD.code_batch = wmsCarryCode.code_batch; + wmsPackOutstockD.carry_id = wmsCarryH.id; + wmsPackOutstockD.carry_code = wmsCarryH.carry_code; + wmsPackOutstockD.startlocation_id = wmsCarryH.location_id; + wmsPackOutstockD.startlocation_code = wmsCarryH.location_code; + wmsPackOutstockD.endlocation_id = endLocations[locationIndex].id; + wmsPackOutstockD.endlocation_code = endLocations[locationIndex].location_code; + locationIndex++; + wmsPackOutstockDs.Add(wmsPackOutstockD); + } + await _db.Insertable(wmsPackOutstockDs).ExecuteCommandAsync(); + + + foreach (WmsPackOutstockD wmsPackOutstockD in wmsPackOutstockDs) + { CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput(); - commonCreatePretaskInput.startlocation_id = startLocation.id; - commonCreatePretaskInput.endlocation_id = endLocation.id; + commonCreatePretaskInput.startlocation_id = wmsPackOutstockD.startlocation_id; + commonCreatePretaskInput.endlocation_id = wmsPackOutstockD.endlocation_id; commonCreatePretaskInput.task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID; commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSPACKOUTSTOCK_ID; - commonCreatePretaskInput.require_id = input.source_id; - commonCreatePretaskInput.carry_id = wmsCarryH.id; - commonCreatePretaskInput.carry_code = wmsCarryH.carry_code; + commonCreatePretaskInput.require_id = wmsPackOutstockD.id; + commonCreatePretaskInput.carry_id = wmsPackOutstockD.carry_id; + commonCreatePretaskInput.carry_code = wmsPackOutstockD.carry_code; commonCreatePretaskInput.isExcuteMission = false; Entities.Dto.Outputs.Result res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput, _db); @@ -246,18 +199,15 @@ namespace Tnb.WarehouseMgr } } - // 更新子表已下发数量 - await _db.Updateable().SetColumns(r => r.sendqty == r.sendqty + input.qty).Where(r => r.id == input.source_id).ExecuteCommandAsync(); - await _db.Ado.CommitTranAsync(); - Logger.LogInformation($"【Distribute】 包材出库下发完成"); + Logger.LogInformation($"【Distribute】 包材自动出库下发完成"); } catch (Exception ex) { await _db.Ado.RollbackTranAsync(); Logger.LogError("【Distribute】 包材出库" + ex.Message); Logger.LogError("【Distribute】 包材出库" + ex.StackTrace); - return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message); + return false; } finally { @@ -265,7 +215,8 @@ namespace Tnb.WarehouseMgr InvokeGenPretaskExcute(); } - return await ToApiResult(HttpStatusCode.OK, "成功"); + return true; } + } } diff --git a/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json b/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json index b6af195c..2eadbb03 100644 --- a/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json +++ b/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json @@ -3,7 +3,7 @@ "ConfigId": "default", "DBType": "PostgreSQL", //MySql;SqlServer;Oracle;PostgreSQL;Dm;Kdbndp;Sqlite; //"Host": "192.168.11.109", - "Host": "127.0.0.1", + "Host": "10.147.19.104", "Port": "5432", //"DBName": "tianyi_db", //"UserName": "postgres",