| using AutoMapper; | 
| using Castle.Core.Resource; | 
| using Org.BouncyCastle.Asn1.Cmp; | 
| using System; | 
| using System.Collections.Generic; | 
| using System.Linq; | 
| using System.Text; | 
| using System.Threading; | 
| using System.Threading.Tasks; | 
| 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.CodeConfigEnum; | 
| using WIDESEA_Core.Enums; | 
| using WIDESEA_Core.Helper; | 
| using WIDESEA_DTO.ERP; | 
| using WIDESEA_DTO.Outbound; | 
| using WIDESEA_External.ERPService; | 
| using WIDESEA_External.Model; | 
| using WIDESEA_IBasicRepository; | 
| using WIDESEA_IBasicService; | 
| using WIDESEA_IOutboundRepository; | 
| using WIDESEA_IOutboundService; | 
| using WIDESEA_IRecordService; | 
| using WIDESEA_IStockRepository; | 
| using WIDESEA_IStockService; | 
| using WIDESEA_Model.Models; | 
|   | 
| namespace WIDESEA_OutboundService | 
| { | 
|     public partial class ProOutOrderService : ServiceBase<Dt_ProOutOrder, IProOutOrderRepository>, IProOutOrderService | 
|     { | 
|         private readonly IUnitOfWorkManage _unitOfWorkManage; | 
|         private readonly IBasicRepository _basicRepository; | 
|         private readonly IMapper _mapper; | 
|         private readonly IStockRepository _stockRepository; | 
|         private readonly IOutboundRepository _outboundRepository; | 
|         private readonly IOutboundOrderService _outboundOrderService; | 
|         private readonly IInvokeERPService _invokeERPService;  | 
|   | 
|         public IProOutOrderRepository Repository => BaseDal; | 
|   | 
|         public ProOutOrderService(IProOutOrderRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IBasicRepository basicRepository, IMapper mapper, IStockRepository stockRepository, IOutboundRepository outboundRepository, IOutboundOrderService outboundOrderService,IInvokeERPService invokeERPService) : base(BaseDal) | 
|         { | 
|             _unitOfWorkManage = unitOfWorkManage; | 
|             _basicRepository = basicRepository; | 
|             _mapper = mapper; | 
|             _stockRepository = stockRepository; | 
|             _outboundRepository = outboundRepository; | 
|             _outboundOrderService = outboundOrderService; | 
|             _invokeERPService = invokeERPService; | 
|         } | 
|         /// <summary> | 
|         /// 接收ERP成品出库单信息(订单出库/寄售出库) | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public async Task<WebResponseContent> ProductDeliveryOrder(ErpProOutOrderDTO outOrderDTO) | 
|         { | 
|             try | 
|             { | 
|                 return outOrderDTO.Way switch | 
|                 { | 
|                     1 => await Task.FromResult(AddDeliveryOrder(outOrderDTO)), | 
|                     2 => await Task.FromResult(UpdateDeliveryOrder(outOrderDTO)), | 
|                     3 => await Task.FromResult(DeleteDeliveryOrder(outOrderDTO)), | 
|                     _ => await Task.FromResult(WebResponseContent.Instance.Error($"操作类型不存在,Way:{outOrderDTO.Way}")), | 
|                 }; | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return await Task.FromResult(WebResponseContent.Instance.Error(ex.Message)); | 
|             } | 
|         } | 
|         /// <summary> | 
|         /// 新增成品出库单 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public WebResponseContent AddDeliveryOrder(ErpProOutOrderDTO outOrderDTO) | 
|         { | 
|             WebResponseContent content=new WebResponseContent(); | 
|             try | 
|             { | 
|                 if (BaseDal.QueryFirst(x => x.ProOutOrderNo == outOrderDTO.OrderNo) != null)  | 
|                 { | 
|                     return content.Error($"出库单号{outOrderDTO.OrderNo}已存在!"); | 
|                 } | 
|                 Dt_Warehouse warehouse=null; | 
|                 List<Dt_CustomerInfo> customerInfos = _basicRepository.CustomerInfoRepository.QueryData(); | 
|                 if (outOrderDTO.OType==1 && string.IsNullOrEmpty(outOrderDTO.WaType)) | 
|                 { | 
|                     warehouse = _basicRepository.WarehouseRepository.QueryFirst(x=>x.WarehouseCode==WarehouseEnum.HA71.ToString()); | 
|                 } | 
|                 else if (outOrderDTO.OType==2) | 
|                 { | 
|                     warehouse = _basicRepository.WarehouseRepository.QueryFirst(x => x.WarehouseCode == WarehouseEnum.HA71.ToString()); | 
|                 } | 
|                 List<Dt_ProOutOrderDetail> proOutOrderDetails = new List<Dt_ProOutOrderDetail>(); | 
|                 Dictionary<string,string> keyValuePairs =new Dictionary<string, string>(); | 
|                 foreach (var item in outOrderDTO.OrderDetails) | 
|                 { | 
|                     //判断客户是否存在 | 
|                     Dt_CustomerInfo? customerInfo = customerInfos.Where(x=>x.Code== item.Customer).FirstOrDefault(); | 
|                     if (customerInfo==null)  | 
|                     { | 
|                         return content.Error($"客户{item.Customer}不存在!"); | 
|                     } | 
|                     Dt_ProOutOrderDetail proOutOrderDetail = _mapper.Map<Dt_ProOutOrderDetail>(item); | 
|                     if (!string.IsNullOrEmpty(item.SaleOrder)) | 
|                     { | 
|                         if (keyValuePairs!=null && keyValuePairs.ContainsKey(item.SaleOrder)) | 
|                         { | 
|                             proOutOrderDetail.EndCustomer = keyValuePairs[item.SaleOrder]; | 
|                         } | 
|                         else | 
|                         { | 
|                             string request = _invokeERPService.InvokeProSaleCustomer(item.SaleOrder); | 
|                             ErpSaleCustomResponseContent responseContent=request.DeserializeObject<ErpSaleCustomResponseContent>(); | 
|                             if (responseContent.Code!=200) | 
|                             { | 
|                                 return content.Error($"订单{item.SaleOrder}终端客户获取失败!"); | 
|                             } | 
|                             //判断终端客户是否存在 | 
|                             Dt_CustomerInfo? customerInfoEnd = customerInfos.Where(x => x.Code == responseContent.Data[0].Endcustomer).FirstOrDefault(); | 
|                             if (customerInfoEnd == null) | 
|                             { | 
|                                 return content.Error($"终端客户{responseContent.Data[0].Endcustomer}不存在!"); | 
|                             } | 
|                             proOutOrderDetail.EndCustomer = responseContent.Data[0].Endcustomer; | 
|                             keyValuePairs.Add(item.SaleOrder, responseContent.Data[0].Endcustomer); | 
|                         } | 
|                     } | 
|                     proOutOrderDetail.QtyPcs += proOutOrderDetail.SpareQty; | 
|                     proOutOrderDetails.Add(proOutOrderDetail); | 
|                 } | 
|                 Dt_ProOutOrder  proOutOrder= new Dt_ProOutOrder() | 
|                 { | 
|                     ProOutOrderNo= outOrderDTO.OrderNo, | 
|                     WarehouseId= warehouse.WarehouseId, | 
|                     ProOrderType= outOrderDTO.OType, | 
|                     ProOrderStatus=OutOrderStatusEnum.未开始.ObjToInt(), | 
|                     PlantShipDate= outOrderDTO.PlantShipDate.ObjToDate(), | 
|                     Remark= outOrderDTO.Note, | 
|                     Details= proOutOrderDetails | 
|                 }; | 
|                 Db.InsertNav(proOutOrder).Include(x => x.Details).ExecuteCommand(); | 
|                 content.OK("成功"); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 更新成品出库单 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public WebResponseContent UpdateDeliveryOrder(ErpProOutOrderDTO outOrderDTO) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                  | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 删除成品出库单 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public WebResponseContent DeleteDeliveryOrder(ErpProOutOrderDTO outOrderDTO) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.Db.Queryable<Dt_ProOutOrder>().Where(x => x.ProOutOrderNo == outOrderDTO.OrderNo).Includes(x => x.Details).First(); | 
|                 if (proOutOrder==null) | 
|                 { | 
|                     return content.Error($"未找到出库单{outOrderDTO.OrderNo}"); | 
|                 } | 
|                 if (proOutOrder.ProOrderStatus==OutOrderStatusEnum.出库完成.ObjToInt() || proOutOrder.ProOrderStatus == OutOrderStatusEnum.出库中.ObjToInt()) | 
|                 { | 
|                     return content.Error("出库单执行中"); | 
|                 } | 
|                 _unitOfWorkManage.BeginTran(); | 
|                 _outboundRepository.ProOutOrderRepository.DeleteData(proOutOrder); | 
|                 _outboundRepository.ProOutOrderDetailRepository.DeleteData(proOutOrder.Details); | 
|                 _unitOfWorkManage.CommitTran(); | 
|                 content.OK("成功"); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 _unitOfWorkManage.RollbackTran(); | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 销售指派 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public async Task<WebResponseContent> ProductSpecifyVer(ErpProductSpecifyVerDTO erpProductSpecifyVerDTO) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 Dt_Warehouse warehouse = _basicRepository.WarehouseRepository.QueryFirst(x=>x.WarehouseCode==erpProductSpecifyVerDTO.WaType); | 
|                 if (warehouse == null) | 
|                     return await Task.FromResult(content.Error($"未找到{erpProductSpecifyVerDTO.WaType}仓库信息")); | 
|                 //查询可指派库存 | 
|                 List<Dt_ProStockInfo> proStockInfos = Db.Queryable<Dt_ProStockInfo>().Where(x => x.ProStockAttribute == ProStockAttributeEnum.成品.ObjToInt()) | 
|                 .Includes(x => x.proStockInfoDetails) | 
|                 .Where(x => x.proStockInfoDetails | 
|                 .Any(v => | 
|                      v.SaleOrder == erpProductSpecifyVerDTO.OrderNo | 
|                     && v.ProductCode == erpProductSpecifyVerDTO.PCode | 
|                     && v.ProductVersion == erpProductSpecifyVerDTO.PVer | 
|                     && v.LotNumber == erpProductSpecifyVerDTO.PLot | 
|                     && v.DateCode == erpProductSpecifyVerDTO.DateCode | 
|                     && (v.SpecifyVer==null||v.SpecifyVer=="") | 
|                 )) | 
|                 .ToList(); | 
|                 List<Dt_ProStockInfoDetail> proStockInfoDetails = new List<Dt_ProStockInfoDetail>(); | 
|                 List<Dt_ProStockInfoDetail> specifyVerDetails = new List<Dt_ProStockInfoDetail>(); | 
|                 if (proStockInfos==null) | 
|                     return await Task.FromResult(content.Error("可指派库存不存在")); | 
|                 proStockInfos = proStockInfos.OrderBy(x => x.proStockInfoDetails.FirstOrDefault()?.DateCode).ThenBy(x => x.CreateDate).ThenBy(x => x.proStockInfoDetails.Sum(x => x.StockPcsQty)).ToList(); | 
|                 foreach (var item in proStockInfos) | 
|                 { | 
|                     proStockInfoDetails.AddRange(item.proStockInfoDetails); | 
|                 } | 
|                 if (proStockInfoDetails.Sum(x=>x.StockPcsQty)< erpProductSpecifyVerDTO.QtyPcs) | 
|                     return await Task.FromResult(content.Error($"可指派库存数量不足,可用:{proStockInfoDetails.Sum(x => x.StockPcsQty)}")); | 
|                 float overQty = 0; | 
|                 foreach (var item in proStockInfoDetails) | 
|                 { | 
|                     specifyVerDetails.Add(item); | 
|                     overQty += item.StockPcsQty; | 
|                     //已满足获取数量不再更改 | 
|                     if (overQty>= erpProductSpecifyVerDTO.QtyPcs) | 
|                     { | 
|                         break; | 
|                     } | 
|                 } | 
|                 specifyVerDetails.ForEach(x => | 
|                 { | 
|                     x.SpecifyVer = erpProductSpecifyVerDTO.Ver; | 
|                 }); | 
|                 _unitOfWorkManage.BeginTran(); | 
|                 _stockRepository.ProStockInfoDetailRepository.UpdateData(specifyVerDetails); | 
|                 _unitOfWorkManage.CommitTran(); | 
|                 content.OK("指派成功"); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 _unitOfWorkManage.RollbackTran(); | 
|                 content.Error(ex.Message); | 
|             } | 
|             return await Task.FromResult(content); | 
|         } | 
|         /// <summary> | 
|         /// 成品出待发货区(平库)+同步ERP出库(绑定了出库单库存) | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public WebResponseContent OutProductPK(SaveModel saveModel, string ProOutNo) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 List<string> OutPKCodes = saveModel.DelKeys.Select(x => x.ToString()).ToList(); | 
|                 if (OutPKCodes.IsNullOrEmpty()) | 
|                 { | 
|                     return content.Error("不能为空"); | 
|                 } | 
|                 Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.Db.Queryable<Dt_ProOutOrder>().Where(x => x.ProOutOrderNo == ProOutNo).Includes(x => x.Details).First(); | 
|                 if (proOutOrder == null) | 
|                 { | 
|                     return content.Error($"出库单{ProOutNo}不存在"); | 
|                 } | 
|                 if (proOutOrder.ProOrderStatus==OutOrderStatusEnum.出库完成.ObjToInt()) | 
|                 { | 
|                     return content.Error($"出库单{ProOutNo}已完成"); | 
|                 } | 
|                 string? userName = App.User.UserName;//GSWMS | 
|                 //获取所有外箱的数据 | 
|                 List<Dt_ProStockInfo> AllproStockInfos = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>() | 
|                     .Where(x => OutPKCodes.Contains(x.PalletCode) && x.ShipmentOrder == proOutOrder.ProOutOrderNo && x.StockStatus == StockStatusEmun.平库入库完成.ObjToInt()) | 
|                     .Includes(x => x.proStockInfoDetails).ToList(); | 
|                 if (AllproStockInfos.Count<=0) | 
|                 { | 
|                     return content.Error($"出库单{ProOutNo}已无绑定库存"); | 
|                 } | 
|                 List<Dt_ProStockInfo> proStockInfos = new List<Dt_ProStockInfo>(); | 
|                 List<Dt_ProStockInfoDetail> proStockInfoDetails = new List<Dt_ProStockInfoDetail>(); | 
|                 List<Dt_Warehouse> warehouses = _basicRepository.WarehouseRepository.QueryData(x => x.WarehouseType == WarehouseTypEnum.成品.ToString()); | 
|                 foreach (var item in OutPKCodes) | 
|                 { | 
|                     //获取库存 | 
|                     Dt_ProStockInfo? proStockInfo = AllproStockInfos.Where(x => x.PalletCode == item).FirstOrDefault(); | 
|                     if (proStockInfo == null) | 
|                     { | 
|                         return content.Error($"未找到{item}库存"); | 
|                     } | 
|                     Dt_Warehouse? dt_Warehouse = warehouses.Where(x=>x.WarehouseId== proStockInfo.WarehouseId).FirstOrDefault(); | 
|                     if (dt_Warehouse==null) | 
|                     { | 
|                         return content.Error($"外箱号{item},不属于成品仓"); | 
|                     } | 
|                     if (proStockInfo.ShipmentOrder!= proOutOrder.ProOutOrderNo) | 
|                     { | 
|                         return content.Error($"外箱号{item},不属于出库订单{proOutOrder.ProOutOrderNo}"); | 
|                     } | 
|                     proStockInfos.Add(proStockInfo); | 
|                     proStockInfoDetails.AddRange(proStockInfo.proStockInfoDetails); | 
|                 } | 
|                  | 
|                 if (proOutOrder.Details.Sum(x=>x.LockQtyPcs-x.OverQtyPcs)< proStockInfoDetails.Sum(x=>x.StockPcsQty)) | 
|                 { | 
|                     return content.Error($"出库数量{proStockInfoDetails.Sum(x => x.StockPcsQty)}>所剩订单数量{proOutOrder.Details.Sum(x => x.LockQtyPcs - x.OverQtyPcs)}"); | 
|                 } | 
|                 List<StockOutItemsItem> stockOutItems = new List<StockOutItemsItem>(); | 
|                 List<Dt_ProOutOrderDetail> proOutOrderDetails = proOutOrder.Details.Where(x=> proStockInfoDetails.Select(x=>x.ProductCode).Contains(x.PCode) && proStockInfoDetails.Select(x => x.ProductVersion).Contains(x.PVer)).ToList(); | 
|                 if (proOutOrderDetails==null || proOutOrderDetails.Count<=0) | 
|                 { | 
|                     return content.Error("对应出库订单明细为空"); | 
|                 } | 
|                 int OldOverCount = proOutOrder.Details.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count(); | 
|                 List<Dt_ProOutOrderDetail> newProDetails=new List<Dt_ProOutOrderDetail>(); | 
|                 foreach (var item in proStockInfoDetails) | 
|                 { | 
|                     //获取对应明细处理出库数据 | 
|                     Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrderDetails.Where(x => x.Id==item.OutDetailId && x.PVer == item.ProductVersion && x.PCode == item.ProductCode).FirstOrDefault(); | 
|                     if (proOutOrderDetail==null) | 
|                     { | 
|                         return content.Error("未找到对应出库订单明细"); | 
|                     } | 
|                     proOutOrderDetail.OverQtyPcs += item.StockPcsQty; | 
|                     item.OutboundQuantity = item.StockPcsQty; | 
|                     item.OutSETQty = item.SETQty; | 
|                     if (proOutOrderDetail.OverQtyPcs> proOutOrderDetail.QtyPcs) | 
|                     { | 
|                         return content.Error($"出库订单明细行{proOutOrderDetail.RowId},溢出{proOutOrderDetail.QtyPcs - proOutOrderDetail.OverQtyPcs}"); | 
|                     } | 
|                     if (proOutOrderDetail.OverQtyPcs == proOutOrderDetail.QtyPcs) | 
|                     { | 
|                         proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); | 
|                         newProDetails.Add(proOutOrderDetail); | 
|                     } | 
|                      | 
|                 } | 
|                  | 
|                 int AddOverCount = newProDetails.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count(); | 
|                 if (proOutOrder.Details.Count == (AddOverCount + OldOverCount)) | 
|                 { | 
|                     proOutOrder.ProOrderStatus = OutOrderStatusEnum.出库完成.ObjToInt(); | 
|                     //获取所有已扫码待发货的库存 | 
|                     List<Dt_ProStockInfo> AllOutStocks = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>() | 
|                     .Where(x => x.ShipmentOrder== ProOutNo && x.StockStatus == StockStatusEmun.平库待发货.ObjToInt()) | 
|                     .Includes(x => x.proStockInfoDetails).ToList(); | 
|                     AllOutStocks.ForEach(x => | 
|                     { | 
|                         proStockInfoDetails.AddRange(x.proStockInfoDetails); | 
|                     }); | 
|                     proStockInfos.AddRange(AllOutStocks); | 
|                     foreach (var item in proStockInfoDetails) | 
|                     { | 
|                         StockOutItemsItem outItemsItem = new StockOutItemsItem() | 
|                         { | 
|                             PartNum = item.ProductCode, | 
|                             Rev = item.ProductVersion, | 
|                             SoNumber = item.OutDetailSaleNo, | 
|                             BatchNumber = item.BagNo, | 
|                             QtyPcs = item.OutboundQuantity, | 
|                             QtySet = item.OutSETQty | 
|                         }; | 
|                         stockOutItems.Add(outItemsItem); | 
|                     } | 
|                 } | 
|                 _unitOfWorkManage.BeginTran(); | 
|                 Dt_Warehouse warehouse = warehouses.Where(x => x.WarehouseId == proOutOrder.WarehouseId).FirstOrDefault(); | 
|                 //处理库存数据和上传ERP | 
|                 if (proOutOrder.ProOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt()) | 
|                 { | 
|                     //成品库存记录变动待加入 | 
|                     ERPProOutOrderModel proOutOrderModel = new ERPProOutOrderModel() | 
|                     { | 
|                         Way = 1, | 
|                         StockOutCode = _outboundOrderService.CreateCodeByRule(nameof(RuleCodeEnum.ProOutCOdeRule)), | 
|                         ConfirmedUserNo = App.User.UserName, | 
|                         AssignUserNo = App.User.UserName, | 
|                         WarehouseCode = warehouse.WarehouseCode, | 
|                         ShipDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | 
|                         DeliverplanCode = proOutOrder.ProOutOrderNo, | 
|                         Remark = proOutOrder.Remark, | 
|                         StockOutItems = stockOutItems | 
|                     }; | 
|                     _stockRepository.ProStockInfoRepository.DeleteAndMoveIntoHty(proStockInfos, OperateTypeEnum.自动完成); | 
|                     _stockRepository.ProStockInfoDetailRepository.DeleteAndMoveIntoHty(proStockInfoDetails, OperateTypeEnum.自动完成); | 
|                     //WebResponseContent contentSaveInfos = SaveOutProPKInfos(proStockInfos); | 
|                     //if (!contentSaveInfos.Status) | 
|                     //{ | 
|                     //    throw new Exception(contentSaveInfos.Message); | 
|                     //}; | 
|                     string response = _invokeERPService.InvokeProOutApi(proOutOrderModel); | 
|                     ErpRequestContent erpRequestContent = response.DeserializeObject<ErpRequestContent>(); | 
|                     if (erpRequestContent.res != 1) | 
|                     { | 
|                         throw new Exception("同步ERP失败,错误信息:" + erpRequestContent.Data); | 
|                     } | 
|                 } | 
|                 else | 
|                 { | 
|                     proStockInfos.ForEach(x => | 
|                     { | 
|                         x.StockStatus = StockStatusEmun.平库待发货.ObjToInt(); | 
|                     }); | 
|                     proStockInfoDetails.ForEach(x => | 
|                     { | 
|                         x.ProOutDetailStatus = StockStatusEmun.平库待发货.ObjToInt(); | 
|                     }); | 
|                     _stockRepository.ProStockInfoRepository.UpdateData(proStockInfos); | 
|                     _stockRepository.ProStockInfoDetailRepository.UpdateData(proStockInfoDetails); | 
|                 } | 
|                 _outboundRepository.ProOutOrderDetailRepository.UpdateData(proOutOrderDetails); | 
|                 BaseDal.UpdateData(proOutOrder); | 
|                 _unitOfWorkManage.CommitTran(); | 
|                 content.OK(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 _unitOfWorkManage.RollbackTran(); | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 获取出库所有的外内包明细 | 
|         /// </summary> | 
|         /// <param name="proStockInfos"></param> | 
|         /// <returns></returns> | 
|         public WebResponseContent SaveOutProPKInfos(List<Dt_ProStockInfo> proStockInfos) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 List<Dt_OutProPKStockInfo> outProPKStockInfos = new List<Dt_OutProPKStockInfo>(); | 
|                 foreach (var fromItem in proStockInfos) | 
|                 { | 
|                     foreach (var lordItem in fromItem.proStockInfoDetails) | 
|                     { | 
|                         Dt_OutProPKStockInfo outProPKStockInfo = new Dt_OutProPKStockInfo() | 
|                         { | 
|                             PCode = lordItem.ProductCode, | 
|                             PVer=lordItem.ProductVersion, | 
|                             PLot=lordItem.ProductVersion, | 
|                             DateCode=lordItem.DateCode, | 
|                             StockId=fromItem.Id, | 
|                             OriginalQuantity=lordItem.StockPcsQty, | 
|                             AssignQuantity=lordItem.StockPcsQty, | 
|                             PalletCode=fromItem.PalletCode, | 
|                             Unit="PCS" | 
|                         }; | 
|                         outProPKStockInfos.Add(outProPKStockInfo); | 
|                     } | 
|                 } | 
|                 Db.InsertNav(outProPKStockInfos).Include(x=>x).ExecuteCommand(); | 
|                 content.OK(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         //根据内包出库 | 
|         public WebResponseContent BagProductPK(SaveModel saveModel) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 var outOrder = saveModel.MainData["proOutNo"].ToString(); | 
|                 var outBags = saveModel.DelKeys.Select(x => x.ToString()).ToList(); | 
|                 if (outBags.Count<=0) | 
|                 { | 
|                     return content.Error("内包信息获取失败"); | 
|                 } | 
|   | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 成品出待发货区(平库)+同步ERP出库(未绑定出库单库存) | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         //public WebResponseContent OutProductNoPK(string[] OutPKCodes, string ProOutNo) | 
|         //{ | 
|         //    WebResponseContent content = new WebResponseContent(); | 
|         //    try | 
|         //    { | 
|         //        if (OutPKCodes.IsNullOrEmpty()) | 
|         //        { | 
|         //            return content.Error("不能为空"); | 
|         //        } | 
|         //        Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.Db.Queryable<Dt_ProOutOrder>().Where(x => x.ProOutOrderNo == ProOutNo).Includes(x => x.Details).First(); | 
|         //        if (proOutOrder == null) | 
|         //        { | 
|         //            return content.Error($"出库单{ProOutNo}不存在"); | 
|         //        } | 
|         //        if (proOutOrder.ProOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt()) | 
|         //        { | 
|         //            return content.Error($"出库单{ProOutNo}已完成"); | 
|         //        } | 
|         //        string? userName = App.User.UserName;//GSWMS | 
|         //        //获取所有外箱的数据 | 
|         //        List<Dt_ProStockInfo> AllproStockInfos = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>() | 
|         //            .Where(x => OutPKCodes.Contains(x.PalletCode) && x.StockStatus == StockStatusEmun.平库入库完成.ObjToInt()) | 
|         //            .Includes(x => x.proStockInfoDetails).ToList(); | 
|         //        List<Dt_ProStockInfo> proStockInfos = new List<Dt_ProStockInfo>(); | 
|         //        List<Dt_ProStockInfoDetail> proStockInfoDetails = new List<Dt_ProStockInfoDetail>(); | 
|         //        List<Dt_Warehouse> warehouses = _basicRepository.WarehouseRepository.QueryData(x => x.WarehouseType == WarehouseTypEnum.成品.ToString()); | 
|         //        foreach (var item in OutPKCodes) | 
|         //        { | 
|         //            //获取库存 | 
|         //            Dt_ProStockInfo? proStockInfo = AllproStockInfos.Where(x => x.PalletCode == item).FirstOrDefault(); | 
|         //            if (proStockInfo == null) | 
|         //            { | 
|         //                return content.Error($"未找到{item}库存"); | 
|         //            } | 
|         //            if (proStockInfo.ShipmentOrder!=null) | 
|         //            { | 
|         //                return content.Error($"外箱号{item}为出库单{proStockInfo.ShipmentOrder}指定库存!"); | 
|         //            } | 
|         //            Dt_Warehouse? dt_Warehouse = warehouses.Where(x => x.WarehouseId == proStockInfo.WarehouseId).FirstOrDefault(); | 
|         //            if (dt_Warehouse == null) | 
|         //            { | 
|         //                return content.Error($"外箱号{item},不属于成品仓"); | 
|         //            } | 
|         //            proStockInfos.Add(proStockInfo); | 
|         //            proStockInfoDetails.AddRange(proStockInfo.proStockInfoDetails); | 
|         //        } | 
|   | 
|         //        if (proOutOrder.Details.Sum(x => x.QtyPcs - x.OverQtyPcs) < proStockInfoDetails.Sum(x => x.StockPcsQty)) | 
|         //        { | 
|         //            return content.Error($"出库数量{proStockInfoDetails.Sum(x => x.StockPcsQty)}>所剩订单数量{proOutOrder.Details.Sum(x => x.QtyPcs - x.OverQtyPcs)}"); | 
|         //        } | 
|         //        List<StockOutItemsItem> stockOutItems = new List<StockOutItemsItem>(); | 
|         //        List<Dt_ProOutOrderDetail> proOutOrderDetails = proOutOrder.Details.Where(x => proStockInfoDetails.Select(x => x.SaleOrder).Contains(x.SaleOrder) && proStockInfoDetails.Select(x => x.ProductCode).Contains(x.PCode) && proStockInfoDetails.Select(x => x.ProductVersion).Contains(x.PVer)).ToList(); | 
|         //        if (proOutOrderDetails == null || proOutOrderDetails.Count <= 0) | 
|         //        { | 
|         //            return content.Error("对应出库订单明细为空"); | 
|         //        } | 
|         //        int OldOverCount = proOutOrder.Details.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count(); | 
|         //        foreach (var item in proStockInfoDetails) | 
|         //        { | 
|         //            //获取对应明细处理出库数据 | 
|         //            Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrderDetails.Where(x => x.SaleOrder == item.SaleOrder && x.PVer == item.ProductVersion && x.PCode == item.ProductCode).FirstOrDefault(); | 
|         //            if (proOutOrderDetail == null) | 
|         //            { | 
|         //                return content.Error("未找到对应出库订单明细"); | 
|         //            } | 
|         //            proOutOrderDetail.OverQtyPcs += item.StockPcsQty; | 
|         //            item.OutboundQuantity = item.StockPcsQty; | 
|         //            item.OutSETQty = item.SETQty; | 
|         //            if (proOutOrderDetail.OverQtyPcs > proOutOrderDetail.QtyPcs) | 
|         //            { | 
|         //                return content.Error($"出库订单明细行{proOutOrderDetail.RowId},溢出{proOutOrderDetail.QtyPcs - proOutOrderDetail.OverQtyPcs}"); | 
|         //            } | 
|         //            if (proOutOrderDetail.OverQtyPcs == proOutOrderDetail.QtyPcs) | 
|         //            { | 
|         //                proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); | 
|         //            } | 
|   | 
|         //        } | 
|         //        proStockInfos.ForEach(x => | 
|         //        { | 
|         //            x.StockStatus = StockStatusEmun.平库待发货.ObjToInt(); | 
|         //        }); | 
|         //        proStockInfoDetails.ForEach(x => | 
|         //        { | 
|         //            x.ProOutDetailStatus = StockStatusEmun.平库待发货.ObjToInt(); | 
|         //        }); | 
|         //        int AddOverCount = proOutOrderDetails.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count(); | 
|         //        if (proOutOrder.Details.Count == (AddOverCount + OldOverCount)) | 
|         //        { | 
|         //            proOutOrder.ProOrderStatus = OutOrderStatusEnum.出库完成.ObjToInt(); | 
|         //            //获取所有已扫码待发货的库存 | 
|         //            List<Dt_ProStockInfo> AllOutStocks = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>() | 
|         //            .Where(x => x.ShipmentOrder == ProOutNo && x.StockStatus == StockStatusEmun.平库待发货.ObjToInt()) | 
|         //            .Includes(x => x.proStockInfoDetails).ToList(); | 
|         //            AllOutStocks.ForEach(x => | 
|         //            { | 
|         //                proStockInfoDetails.AddRange(x.proStockInfoDetails); | 
|         //            }); | 
|         //            proStockInfos.AddRange(AllOutStocks); | 
|         //            foreach (var item in proStockInfoDetails) | 
|         //            { | 
|         //                StockOutItemsItem outItemsItem = new StockOutItemsItem() | 
|         //                { | 
|         //                    PartNum = item.ProductCode, | 
|         //                    Rev = item.ProductVersion, | 
|         //                    SoNumber = item.SaleOrder, | 
|         //                    BatchNumber = item.BagNo, | 
|         //                    QtyPcs = item.OutboundQuantity, | 
|         //                    QtySet = item.OutSETQty | 
|         //                }; | 
|         //                stockOutItems.Add(outItemsItem); | 
|         //            } | 
|         //        } | 
|         //        Dt_Warehouse warehouse = warehouses.Where(x => x.WarehouseId == proOutOrder.WarehouseId).FirstOrDefault(); | 
|         //        _unitOfWorkManage.BeginTran(); | 
|         //        //处理库存数据和上传ERP | 
|         //        if (proOutOrder.ProOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt()) | 
|         //        { | 
|         //            //成品库存记录变动待加入 | 
|         //            ERPProOutOrderModel proOutOrderModel = new ERPProOutOrderModel() | 
|         //            { | 
|         //                Way = 1, | 
|         //                StockOutCode = _outboundOrderService.CreateCodeByRule(nameof(RuleCodeEnum.ProOutCOdeRule)), | 
|         //                ConfirmedUserNo = App.User.UserName, | 
|         //                AssignUserNo = App.User.UserName, | 
|         //                WarehouseCode = warehouse.WarehouseCode, | 
|         //                ShipDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | 
|         //                DeliverplanCode = proOutOrder.ProOutOrderNo, | 
|         //                Remark = proOutOrder.Remark, | 
|         //                StockOutItems = stockOutItems | 
|         //            }; | 
|         //            _stockRepository.ProStockInfoRepository.DeleteAndMoveIntoHty(proStockInfos, OperateTypeEnum.自动完成); | 
|         //            _stockRepository.ProStockInfoDetailRepository.DeleteAndMoveIntoHty(proStockInfoDetails, OperateTypeEnum.自动完成); | 
|         //            string response = _invokeERPService.InvokeProOutApi(proOutOrderModel); | 
|         //            ErpRequestContent erpRequestContent = response.DeserializeObject<ErpRequestContent>(); | 
|         //            if (erpRequestContent.res != 1) | 
|         //            { | 
|         //                throw new Exception("同步ERP失败,错误信息:" + erpRequestContent.Data); | 
|         //            } | 
|         //        } | 
|         //        else | 
|         //        { | 
|         //            _stockRepository.ProStockInfoRepository.UpdateData(proStockInfos); | 
|         //            _stockRepository.ProStockInfoDetailRepository.UpdateData(proStockInfoDetails); | 
|         //        } | 
|         //        _outboundRepository.ProOutOrderDetailRepository.UpdateData(proOutOrderDetails); | 
|         //        BaseDal.UpdateData(proOutOrder); | 
|         //        _unitOfWorkManage.CommitTran(); | 
|         //        content.OK(); | 
|         //    } | 
|         //    catch (Exception ex) | 
|         //    { | 
|         //        content.Error(ex.Message); | 
|         //    } | 
|         //    return content; | 
|         //} | 
|         /// <summary> | 
|         /// PDA获取出库单据 | 
|         /// </summary> | 
|         /// <param name="saveModel"></param> | 
|         /// <returns></returns> | 
|         public WebResponseContent GetProOutOrders(SaveModel saveModel) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 int pageNo = saveModel.MainData["pageNo"].ObjToInt(); | 
|                 int warehouseId = saveModel.MainData["warehouseId"].ObjToInt(); | 
|                 string orderNo = saveModel.MainData["orderNo"].ToString(); | 
|                 List<Dt_ProOutOrder> proOutOrders = new List<Dt_ProOutOrder>(); | 
|                 if (string.IsNullOrEmpty(orderNo)) | 
|                 { | 
|                     proOutOrders = Db.Queryable<Dt_ProOutOrder>().Where(x => x.ProOrderStatus <= OutOrderStatusEnum.出库中.ObjToInt() && x.WarehouseId == warehouseId).Includes(x=>x.Details).OrderByDescending(x => x.Id).ToPageList(pageNo, 5); | 
|                 } | 
|                 else | 
|                 { | 
|                     proOutOrders = Db.Queryable<Dt_ProOutOrder>().Where(x => (x.ProOutOrderNo.Contains(orderNo) || x.ProOutOrderNo.Contains(orderNo)) && x.ProOrderStatus <= OutOrderStatusEnum.出库中.ObjToInt() && x.WarehouseId == warehouseId).OrderByDescending(x => x.Id).Includes(x => x.Details).ToPageList(pageNo, 5); | 
|                 } | 
|   | 
|                 content.OK(data: proOutOrders); | 
|             } | 
|             catch (Exception) | 
|             { | 
|   | 
|                 throw; | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 获取扫码获取订单明细信息 | 
|         /// </summary> | 
|         public WebResponseContent GetOrderDetails(int keyId) | 
|         { | 
|             WebResponseContent content=new WebResponseContent(); | 
|             try | 
|             { | 
|                 //获取出库单号 | 
|                 Dt_ProOutOrder proOutOrder = BaseDal.QueryFirst(x => x.Id == keyId); | 
|                 if (proOutOrder == null) | 
|                 { | 
|                     return content.Error($"未找到出库单{proOutOrder.ProOutOrderNo}"); | 
|                 } | 
|                 //获取明细 | 
|                 List<Dt_ProOutOrderDetail> proOutOrderDetails = _outboundRepository.ProOutOrderDetailRepository.QueryData(x => x.ProOrderId == keyId).OrderBy(x => x.ProOrderDetailStatus).ThenBy(x => x.Id).ToList(); | 
|                 content.OK("成功", new { proOutOrderDetails }); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 查询ERP订单扣除库存数量 | 
|         /// </summary> | 
|         public WebResponseContent OutProErpSync(string outProOrderNo) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 //根据出库单号获取该出库订单的ERP出库库存信息 | 
|                 Dt_ProOutOrder proOutOrder = BaseDal.Db.Queryable<Dt_ProOutOrder>().Where(x=>x.ProOutOrderNo== outProOrderNo).Includes(x => x.Details).First(); | 
|                 if (proOutOrder==null) | 
|                 { | 
|                     return content.Error($"未找到成品出库订单{outProOrderNo}"); | 
|                 } | 
|                 if (proOutOrder.ProOrderStatus>=OutOrderStatusEnum.出库完成.ObjToInt()) | 
|                 { | 
|                     return content.Error($"出库订单已完成或关闭"); | 
|                 } | 
|                 //调用erp出库订单库存查询接口 | 
|                 string response = _invokeERPService.InvokeOutProErpSync(outProOrderNo); | 
|                 ErpOutProSyncResponseContent erpOutProSyncResponse= response.DeserializeObject<ErpOutProSyncResponseContent>(); | 
|                 if (erpOutProSyncResponse.Code!=200) | 
|                 { | 
|                     return content.Error($"ERP出库订单查询接口调用失败,错误信息:{erpOutProSyncResponse.Msg}"); | 
|                 } | 
|                 List<OutProStock> outProStocks = erpOutProSyncResponse.Data; | 
|                 if (outProStocks.Count<=0 || outProStocks==null) | 
|                 { | 
|                     return content.Error($"成品出库订单{outProOrderNo}ERP当前未有出库库存信息"); | 
|                 } | 
|                 // 验证所有出库单号是否一致 | 
|                 OutProStock? outExist = outProStocks.FirstOrDefault(x => x.ShippingNumber != outProOrderNo); | 
|                 if (outExist != null) | 
|                 { | 
|                     return content.Error($"ERP返回了出库订单{outExist.ShippingNumber}库存信息"); | 
|                 } | 
|                 //获取平库库区 | 
|                 Dt_Warehouse warehouse = _basicRepository.WarehouseRepository.QueryFirst(x => x.WarehouseCode == WarehouseEnum.HA101.ToString()); | 
|                 if (warehouse==null) | 
|                 { | 
|                     return content.Error("未找到库区信息"); | 
|                 } | 
|                 var productCodes = outProStocks.Select(x => x.Partnum).Distinct().ToList(); | 
|                 //获取所有平库库存 | 
|                 List<Dt_ProStockInfoDetail> proStockInfoDetails = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo, Dt_ProStockInfoDetail>((master, detail) => master.Id == detail.ProStockId) | 
|                 .Where((master, detail) => master.WarehouseId == warehouse.WarehouseId && productCodes.Contains(detail.ProductCode)) | 
|                 .Select((master, detail) => detail) | 
|                 .ToList(); | 
|                 proStockInfoDetails = proStockInfoDetails.OrderBy(x => x.DateCode).ThenBy(x => x.CreateDate).ToList(); | 
|                 List<int> stockIds = proStockInfoDetails.Select(x => x.ProStockId).Distinct().ToList(); | 
|                 //获取所有平库主表 | 
|                 List<Dt_ProStockInfo> proStockInfos = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>().Where(x => stockIds.Contains(x.Id)).Includes(x => x.proStockInfoDetails).ToList(); | 
|                 List<Dt_ProStockInfo> delProStockInfos = new List<Dt_ProStockInfo>(); | 
|                 List<Dt_ProStockInfoDetail> delStockInfoDetails = new List<Dt_ProStockInfoDetail>(); | 
|                 foreach (var item in outProStocks) | 
|                 { | 
|                     foreach (var itemOut in proStockInfoDetails.Where(x => x.ProductCode == item.Partnum).ToList()) | 
|                     { | 
|                         if (item.Quantity==0) | 
|                         { | 
|                             break; | 
|                         } | 
|                         Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrder.Details.FirstOrDefault(x => x.SaleOrder == item.SoNumber && x.PCode == item.Partnum) ?? throw new Exception($"出库单{proOutOrder.ProOutOrderNo}未找到销售订单{item.SoNumber}明细,请检查"); | 
|                         if (item.Quantity >= itemOut.StockPcsQty) | 
|                         { | 
|                             //更新出库明细单数量 | 
|                             proOutOrderDetail.OverQtyPcs += itemOut.StockPcsQty; | 
|                             item.Quantity -= (int)itemOut.StockPcsQty; | 
|                             delStockInfoDetails.Add(itemOut); | 
|                             proStockInfoDetails.Remove(itemOut); | 
|                             if (proOutOrderDetail.OverQtyPcs > proOutOrderDetail.QtyPcs) | 
|                             { | 
|                                 return content.Error($"出库单{proOutOrder.ProOutOrderNo}销售订单{item.SoNumber}数量溢出{proOutOrderDetail.OverQtyPcs - proOutOrderDetail.QtyPcs}"); | 
|                             } | 
|                             if (proOutOrderDetail.ProOrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) | 
|                             { | 
|                                 proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); | 
|                             } | 
|                             if (proOutOrderDetail.OverQtyPcs == proOutOrderDetail.QtyPcs) | 
|                             { | 
|                                 proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); | 
|                             } | 
|                         } | 
|                         else if (item.Quantity < itemOut.StockPcsQty) | 
|                         { | 
|                              | 
|                             //更新出库明细单数量 | 
|                             proOutOrderDetail.OverQtyPcs += item.Quantity; | 
|                             int Range = (int)itemOut.StockPcsQty / (int)itemOut.SETQty; | 
|                             if (Range == 0) | 
|                             { | 
|                                 return content.Error($"{itemOut.BagNo}单元数量转换失败,请检查,Range:{Range}"); | 
|                             } | 
|                             int outSet =item.Quantity / Range; | 
|                             if (outSet == 0) | 
|                             { | 
|                                 return content.Error($"{itemOut.BagNo}单元数量转换失败,请检查,outSet:{outSet}"); | 
|                             } | 
|                             itemOut.SETQty -= outSet; | 
|                              | 
|                             itemOut.StockPcsQty -= item.Quantity; | 
|                             item.Quantity = 0; | 
|                             if (proOutOrderDetail.OverQtyPcs > proOutOrderDetail.QtyPcs) | 
|                             { | 
|                                 return content.Error($"出库单{proOutOrder.ProOutOrderNo}销售订单{item.SoNumber}数量溢出{proOutOrderDetail.OverQtyPcs - proOutOrderDetail.QtyPcs}"); | 
|                             } | 
|                             if (proOutOrderDetail.ProOrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) | 
|                             { | 
|                                 proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); | 
|                             } | 
|                             if (proOutOrderDetail.OverQtyPcs == proOutOrderDetail.QtyPcs) | 
|                             { | 
|                                 proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); | 
|                             } | 
|                         } | 
|                     } | 
|                     if (item.Quantity>0) | 
|                     { | 
|                         return content.Error($"未找到{item.SoNumber}可扣减库存"); | 
|                     } | 
|                 } | 
|                 if (proOutOrder.Details.Count == proOutOrder.Details.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count()) | 
|                 { | 
|                     proOutOrder.ProOrderStatus = OutOrderStatusEnum.出库完成.ObjToInt(); | 
|                 } | 
|                 else | 
|                 { | 
|                     Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrder.Details.FirstOrDefault(x => x.ProOrderDetailStatus <= OrderDetailStatusEnum.Over.ObjToInt()); | 
|                     return content.Error($"{proOutOrderDetail?.SaleOrder}销售订单数量需出{proOutOrderDetail?.QtyPcs},可出{proOutOrderDetail?.OverQtyPcs}"); | 
|                 } | 
|                 //获取删除的库存主表 | 
|                 List<int> delStockIds = delStockInfoDetails.Select(x => x.ProStockId).Distinct().ToList(); | 
|                 List<int> delStockDetailIds = delStockInfoDetails.Select(x => x.Id).ToList(); | 
|                 foreach (var item in delStockIds) | 
|                 { | 
|                     Dt_ProStockInfo proStockInfo = proStockInfos.FirstOrDefault(x => x.Id == item); | 
|                     Dt_ProStockInfoDetail? proStockInfoDetail = proStockInfo.proStockInfoDetails.FirstOrDefault(x => !delStockDetailIds.Contains(x.Id)); | 
|                     if (proStockInfoDetail == null) | 
|                     { | 
|                         delProStockInfos.Add(proStockInfo); | 
|                     } | 
|                 } | 
|                 //更新数据 | 
|                 _unitOfWorkManage.BeginTran(); | 
|                 _stockRepository.ProStockInfoDetailRepository.DeleteAndMoveIntoHty(delStockInfoDetails, OperateTypeEnum.自动删除); | 
|                 _stockRepository.ProStockInfoRepository.DeleteAndMoveIntoHty(delProStockInfos, OperateTypeEnum.自动完成); | 
|                 _stockRepository.ProStockInfoDetailRepository.UpdateData(proStockInfoDetails); | 
|                 BaseDal.UpdateData(proOutOrder); | 
|                 _outboundRepository.ProOutOrderDetailRepository.UpdateData(proOutOrder.Details); | 
|                 _unitOfWorkManage.CommitTran(); | 
|                 return content.OK(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 _unitOfWorkManage.RollbackTran(); | 
|                 return content.Error(ex.Message); | 
|             } | 
|         } | 
|         /// <summary> | 
|         /// 出库单扫码同步ERP | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public async Task<WebResponseContent> OutProScanCodeSync(SaveModel saveModel) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 string? ProOutNo = saveModel.MainData["outProOrderNo"].ToString(); | 
|                 var Codes = saveModel.DelKeys.Select(x=>x.ToString().Trim()).ToList(); | 
|                 if (Codes.Count<=0) | 
|                 { | 
|                     return await Task.FromResult(content.Error("扫描内容不能为空")); | 
|                 } | 
|                 Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.Db.Queryable<Dt_ProOutOrder>().Where(x => x.ProOutOrderNo == ProOutNo).Includes(x => x.Details).First(); | 
|                 if (proOutOrder == null) | 
|                 { | 
|                     return await Task.FromResult(content.Error($"出库单{ProOutNo}不存在")); | 
|                 } | 
|                 if (proOutOrder.ProOrderStatus >= OutOrderStatusEnum.出库完成.ObjToInt()) | 
|                 { | 
|                     return await Task.FromResult(content.Error($"出库单{ProOutNo}已完成或关闭")); | 
|                 } | 
|                 string? userName = App.User.UserName;//GSWMS | 
|                 List<OutProInfoDTO> outProInfos= new List<OutProInfoDTO>(); | 
|                 foreach (var item in Codes) | 
|                 { | 
|                     string[] proInfoInputs = item.Split(','); | 
|                     if (proInfoInputs.Length!=5) | 
|                     { | 
|                         return await Task.FromResult(content.Error($"外包{item}扫描不全")); | 
|                     } | 
|                     OutProInfoDTO outProInfo=new OutProInfoDTO() | 
|                     { | 
|                         ProductCode= proInfoInputs[1], | 
|                         OutQtys = proInfoInputs[4].ObjToInt() | 
|                     }; | 
|                     outProInfos.Add(outProInfo); | 
|                 } | 
|                 //获取平库库区 | 
|                 Dt_Warehouse warehouse = await _basicRepository.WarehouseRepository.QueryFirstAsync(x => x.WarehouseCode == WarehouseEnum.HA101.ToString()); | 
|                 if (warehouse == null) | 
|                 { | 
|                     return await Task.FromResult(content.Error("未找到库区信息")); | 
|                 } | 
|                  | 
|                 //获取所有平库库存 | 
|                 List<Dt_ProStockInfoDetail> proStockInfoDetails = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo, Dt_ProStockInfoDetail>((master, detail) => master.Id == detail.ProStockId) | 
|                 .Where((master, detail) => master.WarehouseId == warehouse.WarehouseId && outProInfos.Select(x=>x.ProductCode).Contains(detail.ProductCode)) | 
|                 .Select((master, detail) => detail) | 
|                 .ToList(); | 
|                 List<int> stockIds = proStockInfoDetails.Select(x => x.ProStockId).Distinct().ToList(); | 
|                 //获取所有平库主表 | 
|                 List<Dt_ProStockInfo> proStockInfos = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>().Where(x => stockIds.Contains(x.Id)).Includes(x=>x.proStockInfoDetails).ToList(); | 
|                 proStockInfoDetails = proStockInfoDetails.OrderBy(x => x.DateCode).ThenBy(x => x.CreateDate).ThenBy(x=>x.StockPcsQty).ToList(); | 
|   | 
|                 List<Dt_Warehouse> warehouses = await _basicRepository.WarehouseRepository.QueryDataAsync(x => x.WarehouseType == WarehouseTypEnum.成品.ToString()); | 
|                 //将其分组 | 
|                 outProInfos = outProInfos.GroupBy(x => x.ProductCode).Select(x=>new OutProInfoDTO() | 
|                 { | 
|                     ProductCode=x.Key, | 
|                     OutQtys=x.Sum(x=>x.OutQtys) | 
|                 }).ToList(); | 
|                 List<Dt_ProStockInfoDetail> UpStockInfoDetails = new List<Dt_ProStockInfoDetail>(); | 
|                 List<Dt_ProStockInfo> DelStocks = new List<Dt_ProStockInfo>(); | 
|                 foreach (var item in outProInfos) | 
|                 { | 
|                     //获取库存 | 
|                     List<Dt_ProStockInfoDetail> outStocks = proStockInfoDetails.Where(x => x.ProductCode == item.ProductCode && x.OutProNo == null).ToList(); | 
|                     if (outStocks.Count <= 0 || outProInfos==null) | 
|                     { | 
|                         return await Task.FromResult(content.Error($"未找到产品{item.ProductCode}库存")); | 
|                     } | 
|                     if (outStocks.Sum(x=>x.StockPcsQty)< item.OutQtys) | 
|                     { | 
|                         return await Task.FromResult(content.Error($"可用平库数量{outStocks.Sum(x => x.StockPcsQty)}不满足出库数量{item.OutQtys}")); | 
|                     } | 
|                     foreach (var outStock in outStocks) | 
|                     { | 
|                         //如果扣减为0跳出逻辑 | 
|                         if (item.OutQtys == 0) | 
|                         { | 
|                             break; | 
|                         } | 
|                         //判断出库数量是否大于或等于库存数量 | 
|                         if (item.OutQtys >= outStock.StockPcsQty) | 
|                         { | 
|                             Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrder.Details.FirstOrDefault(x => x.PCode == item.ProductCode && x.ProOrderDetailStatus < OrderDetailStatusEnum.Over.ObjToInt()); | 
|                             //判断是否存在同一型号两条明细 | 
|                             if (proOutOrderDetail == null) | 
|                             { | 
|                                 return await Task.FromResult(content.Error($"出库单{proOutOrder.ProOutOrderNo}未找到产品{item.ProductCode}明细,请检查")); | 
|                             } | 
|                             List<Dt_ProOutOrderDetail>? outOrderDetails = proOutOrder.Details.Where(x => x.PCode == item.ProductCode && x.ProOrderDetailStatus < OrderDetailStatusEnum.Over.ObjToInt() && x.Id != proOutOrderDetail.Id).ToList(); | 
|                             float BeyondQtys = proOutOrderDetail.QtyPcs - proOutOrderDetail.OverQtyPcs; | 
|                             //更新出库明细单数量 | 
|                             proOutOrderDetail.OverQtyPcs += outStock.StockPcsQty; | 
|                              | 
|                             //是否超出 | 
|                             if (proOutOrderDetail.OverQtyPcs > proOutOrderDetail.QtyPcs) | 
|                             { | 
|                                 if (outOrderDetails.Count>=1) | 
|                                 { | 
|                                     proOutOrderDetail.OverQtyPcs -= outStock.StockPcsQty; | 
|                                     proOutOrderDetail.OverQtyPcs += BeyondQtys; | 
|                                     outStock.OutboundQuantity = BeyondQtys; | 
|                                     outStock.OutDetailSaleNo = proOutOrderDetail.SaleOrder; | 
|                                     outStock.OutProNo = proOutOrder.ProOutOrderNo; | 
|                                     float Range = outStock.StockPcsQty / outStock.SETQty; | 
|                                     if (outStock.OutboundQuantity== outStock.StockPcsQty) | 
|                                     { | 
|                                         outStock.OutSETQty = outStock.SETQty; | 
|                                         outStock.AssignDel = 1; | 
|                                     } | 
|                                     else | 
|                                     { | 
|                                         outStock.OutSETQty = outStock.OutboundQuantity / Range; | 
|                                     } | 
|                                     if (outStock.OutSETQty==0) | 
|                                     { | 
|                                         return await Task.FromResult(content.Error($"{outStock.BagNo}单元数量转换失败,请检查")); | 
|                                     } | 
|                                     item.OutQtys -= (int)BeyondQtys; | 
|                                     UpStockInfoDetails.Add(outStock); | 
|                                     proStockInfoDetails.Remove(outStock); | 
|                                 } | 
|                                 else | 
|                                 { | 
|                                     return await Task.FromResult(content.Error($"出库单{proOutOrder.ProOutOrderNo}行号{proOutOrderDetail.RowId}产品型号{item.ProductCode}数量溢出{proOutOrderDetail.OverQtyPcs - proOutOrderDetail.QtyPcs}")); | 
|                                 } | 
|                             } | 
|                             else | 
|                             { | 
|                                 outStock.OutboundQuantity = outStock.StockPcsQty; | 
|                                 outStock.OutDetailSaleNo = proOutOrderDetail.SaleOrder; | 
|                                 outStock.OutProNo = proOutOrder.ProOutOrderNo; | 
|                                 outStock.OutSETQty = outStock.SETQty; | 
|                                 outStock.AssignDel = 1; | 
|                                 item.OutQtys -= (int)outStock.StockPcsQty; | 
|                                 UpStockInfoDetails.Add(outStock); | 
|                                 proStockInfoDetails.Remove(outStock); | 
|                             } | 
|                             if (proOutOrderDetail.ProOrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) | 
|                             { | 
|                                 proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); | 
|                             } | 
|                             if (proOutOrderDetail.OverQtyPcs == proOutOrderDetail.QtyPcs) | 
|                             { | 
|                                 proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); | 
|                             } | 
|                         } | 
|                         else if (item.OutQtys < outStock.StockPcsQty) //剩余数量小于 | 
|                         { | 
|                             Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrder.Details.FirstOrDefault(x => x.PCode == item.ProductCode && x.ProOrderDetailStatus < OrderDetailStatusEnum.Over.ObjToInt()); | 
|                             if (proOutOrderDetail == null) | 
|                             { | 
|                                 return await Task.FromResult(content.Error($"出库单{proOutOrder.ProOutOrderNo}未找到产品{item.ProductCode}明细,请检查")); | 
|                             } | 
|                             List<Dt_ProOutOrderDetail>? outOrderDetails = proOutOrder.Details.Where(x => x.PCode == item.ProductCode && x.ProOrderDetailStatus < OrderDetailStatusEnum.Over.ObjToInt() && x.Id != proOutOrderDetail.Id).ToList(); | 
|                             //更新出库明细单数量 | 
|                             float BeyondQtys = proOutOrderDetail.QtyPcs - proOutOrderDetail.OverQtyPcs; | 
|                             proOutOrderDetail.OverQtyPcs += item.OutQtys; | 
|                              | 
|                             //是否超出 | 
|                             if (proOutOrderDetail.OverQtyPcs > proOutOrderDetail.QtyPcs) | 
|                             { | 
|                                 if (outOrderDetails.Count >= 1) | 
|                                 { | 
|                                     proOutOrderDetail.OverQtyPcs -= outStock.StockPcsQty; | 
|                                     proOutOrderDetail.OverQtyPcs += BeyondQtys; | 
|                                     outStock.OutDetailSaleNo = proOutOrderDetail.SaleOrder; | 
|                                     outStock.OutProNo = proOutOrder.ProOutOrderNo; | 
|                                     outStock.OutboundQuantity = BeyondQtys; | 
|                                     float Range = outStock.StockPcsQty / outStock.SETQty; | 
|                                     outStock.OutSETQty = outStock.OutboundQuantity / Range; | 
|                                     if (outStock.OutSETQty == 0) | 
|                                     { | 
|                                         return await Task.FromResult(content.Error($"{outStock.BagNo}单元数量转换失败,请检查")); | 
|                                     } | 
|                                     item.OutQtys = 0; | 
|                                     UpStockInfoDetails.Add(outStock); | 
|                                     proStockInfoDetails.Remove(outStock); | 
|                                 } | 
|                                 else | 
|                                 { | 
|                                     return await Task.FromResult(content.Error($"出库单{proOutOrder.ProOutOrderNo}行号{proOutOrderDetail.RowId}产品型号{item.ProductCode}数量溢出{proOutOrderDetail.OverQtyPcs - proOutOrderDetail.QtyPcs}")); | 
|                                 } | 
|                             } | 
|                             else | 
|                             { | 
|                                 outStock.OutDetailSaleNo = proOutOrderDetail.SaleOrder; | 
|                                 outStock.OutProNo = proOutOrder.ProOutOrderNo; | 
|                                 outStock.OutboundQuantity = item.OutQtys; | 
|                                 float Range = outStock.StockPcsQty / outStock.SETQty; | 
|                                 outStock.OutSETQty = outStock.OutboundQuantity / Range; | 
|                                 if (outStock.OutSETQty == 0) | 
|                                 { | 
|                                     return await Task.FromResult(content.Error($"{outStock.BagNo}单元数量转换失败,请检查")); | 
|                                 } | 
|                                 item.OutQtys = 0; | 
|                                 UpStockInfoDetails.Add(outStock); | 
|                                 proStockInfoDetails.Remove(outStock); | 
|                             } | 
|                             if (proOutOrderDetail.ProOrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) | 
|                             { | 
|                                 proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); | 
|                             } | 
|                             if (proOutOrderDetail.OverQtyPcs == proOutOrderDetail.QtyPcs) | 
|                             { | 
|                                 proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt(); | 
|                             } | 
|                         } | 
|                     } | 
|                 } | 
|                 if (proOutOrder.Details.Count == proOutOrder.Details.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count()) | 
|                 { | 
|                     proOutOrder.ProOrderStatus = OutOrderStatusEnum.出库完成.ObjToInt(); | 
|                 } | 
|                 else | 
|                 { | 
|                     Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrder.Details.FirstOrDefault(x => x.ProOrderDetailStatus < OrderDetailStatusEnum.Over.ObjToInt()); | 
|                     return await Task.FromResult(content.Error($"{proOutOrderDetail?.SaleOrder}销售订单数量需出{proOutOrderDetail?.QtyPcs},可出{proOutOrderDetail?.OverQtyPcs}")); | 
|                 } | 
|                 List<StockOutItemsItem> stockOutItems = new List<StockOutItemsItem>(); | 
|                 //获取所有已扫码待发货的库存 | 
|                 List<Dt_ProStockInfoDetail> assOutStocks = _stockRepository.ProStockInfoDetailRepository.Db.Queryable<Dt_ProStockInfoDetail>() | 
|                 .Where(x => x.OutProNo == ProOutNo).ToList(); | 
|                 UpStockInfoDetails.AddRange(assOutStocks); | 
|                 foreach (var item in UpStockInfoDetails) | 
|                 { | 
|                     StockOutItemsItem outItemsItem = new StockOutItemsItem() | 
|                     { | 
|                         PartNum = item.ProductCode, | 
|                         Rev = item.ProductVersion, | 
|                         SoNumber = item.OutDetailSaleNo, | 
|                         BatchNumber = item.ProductCode, | 
|                         QtyPcs = item.OutboundQuantity, | 
|                         QtySet = item.OutSETQty | 
|                     }; | 
|                     stockOutItems.Add(outItemsItem); | 
|                 } | 
|                 Dt_Warehouse warehouseOut = warehouses.Where(x => x.WarehouseId == proOutOrder.WarehouseId).FirstOrDefault(); | 
|                 //获取删除库存 | 
|                 List<Dt_ProStockInfoDetail> delDetails = UpStockInfoDetails.Where(x => x.AssignDel == 1).ToList(); | 
|                 List<Dt_ProStockInfoDetail> UpDetails = UpStockInfoDetails.Where(x => x.AssignDel != 1).ToList(); | 
|                 //获取删除的库存主表 | 
|                 List<int> delStockIds = delDetails.Select(x => x.ProStockId).Distinct().ToList(); | 
|                 List<int> delStockDetailIds = delDetails.Select(x => x.Id).ToList(); | 
|                 foreach (var item in delStockIds) | 
|                 { | 
|                     Dt_ProStockInfo proStockInfo = proStockInfos.FirstOrDefault(x=>x.Id==item); | 
|                     Dt_ProStockInfoDetail? proStockInfoDetail= proStockInfo.proStockInfoDetails.FirstOrDefault(x=> !delStockDetailIds.Contains(x.Id)); | 
|                     if (proStockInfoDetail==null) | 
|                     { | 
|                         DelStocks.Add(proStockInfo); | 
|                     } | 
|                 } | 
|                 _unitOfWorkManage.BeginTran(); | 
|                 //处理库存数据和上传ERP | 
|                 //成品库存记录变动待加入 | 
|                 ERPProOutOrderModel proOutOrderModel = new ERPProOutOrderModel() | 
|                 { | 
|                     Way = 1, | 
|                     StockOutCode = _outboundOrderService.CreateCodeByRule(nameof(RuleCodeEnum.ProOutCOdeRule)), | 
|                     ConfirmedUserNo = App.User.UserName, | 
|                     AssignUserNo = App.User.UserName, | 
|                     WarehouseCode = warehouseOut.WarehouseCode, | 
|                     ShipDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | 
|                     DeliverplanCode = proOutOrder.ProOutOrderNo, | 
|                     Remark = proOutOrder.Remark, | 
|                     StockOutItems = stockOutItems | 
|                 }; | 
|                 //更新数据 | 
|                 UpDetails.ForEach(x => | 
|                 { | 
|                     x.StockPcsQty -= x.OutboundQuantity; | 
|                     x.SETQty -= x.OutSETQty; | 
|                     x.OutDetailId = 0; | 
|                     x.OutDetailSaleNo = null; | 
|                     x.OutProNo = null; | 
|                 }); | 
|                 _stockRepository.ProStockInfoDetailRepository.DeleteAndMoveIntoHty(delDetails, OperateTypeEnum.自动完成); | 
|                 _stockRepository.ProStockInfoRepository.DeleteAndMoveIntoHty(DelStocks, OperateTypeEnum.自动完成); | 
|                 await _stockRepository.ProStockInfoDetailRepository.UpdateDataAsync(UpDetails); | 
|                 //同步ERP | 
|                 string response = _invokeERPService.InvokeProOutApi(proOutOrderModel); | 
|                 ErpRequestContent erpRequestContent = response.DeserializeObject<ErpRequestContent>(); | 
|                 if (erpRequestContent.res != 1) | 
|                 { | 
|                     throw new Exception("同步ERP失败,错误信息:" + erpRequestContent.Data); | 
|                 } | 
|                 await _outboundRepository.ProOutOrderDetailRepository.UpdateDataAsync(proOutOrder.Details); | 
|                 await BaseDal.UpdateDataAsync(proOutOrder); | 
|                 _unitOfWorkManage.CommitTran(); | 
|                 return await Task.FromResult(content.OK()); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 _unitOfWorkManage.RollbackTran(); | 
|                 return await Task.FromResult(content.Error(ex.Message)); | 
|             } | 
|         } | 
|     } | 
| } |