From eadaa50ef787d67e73d7db11da1e851b558ca470 Mon Sep 17 00:00:00 2001 From: majian <780924089@qq.com> Date: Tue, 14 May 2024 15:29:18 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=80=E5=94=AE=E5=87=BA=E5=BA=93=E4=B8=8E?= =?UTF-8?q?=E6=8B=A3=E8=B4=A7=E6=8E=A5=E5=8F=A3=E4=BB=A5=E5=8F=8A=E9=83=A8?= =?UTF-8?q?=E5=88=86=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/BasLocation.cs | 4 + .../Tnb.ProductionMgr/RedisBackGround.cs | 41 +- .../Consts/ModuleConsts.cs | 13 + .../Consts/WmsWareHouseConst.cs | 12 + .../Dto/Inputs/CarryCodeUnbindInput.cs | 14 + .../Inputs/FinishproductOutstockSignInput.cs | 14 +- .../Dto/Inputs/OutsourcedPartsInstockInput.cs | 8 +- .../Dto/Inputs/SaleReleaseDistributeInput.cs | 25 ++ .../Dto/Inputs/TransferInstockHListInput.cs | 13 + .../Dto/Queries/OutStockStrategyQuery.cs | 5 + .../Entity/WmsSortingtask.cs | 77 ++++ .../Entity/WmsTransferInstockD .cs | 108 +++++ .../Entity/WmsTransferInstockH.cs | 79 ++++ .../IWareHouseService.cs | 15 + .../IWmsCarryBindService.cs | 1 + .../Tnb.WarehouseMgr/TaskManagerDelBase.cs | 3 + .../TransferInstockHService.cs | 113 +++++ .../Tnb.WarehouseMgr/WareHouseService.cs | 104 ++++- .../Tnb.WarehouseMgr/WmsCarryBindService.cs | 48 ++- .../WmsPDACarryBindService.cs | 101 ++--- .../Tnb.WarehouseMgr/WmsSaleReleaseService.cs | 388 ++++++++++++++++++ .../Tnb.WarehouseMgr/WmsSortingtaskService.cs | 93 +++++ 22 files changed, 1195 insertions(+), 84 deletions(-) create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/CarryCodeUnbindInput.cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/SaleReleaseDistributeInput.cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TransferInstockHListInput.cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsSortingtask.cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsTransferInstockD .cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsTransferInstockH.cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr/TransferInstockHService.cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr/WmsSaleReleaseService.cs create mode 100644 WarehouseMgr/Tnb.WarehouseMgr/WmsSortingtaskService.cs diff --git a/BasicData/Tnb.BasicData.Entities/Entity/BasLocation.cs b/BasicData/Tnb.BasicData.Entities/Entity/BasLocation.cs index 03c249a9..3944284a 100644 --- a/BasicData/Tnb.BasicData.Entities/Entity/BasLocation.cs +++ b/BasicData/Tnb.BasicData.Entities/Entity/BasLocation.cs @@ -126,4 +126,8 @@ public partial class BasLocation : BaseEntity /// 是否超配(1:不超配 2:超配) /// public string is_overmatch { get; set; } = "1"; + /// + /// 任务数 + /// + public int task_nums { get; set; } } diff --git a/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs b/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs index d7129edf..3c2bb8a7 100644 --- a/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs +++ b/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs @@ -826,12 +826,13 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA // 找到AGV已到货,没有机械臂确认的数据 ISugarQueryable WmsMechanicalArmHsuagar = db.Queryable() .Where(r => r.agvconfirm == 1 && r.mechanicalconfirm == 0 && configs_upMachine.Contains(r.name)); + LoggerFloor2UpDownMachine.LogInformation($@"【检查机械臂料架区信号_下升降机满托1送到】 {WmsMechanicalArmHsuagar.Count()}"); foreach (WmsMechanicalArmH wmsMechanicalArmH in WmsMechanicalArmHsuagar.ToList()) { // 尝试写入满托送到信号 bool result上升降机空托送到 = await Floor2UpDownMachinecode_SetTag($"下升降机满托{wmsMechanicalArmH.stackingposition}送到", "true"); - LoggerFloor2UpDownMachine.LogInformation($@"【送满托到上升降区】回写 下升降机满托{wmsMechanicalArmH.stackingposition}送到 结果为{result上升降机空托送到}"); + LoggerFloor2UpDownMachine.LogInformation($@"【送满托到下升降区】回写 下升降机满托{wmsMechanicalArmH.stackingposition}送到 结果为{result上升降机空托送到}"); if (!result上升降机空托送到) { return false; @@ -840,10 +841,10 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA int LXCount = db.Queryable() .Where(a => a.carry_id == wmsMechanicalArmH.rackid).Count(); bool result = await Floor2UpDownMachinecode_SetTag($"下升降机满托{wmsMechanicalArmH.stackingposition}数量", LXCount.ToString()); - LoggerFloor2UpDownMachine.LogInformation($@"【送满托到上升降区】设定下升降机满托{wmsMechanicalArmH.stackingposition}满托数量为 {LXCount} 结果为 {result}"); + LoggerFloor2UpDownMachine.LogInformation($@"【送满托到下升降区】设定下升降机满托{wmsMechanicalArmH.stackingposition}满托数量为 {LXCount} 结果为 {result}"); if (!result) { - throw new Exception($@"【送满托到上升降区】设定升降机满托{wmsMechanicalArmH.stackingposition}满托数量为 {LXCount} 结果为 {result}"); + throw new Exception($@"【送满托到下升降区】设定升降机满托{wmsMechanicalArmH.stackingposition}满托数量为 {LXCount} 结果为 {result}"); } // 绑定料架 @@ -1113,8 +1114,8 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA string[] configs_upMachine = new string[2] { "二楼上升降机机械臂左", "二楼上升降机机械臂右" }; // 读取上升降机的左右料架区配置 - List WmsMechanicalArmHs = _repository.AsSugarClient().Queryable().Where(r => r.stackingcount == r.maxnum && r.maxnum != 0 && !string.IsNullOrEmpty(r.rackcode) && r.iscreatepretask == 0 && configs_upMachine.Contains(r.name)).ToList(); - + List WmsMechanicalArmHs = _repository.AsSugarClient().Queryable().Where(r => r.stackingcount == r.maxnum && r.maxnum != 0 && !string.IsNullOrEmpty(r.rackcode) && r.iscreatepretask == 0 && configs_upMachine.Contains(r.name) && r.mechanicalconfirm == 1).ToList(); + foreach (WmsMechanicalArmH wmsMechanicalArmH in WmsMechanicalArmHs) { await s_taskExecuteRackDelivery.WaitAsync(); @@ -1123,9 +1124,9 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA { // 判断是否 上升降机请求取满托 bool 上升降机请求取满托 = (bool)Floor2UpDownMachinecode_GetTag($"上升降机请求取满托{wmsMechanicalArmH.stackingposition}"); + LoggerFloor2RackDelivery.LogError($"【移走上升降区满托的料架】上升降机请求取满托{wmsMechanicalArmH.stackingposition} {上升降机请求取满托}"); if (!上升降机请求取满托) { - LoggerFloor2RackDelivery.LogError($"【移走上升降区满托的料架】上升降机请求取满托{wmsMechanicalArmH.stackingposition} {上升降机请求取满托}"); return false; } @@ -1197,6 +1198,10 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA LoggerFloor2RackDelivery.LogError(ex.ToString()); LoggerFloor2RackDelivery.LogError(ex.StackTrace); } + finally + { + s_taskExecuteRackDelivery.Release(); + } } return true; } @@ -1222,9 +1227,9 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA { // 判断是否 上升降机请求取满托 bool 下升降机请求取空托 = (bool)Floor2UpDownMachinecode_GetTag($"下升降机请求取空托{wmsMechanicalArmH.stackingposition}"); + LoggerFloor2RackDelivery.LogError($"【移走下升降区空托的料架】下升降机请求取空托{wmsMechanicalArmH.stackingposition} {下升降机请求取空托}" ); if (!下升降机请求取空托) { - LoggerFloor2RackDelivery.LogError($"【移走下升降区空托的料架】下升降机请求取空托{wmsMechanicalArmH.stackingposition}"); return false; } LoggerFloor2RackDelivery.LogInformation($"【移走下升降区空托的料架】 开始执行预任务生成 {wmsMechanicalArmH.point_code} {wmsMechanicalArmH.outbill} {wmsMechanicalArmH.barcodes}"); @@ -1436,7 +1441,7 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA ["Value"] = value, }; string result = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand); - // TODO 测试 + // 测试 //JObject valueJson = new JObject(); //valueJson["Value"] = value; @@ -1451,17 +1456,17 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA public Task StartAsync(CancellationToken cancellationToken) { - //Readtimer = new Timer(GetRedisData, null, TimeSpan.Zero, TimeSpan.FromSeconds(300)); - //CheckGettimer = new Timer(CheckGet, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); - //Scantimer = new Timer(ScanInStock, null, TimeSpan.Zero, TimeSpan.FromSeconds(60)); - //SSXcodetimer = new Timer(SSXcode, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); + Readtimer = new Timer(GetRedisData, null, TimeSpan.Zero, TimeSpan.FromSeconds(300)); + CheckGettimer = new Timer(CheckGet, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); + Scantimer = new Timer(ScanInStock, null, TimeSpan.Zero, TimeSpan.FromSeconds(60)); + SSXcodetimer = new Timer(SSXcode, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); - //// 二楼上升降机 - //Floor2UpMachinecodetimer = new Timer(Floor2UpMachinecode, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); - //// 二楼下升降机 - ////Floor2DownMachinecodetimer = new Timer(Floor2DownMachinecode, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); - //// 二楼料架配送 - //Floor2RackDeliverytimer = new Timer(Floor2RackDelivery, null, TimeSpan.Zero, TimeSpan.FromSeconds(60)); + // 二楼上升降机 + Floor2UpMachinecodetimer = new Timer(Floor2UpMachinecode, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); + // 二楼下升降机 + //Floor2DownMachinecodetimer = new Timer(Floor2DownMachinecode, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); + // 二楼料架配送 + Floor2RackDeliverytimer = new Timer(Floor2RackDelivery, null, TimeSpan.Zero, TimeSpan.FromSeconds(30)); return Task.CompletedTask; } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/ModuleConsts.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/ModuleConsts.cs index 49e67eac..5c5478d3 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/ModuleConsts.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/ModuleConsts.cs @@ -209,4 +209,17 @@ public class ModuleConsts /// public const string MODLUE_WMSTASKSTOCK_ID = "27690726707477"; + /// + /// 模块标识-销售出库 + /// + public const string MODULE_WMSSALERELEASE_ID = "25104446664213"; + /// + /// 模块标识-分拣任务 + /// + public const string MODULE_WMSSORTINGTASK_ID = "34088685351445"; + /// + /// 模块标识-成品调拨入库单 + /// + public const string MODULE_WMSTRANSFERINSTOCKH_ID = "34154749548053"; + } \ No newline at end of file diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs index 27767775..5ccb9bcf 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs @@ -203,6 +203,10 @@ /// public const string BIZTYPE_WMSDELIVERY_ID = "26585291847957"; /// + /// 预任务生成业务类型-销售出库下发(未定) TODO + /// + public const string BIZTYPE_WMSSALERELEASE_ID = "BIZTYPE_WMSSALERELEASE_ID"; + /// /// 预任务生成业务类型-载具绑定 /// public const string BIZTYPE_WMSCARRYBIND_ID = "27118595509525"; @@ -211,6 +215,10 @@ /// public const string BIZTYPE_WMSCHECKOUTSTOCK_ID = "27718132310037"; + /// + /// 成品调拨入库 + /// + public const string BIZTYPE_WMSTRANSFERINSTOCK_ID = "34154749548053"; /// /// 条码打印状态-已完成 @@ -302,5 +310,9 @@ /// 一楼成品出库工位 /// public const string FinishproductOutstockStation3 = "30018217822229"; + /// + /// 分拣任务生成Encode + /// + public const string WMS_SORTINGTASK_ENCODE = "Sortingtask"; } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/CarryCodeUnbindInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/CarryCodeUnbindInput.cs new file mode 100644 index 00000000..292ced50 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/CarryCodeUnbindInput.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tnb.WarehouseMgr.Entities.Dto.Inputs +{ + public class CarryCodeUnbindInput + { + public string? carry_id { get; set; } + + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/FinishproductOutstockSignInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/FinishproductOutstockSignInput.cs index 5793bed0..43cf8a79 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/FinishproductOutstockSignInput.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/FinishproductOutstockSignInput.cs @@ -6,18 +6,8 @@ public class FinishproductOutstockSortInput { /// - /// 载具id + /// 分拣任务id /// - public string? carry_id { get; set; } - - ///// - ///// 物料id - ///// - //public string? material_id { get; set; } - - /// - /// 数量 - /// - public decimal qty { get; set; } + public string? source_id { get; set; } } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/OutsourcedPartsInstockInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/OutsourcedPartsInstockInput.cs index 00a452d1..a954b603 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/OutsourcedPartsInstockInput.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/OutsourcedPartsInstockInput.cs @@ -8,7 +8,7 @@ /// /// 载具ID /// - public string? carry_id { get; set; } + public string? carry_code { get; set; } /// /// 物料ID /// @@ -21,5 +21,11 @@ /// 起点 /// public string? startlocation_id { get; set; } + /// + /// 需求单据 + /// + public string? source_id { get; set; } + + } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/SaleReleaseDistributeInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/SaleReleaseDistributeInput.cs new file mode 100644 index 00000000..58231e60 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/SaleReleaseDistributeInput.cs @@ -0,0 +1,25 @@ +namespace Tnb.WarehouseMgr.Entities.Dto +{ + /// + /// 库房业务更新输入参数 + /// + public class SaleReleaseDistributeInput + { + /// + /// 组织ID + /// + public string org_id { get; set; } + /// + /// 创建用户 + /// + public string create_id { get; set; } + /// + /// 物料数量 + /// + public decimal qty { get; set; } + /// + /// 来源单据id + /// + public string? source_id { get; set; } + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TransferInstockHListInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TransferInstockHListInput.cs new file mode 100644 index 00000000..86acf6a5 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TransferInstockHListInput.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tnb.WarehouseMgr.Entities.Dto.Inputs +{ + public class TransferInstockHListInput + { + public string? id { get; set; } + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Queries/OutStockStrategyQuery.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Queries/OutStockStrategyQuery.cs index d4728162..775456e7 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Queries/OutStockStrategyQuery.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Queries/OutStockStrategyQuery.cs @@ -28,6 +28,11 @@ public int BllType { get; set; } public int Size { get; set; } + + /// + /// 数量 + /// + public decimal qty { get; set; } /// /// 规格型号 /// diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsSortingtask.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsSortingtask.cs new file mode 100644 index 00000000..1e5f5422 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsSortingtask.cs @@ -0,0 +1,77 @@ +using JNPF.Common.Contracts; +using JNPF.Common.Security; +using SqlSugar; + +namespace Tnb.WarehouseMgr.Entities; + +/// +/// 分拣任务主表 +/// +[SugarTable("wms_sortingtask")] +public partial class WmsSortingtask : BaseEntity +{ + public WmsSortingtask() + { + id = SnowflakeIdHelper.NextId(); + } + /// + /// 所属组织 + /// + public string? org_id { get; set; } + + /// + /// 分拣任务单号 + /// + public string bill_code { get; set; } + + /// + /// 分拣数量 + /// + public decimal qty { get; set; } + + /// + /// 分拣数量 + /// + public string carry_id { get; set; } + + /// + /// 分拣指定载具 + /// + public string carry_code { get; set; } + + /// + /// 分拣指定库位id + /// + public string location_id { get; set; } + + /// + /// 分拣指定库位 + /// + public string location_code { get; set; } + + /// + /// 状态 + /// + public string status { get; set; } + + /// + /// 分拣完成时间 + /// + public DateTime complete_time { get; set; } + + /// + /// 创建用户 + /// + public string create_id { get; set; } = string.Empty; + + /// + /// 创建时间 + /// + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// 来源单据id + /// + public string source_id { get; set; } = string.Empty; + +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsTransferInstockD .cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsTransferInstockD .cs new file mode 100644 index 00000000..81355be6 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsTransferInstockD .cs @@ -0,0 +1,108 @@ +using JNPF.Common.Contracts; +using JNPF.Common.Security; +using SqlSugar; + +namespace Tnb.WarehouseMgr.Entities.Entity; + +///  +/// 成品调拨入库子表 +///  +[SugarTable("wms_transfer_instock_d")] +public partial class WmsTransferInstockD : BaseEntity +{ + public WmsTransferInstockD() + { + id = SnowflakeIdHelper.NextId(); + } +    ///  +    /// 所属组织 +    ///  +    public string? org_id { get; set; } + +    ///  +    /// 入库单ID +    ///  +    public string? bill_id { get; set; } + +    ///  +    /// 执行状态 +    ///  +    public string? status { get; set; } + +    ///  +    /// 物品ID +    ///  +    public string? material_id { get; set; } + +    ///  +    /// 物品代码 +    ///  +    public string? material_code { get; set; } + +    ///  +    /// 单位ID +    ///  +    public string? unit_id { get; set; } + +    ///  +    /// 单位代码 +    ///  +    public string? unit_code { get; set; } + +    ///  +    /// 入库需求数量 +    ///  +    public decimal? pr_qty { get; set; } + +    ///  +    /// 已下发数量 +    ///  +    public decimal? xf_qty { get; set; } + +    ///  +    /// 实际入库数量 +    ///  +    public decimal? qty { get; set; } + +    ///  +    /// 流程任务Id +    ///  +    public string? f_flowtaskid { get; set; } + +    ///  +    /// 流程引擎Id +    ///  +    public string? f_flowid { get; set; } + +    ///  +    /// 规格型号 +    ///  +    public string? material_desc { get; set; } + +    ///  +    /// 创建用户 +    ///  +    public string? create_id { get; set; } + +    ///  +    /// 创建时间 +    ///  +    public DateTime? create_time { get; set; } + +    ///  +    /// 修改用户 +    ///  +    public string? modify_id { get; set; } + +    ///  +    /// 修改时间 +    ///  +    public DateTime? modify_time { get; set; } + +    ///  +    /// 批号 +    ///  +    public string? pi_code { get; set; } + +} + diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsTransferInstockH.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsTransferInstockH.cs new file mode 100644 index 00000000..b1603b85 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsTransferInstockH.cs @@ -0,0 +1,79 @@ +using JNPF.Common.Contracts; +using JNPF.Common.Security; +using SqlSugar; + +namespace Tnb.WarehouseMgr.Entities.Entity; + +///  +/// 成品调拨入库主表 +///  +[SugarTable("wms_transfer_instock_h")] +public partial class WmsTransferInstockH : BaseEntity +{ + public WmsTransferInstockH() + { + id = SnowflakeIdHelper.NextId(); + } +    ///  +    /// 创建用户 +    ///  +    public string? create_id { get; set; } + +    ///  +    /// 创建时间 +    ///  +    public DateTime? create_time { get; set; } + +    ///  +    /// 修改用户 +    ///  +    public string? modify_id { get; set; } + +    ///  +    /// 修改时间 +    ///  +    public DateTime? modify_time { get; set; } + +    ///  +    /// 所属组织 +    ///  +    public string? org_id { get; set; } + +    ///  +    /// 流程任务Id +    ///  +    public string? f_flowtaskid { get; set; } + +    ///  +    /// 流程引擎Id +    ///  +    public string? f_flowid { get; set; } + +    ///  +    /// 审核员 +    ///  +    public string? auditor_id { get; set; } + +    ///  +    /// 审核状态 +    ///  +    public int? audit_status { get; set; } + + +    ///  +    /// 入库单号 +    ///  +    public string? bill_code { get; set; } + +    ///  +    /// 入库单创建日期 +    ///  +    public DateTime? bill_date { get; set; } + +    ///  +    /// 单据状态 +    ///  +    public string? status { get; set; } + +} + diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs index 77886b53..2eaf6e40 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs @@ -24,6 +24,13 @@ namespace Tnb.WarehouseMgr.Interfaces /// /// Task> OutStockStrategy([FromQuery] OutStockStrategyQuery input); + + /// + /// 出库策略-销售出库下发 + /// + /// + /// + Task>> OutStockStrategy_saleRelease([FromQuery] OutStockStrategyQuery input); /// /// 路径算法 /// @@ -31,6 +38,14 @@ namespace Tnb.WarehouseMgr.Interfaces /// /// Task> PathAlgorithms(string pStartId, string pEndId); + + /// + /// 是否为一楼出库工位 + /// + /// + /// + string[] GetFloor1OutstockLocation(); + /// /// 生成预任务 /// diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsCarryBindService.cs b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsCarryBindService.cs index 22a13c86..97a07702 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsCarryBindService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWmsCarryBindService.cs @@ -12,5 +12,6 @@ namespace Tnb.WarehouseMgr.Interfaces Task CarryBindFloor2UpDownMachine(CarryBindFloor2UpDownMachineInput input); Task CarryUnbindFloor2UpDownMachine(CarryBindFloor2UpDownMachineInput input); + Task CarryCodeUnbind(CarryCodeUnbindInput input); } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/TaskManagerDelBase.cs b/WarehouseMgr/Tnb.WarehouseMgr/TaskManagerDelBase.cs index f96951ed..5e77d8ff 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/TaskManagerDelBase.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/TaskManagerDelBase.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using SqlSugar; using Tnb.BasicData.Entities; +using Tnb.ProductionMgr.Entities; using Tnb.WarehouseMgr.Entities; using Tnb.WarehouseMgr.Entities.Dto.Inputs; using Tnb.WarehouseMgr.Entities.Entity; @@ -41,6 +42,8 @@ namespace Tnb.WarehouseMgr } _ = await _db.Deleteable(preTask).ExecuteCommandAsync(); _ = await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums - 1).Where(it => it.area_code == preTask.area_code).ExecuteCommandAsync(); + _ = await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => preTask.endlocation_id == it.id).ExecuteCommandAsync(); + } await _db.Ado.CommitTranAsync(); } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/TransferInstockHService.cs b/WarehouseMgr/Tnb.WarehouseMgr/TransferInstockHService.cs new file mode 100644 index 00000000..4af4c78d --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr/TransferInstockHService.cs @@ -0,0 +1,113 @@ +using System.Dynamic; +using JNPF.Common.Core.Manager; +using JNPF.Common.Dtos.VisualDev; +using JNPF.Common.Enums; +using JNPF.Common.Extension; +using JNPF.Common.Filter; +using JNPF.Common.Security; +using JNPF.FriendlyException; +using JNPF.Systems.Entitys.Permission; +using JNPF.Systems.Interfaces.System; +using JNPF.VisualDev; +using JNPF.VisualDev.Entitys; +using JNPF.VisualDev.Entitys.Dto.VisualDevModelData; +using JNPF.VisualDev.Interfaces; +using Mapster; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NPOI.SS.Formula.Functions; +using Senparc.Weixin.MP.AdvancedAPIs.Card; +using SqlSugar; +using Tnb.EquipMgr; +using Tnb.EquipMgr.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.Entity; +using Tnb.WarehouseMgr.Entities.Enums; +using Tnb.WarehouseMgr.Interfaces; +using Top.Api; + +namespace Tnb.WarehouseMgr +{ + /// + /// 载具绑定 + /// + [OverideVisualDev(ModuleConsts.MODULE_WMSTRANSFERINSTOCKH_ID)] + public class TransferInstockHService : BaseWareHouseService + { + + private readonly ISqlSugarClient _db; + private readonly IRunService _runService; + private readonly IVisualDevService _visualDevService; + private readonly IUserManager _userManager; + private readonly IBillRullService _billRullService; + public TransferInstockHService( + ISqlSugarRepository repository, + IRunService runService, + IVisualDevService visualDevService, + IUserManager userManager, + IBillRullService billRullService) + { + _db = repository.AsSugarClient(); + _runService = runService; + _visualDevService = visualDevService; + _userManager = userManager; + _billRullService = billRullService; + //OverideFuncs.GetListAsync = GetList; + + + } + + [NonAction] + private async Task GetList(VisualDevModelListQueryInput input) + { + try + { + SqlSugarPagedList result = await _db.Queryable() + .ToPagedListAsync(input.currentPage, input.pageSize); + + var _data = PageResult.SqlSugarPageResult(result); + var json = JsonConvert.SerializeObject(_data); + var data = JsonConvert.DeserializeObject(json); + JArray mainTable = data.list; + + ISugarQueryable wmsTransferInstockDs = _db.Queryable().Where(r => mainTable.Select(r => r["id"].ToString()).ToList().Contains(r.bill_id)); + + foreach (JObject wmsTransferInstockH in mainTable) + { + wmsTransferInstockH["tablefield105"] = JArray.Parse(JsonConvert.SerializeObject(wmsTransferInstockDs.Where(r => r.bill_id == wmsTransferInstockH["id"].ToString()).ToList())); + } + return data; + } + catch(Exception ex) + { + return Task.FromResult(ex); + } + } + + + [HttpPost, NonUnify, AllowAnonymous] + public async Task List(TransferInstockHListInput input) + { + try + { + JObject jobject = new JObject(); + jobject["code"] = "200"; + + List wmsTransferInstockDs = _db.Queryable().Where(r => r.bill_id == input.id && r.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).ToList(); + + + jobject["data"] = JArray.Parse(JsonConvert.SerializeObject(wmsTransferInstockDs)); + return await Task.FromResult(jobject); + } + catch (Exception ex) + { + return Task.FromResult(ex); + } + } + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs index 4a7dbc22..9db3f2e1 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Dynamic; +using System.Linq; using System.Linq.Expressions; using System.Net; using System.Security.Policy; @@ -26,6 +27,7 @@ using NetTaste; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NPOI.OpenXmlFormats.Dml; +using NPOI.SS.Formula.Functions; using Org.BouncyCastle.Crypto; using SqlSugar; using Tnb.BasicData.Entities; @@ -57,6 +59,7 @@ namespace Tnb.WarehouseMgr private readonly IUserManager _userManager; private readonly ICacheManager _cacheManager; private readonly IElevatorControlService _elevatorControlService; + private readonly IWmsCarryBindService _wmsCarryBindService; private static readonly Dictionary _elevatorAgvCtlStatusMap = new(StringComparer.OrdinalIgnoreCase); private readonly ElevatorControlConfiguration _eleCtlCfg = App.Configuration.Build(); private static Dictionary locMap = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -67,7 +70,8 @@ namespace Tnb.WarehouseMgr public WareHouseService(ISqlSugarRepository repository, IDictionaryDataService dictionaryDataService, RedisData redisData, - IBillRullService billRullService, IUserManager userManager, ICacheManager cacheManager, IElevatorControlService elevatorControlService + IBillRullService billRullService, IUserManager userManager, ICacheManager cacheManager, IElevatorControlService elevatorControlService, + IWmsCarryBindService wmsCarryBindService //IConfiguration configuration ) : base(repository.AsSugarClient()) { @@ -78,6 +82,7 @@ namespace Tnb.WarehouseMgr _cacheManager = cacheManager; _elevatorControlService = elevatorControlService; _redisData = redisData; + _wmsCarryBindService = wmsCarryBindService; //_configuration = configuration; } @@ -205,11 +210,76 @@ namespace Tnb.WarehouseMgr } return items.Take(input.Size).ToList(); } + /// - /// 出库策略 + /// 是否为一楼出库工位 + /// + /// + /// + public string[] GetFloor1OutstockLocation() + { + return new string[3] { WmsWareHouseConst.FinishproductOutstockStation1 , WmsWareHouseConst.FinishproductOutstockStation2 + , WmsWareHouseConst.FinishproductOutstockStation3 }; + } + + /// + /// 出库策略-销售出库下发 /// /// [HttpGet] + public async Task>> OutStockStrategy_saleRelease([FromQuery] OutStockStrategyQuery input) + { + Expressionable whereExprable = Expressionable.Create() + .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) + .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) + .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) + .And((a, b, c) => a.out_status == "0") + .And((a, b, c) => c.wh_id == input.warehouse_id) + .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) + .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) + .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) + .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) + .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); + Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() + ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() + : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); + _ = whereExprable.And(carryStatusFilterExp); + Expression> whereExpr = whereExprable.ToExpression(); + + SqlSugarClient cyDb = _db.CopyNew(); + + + + List> items = cyDb.Queryable().LeftJoin((a, b) => a.id == b.carry_id) + .LeftJoin((a, b, c) => a.location_id == c.id) + .Where(whereExpr) + //.OrderByIF((a,b,c)=>SqlFunc.IsNullOrEmpty()) + .OrderBy("a.location_code,layers,loc_line,loc_column") + .Select((a, b, c) => new + { + WmsCarryH = a, + WmsCarryCode = b, + BasLocation = c, + codeqty = b.codeqty + }).ToList().Select(r => + { + input.qty = input.qty - r.codeqty; + + // 出库数量与托盘上的数量不一致需要进行分拣 + if (input.qty < 0) + { + r.WmsCarryCode.codeqty = input.qty + r.codeqty; + return new Tuple("分拣任务", r.WmsCarryH, r.WmsCarryCode, r.BasLocation); + } + else + { + // 正常预任务出库 + return new Tuple("预任务", r.WmsCarryH, r.WmsCarryCode, r.BasLocation); + } + }).ToList(); + return items; + } + public async Task> OutStockStrategy([FromQuery] OutStockStrategyQuery input) { Expressionable whereExprable = Expressionable.Create() @@ -565,7 +635,7 @@ namespace Tnb.WarehouseMgr ["Value"] = value, }; string result = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand); - // TODO 测试 + // 测试 //JObject valueJson = new JObject(); //valueJson["Value"] = value; @@ -1610,6 +1680,30 @@ namespace Tnb.WarehouseMgr */ //更新业务主表的单据状态 foreach (WmsDistaskH? dt in disTasks) { + // 销售出库 + if (dt.biz_type == WmsWareHouseConst.BIZTYPE_WMSSALERELEASE_ID) + { + // TODO 一楼工位放货完成后更新出库明细的实际出库数量 + if (dt.start_floor == 1 && dt.end_floor == 1) + { + WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == dt.carry_id).FirstAsync(); + await _db.Updateable().SetColumns(r => r.purchase_prqty == r.purchase_prqty + wmsCarryCode.codeqty).Where(r => r.id == dt.require_id).ExecuteCommandAsync(); + + CarryCodeUnbindInput carryCodeUnbindInput = new CarryCodeUnbindInput(); + carryCodeUnbindInput.carry_id = dt.carry_id; + await _wmsCarryBindService.CarryCodeUnbind(carryCodeUnbindInput); + } + } + else if (dt.biz_type == WmsWareHouseConst.BIZTYPE_WMSTRANSFERINSTOCK_ID) + { + if (dt.start_floor == 3 && dt.end_floor == 3) + { + WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == dt.carry_id).FirstAsync(); + await _db.Updateable().SetColumns(r => r.qty == r.qty + wmsCarryCode.codeqty).Where(r => r.id == dt.require_id).ExecuteCommandAsync(); + } + } + + List disTaskCodes = await _db.Queryable().Where(it => it.bill_id == dt.id).ToListAsync(); WareHouseUpInput upInput = new() { bizTypeId = dt.biz_type, requireId = dt.require_id!, distaskCodes = disTaskCodes, carryIds = disTasks.Select(x => x.carry_id).ToList() }; @@ -1712,6 +1806,10 @@ namespace Tnb.WarehouseMgr row = await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => it.area_code == eleP.area_code).ExecuteCommandAsync(); } + // 累加终点库位任务数 + row = await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1) + .Where(it => preTasks.Select(r => r.endlocation_id).Contains(it.id)).ExecuteCommandAsync(); + return row > 0; } /// diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryBindService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryBindService.cs index 5f3cded8..22223571 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryBindService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryBindService.cs @@ -47,8 +47,10 @@ namespace Tnb.WarehouseMgr _userManager = userManager; _billRullService = billRullService; OverideFuncs.CreateAsync = CarryBind; - + + } + [NonAction] public async Task CarryBind(VisualDevModelDataCrInput input) { @@ -264,7 +266,49 @@ namespace Tnb.WarehouseMgr } return Task.FromResult(true); } - + + /// + /// 二楼机械手解绑定 + /// + /// + /// + /// + /// + [NonAction] + public async Task CarryCodeUnbind(CarryCodeUnbindInput input) + { + bool isOk = false; + try + { + if (input == null) + { + throw new ArgumentNullException(nameof(input)); + } + + WmsCarryH? carry = await _db.Queryable().SingleAsync(it => it.id == input.carry_id); + if (carry != null) + { + int row = await _db.Deleteable().Where(r => r.carry_id == input.carry_id).ExecuteCommandAsync(); + isOk = row > 0; + + if (!isOk) + { + throw Oops.Oh(ErrorCode.COM1001); + } + } + else + { + if (carry == null) + { + throw new AppFriendlyException("没有可用的主载具", 500); + } + } + } + catch (Exception ex) + { + } + return Task.FromResult(true); + } /* public override async Task ModifyAsync(WareHouseUpInput input) { if (input == null) throw new ArgumentNullException(nameof(input)); diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsPDACarryBindService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsPDACarryBindService.cs index e79d5bf2..0bdbd943 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsPDACarryBindService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsPDACarryBindService.cs @@ -15,6 +15,7 @@ using Tnb.BasicData.Entities; using Tnb.WarehouseMgr.Entities; using Tnb.WarehouseMgr.Entities.Consts; using Tnb.WarehouseMgr.Entities.Dto; +using Tnb.WarehouseMgr.Entities.Entity; using Tnb.WarehouseMgr.Entities.Enums; using Tnb.WarehouseMgr.Interfaces; @@ -151,35 +152,56 @@ namespace Tnb.WarehouseMgr { try { - if (string.IsNullOrEmpty(input.carry_id)) + if (string.IsNullOrEmpty(input.carry_code)) { - throw new AppFriendlyException("载具id不可为空", 500); + throw new AppFriendlyException("载具编号不可为空", 500); } if (string.IsNullOrEmpty(input.material_id)) { - throw new AppFriendlyException("物料不可为空", 500); + throw new AppFriendlyException("物料id不可为空", 500); } if (input.qty <= 0) { throw new AppFriendlyException("数量必须大于0", 500); } + if (string.IsNullOrEmpty(input.source_id)) + { + throw new AppFriendlyException("成品调拨明细id不可为空", 500); + } if (string.IsNullOrEmpty(input.startlocation_id)) { throw new AppFriendlyException("起点不可为空", 500); } + WmsTransferInstockD wmsTransferInstockD = await _db.Queryable().Where(r => r.id == input.source_id).FirstAsync(); + if (wmsTransferInstockD.status == WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID) + { + throw new AppFriendlyException("此成品调拨任务已完成,不允许重复提交", 500); + } await s_taskExecuteSemaphore.WaitAsync(); await _db.Ado.BeginTranAsync(); //入库取终点 //出库起点 InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_CP_ID, Size = 1 }; List endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput); + if (endLocations.Count == 0) + { + throw new AppFriendlyException("没有可用的入库库位", 500); + } WmsPointH sPoint = null!; WmsPointH ePoint = null!; sPoint = await _db.Queryable().FirstAsync(it => it.location_id == input.startlocation_id); if (endLocations?.Count > 0) { - WmsCarryH carry = await _db.Queryable().SingleAsync(it => it.id == input.carry_id); + WmsCarryH carry = await _db.Queryable().SingleAsync(it => it.carry_code == input.carry_code); + if (carry.carry_status == "1") + { + throw new AppFriendlyException("载具已占用!", 500); + } + if (carry.is_lock == 1) + { + throw new AppFriendlyException("载具已锁定!", 500); + } BasLocation loc = await _db.Queryable().SingleAsync(it => it.id == endLocations[0].id); bool isMatch = await IsCarryAndLocationMatchByCarryStd(carry, loc); if (!isMatch) @@ -220,7 +242,7 @@ namespace Tnb.WarehouseMgr points.Add(ePoint); } - WmsCarryH wmsCarryH = await _db.Queryable().FirstAsync(it => it.id == input.carry_id); + WmsCarryH wmsCarryH = await _db.Queryable().FirstAsync(it => it.carry_code == input.carry_code); //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) if (points?.Count > 0) { @@ -244,14 +266,14 @@ namespace Tnb.WarehouseMgr endpoint_code = ePoint?.point_code!, bill_code = _billRullService!.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(), status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID, - biz_type = WmsWareHouseConst.BIZTYPE_WMSDELIVERY_ID, + biz_type = WmsWareHouseConst.BIZTYPE_WMSTRANSFERINSTOCK_ID, task_type = WmsWareHouseConst.WMS_PRETASK_TRANSFER_TYPE_ID }; - preTask.carry_id = input.carry_id; + preTask.carry_id = wmsCarryH.id; preTask.carry_code = wmsCarryH.carry_code; preTask.area_id = sPoint?.area_id!; preTask.area_code = it.Key; - preTask.require_id = ""; + preTask.require_id = input.source_id; preTask.require_code = ""; preTask.create_id = _userManager.UserId; preTask.create_time = DateTime.Now; @@ -272,7 +294,7 @@ namespace Tnb.WarehouseMgr is_lock = 1, location_id = input.startlocation_id, location_code = location.location_code - }).Where(it => it.id == input.carry_id).ExecuteCommandAsync(); + }).Where(it => it.id == wmsCarryH.id).ExecuteCommandAsync(); } //所有库位加锁 @@ -281,7 +303,7 @@ namespace Tnb.WarehouseMgr BasMaterial basMaterial = await _db.Queryable().FirstAsync(it => it.id == input.material_id); WmsCarryCode wmsCarryCode = new WmsCarryCode(); - wmsCarryCode.carry_id = input.carry_id; + wmsCarryCode.carry_id = wmsCarryH.id; wmsCarryCode.barcode = wmsCarryH.carry_code; wmsCarryCode.codeqty = input.qty; wmsCarryCode.material_id = input.material_id; @@ -289,16 +311,34 @@ namespace Tnb.WarehouseMgr wmsCarryCode.material_name = basMaterial.name; wmsCarryCode.location_id = endLocations[0].id; wmsCarryCode.location_code = endLocations[0].location_code; + wmsCarryCode.code_batch = wmsTransferInstockD.pi_code; _ = await _db.Insertable(wmsCarryCode).ExecuteCommandAsync(); } } } } + // 更新成品调拨入库单子表已下发数量 + await _db.Updateable().SetColumns(r => r.xf_qty == r.xf_qty + input.qty).Where(r => r.id == input.source_id).ExecuteCommandAsync(); + + // 已下发数量达到需求数量回写已完成 + wmsTransferInstockD = await _db.Queryable().Where(r => r.id == input.source_id).FirstAsync(); + if (wmsTransferInstockD.xf_qty == wmsTransferInstockD.pr_qty) + { + await _db.Updateable().SetColumns(r => r.status == WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).Where(r => r.id == input.source_id).ExecuteCommandAsync(); + } + + // 入库明细都完成 回写主表完成状态 + List wmsTransferInstockDs =_db.Queryable().InnerJoin((a, b) => a.bill_id == b.bill_id).Where((a, b) => a.id == input.source_id) + .Where((a, b) => b.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).ToList(); + if (wmsTransferInstockDs.Count == 0) + { + await _db.Updateable().SetColumns(r =>r.status == WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).Where(r => r.id == wmsTransferInstockD.bill_id).ExecuteCommandAsync(); + } await _db.Ado.CommitTranAsync(); } - catch (Exception) + catch (Exception ex) { await _db.Ado.RollbackTranAsync(); throw; @@ -325,8 +365,7 @@ namespace Tnb.WarehouseMgr throw new AppFriendlyException("起点id不可为空", 500); } - if (input.location_id != WmsWareHouseConst.FinishproductOutstockStation1 && input.location_id != WmsWareHouseConst.FinishproductOutstockStation2 - && input.location_id != WmsWareHouseConst.FinishproductOutstockStation3) + if (!_wareHouseService.GetFloor1OutstockLocation().Contains(input.location_id)) { throw new AppFriendlyException("非一楼出库库位不允许通过此功能解锁", 500); } @@ -356,40 +395,6 @@ namespace Tnb.WarehouseMgr return await ToApiResult(HttpStatusCode.OK, "成功"); } - /// - /// 3楼到1楼出库 盘点签收 解锁一楼库位 - /// - /// - /// - [HttpPost, NonUnify, AllowAnonymous] - public async Task FinishproductOutstockSort(FinishproductOutstockSortInput input) - { - if (string.IsNullOrEmpty(input.carry_id)) - { - throw new AppFriendlyException("载具id不可为空", 500); - } - if (input.qty <= 0) - { - throw new AppFriendlyException("数量必须大于0", 500); - } - - await _db.Ado.BeginTranAsync(); - try - { - await _db.Updateable().SetColumns(r => new WmsCarryCode - { - codeqty = input.qty, - }).Where(r => r.carry_id == input.carry_id).ExecuteCommandAsync(); - - await _db.Ado.CommitTranAsync(); - } - catch (Exception ex) - { - await _db.Ado.RollbackTranAsync(); - throw; - } - - return await ToApiResult(HttpStatusCode.OK, "成功"); - } + } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsSaleReleaseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsSaleReleaseService.cs new file mode 100644 index 00000000..ff94d00f --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsSaleReleaseService.cs @@ -0,0 +1,388 @@ +using System.Security.Cryptography.X509Certificates; +using JNPF.Common.Core.Manager; +using JNPF.Common.Dtos.VisualDev; +using JNPF.Common.Enums; +using JNPF.Common.Extension; +using JNPF.Common.Security; +using JNPF.EventBus; +using JNPF.FriendlyException; +using JNPF.Systems.Interfaces.System; +using JNPF.VisualDev; +using JNPF.VisualDev.Entitys; +using JNPF.VisualDev.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.CodeAnalysis; +using NPOI.HSSF.Record; +using NPOI.SS.Formula; +using SqlSugar; +using Tnb.BasicData.Entities; +using Tnb.BasicData.Interfaces; +using Tnb.WarehouseMgr.Entities; +using Tnb.WarehouseMgr.Entities.Attributes; +using Tnb.WarehouseMgr.Entities.Consts; +using Tnb.WarehouseMgr.Entities.Dto; +using Tnb.WarehouseMgr.Entities.Dto.Inputs; +using Tnb.WarehouseMgr.Entities.Entity; +using Tnb.WarehouseMgr.Entities.Enums; +using Tnb.WarehouseMgr.Interfaces; + +namespace Tnb.WarehouseMgr +{ + /// + /// 销售出库服务 + /// + [OverideVisualDev(ModuleConsts.MODULE_WMSSALERELEASE_ID)] + [ServiceModule(BizTypeId)] + public class WmsSaleReleaseService : BaseWareHouseService, IPdaStroage + { + private const string BizTypeId = "25104446664213"; + private readonly ISqlSugarClient _db; + private readonly IRunService _runService; + private readonly IVisualDevService _visualDevService; + private readonly IBasLocationService _basLocationService; + private readonly IWareHouseService _wareHouseService; + private readonly IBillRullService _billRullService; + private readonly IUserManager _userManager; + private readonly IWmsCarryBindService _wmsCarryBindService; + public WmsSaleReleaseService( + ISqlSugarRepository repository, + IRunService runService, + IVisualDevService visualDevService, + IBasLocationService basLocationService, + IBillRullService billRullService, + IWareHouseService wareHouseService, + IUserManager userManager, + IEventPublisher eventPublisher, + IWmsCarryBindService wmsCarryBindService + ) + { + _db = repository.AsSugarClient(); + _runService = runService; + _visualDevService = visualDevService; + _basLocationService = basLocationService; + _billRullService = billRullService; + _wareHouseService = wareHouseService; + _userManager = userManager; + _wmsCarryBindService = wmsCarryBindService; + + OverideFuncs.GetDetailsAsync = GetDetailsAsync; + //OverideFuncs.CreateAsync = Create; + } + + + + [NonAction] + private async Task GetDetailsAsync(string id) + { + try + { + return await Task.FromResult(_db.Queryable().Where(r => r.bill_id == id).ToList()); + } + catch (Exception ex) + { + return Task.FromResult(ex); + } + } + + + /// + /// 根据载具编号获取起始库位点 + /// + /// + /// + public async Task GetUnStoreLocationListByCarryId([FromRoute] string carryId) + { + var items = await _db!.Queryable().LeftJoin((a, b) => a.location_id == b.id) + .Where(a => a.id == carryId) + .Select((a, b) => new + { + a.carry_code, + b.location_code, + }) + .ToListAsync(); + return items; + } + + private async Task Create(VisualDevModelDataCrInput input) + { + return await Task.FromResult(true); + } + public override async Task ModifyAsync(WareHouseUpInput input) + { + if (input == null) + { + throw new ArgumentNullException(nameof(input)); + } + + int row = await _db.Updateable().SetColumns(it => new WmsDelivery { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync(); + if (row < 1) + { + throw Oops.Oh(ErrorCode.COM1001); + } + } + + + + /// + /// 下发 + /// + /// + /// + /// + [HttpPost, NonUnify, AllowAnonymous] + public async Task Distribute(SaleReleaseDistributeInput input) + { + try + { + if (input.qty <= 0) + { + throw new AppFriendlyException("数量必须大于0", 500); + } + if (string.IsNullOrEmpty(input.source_id)) + { + throw new AppFriendlyException("来源单据id不可为空", 500); + } + + WmsSaleD wmsOutstockD = await _db.Queryable().FirstAsync(it => it.id == input.source_id); + await s_taskExecuteSemaphore.WaitAsync(); + await _db.Ado.BeginTranAsync(); + //入库取终点 //出库起点 + OutStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_CP_ID, material_id = wmsOutstockD.material_id, qty = input.qty, code_batch = wmsOutstockD.code_batch }; + List> items = await _wareHouseService.OutStockStrategy_saleRelease(inStockStrategyInput); + + decimal canOutstockQty = items.Sum(r => r.Item3.codeqty).ParseToDecimal(); + if (canOutstockQty < input.qty) + { + throw new AppFriendlyException($@"当前可出库数量只有 {canOutstockQty}", 500); + } + + List> items_sorttask = items.Where(r => r.Item1 == "分拣任务").ToList(); + List> items_pretask = items.Where(r => r.Item1 == "预任务").ToList(); + + // 预任务逻辑 + foreach (Tuple item in items_pretask) + { + WmsCarryH carry = item.Item2; + WmsCarryCode carryCode = item.Item3; + BasLocation startLocation = item.Item4; + // 根据一楼工位任务数平均分配任务 确定一楼工位 + BasLocation endLocation = await _db.Queryable().Where(r => _wareHouseService.GetFloor1OutstockLocation().Contains(r.id)).OrderBy("is_lock, task_nums, location_code").FirstAsync(); + + WmsPointH sPoint = null!; + WmsPointH ePoint = null!; + + sPoint = await _db.Queryable().FirstAsync(it => it.location_id == startLocation.id); + + bool isMatch = await IsCarryAndLocationMatchByCarryStd(carry, endLocation); + if (!isMatch) + { + throw new AppFriendlyException("库位与载具规格不匹配", 500); + } + + ePoint = await _db.Queryable().FirstAsync(it => it.location_id == endLocation.id); + + if (ePoint != null) + { + } + else + { + throw new AppFriendlyException($"库位{endLocation.location_code}未在点位表中维护对应点位", 500); + } + + + string endLocationId = endLocation.id; + + // 在线开发 + //VisualDevEntity? templateEntity = await _visualDevService?.GetInfoById(ModuleConsts.MODULE_WMSDELIVERYPDA_ID, true)!; + //await _runService.Create(templateEntity, input); + + // 计算路径,插入预任务申请 + + if (sPoint != null && ePoint != null) + { + List points = new List(); + if (sPoint.area_code != ePoint.area_code) + { + points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id); + if (points.Count <= 2) + { + throw new AppFriendlyException("该路径不存在", 500); + } + } + else + { + points.Add(sPoint); + points.Add(ePoint); + } + + //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) + if (points?.Count > 0) + { + List 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(), + startpoint_id = sPoint?.id!, + startpoint_code = sPoint?.point_code!, + endpoint_id = ePoint?.id!, + endpoint_code = ePoint?.point_code!, + bill_code = _billRullService!.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(), + status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID, + biz_type = WmsWareHouseConst.BIZTYPE_WMSSALERELEASE_ID, + task_type = WmsWareHouseConst.WMS_PRETASK_TRANSFER_TYPE_ID + }; + preTask.carry_id = carry.id; + preTask.carry_code = carry.carry_code; + preTask.area_id = sPoint?.area_id!; + preTask.area_code = it.Key; + preTask.require_id = input.source_id; + preTask.require_code = ""; + preTask.create_id = _userManager.UserId; + preTask.create_time = DateTime.Now; + return preTask; + }).ToList(); + bool isOk = await _wareHouseService.GenPreTask(preTasks, null!); + if (isOk) + { + if (endLocationId != null) + { + //查询库位表 + BasLocation location = await _db.Queryable().SingleAsync(it => it.id == startLocation.id); + { + //载具加锁,增加库位信息 + _ = await _db.Updateable().SetColumns(it => new WmsCarryH + { + carry_status = ((int)EnumCarryStatus.占用).ToString(), + is_lock = 1, + location_id = startLocation.id, + location_code = location.location_code + }).Where(it => it.id == carry.id).ExecuteCommandAsync(); + } + + //所有库位加锁 + string?[] ids = new[] { startLocation.id, endLocationId }; + _ = await _db.Updateable().SetColumns(it => new BasLocation { is_lock = 1 }).Where(it => ids.Contains(it.id)).ExecuteCommandAsync(); + + } + } + } + + } + } + + // 分拣任务逻辑 + foreach (Tuple item in items_sorttask) + { + WmsCarryH carry = item.Item2; + WmsCarryCode carryCode = item.Item3; + BasLocation startLocation = item.Item4; + + // 锁定分拣载具 + await _db.Updateable().SetColumns(r => r.is_lock == 1).Where(r => r.id == carry.id).ExecuteCommandAsync(); + + Dictionary dic = new() + { + [nameof(WmsSortingtask.id)] = SnowflakeIdHelper.NextId(), + [nameof(WmsSortingtask.bill_code)] = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_SORTINGTASK_ENCODE), + [nameof(WmsSortingtask.org_id)] = input.org_id ?? _userManager.User.OrganizeId, + [nameof(WmsSortingtask.qty)] = carryCode.codeqty, + [nameof(WmsSortingtask.carry_id)] = carry.id, + [nameof(WmsSortingtask.carry_code)] = carry.carry_code, + [nameof(WmsSortingtask.status)] = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID, + [nameof(WmsSortingtask.location_id)] = startLocation.id, + [nameof(WmsSortingtask.location_code)] = startLocation.location_code, + [nameof(WmsSortingtask.create_id)] = input.create_id ?? _userManager.UserId, + [nameof(WmsSortingtask.create_time)] = DateTime.Now, + [nameof(WmsSortingtask.source_id)] = input.source_id + }; + + VisualDevModelDataCrInput visualDevModelDataCrInput = new() + { + data = dic + }; + + //在线开发 + VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSSORTINGTASK_ID, false); + await _runService.Create(templateEntity, visualDevModelDataCrInput); + } + + // 更新销售出库单子表已下发数量 + await _db.Updateable().SetColumns(r => r.purchase_arriveqty == r.purchase_arriveqty + input.qty).Where(r => r.id == input.source_id).ExecuteCommandAsync(); + + await _db.Ado.CommitTranAsync(); + } + catch (Exception ex) + { + await _db.Ado.RollbackTranAsync(); + throw; + } + finally + { + _ = s_taskExecuteSemaphore.Release(); + await InvokeGenPretaskExcute(); + } + + return await ToApiResult(HttpStatusCode.OK, "成功"); + } + + /// + /// 分拣 + /// + /// + /// + [HttpPost, NonUnify, AllowAnonymous] + public async Task Sort(FinishproductOutstockSortInput input) + { + if (string.IsNullOrEmpty(input.source_id)) + { + throw new AppFriendlyException("分拣任务id不能为空", 500); + } + + await _db.Ado.BeginTranAsync(); + try + { + WmsSortingtask wmsSortingtask = await _db.Queryable().Where(r => r.id == input.source_id).FirstAsync(); + if (wmsSortingtask.status == WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID) + { + throw new AppFriendlyException("此分拣任务已完成,不允许重复提交", 500); + } + // 解锁分拣载具 + await _db.Updateable().SetColumns(r => r.is_lock == 0).Where(r => r.id == wmsSortingtask.carry_id).ExecuteCommandAsync(); + // 扣减载具物料库存 + await _db.Updateable().SetColumns(r => r.codeqty == r.codeqty - wmsSortingtask.qty).Where(r => r.carry_id == wmsSortingtask.carry_id).ExecuteCommandAsync(); + + await _db.Updateable().SetColumns(r => new WmsSortingtask + { + status = WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID, + complete_time = DateTime.Now + }).Where(r => r.id == wmsSortingtask.id).ExecuteCommandAsync(); + // 改为销售出库单 + await _db.Updateable().SetColumns(r => r.purchase_prqty == r.purchase_prqty + wmsSortingtask.qty).Where(r => r.id == wmsSortingtask.source_id).ExecuteCommandAsync(); + //await _db.Updateable().SetColumns(r => new WmsCarryCode + //{ + // codeqty = input.qty, + //}).Where(r => r.carry_id == input.carry_id).ExecuteCommandAsync(); + + await _db.Ado.CommitTranAsync(); + } + catch (Exception ex) + { + await _db.Ado.RollbackTranAsync(); + throw; + } + + return await ToApiResult(HttpStatusCode.OK, "成功"); + } + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsSortingtaskService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsSortingtaskService.cs new file mode 100644 index 00000000..f372af58 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsSortingtaskService.cs @@ -0,0 +1,93 @@ +using JNPF.Common.Core.Manager; +using JNPF.Common.Dtos.VisualDev; +using JNPF.Common.Enums; +using JNPF.Common.Extension; +using JNPF.EventBus; +using JNPF.FriendlyException; +using JNPF.Systems.Interfaces.System; +using JNPF.VisualDev; +using JNPF.VisualDev.Entitys; +using JNPF.VisualDev.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; +using Tnb.BasicData.Entities; +using Tnb.BasicData.Interfaces; +using Tnb.WarehouseMgr.Entities; +using Tnb.WarehouseMgr.Entities.Attributes; +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 +{ + /// + /// 销售出库服务 + /// + [OverideVisualDev(ModuleConsts.MODULE_WMSSORTINGTASK_ID)] + [ServiceModule(BizTypeId)] + public class WmsSortingtaskService : BaseWareHouseService, IPdaStroage + { + private const string BizTypeId = "34088685351445"; + private readonly ISqlSugarClient _db; + private readonly IRunService _runService; + private readonly IVisualDevService _visualDevService; + private readonly IBasLocationService _basLocationService; + private readonly IWareHouseService _wareHouseService; + private readonly IBillRullService _billRullService; + private readonly IUserManager _userManager; + private readonly IWmsCarryBindService _wmsCarryBindService; + public WmsSortingtaskService( + ISqlSugarRepository repository, + IRunService runService, + IVisualDevService visualDevService, + IBasLocationService basLocationService, + IBillRullService billRullService, + IWareHouseService wareHouseService, + IUserManager userManager, + IEventPublisher eventPublisher + ) + { + _db = repository.AsSugarClient(); + _runService = runService; + _visualDevService = visualDevService; + _basLocationService = basLocationService; + _billRullService = billRullService; + _wareHouseService = wareHouseService; + _userManager = userManager; + + OverideFuncs.CreateAsync = Create; + } + + private async Task Create(VisualDevModelDataCrInput input) + { + //在线开发 + try + { + VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSSORTINGTASK_ID, true); + await _runService.Create(templateEntity, input); + } + catch (Exception) + { + throw; + } + return Task.FromResult(1); + } + public override async Task ModifyAsync(WareHouseUpInput input) + { + if (input == null) + { + throw new ArgumentNullException(nameof(input)); + } + + int row = await _db.Updateable().SetColumns(it => new WmsDelivery { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync(); + if (row < 1) + { + throw Oops.Oh(ErrorCode.COM1001); + } + } + + } +}