1
647556386
2026-02-06 28e67084df6e36f7b3ac3b914d97fa51acb21f8f
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundService.cs
@@ -22,6 +22,7 @@
using WIDESEA_DTO.Base;
using WIDESEA_DTO.Basic;
using WIDESEA_DTO.CalcOut;
using WIDESEA_DTO.Outbound;
using WIDESEA_DTO.ReturnMES;
using WIDESEA_IBasicService;
using WIDESEA_IOutboundService;
@@ -62,6 +63,8 @@
        private readonly IESSApiService _eSSApiService;
        private readonly IRepository<Dt_AllocateOrder> _allocateOrderRepository;
        private readonly IRepository<Dt_AllocateMaterialInfo> _allocateMaterialInfoRepository;
        public readonly IRepository<Dt_InboundOrderDetail> _inboundOrderDetailRepository;
        public readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
        private Dictionary<string, string> stations = new Dictionary<string, string>
        {
@@ -75,7 +78,7 @@
            {"3-1","3-5" },
        };
        public OutboundService(IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_OutboundOrderDetail> detailRepository, IRepository<Dt_OutboundOrder> outboundRepository, IRepository<Dt_OutStockLockInfo> outboundLockInfoRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_StockQuantityChangeRecord> stockChangeRepository, IRepository<Dt_StockInfoDetail_Hty> stockDetailHistoryRepository, IBasicService basicService, IOutboundOrderDetailService outboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutStockLockInfoService outboundStockLockInfoService, IFeedbackMesService feedbackMesService, IRepository<Dt_Task> taskRepository, ILocationInfoService locationInfoService, IESSApiService eSSApiService, IRepository<Dt_AllocateOrder> allocateOrderRepository, IRepository<Dt_AllocateMaterialInfo> allocateMaterialInfoRepository)
        public OutboundService(IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_OutboundOrderDetail> detailRepository, IRepository<Dt_OutboundOrder> outboundRepository, IRepository<Dt_OutStockLockInfo> outboundLockInfoRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_StockQuantityChangeRecord> stockChangeRepository, IRepository<Dt_StockInfoDetail_Hty> stockDetailHistoryRepository, IBasicService basicService, IOutboundOrderDetailService outboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutStockLockInfoService outboundStockLockInfoService, IFeedbackMesService feedbackMesService, IRepository<Dt_Task> taskRepository, ILocationInfoService locationInfoService, IESSApiService eSSApiService, IRepository<Dt_AllocateOrder> allocateOrderRepository, IRepository<Dt_AllocateMaterialInfo> allocateMaterialInfoRepository, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_InboundOrder> inboundOrderRepository)
        {
            _mapper = mapper;
            _unitOfWorkManage = unitOfWorkManage;
@@ -98,6 +101,35 @@
            _eSSApiService = eSSApiService;
            _allocateOrderRepository = allocateOrderRepository;
            _allocateMaterialInfoRepository = allocateMaterialInfoRepository;
            _inboundOrderDetailRepository = inboundOrderDetailRepository;
            _inboundOrderRepository = inboundOrderRepository;
        }
        public WebResponseContent PrintFromData (string barcode)
        {
            var detail = _inboundOrderDetailRepository.QueryFirst(x => x.Barcode == barcode);
            if(detail == null)
            {
                return WebResponseContent.Instance.Error();
            }
            var inbound = _inboundOrderRepository.QueryFirst(x=>x.Id ==  detail.OrderId);
            if(inbound == null)
            {
                return WebResponseContent.Instance.Error();
            }
            var printFormData = new PrintFromDataDTO {
                materialCode = detail.MaterielCode,
                materialName = detail.MaterielName,
                materialSpec = detail.Unit,
                batchNo = detail.BatchNo,
                pruchaseOrderNo = inbound.UpperOrderNo,
                factoryArea = inbound.FactoryArea,
                suplierCode = detail.SupplyCode,
                quantity = detail.BarcodeQty
            };
            return WebResponseContent.Instance.OK(data:printFormData);
        }
        #region å‡ºåº“分配
@@ -209,6 +241,12 @@
                string responseMsg = totalActualAllocate == totalNeedAllocate
                    ? "分拣任务分配成功"
                    : $"分拣任务分配完成(实际分配{totalActualAllocate},需求{totalNeedAllocate},库存不足部分未分配)";
                Dt_OutboundOrder outboundOrder1 = _outboundRepository.Db.Queryable<Dt_OutboundOrder>().Where(x => x.OrderNo == request.OrderNo).Includes(x=>x.Details).First();
                if(totalActualAllocate == 0 && !outboundOrder1.Details.Any(x=>x.LockQuantity >0))
                {
                    UpdateOutboundOrderStatus(request.OrderNo, (int)OutOrderStatusEnum.未开始);
                    return WebResponseContent.Instance.Error("分配库存数量为0,无法出库");
                }
                response.Success = true;
                response.Message = responseMsg;
                response.Tasks = tasks;
