using Furion.DatabaseAccessor; using Furion.DependencyInjection; using Furion.DynamicApiController; using Furion.FriendlyException; using Mapster; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Yitter.IdGenerator; using Admin.NET.Core; namespace Admin.NET.Application { /// /// 出库管理服务 /// [ApiDescriptionSettings("自己的业务", Name = "ExWarehouse", Order = 100)] [Route("api/[Controller]")] public class ExWarehouseService : IDynamicApiController, ITransient { private readonly IRepository _wmsAreaRep; private readonly IRepository _wmsPlaceRep; private readonly IRepository _wmsTaskRep; private readonly IRepository _wmsContainerRep; private readonly IRepository _wmsContainerPlaceRep; private readonly IRepository _wmsMaterialRep; private readonly IRepository _wmsMaterialStockRep; private readonly IRepository _wmsMaterialContainerRep; /// /// 构造函数 /// public ExWarehouseService( IRepository wmsAreaRep, IRepository wmsPlaceRep, IRepository wmsTaskRep, IRepository wmsContainerRep, IRepository wmsContainerPlaceRep, IRepository wmsMaterialRep, IRepository wmsMaterialStockRep, IRepository wmsMaterialContainerRep ) { this._wmsAreaRep = wmsAreaRep; this._wmsPlaceRep = wmsPlaceRep; this._wmsTaskRep = wmsTaskRep; this._wmsContainerRep = wmsContainerRep; this._wmsContainerPlaceRep = wmsContainerPlaceRep; this._wmsMaterialRep = wmsMaterialRep; this._wmsMaterialStockRep = wmsMaterialStockRep; this._wmsMaterialContainerRep = wmsMaterialContainerRep; } /// /// 分页查询物料出库管理信息 /// /// /// [HttpGet("page")] public async Task> Page([FromQuery] ExWarehouseSearch input) { var wmsMaterialStocks = await _wmsMaterialStockRep.DetachedEntities .Where (!string.IsNullOrEmpty(input.MaterialName), u => EF.Functions.Like(u.MaterialName, $"%{input.MaterialName.Trim()}%")) .ProjectToType() .ToListAsync(); return wmsMaterialStocks.ToADPagedList(input.PageNo, input.PageSize); } /// /// 自动出库 /// /// /// [HttpPost("AutoExWarehouse")] [UnitOfWork] public async Task AutoExWarehouse(List inputs) { // 根据托盘号、库位编号去重 var containerCodeDistinct = inputs.Select(u => new { u.ContainerCode, u.PlaceCode }).Distinct().ToList(); if (containerCodeDistinct.Count <= 0) throw Oops.Oh("暂无库存出库"); // 查询库区名称 var wmsArea = await _wmsAreaRep.FirstOrDefaultAsync(u => u.AreaName.Contains("绝缘立库")); if (wmsArea != null) throw Oops.Oh("库区不存在"); foreach (var item in containerCodeDistinct) { var wmsMaterialContainerList = new List(); // 判断任务 var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(p => p.ContainerCode == item.ContainerCode && p.TaskStatus != TaskStatusEnum.WANCHENG); if (wmsTask != null) throw Oops.Oh("周转箱号存在未完成的任务!"); // 检查周转箱号信息 var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(n => n.ContainerCode == item.ContainerCode); if (wmsContainer == null) throw Oops.Oh("库存中没有该:" + wmsContainer.ContainerCode + "托盘!"); // 检查库位信息 var wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(p => p.PlaceCode == item.PlaceCode); if (wmsPlace == null) throw Oops.Oh("库位不存在!"); if (wmsPlace.Islock == YesOrNot.Y) throw Oops.Oh("库位被锁定!"); // 更新状态为“待出” wmsPlace.PlaceStatus = PlaceStatus.DAICHU; await _wmsPlaceRep.UpdateAsync(wmsPlace); // 检查库存 var wmsMaterialStockList = inputs.Where(u => u.ContainerCode == wmsContainer.ContainerCode && u.PlaceCode == wmsPlace.PlaceCode).ToList(); if (wmsMaterialStockList.Count <= 0) throw Oops.Oh("库存数据异常!"); // 检查库位与周转箱号关系 var wmsContainerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(p => p.ContainerCode == wmsContainer.ContainerCode && p.ContainerId == wmsContainer.Id && p.PlaceCode == wmsPlace.PlaceCode && p.PlaceId == wmsPlace.Id && p.ContainerPlaceStatus == CommonStatus.ENABLE); if (wmsContainerPlace == null) throw Oops.Oh("托盘号与库位关系不存在!"); // 不是空料箱才会有组盘关系 if (wmsPlace.EmptyContainer == YesOrNot.N) { // 检查物料与周转箱号关系 wmsMaterialContainerList = await _wmsMaterialContainerRep.Where(p => p.ContainerCode == wmsContainer.ContainerCode && p.BindStatus == CommonStatus.ENABLE).ToListAsync(); if (wmsMaterialContainerList.Count <= 0) throw Oops.Oh("周转箱号与物料关系不存在!"); } else { // 更新空料箱库存 var wmsMaterialStock = await _wmsMaterialStockRep.FirstOrDefaultAsync(u => u.ContainerCode == wmsContainer.ContainerCode); if (wmsMaterialStock.Source == RuKuSourceEnum.KONGTUO) { wmsMaterialStock.PlaceCode = "N/A"; await _wmsMaterialStockRep.UpdateAsync(wmsMaterialStock); } } if (wmsTask == null) { string taskNo = "CHUKU" + DateTime.Today.ToString("yyyyMMdd"); var wmsTaskModel = await _wmsTaskRep.DetachedEntities.FirstOrDefaultAsync(u => EF.Functions.Like(u.TaskNo, $"%{taskNo}%")); if (wmsTaskModel == null) { taskNo = taskNo + "0001"; } else { //获取流水号最大的数据 var maxSerialNumber = await _wmsTaskRep.MaxAsync(t => t.TaskNo); taskNo = Comm.GenerateNewInvoiceNumber(maxSerialNumber, 1); } // 新增任务 var takmodel = new WmsTask() { TaskNo = taskNo,//YitIdHelper.NextId().ToString(), TaskModel = TaskModel.QUANZIDONG, TaskType = TaskType.CHUKU, TaskLevel = 1, TaskStatus = TaskStatusEnum.WEIZHIXING, ContainerCode = wmsContainer.ContainerCode, SourcePlace = wmsPlace.PlaceCode, Aisle = wmsPlace.Aisle, ToPlace = "出库口", AreaName = wmsArea.AreaName, Description = wmsPlace.EmptyContainer == YesOrNot.Y ? "空托" : "物料", OrderNo = wmsMaterialContainerList.Count <= 0 ? "N/A" : wmsMaterialContainerList.FirstOrDefault().OrderNo, TaskDodeviceStatus = TaskDodeviceStatusEnum.W, IsRead = true }; await _wmsTaskRep.InsertAsync(takmodel); } } } /// /// 人工出库 /// /// /// [HttpPost("manualExWarehouse")] [UnitOfWork] public async Task ManualExWarehouse(List inputs) { // 根据托盘号、库位编号去重 var containerCodeDistinct = inputs.Select(u => new { u.ContainerCode, u.PlaceCode }).Distinct().ToList(); if (containerCodeDistinct.Count <= 0) throw Oops.Oh("暂无库存出库"); // 查询库区名称 var wmsArea = await _wmsAreaRep.FirstOrDefaultAsync(u => u.AreaName.Contains("绝缘立库")); if (wmsArea != null) throw Oops.Oh("库区不存在"); foreach (var item in containerCodeDistinct) { var wmsMaterialContainerList = new List(); // 判断任务 var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(p => p.ContainerCode == item.ContainerCode && p.TaskStatus != TaskStatusEnum.WANCHENG); if (wmsTask != null) throw Oops.Oh("托盘号存在未完成的任务!"); // 检查托盘号信息 var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(n => n.ContainerCode == item.ContainerCode); if (wmsContainer == null) throw Oops.Oh("周转箱号不存在!"); // 检查库位信息 var wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(p => p.PlaceCode == item.PlaceCode); if (wmsPlace == null) throw Oops.Oh("库位不存在!"); if (wmsPlace.Islock == YesOrNot.Y) throw Oops.Oh("库位被锁定!"); // 检查库存 var wmsMaterialStockList = inputs.Where(u => u.ContainerCode == wmsContainer.ContainerCode && u.PlaceCode == wmsPlace.PlaceCode).ToList(); if (wmsMaterialStockList.Count <= 0) throw Oops.Oh("库存数据异常!"); // 检查库位与托盘号关系 var wmsContainerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(p => p.ContainerCode == wmsContainer.ContainerCode && p.ContainerId == wmsContainer.Id && p.PlaceCode == wmsPlace.PlaceCode && p.PlaceId == wmsPlace.Id && p.ContainerPlaceStatus == CommonStatus.ENABLE); if (wmsContainerPlace == null) throw Oops.Oh("托盘号与库位关系不存在!"); // 不是空托才会有组盘关系 if (wmsPlace.EmptyContainer == YesOrNot.N) { // 检查物料与空托号关系 wmsMaterialContainerList = await _wmsMaterialContainerRep.Where(p => p.ContainerCode == wmsContainer.ContainerCode && p.BindStatus == CommonStatus.ENABLE).ToListAsync(); if (wmsMaterialContainerList.Count <= 0) throw Oops.Oh("托盘号与物料关系不存在!"); } else { // 更新空料箱库存 var wmsMaterialStock = await _wmsMaterialStockRep.FirstOrDefaultAsync(u => u.ContainerCode == wmsContainer.ContainerCode); if (wmsMaterialStock.Source == RuKuSourceEnum.KONGTUO) { await _wmsMaterialStockRep.DeleteAsync(wmsMaterialStock); } } if (wmsTask == null) { //构建出库物料和周转箱号关系 var orderNo = "N/A"; if (wmsMaterialContainerList.Count > 0) orderNo = YitIdHelper.NextId().ToString(); foreach (var wmsMaterialContaine in wmsMaterialContainerList) { //更新状态为”删除“ wmsMaterialContaine.BindStatus = CommonStatus.DELETED; await _wmsMaterialContainerRep.UpdateNowAsync(wmsMaterialContaine); //新增组盘绑定记录 正常 var addWmsMaterialContainer = wmsMaterialContaine; addWmsMaterialContainer.Id = YitIdHelper.NextId(); addWmsMaterialContainer.OrderNo = orderNo; addWmsMaterialContainer.BindStatus = CommonStatus.ENABLE; await _wmsMaterialContainerRep.InsertNowAsync(addWmsMaterialContainer); // 这里没有分拣操作直接更新库存信息 var wmsMaterialStock = await _wmsMaterialStockRep.FirstOrDefaultAsync(u => u.ContainerCode == wmsMaterialContaine.ContainerCode); wmsMaterialStock.PlaceCode = "N/A"; wmsMaterialStock.StockNumber -= wmsMaterialContaine.BindQuantity; await _wmsMaterialStockRep.UpdateAsync(wmsMaterialStock); } string taskNo = "CHUKU" + DateTime.Today.ToString("yyyyMMdd"); var wmsTaskModel = await _wmsTaskRep.DetachedEntities.FirstOrDefaultAsync(u => EF.Functions.Like(u.TaskNo, $"%{taskNo}%")); if (wmsTaskModel == null) { taskNo = taskNo + "0001"; } else { //获取流水号最大的数据 var maxSerialNumber = await _wmsTaskRep.MaxAsync(t => t.TaskNo); taskNo = Comm.GenerateNewInvoiceNumber(maxSerialNumber, 1); } // 新增任务 var addWmsTask = new WmsTask() { TaskNo = taskNo,//YitIdHelper.NextId().ToString(), TaskModel = TaskModel.SHOUDONG, TaskType = TaskType.CHUKU, TaskLevel = 1, TaskStatus = TaskStatusEnum.WANCHENG, ContainerCode = wmsContainer.ContainerCode, SourcePlace = wmsPlace.PlaceCode, Aisle = wmsPlace.Aisle, ToPlace = "出库口", AreaName = wmsArea.AreaName, Description = wmsPlace.EmptyContainer == YesOrNot.Y ? "空托" : "物料", OrderNo = orderNo, TaskDodeviceStatus=TaskDodeviceStatusEnum.W, UpdatedTime = DateTime.Now, }; await _wmsTaskRep.InsertAsync(addWmsTask); // 更新库位与周转箱号关系表状态为“删除” wmsContainerPlace.ContainerPlaceStatus = CommonStatus.DELETED; await _wmsContainerPlaceRep.UpdateAsync(wmsContainerPlace); // 更新库位为“空闲” wmsPlace.PlaceStatus = PlaceStatus.KONGXIAN; wmsPlace.Islock = YesOrNot.N; wmsPlace.EmptyContainer = YesOrNot.N; await _wmsPlaceRep.UpdateAsync(wmsPlace); // 更新周转箱号状态为“空闲” wmsContainer.ContainerStatus = ContainerStatus.KOUXIAN; await _wmsContainerRep.UpdateAsync(wmsContainer); } } } /// /// 呼叫空托 /// /// [HttpPost("callairflare")] [UnitOfWork] public async Task CallAirflare(CallAirflareInput input) { //获取库位中存货是空托的库位 var wmsPlace = await _wmsPlaceRep.Where(u => u.PlaceStatus == PlaceStatus.CUNHUO && u.EmptyContainer== YesOrNot.Y).ToListAsync(); if (wmsPlace.Count > 0) { } } } }