647556386
3 天以前 3460ffdc967b65ea67c959212c2505a19008401e
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs
@@ -34,6 +34,10 @@
using WIDESEA_BasicService.MESOperation;
using WIDESEA_Core.Util;
using WIDESEA_DTO.Allocate;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using WIDESEA_IRecordService;
using Microsoft.AspNetCore.Http;
using MailKit.Net.Smtp;
namespace WIDESEA_OutboundService
{
@@ -70,6 +74,8 @@
        private readonly IFeedbackMesService _feedbackMesService;
        private readonly HttpClientHelper _httpClientHelper;
        private readonly IRepository<Dt_MesReturnRecord> _mesReturnRecord;
        private readonly IStockQuantityChangeRecordService _stockQuantityChangeRecordService;
        private readonly IInboundOrderService _inboundOrderService;
        private Dictionary<string, string> stations = new Dictionary<string, string>
        {
@@ -88,7 +94,7 @@
        public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService,
            IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService,
            IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService, IOutboundOrderService outboundOrderService,
            IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService, IAllocateService allocateService, IRepository<Dt_InboundOrder> inboundOrderRepository, IInboundOrderDetailService inboundOrderDetailService, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IReCheckOrderService reCheckOrderService, ITask_HtyService task_HtyService, IRepository<Dt_InterfaceLog> interfaceLog, IInboundService inboundService, IFeedbackMesService feedbackMesService, HttpClientHelper httpClientHelper, IRepository<Dt_MesReturnRecord> mesReturnRecord) : base(BaseDal)
            IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService, IAllocateService allocateService, IRepository<Dt_InboundOrder> inboundOrderRepository, IInboundOrderDetailService inboundOrderDetailService, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IReCheckOrderService reCheckOrderService, ITask_HtyService task_HtyService, IRepository<Dt_InterfaceLog> interfaceLog, IInboundService inboundService, IFeedbackMesService feedbackMesService, HttpClientHelper httpClientHelper, IRepository<Dt_MesReturnRecord> mesReturnRecord,IStockQuantityChangeRecordService stockQuantityChangeRecordService,IInboundOrderService inboundOrderService) : base(BaseDal)
        {
            _unitOfWorkManage = unitOfWorkManage;
            _stockInfoService = stockInfoService;
@@ -115,6 +121,8 @@
            _feedbackMesService = feedbackMesService;
            _httpClientHelper = httpClientHelper;
            _mesReturnRecord = mesReturnRecord;
            _stockQuantityChangeRecordService = stockQuantityChangeRecordService;
            _inboundOrderService = inboundOrderService;
        }
