using Furion.DatabaseAccessor;
|
using Furion.DependencyInjection;
|
using Furion.DynamicApiController;
|
using Furion.FriendlyException;
|
using Mapster;
|
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.EntityFrameworkCore;
|
using System.Linq.Dynamic.Core;
|
using Admin.NET.Core;
|
using Yitter.IdGenerator;
|
using Microsoft.Extensions.Logging;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
namespace Admin.NET.Application
|
{
|
/// <summary>
|
/// 物料分拣服务
|
/// </summary>
|
[ApiDescriptionSettings("Pda分拣", Name = "MaterialSorting", Order = 100)]
|
[Route("api/[Controller]")]
|
public class MaterialSortingService : IDynamicApiController, ITransient
|
{
|
private readonly IRepository<WmsOrder, MasterDbContextLocator> _wmsOrderRep;
|
private readonly IRepository<WmsOrderDetails, MasterDbContextLocator> _wmsOrderDetailsRep;
|
private readonly IRepository<WmsTask, MasterDbContextLocator> _wmsTaskRep;
|
private readonly IRepository<WmsPlace, MasterDbContextLocator> _wmsPlaceRep;
|
private readonly IRepository<WmsArea, MasterDbContextLocator> _wmsAreaRep;
|
private readonly IRepository<WmsWarehouseEntrance, MasterDbContextLocator> _wmsWarehouseEntranceRep;
|
private readonly IRepository<WmsMaterialContainer, MasterDbContextLocator> _wmsMaterialContainerRep;
|
private readonly IRepository<WmsContainer, MasterDbContextLocator> _wmsContainerRep;
|
private readonly IRepository<WmsContainerPlace, MasterDbContextLocator> _wmsContainerPlaceRep;
|
private readonly IRepository<WmsMaterialStock, MasterDbContextLocator> _wmsMaterialStockRep;
|
private readonly IRepository<WmsOrderType, MasterDbContextLocator> _wmsOrderTypeRep;
|
private readonly IRepository<WmsSortOrder, MasterDbContextLocator> _wmsSortOrderRep;
|
private readonly IRepository<WmsTakeMaterialOrder, MasterDbContextLocator> _wmsTakeMaterialOrderRep;
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
public MaterialSortingService(
|
IRepository<WmsOrder, MasterDbContextLocator> wmsOrderRep,
|
IRepository<WmsOrderDetails, MasterDbContextLocator> wmsOrderDetailsRep,
|
IRepository<WmsTask, MasterDbContextLocator> wmsTaskRep,
|
IRepository<WmsPlace, MasterDbContextLocator> wmsPlaceRep,
|
IRepository<WmsArea, MasterDbContextLocator> wmsAreaRep,
|
IRepository<WmsWarehouseEntrance, MasterDbContextLocator> wmsWarehouseEntranceRep,
|
IRepository<WmsMaterialContainer, MasterDbContextLocator> wmsMaterialContainerRep,
|
IRepository<WmsContainer, MasterDbContextLocator> wmsContainerRep,
|
IRepository<WmsContainerPlace, MasterDbContextLocator> wmsContainerPlaceRep,
|
IRepository<WmsMaterialStock, MasterDbContextLocator> wmsMaterialStockRep,
|
IRepository<WmsOrderType, MasterDbContextLocator> wmsOrderTypeRep,
|
IRepository<WmsSortOrder, MasterDbContextLocator> wmsSortOrderRep,
|
IRepository<WmsTakeMaterialOrder, MasterDbContextLocator> wmsTakeMaterialOrderRep
|
)
|
{
|
_wmsOrderRep = wmsOrderRep;
|
_wmsOrderDetailsRep = wmsOrderDetailsRep;
|
_wmsTaskRep = wmsTaskRep;
|
_wmsPlaceRep = wmsPlaceRep;
|
_wmsAreaRep = wmsAreaRep;
|
_wmsWarehouseEntranceRep = wmsWarehouseEntranceRep;
|
_wmsMaterialContainerRep = wmsMaterialContainerRep;
|
_wmsContainerRep = wmsContainerRep;
|
_wmsContainerPlaceRep = wmsContainerPlaceRep;
|
_wmsMaterialStockRep = wmsMaterialStockRep;
|
_wmsOrderTypeRep = wmsOrderTypeRep;
|
_wmsSortOrderRep = wmsSortOrderRep;
|
_wmsTakeMaterialOrderRep = wmsTakeMaterialOrderRep;
|
}
|
|
/// <summary>
|
/// 扫描分拣托盘
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("GetSortInfo")]
|
public async Task<GetSortInfoOutput> GetSortInfo([FromQuery] GetSortInfoInput input)
|
{
|
//检查托盘
|
var wareContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == input.ContainerCode);
|
if (wareContainer == null) throw Oops.Oh("容器信息不存在!");
|
if (wareContainer.ContainerStatus == ContainerStatus.JINYONG) throw Oops.Oh("容器已禁用!");
|
if (wareContainer.ContainerStatus == ContainerStatus.KUWEI) throw Oops.Oh("容器在库位不可使用!");
|
if (wareContainer.ContainerStatus != ContainerStatus.FENJIAN) throw Oops.Oh("容器不存在分拣信息!");
|
|
//判断是否在任务中
|
var isExit = await _wmsTaskRep.AnyAsync(n => n.TaskStatus != TaskStatusEnum.WANCHENG && n.ContainerCode == input.ContainerCode);
|
if (isExit) throw Oops.Oh("容器存在未完成任务!");
|
|
// 查询分拣记录
|
var wareSortOrderList = await _wmsSortOrderRep.DetachedEntities
|
.Where(p => p.ContainerCode == input.ContainerCode && p.SortStatus != SortStatusEnum.FENJIANWANCHENG).ToListAsync();
|
|
return new GetSortInfoOutput
|
{
|
WmsContainer = wareContainer.Adapt<WmsContainerDto>(),
|
WmsSortOrderList = wareSortOrderList
|
};
|
}
|
|
|
/// <summary>
|
/// 分拣确认
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("SortSure")]
|
[UnitOfWork]
|
public async Task SortSure(GetSortInfoOutput input)
|
{
|
if (input.WmsContainer == null || input.WmsSortOrderList.Count == 0) throw Oops.Oh("传递参数异常!");
|
|
//检查托盘
|
var wareContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == input.WmsContainer.ContainerCode);
|
if (wareContainer == null) throw Oops.Oh("容器信息不存在!");
|
if (wareContainer.ContainerStatus == ContainerStatus.JINYONG) throw Oops.Oh("容器已禁用!");
|
if (wareContainer.ContainerStatus == ContainerStatus.KUWEI) throw Oops.Oh("容器在库位不可使用!");
|
if (wareContainer.ContainerStatus != ContainerStatus.FENJIAN) throw Oops.Oh("容器不存在分拣信息!");
|
|
var wmsMaterialContainers = await _wmsMaterialContainerRep
|
.Where(p => p.ContainerCode == input.WmsContainer.ContainerCode && p.BindStatus == CommonStatus.ENABLE).ToListAsync();
|
foreach (var item in input.WmsSortOrderList)
|
{
|
var wmsMaterialContainerModel = wmsMaterialContainers.FirstOrDefault(p => p.MaterialNo == item.Materialcode);
|
if (wmsMaterialContainerModel != null)
|
{
|
if (wmsMaterialContainerModel.BindQuantity < item.ActualQuantity) throw Oops.Oh("分拣组盘异常!");
|
wmsMaterialContainerModel.BindQuantity -= item.ActualQuantity;
|
if (wmsMaterialContainerModel.BindQuantity <= 0)
|
{
|
wmsMaterialContainers.Remove(wmsMaterialContainerModel);
|
await _wmsMaterialContainerRep.DeleteAsync(wmsMaterialContainerModel);
|
}
|
else
|
{
|
await _wmsMaterialContainerRep.UpdateAsync(wmsMaterialContainerModel);
|
}
|
}
|
var stockModel = await _wmsMaterialStockRep.FirstOrDefaultAsync(p => p.ContainerCode == wareContainer.ContainerCode && p.MaterialNo == item.Materialcode);
|
if (stockModel != null)
|
{
|
if (stockModel.StockNumber < item.ActualQuantity) throw Oops.Oh("分拣库存异常!");
|
stockModel.StockNumber -= item.ActualQuantity;
|
if (stockModel.StockNumber <= 0) await _wmsMaterialStockRep.DeleteAsync(stockModel);
|
else await _wmsMaterialStockRep.UpdateAsync(stockModel);
|
}
|
|
// 这里还需要根据实际下发数来更新分拣状态
|
var wareSortOrderModel = await _wmsSortOrderRep.FirstOrDefaultAsync(p => p.ContainerCode == wareContainer.ContainerCode
|
&& p.SortStatus != SortStatusEnum.FENJIANWANCHENG && p.Materialcode == item.Materialcode);
|
|
if (wareSortOrderModel != null)
|
{
|
wareSortOrderModel.ActualQuantity += item.ActualQuantity;
|
|
if (wareSortOrderModel.ActualQuantity >= wareSortOrderModel.SortQuantity)
|
{
|
wareSortOrderModel.SortStatus = SortStatusEnum.FENJIANWANCHENG;
|
_wmsSortOrderRep.UpdateNow(wareSortOrderModel);
|
|
// 分拣单完成后判断出库明细是否完成
|
}
|
else
|
{
|
wareSortOrderModel.SortStatus = SortStatusEnum.FENJIANZHONG;
|
_wmsSortOrderRep.UpdateNow(wareSortOrderModel);
|
}
|
}
|
}
|
|
var wareSortOrderCount = await _wmsSortOrderRep
|
.Where(p => p.ContainerCode == input.WmsContainer.ContainerCode && p.SortStatus != SortStatusEnum.FENJIANWANCHENG).CountAsync();
|
|
//更新托盘状态,分拣完成
|
if (wareSortOrderCount == 0)
|
{
|
if (wmsMaterialContainers.Count == 0) wareContainer.ContainerStatus = ContainerStatus.KOUXIAN;
|
else wareContainer.ContainerStatus = ContainerStatus.ZUPANG;
|
// 更新容器状态
|
await _wmsContainerRep.UpdateAsync(wareContainer);
|
}
|
}
|
|
|
/// <summary>
|
/// pda出库单查询
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("SortPdaPage")]
|
public async Task<PageResult<SortPdaPageOutput>> SortPdaPage([FromQuery] SortPdaPageInput input)
|
{
|
var wmsTakeMaterialOrder = await _wmsTakeMaterialOrderRep.DetachedEntities
|
.Where(!string.IsNullOrEmpty(input.No), u => EF.Functions.Like(u.NO, $"%{input.No.Trim()}%"))
|
.ProjectToType<SortPdaPageOutput>()
|
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
return wmsTakeMaterialOrder;
|
}
|
|
/// <summary>
|
/// pda根据出库单获取分拣单明细
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("SortPdaDetailPage")]
|
public async Task<PageResult<SortPdaDetailPageOutput>> SortPdaDetailPage([FromQuery] SortPdaDetailPageInput input)
|
{
|
var wmsTakeMaterialOrder = await _wmsSortOrderRep.DetachedEntities
|
.Where(x=>x.OrderNo ==input.No)
|
.ProjectToType<SortPdaDetailPageOutput>()
|
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
return wmsTakeMaterialOrder;
|
}
|
}
|
}
|