Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/WmsInventorycheckService.cs

294 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
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;
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_WmsInventorycheck_ID)]
public class WmsInventorycheckService : BaseWareHouseService
{
private readonly ISqlSugarClient _db;
private readonly IDictionaryDataService _dictionaryDataService;
private readonly IUserManager _userManager;
private readonly IWareHouseService _wareHouseService;
private readonly IBillRullService _billRullService;
private readonly IPrdInstockService _prdInstockService;
private readonly IThirdApiRecordService _thirdApiRecordService;
private static Dictionary<string, object> _dicBillCodes = new();
public WmsInventorycheckService(
ISqlSugarRepository<WmsInventorycheckH> repository,
IDictionaryDataService dictionaryDataService,
IUserManager userManager,
IBillRullService billRullService,
IWareHouseService wareHouseService,
IPrdInstockService prdInstockService,
IThirdApiRecordService thirdApiRecordService,
IEventPublisher eventPublisher
)
{
_db = repository.AsSugarClient();
_dictionaryDataService = dictionaryDataService;
_userManager = userManager;
_billRullService = billRullService;
_wareHouseService = wareHouseService;
_thirdApiRecordService = thirdApiRecordService;
_prdInstockService = prdInstockService;
}
/// <summary>
/// 盘点单提交
/// </summary>
/// <param name="input"></param>
/// <exception cref="ArgumentNullException"></exception>
[HttpPost]
public async Task<dynamic> Submit(WmsInventorycheckSubmitInput input)
{
try
{
return await ToApiResult(HttpStatusCode.OK, "成功");
}
catch (PostgresException ex)
{
Logger.LogError(ex.Message);
Logger.LogError(ex.StackTrace);
throw new AppFriendlyException($"{ex.Message}", 500);
}
catch (Exception ex)
{
Logger.LogInformation(ex.Message);
Logger.LogInformation(ex.StackTrace);
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);
}
}
}
}