using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEA_Common.LocationEnum;
|
using WIDESEA_Common.OrderEnum;
|
using WIDESEA_Common.StockEnum;
|
using WIDESEA_Core;
|
using WIDESEA_Core.BaseRepository;
|
using WIDESEA_Core.BaseServices;
|
using WIDESEA_Core.Helper;
|
using WIDESEA_IBasicService;
|
using WIDESEA_IOutboundRepository;
|
using WIDESEA_IOutboundService;
|
using WIDESEA_IRecordService;
|
using WIDESEA_IStockService;
|
using WIDESEA_Model.Models;
|
using WIDESEA_OutboundRepository;
|
|
namespace WIDESEA_OutboundService
|
{
|
public partial class ProOutOrderDetailService : ServiceBase<Dt_ProOutOrderDetail, IProOutOrderDetailRepository>, IProOutOrderDetailService
|
{
|
private readonly IUnitOfWorkManage _unitOfWorkManage;
|
|
public IProOutOrderDetailRepository Repository => BaseDal;
|
private readonly IStockService _stockInfoService;
|
private readonly IBasicService _basicService;
|
private readonly IOutProStockInfoService _outProStockInfoService;
|
private readonly IProOutOrderRepository _proOutOrderRepository;
|
private readonly IRecordService _recordService;
|
public ProOutOrderDetailService(IProOutOrderDetailRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockService stockInfoService, IBasicService basicService,IOutProStockInfoService outProStockInfoService, IRecordService recordService, IProOutOrderRepository proOutOrderRepository) : base(BaseDal)
|
{
|
_unitOfWorkManage = unitOfWorkManage;
|
_stockInfoService = stockInfoService;
|
_basicService = basicService;
|
_outProStockInfoService = outProStockInfoService;
|
_recordService = recordService;
|
_proOutOrderRepository=proOutOrderRepository;
|
}
|
/// <summary>
|
/// 出库库存分配后,更新数据库数据
|
/// </summary>
|
public WebResponseContent LockOutboundStockDataUpdate(List<Dt_ProStockInfo> proStockInfos, List<Dt_ProOutOrderDetail> proOutOrderDetails, List<Dt_OutProStockInfo> outProStockInfos, List<Dt_LocationInfo> locationInfos, LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List<Dt_Task>? tasks = null)
|
{
|
try
|
{
|
//更新库存属性
|
_stockInfoService.ProStockInfoService.Repository.UpdateData(proStockInfos);
|
List<Dt_ProStockInfoDetail> proStockInfoDetails = new List<Dt_ProStockInfoDetail>();
|
foreach (var item in proStockInfos)
|
{
|
proStockInfoDetails.AddRange(item.proStockInfoDetails);
|
}
|
//更新库存明细
|
proStockInfoDetails.ForEach(x => x.ProOutDetailStatus = StockStatusEmun.出库锁定.ObjToInt());
|
_stockInfoService.ProStockInfoDetailService.Repository.UpdateData(proStockInfoDetails);
|
Dt_ProOutOrder proOutOrder = _proOutOrderRepository.QueryFirst(x => x.Id == proOutOrderDetails.FirstOrDefault().ProOrderId);
|
if (proOutOrder.ProOrderStatus == OutOrderStatusEnum.未开始.ObjToInt())
|
{
|
proOutOrder.ProOrderStatus = OutOrderStatusEnum.出库中.ObjToInt();
|
_proOutOrderRepository.UpdateData(proOutOrder);
|
}
|
BaseDal.UpdateData(proOutOrderDetails);
|
|
List<Dt_OutProStockInfo> addOutStockLockInfos = outProStockInfos.Where(x => x.Id == 0).ToList();
|
if (addOutStockLockInfos != null && addOutStockLockInfos.Any())
|
{
|
if (tasks != null)
|
{
|
addOutStockLockInfos.ForEach(x =>
|
{
|
x.TaskNum = tasks.FirstOrDefault(v => v.PalletCode == x.PalletCode)?.TaskNum;
|
});
|
}
|
|
_outProStockInfoService.Repository.AddData(addOutStockLockInfos);
|
}
|
List<Dt_OutProStockInfo> updateOutStockLockInfos = outProStockInfos.Where(x => x.Id > 0).ToList();
|
if (updateOutStockLockInfos != null && updateOutStockLockInfos.Any())
|
{
|
_outProStockInfoService.Repository.UpdateData(updateOutStockLockInfos);
|
}
|
|
_recordService.LocationStatusChangeRecordSetvice.AddLocationStatusChangeRecord(locationInfos, locationStatus, LocationChangeType.OutboundAssignLocation, "", tasks?.Select(x => x.TaskNum).ToList());
|
_basicService.LocationInfoService.Repository.UpdateLocationStatus(locationInfos, locationStatus);
|
return WebResponseContent.Instance.OK();
|
}
|
catch (Exception ex)
|
{
|
return WebResponseContent.Instance.Error(ex.Message);
|
}
|
}
|
/// <summary>
|
/// 分配库存处理货位数据
|
/// </summary>
|
public (List<Dt_ProStockInfo>, List<Dt_ProOutOrderDetail>, List<Dt_OutProStockInfo>, List<Dt_LocationInfo>) AssignProStockOut(List<Dt_ProOutOrderDetail> proOutOrderDetails)
|
{
|
List<Dt_ProStockInfo> outStocks = new List<Dt_ProStockInfo>();
|
List<Dt_OutProStockInfo> outProStockInfos = new List<Dt_OutProStockInfo>();
|
List<Dt_LocationInfo> locationInfos = new List<Dt_LocationInfo>();
|
//获取成品订单
|
Dt_ProOutOrder proOutOrder = _proOutOrderRepository.QueryFirst(x=>x.Id==proOutOrderDetails.FirstOrDefault().ProOrderId);
|
if (proOutOrder==null)
|
{
|
throw new Exception("未找到成品订单");
|
}
|
//List<Dt_ProOutOrderDetail> groupDetails = proOutOrderDetails.GroupBy(x => new { x.SaleOrder, x.PCode, x.PVer, x.PLot, x.DateCode }).Select(x => new Dt_ProOutOrderDetail()
|
//{
|
// QtyPcs = x.Sum(x => x.QtyPcs) - x.Sum(x => x.OverQtyPcs),
|
// SaleOrder = x.Key.SaleOrder,
|
// PCode = x.Key.PCode,
|
// PVer = x.Key.PVer,
|
// PLot = x.Key.PLot,
|
// DateCode = x.Key.DateCode,
|
//}).ToList();
|
//foreach (var item in groupDetails)
|
//{
|
// float needQty = item.QtyPcs;
|
// //查找可用库存
|
// List<Dt_ProStockInfo> stockInfoss = _stockInfoService.ProStockInfoService.GetUseableStocks(proOutOrder.WarehouseId, item);
|
// if (!stockInfoss.Any())
|
// {
|
// throw new Exception("未找到可分配库存");
|
// }
|
// //获取出库库存
|
// List<Dt_ProStockInfo> assignOutStocks = _stockInfoService.ProStockInfoService.GetOutboundStocks(stockInfoss, item, needQty, out float residueQuantity);
|
// item.LockQtyPcs += needQty - residueQuantity;
|
// if (item.QtyPcs> item.LockQtyPcs)
|
// {
|
// throw new Exception($"产品编码{item.PCode}可分配数量不足,可用数量{item.LockQtyPcs}");
|
// }
|
// outStocks.AddRange(assignOutStocks);
|
// float assignQuantity = needQty - residueQuantity;
|
// bool isCanLot = string.IsNullOrEmpty(item.PLot);
|
// bool isCanDate = string.IsNullOrEmpty(item.DateCode);
|
// List<Dt_ProOutOrderDetail> details = proOutOrderDetails
|
// .Where(x =>x.PCode == item.PCode && x.PVer == item.PVer
|
// && (isCanLot ? isCanLot : x.PLot == item.PLot)
|
// && (isCanDate ? isCanDate : x.DateCode == item.DateCode))
|
// .ToList();
|
|
// for (int i = 0; i < details.Count; i++)
|
// {
|
// float orderQuantity = details[i].QtyPcs;
|
// for (int j = 0; j < assignOutStocks.Count; j++)
|
// {
|
// //出库订单明细已分配数量
|
// float detailAssignQuantity = outProStockInfos.Where(x => x.PCode == item.PCode && x.PVer == item.PVer
|
// && (isCanLot ? isCanLot : x.PLot == item.PLot)
|
// && (isCanDate ? isCanDate : x.DateCode == item.DateCode)
|
// && x.OrderDetailId == details[i].Id).Sum(x => x.AssignQuantity);
|
|
// float palletAssignQuantity = outProStockInfos.Where(x => x.PCode == item.PCode && x.PVer == item.PVer
|
// && (isCanLot ? isCanLot : x.PLot == item.PLot)
|
// && (isCanDate ? isCanDate : x.DateCode == item.DateCode)
|
// && x.PalletCode == assignOutStocks[j].PalletCode).Sum(x => x.AssignQuantity);
|
// //出库详情已分配数量
|
// palletAssignQuantity = outProStockInfos.Where(x => x.PCode == item.PCode && x.PVer == item.PVer
|
// && (isCanLot ? isCanLot : x.PLot == item.PLot)
|
// && (isCanDate ? isCanDate : x.DateCode == item.DateCode)
|
// && x.PalletCode == assignOutStocks[j].PalletCode).Sum(x => x.AssignQuantity);//出库详情已分配数量
|
// float palletOutboundQuantity = assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity);
|
// if (palletAssignQuantity < palletOutboundQuantity)//如果出库详情已分配数量小于托盘已分配数量,则可以继续添加该托盘出库信息
|
// {
|
// float orderDetailNeedQuantity = details[i].QtyPcs - detailAssignQuantity;
|
// if (orderDetailNeedQuantity > assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity) - palletAssignQuantity)
|
// {
|
// details[i].LockQtyPcs += assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity) - palletAssignQuantity;
|
// Dt_OutProStockInfo outStockLockInfo = _outProStockInfoService.GetOutStockLockInfo(proOutOrder, details[i], assignOutStocks[j], assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity) - palletAssignQuantity);
|
// outProStockInfos.Add(outStockLockInfo);
|
// }
|
// else
|
// {
|
// Dt_OutProStockInfo outStockLockInfo = _outProStockInfoService.GetOutStockLockInfo(proOutOrder, details[i], assignOutStocks[j], details[i].QtyPcs - details[i].LockQtyPcs);
|
// outProStockInfos.Add(outStockLockInfo);
|
// details[i].LockQtyPcs = details[i].QtyPcs;
|
// break;
|
// }
|
|
// }
|
// }
|
// }
|
// List<string> locationArr = outStocks.Select(x => x.LocationCode).ToList();
|
|
// locationInfos.AddRange(_basicService.LocationInfoService.Repository.GetLocationInfos(locationArr));
|
|
//}
|
foreach (var item in proOutOrderDetails)
|
{
|
float needQty = item.QtyPcs;
|
//查找可用库存
|
List<Dt_ProStockInfo> stockInfoss = _stockInfoService.ProStockInfoService.GetUseableStocks(proOutOrder.WarehouseId, item);
|
if (!stockInfoss.Any())
|
{
|
throw new Exception("未找到可分配库存");
|
}
|
//获取出库库存
|
List<Dt_ProStockInfo> assignOutStocks = _stockInfoService.ProStockInfoService.GetOutboundStocks(stockInfoss, item, needQty, out float residueQuantity);
|
item.LockQtyPcs += needQty - residueQuantity;
|
if (item.QtyPcs > item.LockQtyPcs)
|
{
|
throw new Exception($"产品编码{item.PCode},版本{item.PVer.Substring(0, 1)}可分配数量不足,可用数量{item.LockQtyPcs}");
|
}
|
outStocks.AddRange(assignOutStocks);
|
float assignQuantity = needQty - residueQuantity;
|
bool isCanLot = string.IsNullOrEmpty(item.PLot);
|
bool isCanDate = string.IsNullOrEmpty(item.DateCode);
|
float orderQuantity = item.QtyPcs;
|
for (int j = 0; j < assignOutStocks.Count; j++)
|
{
|
//出库订单明细已分配数量
|
float detailAssignQuantity = outProStockInfos.Where(x => x.OrderDetailId == item.Id).Sum(x => x.AssignQuantity);
|
////出库详情已分配数量
|
//float palletAssignQuantity = outProStockInfos.Where(x => x.PCode == item.PCode && x.PVer == item.PVer
|
// && (isCanLot ? isCanLot : x.PLot == item.PLot)
|
// && (isCanDate ? isCanDate : x.DateCode == item.DateCode)
|
// && x.PalletCode == assignOutStocks[j].PalletCode).Sum(x => x.AssignQuantity);
|
////出库详情已分配数量
|
//float palletOutboundQuantity = assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity);
|
//if (palletAssignQuantity < palletOutboundQuantity)//如果出库详情已分配数量小于托盘已分配数量,则可以继续添加该托盘出库信息
|
//{
|
float orderDetailNeedQuantity = item.QtyPcs - detailAssignQuantity;
|
if (orderDetailNeedQuantity > assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity))
|
{
|
item.LockQtyPcs += assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity);
|
Dt_OutProStockInfo outStockLockInfo = _outProStockInfoService.GetOutStockLockInfo(proOutOrder, item, assignOutStocks[j], assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity));
|
outProStockInfos.Add(outStockLockInfo);
|
}
|
else
|
{
|
Dt_OutProStockInfo outStockLockInfo = _outProStockInfoService.GetOutStockLockInfo(proOutOrder, item, assignOutStocks[j], item.QtyPcs - item.LockQtyPcs);
|
outProStockInfos.Add(outStockLockInfo);
|
item.LockQtyPcs = item.QtyPcs;
|
break;
|
}
|
|
//}
|
}
|
List<string> locationArr = outStocks.Select(x => x.LocationCode).ToList();
|
|
locationInfos.AddRange(_basicService.LocationInfoService.Repository.GetLocationInfos(locationArr));
|
|
}
|
return (outStocks, proOutOrderDetails, outProStockInfos, locationInfos);
|
}
|
}
|
}
|