using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEA_Core.BaseServices; using WIDESEA_Core; using WIDESEA_IInboundService; using WIDESEA_Model.Models; using WIDESEA_Common.OrderEnum; using WIDESEA_Core.Helper; using Microsoft.AspNetCore.Mvc.RazorPages; using WIDESEA_Core.Enums; using SqlSugar; using WIDESEA_Core.BaseRepository; using WIDESEA_Common.StockEnum; using Microsoft.AspNetCore.Mvc; using WIDESEA_DTO.Inbound; using WIDESEA_DTO.ReturnMES; using MailKit.Search; using static System.Collections.Specialized.BitVector32; using WIDESEA_Common.CommonEnum; using WIDESEA_Common.TaskEnum; using WIDESEA_IBasicService; using static HslCommunication.Profinet.Knx.KnxCode; using System.Collections; using WIDESEA_Common.AllocateEnum; using WIDESEA_Model.Models.Basic; using WIDESEA_IOutboundService; using WIDESEA_DTO.CalcOut; using Newtonsoft.Json.Serialization; using Newtonsoft.Json; using WIDESEA_DTO.Basic; namespace WIDESEA_InboundService { public class TakeStockOrderService : ServiceBase>, ITakeStockOrderService { public IRepository Repository => BaseDal; private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IRepository _takeStockOrder; private readonly IRepository _stockInfoRepository; private readonly IRepository _takeStockOrderDetail; private readonly IRepository _taskRepository; private readonly ILocationInfoService _locationInfoService; private readonly IRepository _inboundOrderRepository; private readonly IRepository _outboundOrderRepository; private readonly IRepository _inboundOrderDetailRepository; private readonly IRepository _outboundOrderDetailRepository; private readonly IOutboundPickingService _outboundPickingService; private readonly IRepository _stockInfoDetailRepository; private readonly IOutboundService _outboundService; private readonly IFeedbackMesService _feedbackMesService; private readonly IESSApiService _eSSApiService; public TakeStockOrderService(IRepository BaseDal, IUnitOfWorkManage unitOfWorkManage,IRepository takeStockOrder,IRepository stockInfoRepository,IRepository takeStockOrderDetail,IRepository taskRepository,ILocationInfoService locationInfoService, IRepository inboundOrderRepository,IRepository outboundOrderRepository,IRepository inboundOrderDetailRepository, IRepository outboundOrderDetailRepository, IOutboundPickingService outboundPickingService, IRepository stockInfoDetailRepository, IOutboundService outboundService,IFeedbackMesService feedbackMesService,IESSApiService eSSApiService) : base(BaseDal) { _unitOfWorkManage = unitOfWorkManage; _takeStockOrder = takeStockOrder; _stockInfoRepository = stockInfoRepository; _takeStockOrderDetail = takeStockOrderDetail; _taskRepository = taskRepository; _locationInfoService = locationInfoService; _inboundOrderRepository = inboundOrderRepository; _outboundOrderRepository = outboundOrderRepository; _inboundOrderDetailRepository = inboundOrderDetailRepository; _outboundOrderDetailRepository = outboundOrderDetailRepository; _outboundPickingService = outboundPickingService; _stockInfoDetailRepository = stockInfoDetailRepository; _outboundService = outboundService; _feedbackMesService = feedbackMesService; _eSSApiService = eSSApiService; } private Dictionary stations = new Dictionary { {"2-1","2-9" }, {"3-1","3-9" }, }; private Dictionary movestations = new Dictionary { {"2-1","2-5" }, {"3-1","3-5" }, }; public WebResponseContent ValidateBoxNo(string orderNo, string boxNo) { try { Dt_StockInfo stockInfo = _stockInfoRepository.QueryFirst(x => x.PalletCode == boxNo); if (stockInfo == null) { return WebResponseContent.Instance.Error("未找到该托盘库存"); } if(stockInfo.StockStatus != StockStatusEmun.盘点出库完成.ObjToInt() && stockInfo.StockStatus != StockStatusEmun.盘点库存完成.ObjToInt()) { return WebResponseContent.Instance.Error("该托盘处于非盘点状态,请检查盘点任务"); } Dt_TakeStockOrder takeStockOrder = _takeStockOrder.QueryFirst(x=>x.AllPalletCode.Contains(boxNo)&& x.TakeStockStatus == TakeStockStatusEnum.盘点中.ObjToInt()); if (takeStockOrder == null) { return WebResponseContent.Instance.Error("该托盘未找到该盘点单据"); } if (takeStockOrder.AllPalletCode.Contains(",")) { var remarkValues = takeStockOrder.AllPalletCode .Split(',') .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)) .ToList(); if (remarkValues.Count == 0) { return WebResponseContent.Instance.Error("盘点单箱号仅包含逗号,无有效箱号数据"); } bool isMatch = remarkValues.Any(val => val.Equals(boxNo, StringComparison.OrdinalIgnoreCase)); if (!isMatch) { return WebResponseContent.Instance.Error($"箱号【{boxNo}】未在盘点单箱号【{takeStockOrder.AllPalletCode}】中找到匹配项"); } } var resultData = new { takeStockOrder = takeStockOrder.OrderNo }; return WebResponseContent.Instance.OK(data:resultData); } catch(Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } public WebResponseContent ValidateBarcode(string boxNo, string barcode) { try { Dt_StockInfo stockInfo = _stockInfoRepository.Db.Queryable().Where(x => x.PalletCode == boxNo).Includes(x => x.Details).First(); if(stockInfo == null) { return WebResponseContent.Instance.Error("未找到该料箱库存信息"); } if(stockInfo.Details == null) { return WebResponseContent.Instance.Error("未找到该料箱库存"); } List barcodes = stockInfo.Details.Select(x => x.Barcode).ToList(); bool isMatch = barcodes.Any(val => val.Equals(barcode, StringComparison.OrdinalIgnoreCase)); if (!isMatch) { return WebResponseContent.Instance.Error($"条码【{barcode}】未在【{boxNo}】料箱条码中找到匹配项"); } var stockDetail = stockInfo.Details.FirstOrDefault(x=>x.Barcode == barcode); var resultData = new { stockQuantity = stockDetail.StockQuantity }; return WebResponseContent.Instance.OK(data:resultData); } catch(Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } public WebResponseContent CompleteStockTake([FromBody] CompleteStockTakeDTO completeStockTakeDTO) { try { Dt_TakeStockOrder takeStockOrder = _takeStockOrder.QueryFirst(x=>x.OrderNo == completeStockTakeDTO.orderNo); if (takeStockOrder == null) { return WebResponseContent.Instance.Error("未找到该盘点单据"); } Dt_StockInfo stockInfo = _stockInfoRepository.Db.Queryable().Where(x => x.PalletCode == completeStockTakeDTO.boxNo).Includes(x=>x.Details).First(); if(stockInfo == null) { return WebResponseContent.Instance.Error("未找到该托盘库存"); } Dt_StockInfoDetail stockInfoDetail = stockInfo.Details.FirstOrDefault(x => x.Barcode == completeStockTakeDTO.barcode); if(stockInfoDetail == null) { return WebResponseContent.Instance.Error("条码库存数据未找到匹配数据"); } Dt_TakeStockOrderDetail takeStockOrderDetail = new Dt_TakeStockOrderDetail() { TakeStockId = takeStockOrder.Id, MaterielCode = stockInfoDetail.MaterielCode, MaterielName = stockInfoDetail.MaterielName ?? "", BatchNo = stockInfoDetail.BatchNo, TakePalletCode = completeStockTakeDTO.boxNo, TakeDetalStatus = TakeStockDetailStatusEnum.未进行平账处理.ObjToInt(), Unit = stockInfoDetail.Unit, SysQty = completeStockTakeDTO.stockQuantity, Qty = completeStockTakeDTO.actualQuantity, Remark = "盘亏", barcode = completeStockTakeDTO.barcode, WarehouseCode = stockInfoDetail.WarehouseCode ?? "", FactoryArea = stockInfoDetail.FactoryArea, SupplyCode = stockInfoDetail.SupplyCode ?? "", TakeStockNo = takeStockOrder.OrderNo, DifferenceQty = completeStockTakeDTO.actualQuantity - completeStockTakeDTO.stockQuantity }; stockInfoDetail.StockId = 0; stockInfoDetail.OrderNo = takeStockOrder.OrderNo; stockInfo.StockStatus = StockStatusEmun.盘点库存完成.ObjToInt(); _unitOfWorkManage.BeginTran(); _takeStockOrderDetail.AddData(takeStockOrderDetail); _stockInfoDetailRepository.UpdateData(stockInfoDetail); _stockInfoRepository.UpdateData(stockInfo); _unitOfWorkManage.CommitTran(); return WebResponseContent.Instance.OK("盘点完成,请取走该异常料箱进行平账处理!"); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } public WebResponseContent ReturnBox(string orderNo, string boxNo, string sourceAddress) { WebResponseContent content = new WebResponseContent(); try { Dt_TakeStockOrder takeStockOrder = _takeStockOrder.QueryFirst(x=>x.OrderNo == orderNo); if(takeStockOrder == null) { return content.Error("未找到该盘点单据"); } var stock = _stockInfoRepository.Db.Queryable().Where(x => x.PalletCode == boxNo).Includes(x=>x.Details).First(); if (stock == null) { return content.Error($"未找到托盘{boxNo}库存信息不允许回库"); } var task = _taskRepository.QueryFirst(x => x.PalletCode == boxNo); if (task != null) { return content.Error($"托盘{boxNo}存在任务,回库失败!"); } if(stock.StockStatus != StockStatusEmun.盘点出库完成.ObjToInt() && stock.StockStatus != StockStatusEmun.盘点库存完成.ObjToInt()) { return content.Error("该托盘状态不对,不允许盘点入库"); } var palletCodes = new HashSet(StringComparer.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(takeStockOrder.AllPalletCode)) { palletCodes = takeStockOrder.AllPalletCode .Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(p => p.Trim()) .ToHashSet(StringComparer.OrdinalIgnoreCase); } int overPalletCodeCount = _stockInfoRepository.QueryData(x => palletCodes.Contains(x.PalletCode) && (x.StockStatus == StockStatusEmun.出库完成.ObjToInt() || x.StockStatus == StockStatusEmun.入库完成.ObjToInt() || x.StockStatus == StockStatusEmun.出库锁定.ObjToInt()|| x.StockStatus == StockStatusEmun.入库确认.ObjToInt())).Count(); bool hasRelatedTasks = palletCodes.Count == overPalletCodeCount + 1; if (hasRelatedTasks) { takeStockOrder.TakeStockStatus = (int)TakeStockStatusEnum.盘点完成; } stock.StockStatus = StockStatusEmun.入库确认.ObjToInt(); // 分配新货位 var newLocation = _locationInfoService.AssignLocation(stock.LocationType); if (newLocation == null) { return WebResponseContent.Instance.Error("没有空闲库位可回库"); } var newTask = new Dt_Task() { CurrentAddress = takeStockOrder.Remark, Grade = 0, PalletCode = boxNo, NextAddress = "", OrderNo = takeStockOrder.OrderNo, Roadway = newLocation.RoadwayNo, SourceAddress = stations.GetValueOrDefault(sourceAddress)??"", TargetAddress = newLocation.LocationCode, TaskStatus = (int)TaskStatusEnum.New, TaskType = TaskTypeEnum.InInventory.ObjToInt(), PalletType = stock.PalletType, WarehouseId = stock.WarehouseId }; if (stock.Details.Count <= 0) { stock.PalletType = (int)PalletTypeEnum.Empty; newTask.TaskType = TaskTypeEnum.InEmpty.ObjToInt(); } _unitOfWorkManage.BeginTran(); _stockInfoRepository.UpdateData(stock); _takeStockOrder.UpdateData(takeStockOrder); _taskRepository.AddData(newTask); _unitOfWorkManage.CommitTran(); var moveResult = _eSSApiService.MoveContainerAsync(new MoveContainerRequest { slotCode = movestations[sourceAddress], containerCode = boxNo }); return content.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return content.Error(ex.Message); } } public WebResponseContent ManualReconciliation(int id) { try { Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x=>x.Id == id); if(takeStockOrderDetail == null) { return WebResponseContent.Instance.Error("未找到该盘点差异记录"); } else { if(takeStockOrderDetail.TakeDetalStatus != TakeStockDetailStatusEnum.未进行平账处理.ObjToInt()) { return WebResponseContent.Instance.Error("该记录已经进行了平账操作"); } takeStockOrderDetail.DifferenceQty = 0; takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.已进行平账处理.ObjToInt(); } _takeStockOrderDetail.UpdateData(takeStockOrderDetail); return WebResponseContent.Instance.OK(); } catch(Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } public WebResponseContent SelectOrder(string remark, int id) { try { Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x => x.Id == id); if (takeStockOrderDetail == null) { return WebResponseContent.Instance.Error("未找到该盘点差异记录"); } else { //查杂收单 if (takeStockOrderDetail.Remark == "盘盈") { List inboundOrderDetails = new List(); List inboundOrders = _inboundOrderRepository.Db.Queryable().Where(x => x.BusinessType == "12" && x.OrderStatus != InOrderStatusEnum.入库完成.ObjToInt()).Includes(x => x.Details).ToList(); foreach (var inboundOrder in inboundOrders) { var matchedDetails = inboundOrder.Details .Where(detail => !string.IsNullOrEmpty(detail.MaterielCode) && detail.MaterielCode == takeStockOrderDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()) .WhereIF(!string.IsNullOrEmpty(takeStockOrderDetail.FactoryArea), detail => !string.IsNullOrEmpty(inboundOrder.FactoryArea) && inboundOrder.FactoryArea == takeStockOrderDetail.FactoryArea) .WhereIF(!string.IsNullOrEmpty(takeStockOrderDetail.WarehouseCode), detail => !string.IsNullOrEmpty(detail.WarehouseCode) && detail.WarehouseCode == takeStockOrderDetail.WarehouseCode) .WhereIF(!string.IsNullOrEmpty(takeStockOrderDetail.BatchNo), detail => !string.IsNullOrEmpty(detail.BatchNo) && detail.BatchNo == takeStockOrderDetail.BatchNo) .ToList(); // 将匹配的明细添加到总列表 if (matchedDetails.Any()) { inboundOrderDetails.AddRange(matchedDetails); } } return WebResponseContent.Instance.OK("成功",data: inboundOrderDetails); } else { List outboundOrderDetails = new List(); List outboundOrders = _outboundOrderRepository.Db.Queryable().Where(x => x.BusinessType == "23" && x.OrderStatus != OutOrderStatusEnum.出库完成.ObjToInt()).Includes(x => x.Details).ToList(); foreach (var outboundOrder in outboundOrders) { var matchedDetails = outboundOrder.Details .Where(detail => !string.IsNullOrWhiteSpace(detail.MaterielCode) && detail.MaterielCode == takeStockOrderDetail.MaterielCode && detail.OrderQuantity-detail.MoveQty-detail.OverOutQuantity>0) .WhereIF(!string.IsNullOrWhiteSpace(takeStockOrderDetail.FactoryArea), detail => !string.IsNullOrWhiteSpace(outboundOrder.FactoryArea) && outboundOrder.FactoryArea == takeStockOrderDetail.FactoryArea) .WhereIF(!string.IsNullOrWhiteSpace(takeStockOrderDetail.WarehouseCode), detail => !string.IsNullOrWhiteSpace(detail.WarehouseCode) && detail.WarehouseCode == takeStockOrderDetail.WarehouseCode) .Where(detail => string.IsNullOrWhiteSpace(detail.BatchNo)|| detail.BatchNo == takeStockOrderDetail.BatchNo) .Where(detail => string.IsNullOrWhiteSpace(detail.SupplyCode) || detail.SupplyCode == takeStockOrderDetail.SupplyCode) .ToList(); if (matchedDetails.Any()) { outboundOrderDetails.AddRange(matchedDetails); } } return WebResponseContent.Instance.OK("成功", data: outboundOrderDetails); } } } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } public WebResponseContent DocumentReconciliation(string barcode) { WebResponseContent webResponseContent = new WebResponseContent(); try { Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x => x.barcode == barcode); if (takeStockOrderDetail == null) { return WebResponseContent.Instance.Error("未找到该盘点差异数据"); } Dt_OutboundOrderDetail outboundOrderDetail = _outboundOrderDetailRepository.QueryFirst(x => x.Remark == takeStockOrderDetail.TakeStockNo && (x.OrderQuantity-x.LockQuantity-x.MoveQty)>0); if (outboundOrderDetail == null) { return WebResponseContent.Instance.Error("未找到选择的杂发平账单据"); } if(outboundOrderDetail.MaterielCode != takeStockOrderDetail.MaterielCode) { return WebResponseContent.Instance.Error("与杂发平账单据物料编码不匹配"); } if (!string.IsNullOrWhiteSpace(outboundOrderDetail.BatchNo)&& outboundOrderDetail.BatchNo != takeStockOrderDetail.BatchNo) { return WebResponseContent.Instance.Error("与杂发平账单据物料批次不匹配"); } if (!string.IsNullOrWhiteSpace(outboundOrderDetail.SupplyCode) && outboundOrderDetail.SupplyCode != takeStockOrderDetail.SupplyCode) { return WebResponseContent.Instance.Error("与杂发平账单据供应商不匹配"); } Dt_OutboundOrder outboundOrder = _outboundOrderRepository.Db.Queryable().Where(x => x.Id == outboundOrderDetail.OrderId).Includes(x => x.Details).First(); takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.杂收杂发平账处理.ObjToInt(); OutboundCompleteRequestDTO request = new OutboundCompleteRequestDTO() { OrderNo = outboundOrder.OrderNo, PalletCode = takeStockOrderDetail.TakePalletCode, Barcode = takeStockOrderDetail.barcode, Operator = App.User.UserName }; webResponseContent = CompleteOutboundWithBarcode(request,outboundOrderDetail.Id); takeStockOrderDetail.DifferenceQty = 0; _takeStockOrderDetail.UpdateData(takeStockOrderDetail); return WebResponseContent.Instance.OK(data: webResponseContent); } catch(Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } public WebResponseContent CompleteOutboundWithBarcode(OutboundCompleteRequestDTO request ,int orderDetailId) { WebResponseContent content = WebResponseContent.Instance; OutboundCompleteResponseDTO response = new(); try { // 1. 根据托盘号查找库存信息 Dt_StockInfo stockInfo = _stockInfoRepository.QueryFirst(x => x.PalletCode == request.PalletCode); if (stockInfo == null) { response.Success = false; response.Message = $"托盘号 {request.PalletCode} 对应的库存不存在"; return WebResponseContent.Instance.Error($"托盘号 {request.PalletCode} 对应的库存不存在"); } // 2. 根据条码查找库存明细 Dt_StockInfoDetail stockDetail = _stockInfoDetailRepository.QueryFirst(x => x.Barcode == request.Barcode); if (stockDetail == null) { response.Success = false; response.Message = $"条码 {request.Barcode} 对应的库存明细不存在"; return WebResponseContent.Instance.Error($"条码 {request.Barcode} 对应的库存明细不存在"); } // 4. 查找出库单信息 Dt_OutboundOrder outboundOrder = _outboundOrderRepository.QueryFirst(o => o.OrderNo == request.OrderNo); if (outboundOrder == null) { response.Success = false; response.Message = $"出库单 {request.OrderNo} 不存在"; return WebResponseContent.Instance.Error($"出库单 {request.OrderNo} 不存在"); } Dt_OutboundOrderDetail outboundOrderDetail = _outboundOrderDetailRepository.QueryFirst(x => x.Id == orderDetailId); if (outboundOrderDetail == null) { return WebResponseContent.Instance.Error("未找到出库单明细"); } // 实际出库量 decimal actualOutboundQuantity = outboundOrderDetail.OrderQuantity-outboundOrderDetail.LockQuantity-outboundOrderDetail.MoveQty; // 8. 判断是否需要拆包(当出库数量小于库存数量时需要拆包) bool isUnpacked = actualOutboundQuantity < stockDetail.StockQuantity; List returnDTOs = new List(); string newBarcode = string.Empty; // 9. 开启事务 _unitOfWorkManage.BeginTran(); try { decimal beforeQuantity = stockDetail.StockQuantity; // 原始库存量 Dt_AllocateMaterialInfo allocateMaterialInfo = new Dt_AllocateMaterialInfo(); // 根据是否拆包执行不同的操作 if (isUnpacked) { (string NewBarcode, List MaterialCodeReturnDTOs) result = _outboundService.PerformUnpackOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, 0, outboundOrder.Id, outboundOrder.OrderNo); returnDTOs = result.MaterialCodeReturnDTOs; newBarcode = result.NewBarcode; MaterialCodeReturnDTO returnDTO = returnDTOs.First(x => x.Barcode == newBarcode); if (outboundOrder.OrderType != 0) { allocateMaterialInfo = new Dt_AllocateMaterialInfo() { Barcode = returnDTO.Barcode, BatchNo = returnDTO.BatchNo, FactoryArea = returnDTO.FactoryArea, MaterialCode = returnDTO.MaterialCode, MaterialName = returnDTO.MaterialName, OrderId = outboundOrder.Id, OrderNo = outboundOrder.OrderNo, Quantity = returnDTO.Quantity, SupplyCode = returnDTO.SuplierCode, Unit = stockDetail.Unit }; } } else { _outboundService.PerformFullOutboundOperation(stockDetail, stockInfo, actualOutboundQuantity, request, beforeQuantity, 0); if (outboundOrder.OrderType != 0) { allocateMaterialInfo = new Dt_AllocateMaterialInfo() { Barcode = stockDetail.Barcode, BatchNo = stockDetail.BatchNo, FactoryArea = stockDetail.FactoryArea, MaterialCode = stockDetail.MaterielCode, MaterialName = stockDetail.MaterielName, OrderId = outboundOrder.Id, OrderNo = outboundOrder.OrderNo, Quantity = stockDetail.StockQuantity, SupplyCode = stockDetail.SupplyCode, Unit = stockDetail.Unit }; } } List outboundOrderDetails = new List(); outboundOrderDetails.Add(outboundOrderDetail); decimal allocatedQuantity = actualOutboundQuantity; List updateDetails = new(); foreach (var item in outboundOrderDetails) { if (allocatedQuantity <= 0) break; decimal barcodeQuantity = allocatedQuantity; if (item.LockQuantity - item.OverOutQuantity >= allocatedQuantity) { item.OverOutQuantity += allocatedQuantity; item.CurrentDeliveryQty += allocatedQuantity; allocatedQuantity = 0; } else { barcodeQuantity = allocatedQuantity; allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity); item.OverOutQuantity = allocatedQuantity; item.LockQuantity = allocatedQuantity; item.CurrentDeliveryQty = allocatedQuantity; } updateDetails.Add(item); List barcodesList = new List(); Barcodes barcodes = new Barcodes { Barcode = isUnpacked ? newBarcode : stockDetail?.Barcode, Qty = barcodeQuantity, SupplyCode = stockDetail?.SupplyCode ?? "", BatchNo = stockDetail?.BatchNo ?? "", Unit = stockDetail?.Unit ?? "" }; if (!string.IsNullOrEmpty(item.ReturnJsonData)) { barcodesList = JsonConvert.DeserializeObject>(item.ReturnJsonData) ?? new List(); } barcodesList.Add(barcodes); JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; item.ReturnJsonData = JsonConvert.SerializeObject(barcodesList, settings); } // 更新出库单明细的已出库数量 _outboundOrderDetailRepository.UpdateData(updateDetails); // 更新锁定记录的累计已出库数量(需要更新该托盘该物料的所有相关记录) //UpdateLockInfoAllocatedQuantity(stockInfo.Id, stockDetail.MaterielCode, stockDetail.BatchNo, actualOutboundQuantity); // 提交事务 _unitOfWorkManage.CommitTran(); // 构建返回信息 ScannedStockDetailDTO scannedDetail = new ScannedStockDetailDTO { StockDetailId = stockDetail.Id, PalletCode = stockInfo.PalletCode, MaterielCode = stockDetail.MaterielCode, MaterielName = stockDetail.MaterielName, BatchNo = stockDetail.BatchNo, OriginalBarcode = request.Barcode, BeforeQuantity = beforeQuantity, AfterQuantity = isUnpacked ? actualOutboundQuantity : 0, ChangeQuantity = -actualOutboundQuantity, IsUnpacked = isUnpacked, MaterialCodes = returnDTOs }; response.Success = true; response.Message = "出库完成"; response.ScannedDetail = scannedDetail; response.UpdatedDetails = updateDetails; if (!string.IsNullOrEmpty(newBarcode)) { // 物料新条码回传 _feedbackMesService.BarcodeFeedback(newBarcode); } List details = _outboundOrderDetailRepository.QueryData(x => x.OrderId == outboundOrder.Id); if(details.All(x => x.OverOutQuantity >= x.OrderQuantity - x.MoveQty)) { _feedbackMesService.OutboundFeedback(outboundOrder.OrderNo); outboundOrder.OrderStatus = OutOrderStatusEnum.出库完成.ObjToInt(); _outboundOrderRepository.UpdateData(outboundOrder); } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); response.Success = false; response.Message = $"出库处理失败:{ex.Message}"; return WebResponseContent.Instance.Error(ex.Message); } content = WebResponseContent.Instance.OK(data: response); } catch (Exception ex) { content = WebResponseContent.Instance.Error("处理出库完成失败:" + ex.Message); } return content; } public WebResponseContent StockTakeGroupPallet(string barcode, string boxNo) { throw new NotImplementedException(); } } }