using Admin.NET.Application.CommonHelper;
|
using Admin.NET.Application.Entity;
|
using Admin.NET.Core.Helper.ExcelHelper;
|
using DocumentFormat.OpenXml.Wordprocessing;
|
using Elastic.Clients.Elasticsearch.Snapshot;
|
using Furion.DatabaseAccessor;
|
using Microsoft.AspNetCore.Http;
|
using MimeKit;
|
using System.Data;
|
using System.Text;
|
using System.Web;
|
using static SKIT.FlurlHttpClient.Wechat.Api.Models.ChannelsECMerchantAddFreightTemplateRequest.Types.FreightTemplate.Types;
|
|
namespace Admin.NET.Application;
|
/// <summary>
|
/// 移动单服务
|
/// </summary>
|
[ApiDescriptionSettings(ApplicationConst.WmsOrderGroupName, Order = 100)]
|
public class WmsOrderMovementService : IDynamicApiController, ITransient
|
{
|
private readonly SqlSugarRepository<WmsOrderMovement> _rep;
|
private readonly SqlSugarRepository<WmsStockQuan> _WmsStockQuanRep;
|
private readonly SqlSugarRepository<WmsOrderMovementDetails> _WmsOrderMovementDetailsRep;
|
private readonly SqlSugarRepository<V_WmsOrderMovementDetails> _v_wmsOrderMovementDetailsRep;
|
private readonly SqlSugarRepository<WmsBaseCustomer> _BaseCustomerRep;
|
private readonly SqlSugarRepository<WmsBaseMaterial> _wmsMaterialRep;
|
private readonly SqlSugarRepository<WmsBaseBusinessType> _WmsBaseBusinessTypeRep;
|
private readonly SqlSugarRepository<WmsConfigNoRule> _WmsNoCreateRuleRep;
|
private readonly SqlSugarRepository<WmsConfigSerialSN> _repSNRep;
|
private readonly SqlSugarRepository<WmsConfigSerialRule> _repRuleDetailRep;
|
private readonly SqlSugarRepository<WmsOrderDeliverDetails> _WmsOrderDeliverDetailsRep;
|
private readonly SqlSugarRepository<WmsLogAction> _wareActionLogRep;
|
private readonly WmsStockQuanService _wmsStockQuanService;
|
private readonly SqlSugarRepository<WmsBasePlace> _wmsPlaceRep;
|
private readonly SqlSugarRepository<WmsBaseContainer> _wmsContainerRep;
|
private readonly SqlSugarRepository<WmsContainerPlace> _wmsContainerPlace;
|
private readonly SqlSugarRepository<WmsOrderMovement> _wmsOrderMovementRep;
|
private readonly SqlSugarRepository<WmsBaseArea> _wmsAreaRep;
|
private readonly SqlSugarRepository<v_wms_stock_quan> _v_wms_stock_quanRep;
|
private readonly SqlSugarRepository<v_wms_base_container> _v_wms_containerRep;
|
private readonly SqlSugarRepository<WmsTask> _wmsTask;
|
|
|
|
|
public WmsOrderMovementService(
|
SqlSugarRepository<WmsOrderMovement> rep,
|
SqlSugarRepository<WmsStockQuan> wmsStockQuanRep,
|
SqlSugarRepository<WmsOrderMovementDetails> wmsOrderMovementDetailsRep,
|
SqlSugarRepository<WmsBaseCustomer> baseCustomerRep,
|
SqlSugarRepository<WmsBaseBusinessType> WmsBaseBusinessTypeRep,
|
SqlSugarRepository<WmsConfigNoRule> wmsNoCreateRuleRep,
|
SqlSugarRepository<WmsConfigSerialSN> repSNRep,
|
SqlSugarRepository<WmsConfigSerialRule> repRuleDetailRep,
|
SqlSugarRepository<WmsOrderDeliverDetails> WmsOrderDeliverDetailsRep
|
, SqlSugarRepository<WmsLogAction> wareActionLogRep
|
,
|
WmsStockQuanService wmsStockQuanService,
|
SqlSugarRepository<V_WmsOrderMovementDetails> v_wmsOrderMovementDetailsRep
|
,
|
SqlSugarRepository<WmsBaseMaterial> WmsMaterial,
|
SqlSugarRepository<WmsBaseBusinessType> WmsBaseBusinessType,
|
SqlSugarRepository<WmsBasePlace> wmsPlaceRep,
|
SqlSugarRepository<WmsBaseContainer> wmsContainerRep,
|
SqlSugarRepository<WmsContainerPlace> wmsContainerPlace,
|
SqlSugarRepository<WmsOrderMovement> wmsOrderMovementRep,
|
SqlSugarRepository<WmsBaseArea> wmsAreaRep,
|
SqlSugarRepository<v_wms_stock_quan> v_wms_stock_quanRep,
|
SqlSugarRepository<v_wms_base_container> v_wms_containerRep,
|
SqlSugarRepository<WmsTask> wmsTask
|
)
|
{
|
_v_wmsOrderMovementDetailsRep = v_wmsOrderMovementDetailsRep;
|
_rep = rep;
|
_WmsStockQuanRep = wmsStockQuanRep;
|
_WmsOrderMovementDetailsRep = wmsOrderMovementDetailsRep;
|
_BaseCustomerRep = baseCustomerRep;
|
_WmsBaseBusinessTypeRep = WmsBaseBusinessTypeRep;
|
_WmsNoCreateRuleRep = wmsNoCreateRuleRep;
|
_repSNRep = repSNRep;
|
_repRuleDetailRep = repRuleDetailRep;
|
_WmsOrderDeliverDetailsRep = WmsOrderDeliverDetailsRep;
|
_wareActionLogRep = wareActionLogRep;
|
_wmsStockQuanService = wmsStockQuanService;
|
_wmsMaterialRep = WmsMaterial;
|
_WmsBaseBusinessTypeRep = WmsBaseBusinessType;
|
_wmsPlaceRep = wmsPlaceRep;
|
_wmsContainerRep = wmsContainerRep;
|
_wmsContainerPlace = wmsContainerPlace;
|
_wmsOrderMovementRep = wmsOrderMovementRep;
|
_wmsAreaRep = wmsAreaRep;
|
_v_wms_stock_quanRep = v_wms_stock_quanRep;
|
_v_wms_containerRep = v_wms_containerRep;
|
_wmsTask = wmsTask;
|
}
|
|
/// <summary>
|
/// 分页查询移动单
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "Page")]
|
[Description("WmsOrderMovement/Page")]
|
public async Task<SqlSugarPagedList<WmsOrderMovementOutput>> Page(WmsOrderMovementInput input)
|
{
|
var query = CommonPageFilter(input);
|
return await query
|
.OrderBy(x => x.OrderStatus).OrderByDescending(x => x.CreateTime)
|
//.OrderBuilder(input)
|
.ToPagedListAsync(input.Page, input.PageSize);
|
}
|
|
/// <summary>
|
/// 不分页查询移动单
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet]
|
[ApiDescriptionSettings(Name = "List")]
|
[Description("WmsOrderMovement/List")]
|
public async Task<List<WmsOrderMovementOutput>> List([FromQuery] WmsOrderMovementInput input)
|
{
|
var query = CommonPageFilter(input);
|
return await query.OrderBuilder(input, "", "Id").Select<WmsOrderMovementOutput>().ToListAsync();
|
}
|
|
/// <summary>
|
/// 增加移动单
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "Add")]
|
[Description("WmsOrderMovement/Add")]
|
public async Task<long> Add(AddWmsOrderMovementInput input)
|
{
|
var entity = input.Adapt<WmsOrderMovement>();
|
|
//重复性验证
|
await CheckExist(entity);
|
|
await _rep.InsertAsync(entity);
|
return entity.Id;
|
}
|
|
|
|
/// <summary>
|
/// 增加下架单
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "AddOff")]
|
[Description("WmsOrderMovement/AddOff")]
|
[UnitOfWork]
|
public async Task<List<WmsOrderMovementDetails>> AddOff(DiyAddWmsOrderMovementInput input)
|
{
|
if (input.orderDetails is null || input.orderDetails.Count == 0)
|
{
|
throw Oops.Oh("明细不能为空");
|
}
|
var hearId = await AddOrderEFsql(input);
|
return hearId;
|
}
|
|
private async Task<List<WmsOrderMovementDetails>> AddOrderEFsql(DiyAddWmsOrderMovementInput input)
|
{
|
//新增表头
|
var warehousOrder = input.Adapt<WmsOrderMovement>();
|
var hearId = Yitter.IdGenerator.YitIdHelper.NextId();
|
warehousOrder.Id = hearId;
|
|
warehousOrder.OrderType = OrderTypeEnum.下架单;
|
warehousOrder.OrderTypeName = OrderTypeEnum.下架单.GetDescription();
|
warehousOrder.BusinessType = (int)input.BusinessType;
|
var entity = await _WmsBaseBusinessTypeRep.GetFirstAsync(u => u.BusinessTypeValue == (int)input.BusinessType);
|
if (entity == null)
|
{
|
throw Oops.Oh("业务类型名称获取失败");
|
}
|
|
if (string.IsNullOrWhiteSpace(warehousOrder.ToPlaceCode) && string.IsNullOrWhiteSpace(warehousOrder.ToAreaCode))
|
{
|
throw Oops.Oh($"目标库区、目标库位不能同时为空");
|
}
|
|
warehousOrder.BusinessTypeName = entity.BusinessTypeName;
|
//warehousOrder.BusinessTypeName = GetEnumDescriptionUtil.GetEnumDescription(input.BusinessType);
|
warehousOrder.OrderSocure = input.OrderSocure == null ? SourceByEnum.自建 : input.OrderSocure;
|
warehousOrder.OrderStatus = OrderStatusEnum.新建;
|
warehousOrder.OrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建);
|
|
// 获取当前时间
|
DateTime currentTime = DateTime.Now;
|
|
// 格式化为年月日字符串
|
string formattedDate = currentTime.ToString("yyyyMMdd");
|
|
//按照单号规则生成单号 - 查找最新的创建的一条单据记录
|
var newestOrder = await _rep.AsQueryable().Where(p => p.OrderType == OrderTypeEnum.下架单).Where(p => p.OrderNo.Contains(formattedDate)).OrderBy(it => it.CreateTime, OrderByType.Desc)
|
.FirstAsync();
|
//按照单号规则生成单号-ly
|
warehousOrder.OrderNo = await SerialUtilOrder.GetSerialOrder(OrderTypeEnum.下架单, _WmsNoCreateRuleRep, _repSNRep, (int)warehousOrder.BusinessType,
|
newestOrder == null ? null : newestOrder.OrderNo);
|
if (warehousOrder.OrderNo == null || warehousOrder.OrderNo == "")
|
{
|
warehousOrder.OrderNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString();
|
}
|
|
if (input.FinancialType.HasValue)
|
{
|
warehousOrder.FinancialTypeName = GetEnumDescriptionUtil.GetEnumDescription(input.FinancialType);
|
}
|
if (!String.IsNullOrEmpty(input.CustCode))
|
{
|
var Item_BaseCustomer = await _BaseCustomerRep.GetFirstAsync(u => u.CustCode == input.CustCode);
|
if (Item_BaseCustomer != null)
|
{
|
warehousOrder.CustCode = Item_BaseCustomer.CustCode;
|
warehousOrder.CustChinaName = Item_BaseCustomer.CustChinaName;
|
warehousOrder.CustEnglishName = Item_BaseCustomer.CustEnglishName;
|
}
|
else
|
{
|
throw Oops.Oh("客户编号不正确!");
|
}
|
}
|
|
|
//新增明细
|
var warehousOrderDetails1 = input.orderDetails.Adapt<List<WmsOrderMovementDetails>>();
|
|
//--------ly关联DO单 入口是DO单,寻找需要更新的DO单明细
|
|
await HandleValidDoDetail(input);
|
|
//--------ly关联DO单 入口是DO单,寻找需要更新的DO单明细
|
|
int index = 0;
|
|
foreach (var w in warehousOrderDetails1)
|
{
|
if (w.Quantity <= 0)
|
{
|
throw Oops.Oh("创建失败:数量需要大于0");
|
}
|
var idMaterial = Yitter.IdGenerator.YitIdHelper.NextId();
|
index++;
|
string myLineNumeber = index.ToString();
|
w.Id = idMaterial;
|
w.MovementNo = warehousOrder.OrderNo;
|
w.MovementId = warehousOrder.Id;
|
w.OrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建);
|
w.LineNumber = OrderHelper.AutoCompleEBELP(myLineNumeber, 4);
|
if (!String.IsNullOrEmpty(warehousOrder.CustCode))
|
{
|
w.CustCode = warehousOrder.CustCode;
|
w.CustName = warehousOrder.CustChinaName;
|
}
|
w.Unit = w.Unit;
|
w.IsDelete = false;
|
}
|
|
try
|
{
|
// await _rep.AsTenant().BeginTranAsync();
|
//插入主表
|
if (warehousOrder != null)
|
{
|
await _rep.InsertAsync(warehousOrder);
|
}
|
//插入明细表
|
if (warehousOrderDetails1.Count > 0)
|
{
|
await _WmsOrderMovementDetailsRep.InsertRangeAsync(warehousOrderDetails1);
|
}
|
// await _rep.AsTenant().CommitTranAsync();
|
}
|
catch
|
{
|
// await _rep.AsTenant().RollbackTranAsync();
|
throw;
|
}
|
return warehousOrderDetails1;
|
}
|
|
|
/// <summary>
|
/// 验证Do单是否还有物料可用
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
|
private async Task HandleValidDoDetail(DiyAddWmsOrderMovementInput input)
|
{
|
|
//------------ly-0726 验证下架单和do-----------
|
List<WmsOrderMovementDetails> handleListXjd = new List<WmsOrderMovementDetails>();
|
List<WmsOrderDeliverDetails> handleListDeliverDetails = new List<WmsOrderDeliverDetails>();
|
List<string> queryCodeListForXjd = input.orderDetails.Where(v=> !String.IsNullOrEmpty(v.RelationNo) == true).Select(v => v.RelationNo).Distinct().ToList(); //DoNo
|
if (queryCodeListForXjd.Count > 0)
|
{
|
//查询下架单中已关联do的数据
|
handleListXjd = await _WmsOrderMovementDetailsRep.GetListAsync(u => queryCodeListForXjd.Contains(u.RelationNo) && u.IsDelete == false);
|
//查询所有相关Do的数据
|
handleListDeliverDetails = await _WmsOrderDeliverDetailsRep.GetListAsync(u => queryCodeListForXjd.Contains(u.DoNo) && u.IsDelete == false);
|
}
|
|
foreach (var item in input.orderDetails)
|
{
|
if (!String.IsNullOrEmpty(item.RelationNo))
|
{
|
//所有DO总数
|
decimal hasUsedDoQty = handleListDeliverDetails.Where(x => x.MaterialCode == item.MaterialCode && x.DoLineNumber == item.RelationNoLineNumber && x.DoNo == item.RelationNo &&
|
(x.DoDetailStatus == OrderStatusEnum.新建 || x.DoDetailStatus == OrderStatusEnum.处理中)).Sum(x => x.Quantity);
|
|
if (hasUsedDoQty > 0)
|
{
|
//所有下架单中已关联Do总数
|
decimal hasUsedPoQtyInXjd = handleListXjd.Where(x => x.MaterialCode == item.MaterialCode && x.RelationNoLineNumber == item.RelationNoLineNumber && x.RelationNo == item.RelationNo &&
|
(x.OrderStatus == OrderStatusEnum.新建 || x.OrderStatus == OrderStatusEnum.处理中) && x.MovementNo != item.MovementNo).Sum(x => (decimal)x.Quantity);
|
|
|
if (hasUsedDoQty < hasUsedPoQtyInXjd) //下架单中已关联po总数
|
{
|
throw Oops.Oh($"创建失败:DO单号{item.RelationNo},物料编号{item.MaterialCode},DO行号{item.RelationNoLineNumber}需求数量{hasUsedDoQty}已全部创建下架单!");
|
}
|
|
decimal usedQtyHasNow = hasUsedDoQty - hasUsedPoQtyInXjd;
|
if (usedQtyHasNow < item.Quantity)
|
{
|
throw Oops.Oh($"创建失败:DO单号{item.RelationNo},物料编号{item.MaterialCode},DO行号{item.RelationNoLineNumber}剩余可用数{usedQtyHasNow}!");
|
}
|
}
|
|
|
}
|
}
|
}
|
|
|
/// <summary>
|
/// 取消移动单 -下架单 ly
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "Delete")]
|
[Description("WmsOrderMovement/Delete")]
|
public async Task Delete(DeleteWmsOrderMovementInput input)
|
{
|
var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
entity.OrderStatus = OrderStatusEnum.已取消;
|
entity.OrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已取消);
|
var OrderDetails = await _WmsOrderMovementDetailsRep.AsQueryable()
|
.Where(x => x.MovementId == entity.Id)
|
.Where(u => u.IsDelete == false)
|
.Select<WmsOrderMovementDetails>()
|
.ToListAsync();
|
//取消明细
|
List<WmsOrderMovementDetails> deleteWareOrderDetails = new List<WmsOrderMovementDetails>();
|
var deleteList = OrderDetails.Where(x => x.IsDelete == false).ToList();
|
foreach (var item in deleteList)
|
{
|
if (item.OrderStatus != OrderStatusEnum.新建)
|
{
|
throw Oops.Oh($"物料{item.MaterialCode}的状态{item.OrderStatusName},不允许取消");
|
}
|
item.OrderStatus = OrderStatusEnum.已取消;
|
item.OrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已取消);
|
deleteWareOrderDetails.Add(item);
|
}
|
try
|
{
|
await _rep.AsTenant().BeginTranAsync();
|
await _rep.UpdateAsync(entity); //更新状态
|
await _WmsOrderMovementDetailsRep.UpdateRangeAsync(deleteWareOrderDetails); //更新状态
|
await _rep.AsTenant().CommitTranAsync();
|
}
|
catch
|
{
|
await _rep.AsTenant().RollbackTranAsync();
|
throw;
|
}
|
}
|
|
/// <summary>
|
/// 更新移动单--下架单 ly
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "Update")]
|
[Description("WmsOrderMovement/Update")]
|
public async Task Update(DiyAddWmsOrderMovementInput input)
|
{
|
if (input.orderDetails is null || input.orderDetails.Count == 0)
|
{
|
throw Oops.Oh("明细不能为空");
|
}
|
var dbOrder = await _rep.GetFirstAsync(w => w.OrderNo == input.OrderNo);
|
if (dbOrder == null)
|
{
|
throw Oops.Oh($"订单{input.OrderNo}不存在");
|
}
|
if (dbOrder.OrderStatus != OrderStatusEnum.新建)
|
{
|
throw Oops.Oh($"订单状态{input.OrderStatus}不可操作");
|
}
|
dbOrder.PlannedDate = input.PlannedDate;
|
dbOrder.CostCenter = input.CostCenter;
|
dbOrder.DeliveryAddress = input.DeliveryAddress;
|
dbOrder.FinancialType = input.FinancialType;
|
if (input.FinancialType != null)
|
{
|
dbOrder.FinancialTypeName = GetEnumDescriptionUtil.GetEnumDescription(input.FinancialType);
|
}
|
dbOrder.SourceWarehouseCode = input.SourceWarehouseCode;
|
dbOrder.ToAreaCode = input.ToAreaCode;
|
dbOrder.ToPlaceCode = input.ToPlaceCode;
|
dbOrder.CustCode = input.CustCode;
|
|
var Item_BaseCustomer = await _BaseCustomerRep.GetFirstAsync(u => u.CustCode == input.CustCode);
|
if (Item_BaseCustomer != null)
|
{
|
dbOrder.CustChinaName = Item_BaseCustomer.CustChinaName;
|
dbOrder.CustEnglishName = Item_BaseCustomer.CustEnglishName;
|
}
|
|
dbOrder.Priority = input.Priority;
|
dbOrder.OrderReason = input.OrderReason;
|
|
|
|
var AsnOrderDetails = await _WmsOrderMovementDetailsRep.AsQueryable()
|
.Where(x => x.MovementId == dbOrder.Id)
|
.Where(u => u.IsDelete == false)
|
.Select<WmsOrderMovementDetails>()
|
.ToListAsync();
|
|
List<WmsOrderMovementDetails> addWareAsnOrderDetails = new List<WmsOrderMovementDetails>();
|
List<WmsOrderMovementDetails> updateWareAsnOrderDetails = new List<WmsOrderMovementDetails>();
|
List<WmsOrderMovementDetails> deleteWareAsnOrderDetails = new List<WmsOrderMovementDetails>();
|
|
|
//--------ly关联DO单 入口是DO单,寻找需要更新的DO单明细
|
await HandleValidDoDetail(input);
|
//--------ly关联DO单 入口是DO单,寻找需要更新的DO单明细
|
|
//寻找更新的
|
var updateList = AsnOrderDetails.Where(x => input.orderDetails.Any(p => p.LineNumber == x.LineNumber && p.MaterialCode == x.MaterialCode)).ToList();
|
|
foreach (var item in updateList)
|
{
|
var orderDetails = input.orderDetails.FirstOrDefault(x => x.MaterialCode == item.MaterialCode && x.LineNumber == item.LineNumber);
|
if (orderDetails == null)
|
{
|
continue;
|
}
|
else
|
{
|
if (orderDetails.Quantity<=0)
|
{
|
throw Oops.Oh("创建失败:数量需要大于0");
|
}
|
item.Quantity = (decimal)orderDetails.Quantity;
|
item.LineNumber = orderDetails.LineNumber;
|
item.CustCode = dbOrder.CustCode;
|
item.CustName = dbOrder.CustChinaName;
|
item.ToAreaCode = dbOrder.ToAreaCode;
|
item.ToPlaceCode = dbOrder.ToPlaceCode;
|
}
|
//变更明细的状态
|
updateWareAsnOrderDetails.Add(item);
|
}
|
|
//寻找删除的
|
var deleteList = AsnOrderDetails.Where(x => !input.orderDetails.Any(p => p.LineNumber == x.LineNumber && p.MaterialCode == x.MaterialCode)).ToList();
|
foreach (var item in deleteList)
|
{
|
if (item.CreateWaveQuantity > 0)
|
{
|
throw Oops.Oh($"物料{item.MaterialCode}的已发数量{item.CreateWaveQuantity}大于0,不允许删除");
|
}
|
deleteWareAsnOrderDetails.Add(item);
|
}
|
//获取最大行号
|
var maxAsnLineNumber = AsnOrderDetails.Max(u => u.LineNumber);
|
int index = Convert.ToInt32(maxAsnLineNumber);
|
//寻找新增的
|
var addList = input.orderDetails.Where(x => !AsnOrderDetails.Any(p => p.LineNumber == x.LineNumber && p.MaterialCode == x.MaterialCode)).ToList();
|
foreach (var w in addList)
|
{
|
if (w.Quantity == 0)
|
{
|
throw Oops.Oh("创建失败:数量需要大于0");
|
}
|
index++;//行号递增
|
var newLineNumber = OrderHelper.AutoCompleEBELP(index.ToString(), 4);
|
WmsOrderMovementDetails item = new WmsOrderMovementDetails()
|
{
|
Id = Yitter.IdGenerator.YitIdHelper.NextId(),
|
OrderStatus = OrderStatusEnum.新建,
|
OrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建),
|
MovementNo = dbOrder.OrderNo,
|
MovementId = dbOrder.Id,
|
LineNumber = newLineNumber,
|
MaterialCode = w.MaterialCode,
|
MaterialName = w.MaterialName,
|
SupplierCode = w.SupplierCode,
|
Quantity = (decimal)w.Quantity,
|
PredetermineQuantity = (decimal)w.PredetermineQuantity,
|
PickQuantity = (decimal)w.PickQuantity,
|
OffShelvesQuantity = (decimal)w.OffShelvesQuantity,
|
CreateWaveQuantity = (decimal)w.CreateWaveQuantity,
|
CustCode = dbOrder.CustCode,
|
CustName = dbOrder.CustChinaName,
|
RelationNo= w.RelationNo,
|
RelationNoLineNumber= w.RelationNoLineNumber,
|
Unit = w.Unit,
|
ToAreaCode = dbOrder.ToAreaCode,
|
ToPlaceCode = dbOrder.ToPlaceCode,
|
|
};
|
addWareAsnOrderDetails.Add(item);
|
}
|
try
|
{
|
await _rep.AsTenant().BeginTranAsync();
|
|
await _rep.UpdateAsync(dbOrder);
|
if (addWareAsnOrderDetails.Count > 0)
|
{
|
await _WmsOrderMovementDetailsRep.InsertRangeAsync(addWareAsnOrderDetails);
|
}
|
if (updateWareAsnOrderDetails.Count > 0)
|
{
|
await _WmsOrderMovementDetailsRep.UpdateRangeAsync(updateWareAsnOrderDetails);
|
}
|
if (deleteWareAsnOrderDetails.Count > 0)
|
{
|
await _WmsOrderMovementDetailsRep.DeleteAsync(deleteWareAsnOrderDetails);
|
}
|
await _rep.AsTenant().CommitTranAsync();
|
}
|
catch
|
{
|
await _rep.AsTenant().RollbackTranAsync();
|
throw;
|
}
|
}
|
|
|
/// <summary>
|
/// 获取移动单
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet]
|
[ApiDescriptionSettings(Name = "Detail")]
|
[Description("WmsOrderMovement/Detail")]
|
public async Task<WmsOrderMovement> Detail([FromQuery] QueryByIdWmsOrderMovementInput input)
|
{
|
return await _rep.GetFirstAsync(u => u.Id == input.Id);
|
}
|
|
|
|
|
|
#region 导入
|
|
/// <summary>
|
/// Excel模板导入移动单功能
|
/// </summary>
|
/// <param name="file">Excel模板文件</param>
|
/// <returns>导入的记录数</returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "ImportExcel")]
|
[Description("WmsOrderMovement/ImportExcel")]
|
public async Task<int> ImportExcelAsync(IFormFile file)
|
{
|
//声明下架单新增的参数信息
|
var AddInfoList = new DiyAddWmsOrderMovementInput();
|
int _HeadStartLine = 2;//第1行是说明,第2行是列名
|
int _DataStartLine = 3;//第3行开始是数据
|
DataTable importDataTable = ExcelUtil.ImportExcelToDataTable(file, _HeadStartLine, _DataStartLine);
|
var addList = await CommonImport(importDataTable, _DataStartLine);
|
//var XIAJIATypeList = await _WmsBaseBusinessTypeRep.AsQueryable().Where(p => p.UpDownShelvesType == UpDownShelvesTypeEnum.下架).Select(p => p.BusinessTypeValue).ToListAsync();
|
if (addList.BusinessType == 0) throw Oops.Oh("上传的业务类型编号" + (int)addList.BusinessType + "不正确,请检查后再上传");
|
await AddOff(addList);
|
if (addList.FinancialType != FinancialTypeEnum.测试类型) throw Oops.Oh("财务类型" + (int)addList.FinancialType + "不正确,请检查后再上传");
|
return addList.orderDetails.Count;
|
}
|
|
/// <summary>
|
/// DataTable转换实体对象列表
|
/// </summary>
|
/// <param name="dataTable"></param>
|
/// <param name="dataStartLine">模版列名开始行</param>
|
/// <returns></returns>
|
private async Task<DiyAddWmsOrderMovementInput> CommonImport(DataTable dataTable, int dataStartLine)
|
{
|
var mainOrder = new DiyAddWmsOrderMovementInput();
|
var details = new List<DiyWmsOrderMovementDetailsInput>();
|
int index = dataStartLine;//模版列名开始行
|
foreach (System.Data.DataRow row in dataTable.Rows)
|
{
|
index++;
|
//导入模版定制化代码(替换模版使用)
|
|
var addItem = new DiyWmsOrderMovementDetailsInput();
|
#region 定义变量
|
//主表
|
var _BusinessTypeName = "";//业务类型
|
var _PlannedDate = "";//计划/交货日期
|
var _CostCenter = "";//成本中心
|
var _CustName = "";//客户
|
var _DeliveryAddress = "";//客户发往地
|
var _MainToAreaCode = "";//目标库区
|
var _MainToPlaceCode = "";//目标库位
|
var _MainPriority = ""; //优先级(主表)
|
var _Remarks = "";//单据原因
|
//明细
|
var _MaterialCode = "";//物料编号
|
var _Quantity = "";//数量
|
#endregion
|
|
var BusinessTypeModel = new WmsBaseBusinessType();
|
#region 取值
|
//主表
|
_BusinessTypeName = row["业务类型"]?.ToString();
|
_PlannedDate = row["计划/交货日期"]?.ToString();
|
_CostCenter = row["成本中心"]?.ToString();
|
_CustName = row["客户"]?.ToString();
|
_DeliveryAddress = row["客户发往地"]?.ToString();
|
_MainToAreaCode = row["目标库区"]?.ToString();
|
_MainToPlaceCode = row["目标库位"]?.ToString();
|
_MainPriority = row["优先级"]?.ToString();
|
_Remarks = row["单据原因(可空)"]?.ToString();
|
//明细表
|
_MaterialCode = row["物料编号"]?.ToString();
|
_Quantity = row["数量"]?.ToString();
|
|
|
#endregion
|
if (index == 4)
|
{
|
//主表字段
|
if (string.IsNullOrEmpty(_BusinessTypeName))
|
{
|
throw Oops.Oh($"第{index}行[业务类型]{_BusinessTypeName}不能为空!");
|
}
|
if (!string.IsNullOrEmpty(_BusinessTypeName))
|
{
|
mainOrder.BusinessTypeName = (string)(_BusinessTypeName.Trim());
|
BusinessTypeModel = BusinessTypeHelper.GetBusinessNameInfoFromDB(_BusinessTypeName, _WmsBaseBusinessTypeRep);
|
mainOrder.BusinessType = (BusinessTypeEnum)(int)BusinessTypeModel.BusinessTypeValue;
|
}
|
|
//时间格式判断和提示
|
if (!string.IsNullOrEmpty(_PlannedDate))
|
{
|
var plannedDate = (string)(_PlannedDate.Trim());
|
DateTime dateTime;
|
|
// 尝试使用不同的日期时间格式解析
|
if (DateTime.TryParseExact(plannedDate, new string[] { "yyyyMMdd", "yyyy-MM-dd", "yyyy/MM/dd" }, null, System.Globalization.DateTimeStyles.None, out dateTime))
|
{
|
mainOrder.PlannedDate = dateTime;
|
}
|
else
|
{
|
throw new ArgumentException($"无法将输入字符串 '{plannedDate}' 转换为 DateTime.可以尝试将日期写为“yyyyMMdd\", \"yyyy-MM-dd\", \"yyyy/MM/dd”格式的");
|
}
|
|
|
// mainOrder.PlannedDate = Convert.ToDateTime(Convert.ToDateTime(_PlannedDate.Trim()).ToShortDateString());
|
}
|
|
if (!string.IsNullOrEmpty(_CostCenter))
|
{
|
mainOrder.CostCenter = (string)(_CostCenter.Trim());
|
}
|
//客户
|
if (!string.IsNullOrEmpty(_CustName))
|
{
|
mainOrder.CustCode = (string)(_CustName.Trim());
|
}
|
if (!string.IsNullOrEmpty(_DeliveryAddress))
|
{
|
mainOrder.DeliveryAddress = (string)(_DeliveryAddress.Trim());
|
}
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(_MainToAreaCode))
|
{
|
mainOrder.ToAreaCode = (string)(_MainToAreaCode.Trim());
|
}
|
if (!string.IsNullOrEmpty(_MainToPlaceCode))
|
{
|
mainOrder.ToPlaceCode = (string)(_MainToPlaceCode.Trim());
|
}
|
|
|
if (!string.IsNullOrEmpty(_MainPriority))
|
{
|
if (!int.TryParse(_MainPriority, out int priority) && !string.IsNullOrEmpty(_MainPriority))
|
{
|
throw Oops.Oh($"第{index}行[优先级]{_MainPriority}值不正确!");
|
}
|
if (priority <= 0 && !string.IsNullOrEmpty(_MainPriority))
|
{
|
throw Oops.Oh($"第{index}行[优先级]{_MainPriority}值不能小于等于0!");
|
}
|
else
|
{
|
mainOrder.Priority = priority;
|
}
|
|
}
|
|
if (!string.IsNullOrEmpty(_Remarks))
|
{
|
mainOrder.OrderReason = (string)(_Remarks.Trim());
|
}
|
mainOrder.OrderSocure = SourceByEnum.导入;
|
}
|
|
|
|
//明细表
|
//判断主表信息是否有重复
|
if (!string.IsNullOrEmpty(_PlannedDate))
|
{
|
var plannedDate = (string)(_PlannedDate.Trim());
|
DateTime dateTime;
|
// 尝试使用不同的日期时间格式解析
|
if (DateTime.TryParseExact(plannedDate, new string[] { "yyyyMMdd", "yyyy-MM-dd", "yyyy/MM/dd" }, null, System.Globalization.DateTimeStyles.None, out dateTime))
|
{
|
if (mainOrder.PlannedDate != dateTime)
|
{
|
throw Oops.Oh("excel中交货日期" + (string)(_PlannedDate.Trim()) + "不一致请修改后再导入");
|
}
|
}
|
else
|
{
|
throw new ArgumentException($"无法将输入字符串 '{plannedDate}' 转换为 DateTime.可以尝试将日期写为“yyyyMMdd\", \"yyyy-MM-dd\", \"yyyy/MM/dd”格式的");
|
}
|
}
|
//判断单据中第一条的业务类型和后面是否存在不同的情况,如果有就报错
|
if (mainOrder.BusinessTypeName != _BusinessTypeName) throw Oops.Oh("请检查输入的业务类型是否一致!");
|
if (!string.IsNullOrEmpty(_CostCenter))
|
{
|
if (mainOrder.CostCenter != (string)(_CostCenter.Trim())) throw Oops.Oh("excel中成本中心" + _CostCenter.Trim() + "不一致请修改");
|
}
|
if (!string.IsNullOrEmpty(_CustName))
|
{
|
|
if (mainOrder.CustCode != (string)(_CustName.Trim())) throw Oops.Oh("excel中客户" + _CustName.Trim() + "不一致请修改");
|
}
|
if (!string.IsNullOrEmpty(_DeliveryAddress))
|
{
|
if (mainOrder.DeliveryAddress != (string)(_DeliveryAddress.Trim())) throw Oops.Oh("excel中客户发往地" + _DeliveryAddress.Trim() + "不一致请修改");
|
}
|
if (!string.IsNullOrEmpty(_MainToAreaCode))
|
{
|
if (mainOrder.ToAreaCode != (string)(_MainToAreaCode.Trim())) throw Oops.Oh("excel中目标库区" + _MainToAreaCode.Trim() + "不一致请修改");
|
}
|
if (!string.IsNullOrEmpty(_MainToPlaceCode))
|
{
|
if (mainOrder.ToPlaceCode != (string)(_MainToPlaceCode.Trim())) throw Oops.Oh("excel中目标库位" + _MainToPlaceCode.Trim() + "不一致请修改");
|
}
|
|
|
if (!string.IsNullOrEmpty(_MaterialCode))
|
{
|
addItem.MaterialCode = (string)(_MaterialCode.Trim());
|
}
|
var wmsMaterialInput = new WmsMaterialInput();
|
wmsMaterialInput.MaterialCode = addItem.MaterialCode;
|
//通过物料编号去获取物料信息
|
//var materialInfo = await _wmsStockQuanService.Page(wmsMaterialInput);
|
//var materialList = new List<v_wms_stock_quan_for_use>();
|
//foreach (var item in materialInfo.Items)
|
//{
|
// materialList.Add(item);
|
//}
|
var materialInfo = await _wmsMaterialRep.AsQueryable().FirstAsync(p => p.MaterialCode == addItem.MaterialCode);
|
if (materialInfo == null) throw Oops.Oh("未找到" + addItem.MaterialCode + "物料信息");
|
addItem.MaterialName = materialInfo.MaterialName;
|
addItem.Unit = materialInfo.POUnit;
|
addItem.DispenseQuantity = 0;
|
addItem.PredetermineQuantity = 0;
|
addItem.PickQuantity = 0;
|
if (!string.IsNullOrEmpty(_Quantity))
|
{
|
if (!decimal.TryParse(_Quantity, out decimal quantity) && !string.IsNullOrEmpty(_Quantity))
|
{
|
throw Oops.Oh($"第{index}行[数量]{_Quantity}值不正确!");
|
}
|
if (quantity <= 0 && !string.IsNullOrEmpty(_Quantity))
|
{
|
throw Oops.Oh($"第{index}行[数量]{_Quantity}值不能小于等于0!");
|
}
|
else
|
{
|
addItem.Quantity = quantity;
|
}
|
|
}
|
if (!string.IsNullOrEmpty(_CustName))
|
{
|
addItem.CustCode = (string)(_CustName.Trim());
|
}
|
|
if (!string.IsNullOrEmpty(_MainToAreaCode))
|
{
|
addItem.ToAreaCode = (string)(_MainToAreaCode.Trim());
|
}
|
if (!string.IsNullOrEmpty(_MainToPlaceCode))
|
{
|
addItem.ToPlaceCode = (string)(_MainToPlaceCode.Trim());
|
}
|
|
details.Add(addItem);
|
}
|
mainOrder.orderDetails = details;
|
//验重
|
return mainOrder;
|
}
|
|
/// <summary>
|
/// 根据版本下载移动单的Excel导入模板
|
/// </summary>
|
/// <returns>下载的模板文件</returns>
|
[HttpGet]
|
[ApiDescriptionSettings(Name = "DownloadExcelTemplate")]
|
[Description("WmsOrderMovement/DownloadExcelTemplate")]
|
public IActionResult DownloadExcelTemplate()
|
{
|
string _path = TemplateConst.EXCEL_TEMPLATEFILE_导入模版路径 + $"\\移动单{TemplateConst.EXCEL_TEMPLATEFILE_导入模版名称后缀}.xlsx";
|
var fileName = HttpUtility.UrlEncode($"导入模板(移动单).xlsx", Encoding.GetEncoding("UTF-8"));
|
return new FileStreamResult(new FileStream(_path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName };
|
}
|
|
#endregion
|
|
#region 私有方法
|
|
/// <summary>
|
/// 公共查询移动单条件
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
private ISugarQueryable<WmsOrderMovementOutput> CommonPageFilter(WmsOrderMovementInput input)
|
{
|
var query = _rep.AsQueryable()
|
.WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u =>
|
u.OrderNo.Contains(input.SearchKey.Trim())
|
|| u.CreateUserName.Contains(input.SearchKey.Trim())
|
|| u.UpdateUserName.Contains(input.SearchKey.Trim())
|
)
|
.WhereIF(!string.IsNullOrWhiteSpace(input.OrderNo), u => u.OrderNo.Contains(input.OrderNo.Trim()))
|
.WhereIF(input.OrderType.HasValue, u => u.OrderType == input.OrderType)
|
.WhereIF(input.OrderSocure.HasValue, u => u.OrderSocure == input.OrderSocure)
|
.WhereIF(input.BusinessType.HasValue, u => u.BusinessType == input.BusinessType)
|
.WhereIF(input.OrderStatus.HasValue, u => u.OrderStatus == input.OrderStatus)
|
.Select<WmsOrderMovementOutput>()
|
.OrderBy(n => n.PlannedDate)
|
.OrderBy(n => n.OrderStatus);
|
return query;
|
}
|
|
/// <summary>
|
/// 重复性验证
|
/// </summary>
|
/// <param name="input">验证对象</param>
|
/// <param name="isEdit">是否是编辑</param>
|
/// <returns></returns>
|
private async Task CheckExist(WmsOrderMovement input, bool isEdit = false)
|
{
|
|
|
|
//没有配置组合校验,不需要验重
|
|
|
//没有配置单独校验,不需要验重
|
}
|
|
/// <summary>
|
/// 根据组合校验和单独校验验证数据是否已存在-导入时验证
|
/// </summary>
|
/// <param name="inputs"></param>
|
/// <returns></returns>
|
private async Task CheckExisitForImport(List<WmsOrderMovement> inputs)
|
{
|
if (inputs?.Count <= 0)
|
{
|
throw Oops.Oh($"导入数据不能为空");
|
}
|
//根据组合校验验证表格中中是否已存在相同数据
|
|
|
|
|
|
|
|
|
//根据单独校验验证表格中中是否已存在相同数据
|
|
|
|
}
|
#endregion
|
|
|
|
/// <summary>
|
/// 下架单- 单主表明细导出 ---ly
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet]
|
[ApiDescriptionSettings(Name = "XjdOrderExcelOutting")]
|
[Description("WmsOrderMovement/XjdOrderExcelOutting")]
|
[AllowAnonymous]
|
public async Task<IActionResult> XjdOrderExcelOutting([FromQuery] WmsOrderMovementInput input)
|
{
|
var vs = (from p in _v_wmsOrderMovementDetailsRep.AsQueryable().ToList()
|
join m in _rep.AsQueryable()
|
.WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u =>
|
u.OrderNo.Contains(input.SearchKey.Trim())
|
|| u.CreateUserName.Contains(input.SearchKey.Trim())
|
|| u.UpdateUserName.Contains(input.SearchKey.Trim())
|
)
|
.WhereIF(!string.IsNullOrWhiteSpace(input.OrderNo), u => u.OrderNo.Contains(input.OrderNo.Trim()))
|
.WhereIF(input.OrderType.HasValue, u => u.OrderType == input.OrderType)
|
.WhereIF(input.OrderSocure.HasValue, u => u.OrderSocure == input.OrderSocure)
|
.WhereIF(input.BusinessType.HasValue, u => u.BusinessType == input.BusinessType)
|
.WhereIF(input.OrderStatus.HasValue, u => u.OrderStatus == input.OrderStatus).ToList() on p.MovementId equals m.Id
|
select new WmsOrderMovementExcelOutput
|
{
|
OrderNo = m.OrderNo,
|
BusinessTypeName = m.BusinessTypeName,
|
OrderSocure = m.OrderSocure,
|
OrderStatusName = m.OrderStatusName,
|
PlannedDate = m.PlannedDate,
|
CreateTime = m.CreateTime,
|
UpdateTime = m.UpdateTime,
|
CreateUserName = m.CreateUserName,
|
UpdateUserName = m.UpdateUserName,
|
CostCenter = m.CostCenter,
|
MaterialName = p.MaterialName,
|
MaterialCode = p.MaterialCode,
|
Quantity = p.Quantity,
|
PredetermineQuantity = p.PredetermineQuantity,
|
DispenseQuantity = p.DispenseQuantity,
|
PickQuantity = p.PickQuantity,
|
OffShelvesQuantity = p.OffShelvesQuantity,
|
CreateWaveQuantity = p.CreateWaveQuantity,
|
Unit = p.Unit,
|
ErpCode = p.ErpCode,
|
SupplierBatch = p.SupplierBatch,
|
Batch = p.Batch,
|
ContainerCode = p.ContainerCode,
|
SourcePlaceCode = p.SourcePlaceCode,
|
RelationNo = p.RelationNo,
|
ErpOrderNo = p.ErpOrderNo,
|
ToPlaceName = p.ToPlaceName,
|
SourceAreaCode = p.SourceAreaCode,
|
SupplierCode = p.SupplierCode,
|
FinancialTypeName = m.FinancialTypeName,
|
SourceWarehouseName = m.SourceWarehouseName,
|
ToAreaCode = m.ToAreaCode,
|
ToPlaceCode = m.ToPlaceCode,
|
Priority = m.Priority,
|
OrderReason = m.OrderReason
|
|
}).ToList();
|
var fileName = "下架单详情";
|
var excelBaseResult = new Excel2003Result<WmsOrderMovementExcelOutput>(vs, fileName, false, "下架单导出详情");
|
return new FileStreamResult(excelBaseResult.GetExcelStream(), "application/vnd.ms-excel");
|
}
|
|
|
/// <summary>
|
/// 关闭上架单 下架单-ly0708
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "CloseOrder")]
|
[Description("WmsOrderMovement/CloseOrder")]
|
public async Task CloseOrder(DeleteWmsOrderMovementInput input)
|
{
|
var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
if (entity.OrderStatus == OrderStatusEnum.已完成 || entity.OrderStatus == OrderStatusEnum.已取消)
|
{
|
throw Oops.Oh($"单据状态{entity.OrderStatusName},不允许操作!");
|
}
|
entity.OrderStatus = OrderStatusEnum.已关闭;
|
entity.OrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已关闭);
|
var OrderDetails = await _WmsOrderMovementDetailsRep.AsQueryable()
|
.Where(x => x.MovementId == entity.Id)
|
.Where(u => u.IsDelete == false)
|
.Select<WmsOrderMovementDetails>()
|
.ToListAsync();
|
//关闭明细
|
List<WmsOrderMovementDetails> deleteWareOrderDetails = new List<WmsOrderMovementDetails>();
|
var deleteList = OrderDetails.Where(x => x.IsDelete == false).ToList();
|
foreach (var item in deleteList)
|
{
|
item.OrderStatus = OrderStatusEnum.已关闭;
|
item.OrderStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已关闭);
|
deleteWareOrderDetails.Add(item);
|
}
|
|
// ----------------记录操作日志
|
List<WmsLogAction> addWareActionLogList = new List<WmsLogAction>();
|
string actionTitle = $"{OrderTypeEnum.下架单}{entity.OrderNo}{GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已关闭)}";//操作履历标题
|
if (entity.OrderType == OrderTypeEnum.上架单)
|
{
|
actionTitle = $"{OrderTypeEnum.上架单}{entity.OrderNo}{GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已关闭)}";//操作履历标题
|
}
|
var idWmsLogAction = Yitter.IdGenerator.YitIdHelper.NextId();
|
WmsLogAction wareActionLog = CommonHelper. LogActionHelper.CreateWmsLogAction(idWmsLogAction, actionTitle);
|
addWareActionLogList.Add(wareActionLog);
|
// ----------------记录操作日志
|
|
|
try
|
{
|
await _rep.AsTenant().BeginTranAsync();
|
|
await _rep.UpdateAsync(entity); //更新状态
|
await _WmsOrderMovementDetailsRep.UpdateRangeAsync(deleteWareOrderDetails); //更新状态
|
await _wareActionLogRep.InsertRangeAsync(addWareActionLogList); //操作日志
|
|
await _rep.AsTenant().CommitTranAsync();
|
}
|
catch
|
{
|
await _rep.AsTenant().RollbackTranAsync();
|
throw;
|
}
|
}
|
|
|
|
/// <summary>
|
/// 下架单绑定物料-分页查询可用库存,按照物料名称分组
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "GetKcMaterialGroup")]
|
[Description("WmsOrderMovement/GetKcMaterialGroup")]
|
public async Task<SqlSugarPagedList<WmsOrderMovementKcForMaterialOutput>> GetKcMaterialGroup(WmsOrderMovementKcForMaterialInput input)
|
{
|
throw Oops.Oh("此方法不再使用了,请调用接口 v_wms_stock_quan_group/Page!");
|
/*
|
物料编号汇总的数量
|
* **/
|
//var query = _v_wms_stock_quan_use_groupRep.AsQueryable()
|
// //.WhereIF(!string.IsNullOrWhiteSpace(input.MaterialName), u => u.MaterialName.Contains(input.MaterialName.Trim()))
|
// //.WhereIF(!string.IsNullOrWhiteSpace(input.SnCode), u => u.SNCode.Contains(input.SnCode.Trim()))
|
// .WhereIF(!string.IsNullOrWhiteSpace(input.MaterialCode), u => u.MaterialCode.Contains(input.MaterialCode.Trim()))
|
// //.Where(p => p.ContainerIsDisabled == false)
|
// //.Where(p => p.PlaceStatus == PlaceStatusEnum.正常)
|
// .Select<WmsOrderMovementKcForMaterialOutput>();
|
//return await query.OrderBuilder(input, "", "MaterialCode").ToPagedListAsync(input.Page, input.PageSize);
|
}
|
|
/// <summary>
|
/// 点到点搬运
|
/// </summary>
|
/// <returns></returns>
|
[HttpPost]
|
[ApiDescriptionSettings(Name = "PointToPoint")]
|
[Description("WmsOrderMovement/PointToPoint")]
|
[UnitOfWork]
|
public async Task PointToPoint(PointToPointInput input)
|
{
|
var wmsContainerPlaceModal = new WmsContainerPlace();
|
if (!string.IsNullOrEmpty(input.SourcePlaceCode))
|
{
|
// 校验原库位是否存在
|
var sourcePlaceModal = await _wmsPlaceRep.GetFirstAsync(n => n.PlaceCode == input.SourcePlaceCode && n.IsDelete == false);
|
|
if (sourcePlaceModal == null) throw Oops.Oh($"扫描库位{input.SourcePlaceCode}不存在,请重新扫描!");
|
|
// 校验库位容器关系
|
wmsContainerPlaceModal = await _wmsContainerPlace.GetFirstAsync(n => n.PlaceId == sourcePlaceModal.Id && n.IsDelete == false);
|
|
if (wmsContainerPlaceModal == null) throw Oops.Oh("来源库位不存在需搬运的容器,请重新扫描!");
|
}
|
if (!string.IsNullOrEmpty(input.ContainerCode))
|
{
|
// 校验容器是否存在
|
var containerModal = await _wmsContainerRep.GetFirstAsync(n => n.ContainerCode == input.ContainerCode && n.IsDelete == false);
|
|
if (containerModal == null) throw Oops.Oh($"该容器{input.ContainerCode}不存在,请重新扫描!");
|
|
// 校验库位容器关系
|
wmsContainerPlaceModal = await _wmsContainerPlace.GetFirstAsync(n => n.ContainerId == containerModal.Id && n.IsDelete == false);
|
|
if (wmsContainerPlaceModal == null) throw Oops.Oh($"该容器{input.ContainerCode}未绑定库位,不可搬运!请先绑定库位!");
|
|
}
|
// 校验目标库位是否存在
|
var toPlaceModal = await _wmsPlaceRep.GetFirstAsync(n => n.PlaceCode == input.ToPlaceCode && n.IsDelete == false && n.IsDisabled == false);
|
|
//if (toPlaceModal == null) throw Oops.Oh($"扫描目标库位{input.ToPlaceCode}不存在,请重新扫描!");
|
//ly0816 没找到 库位就去库区找任意一个空库位
|
if (toPlaceModal == null)
|
{
|
var toAreaModal = await _wmsAreaRep.GetFirstAsync(n => n.AreaCode == input.ToPlaceCode && n.IsDelete == false && n.IsDisabled == false);
|
if (toAreaModal == null) throw Oops.Oh($"扫描目标库区/库位{input.ToPlaceCode}不存在,请重新扫描!");
|
toPlaceModal = await _wmsPlaceRep.GetFirstAsync(n => n.AreaCode == toAreaModal.AreaCode && n.IsDelete == false && n.IsDisabled == false);
|
if (toPlaceModal == null) throw Oops.Oh($"扫描目标库位库区/库位{input.ToPlaceCode}不存在,请重新扫描!");
|
}
|
|
var _v_wms_container = await _v_wms_containerRep.GetFirstAsync(u => u.ContainerCode == wmsContainerPlaceModal.ContainerCode);
|
|
if(_v_wms_container == null) throw Oops.Oh($"容器视图{wmsContainerPlaceModal.ContainerCode}不存在!");
|
|
BusinessTypeEnum businessTypeEnum = BusinessTypeEnum.点到点移库;
|
var businessTypeInfo = BusinessTypeHelper.GetBusinessTypeInfoFromDB((int)businessTypeEnum, _WmsBaseBusinessTypeRep);
|
// 创建下架单
|
//4 创建上架单
|
var hearId = Yitter.IdGenerator.YitIdHelper.NextId();//上架单ID
|
string orderNo = await OrderHelper.CreateOrderNoByRuleCommon(OrderTypeEnum.移库单, (int)businessTypeEnum, _wmsOrderMovementRep, _WmsNoCreateRuleRep, _repSNRep);
|
|
WmsBaseArea toArea = await BaseInfoHelper.GetAreaByPlace(toPlaceModal, _wmsAreaRep);
|
var addWmsOrderMovement = new WmsOrderMovement()
|
{
|
Id = hearId,
|
OrderNo = orderNo, //按照单号规则生成单号-ly update by liuwq 20240725
|
OrderType = OrderTypeEnum.移库单,
|
OrderTypeName = OrderTypeEnum.移库单.GetDescription(),
|
BusinessType = (int)businessTypeEnum,
|
BusinessTypeName = businessTypeEnum.GetDescription(),
|
OrderStatus = OrderStatusEnum.新建,
|
OrderStatusName = OrderStatusEnum.新建.GetDescription(),
|
|
SourceWarehouseCode = _v_wms_container.WarehouseCode,
|
SourceWarehouseName = _v_wms_container.WarehouseName,
|
ToAreaCode = toArea.AreaCode,
|
ToAreaName = toArea.AreaName,
|
ToPlaceCode = toPlaceModal.PlaceCode,
|
ToPlaceName = toPlaceModal.PlaceName,
|
OrderSocure = SourceByEnum.系统
|
};
|
|
// 添加移动单
|
await _wmsOrderMovementRep.InsertAsync(addWmsOrderMovement);
|
// 通过容器查询到库存
|
var stockList = await _v_wms_stock_quanRep.AsQueryable()
|
.Where(n => n.ContainerCode == wmsContainerPlaceModal.ContainerCode)
|
.ToListAsync();
|
|
List<WmsOrderMovementDetails> addWmsOrderMovementDetailsList = new List<WmsOrderMovementDetails>();
|
int lineNumber = 0;//移动单明细行号
|
foreach (var item in stockList)
|
{
|
if (item.LockStatus==LockStatusEnum.已锁定)
|
{
|
throw Oops.Oh($"容器{item.ContainerCode}上的物料{item.MaterialCode},跟踪码{item.SNCode} 已锁定!"); //ly0816-锁定 可能在分拣
|
}
|
lineNumber++;
|
//3.根据容器的库存创建上架单明细
|
var wmsOrderMovementDetails = new WmsOrderMovementDetails()
|
{
|
MovementId = hearId,
|
MovementNo = addWmsOrderMovement.OrderNo,
|
LineNumber = OrderHelper.AutoCompleEBELP(lineNumber.ToString(), 4),
|
SNCode = item.SNCode,
|
SupplierCode = item.SupplierCode,
|
SupplierName = item.SupplierName,
|
Batch = item.Batch,
|
ErpOrderNo = item.ErpOrderNo,
|
ErpCode = item.ErpCode,
|
Unit = item.MaterialUnit,
|
SupplierBatch = item.SupplierBatch,
|
OrderStatus = OrderStatusEnum.新建,
|
OrderStatusName = OrderStatusEnum.新建.GetDescription(),
|
//ToAreaCode = input.ToAreaCode,
|
//ToPlaceCode = input.ToPlaceCode,
|
ContainerCode = wmsContainerPlaceModal.ContainerCode,
|
ContainerName = wmsContainerPlaceModal.ContainerName,
|
SourceWarehouseCode = _v_wms_container.WarehouseCode,
|
SourceWarehouseName = _v_wms_container.WarehouseName,
|
SourceAreaCode = _v_wms_container.AreaCode,
|
SourceAreaName = _v_wms_container.AreaName,
|
SourcePlaceCode = _v_wms_container.PlaceCode,
|
SourcePlaceName = _v_wms_container.PlaceName,
|
ToPlaceCode = toPlaceModal.PlaceCode,
|
ToPlaceName = toPlaceModal.PlaceName,
|
ToAreaCode = toPlaceModal.AreaCode,
|
ToAreaName = toPlaceModal.AreaName,
|
MaterialCode = item.MaterialCode,
|
MaterialName = item.MaterialName,
|
Quantity = item.Quantity,
|
ActionRemark = "PDA点到点搬运",
|
ActionTime = DateTime.Now
|
};
|
addWmsOrderMovementDetailsList.Add(wmsOrderMovementDetails);
|
}
|
// 添加点到点移动单明细
|
if (addWmsOrderMovementDetailsList.Count > 0)
|
await _WmsOrderMovementDetailsRep.InsertRangeAsync(addWmsOrderMovementDetailsList);
|
|
|
|
var wmsTask = new WmsTask()
|
{
|
MoveType = businessTypeInfo.MoveType,
|
MoveTypeName = businessTypeInfo.MoveTypeName,
|
BusinessType = (int)businessTypeEnum,
|
BusinessTypeName = businessTypeInfo.BusinessTypeName,
|
ContainerCode = wmsContainerPlaceModal.ContainerCode,
|
IsFlagFinish = false,
|
OrderNo = addWmsOrderMovement.OrderNo,
|
TaskDescribe = "点到点",
|
TaskStatus = TaskStatusEnum.新建,
|
TaskStatusName = TaskStatusEnum.新建.GetDescription(),
|
TaskNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(),
|
TaskPriority = 0,
|
TaskName = businessTypeEnum.GetDescription(),
|
SourcePlaceCode = wmsContainerPlaceModal.PlaceCode,//源库位
|
|
ToAreaCode = toArea.AreaCode,
|
ToPlaceCode = toPlaceModal.PlaceCode
|
};
|
// 添加任务
|
await _wmsTask.InsertAsync(wmsTask);
|
}
|
|
}
|