@@ -2316,6 +2324,10 @@
            {
                return WebResponseContent.Instance.Error("未找到满足出库条件的出库单");
            }
            if(outboundOrder.IsBatch == 0)
            {
                return WebResponseContent.Instance.Error("该单据不属于分批回传单据,不允许虚拟出入库");
            }
            //先清空单据虚拟出入库数量进行计算
            foreach (var item in outboundOrder.Details)
            {
@@ -2326,248 +2338,374 @@
            return WebResponseContent.Instance.OK("成功");
        }
        public WebResponseContent BarcodeValidate(NoStockOutModel noStockOut)
    public WebResponseContent BarcodeValidate(NoStockOutModel noStockOut)
    {
        try
        {
            try
            Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>()
                .Where(x => x.UpperOrderNo == noStockOut.inOder && x.OrderStatus != InOrderStatusEnum.入库完成.ObjToInt())
                .Includes(x => x.Details)
                .First();
            if (inboundOrder == null)
            {
                Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == noStockOut.inOder && x.OrderStatus != InOrderStatusEnum.入库完成.ObjToInt()).Includes(x => x.Details).First();
                if (inboundOrder == null)
                {
                    return WebResponseContent.Instance.Error($"未找到采购单:{noStockOut.inOder}");
                }
                Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == noStockOut.outOder && x.OrderStatus != OutOrderStatusEnum.出库完成.ObjToInt()).Includes(x => x.Details).First();
                if (outboundOrder == null)
                {
                    return WebResponseContent.Instance.Error($"未找到出库单:{noStockOut.inOder}");
                }
                return WebResponseContent.Instance.Error($"未找到采购单:{noStockOut.inOder}");
            }
                //存储入库单据明细信息
                var detailLists = new List<Dt_InboundOrderDetail>();
            Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>()
                .Where(x => x.UpperOrderNo == noStockOut.outOder && x.OrderStatus != OutOrderStatusEnum.出库完成.ObjToInt())
                .Includes(x => x.Details)
                .First();
            if (outboundOrder == null)
            {
                return WebResponseContent.Instance.Error($"未找到出库单:{noStockOut.outOder}");
            }
                var matchedDetail = inboundOrder.Details.FirstOrDefault(detail =>
                    detail.Barcode == noStockOut.barCode &&
                    detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
            var detailLists = new List<Dt_InboundOrderDetail>();
            var matchedDetail = inboundOrder.Details.FirstOrDefault(detail =>
                detail.Barcode == noStockOut.barCode &&
                detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()&& detail.ReceiptQuantity == 0);
            if (matchedDetail == null)
            {
                matchedDetail = inboundOrder.Details.FirstOrDefault(detail =>
                    detail.OutBoxbarcodes == noStockOut.barCode &&
                    detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt() && detail.ReceiptQuantity == 0);
                if (matchedDetail == null)
                {
                    matchedDetail = inboundOrder.Details.FirstOrDefault(detail =>
                        detail.OutBoxbarcodes == noStockOut.barCode &&
                        detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
                    if (matchedDetail == null)
                    {
                        return WebResponseContent.Instance.Error($"在采购单 {noStockOut.inOder} ä¸­æœªæ‰¾åˆ°æ¡ç ä¸º {noStockOut.barCode} çš„æ˜Žç»†ã€‚");
                    }
                    else
                    {
                        // æ·»åŠ æ‰€æœ‰éžå®ŒæˆçŠ¶æ€çš„æ˜Žç»†æ¡ç 
                        foreach (var detail in inboundOrder.Details)
                        {
                            if (detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt() &&
                                !string.IsNullOrEmpty(detail.Barcode))
                            {
                                detailLists.Add(detail);
                            }
                        }
                    }
                    return WebResponseContent.Instance.Error($"在采购单 {noStockOut.inOder} ä¸­æœªæ‰¾åˆ°æ¡ç ä¸º {noStockOut.barCode} çš„可出库明细。");
                }
                else
                {
                    if (!string.IsNullOrEmpty(noStockOut.barCode))
                    // æ·»åŠ æ‰€æœ‰åŒ¹é…å¤–ç®±ç ä¸”éžå®ŒæˆçŠ¶æ€çš„æ˜Žç»†
                    foreach (var detail in inboundOrder.Details)
                    {
                        detailLists.Add(matchedDetail);
                        if (detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt() &&
                            !string.IsNullOrEmpty(detail.Barcode) &&
                            detail.OutBoxbarcodes == noStockOut.barCode && detail.OrderQuantity > detail.NoStockOutQty)
                        {
                            detailLists.Add(detail);
                        }
                    }
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(noStockOut.barCode))
                {
                    detailLists.Add(matchedDetail);
                }
            }
                if (!detailLists.Any())
                {
                    return WebResponseContent.Instance.Error("该条码已经没有可出库数量");
                }
                var outDetails = new List<Dt_OutboundOrderDetail>();
                // éåŽ†æ¯ä¸ªå…¥åº“æ˜Žç»†
                foreach (var item in detailLists)
                {
                    // é‡ç½®å½“前入库明细的无库存出库数量
                    item.NoStockOutQty = 0;
                    var matchedCode = outboundOrder.Details.FirstOrDefault(detail => detail.MaterielCode == item.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt() && (detail.OrderQuantity-detail.LockQuantity-detail.MoveQty-detail.NoStockOutQty)>0);
                    // å½“前条码需要出库的总数量(入库单剩余可出数量)
                    decimal remainingBarcodeQty = item.OrderQuantity - item.ReceiptQuantity;
                    if (remainingBarcodeQty <= 0)
                    {
                        return WebResponseContent.Instance.Error($"该采购单中的条码{item.Barcode}对应的可出数量为0");
                    }
                    if (matchedCode == null)
                    // ç­›é€‰å‡ºåº“单中符合条件的明细(同物料、非完成、有剩余可出数量)
                    var eligibleOutDetails = outboundOrder.Details.Where(detail =>
                        detail.MaterielCode == item.MaterielCode &&
                        detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt() &&
                        (detail.OrderQuantity - detail.LockQuantity - detail.MoveQty - detail.NoStockOutQty) > 0).ToList();
                    if (!eligibleOutDetails.Any())
                    {
                        return WebResponseContent.Instance.Error($"在出库单的物料编码中未找到与采购单中的{item.MaterielCode} å¯¹åº”的物料。");
                        return WebResponseContent.Instance.Error($"在出库单中未找到物料{item.MaterielCode}的可出库明细");
                    }
                    if (!matchedCode.BatchNo.IsNullOrEmpty() && matchedCode.BatchNo != "")
                    // éåŽ†ç¬¦åˆæ¡ä»¶çš„å‡ºåº“æ˜Žç»†ï¼Œé€è¡Œåˆ†é…æ•°é‡
                    foreach (var outDetail in eligibleOutDetails)
                    {
                        var matcheBatch = outboundOrder.Details.FirstOrDefault(detail => detail.BatchNo == item.BatchNo);
                        if (matcheBatch == null)
                        // è®¡ç®—当前出库行的剩余可出数量
                        decimal rowRemainingQty = outDetail.OrderQuantity - outDetail.LockQuantity - outDetail.MoveQty - outDetail.NoStockOutQty;
                        if (rowRemainingQty <= 0) continue;
                        if (!outDetail.BatchNo.IsNullOrEmpty())
                        {
                            return WebResponseContent.Instance.Error($"在出库单的物料编码中未找到与采购单批次中的{item.BatchNo} å¯¹åº”的物料。");
                        }
                    }
                    if (!matchedCode.SupplyCode.IsNullOrEmpty() && matchedCode.SupplyCode != "")
                    {
                        var matcheBatch = outboundOrder.Details.FirstOrDefault(detail => detail.SupplyCode == item.SupplyCode);
                        if (matcheBatch == null)
                        {
                            return WebResponseContent.Instance.Error($"在出库单的物料编码中未找到与采购单供应商中的{item.SupplyCode} å¯¹åº”的物料。");
                        }
                    }
                    if (!outboundOrder.FactoryArea.IsNullOrEmpty() && outboundOrder.FactoryArea != "" && !inboundOrder.FactoryArea.IsNullOrEmpty() && inboundOrder.FactoryArea != "")
                    {
                        if (inboundOrder.FactoryArea != outboundOrder.FactoryArea)
                        {
                            return WebResponseContent.Instance.Error($"该条码{item.Barcode}对应的单据厂区与出库单据不一致!不允许出库。");
                        }
                    }
                    if(inboundOrder.BusinessType != "11")
                    {
                        if (!matchedCode.WarehouseCode.IsNullOrEmpty() && matchedCode.WarehouseCode != "")
                        {
                            var matcheBatch = outboundOrder.Details.FirstOrDefault(detail => detail.WarehouseCode == item.WarehouseCode);
                            if (matcheBatch == null)
                            if (outDetail.BatchNo != item.BatchNo)
                            {
                                return WebResponseContent.Instance.Error($"仓库不一致!在出库单的物料编码中未找到与采购单仓库中的{item.WarehouseCode} å¯¹åº”的物料。");
                                return WebResponseContent.Instance.Error($"出库单行批次{outDetail.BatchNo}与采购单批次{item.BatchNo}不匹配");
                            }
                        }
                        if (!outDetail.SupplyCode.IsNullOrEmpty())
                        {
                            if (outDetail.SupplyCode != item.SupplyCode)
                            {
                                return WebResponseContent.Instance.Error($"出库单行供应商{outDetail.SupplyCode}与采购单供应商{item.SupplyCode}不匹配");
                            }
                        }
                        if (!string.IsNullOrEmpty(outboundOrder.FactoryArea) && !string.IsNullOrEmpty(inboundOrder.FactoryArea))
                        {
                            if (inboundOrder.FactoryArea != outboundOrder.FactoryArea)
                            {
                                return WebResponseContent.Instance.Error($"该条码{item.Barcode}对应的单据厂区与出库单据不一致!不允许出库。");
                            }
                        }
                        if (inboundOrder.BusinessType != "11" && !outDetail.WarehouseCode.IsNullOrEmpty())
                        {
                            if (outDetail.WarehouseCode != item.WarehouseCode)
                            {
                                return WebResponseContent.Instance.Error($"仓库不一致!出库单行仓库{outDetail.WarehouseCode}与采购单仓库{item.WarehouseCode}不匹配");
                            }
                        }
                        else
                        {
                            item.WarehouseCode = outDetail.WarehouseCode;
                        }
                        // è®¡ç®—本次分配的数量(取剩余条码数量和当前行剩余数量的较小值)
                        decimal assignQty = Math.Min(remainingBarcodeQty, rowRemainingQty);
                        // æ›´æ–°å…¥åº“明细和出库明细的无库存出库数量
                        item.NoStockOutQty += assignQty;
                        outDetail.NoStockOutQty += assignQty;
                        // æ›´æ–°å‰©ä½™éœ€è¦åˆ†é…çš„æ¡ç æ•°é‡
                        remainingBarcodeQty -= assignQty;
                        // è®°å½•已更新的出库明细(去重)
                        if (!outDetails.Contains(outDetail))
                        {
                            outDetails.Add(outDetail);
                        }
                        // éªŒè¯å½“前行是否溢出
                        if ((outDetail.LockQuantity + outDetail.NoStockOutQty + outDetail.MoveQty) > outDetail.OrderQuantity)
                        {
                            return WebResponseContent.Instance.Error($"出库单明细{outDetail.Id}数量溢出,超出数量:{(outDetail.LockQuantity + outDetail.NoStockOutQty + outDetail.MoveQty) - outDetail.OrderQuantity}");
                        }
                        // å¤„理MES参数回传:记录当前条码分配到该行的实际数量
                        List<Barcodes> barcodesList = new List<Barcodes>();
                        Barcodes barcodes = new Barcodes
                        {
                            Barcode = item.Barcode,
                            Qty = assignQty,
                            SupplyCode = item?.SupplyCode ?? "",
                            BatchNo = item?.BatchNo ?? "",
                            Unit = item?.Unit ?? ""
                        };
                        // ååºåˆ—化该行已有的条码记录
                        if (!string.IsNullOrEmpty(outDetail.documentsNO))
                        {
                            try
                            {
                                barcodesList = JsonConvert.DeserializeObject<List<Barcodes>>(outDetail.documentsNO) ?? new List<Barcodes>();
                            }
                            catch (JsonException ex)
                            {
                                return WebResponseContent.Instance.Error($"出库单明细{outDetail.Id}的documentsNO字段格式错误:{ex.Message}");
                            }
                        }
                        // æ·»åŠ æœ¬æ¬¡åˆ†é…çš„è®°å½•
                        barcodesList.Add(barcodes);
                        // åºåˆ—化回存
                        JsonSerializerSettings settings = new JsonSerializerSettings
                        {
                            ContractResolver = new CamelCasePropertyNamesContractResolver()
                        };
                        outDetail.documentsNO = JsonConvert.SerializeObject(barcodesList, settings);
                        // æ¡ç æ•°é‡åˆ†é…å®Œæ¯•,退出当前行循环
                        if (remainingBarcodeQty <= 0)
                        {
                            break;
                        }
                    }
                    //剩余入库数量即虚拟出入库剩余可出数量
                    decimal outQuantity = item.OrderQuantity - item.ReceiptQuantity;
                    if (outQuantity == 0)
                    // æ‰€æœ‰ç¬¦åˆæ¡ä»¶çš„出库行遍历完后,条码数量仍有剩余
                    if (remainingBarcodeQty > 0)
                    {
                        return WebResponseContent.Instance.Error($"该采购单中的条码对应的可出数量为0");
                        return WebResponseContent.Instance.Error($"条码{item.Barcode}需出库数量{item.OrderQuantity - item.ReceiptQuantity},但出库单中物料{item.MaterielCode}剩余可出总量不足,仍剩余{remainingBarcodeQty}数量未分配");
                    }
                    if (matchedCode.OrderQuantity - matchedCode.LockQuantity - matchedCode.MoveQty - matchedCode.NoStockOutQty < outQuantity)
                    {
                        return WebResponseContent.Instance.Error($"该采购单中的条码对应的可出数量超出出库单出库数量{item.OrderQuantity - (matchedCode.OrderQuantity - matchedCode.LockQuantity - matchedCode.MoveQty)},不满足整包出库");
                    }
                    //单据出库锁定数量
                    item.NoStockOutQty += outQuantity;
                    matchedCode.NoStockOutQty += outQuantity;
                    //回传MES参数
                    List<Barcodes> barcodesList = new List<Barcodes>();
                    Barcodes barcodes = new Barcodes
                    {
                        Barcode = item.Barcode,
                        Qty = item.BarcodeQty,
                        SupplyCode = item?.SupplyCode ?? "",
                        BatchNo = item?.BatchNo ?? "",
                        Unit = item?.Unit ?? ""
                    };
                    if (!string.IsNullOrEmpty(matchedCode.documentsNO))
                    {
                        barcodesList = JsonConvert.DeserializeObject<List<Barcodes>>(matchedCode.documentsNO) ?? new List<Barcodes>();
                    }
                    barcodesList.Add(barcodes);
                    JsonSerializerSettings settings = new JsonSerializerSettings
                    {
                        ContractResolver = new CamelCasePropertyNamesContractResolver()
                    };
                    matchedCode.documentsNO = JsonConvert.SerializeObject(barcodesList, settings);
                    if ((matchedCode.LockQuantity + matchedCode.NoStockOutQty+matchedCode.MoveQty) > matchedCode.OrderQuantity)
                    {
                        return WebResponseContent.Instance.Error($"出库单明细数量溢出{matchedCode.OrderQuantity - matchedCode.LockQuantity-matchedCode.NoStockOutQty-matchedCode.MoveQty}");
                    }
                    item.OrderDetailStatus = OrderDetailStatusEnum.Inbounding.ObjToInt();
                    outDetails.Add(matchedCode);
                }
                _unitOfWorkManage.BeginTran();
                _inboundOrderDetailService.UpdateData(detailLists);
                _outboundOrderDetailService.UpdateData(outDetails);
                _unitOfWorkManage.CommitTran();
                return WebResponseContent.Instance.OK("成功",data:detailLists);
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                return WebResponseContent.Instance.Error(ex.Message);
            }
            _inboundOrderDetailService.UpdateData(detailLists);
            _outboundOrderDetailService.UpdateData(outDetails);
            _unitOfWorkManage.CommitTran();
            return WebResponseContent.Instance.OK("成功", data: detailLists);
        }
        public WebResponseContent DeleteBarcode(NoStockOutModel noStockOut)
        catch (Exception ex)
        {
            try
            _unitOfWorkManage.RollbackTran();
            return WebResponseContent.Instance.Error(ex.Message);
        }
    }
    public WebResponseContent DeleteBarcode(NoStockOutModel noStockOut)
    {
        try
        {
            Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>()
                .Where(x => x.UpperOrderNo == noStockOut.inOder && x.OrderStatus != InOrderStatusEnum.入库完成.ObjToInt())
                .Includes(x => x.Details)
                .First();
            if (inboundOrder == null)
            {
                Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == noStockOut.inOder && x.OrderStatus != InOrderStatusEnum.入库完成.ObjToInt()).Includes(x => x.Details).First();
                if (inboundOrder == null)
                {
                    return WebResponseContent.Instance.Error($"未找到采购单:{noStockOut.inOder}");
                }
                var matchedDetail = inboundOrder.Details.FirstOrDefault(detail => detail.Barcode == noStockOut.barCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
                return WebResponseContent.Instance.Error($"未找到采购单:{noStockOut.inOder}");
            }
                if (matchedDetail == null)
                {
                    return WebResponseContent.Instance.Error($"在采购单 {noStockOut.inOder} ä¸­æœªæ‰¾åˆ°æ¡ç ä¸º {noStockOut.barCode} çš„æ˜Žç»†ã€‚");
                }
                matchedDetail.NoStockOutQty = 0;
            var matchedDetail = inboundOrder.Details.FirstOrDefault(detail =>
                detail.Barcode == noStockOut.barCode &&
                detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
                if (matchedDetail.ReceiptQuantity == 0 && matchedDetail.OverInQuantity == 0)
                {
                    matchedDetail.OrderDetailStatus = OrderDetailStatusEnum.New.ObjToInt();
                }
            if (matchedDetail == null)
            {
                return WebResponseContent.Instance.Error($"在采购单 {noStockOut.inOder} ä¸­æœªæ‰¾åˆ°æ¡ç ä¸º {noStockOut.barCode} çš„æ˜Žç»†ã€‚");
            }
                Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == noStockOut.outOder && x.OrderStatus != OutOrderStatusEnum.出库完成.ObjToInt()).Includes(x => x.Details).First();
                if (outboundOrder == null)
                {
                    return WebResponseContent.Instance.Error($"未找到出库单:{noStockOut.inOder}");
                }
            // é‡ç½®å…¥åº“明细的无库存出库数量
            decimal revokedTotalQty = matchedDetail.NoStockOutQty; // è®°å½•需要撤销的总数量(入库单中已分配的数量)
            matchedDetail.NoStockOutQty = 0;
            if(inboundOrder.BusinessType == "11")
            {
                matchedDetail.WarehouseCode ="";
            }
                // æ’¤é”€å›žä¼ MES参数
            // é‡ç½®å…¥åº“明细状态
            if (matchedDetail.ReceiptQuantity == 0 && matchedDetail.OverInQuantity == 0)
            {
                matchedDetail.OrderDetailStatus = OrderDetailStatusEnum.New.ObjToInt();
            }
            Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>()
                .Where(x => x.UpperOrderNo == noStockOut.outOder && x.OrderStatus != OutOrderStatusEnum.出库完成.ObjToInt())
                .Includes(x => x.Details)
                .First();
            if (outboundOrder == null)
            {
                return WebResponseContent.Instance.Error($"未找到出库单:{noStockOut.outOder}");
            }
            // æ‰¾åˆ°æ‰€æœ‰å…³è”该条码的出库明细行
            // åŒç‰©æ–™ã€éžå®ŒæˆçŠ¶æ€ã€documentsNO包含该条码
            var matchedCodeList = outboundOrder.Details.Where(detail =>
                detail.MaterielCode == matchedDetail.MaterielCode && // ç¡®ä¿ç‰©æ–™åŒ¹é…
                detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt() &&
                !string.IsNullOrEmpty(detail.documentsNO) &&
                detail.documentsNO.Contains(noStockOut.barCode) // åŒ…含当前条码
            ).ToList();
            if (!matchedCodeList.Any())
            {
                return WebResponseContent.Instance.Error($"在出库单中未找到关联条码{noStockOut.barCode}的物料{matchedDetail.MaterielCode}明细。");
            }
            //逐行处理出库明细的撤销逻辑
            decimal remainingRevokeQty = revokedTotalQty; // å‰©ä½™éœ€è¦æ’¤é”€çš„æ•°é‡
            foreach (var matchedCode in matchedCodeList)
            {
                if (remainingRevokeQty <= 0) break; // æ‰€æœ‰æ•°é‡å·²æ’¤é”€ï¼Œé€€å‡ºå¾ªçޝ
                // å¤„理MES参数撤销
                List<Barcodes> barcodesList = new List<Barcodes>();
                Barcodes barcodes = new Barcodes
                {
                    Barcode = matchedDetail.Barcode,
                    Qty = matchedDetail.BarcodeQty,
                    SupplyCode = matchedDetail?.SupplyCode ?? "",
                    BatchNo = matchedDetail?.BatchNo ?? "",
                    Unit = matchedDetail?.Unit ?? ""
                };
                var matchedCode = outboundOrder.Details.FirstOrDefault(detail =>
                    detail.documentsNO.Contains(barcodes.Barcode) &&
                    detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()
                );
                if (matchedCode == null)
                {
                    return WebResponseContent.Instance.Error($"在出库单的物料编码中未找到与采购单中的{matchedDetail.MaterielCode} å¯¹åº”的物料。");
                }
                if (!string.IsNullOrEmpty(matchedCode.documentsNO))
                {
                    barcodesList = JsonConvert.DeserializeObject<List<Barcodes>>(matchedCode.documentsNO) ?? new List<Barcodes>();
                    try
                    {
                        barcodesList = JsonConvert.DeserializeObject<List<Barcodes>>(matchedCode.documentsNO) ?? new List<Barcodes>();
                    }
                    catch (JsonException ex)
                    {
                        return WebResponseContent.Instance.Error($"出库单明细{matchedCode.Id}的documentsNO字段格式错误:{ex.Message}");
                    }
                }
                barcodesList.RemoveAll(b =>
                    string.Equals(b.Barcode, barcodes.Barcode, StringComparison.OrdinalIgnoreCase)
                );
                // ç­›é€‰å‡ºå½“前条码的所有记录
                var barcodeRecords = barcodesList.Where(b =>
                    string.Equals(b.Barcode, noStockOut.barCode, StringComparison.OrdinalIgnoreCase)).ToList();
                if (!barcodeRecords.Any()) continue;
                // è®¡ç®—该行需要撤销的数量(累加该条码在该行的所有分配数量)
                decimal rowRevokeQty = barcodeRecords.Sum(b => b.Qty);
                // å®žé™…撤销数量:取该行可撤销数量和剩余需要撤销数量的较小值
                decimal actualRevokeQty = Math.Min(rowRevokeQty, remainingRevokeQty);
                // ç§»é™¤è¯¥è¡Œä¸­è¯¥æ¡ç çš„记录(或部分记录,若剩余撤销数量不足)
                if (actualRevokeQty < rowRevokeQty)
                {
                    // å‰©ä½™æ’¤é”€æ•°é‡ä¸è¶³ï¼Œåªç§»é™¤éƒ¨åˆ†è®°å½•(按数量扣减)
                    decimal tempQty = actualRevokeQty;
                    var removeList = new List<Barcodes>();
                    foreach (var record in barcodeRecords)
                    {
                        if (tempQty <= 0) break;
                        if (record.Qty <= tempQty)
                        {
                            removeList.Add(record);
                            tempQty -= record.Qty;
                        }
                        else
                        {
                            // è®°å½•数量拆分,扣减部分数量
                            record.Qty -= tempQty;
                            tempQty = 0;
                        }
                    }
                    barcodesList.RemoveAll(b => removeList.Contains(b));
                }
                else
                {
                    // ç§»é™¤è¯¥è¡Œä¸­è¯¥æ¡ç çš„æ‰€æœ‰è®°å½•
                    barcodesList.RemoveAll(b =>
                        string.Equals(b.Barcode, noStockOut.barCode, StringComparison.OrdinalIgnoreCase));
                }
                //重新序列化MES参数
                JsonSerializerSettings settings = new JsonSerializerSettings
                {
                    ContractResolver = new CamelCasePropertyNamesContractResolver()
                };
                matchedCode.documentsNO = JsonConvert.SerializeObject(barcodesList, settings);
                matchedCode.NoStockOutQty -= matchedDetail.OrderQuantity;
                //扣减出库明细的无库存出库数量
                matchedCode.NoStockOutQty = Math.Max(0, matchedCode.NoStockOutQty - actualRevokeQty);
                remainingRevokeQty -= actualRevokeQty;
                //重置出库明细状态
                if (matchedCode.LockQuantity == 0 && matchedCode.OverOutQuantity == 0)
                {
                    matchedCode.OrderDetailStatus = OrderDetailStatusEnum.New.ObjToInt();
                }
                _unitOfWorkManage.BeginTran();
                _inboundOrderDetailService.UpdateData(matchedDetail);
                _outboundOrderDetailService.UpdateData(matchedCode);
                _unitOfWorkManage.CommitTran();
                return WebResponseContent.Instance.OK();
            }
            catch (Exception ex)
            //若仍有未撤销的数量,说明数据不一致
            if (remainingRevokeQty > 0)
            {
                _unitOfWorkManage.RollbackTran();
                return WebResponseContent.Instance.Error(ex.Message);
                return WebResponseContent.Instance.Error($"撤销条码{noStockOut.barCode}时,出库单中可撤销数量不足,仍有{remainingRevokeQty}数量未撤销");
            }
        }
        public async Task<WebResponseContent> NoStockOutSubmit(NoStockOutSubmit noStockOutSubmit)
            _unitOfWorkManage.BeginTran();
            _inboundOrderDetailService.UpdateData(matchedDetail);
            _outboundOrderDetailService.UpdateData(matchedCodeList);
            _unitOfWorkManage.CommitTran();
            return WebResponseContent.Instance.OK("条码撤销成功", data: new { RevokedQty = revokedTotalQty });
        }
        catch (Exception ex)
        {
            _unitOfWorkManage.RollbackTran();
            return WebResponseContent.Instance.Error(ex.Message);
        }
    }
    public async Task<WebResponseContent> NoStockOutSubmit(NoStockOutSubmit noStockOutSubmit)
        {
            try
            {
@@ -2585,13 +2723,14 @@
                Dictionary<int, Dt_InboundOrder> updateInboundOrders = new Dictionary<int, Dt_InboundOrder>();
                List<Dt_StockQuantityChangeRecord> changeRecords = new List<Dt_StockQuantityChangeRecord>();
                _unitOfWorkManage.BeginTran();
                List<Dt_InboundOrderDetail> allInboundDetails = _inboundOrderDetailService.Db
                    .Queryable<Dt_InboundOrderDetail>()
                    .Where(detail => noStockOutSubmit.BarCodeSubmit.Contains(detail.Barcode)
                        && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt())
                    .ToList();
                .Queryable<Dt_InboundOrderDetail>()
                .Where(detail => noStockOutSubmit.BarCodeSubmit.Contains(detail.Barcode)
                    && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt())
                .ToList();
                var detailGroupByOrderId = allInboundDetails.GroupBy(d => d.OrderId).ToList();
                foreach (var group in detailGroupByOrderId)
@@ -2600,8 +2739,24 @@
                    List<Dt_InboundOrderDetail> groupDetails = group.ToList();
                    List<string> groupBarCodes = groupDetails.Select(d => d.Barcode).ToList();
                    orderIdBarCodeDict[orderId] = groupBarCodes;
                    Dt_InboundOrder currentInboundOrder = null;
                    if (!updateInboundOrders.TryGetValue(orderId, out currentInboundOrder))
                    {
                        currentInboundOrder = _inboundOrderRepository.Db
                            .Queryable<Dt_InboundOrder>()
                            .Where(x => x.Id == orderId)
                            .Includes(x => x.Details)
                            .First();
                        if (currentInboundOrder == null)
                        {
                            _unitOfWorkManage.RollbackTran();
                            return WebResponseContent.Instance.Error($"未找到入库单ID为 {orderId} çš„单据");
                        }
                        updateInboundOrders[orderId] = currentInboundOrder;
                    }
                    foreach (var detail in groupDetails)
                    {
@@ -2613,53 +2768,49 @@
                            detail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt();
                        }
                        updateInboundDetails.Add(detail);
                    }
                    if (!updateInboundOrders.ContainsKey(orderId))
                    {
                        Dt_InboundOrder inboundOrder = _inboundOrderRepository.Db
                            .Queryable<Dt_InboundOrder>()
                            .Where(x => x.Id == orderId)
                            .Includes(x => x.Details)
                            .First();
                        if (inboundOrder == null)
                        //添加库存变动记录
                        Dt_StockQuantityChangeRecord changeRecord = new Dt_StockQuantityChangeRecord
                        {
                            _unitOfWorkManage.RollbackTran();
                            return WebResponseContent.Instance.Error($"未找到入库单ID为 {orderId} çš„单据");
                        }
                        // åˆ¤æ–­æ•´å•是否全部完成
                        int totalDetailCount = inboundOrder.Details.Count();
                        int beforeDetailCount = inboundOrder.Details.Where(x => x.OrderId == orderId && x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt())
                            .Count();
                        int finishedDetailCount = updateInboundDetails
                            .Where(x => x.OrderId == orderId && x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt())
                            .Count();
                        inboundOrder.OrderStatus = totalDetailCount == finishedDetailCount+beforeDetailCount
                            ? InOrderStatusEnum.入库完成.ObjToInt()
                            : InOrderStatusEnum.入库中.ObjToInt();
                        updateInboundOrders[orderId] = inboundOrder;
                            StockDetailId = detail.Id,
                            PalleCode = DateTime.Now.ToString(),
                            MaterielCode = detail.MaterielCode,
                            MaterielName = detail.MaterielName ?? "",
                            BatchNo = detail.BatchNo ?? "",
                            OriginalSerilNumber = detail.Barcode,
                            NewSerilNumber = "",
                            OrderNo = currentInboundOrder.InboundOrderNo,
                            TaskNum = 0,
                            ChangeType = (int)StockChangeTypeEnum.Inbound,
                            ChangeQuantity = detail.NoStockOutQty,
                            BeforeQuantity = detail.OverInQuantity - detail.NoStockOutQty,
                            AfterQuantity = detail.OverInQuantity,
                            SupplyCode = detail.SupplyCode ?? "",
                            WarehouseCode = detail.WarehouseCode ?? "",
                            Remark = $"虚拟入库"
                        };
                        changeRecords.Add(changeRecord);
                    }
                    var inboundOrder = updateInboundOrders[orderId];
                    int totalDetailCount = inboundOrder.Details.Count;
                    int finishedDetailCount = inboundOrder.Details.Count(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt())
                                             + groupDetails.Count(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt());
                    inboundOrder.OrderStatus = totalDetailCount == finishedDetailCount
                        ? InOrderStatusEnum.入库完成.ObjToInt()
                        : InOrderStatusEnum.入库中.ObjToInt();
                }
                // 6. æ‰¹é‡æ›´æ–°æ˜Žç»†å’Œä¸»å•(批量操作提升性能)
                if (updateInboundDetails.Any())
                {
                    foreach (var detail in updateInboundDetails)
                    {
                        _inboundOrderDetailService.UpdateData(detail);
                    }
                    _inboundOrderDetailService.Db.Updateable(updateInboundDetails).ExecuteCommand();
                }
                if (updateInboundOrders.Any())
                {
                    foreach (var order in updateInboundOrders.Values)
                    {
                        _inboundOrderRepository.UpdateData(order);
                    }
                    // æ‰¹é‡æ›´æ–°å…¥åº“主单
                    _inboundOrderService.Db.Updateable(updateInboundOrders.Values.ToList()).ExecuteCommand();
                }
                // 7. å¾ªçŽ¯åˆ†ç»„ç»“æžœï¼Œè°ƒç”¨MES回传方法(按入库单分组回传)
