From 55d79652ba8a45255f2721a46e2b884c5843c1fa Mon Sep 17 00:00:00 2001 From: chenwenkai <1084072318@qq.com> Date: Thu, 31 Oct 2024 18:11:49 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=98=E7=82=B9=E7=89=A9=E6=96=99=E5=BA=93?= =?UTF-8?q?=E5=AD=98=E6=9F=A5=E8=AF=A2=E5=92=8C=E6=95=B0=E9=87=8F=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Inputs/WmsInventorycheckSubmitInput.cs | 127 +++++++++++ .../Entity/WmsInventorycheckD.cs | 12 + .../Entity/WmsInventorycheckH.cs | 9 +- .../Entity/WmsInventorycheckRecord.cs | 12 + .../Tnb.WarehouseMgr/ErpToWmsService.cs | 3 + .../WmsInventorycheckService.cs | 207 ++++++++++++++++++ 6 files changed, 369 insertions(+), 1 deletion(-) diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/WmsInventorycheckSubmitInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/WmsInventorycheckSubmitInput.cs index 607a6067..58652c95 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/WmsInventorycheckSubmitInput.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/WmsInventorycheckSubmitInput.cs @@ -26,4 +26,131 @@ namespace Tnb.WarehouseMgr.Entities.Dto.Inputs public string location_id { get; set; } } + + /// + /// 盘点物料查询数量明细 + /// + public class WmsInventoryCheckQtyInput + { + /// + /// 仓库id + /// + public string warehouse_id { get; set; } + /// + /// 物料id + /// + public string material_id { get; set; } + /// + /// 批次号 + /// + public string code_batch { get; set; } + } + + /// + /// 盘点物料查询数量明细返回 + /// + public class WmsInventoryCheckSearchOut + { + /// + /// 物料id + /// + public string material_id { get; set; } + /// + /// 物料编码 + /// + + public string material_code { get;set; } + /// + /// 物料名称 + /// + + public string material_name { get;set; } + /// + /// 库位id + /// + public string location_id { get;set; } + /// + /// 库位编码 + /// + public string location_code { get; set; } + /// + /// 批次 + /// + public string code_batch { get;set; } + /// + /// 物料数量 + /// + public decimal? qty { get; set; } + /// + /// 物料型号 + /// + public string material_standard { get; set; } + /// + /// 物料规格 + /// + public string material_specifition { get; set; } + /// + /// 载具id + /// + public string carry_id { get; set; } + /// + /// 载具编号 + /// + public string carry_code { get; set; } + } + + /// + /// 盘点提交 + /// + public class WmsInventoryCheckDSubmitInput + { + /// + /// 盘点单明细id + /// + public string checkd_bill_id { get;set; } + + public List details { get; set; } + + } + + /// + /// 盘点提交明细列表 + /// + public class WmsInventoryCheckListSubmitInput + { + /// + /// 物料id + /// + public string material_id { get;set; } + /// + /// 批次号 + /// + public string code_batch { get; set; } + /// + /// 查询数量 + /// + public decimal? qty { get;set; } + /// + /// 盘点实际数量 + /// + public decimal? check_qty { get; set; } + /// + /// 库位id + /// + public string location_id { get; set; } + /// + /// 库位编码 + /// + public string location_code { get; set; } + + /// + /// 载具id + /// + public string carry_id { get; set; } + /// + /// 载具编码 + /// + public string carry_code { get; set; } + } + } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckD.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckD.cs index 276cbab3..f58c9d4f 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckD.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckD.cs @@ -121,4 +121,16 @@ public partial class WmsInventorycheckD : BaseEntity /// 辅助属性 小批号 /// public string auxprop_xph { get; set; } + /// + /// 盘点状态:0未盘点1已盘点 + /// + public string check_status { get; set; } + /// + /// 盘点完成时间 + /// + public DateTime? check_time { get; set; } + /// + /// 盘点人 + /// + public string checker_id { get; set; } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckH.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckH.cs index c3741372..3f275d4f 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckH.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckH.cs @@ -88,6 +88,13 @@ public partial class WmsInventorycheckH : BaseEntity /// 盘点日期 /// public string? check_date { get; set; } - + /// + /// 盘点任务完成状态:0未盘点,1盘点中,2已盘点 + /// + public string? check_status { get; set; } + /// + /// 盘点完成时间 + /// + public DateTime? check_time { get; set; } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckRecord.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckRecord.cs index 0939de14..9d30bd27 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckRecord.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsInventorycheckRecord.cs @@ -63,5 +63,17 @@ public partial class WmsInventorycheckRecord : BaseEntity /// 库位编码 /// public string? location_code { get; set; } + /// + /// 批次 + /// + public string? code_batch { get; set; } + /// + /// 查询数量 + /// + public string? search_qty { get; set; } + /// + /// 实际盘点数量 + /// + public string? check_qty { get; set; } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs b/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs index c5e31e74..2fbe2ad6 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs @@ -2769,6 +2769,7 @@ namespace Tnb.WarehouseMgr wmsInventorycheckH.erp_bill_code = input.erp_bill_code; wmsInventorycheckH.erp_pk = input.erp_pk; wmsInventorycheckH.check_date = input.check_date; + wmsInventorycheckH.check_status = "0"; await db.Insertable(wmsInventorycheckH).ExecuteCommandAsync(); @@ -2822,6 +2823,8 @@ namespace Tnb.WarehouseMgr throw new AppFriendlyException($@"表体明细中组织{detail.auxprop_gys}在wms系统中未找到!", 500); } wmsInventorycheckD.auxprop_xph = detail.auxprop_xph; + wmsInventorycheckD.check_status = "0"; + wmsInventorycheckDs.Add(wmsInventorycheckD); } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsInventorycheckService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsInventorycheckService.cs index e6939215..33458cba 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsInventorycheckService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsInventorycheckService.cs @@ -3,17 +3,24 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Aop.Api.Domain; using JNPF.Common.Core.Manager; using JNPF.Common.Enums; +using JNPF.Common.Security; using JNPF.EventBus; using JNPF.FriendlyException; +using JNPF.Systems.Entitys.System; using JNPF.Systems.Interfaces.System; using JNPF.VisualDev; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using Newtonsoft.Json; using Npgsql; using SqlSugar; +using Tnb.BasicData; +using Tnb.BasicData.Entities; using Tnb.BasicData.Interfaces; +using Tnb.ProductionMgr.Entities.Entity; using Tnb.ProductionMgr.Interfaces; using Tnb.WarehouseMgr.Entities; using Tnb.WarehouseMgr.Entities.Consts; @@ -82,5 +89,205 @@ namespace Tnb.WarehouseMgr return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message); } } + + /// + /// 获取仓库中该物料批次的所有库位库存信息 + /// + /// + /// + [HttpPost] + public async Task> MaterialLocationQty(WmsInventoryCheckQtyInput input) + { + if(string.IsNullOrEmpty(input.material_id)) + throw Oops.Bah("物料id不能为空"); + if (string.IsNullOrEmpty(input.warehouse_id)) + throw Oops.Bah("仓库id不能为空"); + if (string.IsNullOrEmpty(input.code_batch)) + throw Oops.Bah("物料批次不能为空"); + + var result=new List(); + + var items = await _db.Queryable().InnerJoin((a, b) => a.carry_id == b.id) + .InnerJoin((a, b, c) => b.location_id == c.id).InnerJoin((a, b, c, d) => c.wh_id == d.id) + .LeftJoin((a, b, c, d, e) => e.barcode == a.barcode) + .InnerJoin((a, b, c, d, e, f) => f.id == a.material_id) + .LeftJoin((a, b, c, d, e, f, g) => g.EnCode == f.unit_id && g.DictionaryTypeId == WmsWareHouseConst.UNITTYPEID) + .Where((a, b, c, d, e, f) => c.is_type == ((int)EnumLocationType.存储库位).ToString() + && d.id == input.warehouse_id + && a.material_id == input.material_id + && a.code_batch==input.code_batch + ) + .Select((a, b, c, d, e, f, g) => new WmsInventoryCheckSearchOut + { + material_code=a.material_code, + material_name = f.name, + material_id = f.id, + location_id = c.id, + location_code=c.location_code, + code_batch = a.code_batch, + material_specifition=f.material_specification, + material_standard=f.material_standard, + qty=0, + carry_id=a.carry_id, + carry_code=b.carry_code + }, true).ToListAsync(); + + List carryCodes = await _db.Queryable() + .InnerJoin((a, b) => a.carry_id == b.id) + .InnerJoin((a, b, c) => b.location_id == c.id).Where((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString() && c.wh_id == input.warehouse_id && a.material_id == input.material_id && a.code_batch==input.code_batch).Select((a, b, c) => new WmsCarryCode + { + warehouse_id = c.wh_id + }, true).ToListAsync(); + + var storeMap = items.DistinctBy(x => new { x.material_id, x.location_id, x.code_batch }).ToDictionary(x => new { x.material_id, x.location_id, x.code_batch }, x => x); + + var group = items.GroupBy(g => new { g.material_id, g.location_id, g.code_batch }); + + foreach (var itGroup in group) + { + _ = storeMap.TryGetValue(itGroup.Key, out WmsInventoryCheckSearchOut? stockReport); + + List curCarryCodes = carryCodes.FindAll(x => x.material_id == itGroup.Key.material_id + && x.location_id == itGroup.Key.location_id && x.code_batch == itGroup.Key.code_batch); + stockReport.qty = 0; + curCarryCodes.ForEach(x => + { + stockReport.qty += x.codeqty; + }); + result.Add(stockReport); + } + + return result; + } + + /// + /// 修改盘点的物料数量 + /// + /// + [HttpPost] + public async Task SaveCheck(WmsInventoryCheckDSubmitInput input) + { + try + { + if (string.IsNullOrEmpty(input.checkd_bill_id)) + throw Oops.Bah("盘点子表id不能为空"); + + await _db.Ado.BeginTranAsync(); + var wmsInventoryCheckD = await _db.Queryable().Where(r => r.id == input.checkd_bill_id).FirstAsync(); + if (wmsInventoryCheckD == null) + throw Oops.Bah($"盘点单子表id:{input.checkd_bill_id}数据不存在"); + if (wmsInventoryCheckD.check_status == "1") + throw Oops.Bah($"该盘点单已完成盘点,不能重复盘点"); + var wmsInventoryCheckH = await _db.Queryable().Where(r => r.id == wmsInventoryCheckD.bill_id).FirstAsync(); + //汇总实际数量 + decimal actual_qty = (input.details != null && input.details.Count > 0) ? input.details.Sum(r => (r.check_qty.HasValue ? r.check_qty.Value : 0)) : 0; + + await _db.Updateable() + .SetColumns(r => r.actual_qty == actual_qty) + .SetColumns(r => r.check_time == DateTime.Now) + .SetColumns(r => r.checker_id == _userManager.UserId) + .SetColumns(r=>r.check_status=="1") + .Where(r => r.id == wmsInventoryCheckD.id).ExecuteCommandAsync(); + //查找到盘点任务单下面所有的物料明细 + var noChecks = await _db.Queryable().Where(r => r.bill_id == wmsInventoryCheckH.id).ToListAsync(); + + if(noChecks!=null && noChecks.Where(r=>r.check_status=="0" || string.IsNullOrEmpty(r.check_status)).Count()>0) //存在还没完成盘点的物料明细 + { + await _db.Updateable() + .SetColumns(r => r.check_status == "1") + .Where(r => r.id == wmsInventoryCheckH.id).ExecuteCommandAsync(); + } + else if(noChecks != null && noChecks.Where(r => r.check_status == "0" || string.IsNullOrEmpty(r.check_status)).Count() == 0) //盘点任务单下的物料明细都已盘点完成,任务单状态变成已盘点 + { + await _db.Updateable() + .SetColumns(r => r.check_status == "2") + .SetColumns(r=>r.check_time==DateTime.Now) + .Where(r => r.id == wmsInventoryCheckH.id).ExecuteCommandAsync(); + } + //先删除盘点记录表里面和此物料盘点明细有关的所有记录,再把此次盘点的详情保存到记录表 + await _db.Deleteable().Where(r => r.bill_id == wmsInventoryCheckH.id && r.mat_bill_id == wmsInventoryCheckD.id).ExecuteCommandAsync(); + if(input.details!=null && input.details.Count > 0) + { + var WmsInventorycheckRecords=new List(); + + foreach (var item in input.details) + { + var record = new WmsInventorycheckRecord() + { + create_id = _userManager.UserId, + create_time = DateTime.Now, + bill_id = wmsInventoryCheckH.id, + mat_bill_id = wmsInventoryCheckD.id, + carry_id = item.carry_id, + carry_code = item.carry_code, + location_id = item.location_id, + location_code = item.location_code, + code_batch = item.code_batch, + search_qty = item.qty.HasValue ? item.qty.Value.ToString() : "0", + check_qty = item.check_qty.HasValue ? item.check_qty.Value.ToString() : "0" + }; + WmsInventorycheckRecords.Add(record); + } + await _db.Insertable(WmsInventorycheckRecords).ExecuteCommandAsync(); + } + + + #region 调用bip接口 + List> requestData = new List>(); + List tableIds = new List(); + tableIds.Add(wmsInventoryCheckD.material_id); + List erpExtendFields = await _db.Queryable().Where(x => tableIds.Contains(x.table_id)).ToListAsync(); + Dictionary erpRequestData = new Dictionary(); + + erpRequestData.Add("cspecialhid", wmsInventoryCheckH.erp_pk);//盘点单主表id + List> erpRequestDataDetails = new List>(); + erpRequestDataDetails.Add(new Dictionary() + { + ["cspecialbid"] = wmsInventoryCheckD.erp_line_pk, //盘点单子表id + ["cspeciallid"] = wmsInventoryCheckH.erp_pk, //盘点单主表id + ["crowno"] = wmsInventoryCheckD.lineno, //行号 + ["ncountnum"] = actual_qty, //实际盘点总数量 + ["cmaterialoid"] = erpExtendFields.Find(x => x.table_id == wmsInventoryCheckD.material_id)?.cmaterialoid ?? null, //物料id + }); + erpRequestData.Add("dtls", erpRequestDataDetails); + requestData.Add(erpRequestData); + + BasFactoryConfig config = await _db.Queryable().FirstAsync(x => x.enabled == 1 && x.key == FactoryConfigConst.BIPURL); + + ThirdWebapiRecord thirdWebapiRecord = new ThirdWebapiRecord(); + thirdWebapiRecord.id = SnowflakeIdHelper.NextId(); + thirdWebapiRecord.third_name = WmsWareHouseConst.BIP; + thirdWebapiRecord.name = "盘点单"; + thirdWebapiRecord.method = "POST"; + thirdWebapiRecord.url = config.value + "uapws/rest/InvCount/save"; + //thirdWebapiRecord.url = WmsWareHouseConst.BIP_DOMAIN + "uapws/rest/InvCount/save"; + thirdWebapiRecord.request_data = JsonConvert.SerializeObject(requestData); + thirdWebapiRecord.create_time = DateTime.Now; + thirdWebapiRecord.remark = "【WmsInventorycheckService SubmitCheck】盘点单主表id:" + wmsInventoryCheckH.id + ",盘点单子表id:" + wmsInventoryCheckD.id; + + await _db.Insertable(thirdWebapiRecord).ExecuteCommandAsync(); + + BasFactoryConfig callErp = await _db.Queryable().FirstAsync(x => x.enabled == 1 && x.key == FactoryConfigConst.CALLERP); + if (callErp.value == "1") + { + await _thirdApiRecordService.Send(new List { thirdWebapiRecord }, "自动", _db); + } + + #endregion + + await _db.Ado.CommitTranAsync(); + + return await ToApiResult(HttpStatusCode.OK, "成功"); + } + catch (Exception ex) + { + await _db.Ado.RollbackTranAsync(); + Logger.LogInformation(ex.Message); + Logger.LogInformation(ex.StackTrace); + return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message); + } + } + + } }