using Admin.NET.Application.CommonHelper;
using Admin.NET.Application.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Admin.NET.Application;
///
/// 下架服务
///
[ApiDescriptionSettings(ApplicationConst.WmsOperationsGroupName, Order = 100)]
public class WmsUnshelveService : IDynamicApiController, ITransient
{
private readonly SqlSugarRepository _wmsPlaceRep;
private readonly SqlSugarRepository _wmsContainerRep;
private readonly SqlSugarRepository _wmsContainerPlaceRep;
private readonly SqlSugarRepository _wmsStockQuanRep;
private readonly SqlSugarRepository _wmsTaskRep;
private readonly SqlSugarRepository _wmsContainerTypeRep;
private readonly SqlSugarRepository _wmsContainerPackagingRep;
private readonly SqlSugarRepository _v_wms_stock_quanRep;
private readonly SqlSugarRepository _wmsOrderMovementRep;
private readonly SqlSugarRepository _wmsOrderMovementDetailsRep;
private readonly SqlSugarRepository _repSNRep;
private readonly SqlSugarRepository _WmsNoCreateRuleRep;
private readonly SqlSugarRepository _wmsLogActionRep;
private readonly SqlSugarRepository _wmsRecordTransRep;
private readonly SqlSugarRepository _wmsBaseBusinessTypeRep;
private readonly SqlSugarRepository _WmsAreaRep;
///
/// 构造函数
///
public WmsUnshelveService(SqlSugarRepository wmsPlaceRep,
SqlSugarRepository wmsContainerRep,
SqlSugarRepository wmsContainerPlaceRep,
SqlSugarRepository wmsStockQuanRep,
SqlSugarRepository wmsTaskRep,
SqlSugarRepository wmsContainerTypeRep,
SqlSugarRepository wmsContainerPackagingRep,
SqlSugarRepository v_wms_stock_quanRep,
SqlSugarRepository wmsOrderMovementRep,
SqlSugarRepository wmsOrderMovementDetailsRep,
SqlSugarRepository repSNRep,
SqlSugarRepository wmsNoCreateRuleRep,
SqlSugarRepository wmsLogActionRep,
SqlSugarRepository wmsRecordTransRep,
SqlSugarRepository wmsBaseBusinessTypeRep,
SqlSugarRepository wmsAreaRep)
{
this._wmsPlaceRep = wmsPlaceRep;
this._wmsContainerRep = wmsContainerRep;
this._wmsContainerPlaceRep = wmsContainerPlaceRep;
this._wmsStockQuanRep = wmsStockQuanRep;
this._wmsTaskRep = wmsTaskRep;
this._wmsContainerTypeRep= wmsContainerTypeRep;
this._wmsContainerPackagingRep= wmsContainerPackagingRep;
this._v_wms_stock_quanRep = v_wms_stock_quanRep;
this._wmsOrderMovementRep= wmsOrderMovementRep;
this._wmsOrderMovementDetailsRep=wmsOrderMovementDetailsRep;
this._repSNRep= repSNRep;
this._WmsNoCreateRuleRep = wmsNoCreateRuleRep;
this._wmsLogActionRep = wmsLogActionRep;
this._wmsRecordTransRep = wmsRecordTransRep;
this._wmsBaseBusinessTypeRep = wmsBaseBusinessTypeRep;
this._WmsAreaRep = wmsAreaRep;
}
///
/// PDA容器下架判断目标库位是否异常
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "GetPlaceInfo", Description = "PDA容器下架判断目标库位是否异常")]
[Description("/Unshelve/GetPlaceInfo")]
public async Task GetPlaceInfo(GetPlaceInfoInput input)
{
var wmsPlace = await _wmsPlaceRep.GetFirstAsync(o => o.PlaceCode == input.PlaceCode && o.IsDelete==false);
if(wmsPlace==null) throw Oops.Oh($"该地标/库位不存在,请检查库位基础数据!");
if (wmsPlace.PlaceStatus == PlaceStatusEnum.锁定)
{
var wmsTask = await _wmsTaskRep.GetFirstAsync(o => o.SourcePlaceCode == wmsPlace.PlaceCode&&o.TaskStatus== TaskStatusEnum.已下发);
throw Oops.Oh($"该库位被任务号{wmsTask.TaskNo}锁定,不可使用!");
}
if(wmsPlace.PlaceStatus== PlaceStatusEnum.封存) throw Oops.Oh($"该库位已冻结,不可使用!如需解冻,请先解冻该库位!");
}
///
/// PDA下架查询-获取物料编号对应的容器类型
///
///
[HttpGet]
[ApiDescriptionSettings(Name = "GetMaterialCodeByInfo", Description = "PDA容器下架查询-获取物料编号对应的容器类型")]
[Description("/Unshelve/GetMaterialCodeByInfo")]
public async Task GetMaterialCodeByInfo([FromQuery] GetMaterialCodeByInfoInput input)
{
if(string.IsNullOrEmpty(input.MaterialCode)) throw Oops.Oh($"物料编号不能为空!!");
var wmsMaterial = await _wmsContainerPackagingRep.AsQueryable().
WhereIF(!string.IsNullOrEmpty(input.MaterialCode), o => o.MaterialCode.Contains(input.MaterialCode.Trim())).FirstAsync();
if (wmsMaterial == null) throw Oops.Oh($"该物料编号{input.MaterialCode}在系统中没有关联容器类型,请先添加容器类型!");
var wmsContainerType = new GetContainerTypeOutPut()
{
ContainerTypeCode = wmsMaterial.ContainerTypeCode,
ContainerTypeName = wmsMaterial.ContainerTypeName,
};
return wmsContainerType;
}
///
/// 容器下架执行
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "ContainerUnshelveExecute", Description = "PDA容器下架确认-创建下架单、调度任务")]
[Description("/Unshelve/ContainerUnshelveExecute")]
public async Task ContainerUnshelveExecute(WmsUnshelveInput input)
{
//ly-0813 添加来源库区
//var AreaCodeItem = await _WmsAreaRep.GetFirstAsync(w => w.AreaCode == input.AreaCode && w.IsDelete == false);
//if (AreaCodeItem==null)
//{
// throw Oops.Oh($"来源库区{input.AreaCode}不存在!");
//}
//获取库存中已上架的容器类型集合按时间排序 排除目标库位是自己的
var contaierList = await _v_wms_stock_quanRep.AsQueryable()
.Where(o => o.PlaceCode != input.PlaceCode && o.ContainerTypeCode == input.ContainerTypeCode && o.MaterialTypeCode=="RQ" && o.IsDelete == false && o.StockStatus==StockStatusEnum.已上架)
.OrderBy(o=>o.CreateTime).ToListAsync();
//判断当前容器类型是否有库存
if (contaierList.Count<=0) throw Oops.Oh($"当前容器类型{input.ContainerTypeCode}没有库存,请先上架该类型的容器!");
//查询第一个容器号的容器组盘集合 不能自己呼叫自己
var contaierInfoList = contaierList
.Where(u => u.ContainerCode == contaierList[0].ContainerCode && u.ContainerCode != input.PlaceCode)
.ToList();
//if (contaierInfoList.Count <= 0)
//{
// throw Oops.Oh($"来源库区{input.AreaCode}没有找到已上架的容器!");
//}
//源库位
string sourcePlaceCode = contaierInfoList[0].PlaceCode;
string sourcePlaceName = contaierInfoList[0].PlaceName;
//if (contaierInfoList[0].PlaceCode == input.PlaceCode)
//{
// throw Oops.Oh($"来源库位{contaierInfoList[0].PlaceCode}和目标库位{input.PlaceCode}相同!");
//}
//新增事务记录
List addWmsRecordTransList = new List();
//新增操作履历
List addWmsLogActionList = new List();
//新增下架单明细
List addWmsOrderMovementDetailsList = new List();
//获取目标库位信息
WmsBasePlace toPlace = null;
if (!string.IsNullOrWhiteSpace(input.PlaceCode))
{
toPlace = await _wmsPlaceRep.GetFirstAsync(w => w.PlaceCode == input.PlaceCode && w.IsDelete == false);
if (toPlace == null)
{
throw Oops.Oh($"目标库位{input.PlaceCode}不存在!");
}
if (toPlace.IsDisabled == true)
{
throw Oops.Oh($"目标库位{input.PlaceCode}已禁用!");
}
if (toPlace.IsVirtually == true)
{
throw Oops.Oh($"目标库位{input.PlaceCode}是虚拟库位!");
}
//库位属性 正常和禁出的可以组盘上架
if (toPlace.PlaceStatus != PlaceStatusEnum.正常 && toPlace.PlaceStatus != PlaceStatusEnum.禁出)
{
throw Oops.Oh($"目标库位{input.PlaceCode}库位属性是{toPlace.PlaceStatus.GetDescription()}!");
}
}
else
{
//用户必须指定一个 库位。
throw Oops.Oh($"目标库位不能为空!");
}
BusinessTypeEnum businessTypeEnum = BusinessTypeEnum.容器下架;
// 获取业务类型 update by liuwq 2024 07 30
var wmsBaseBusinessType = BusinessTypeHelper.GetBusinessTypeInfoFromDB((int)businessTypeEnum, _wmsBaseBusinessTypeRep);
int lineNumber = 0;//移动单明细行号
var hearId = Yitter.IdGenerator.YitIdHelper.NextId();//上架单ID
//3.循环库存信息-创建上架单明细
foreach (var vstockQuan in contaierInfoList)
{
var wmsContainerItem = await _wmsContainerRep.GetFirstAsync(w => w.ContainerCode == vstockQuan.SNCode &&w.IsDelete == false);
if (wmsContainerItem == null) throw Oops.Oh($"容器{vstockQuan.SNCode}不存在!");
if (wmsContainerItem.IsDisabled == true) throw Oops.Oh($"容器{vstockQuan.SNCode}已禁用!");
if (wmsContainerItem.IsVirtually == true) throw Oops.Oh($"容器{vstockQuan.SNCode}是虚拟容器!");
var stockQuan = await _wmsStockQuanRep.GetFirstAsync(w => w.Id==vstockQuan.Id);
if(stockQuan==null) throw Oops.Oh($"容器{vstockQuan.SNCode}不存在!");
if (string.IsNullOrWhiteSpace(vstockQuan.ContainerCode))
{
throw Oops.Oh($"库存{vstockQuan.SNCode}容器号不能为空!");
}
lineNumber++;
#region 创建下架单明细
//3.根据容器的库存创建下架单明细
var wmsOrderMovementDetails = new WmsOrderMovementDetails()
{
MovementId = hearId,
LineNumber = OrderHelper.AutoCompleEBELP(lineNumber.ToString(), 4),//lineNumber.ToString(),
SNCode = vstockQuan.SNCode,
SupplierCode = vstockQuan.SupplierCode,
SupplierName = vstockQuan.SupplierName,
Batch = vstockQuan.Batch,
ErpOrderNo = vstockQuan.ErpOrderNo,
ErpCode = vstockQuan.ErpCode,
Unit = vstockQuan.MaterialUnit,
SupplierBatch = vstockQuan.SupplierBatch,
OrderStatus = OrderStatusEnum.新建,
OrderStatusName = OrderStatusEnum.新建.GetDescription(),
//ToAreaCode = input.ToAreaCode,
//ToPlaceCode = input.ToPlaceCode,
ContainerCode = vstockQuan.ContainerCode,
ContainerName = vstockQuan.ContainerName,
SourceWarehouseCode = vstockQuan.WarehouseCode,
SourceWarehouseName = vstockQuan.WarehouseName,
SourceAreaCode = vstockQuan.AreaCode,
SourceAreaName = vstockQuan.AreaName,
SourcePlaceCode = vstockQuan.PlaceCode,
SourcePlaceName = vstockQuan.PlaceName,
ToPlaceCode = toPlace.PlaceCode,
ToPlaceName = toPlace.PlaceName,
ToAreaCode = toPlace.AreaCode,
ToAreaName = toPlace.AreaName,
MaterialCode = vstockQuan.MaterialCode,
MaterialName = vstockQuan.MaterialName,
Quantity = vstockQuan.Quantity,
ActionRemark = "PDA下架架创建下架单",
ActionTime = DateTime.Now
};
addWmsOrderMovementDetailsList.Add(wmsOrderMovementDetails);
#endregion
#region 转移库存操作日志
string recordTransRemarks = string.Empty;
//新增操作日志
WmsLogAction wareActionLog = LogActionHelper.CreateWmsLogAction(vstockQuan.Id, businessTypeEnum.GetDescription(), recordTransRemarks);
addWmsLogActionList.Add(wareActionLog);
#endregion
}
// 获取当前时间
DateTime currentTime = DateTime.Now;
// 格式化为年月日字符串
string formattedDate = currentTime.ToString("yyyyMMdd");
//按照单号规则生成单号 - 查找最新的创建的一条单据记录
var newestOrder = await _wmsOrderMovementRep.AsQueryable().Where(p => p.OrderType == OrderTypeEnum.下架单).Where(p => p.OrderNo.Contains(formattedDate)).OrderBy(it => it.CreateTime, OrderByType.Desc)
.FirstAsync();
//按照单号规则生成单号-ly
var OrderNoSjd = await SerialUtilOrder.GetSerialOrder(OrderTypeEnum.下架单, _WmsNoCreateRuleRep, _repSNRep, (int)businessTypeEnum, newestOrder == null ? null : newestOrder.OrderNo);
if (OrderNoSjd == null || OrderNoSjd == "")
{
var OrderNoSjdRQ = await SerialUtilOrder.GetSerialOrder(OrderTypeEnum.下架单, _WmsNoCreateRuleRep, _repSNRep, (int)businessTypeEnum, newestOrder == null ? null : newestOrder.OrderNo);
if (OrderNoSjdRQ != null || OrderNoSjdRQ != "")
{
OrderNoSjd = OrderNoSjdRQ;
}
else
{
OrderNoSjd = Yitter.IdGenerator.YitIdHelper.NextId().ToString();
}
}
var businessTypeInfo = BusinessTypeHelper.GetBusinessTypeInfoFromDB((int)businessTypeEnum, _wmsBaseBusinessTypeRep);
//4 创建下架单
var addWmsOrderMovement = new WmsOrderMovement()
{
Id = hearId,
OrderNo = OrderNoSjd, //按照单号规则生成单号-ly
OrderType = OrderTypeEnum.下架单,
OrderTypeName = OrderTypeEnum.下架单.GetDescription(),
BusinessType = (int)businessTypeEnum,
BusinessTypeName = businessTypeEnum.GetDescription(),
OrderStatus = OrderStatusEnum.新建,
OrderStatusName = OrderStatusEnum.新建.GetDescription(),
OrderSocure = SourceByEnum.系统
};
BusinessTypeEnum wmsTaskBusinessTypeEnum = BusinessTypeEnum.容器下架;
//5.创建调度任务
var wmsTask = new WmsTask()
{
MoveType = businessTypeInfo.MoveType,
MoveTypeName = businessTypeInfo.MoveTypeName,
BusinessType = businessTypeInfo.BusinessTypeValue,
BusinessTypeName = businessTypeInfo.BusinessTypeName,
ContainerCode = contaierList.FirstOrDefault().ContainerCode,
IsFlagFinish = false,
OrderNo = addWmsOrderMovement.OrderNo,
TaskDescribe = "PDA容器下架",
TaskStatus = TaskStatusEnum.新建,
TaskStatusName = TaskStatusEnum.新建.GetDescription(),
TaskNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(),
TaskPriority = 0,
TaskName = wmsTaskBusinessTypeEnum.GetDescription(),
ToAreaCode = toPlace.AreaCode,
SourcePlaceCode = sourcePlaceCode,
ToPlaceCode = input.PlaceCode
};
var _tenant = _wmsOrderMovementRep.AsTenant();
try
{
await _tenant.BeginTranAsync();
#region 事务内执行操作
//新增操作日志
await _wmsLogActionRep.InsertRangeAsync(addWmsLogActionList);
if (addWmsOrderMovementDetailsList?.Count > 0)
{
//新增下架单
await _wmsOrderMovementRep.InsertAsync(addWmsOrderMovement);
await _wmsOrderMovementDetailsRep.InsertRangeAsync(addWmsOrderMovementDetailsList);
//新增任务调度
await _wmsTaskRep.InsertAsync(wmsTask);
}
else
{
throw Oops.Oh($"下架单明细为空!");
}
#endregion
await _tenant.CommitTranAsync();
}
catch
{
await _tenant.RollbackTranAsync();
throw;
}
}
}