@@ -768,6 +806,10 @@
                Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(x => x.OrderNo == orderNo);
                if (outboundOrder == null) return false;
                outboundOrder.OrderStatus = status;
                if(outboundOrder.CreateType == OrderCreateTypeEnum.CreateInSystem.ObjToInt())
                {
                    outboundOrder.ReturnToMESStatus = 5;
                }
                _outboundRepository.UpdateData(outboundOrder);
                return true;
            }
@@ -1109,8 +1151,15 @@
                        {
                            barcodeQuantity = item.LockQuantity - item.OverOutQuantity;
                            allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity);
                            if(item.ReturnToMESStatus == 0)
                            {
                                item.CurrentDeliveryQty = item.LockQuantity;
                            }
                            else
                            {
                                item.CurrentDeliveryQty += item.LockQuantity - item.OverOutQuantity;
                            }
                            item.OverOutQuantity = item.LockQuantity;
                            item.CurrentDeliveryQty = item.LockQuantity;
                        }
                        updateDetails.Add(item);
@@ -1157,7 +1206,22 @@
                    response.Success = true;
                    response.Message = "出库完成";
                    response.UpdatedDetails = updateDetails;
                    if (CheckOutboundOrderDetailCompletedByMatCode(request.OrderNo, lockInfo.MaterielCode, outboundOrderDetails))
                    {
                        Func<Dt_OutStockLockInfo, bool> supWhere = x => string.IsNullOrEmpty(outboundOrderDetails.First().SupplyCode) ? true : x.SupplyCode == outboundOrderDetails.First().SupplyCode;
                        Func<Dt_OutStockLockInfo, bool> wareWhere = x => string.IsNullOrEmpty(outboundOrderDetails.First().WarehouseCode) ? true : x.WarehouseCode == outboundOrderDetails.First().WarehouseCode;
                        List<Dt_OutStockLockInfo> stockLockInfos = _outboundLockInfoRepository.QueryData(x =>
                                x.OrderNo == request.OrderNo &&
                                x.MaterielCode == stockInfoDetail.MaterielCode).Where(supWhere).Where(wareWhere).ToList();
                        if (stockLockInfos != null && stockLockInfos.Any())
                        {
                            _outboundLockInfoRepository.DeleteAndMoveIntoHty(stockLockInfos, WIDESEA_Core.Enums.OperateTypeEnum.自动删除);
                        }
                    }
                    // æ£€æŸ¥å‡ºåº“单是否完成
                    if (CheckOutboundOrderCompleted(request.OrderNo))
                    {
@@ -1474,8 +1538,15 @@
                        {
                            barcodeQuantity = item.LockQuantity - item.OverOutQuantity;
                            allocatedQuantity -= (item.LockQuantity - item.OverOutQuantity);
                            if (item.ReturnToMESStatus == 0)
                            {
                                item.CurrentDeliveryQty = item.LockQuantity;
                            }
                            else
                            {
                                item.CurrentDeliveryQty += item.LockQuantity - item.OverOutQuantity;
                            }
                            item.OverOutQuantity = item.LockQuantity;
                            item.CurrentDeliveryQty = item.LockQuantity;
                        }
                        updateDetails.Add(item);
@@ -1551,7 +1622,7 @@
                        _feedbackMesService.BarcodeFeedback(newBarcode);
                    }
                    if (CheckOutboundOrderDetailCompletedByMatCode(request.OrderNo, lockInfo.MaterielCode, outboundOrderDetails.First()))
                    if (CheckOutboundOrderDetailCompletedByMatCode(request.OrderNo, lockInfo.MaterielCode, outboundOrderDetails))
                    {
                        Func<Dt_OutStockLockInfo, bool> supWhere = x => string.IsNullOrEmpty(outboundOrderDetails.First().SupplyCode) ? true : x.SupplyCode == outboundOrderDetails.First().SupplyCode;
@@ -1572,12 +1643,11 @@
                    {
                        UpdateOutboundOrderStatus(request.OrderNo, OutOrderStatusEnum.出库完成.ObjToInt());
                        if (outboundOrder.OrderType != OutOrderTypeEnum.InternalAllocat.ObjToInt())
                        if (outboundOrder.OrderType != OutOrderTypeEnum.InternalAllocat.ObjToInt() && outboundOrder.CreateType!=OrderCreateTypeEnum.CreateInSystem.ObjToInt())
                        {
                            _feedbackMesService.OutboundFeedback(outboundOrder.OrderNo);
                        }
                    }
                }
                catch (Exception ex)
                {
@@ -1906,14 +1976,30 @@
        /// <summary>
        /// æ£€æŸ¥å‡ºåº“单明细是否完成
        /// </summary>
        public bool CheckOutboundOrderDetailCompletedByMatCode(string orderNo, string materialCode, Dt_OutboundOrderDetail outboundOrderDetail)
        public bool CheckOutboundOrderDetailCompletedByMatCode(string orderNo, string materialCode, List<Dt_OutboundOrderDetail> outboundOrderDetails)
        {
            if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(materialCode) || outboundOrderDetails == null || !outboundOrderDetails.Any())
                return false;
            // æŸ¥è¯¢ä¸»è®¢å•,不存在直接返回false
            Dt_OutboundOrder outboundOrder = _outboundRepository.QueryFirst(x => x.OrderNo == orderNo);
            if (outboundOrder == null) return false;
            List<Dt_OutboundOrderDetail> details = _detailRepository.QueryData(x => x.OrderId == outboundOrder.Id && x.MaterielCode == materialCode && (string.IsNullOrEmpty(outboundOrderDetail.SupplyCode) || x.SupplyCode == outboundOrderDetail.SupplyCode) && (string.IsNullOrEmpty(outboundOrderDetail.WarehouseCode) || x.WarehouseCode == outboundOrderDetail.WarehouseCode));
            var firstDetail = outboundOrderDetails.FirstOrDefault();
            string supplyCode = firstDetail.SupplyCode;
            string warehouseCode = firstDetail.WarehouseCode;
            List<int> ids = outboundOrderDetails.Select(x => x.Id).ToList();
            // æ£€æŸ¥æ‰€æœ‰æ˜Žç»†çš„已出数量是否都等于单据数量
            List<Dt_OutboundOrderDetail> details = _detailRepository.QueryData(x =>
                x.OrderId == outboundOrder.Id
                && x.MaterielCode == materialCode
                && ids.Contains(x.Id)
                && (string.IsNullOrEmpty(supplyCode) || x.SupplyCode == supplyCode)
                && (string.IsNullOrEmpty(warehouseCode) || x.WarehouseCode == warehouseCode)
            );
            if (!details.Any()) return false;
            return details.All(x => x.OverOutQuantity >= x.OrderQuantity - x.MoveQty);
        }
