| 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("未找到成品订单"); | 
|             } | 
|             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); | 
|                 //分配出库的PCS数量 | 
|                 float assignQuantity = needQty; | 
|                 //订单明细的出库PCS数量 | 
|                 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 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 - detailAssignQuantity); | 
|                         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); | 
|         } | 
|     } | 
| } |