using AutoMapper; using System; using System.Collections.Generic; 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; using WIDESEA_Core.Helper; using WIDESEA_DTO.MES; using WIDESEA_IBasicRepository; using WIDESEA_IBasicService; using WIDESEA_IOutboundRepository; using WIDESEA_IOutboundService; using WIDESEA_IRecordService; using WIDESEA_IStockService; using WIDESEA_Model.Models; using WIDESEA_OutboundRepository; namespace WIDESEA_OutboundService { public class OutMESOrderService : ServiceBase, IOutMESOrderService { public IOutMESOrderRepository Repository => BaseDal; private IBasicRepository _basicRepository; private IStockService _stockService; 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, IOutboundRepository outboundRepository) : base(BaseDal) { _basicRepository = basicRepository; _stockService = stockService; _outStockLockInfoService = outStockLockInfoService; _basicService = basicService; _locationStatusChangeRecordService = locationStatusChangeRecordService; _outboundRepository = outboundRepository; _mapper = mapper; } List GradeCodes = new List { "001" }; /// /// 接收MES领料计划 /// /// public WebResponseContent ReceiveOutBound(List outMESOrderDTOs) { WebResponseContent content = new WebResponseContent(); try { if (outMESOrderDTOs==null || outMESOrderDTOs.Count <= 0) { return content.Error("领料计划传入信息为空"); } outMESOrderDTOs.Select(x => x.OutDetailId); List warehouses = _basicRepository.WarehouseRepository.QueryData(); OutMESOrderDTO? CheckGradeCode = outMESOrderDTOs.FirstOrDefault(x => !GradeCodes.Contains(x.GradeCode)); if (CheckGradeCode != null) { return content.Error($"领料计划库区{nameof(OutMESOrderDTO.GradeCode)}:{CheckGradeCode.GradeCode}不存在"); } OutMESOrderDTO? CheckOutDetailId = outMESOrderDTOs.FirstOrDefault(x => x.OutDetailId <= 0); if (CheckOutDetailId != null) { 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 materielInfos = _basicRepository.MaterielInfoRepository.QueryData(x=>x.MaterielInvOrgId==MaterielInvOrgEnum.新厂.ObjToInt()); //获取所有领料计划 List outMESOrders = BaseDal.QueryData(); OutMESOrderDTO? CheckMaterialCode = outMESOrderDTOs.FirstOrDefault(x=> !materielInfos.Select(x=>x.MaterielCode).Contains(x.MaterialCode)); if (CheckMaterialCode != null) { return content.Error($"物料编码{nameof(OutMESOrderDTO.MaterialCode)}:{CheckMaterialCode.MaterialCode}信息不存在"); } Dt_OutMESOrder? OldoutMESOrder = outMESOrders.FirstOrDefault(x=> outMESOrderDTOs.Select(x=>x.OutDetailId).Contains(x.OutDetailId)); if (OldoutMESOrder!=null) { return content.Error($"领料计划{nameof(OutMESOrderDTO.OutDetailId)}:{OldoutMESOrder.OutDetailId}信息已存在"); } List outMESOrder = outMESOrderDTOs.Select(x=> _mapper.Map(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("接收成功"); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 出库库存分配后,更新数据库数据 /// public WebResponseContent LockOutboundStockDataUpdate(List stockInfos, List outboundOrderDetails, List outStockLockInfos, List locationInfos, LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List? tasks = null) { try { _stockService.StockInfoService.Repository.UpdateData(stockInfos); BaseDal.UpdateData(outboundOrderDetails); List 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 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); } } /// /// 分配库存 /// public (List, List, List, List) AssignStockOutbound(List outboundOrders) { if (!outboundOrders.Any()) { throw new Exception($"未找到出库单明细信息"); } List outStocks = new List(); //出库详情 List outStockLockInfos = new List(); //货位存储 List locationInfos = new List(); foreach (var item in outboundOrders) { decimal needQuantity = item.ReqQuantity; //获取可用库存 List 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 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); } } }