heshaofeng
2026-03-09 557f7f6079c30cd6fe8d6005cea3d89468bbcd31
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs
@@ -3,7 +3,8 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SqlSugar;
using SqlSugar.Extensions;
using WIDESEA_BasicService;
using WIDESEA_Common.AllocateEnum;
using WIDESEA_Common.OrderEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
@@ -11,6 +12,7 @@
using WIDESEA_Core.CodeConfigEnum;
using WIDESEA_Core.DB;
using WIDESEA_Core.Enums;
using WIDESEA_Core.Helper;
using WIDESEA_Core.Seed;
using WIDESEA_IBasicService;
using WIDESEA_IOutboundService;
@@ -22,20 +24,24 @@
    {
        private readonly IMapper _mapper;
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly IMaterielInfoService _materielInfoService;
        public IRepository<Dt_OutboundOrder> Repository => BaseDal;
        private readonly ILogger<OutboundOrderService> _logger;
        private readonly IRepository<Dt_OutboundOrderDetail> _outboundOrderDetailRepository;
        private readonly IMaterialUnitService _materialUnitService;
        public OutboundOrderService(IRepository<Dt_OutboundOrder> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_OutboundOrderDetail> outboundOrderDetailRepository, ILogger<OutboundOrderService> logger, IMaterialUnitService materialUnitService) : base(BaseDal)
        private readonly IRepository<Dt_OutStockLockInfo> _outStockLockInfoRepository;
        public OutboundOrderService(IRepository<Dt_OutboundOrder> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_OutboundOrderDetail> outboundOrderDetailRepository, ILogger<OutboundOrderService> logger, IMaterialUnitService materialUnitService, IMaterielInfoService materielInfoService, IRepository<Dt_OutStockLockInfo> outStockLockInfoRepository) : base(BaseDal)
        {
            _mapper = mapper;
            _unitOfWorkManage = unitOfWorkManage;
            _outboundOrderDetailRepository = outboundOrderDetailRepository;
            _logger = logger;
            _materialUnitService = materialUnitService;
            _materielInfoService = materielInfoService;
            _outStockLockInfoRepository = outStockLockInfoRepository;
        }
        private int[] OrderTypes = new int[] { InOrderTypeEnum.AllocatOutbound.ObjToInt(), InOrderTypeEnum.InternalAllocat.ObjToInt(), InOrderTypeEnum.ReCheck.ObjToInt() };
        private int[] OrderTypes = new int[] { (int)InOrderTypeEnum.AllocatOutbound, (int)InOrderTypeEnum.InternalAllocat, (int)InOrderTypeEnum.ReCheck };
        public async Task<WebResponseContent> ReceiveOutboundOrder(Dt_OutboundOrder model, int operateType)
        {
            try
@@ -62,21 +68,30 @@
                if (BaseDal.QueryFirst(x => x.UpperOrderNo == model.UpperOrderNo) != null)
                {
                    return WebResponseContent.Instance.Error($"出库单号重复");
                    return WebResponseContent.Instance.Error($"{model.UpperOrderNo}出库单号重复");
                }
                var materielCodes = model.Details.Select(x => x.MaterielCode).Distinct().ToList();
                var materielInfos = _materielInfoService.Db.Queryable<Dt_MaterielInfo>().Where(x => materielCodes.Contains(x.MaterielCode)).ToList();
                foreach (var item in model.Details)
                {
                    var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode,item.BarcodeUnit, item.BarcodeQty);
                    var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeQty);
                    item.Unit = issueoStockResult.Unit;
                    item.OrderQuantity = issueoStockResult.Quantity;
                    var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
                    item.MoveQty = moveissueoStockResult.Quantity;
                    if (materielInfos.Any())
                    {
                        item.MaterielName = materielInfos.FirstOrDefault(x => x.MaterielCode == item.MaterielCode)?.MaterielName ?? "";
                    }
                }
                if (!OrderTypes.Contains(model.OrderType))
                {
                    model.OrderNo = CreateCodeByRule(nameof(RuleCodeEnum.OutboundOrderRule));
                }
                Db.InsertNav(model).Include(x => x.Details).ExecuteCommand();
                return WebResponseContent.Instance.OK();
