wangxinhui
2025-10-26 733c975cd8647f6d006736f1863bad731e32e6fb
ÏîÄ¿´úÂë/WMS/WMSServices/WIDESEA_OutboundService/OutMESOrderService.cs
@@ -4,6 +4,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.MaterielEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseServices;
@@ -16,6 +17,7 @@
using WIDESEA_IRecordService;
using WIDESEA_IStockService;
using WIDESEA_Model.Models;
using WIDESEA_OutboundRepository;
namespace WIDESEA_OutboundService
{
@@ -27,55 +29,73 @@
        private IOutStockLockInfoService _outStockLockInfoService;
        private IBasicService _basicService;
        private ILocationStatusChangeRecordService _locationStatusChangeRecordService;
        private IOutboundRepository _outboundRepository;
        private readonly IMapper _mapper;
        public OutMESOrderService(IOutMESOrderRepository BaseDal,IBasicRepository basicRepository, IStockService stockService, IOutStockLockInfoService outStockLockInfoService, IBasicService basicService, ILocationStatusChangeRecordService locationStatusChangeRecordService,IMapper mapper) : base(BaseDal)
        public OutMESOrderService(IOutMESOrderRepository BaseDal,IBasicRepository basicRepository, IStockService stockService, IOutStockLockInfoService outStockLockInfoService, IBasicService basicService, ILocationStatusChangeRecordService locationStatusChangeRecordService,IMapper mapper, IOutboundRepository outboundRepository) : base(BaseDal)
        {
            _basicRepository = basicRepository;
            _stockService = stockService;
            _outStockLockInfoService = outStockLockInfoService;
            _basicService = basicService;
            _locationStatusChangeRecordService = locationStatusChangeRecordService;
            _outboundRepository = outboundRepository;
            _mapper = mapper;
        }
        List<string> GradeCodes = new List<string>
        {
            "001"
        };
        /// <summary>
        /// æŽ¥æ”¶MES领料计划
        /// </summary>
        /// <returns></returns>
        public WebResponseContent ReceiveOutBound(OutMESOrderDTO outMESOrderDTO)
        public WebResponseContent ReceiveOutBound(List<OutMESOrderDTO> outMESOrderDTOs)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (outMESOrderDTO==null)
                if (outMESOrderDTOs==null || outMESOrderDTOs.Count <= 0)
                {
                    return content.Error("领料计划传入信息为空");
                }
                if (outMESOrderDTO.OutDetailId <= 0)
                outMESOrderDTOs.Select(x => x.OutDetailId);
                List<Dt_Warehouse> warehouses = _basicRepository.WarehouseRepository.QueryData();
                OutMESOrderDTO? CheckGradeCode = outMESOrderDTOs.FirstOrDefault(x => !GradeCodes.Contains(x.GradeCode));
                if (CheckGradeCode != null)
                {
                    return content.Error($"领料计划{nameof(OutMESOrderDTO.OutDetailId)}:{outMESOrderDTO.OutDetailId}需要大于0");
                    return content.Error($"领料计划库区{nameof(OutMESOrderDTO.GradeCode)}:{CheckGradeCode.GradeCode}不存在");
                }
                if (outMESOrderDTO.ReqQuantity <= 0)
                OutMESOrderDTO? CheckOutDetailId = outMESOrderDTOs.FirstOrDefault(x => x.OutDetailId <= 0);
                if (CheckOutDetailId != null)
                {
                    return content.Error($"领料计划{nameof(OutMESOrderDTO.ReqQuantity)}:{outMESOrderDTO.ReqQuantity}需要大于0");
                    return content.Error($"领料计划{nameof(OutMESOrderDTO.OutDetailId)}:{CheckOutDetailId.ProductOrderNo}需要大于0");
                }
                OutMESOrderDTO? CheckReqQuantity = outMESOrderDTOs.FirstOrDefault(x => x.ReqQuantity <= 0);
                if (CheckReqQuantity != null)
                {
                    return content.Error($"领料计划{nameof(OutMESOrderDTO.ReqQuantity)}:{CheckReqQuantity.ProductOrderNo}需要大于0");
                }
                //获取所有物料信息
                List<Dt_MaterielInfo> materielInfos = _basicRepository.MaterielInfoRepository.QueryData(x=>x.MaterielInvOrgId==MaterielInvOrgEnum.新厂.ObjToInt());
                //获取所有临料计划
                //获取所有领料计划
                List<Dt_OutMESOrder> outMESOrders = BaseDal.QueryData();
                Dt_MaterielInfo? ExistmaterielInfo = materielInfos.FirstOrDefault(x=>x.MaterielCode== outMESOrderDTO.MaterialCode);
                if (ExistmaterielInfo == null)
                OutMESOrderDTO? CheckMaterialCode = outMESOrderDTOs.FirstOrDefault(x=> !materielInfos.Select(x=>x.MaterielCode).Contains(x.MaterialCode));
                if (CheckMaterialCode != null)
                {
                    return content.Error($"物料编码{nameof(OutMESOrderDTO.MaterialCode)}:{outMESOrderDTO.MaterialCode}信息不存在");
                    return content.Error($"物料编码{nameof(OutMESOrderDTO.MaterialCode)}:{CheckMaterialCode.MaterialCode}信息不存在");
                }
                Dt_OutMESOrder? OldoutMESOrder = outMESOrders.FirstOrDefault(x=>x.OutDetailId==outMESOrderDTO.OutDetailId);
                Dt_OutMESOrder? OldoutMESOrder = outMESOrders.FirstOrDefault(x=> outMESOrderDTOs.Select(x=>x.OutDetailId).Contains(x.OutDetailId));
                if (OldoutMESOrder!=null)
                {
                    return content.Error($"领料计划{nameof(OutMESOrderDTO.OutDetailId)}:{outMESOrderDTO.OutDetailId}信息已存在");
                    return content.Error($"领料计划{nameof(OutMESOrderDTO.OutDetailId)}:{OldoutMESOrder.OutDetailId}信息已存在");
                }
                return content.Error($"领料计划{nameof(OutMESOrderDTO.ProductOrderNo)}:{outMESOrderDTO.ProductOrderNo},物料{outMESOrderDTO.MaterialCode}无可分配库存");
                Dt_OutMESOrder outMESOrder = _mapper.Map<Dt_OutMESOrder>(outMESOrderDTO);
                List<Dt_OutMESOrder> outMESOrder = outMESOrderDTOs.Select(x=> _mapper.Map<Dt_OutMESOrder>(x)).ToList();
                foreach (var item in outMESOrder)
                {
                    Dt_MaterielInfo materielInfo = materielInfos.FirstOrDefault(x=>x.MaterielCode==item.MaterialCode);
                    item.WarehouseId = materielInfo.WarehouseId;
                }
                BaseDal.AddData(outMESOrder);
                return content.OK("接收成功");
            }
