using Furion.DatabaseAccessor; using Furion.DatabaseAccessor.Extensions; using Furion.DependencyInjection; using Furion.DynamicApiController; using Furion.FriendlyException; using iWare.Wms.Core; using Mapster; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Linq.Dynamic.Core; namespace iWare.Wms.Application { /// /// 出库管理 /// //[ApiDescriptionSettings("仓库作业", Name = "IExWarehouse", Order = 100)] //[Route("api/[Controller]")] public class ExWarehouseService : IExWarehouseService, IDynamicApiController, ITransient { private readonly IRepository _wmsContainerRep; private readonly IRepository _wmsMaterialRep; private readonly IRepository _wmsMaterialContainerRep; private readonly IRepository _wmsAreaRep; private readonly IRepository _wmsPlaceRep; private readonly IRepository _wmsTaskRep; private readonly IRepository _wmsMaterialStockRep; private readonly IRepository _wmsContainerPlaceRep; public ExWarehouseService( IRepository wmsContainerRep, IRepository wmsMaterialRep, IRepository wmsMaterialContainerRep, IRepository wmsAreaRep, IRepository wmsPlaceRep, IRepository wmsTaskRep, IRepository wmsMaterialStockRep, IRepository wmsContainerPlaceRep ) { _wmsContainerRep = wmsContainerRep; _wmsMaterialRep = wmsMaterialRep; _wmsMaterialContainerRep = wmsMaterialContainerRep; _wmsAreaRep = wmsAreaRep; _wmsPlaceRep = wmsPlaceRep; _wmsTaskRep = wmsTaskRep; _wmsMaterialStockRep = wmsMaterialStockRep; _wmsContainerPlaceRep = wmsContainerPlaceRep; } /// /// 分页查询库存表 /// /// /// [HttpGet("page")] public async Task> Page([FromQuery] WmsMaterialStockSearch input) { var wmsMaterialStocks = await _wmsMaterialStockRep.DetachedEntities .Where(!string.IsNullOrEmpty(input.Materialno), u => EF.Functions.Like(u.MaterialNo, $"%{input.Materialno.Trim()}%")) .Where(input.Materialtype != null, u => u.MaterialType == input.Materialtype) .Where(!string.IsNullOrEmpty(input.Materialbatch), u => EF.Functions.Like(u.MaterialBatch, $"%{input.Materialbatch.Trim()}%")) .Where(!string.IsNullOrEmpty(input.Materialname), u => EF.Functions.Like(u.MaterialName, $"%{input.Materialname.Trim()}%")) .Where(!string.IsNullOrEmpty(input.Materialspec), u => EF.Functions.Like(u.MaterialSpec, $"%{input.Materialspec.Trim()}%")) .Where(input.Inspectionmethod != null, u => u.InspectionMethod == input.Inspectionmethod) .Where(input.Unittype != null, u => u.UnitType == input.Unittype) .Where(input.Unitno != null, u => u.UnitNo == input.Unitno) .Where(u => u.StockNumber != 0) .Where(!string.IsNullOrEmpty(input.Placecode), u => u.PlaceCode == input.Placecode) .Where(!string.IsNullOrEmpty(input.Containercode), u => u.ContainerCode == input.Containercode) .OrderBy(PageInputOrder.OrderBuilder(input)) .ProjectToType() .ToADPagedListAsync(input.PageNo, input.PageSize); return wmsMaterialStocks; } /// /// 手动出库 /// /// /// [HttpPost("ManualWare")] [UnitOfWork] public async Task ManualWare(ExManualWarehouseInput input) { //检查是正在出库 var isExit = await _wmsTaskRep.AnyAsync(n => n.TaskStatus != Core.Enum.TaskStatus.WANCHENG && n.ContainerCode==input.Containercode); if (isExit) throw Oops.Oh("存在出库任务!"); //检查库位信息 var placeModel = await _wmsPlaceRep.DetachedEntities.Where(p => p.PlaceCode == input.Placecode).ProjectToType().FirstOrDefaultAsync(); if (placeModel == null) throw Oops.Oh("库位不存在!"); if (placeModel.Islock == YesOrNot.Y) throw Oops.Oh("库位被锁定!"); if (placeModel.PlaceStatus != Core.Enum.PlaceStatus.CUNHUO) throw Oops.Oh("库位异常货!"); //容器信息 var containerModel = await _wmsContainerRep.FirstOrDefaultAsync(n => n.ContainerCode == input.Containercode && n.ContainerStatus == Core.Enum.ContainerStatus.KUWEI); if (containerModel == null) throw Oops.Oh("托盘信息不存在!"); //库位容器关系 var containerPlaceModel = await _wmsContainerPlaceRep.FirstOrDefaultAsync(p => p.ContainerCode == containerModel.ContainerCode && p.ContainerId == containerModel.Id && p.PlaceCode == placeModel.PlaceCode && p.PlaceId == placeModel.Id && p.ContainerPlaceStatus == CommonStatus.ENABLE); if (containerPlaceModel == null) throw Oops.Oh("库位容器关系不存在!"); //库存物料信息 var materialStockModelList = await _wmsMaterialStockRep.Where(n => n.ContainerCode == input.Containercode && n.PlaceCode == input.Placecode).ToListAsync(); if (materialStockModelList.Count == 0) throw Oops.Oh("物料信息不存在!"); //关系对应出库的物料 var materialContainersList = await _wmsMaterialContainerRep.Where(p => p.ContainerCode == containerModel.ContainerCode && p.BindStatus == CommonStatus.ENABLE).ToListAsync(); //单据号 var orderNo = "N/A"; //创建任务 if (materialContainersList.Count > 0) orderNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(); var takmodel = new WmsTask() { TaskNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(), TaskModel = Core.Enum.TaskModel.SHOUDONG, TaskType = Core.Enum.TaskType.CHUKU, TaskLevel = 1, TaskStatus = Core.Enum.TaskStatus.WANCHENG, ContainerCode = input.Containercode, SourcePlace = input.Placecode, Aisle = placeModel.Aisle, ToPlace = "N/A", AreaName = placeModel.WmsArea.AreaName, OrderNo = orderNo, }; await _wmsTaskRep.InsertAsync(takmodel); //托盘状态 if (orderNo == "N/A") containerModel.ContainerStatus = Core.Enum.ContainerStatus.KOUXIAN; else containerModel.ContainerStatus = Core.Enum.ContainerStatus.ZUPANG; await _wmsContainerRep.UpdateAsync(containerModel); //组盘信息 //入库时组盘信息逻辑删除 foreach (var item in materialContainersList) { //修改 item.BindStatus = CommonStatus.DELETED; await _wmsMaterialContainerRep.UpdateAsync(item); } foreach (var item in materialContainersList) { //新增出库绑定记录 禁用 var bindentranceModel = new WmsMaterialContainer() { ContainerId = item.ContainerId, ContainerCode = item.ContainerCode, MaterialName = item.MaterialName, MaterialNo = item.MaterialNo, MaterialBatch = item.MaterialBatch, MaterialSpec = item.MaterialSpec, MaterialId = item.MaterialId, BindQuantity = item.BindQuantity, BindStatus = CommonStatus.DISABLE, OrderNo = orderNo, }; await _wmsMaterialContainerRep.InsertNowAsync(bindentranceModel); //新增组盘绑定记录 正常 var newbindentranceModel = new WmsMaterialContainer() { ContainerId = item.ContainerId, ContainerCode = item.ContainerCode, MaterialName = item.MaterialName, MaterialNo = item.MaterialNo, MaterialBatch = item.MaterialBatch, MaterialSpec = item.MaterialSpec, MaterialId = item.MaterialId, BindQuantity = item.BindQuantity, BindStatus = CommonStatus.ENABLE, OrderNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(), }; await _wmsMaterialContainerRep.InsertNowAsync(newbindentranceModel); } //库位 placeModel.PlaceStatus = Core.Enum.PlaceStatus.KONGXIAN; placeModel.EmptyContainer = YesOrNot.N; await _wmsPlaceRep.UpdateAsync(placeModel); //修改库存 foreach (var item in materialStockModelList) { item.PlaceCode = "N/A"; item.AreaId = 0; item.StockNumber = 0; await _wmsMaterialStockRep.UpdateAsync(item); } //删除托盘库位关系 containerPlaceModel.ContainerPlaceStatus = CommonStatus.DELETED; await _wmsContainerPlaceRep.UpdateAsync(containerPlaceModel); } /// /// 自动出库 /// /// /// [HttpPost("AutoWare")] [UnitOfWork] public async Task AutoWare(ExAutoWarehouseInput input) { //检查是正在出库 var isExit = await _wmsTaskRep.AnyAsync(n => n.TaskStatus != Core.Enum.TaskStatus.WANCHENG && n.ContainerCode == input.Containercode); if (isExit) throw Oops.Oh("存在出库任务!"); //检查库位信息 var placeModel = await _wmsPlaceRep.DetachedEntities.Where(p => p.PlaceCode == input.Placecode).ProjectToType().FirstOrDefaultAsync(); if (placeModel == null) throw Oops.Oh("库位不存在!"); if (placeModel.Islock == YesOrNot.Y) throw Oops.Oh("库位被锁定!"); if (placeModel.PlaceStatus != Core.Enum.PlaceStatus.CUNHUO) throw Oops.Oh("库位异常货!"); //容器信息 var containerModel = await _wmsContainerRep.FirstOrDefaultAsync(n => n.ContainerCode == input.Containercode && n.ContainerStatus == Core.Enum.ContainerStatus.KUWEI); if (containerModel == null) throw Oops.Oh("托盘信息不存在!"); //库位容器关系 var containerPlaceModel = await _wmsContainerPlaceRep.FirstOrDefaultAsync(p => p.ContainerCode == containerModel.ContainerCode && p.ContainerId == containerModel.Id && p.PlaceCode == placeModel.PlaceCode && p.PlaceId == placeModel.Id && p.ContainerPlaceStatus == CommonStatus.ENABLE); if (containerPlaceModel == null) throw Oops.Oh("库位容器关系不存在!"); //物料信息 var materialStockList = await _wmsMaterialStockRep.Where(n => n.ContainerCode == input.Containercode && n.PlaceCode == input.Placecode).ToListAsync(); if (materialStockList.Count == 0) throw Oops.Oh("物料信息不存在!"); //关系对应出库的物料 var materialContainersList = await _wmsMaterialContainerRep.Where(n => n.ContainerCode == input.Containercode && n.BindStatus == CommonStatus.ENABLE).ToListAsync(); //单据信息 var orderNo = "N/A"; if (materialContainersList.Count > 0) orderNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(); //创建任务 var takmodel = new WmsTask() { TaskNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(), TaskModel = Core.Enum.TaskModel.ZIDONG, TaskType = Core.Enum.TaskType.CHUKU, TaskLevel = 1, Aisle=placeModel.Aisle, TaskStatus = Core.Enum.TaskStatus.WEIZHIXING, ContainerCode = input.Containercode, SourcePlace = input.Placecode, ToPlace = input.Entrance, AreaName = placeModel.WmsArea.AreaName, OrderNo = orderNo, }; await _wmsTaskRep.InsertAsync(takmodel); //组盘信息 foreach (var item in materialContainersList) { //修改 item.BindStatus = CommonStatus.DISABLE; await _wmsMaterialContainerRep.UpdateAsync(item); //新增 var bindentranceModel = new WmsMaterialContainer() { ContainerId = item.ContainerId, ContainerCode = item.ContainerCode, MaterialName = item.MaterialName, MaterialNo = item.MaterialNo, MaterialBatch = item.MaterialBatch, MaterialSpec = item.MaterialSpec, MaterialId = item.MaterialId, BindQuantity = item.BindQuantity, BindStatus = CommonStatus.ENABLE, OrderNo = orderNo, }; await _wmsMaterialContainerRep.InsertNowAsync(bindentranceModel); } //库位 placeModel.PlaceStatus = Core.Enum.PlaceStatus.DAICHU; await _wmsPlaceRep.UpdateAsync(placeModel); } } }