using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; 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_Common.WareHouseEnum; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_Core.Helper; using WIDESEA_DTO.ERP; using WIDESEA_External.ERPService; using WIDESEA_External.Model; using WIDESEA_IBasicService; using WIDESEA_IOutboundRepository; using WIDESEA_IOutboundService; using WIDESEA_IRecordService; using WIDESEA_IStockRepository; using WIDESEA_IStockService; using WIDESEA_Model.Models; using WIDESEA_OutboundRepository; namespace WIDESEA_OutboundService { public partial class ErpProScrapSheetDetailService : ServiceBase, IErpProScrapSheetDetailService { private readonly IUnitOfWorkManage _unitOfWorkManage; public IErpProScrapSheetDetailRepository Repository => BaseDal; public IErpProScrapSheetRepository _proScrapSheetRepository; public IInvokeERPService _invokeERPService; public IStockRepository _stockRepository; public IStockService _stockService; public IOutProStockInfoService _outProStockInfoService; public IBasicService _basicService; public IRecordService _recordService; public ErpProScrapSheetDetailService(IErpProScrapSheetDetailRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IErpProScrapSheetRepository proScrapSheetRepository, IInvokeERPService invokeERPService, IStockRepository stockRepository, IStockService stockService, IOutProStockInfoService outProStockInfoService, IRecordService recordService, IBasicService basicService) : base(BaseDal) { _unitOfWorkManage = unitOfWorkManage; _proScrapSheetRepository = proScrapSheetRepository; _invokeERPService = invokeERPService; _stockRepository = stockRepository; _stockService = stockService; _outProStockInfoService = outProStockInfoService; _recordService = recordService; _basicService = basicService; } //获取对应单号的报废明细 public List GetByDetails(string scrapNo) { List proScrapSheetDetails = _proScrapSheetRepository.Db.Queryable((master, detail) => master.Id == detail.ProScrapSheetId) .Where((master, detail) => master.ProScrapSheetOrderNo==scrapNo) .Select((master, detail) => detail) .ToList(); return proScrapSheetDetails; } /// /// 提交报废操作 /// /// public WebResponseContent UpProScrap(string scrapNo,int[] keys) { WebResponseContent content = new WebResponseContent(); try { //获取所有的报废明细 Dt_ErpProScrapSheet erpProScrapSheet = _proScrapSheetRepository.Db.Queryable().Where(x => x.ProScrapSheetOrderNo == scrapNo).Includes(x => x.Details).First(); if (erpProScrapSheet == null) { return content.Error($"未找到对应报废单{scrapNo}"); } if (erpProScrapSheet.Details == null || erpProScrapSheet.Details.Count<=0) { return content.Error($"未找到对应报废单{scrapNo}明细"); } List erpProScrapSheetDetails = erpProScrapSheet.Details.Where(x=> keys.Contains(x.Id) && x.ScrapProDetailStatus== OutOrderStatusEnum.出库完成.ObjToInt()).ToList(); List overDetails= erpProScrapSheet.Details.Where(x => x.ScrapProDetailStatus == OutOrderStatusEnum.关闭.ObjToInt()).ToList(); int overCount = overDetails.Count; //进行报废提交操作 if (erpProScrapSheetDetails.Count!= keys.Length) { return content.Error($"提交了已报废明细或正在出库中,请检查"); } if ((overCount + keys.Length) == erpProScrapSheet.Details.Count) { erpProScrapSheet.ProScrapStatus = ProScrapSheetStatusEnum.Valid.ObjToInt(); } List scrapSheetItems = new List(); foreach (var item in erpProScrapSheetDetails) { item.ScrapProDetailStatus = OutOrderStatusEnum.关闭.ObjToInt(); item.OverScrapPcsQty = item.ScrapPcsQty; item.OverScrapSETQty = item.ScrapSETQty; ScrapSheetItem scrapSheetItem = new ScrapSheetItem() { PartNum = item.ScrapProCode, PartRev = item.ScrapProVersion, Lotno = item.ScrapProVersion, QtyOfArray = item.ScrapSETQty, QtyOfUnit = item.ScrapPcsQty, QtyOfArray_Alloc = 0, QtyOfUnit_Alloc = 0, }; scrapSheetItems.Add(scrapSheetItem); } _unitOfWorkManage.BeginTran(); _proScrapSheetRepository.UpdateData(erpProScrapSheet); BaseDal.UpdateData(erpProScrapSheetDetails); if (erpProScrapSheet.ProScrapStatus == ProScrapSheetStatusEnum.Valid.ObjToInt()) { ERPScrapSheetModel scrapSheetModel = new ERPScrapSheetModel() { Way = 1, UniqueTag = erpProScrapSheet.Id.ToString(), Code = erpProScrapSheet.ProScrapSheetOrderNo, Status = ProScrapSheetStatusEnum.Valid.ToString(), Createtime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Createuser = erpProScrapSheet.Creater, WarehouseCode = WarehouseEnum.HA71.ToString(), DataItem = new List() }; if (overCount>0) { foreach (var item in overDetails) { ScrapSheetItem scrapSheetItem = new ScrapSheetItem() { PartNum = item.ScrapProCode, PartRev = item.ScrapProVersion, Lotno = item.ScrapProVersion, QtyOfArray = item.ScrapSETQty, QtyOfUnit = item.ScrapPcsQty, QtyOfArray_Alloc = 0, QtyOfUnit_Alloc = 0, }; scrapSheetItems.Add(scrapSheetItem); } } scrapSheetModel.DataItem = scrapSheetItems; //上传ERP报废 string response = _invokeERPService.InvokeProScrapSheetApi(scrapSheetModel); ErpRequestContent requestContent = response.DeserializeObject(); if (requestContent.res != 1) { throw new Exception($"{requestContent.Data}"); } } _unitOfWorkManage.CommitTran(); content.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); content.Error(ex.Message); } return content; } /// /// 报废数据处理 /// public WebResponseContent LockOutboundStockDataUpdate(List proStockInfos, List scrapSheetDetails, List outProStockInfos, List locationInfos, LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List? tasks = null) { try { //更新库存属性 _stockService.ProStockInfoService.Repository.UpdateData(proStockInfos); List proStockInfoDetails = new List(); foreach (var item in proStockInfos) { proStockInfoDetails.AddRange(item.proStockInfoDetails); } //更新库存明细 proStockInfoDetails.ForEach(x => x.ProOutDetailStatus = StockStatusEmun.出库锁定.ObjToInt()); _stockService.ProStockInfoDetailService.Repository.UpdateData(proStockInfoDetails); BaseDal.UpdateData(scrapSheetDetails); List 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 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); } } public (List, List, List, List) AssignProStockOut(List proOutOrderDetails, Dt_ErpProScrapSheet scrapSheet) { List outStocks = new List(); List outProStockInfos = new List(); List locationInfos = new List(); //List 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 stockInfoss = _stockInfoService.ProStockInfoService.GetUseableStocks(proOutOrder.WarehouseId, item); // if (!stockInfoss.Any()) // { // throw new Exception("未找到可分配库存"); // } // //获取出库库存 // List 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 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 locationArr = outStocks.Select(x => x.LocationCode).ToList(); // locationInfos.AddRange(_basicService.LocationInfoService.Repository.GetLocationInfos(locationArr)); //} foreach (var item in proOutOrderDetails) { float needQty = item.ScrapPcsQty; //查找可用库存 List stockInfoss = _stockService.ProStockInfoService.GetUseableStocks(scrapSheet.WarehouseId, item); if (!stockInfoss.Any()) { throw new Exception("未找到可分配库存"); } //获取出库库存 List assignOutStocks = _stockService.ProStockInfoService.GetOutboundStocks(stockInfoss, item, needQty, out float residueQuantity); item.LockPcsQty += (int)(needQty - residueQuantity); if (item.ScrapPcsQty > item.LockPcsQty) { throw new Exception($"产品编码{item.ScrapProCode}可分配数量不足,可用数量{item.LockPcsQty}"); } outStocks.AddRange(assignOutStocks); item.LockPcsQty = 0; 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.ScrapPcsQty - detailAssignQuantity; if (orderDetailNeedQuantity > assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity)) { item.LockPcsQty += (int)assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity); Dt_OutProStockInfo outStockLockInfo = _outProStockInfoService.GetOutStockLockInfo(scrapSheet, item, assignOutStocks[j], assignOutStocks[j].proStockInfoDetails.Sum(x => x.OutboundQuantity)); outProStockInfos.Add(outStockLockInfo); } else { Dt_OutProStockInfo outStockLockInfo = _outProStockInfoService.GetOutStockLockInfo(scrapSheet, item, assignOutStocks[j], item.ScrapPcsQty - detailAssignQuantity); outProStockInfos.Add(outStockLockInfo); item.LockPcsQty = item.ScrapPcsQty; break; } //} } List locationCodes = outStocks.Select(x => x.LocationCode).ToList(); List locationInfos1 = _basicService.LocationInfoService.Repository.GetLocationInfos(locationCodes); if (locationInfos1 == null) { throw new Exception($"{locationCodes}货位查询为空,请检查"); } locationInfos.AddRange(locationInfos1); } return (outStocks, proOutOrderDetails, outProStockInfos, locationInfos); } } }