盘点物料库存查询和数量提交

This commit is contained in:
2024-10-31 18:11:49 +08:00
parent b750f2a981
commit 55d79652ba
6 changed files with 369 additions and 1 deletions

View File

@@ -26,4 +26,131 @@ namespace Tnb.WarehouseMgr.Entities.Dto.Inputs
public string location_id { get; set; }
}
/// <summary>
/// 盘点物料查询数量明细
/// </summary>
public class WmsInventoryCheckQtyInput
{
/// <summary>
/// 仓库id
/// </summary>
public string warehouse_id { get; set; }
/// <summary>
/// 物料id
/// </summary>
public string material_id { get; set; }
/// <summary>
/// 批次号
/// </summary>
public string code_batch { get; set; }
}
/// <summary>
/// 盘点物料查询数量明细返回
/// </summary>
public class WmsInventoryCheckSearchOut
{
/// <summary>
/// 物料id
/// </summary>
public string material_id { get; set; }
/// <summary>
/// 物料编码
/// </summary>
public string material_code { get;set; }
/// <summary>
/// 物料名称
/// </summary>
public string material_name { get;set; }
/// <summary>
/// 库位id
/// </summary>
public string location_id { get;set; }
/// <summary>
/// 库位编码
/// </summary>
public string location_code { get; set; }
/// <summary>
/// 批次
/// </summary>
public string code_batch { get;set; }
/// <summary>
/// 物料数量
/// </summary>
public decimal? qty { get; set; }
/// <summary>
/// 物料型号
/// </summary>
public string material_standard { get; set; }
/// <summary>
/// 物料规格
/// </summary>
public string material_specifition { get; set; }
/// <summary>
/// 载具id
/// </summary>
public string carry_id { get; set; }
/// <summary>
/// 载具编号
/// </summary>
public string carry_code { get; set; }
}
/// <summary>
/// 盘点提交
/// </summary>
public class WmsInventoryCheckDSubmitInput
{
/// <summary>
/// 盘点单明细id
/// </summary>
public string checkd_bill_id { get;set; }
public List<WmsInventoryCheckListSubmitInput> details { get; set; }
}
/// <summary>
/// 盘点提交明细列表
/// </summary>
public class WmsInventoryCheckListSubmitInput
{
/// <summary>
/// 物料id
/// </summary>
public string material_id { get;set; }
/// <summary>
/// 批次号
/// </summary>
public string code_batch { get; set; }
/// <summary>
/// 查询数量
/// </summary>
public decimal? qty { get;set; }
/// <summary>
/// 盘点实际数量
/// </summary>
public decimal? check_qty { get; set; }
/// <summary>
/// 库位id
/// </summary>
public string location_id { get; set; }
/// <summary>
/// 库位编码
/// </summary>
public string location_code { get; set; }
/// <summary>
/// 载具id
/// </summary>
public string carry_id { get; set; }
/// <summary>
/// 载具编码
/// </summary>
public string carry_code { get; set; }
}
}

View File

@@ -121,4 +121,16 @@ public partial class WmsInventorycheckD : BaseEntity<string>
/// 辅助属性 小批号
/// </summary>
public string auxprop_xph { get; set; }
/// <summary>
/// 盘点状态0未盘点1已盘点
/// </summary>
public string check_status { get; set; }
/// <summary>
/// 盘点完成时间
/// </summary>
public DateTime? check_time { get; set; }
/// <summary>
/// 盘点人
/// </summary>
public string checker_id { get; set; }
}

View File

@@ -88,6 +88,13 @@ public partial class WmsInventorycheckH : BaseEntity<string>
/// 盘点日期
/// </summary>
public string? check_date { get; set; }
/// <summary>
/// 盘点任务完成状态0未盘点1盘点中2已盘点
/// </summary>
public string? check_status { get; set; }
/// <summary>
/// 盘点完成时间
/// </summary>
public DateTime? check_time { get; set; }
}

View File

@@ -63,5 +63,17 @@ public partial class WmsInventorycheckRecord : BaseEntity<string>
/// 库位编码
/// </summary>
public string? location_code { get; set; }
/// <summary>
/// 批次
/// </summary>
public string? code_batch { get; set; }
/// <summary>
/// 查询数量
/// </summary>
public string? search_qty { get; set; }
/// <summary>
/// 实际盘点数量
/// </summary>
public string? check_qty { get; set; }
}

View File

@@ -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);
}

View File

@@ -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);
}
}
/// <summary>
/// 获取仓库中该物料批次的所有库位库存信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<WmsInventoryCheckSearchOut>> 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<WmsInventoryCheckSearchOut>();
var items = await _db.Queryable<WmsCarryCode>().InnerJoin<WmsCarryH>((a, b) => a.carry_id == b.id)
.InnerJoin<BasLocation>((a, b, c) => b.location_id == c.id).InnerJoin<BasWarehouse>((a, b, c, d) => c.wh_id == d.id)
.LeftJoin<WmsTempCode>((a, b, c, d, e) => e.barcode == a.barcode)
.InnerJoin<BasMaterial>((a, b, c, d, e, f) => f.id == a.material_id)
.LeftJoin<DictionaryDataEntity>((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<WmsCarryCode> carryCodes = await _db.Queryable<WmsCarryCode>()
.InnerJoin<WmsCarryH>((a, b) => a.carry_id == b.id)
.InnerJoin<BasLocation>((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<WmsCarryCode> 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;
}
/// <summary>
/// 修改盘点的物料数量
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<dynamic> SaveCheck(WmsInventoryCheckDSubmitInput input)
{
try
{
if (string.IsNullOrEmpty(input.checkd_bill_id))
throw Oops.Bah("盘点子表id不能为空");
await _db.Ado.BeginTranAsync();
var wmsInventoryCheckD = await _db.Queryable<WmsInventorycheckD>().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<WmsInventorycheckH>().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<WmsInventorycheckD>()
.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<WmsInventorycheckD>().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<WmsInventorycheckH>()
.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<WmsInventorycheckH>()
.SetColumns(r => r.check_status == "2")
.SetColumns(r=>r.check_time==DateTime.Now)
.Where(r => r.id == wmsInventoryCheckH.id).ExecuteCommandAsync();
}
//先删除盘点记录表里面和此物料盘点明细有关的所有记录,再把此次盘点的详情保存到记录表
await _db.Deleteable<WmsInventorycheckRecord>().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<WmsInventorycheckRecord>();
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<Dictionary<string, object>> requestData = new List<Dictionary<string, object>>();
List<string> tableIds = new List<string>();
tableIds.Add(wmsInventoryCheckD.material_id);
List<ErpExtendField> erpExtendFields = await _db.Queryable<ErpExtendField>().Where(x => tableIds.Contains(x.table_id)).ToListAsync();
Dictionary<string, object> erpRequestData = new Dictionary<string, object>();
erpRequestData.Add("cspecialhid", wmsInventoryCheckH.erp_pk);//盘点单主表id
List<Dictionary<string, object>> erpRequestDataDetails = new List<Dictionary<string, object>>();
erpRequestDataDetails.Add(new Dictionary<string, object>()
{
["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<BasFactoryConfig>().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<BasFactoryConfig>().FirstAsync(x => x.enabled == 1 && x.key == FactoryConfigConst.CALLERP);
if (callErp.value == "1")
{
await _thirdApiRecordService.Send(new List<ThirdWebapiRecord> { 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);
}
}
}
}