@@ -90,8 +105,10 @@
        {
            try
            {
                var outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == model.UpperOrderNo).Includes(x => x.Details).First();
                var outboundOrder = Db.Queryable<Dt_OutboundOrder>()
                    .Where(x => x.UpperOrderNo == model.UpperOrderNo)
                    .Includes(x => x.Details)
                    .First();
                if (outboundOrder == null)
                {
                    return WebResponseContent.Instance.Error($"未找到出库单信息");
@@ -100,16 +117,17 @@
                {
                    return WebResponseContent.Instance.Error($"未找到出库单明细信息");
                }
                if (outboundOrder.OrderStatus != OutOrderStatusEnum.未开始.ObjToInt())
                {
                    return WebResponseContent.Instance.Error($"该订单状态不允许修改");
                }
                List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
                List<Dt_OutboundOrderDetail> updateoutboundOrderDetails = new List<Dt_OutboundOrderDetail>();
                List<int> detailIds = new List<int>();
                var materielCodes = model.Details.Select(x => x.MaterielCode).Distinct().ToList();
                var materielInfos = _materielInfoService.Db.Queryable<Dt_MaterielInfo>()
                    .Where(x => materielCodes.Contains(x.MaterielCode))
                    .ToList();
                foreach (var item in model.Details)
                {
                    var outboundOrderDetail = outboundOrder.Details.FirstOrDefault(x => x.lineNo == item.lineNo);
                    if (outboundOrderDetail == null)
                    {
@@ -128,39 +146,82 @@
                            BarcodeQty = item.OrderQuantity,
                            BarcodeUnit = item.Unit,
                        };
                        var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode,item.BarcodeUnit, item.BarcodeQty);
                        item.Unit = issueoStockResult.Unit;
                        item.OrderQuantity = issueoStockResult.Quantity;
                        var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
                        item.MoveQty = moveissueoStockResult.Quantity;
                        outboundOrderDetails.Add(outboundOrderDetail);
                    }
                    else
                    {
                        outboundOrderDetail.lineNo = item.lineNo;
                        outboundOrderDetail.MaterielCode = item.MaterielCode;
                        outboundOrderDetail.SupplyCode = item.SupplyCode;
                        outboundOrderDetail.BatchNo = item.BatchNo;
                        outboundOrderDetail.Unit = item.Unit;
                        outboundOrderDetail.WarehouseCode = item.WarehouseCode;
                        outboundOrderDetail.MoveQty = item.MoveQty;
                        outboundOrderDetail.OrderQuantity = item.OrderQuantity;
                        outboundOrderDetail.BarcodeMoveQty = item.MoveQty;
                        outboundOrderDetail.BarcodeQty = item.OrderQuantity;
                        outboundOrderDetail.BarcodeUnit = item.Unit;
                        var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeQty);
                        outboundOrderDetail.Unit = issueoStockResult.Unit;
                        outboundOrderDetail.OrderQuantity = issueoStockResult.Quantity;
                        var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
                        outboundOrderDetail.MoveQty = moveissueoStockResult.Quantity;
                        outboundOrderDetail.MaterielName = materielInfos.FirstOrDefault(x => x.MaterielCode == item.MaterielCode)?.MaterielName ?? "";
                        outboundOrderDetails.Add(outboundOrderDetail);
                    }
                    else
                    {
                        #region é”å®šçŠ¶æ€ä¸‹éžæ•°é‡å­—æ®µä¸€è‡´æ€§æ ¡éªŒ
                        if (outboundOrderDetail.LockQuantity != 0)
                        {
                            var isFieldChanged = !string.Equals(outboundOrderDetail.MaterielCode, item.MaterielCode)
                                || !string.Equals(outboundOrderDetail.SupplyCode, item.SupplyCode)
                                || !string.Equals(outboundOrderDetail.BatchNo, item.BatchNo)
                                || !string.Equals(outboundOrderDetail.Unit, item.Unit)
                                || !string.Equals(outboundOrderDetail.WarehouseCode, item.WarehouseCode)
                                || !string.Equals(outboundOrderDetail.lineNo, item.lineNo)
                                ;
                            if (isFieldChanged)
                            {
                                return WebResponseContent.Instance.Error($"行号{item.lineNo}已锁定出库(锁定数量:{outboundOrderDetail.LockQuantity}),仅允许修改订单数量,禁止修改物料/批次/仓库等其他信息");
                            }
                            else
                            {
                                if(item.MoveQty > (outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity))
                                {
                                    return WebResponseContent.Instance.Error($"行号{item.lineNo}挪料数量不能超过剩下的订单数量{outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity}");
                                }
                                outboundOrderDetail.MoveQty = item.MoveQty;
                            }
                        }
                        #endregion
                        #region åŽŸæœ‰æ•°é‡æ ¡éªŒé€»è¾‘ä¿ç•™
                        if (item.OrderQuantity < outboundOrderDetail.LockQuantity + outboundOrderDetail.MoveQty)
                        {
                            return WebResponseContent.Instance.Error($"修改的行号{item.lineNo}数量超过了智仓出库锁定数量加上挪料数量,不允许修改");
                        }
                        #endregion
                        #region å­—段赋值逻辑:锁定状态仅改数量,未锁定则全量更新
                        if (outboundOrderDetail.LockQuantity == 0)
                        {
                            outboundOrderDetail.lineNo = item.lineNo;
                            outboundOrderDetail.MaterielCode = item.MaterielCode;
                            outboundOrderDetail.SupplyCode = item.SupplyCode;
                            outboundOrderDetail.BatchNo = item.BatchNo;
                            outboundOrderDetail.Unit = item.Unit;
                            outboundOrderDetail.WarehouseCode = item.WarehouseCode;
                            outboundOrderDetail.MoveQty = item.MoveQty;
                            outboundOrderDetail.BarcodeMoveQty = item.MoveQty;
                            outboundOrderDetail.BarcodeQty = item.OrderQuantity;
                            outboundOrderDetail.BarcodeUnit = item.Unit;
                            var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeQty);
                            outboundOrderDetail.Unit = issueoStockResult.Unit;
                            outboundOrderDetail.OrderQuantity = issueoStockResult.Quantity;
                            var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
                            outboundOrderDetail.MoveQty = moveissueoStockResult.Quantity;
                        }
                        else
                        {
                            outboundOrderDetail.OrderQuantity = item.OrderQuantity;
                        }
                        #endregion
                        outboundOrderDetail.MaterielName = materielInfos.FirstOrDefault(x => x.MaterielCode == item.MaterielCode)?.MaterielName ?? "";
                        updateoutboundOrderDetails.Add(outboundOrderDetail);
                        detailIds.Add(outboundOrderDetail.Id);
                    }
                }
                outboundOrder.UpperOrderNo = model.UpperOrderNo;
                outboundOrder.BusinessType = model.BusinessType;
