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)
{
}
}
}
}