@@ -2669,26 +2820,26 @@
                    List<string> barCodeList = kvp.Value;
                    //入库回传MES
                    NoStockOutBatchInOrderFeedbackToMes(orderId, barCodeList);
                }
                //只对出库条码的出库单明细进行计算回传
                List<Dt_OutboundOrderDetail> outboundOrderDetail = outboundOrder.Details
    .Where(x => !string.IsNullOrWhiteSpace(x.documentsNO)
        && noStockOutSubmit.BarCodeSubmit.Any(barcode =>
            x.documentsNO.IndexOf(barcode, StringComparison.OrdinalIgnoreCase) >= 0))
    .ToList();
                .Where(x => !string.IsNullOrWhiteSpace(x.documentsNO)
                    && noStockOutSubmit.BarCodeSubmit.Any(barcode =>
                        x.documentsNO.IndexOf(barcode, StringComparison.OrdinalIgnoreCase) >= 0))
                .ToList();
                foreach (var item in outboundOrderDetail)
                {
                    item.LockQuantity = item.NoStockOutQty;
                    item.OverOutQuantity = item.NoStockOutQty;
                    item.LockQuantity += item.NoStockOutQty;
                    item.OverOutQuantity += item.NoStockOutQty;
                    item.CurrentDeliveryQty += item.NoStockOutQty;
                    //添加回传MES参数
                    List<Barcodes> barcodesList = new List<Barcodes>();
                    List<Barcodes> documentsNOList = new List<Barcodes>();
                    if (!string.IsNullOrEmpty(item.ReturnJsonData))
                    {
                        barcodesList = JsonConvert.DeserializeObject<List<Barcodes>>(item.documentsNO) ?? new List<Barcodes>();
                        barcodesList = JsonConvert.DeserializeObject<List<Barcodes>>(item.ReturnJsonData) ?? new List<Barcodes>();
                    }
                    if (!string.IsNullOrEmpty(item.documentsNO) && item.documentsNO!="")
                    {
@@ -2703,18 +2854,47 @@
                        ContractResolver = new CamelCasePropertyNamesContractResolver()
                    };
                    item.ReturnJsonData = JsonConvert.SerializeObject(barcodesList, settings);
                    //添加库存变动记录
                    Dt_StockQuantityChangeRecord changeRecord = new Dt_StockQuantityChangeRecord
                    {
                        StockDetailId = item.Id,
                        PalleCode = DateTime.Now.ToString(),
                        MaterielCode = item.MaterielCode,
                        MaterielName = item.MaterielName ?? "",
                        BatchNo = item.BatchNo ?? "",
                        OriginalSerilNumber = item.ReturnJsonData,
                        NewSerilNumber = "",
                        OrderNo = outboundOrder.OrderNo,
                        TaskNum = 0,
                        ChangeType = (int)StockChangeTypeEnum.Inbound,
                        ChangeQuantity = -item.NoStockOutQty,
                        BeforeQuantity = item.OrderQuantity,
                        AfterQuantity = item.OrderQuantity - item.OverOutQuantity,
                        SupplyCode = item.SupplyCode ?? "",
                        WarehouseCode = item.WarehouseCode ?? "",
                        Remark = $"虚拟出库"
                    };
                    changeRecords.Add(changeRecord);
                    outboundOrderDetails.Add(item);
                }
                _outboundOrderDetailService.UpdateData(outboundOrderDetails);
                //批量添加库存变动记录
                if (changeRecords.Any())
                {
                    _stockQuantityChangeRecordService.Db.Insertable(changeRecords).ExecuteCommand();
                }
                // æ£€æŸ¥å‡ºåº“单是否完成
                if (CheckOutboundOrderCompleted(outboundOrder.OrderNo))
                {
                    outboundOrder.OrderStatus = OutOrderStatusEnum.出库完成.ObjToInt();
                    _outboundOrderService.UpdateData(outboundOrder);
                }
                else
                {
                    outboundOrder.OrderStatus = OutOrderStatusEnum.出库中.ObjToInt();
                }
                _outboundOrderService.UpdateData(outboundOrder);
                _unitOfWorkManage.CommitTran();
                //出库回传MES
                _feedbackMesService.OutboundFeedback(outboundOrder.OrderNo);