@@ -172,14 +233,22 @@
                _unitOfWorkManage.BeginTran();
                foreach (var item in deletePurchaseOrderDetails)
                {
                    // _outboundOrderDetailRepository.DeleteAndMoveIntoHty(item, OperateTypeEnum.自动删除);
                    if (item.LockQuantity > 0)
                    {
                        return WebResponseContent.Instance.Error($"原单据行号{item.lineNo}已经锁定出库,不允许删除,请重新更改数据推送");
                    }
                    _outboundOrderDetailRepository.DeleteData(item);
                }
                _outboundOrderDetailRepository.UpdateData(updateoutboundOrderDetails);
                _outboundOrderDetailRepository.AddData(outboundOrderDetails);
                if (outboundOrder.Details.All(x => x.OverOutQuantity >= x.OrderQuantity - x.MoveQty))
                {
                    outboundOrder.OrderStatus = (int)OutOrderStatusEnum.出库完成;
                }
                BaseDal.UpdateData(outboundOrder);
                _unitOfWorkManage.CommitTran();
                return WebResponseContent.Instance.OK();
@@ -204,7 +273,7 @@
                {
                    return WebResponseContent.Instance.Error($"未找到出库单明细信息");
                }
                if (outboundOrder.OrderStatus != OutOrderStatusEnum.未开始.ObjToInt())
                if (outboundOrder.OrderStatus != (int)OutOrderStatusEnum.未开始)
                {
                    return WebResponseContent.Instance.Error($"该订单状态不允许删除");
                }