@@ -85,5 +105,117 @@
            }
            return content;
        }
        /// <summary>
        /// å‡ºåº“库存分配后,更新数据库数据
        /// </summary>
        public WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutMESOrder> outboundOrderDetails, List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos, LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List<Dt_Task>? tasks = null)
        {
            try
            {
                _stockService.StockInfoService.Repository.UpdateData(stockInfos);
                BaseDal.UpdateData(outboundOrderDetails);
                List<Dt_OutStockLockInfo> addOutStockLockInfos = outStockLockInfos.Where(x => x.Id == 0).ToList();
                if (addOutStockLockInfos != null && addOutStockLockInfos.Any())
                {
                    if (tasks != null)
                    {
                        addOutStockLockInfos.ForEach(x =>
                        {
                            x.TaskNum = tasks.FirstOrDefault(v => v.PalletCode == x.PalletCode)?.TaskNum;
                        });
                    }
                    _outStockLockInfoService.Repository.AddData(addOutStockLockInfos);
                }
                List<Dt_OutStockLockInfo> updateOutStockLockInfos = outStockLockInfos.Where(x => x.Id > 0).ToList();
                if (updateOutStockLockInfos != null && updateOutStockLockInfos.Any())
                {
                    _outStockLockInfoService.Repository.UpdateData(updateOutStockLockInfos);
                }
                //添加货位状态
                _locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfos, locationStatus, LocationChangeType.OutboundAssignLocation, "", tasks?.Select(x => x.TaskNum).ToList());
                //批量更新货位状态
                _basicService.LocationInfoService.Repository.UpdateLocationStatus(locationInfos, locationStatus);
                return WebResponseContent.Instance.OK();
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        /// <summary>
        /// åˆ†é…åº“å­˜
        /// </summary>
        public (List<Dt_StockInfo>, List<Dt_OutMESOrder>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) AssignStockOutbound(List<Dt_OutMESOrder> outboundOrders)
        {
            if (!outboundOrders.Any())
            {
                throw new Exception($"未找到出库单明细信息");
            }
            List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>();
            //出库详情
            List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>();
            //货位存储
            List<Dt_LocationInfo> locationInfos = new List<Dt_LocationInfo>();
            foreach (var item in outboundOrders)
            {
                decimal needQuantity = item.ReqQuantity;
                //获取可用库存
                List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterialCode, item.WarehouseId).Where(x => !outStocks.Select(x => x.PalletCode).Contains(x.PalletCode)).ToList();
                if (!stockInfos.Any())
                {
                    throw new Exception($"未找到可分配库存");
                }
                //分配实际库存
                List<Dt_StockInfo> autoAssignStocks = _stockService.StockInfoService.GetOutboundStocks(stockInfos, needQuantity).OrderBy(x => x.StockLength).ToList();
                //添加库存分配
                outStocks.AddRange(autoAssignStocks);
                //订单数量
                decimal orderQuantity = item.ReqQuantity;
                bool assignStop = true;
                while (assignStop)
                {
                    //出库订单明细已分配数量
                    decimal detailAssignQuantity = outStockLockInfos.Where(x => x.OrderDetailId == item.OutDetailId).Sum(x => x.AssignQuantity);
                    decimal orderDetailNeedQuantity = item.ReqQuantity - detailAssignQuantity;
                    decimal useStockLength = autoAssignStocks[0].StockLength - autoAssignStocks[0].StockOutLength;
                    if (orderDetailNeedQuantity > useStockLength)
                    {
                        //生成详情
                        Dt_OutStockLockInfo outStockLockInfo = _outStockLockInfoService.GetOutStockLockInfo(item, autoAssignStocks[0], useStockLength);
                        outStockLockInfos.Add(outStockLockInfo);
                        item.AssignTotalUsage += useStockLength;
                        autoAssignStocks.Remove(autoAssignStocks[0]);
                    }
                    else
                    {
                        //生成详情
                        Dt_OutStockLockInfo outStockLockInfo = _outStockLockInfoService.GetOutStockLockInfo(item, autoAssignStocks[0], orderDetailNeedQuantity);
                        outStockLockInfos.Add(outStockLockInfo);
                        item.AssignTotalUsage = orderQuantity;
                        autoAssignStocks[0].StockOutLength += orderDetailNeedQuantity;
                        if (autoAssignStocks[0].StockOutLength == autoAssignStocks[0].StockLength)
                        {
                            autoAssignStocks.Remove(autoAssignStocks[0]);
                        }
                        assignStop = false;
                    }
                }
                locationInfos.AddRange(_basicRepository.LocationInfoRepository.GetLocationInfos(outStocks.Select(x => x.LocationCode).ToList()));
            }
            return (outStocks, outboundOrders, outStockLockInfos, locationInfos);
        }
    }
}