@@ -2774,7 +2954,7 @@
                        BusinessType = "3",
                        FactoryArea = inboundOrder.FactoryArea,
                        OperationType = 1,
                        Operator = inboundOrder.Operator,
                        Operator = App.User.UserName,
                        OrderNo = inboundOrder.UpperOrderNo,
                        fromWarehouse = allocate?.FromWarehouse ?? "",
                        toWarehouse = allocate?.ToWarehouse ?? "",
@@ -2788,13 +2968,45 @@
                    var response = NoStockOutresponseModel(inboundOrder, 3, null, allocatefeedmodel);
                    if (response != null && response.IsSuccess)
                    if (response != null && response.IsSuccess && response.Data.Code == "200")
                    {
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 });
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
                            .Where(it => it.OrderId == inboundOrder.Id && barCodeList.Contains(it.Barcode)).ExecuteCommand();
                        if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt())
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        else if (inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt())
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 3 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        else
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 0 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                    }
                    else
                    {
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 });
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
                            .Where(it => it.OrderId == inboundOrder.Id && barCodeList.Contains(it.Barcode)).ExecuteCommand();
                        if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt())
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        else if (inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt())
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 4 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        else
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 0 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        return content.Error("回传MES失败");
                    }
                }
@@ -2807,7 +3019,7 @@
                        business_type = inboundOrder.BusinessType,
                        factoryArea = inboundOrder.FactoryArea,
                        operationType = 1,
                        Operator = inboundOrder.Operator,
                        Operator = App.User.UserName,
                        orderNo = inboundOrder.UpperOrderNo,
                        status = inboundOrder.OrderStatus,
                        details = NoStockOutFeedbackInboundDetailsModelDto(detail)