@@ -241,6 +310,19 @@
            return WebResponseContent.Instance.OK(null, order);
        }
        /// <summary>
        /// æ ¹æ®æ‰˜ç›˜å·èŽ·å–å•æ®ç¼–å·
        /// </summary>
        public WebResponseContent GetOrderNoByPalletCode(string palletCode)
        {
           var orderNo = _outStockLockInfoRepository.QueryData(x => x.PalletCode == palletCode).Select(x=>x.OrderNo).FirstOrDefault();
            if(string.IsNullOrWhiteSpace(orderNo))
            {
                return WebResponseContent.Instance.Error($"该托盘{palletCode}已拣选完");
            }
            return WebResponseContent.Instance.OK(data: orderNo);
        }
        static object lock_code = new object();
        public string CreateCodeByRule(string ruleCode)
@@ -301,5 +383,131 @@
                return code;
            }
        }
        public override PageGridData<Dt_OutboundOrder> GetPageData(PageDataOptions options)
        {
            Dictionary<string, SqlSugar.OrderByType> orderbyDic = GetPageDataSort(options, TProperties);
            List<OrderByModel> orderByModels = new List<OrderByModel>();
            foreach (var item in orderbyDic)
            {
                OrderByModel orderByModel = new()
                {
                    FieldName = item.Key,
                    OrderByType = item.Value
                };
                orderByModels.Add(orderByModel);
            }
            ISugarQueryable<Dt_OutboundOrder> sugarQueryable1 = BaseDal.Db.Queryable<Dt_OutboundOrder>().Includes(x => x.Details);
            int totalCount = 0;
            List<SearchParameters> searchParametersList = new List<SearchParameters>();
            if (!string.IsNullOrEmpty(options.Wheres))
            {
                try
                {
                    searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
                    options.Filter = searchParametersList;
                    if (searchParametersList.Count > 0)
                    {
                        var materielCodeParam = searchParametersList.FirstOrDefault(x =>
                    x.Name.Equals("materielCode", StringComparison.OrdinalIgnoreCase));
                        if (materielCodeParam != null && !string.IsNullOrEmpty(materielCodeParam.Value?.ToString()))
                        {
                            string materielCode = materielCodeParam.Value.ToString().Trim();
                            sugarQueryable1 = sugarQueryable1.Where(x =>
                                x.Details.Any(d => d.MaterielCode.Contains(materielCode)));
                        }
                        var upperOrderNoParam = searchParametersList.FirstOrDefault(x =>
                            x.Name.Equals(nameof(Dt_OutboundOrder.UpperOrderNo).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase));
                        if (upperOrderNoParam != null && !string.IsNullOrEmpty(upperOrderNoParam.Value?.ToString()))
                        {
                            string upperOrderNo = upperOrderNoParam.Value.ToString().Trim();
                            sugarQueryable1 = sugarQueryable1.Where(x => x.UpperOrderNo.Contains(upperOrderNo));
                        }
                        var orderNoParam = searchParametersList.FirstOrDefault(x =>
                            x.Name.Equals(nameof(Dt_OutboundOrder.OrderNo).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase));
                        if (orderNoParam != null && !string.IsNullOrEmpty(orderNoParam.Value?.ToString()))
                        {
                            string orderNo = orderNoParam.Value.ToString().Trim();
                            sugarQueryable1 = sugarQueryable1.Where(x => x.OrderNo.Contains(orderNo));
                        }
                        var orderStatusParam = searchParametersList.FirstOrDefault(x =>
                            x.Name.Equals(nameof(Dt_OutboundOrder.OrderStatus).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase));
                        if (orderStatusParam != null && !string.IsNullOrEmpty(orderStatusParam.Value?.ToString()))
                        {
                            string orderStatus = orderStatusParam.Value.ToString().Trim();
                            sugarQueryable1 = sugarQueryable1.Where(x => x.OrderStatus.Equals(orderStatus));
                        }
                        var returnToMESStatusParam = searchParametersList.FirstOrDefault(x =>
                            x.Name.Equals(nameof(Dt_OutboundOrder.ReturnToMESStatus).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase));
                        if (returnToMESStatusParam != null && !string.IsNullOrEmpty(returnToMESStatusParam.Value?.ToString()))
                        {
                            string returnToMESStatus = returnToMESStatusParam.Value.ToString().Trim();
                            sugarQueryable1 = sugarQueryable1.Where(x => x.ReturnToMESStatus.Equals(returnToMESStatus));
                        }
                        var businessTypeParam = searchParametersList.FirstOrDefault(x =>
                            x.Name.Equals(nameof(Dt_OutboundOrder.BusinessType).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase));
                        if (businessTypeParam != null && !string.IsNullOrEmpty(businessTypeParam.Value?.ToString()))
                        {
                            string businessType = businessTypeParam.Value.ToString().Trim();
                            sugarQueryable1 = sugarQueryable1.Where(x => x.BusinessType.Equals(businessType));
                        }
                        var departmentNameParam = searchParametersList.FirstOrDefault(x =>
                   x.Name.Equals("departmentName", StringComparison.OrdinalIgnoreCase));
                        if (departmentNameParam != null && !string.IsNullOrEmpty(departmentNameParam.Value?.ToString()))
                        {
                            string departmentName = departmentNameParam.Value.ToString().Trim();
                            sugarQueryable1 = sugarQueryable1.Where(x =>
                                x.DepartmentName.Contains(departmentName));
                        }
                        var createDateParams = searchParametersList
                    .Where(x => x.Name.Equals("createDate", StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(x.Value?.ToString()))
                    .ToList();
                        DateTime? minCreateDate = null;
                        DateTime? maxCreateDate = null;
                        foreach (var dateParam in createDateParams)
                        {
                            if (DateTime.TryParse(dateParam.Value.ToString(), out DateTime dateValue))
                            {
                                LinqExpressionType expressionType = dateParam.DisplayType.GetLinqCondition();
                                switch (expressionType)
                                {
                                    case LinqExpressionType.ThanOrEqual:
                                        minCreateDate = dateValue;
                                        break;
                                    case LinqExpressionType.LessThanOrEqual:
                                        maxCreateDate = dateValue;
                                        break;
                                }
                            }
                        }
                        if (minCreateDate.HasValue)
                        {
                            sugarQueryable1 = sugarQueryable1.Where(x => x.CreateDate >= minCreateDate.Value);
                        }
                        if (maxCreateDate.HasValue)
                        {
                            sugarQueryable1 = sugarQueryable1.Where(x => x.CreateDate <= maxCreateDate.Value);
                        }
                    }
                }
                catch { }
            }
            var data = sugarQueryable1
                .Where(x => x.OrderType == 0 || x.OrderType == 116)
                .OrderBy(orderByModels)
                .ToPageList(options.Page, options.Rows, ref totalCount);
            return new PageGridData<Dt_OutboundOrder>(totalCount, data);
        }
    }
}