using Admin.NET.Core.Service; using Admin.NET.Application.Entity; using Microsoft.AspNetCore.Http; using System.Data; using System.Web; using System.Text; using Mapster; using Admin.NET.Application.CommonHelper; namespace Admin.NET.Application; /// /// 容器库位关系服务 /// [ApiDescriptionSettings(ApplicationConst.WmsStockQuanGroupName, Order = 100)] public class WmsContainerPlaceService : IDynamicApiController, ITransient { private readonly SqlSugarRepository _rep; private readonly SqlSugarRepository _wmsContainerRep; private readonly SqlSugarRepository _wmsPlaceRep; private readonly SqlSugarRepository _wmsStockQuanRep; private readonly SqlSugarRepository _v_wms_stock_quanRep; private readonly SqlSugarRepository _wmsBaseBusinessTypeRep; private readonly SqlSugarRepository _wmsLogActionRep; private readonly SqlSugarRepository _wmsRecordTransRep; public WmsContainerPlaceService( SqlSugarRepository rep, SqlSugarRepository wmsContainerRep, SqlSugarRepository wmsPlaceRep, SqlSugarRepository wmsStockQuanRep, SqlSugarRepository v_wms_stock_quanRep, SqlSugarRepository wmsBaseBusinessTypeRep, SqlSugarRepository wmsLogActionRep, SqlSugarRepository wmsRecordTransRep) { _rep = rep; _wmsContainerRep = wmsContainerRep; _wmsPlaceRep = wmsPlaceRep; _wmsStockQuanRep = wmsStockQuanRep; _v_wms_stock_quanRep = v_wms_stock_quanRep; _wmsBaseBusinessTypeRep = wmsBaseBusinessTypeRep; _wmsLogActionRep = wmsLogActionRep; _wmsRecordTransRep = wmsRecordTransRep; } /// /// 分页查询容器库位关系 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Page")] [Description("WmsContainerPlace/Page")] public async Task> Page(WmsContainerPlaceInput input) { var query = CommonPageFilter(input); return await query.OrderBuilder(input, "", "Id").ToPagedListAsync(input.Page, input.PageSize); } /// /// 不分页查询容器库位关系 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "List")] [Description("WmsContainerPlace/List")] public async Task> List([FromQuery] WmsContainerPlaceInput input) { var query = CommonPageFilter(input); return await query.OrderBuilder(input, "", "Id").Select().ToListAsync(); } /// /// 增加容器库位关系 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Add")] [Description("WmsContainerPlace/Add")] public async Task Add(AddWmsContainerPlaceInput input) { var entity = input.Adapt(); //重复性验证 await CheckExist(entity); await _rep.InsertAsync(entity); return entity.Id; } /// /// 删除容器库位关系 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Delete")] [Description("WmsContainerPlace/Delete")] public async Task Delete(DeleteWmsContainerPlaceInput input) { var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); //await _rep.FakeDeleteAsync(entity); //假删除 await _rep.DeleteAsync(entity); //真删除 } /// /// 更新容器库位关系 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Update")] [Description("WmsContainerPlace/Update")] public async Task Update(UpdateWmsContainerPlaceInput input) { var entity = input.Adapt(); //重复性验证 await CheckExist(entity, true); await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } /// /// 获取容器库位关系 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "Detail")] [Description("WmsContainerPlace/Detail")] public async Task Detail([FromQuery] QueryByIdWmsContainerPlaceInput input) { return await _rep.GetFirstAsync(u => u.Id == input.Id); } #region 库位解绑 /// /// 扫描容器带出库存信息 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "ContainerStock")] [Description("WmsContainerPlace/ContainerStock")] public async Task ContainerStock([FromQuery] ContainerStockInput input) { //查询容器信息 var containerModel = await _wmsContainerRep.AsQueryable().Where(z => z.ContainerCode == input.ContainerCode).FirstAsync(); if (containerModel == null) throw Oops.Oh("容器信息不存在!"); //查询容器库位信息 var containerPlaceList = await _rep.AsQueryable().Where(z => z.ContainerCode == containerModel.ContainerCode).ToListAsync(); if (containerPlaceList.Count == 0) throw Oops.Oh("库位容器关系异常,库位容器关系不存在!"); if (containerPlaceList.Count > 1) throw Oops.Oh("库位容器关系异常,当前容器存在多条库位容器关系!"); //查询库位信息 var placeModel = await _wmsPlaceRep.AsQueryable().Where(z => z.PlaceCode == containerPlaceList.FirstOrDefault().PlaceCode).FirstAsync(); if (placeModel == null) throw Oops.Oh($"库位编号{containerPlaceList.FirstOrDefault().PlaceCode}不存在!"); if (placeModel.IsVirtually == true) throw Oops.Oh($"当前容器{containerModel.ContainerCode}处于虚拟库位'{placeModel.PlaceName}',无法进行解绑操作!"); if (placeModel.PlaceStatus != PlaceStatusEnum.正常) throw Oops.Oh("库位属性异常不可使用!"); //查找库存信息 var stockList = await _wmsStockQuanRep.AsQueryable().Where(z => z.ContainerCode == containerModel.ContainerCode).ToListAsync(); //定义输出参 var StockOutputModel = new StockOutput(); StockOutputModel.PlaceCode = placeModel.PlaceCode; StockOutputModel.StockList = stockList.Adapt>(); return StockOutputModel; } /// /// 扫描库位带出库存信息 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "PlaceStock")] [Description("WmsContainerPlace/PlaceStock")] public async Task PlaceStock([FromQuery] PlaceStockInput input) { //查询库位信息 var placeModel = await _wmsPlaceRep.AsQueryable().Where(z => z.PlaceCode == input.PlaceCode).FirstAsync(); if (placeModel == null) throw Oops.Oh("库位信息不存在!"); if (placeModel.IsVirtually == true) throw Oops.Oh("虚拟库位无法进行解绑操作!"); if (placeModel.PlaceStatus != PlaceStatusEnum.正常) throw Oops.Oh("库位属性异常不可使用!"); //查询容器库位信息 var containerPlaceList = await _rep.AsQueryable().Where(z => z.PlaceCode == placeModel.PlaceCode).ToListAsync(); if (containerPlaceList.Count == 0) throw Oops.Oh("库位容器关系异常,库位容器关系不存在!"); if (containerPlaceList.Count > 1) throw Oops.Oh("库位容器关系异常,当前容器存在多条库位容器关系!"); //查询容器信息 var containerModel = await _wmsContainerRep.AsQueryable().Where(z => z.ContainerCode == containerPlaceList.First().ContainerCode).FirstAsync(); if (containerModel == null) throw Oops.Oh("容器信息不存在!"); //查找库存信息 var stockList = await _wmsStockQuanRep.AsQueryable().Where(z => z.ContainerCode == containerModel.ContainerCode).ToListAsync(); //定义输出参 var StockOutputModel = new StockOutput(); StockOutputModel.PlaceCode = placeModel.PlaceCode; StockOutputModel.StockList = stockList.Adapt>(); return StockOutputModel; } /// /// 库位解绑 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "PlaceUnbind")] [Description("WmsContainerPlace/PlaceUnbind")] public async Task PlaceUnbind([FromBody] PlaceUnbindInput input) { //查询库位信息 var placeModel = await _wmsPlaceRep.AsQueryable().Where(z => z.PlaceCode == input.PlaceCode).FirstAsync(); if (placeModel == null) throw Oops.Oh("库位信息不存在!"); //查询当前库区的在途库位信息 var placeZtList = await StockQuanHelper.GetZTPlace(_wmsPlaceRep, placeModel); //查询容器库位信息 var containerPlaceModel = await _rep.AsQueryable().Where(z => z.PlaceCode == placeModel.PlaceCode).FirstAsync(); if (containerPlaceModel == null) throw Oops.Oh("库位容器关系不存在!"); //更新容器库位信息 containerPlaceModel.PlaceId = placeZtList.FirstOrDefault().Id; containerPlaceModel.PlaceCode = placeZtList.FirstOrDefault().PlaceCode; containerPlaceModel.PlaceName = placeZtList.FirstOrDefault().PlaceName; //await _rep.UpdateAsync(containerPlaceModel); //-------------ly0725 库存容器上 面有物料 1如果有物料 就插入事务 2插入操作日志 #region 事务日志入参 操作日志入参 List addWmsRecordTransList = new List(); List addWmsLogActionList = new List(); BusinessTypeEnum businessTypeEnum = BusinessTypeEnum.库位解绑; // 获取业务类型 var wmsBaseBusinessType = BusinessTypeHelper.GetBusinessTypeInfoFromDB((int)businessTypeEnum, _wmsBaseBusinessTypeRep); //update by liuwq 20240730 //获取目标库位 var toPlace =await BaseInfoHelper.GetPlace(containerPlaceModel.PlaceCode, _wmsPlaceRep); await HandleLogDetails(toPlace, wmsBaseBusinessType,placeModel, containerPlaceModel.ContainerCode, addWmsRecordTransList, addWmsLogActionList); #endregion try { await _rep.AsTenant().BeginTranAsync(); // 新增库位容器关系 或 更新容器库位信息 await _rep.UpdateAsync(containerPlaceModel); //操作日志 if (addWmsLogActionList.Count > 0) { await _wmsLogActionRep.InsertRangeAsync(addWmsLogActionList); } //事务日志 if (addWmsRecordTransList.Count > 0) { await _wmsRecordTransRep.InsertRangeAsync(addWmsRecordTransList); } await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } } #endregion #region 库位绑定 /// /// 库位绑定扫描容器带出库存信息 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "BindContainerStock")] [Description("WmsContainerPlace/BindContainerStock")] public async Task BindContainerStock([FromQuery] ContainerStockInput input) { //查询容器信息 var containerModel = await _wmsContainerRep.AsQueryable().Where(z => z.ContainerCode == input.ContainerCode).FirstAsync(); if (containerModel == null) throw Oops.Oh("容器信息不存在!"); //查询容器库位信息 var containerPlaceList = await _rep.AsQueryable().Where(z => z.ContainerCode == containerModel.ContainerCode).ToListAsync(); if (containerPlaceList.Count > 1) throw Oops.Oh("库位容器关系异常,当前容器存在多条库位容器关系!"); //查找库存信息 var stockList = await _wmsStockQuanRep.AsQueryable().Where(z => z.ContainerCode == containerModel.ContainerCode).ToListAsync(); //定义输出参 var StockOutputModel = new StockOutput(); if (containerPlaceList.Count > 0) StockOutputModel.PlaceCode = containerPlaceList.FirstOrDefault().PlaceCode; StockOutputModel.StockList = stockList.Adapt>(); return StockOutputModel; } /// /// 库位绑定 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "PlaceBind")] [Description("WmsContainerPlace/PlaceBind")] public async Task PlaceBind([FromBody] PlaceUnbindInput input) { //查询绑定库位信息 var placeModel = await _wmsPlaceRep.AsQueryable().Where(z => z.PlaceCode == input.PlaceCode).FirstAsync(); if (placeModel == null) throw Oops.Oh("库位信息不存在!"); if (placeModel.IsVirtually == true) throw Oops.Oh("无法绑定虚拟库位!"); if (placeModel.PlaceStatus != PlaceStatusEnum.正常) throw Oops.Oh("库位属性异常不可使用!"); //查询绑定容器库位信息 var containerPlaceList = await _rep.AsQueryable().Where(z => z.PlaceCode == placeModel.PlaceCode && z.ContainerCode == input.ContainerCode).ToListAsync(); if (containerPlaceList.Count > 0) throw Oops.Oh($"当前库位{placeModel.PlaceCode}已经和容器{input.ContainerCode}存在绑定关系"); PlaceHelper.ValidateBindContainerCount(containerPlaceList, placeModel); //查询容器信息 var containerModel = await _wmsContainerRep.AsQueryable().Where(z => z.ContainerCode == input.ContainerCode).FirstAsync(); if (containerModel == null) throw Oops.Oh("容器信息不存在!"); //查询容器库位信息 var containerPlaceModel = await _rep.AsQueryable().Where(z => z.ContainerCode == input.ContainerCode).FirstAsync(); var isInsert = false; if (containerPlaceModel == null) { //新增库位容器关系 containerPlaceModel = new WmsContainerPlace(); containerPlaceModel.PlaceId = placeModel.Id; containerPlaceModel.PlaceCode = placeModel.PlaceCode; containerPlaceModel.PlaceName = placeModel.PlaceName; containerPlaceModel.ContainerId = containerModel.Id; containerPlaceModel.ContainerCode = containerModel.ContainerCode; containerPlaceModel.ContainerName = containerModel.ContainerName; isInsert = true; //await _rep.InsertAsync(containerPlaceModel); } else { //更新容器库位信息 containerPlaceModel.PlaceId = placeModel.Id; containerPlaceModel.PlaceCode = placeModel.PlaceCode; containerPlaceModel.PlaceName = placeModel.PlaceName; //await _rep.UpdateAsync(containerPlaceModel); isInsert = false; } //-------------ly0725 库存容器上 面有物料 1如果有物料 就插入事务 2插入操作日志 #region 事务日志入参 操作日志入参 List addWmsRecordTransList = new List(); List addWmsLogActionList = new List(); BusinessTypeEnum businessTypeEnum = BusinessTypeEnum.库位绑定; // 获取业务类型 var wmsBaseBusinessType = BusinessTypeHelper.GetBusinessTypeInfoFromDB((int)businessTypeEnum, _wmsBaseBusinessTypeRep); //update by liuwq 20240730 //获取目标库位 var toPlace = await BaseInfoHelper.GetPlace(containerPlaceModel.PlaceCode, _wmsPlaceRep); await HandleLogDetails(toPlace,wmsBaseBusinessType, placeModel, containerModel.ContainerCode, addWmsRecordTransList, addWmsLogActionList); #endregion try { await _rep.AsTenant().BeginTranAsync(); // 新增库位容器关系 或 更新容器库位信息 if (isInsert) { await _rep.InsertAsync(containerPlaceModel); } else { await _rep.UpdateAsync(containerPlaceModel); } //操作日志 if (addWmsLogActionList.Count > 0) { await _wmsLogActionRep.InsertRangeAsync(addWmsLogActionList); } //事务日志 if (addWmsRecordTransList.Count > 0) { await _wmsRecordTransRep.InsertRangeAsync(addWmsRecordTransList); } await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } } #endregion private async Task HandleLogDetails(WmsBasePlace toPlace ,WmsBaseBusinessType wmsBaseBusinessType, WmsBasePlace placeModel, string ContainerCode, List addWmsRecordTransList, List addWmsLogActionList) { var allStockQuanViewList = await _v_wms_stock_quanRep.GetListAsync(f => f.ContainerCode.Equals(ContainerCode)); string recordTransRemarks = $"PDA{wmsBaseBusinessType.BusinessTypeName}"; //容器上如果有库存物料 就插入事务 var StockModel = await _wmsStockQuanRep.AsQueryable().FirstAsync(p => p.ContainerCode == ContainerCode); if (StockModel != null) { #region 创建事务日志入参 //获取源库存信息 var sourceStockView = StockQuanHelper.GetVMmsStockQuan(allStockQuanViewList, StockModel.SNCode); // 其他参数对象 TransferOtherDetail transferOtherDetail = new TransferOtherDetail() { RelationNo = "", RelationNoLineNumber = "", Remarks = recordTransRemarks, }; #endregion //新增事务记录 //解绑变在途库位 addWmsRecordTransList.Add(LogRecordHelper.CreateWmsRecordTrans(wmsBaseBusinessType, sourceStockView, StockModel, toPlace, transferOtherDetail)); } #region 操作日志入参 //新增操作日志 WmsLogAction wareActionLog = LogActionHelper.CreateWmsLogAction(placeModel.Id, recordTransRemarks, $"PDA库位{placeModel.PlaceCode},容器{ContainerCode}"); addWmsLogActionList.Add(wareActionLog); #endregion } #region 私有方法 /// /// 公共查询容器库位关系条件 /// /// /// private ISugarQueryable CommonPageFilter(WmsContainerPlaceInput input) { var query = _rep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => u.PlaceCode.Contains(input.SearchKey.Trim()) || u.ContainerCode.Contains(input.SearchKey.Trim()) || u.CreateUserName.Contains(input.SearchKey.Trim()) || u.UpdateUserName.Contains(input.SearchKey.Trim()) || u.PlaceName.Contains(input.SearchKey.Trim()) || u.ContainerName.Contains(input.SearchKey.Trim()) ) .WhereIF(input.PlaceId > 0, u => u.PlaceId == input.PlaceId) .WhereIF(!string.IsNullOrWhiteSpace(input.PlaceCode), u => u.PlaceCode.Contains(input.PlaceCode.Trim())) .WhereIF(input.ContainerId > 0, u => u.ContainerId == input.ContainerId) .WhereIF(!string.IsNullOrWhiteSpace(input.ContainerCode), u => u.ContainerCode.Contains(input.ContainerCode.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.PlaceName), u => u.PlaceName.Contains(input.PlaceName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.ContainerName), u => u.ContainerName.Contains(input.ContainerName.Trim())) .Select(); return query; } /// /// 重复性验证 /// /// 验证对象 /// 是否是编辑 /// private async Task CheckExist(WmsContainerPlace input, bool isEdit = false) { //没有配置组合校验,不需要验重 //没有配置单独校验,不需要验重 } /// /// 根据组合校验和单独校验验证数据是否已存在-导入时验证 /// /// /// private async Task CheckExisitForImport(List inputs) { if (inputs?.Count <= 0) { throw Oops.Oh($"导入数据不能为空"); } //根据组合校验验证表格中中是否已存在相同数据 //根据单独校验验证表格中中是否已存在相同数据 } #endregion }