@@ -2819,13 +3031,44 @@
                    }
                    var response = NoStockOutresponseModel(inboundOrder, 3, feedmodel);
                    if (response != null && response.IsSuccess)
                    if (response != null && response.IsSuccess && response.Data.Code == "200")
                    {
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 });
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
                            .Where(it => it.OrderId == inboundOrder.Id && barCodeList.Contains(it.Barcode)).ExecuteCommand();
                        if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt())
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        else if (inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt())
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 3 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        else
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 0 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                    }
                    else
                    {
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 });
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 }).Where(it => it.OrderId == inboundOrder.Id && barCodeList.Contains(it.Barcode)).ExecuteCommand();
                        if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt())
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        else if (inboundOrder.OrderStatus == InOrderStatusEnum.入库中.ObjToInt())
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 4 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        else
                        {
                            _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 0 })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                        }
                        return content.Error("回传MES失败");
                    }
                }
@@ -2859,7 +3102,7 @@
               }).ToList();
            return groupedData;
        }
        public List<FeedbackInboundDetailsModel> NoStockOutFeedbackInboundDetailsModelDto(List<Dt_InboundOrderDetail> inboundOrderDetails)
        public List<FeedbackInboundDetailsModel> NoStockOutFeedbackInboundDetailsModelDto(List<Dt_InboundOrderDetail> inboundOrderDetails )
        {
            var groupedData = inboundOrderDetails.GroupBy(item => new { item.MaterielCode, item.lineNo, item.BarcodeUnit, item.WarehouseCode })
               .Select(group => new FeedbackInboundDetailsModel