@@ -1926,6 +2012,12 @@
            try
            {
                var stock = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletCode).FirstAsync();
                Dt_Task task = _taskRepository.QueryFirst(x => x.PalletCode == palletCode);
                if (task != null)
                {
                    return WebResponseContent.Instance.Error("任务信息列表存在该托盘的任务信息,不可取走空箱,请检查任务是否完成");
                }
                if (stock == null)
                {
@@ -1971,21 +2063,20 @@
                if (stock.Details.Count <= 0)
                {
                    stock.PalletType = (int)PalletTypeEnum.Empty;
                    stock.StockStatus = (int)StockStatusEmun.组盘暂存;
                    stock.StockStatus = (int)StockStatusEmun.入库确认;
                    stock.LocationCode = "";
                }
                else if (stock.Details.Count > 0)
                {
                    Dt_OutStockLockInfo lockInfo = _outboundLockInfoRepository.QueryFirst(x =>
                       x.OrderNo == OrderNo &&
                       x.StockId == stock.Id &&
                       x.PalletCode == palletCode);
                    if (lockInfo != null && lockInfo.SortedQuantity != lockInfo.AssignQuantity)
                    {
                        return content.Error($"托盘{palletCode}库存未拣选完不允许回库");
                        return content.Error($"托盘{palletCode}库存,在单据{lockInfo.OrderNo}里面还未拣选完成,不允许回库");
                    }
                    stock.StockStatus = (int)StockStatusEmun.组盘暂存;
                    stock.StockStatus = (int)StockStatusEmun.入库确认;
                    stock.LocationCode = "";
                }
@@ -2001,6 +2092,11 @@
                // åˆ†é…æ–°è´§ä½
                var newLocation = _locationInfoService.AssignLocation(stock.LocationType);
                if(newLocation == null)
                {
                    return WebResponseContent.Instance.Error("没有空闲库位可回库");
                }
                var newTask = new Dt_Task()
                {
                    CurrentAddress = stations.GetValueOrDefault(station) ?? "",