dengjunjie
2025-12-29 dab0a583302f306d8c0ec37fbae37c9b4e37e473
WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -80,6 +80,7 @@
using System.Drawing.Printing;
using System;
using WIDESEA_Common.Log;
using static WIDESEA_Common.HouseInboundPassBack.data.data1;
namespace WIDESEA_TaskInfoService
{
@@ -112,7 +113,7 @@
        public ITaskRepository Repository => BaseDal;
        public TaskService(ITaskRepository BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IMaterielInfoService materielInfoService, IInboundOrderDetail_HtyService inboundOrderDetail_HtyService, IOutboundOrder_HtyService outboundOrder_HtyService, IOutboundOrderDetail_HtyService outboundOrderDetail_HtyService, IInboundOrder_HtyService inboundOrder_HtyService, IStockRepository stockRepository, IInboundOrderDetailService inboundOrderDetailService, IBasicService basicService, IOutboundService outboundService, IInboundService inboundService, IRecordService recordService, IStockService stockService, ITask_HtyService taskHtyService, ILocationInfoService locationInfoService, IOutboundOrderDetailRepository outboundOrderDetailRepository, IBasicRepository basicRepository, IStockInfoDetailRepository stockInfoDetailRepository, IPalletTypeInfoRepository palletTypeInfoRepository, IReturnOrderRepository returnOrderRepository, IProductionRepository productionRepository,IInboundRepository inboundRepository) : base(BaseDal)
        public TaskService(ITaskRepository BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IMaterielInfoService materielInfoService, IInboundOrderDetail_HtyService inboundOrderDetail_HtyService, IOutboundOrder_HtyService outboundOrder_HtyService, IOutboundOrderDetail_HtyService outboundOrderDetail_HtyService, IInboundOrder_HtyService inboundOrder_HtyService, IStockRepository stockRepository, IInboundOrderDetailService inboundOrderDetailService, IBasicService basicService, IOutboundService outboundService, IInboundService inboundService, IRecordService recordService, IStockService stockService, ITask_HtyService taskHtyService, ILocationInfoService locationInfoService, IOutboundOrderDetailRepository outboundOrderDetailRepository, IBasicRepository basicRepository, IStockInfoDetailRepository stockInfoDetailRepository, IPalletTypeInfoRepository palletTypeInfoRepository, IReturnOrderRepository returnOrderRepository, IProductionRepository productionRepository, IInboundRepository inboundRepository) : base(BaseDal)
        {
            _mapper = mapper;
            _stockRepository = stockRepository;
@@ -167,6 +168,30 @@
                    return WebResponseContent.Instance.Error($"未找到WCSApi地址,请检查配置文件");
                }
                string response = HttpHelper.Post($"{url}/api/Task/ReceiveTask", taskDTOs.Serialize());
                return JsonConvert.DeserializeObject<WebResponseContent>(response) ?? WebResponseContent.Instance.Error("返回错误");
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        public WebResponseContent PushTasksWCS(List<Dt_Task> tasks, string agvDescription = "")
        {
            try
            {
                List<WMSTaskDTO> taskDTOs = _mapper.Map<List<WMSTaskDTO>>(tasks);
                taskDTOs.ForEach(x =>
                {
                    x.AGVArea = agvDescription;
                });
                string url = AppSettings.app("WCS");
                if (string.IsNullOrEmpty(url))
                {
                    return WebResponseContent.Instance.Error($"未找到WCSApi地址,请检查配置文件");
                }
                string response = HttpHelper.Post($"{url}/api/Task/ReceiveCPTask", taskDTOs.Serialize());
                return JsonConvert.DeserializeObject<WebResponseContent>(response) ?? WebResponseContent.Instance.Error("返回错误");
            }
@@ -467,35 +492,308 @@
                dt_StockInfo.LocationCode = dt_LocationInfo.LocationCode;
                Dt_InboundOrder? inboundOrder = _inboundService.InbounOrderService.Db.Queryable<Dt_InboundOrder>().Where(x => x.OrderNo == dt_StockInfo.Details.FirstOrDefault().OrderNo).Includes(x => x.Details).First();
                Dt_InboundOrderDetail? inboundOrderDetail = null;
                // 3. 处理入库逻辑
                if (task.TaskType == TaskTypeEnum.Inbound.ObjToInt())
                if (warehouse.WarehouseCode.Contains("TestJCLK"))
                {
                    return ProcessInbound(task, dt_StockInfo, dt_LocationInfo);
                }
                if (task.TaskType == TaskTypeEnum.SurplusReturn.ObjToInt() || task.TaskType == TaskTypeEnum.ReverseIn.ObjToInt())
                {
                    return ReturnInbound(task, dt_StockInfo, dt_LocationInfo);
                }
                if(task.TaskType == TaskTypeEnum.InInventory.ObjToInt())
                {
                    int lastStatus = dt_LocationInfo.LocationStatus;
                    dt_LocationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
                    dt_StockInfo.StockStatus = StockStatusEmun.入库完成.ObjToInt();
                    // 更新库存明细状态
                    dt_StockInfo.Details.ForEach(x => x.Status = StockStatusEmun.入库完成.ObjToInt());
                    _unitOfWorkManage.BeginTran();
                    UpdateTaskStatus(task);
                    UpdateLocationStatus(dt_LocationInfo, lastStatus);
                    UpdateStockInfo(dt_StockInfo);
                    AddRecords(task, dt_StockInfo, dt_LocationInfo, lastStatus);
                    _unitOfWorkManage.CommitTran();
                    return WebResponseContent.Instance.OK();
                    // 1. 获取入库单信息
                    Dt_InboundOrder? inboundOrder = null;
                    if (!string.IsNullOrEmpty(dt_StockInfo.Details.FirstOrDefault()?.OrderNo))
                    {
                        inboundOrder = _inboundService.InbounOrderService.Db.Queryable<Dt_InboundOrder>()
                            .Where(x => x.OrderNo == dt_StockInfo.Details.FirstOrDefault().OrderNo)
                            .Includes(x => x.Details)
                            .First();
                    }
                    // 3. 处理入库逻辑
                    if (task.TaskType == TaskTypeEnum.Inbound.ObjToInt())
                    {
                        int lastStatus = dt_LocationInfo.LocationStatus;
                        dt_LocationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
                        if (task.TaskType == TaskTypeEnum.Inbound.ObjToInt() && inboundOrder == null)
                        {
                            return WebResponseContent.Instance.Error("未找到入库单信息");
                        }
                        var allBoxCodesForDetail = BaseDal.Db.Queryable<Dt_StockInfoDetailCP>()
                     .Where(x => x.StockDetailId == dt_StockInfo.Details.FirstOrDefault().Id)
                     .Select(x => x.BoxCode)
                     .ToList();
                        // 2. 获取托盘下的所有箱号
                        var boxCodes = new List<string>();
                        // 方法1:从库存明细的BoxCodes字段获取(组盘时保存的)
                        foreach (var detail in allBoxCodesForDetail)
                        {
                            if (!string.IsNullOrEmpty(detail))
                            {
                                var codes = detail.Split(',', StringSplitOptions.RemoveEmptyEntries);
                                boxCodes.AddRange(codes);
                            }
                        }
                        // 根据托盘明细获取对应的入库单明细
                        List<Dt_InboundOrderDetail> inboundOrderDetails = new List<Dt_InboundOrderDetail>();
                        // 处理多个库存明细的情况
                        foreach (var stockDetail in dt_StockInfo.Details)
                        {
                            if (!string.IsNullOrEmpty(stockDetail.OrderNo))
                            {
                                var detail = inboundOrder.Details.FirstOrDefault(x => x.LinId == stockDetail.LinId && x.BatchNo == stockDetail.BatchNo);
                                if (detail != null && !inboundOrderDetails.Any(x => x.Id == detail.Id))
                                {
                                    inboundOrderDetails.Add(detail);
                                }
                            }
                        }
                        if (!inboundOrderDetails.Any())
                        {
                            return WebResponseContent.Instance.Error($"未找到对应的入库单明细");
                        }
                        // 更新入库单明细状态
                        foreach (var inboundOrderDetail in inboundOrderDetails)
                        {
                            // 检查该明细是否已全部入库
                            decimal totalStockQuantity = dt_StockInfo.Details
                                .Where(x => x.LinId == inboundOrderDetail.LinId && x.BatchNo == inboundOrderDetail.BatchNo)
                                .Sum(x => x.StockQuantity);
                            decimal orderQuantity = Convert.ToDecimal(inboundOrderDetail.OrderQuantity);
                            decimal receiptQuantity = Convert.ToDecimal(inboundOrderDetail.ReceiptQuantity);
                            decimal overInQuantity = Convert.ToDecimal(inboundOrderDetail.OverInQuantity);
                            // 更新收货数量
                            inboundOrderDetail.OverInQuantity = totalStockQuantity += overInQuantity;
                            // 检查是否全部完成
                            if (inboundOrderDetail.OverInQuantity == inboundOrderDetail.OrderQuantity)
                            {
                                inboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt();
                            }
                            else
                            {
                                inboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Inbounding.ObjToInt();
                            }
                        }
                        ///更新库存状态
                        dt_StockInfo.StockStatus = StockStatusEmun.入库完成.ObjToInt();
                        // 更新库存明细状态
                        dt_StockInfo.Details.ForEach(x => x.Status = StockStatusEmun.入库完成.ObjToInt());
                        // 3. 查询成品入库明细(CP入库单明细)
                        List<Dt_CPInboundOrderDetail> cpInboundDetails = new List<Dt_CPInboundOrderDetail>();
                        if (boxCodes.Any())
                        {
                            cpInboundDetails = BaseDal.Db.Queryable<Dt_CPInboundOrderDetail>()
                                .Where(x => boxCodes.Contains(x.BoxCode))
                                .ToList();
                        }
                        // 更新成品入库明细状态
                        if (cpInboundDetails.Any())
                        {
                            foreach (var cpDetail in cpInboundDetails)
                            {
                                cpDetail.CPOrderDetailStatus = InboundStatusEnum.入库完成.ObjToInt();
                            }
                        }
                        // 4. 查询并更新成品库存明细(如果有单独的成品库存表)
                        List<Dt_StockInfoDetailCP> cpStockDetails = new List<Dt_StockInfoDetailCP>();
                        if (boxCodes.Any())
                        {
                            cpStockDetails = BaseDal.Db.Queryable<Dt_StockInfoDetailCP>()
                                .Where(x => boxCodes.Contains(x.BoxCode))
                                .ToList();
                            // 更新成品库存明细状态
                            foreach (var cpStockDetail in cpStockDetails)
                            {
                                cpStockDetail.CPStockDetailStatus = StockStatusEmun.入库完成.ObjToInt();
                            }
                        }
                        try
                        {
                            _unitOfWorkManage.BeginTran();
                            // 更新任务状态
                            UpdateTaskStatus(task);
                            // 更新货位状态
                            UpdateLocationStatus(dt_LocationInfo, lastStatus);
                            // 更新库存信息
                            UpdateStockInfo(dt_StockInfo);
                            // 添加记录
                            AddRecords(task, dt_StockInfo, dt_LocationInfo, lastStatus);
                            // 更新入库单明细
                            if (inboundOrderDetails.Any())
                            {
                                BaseDal.Db.Updateable(inboundOrderDetails).ExecuteCommand();
                                // 检查入库单是否全部完成
                                bool allCompleted = inboundOrder.Details.All(x =>
                                    x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt());
                                if (allCompleted)
                                {
                                    inboundOrder.OrderStatus = InboundStatusEnum.入库完成.ObjToInt();
                                }
                                else
                                {
                                    inboundOrder.OrderStatus = InboundStatusEnum.入库中.ObjToInt();
                                }
                            }
                            // 更新入库单
                            UpdateInboundOrder(inboundOrder, inboundOrderDetails.FirstOrDefault());
                            // 更新成品入库明细状态
                            if (cpInboundDetails.Any())
                            {
                                BaseDal.Db.Updateable(cpInboundDetails).ExecuteCommand();
                            }
                            // 更新成品库存明细状态
                            if (cpStockDetails.Any())
                            {
                                BaseDal.Db.Updateable(cpStockDetails).ExecuteCommand();
                            }
                            // 单据数量全部上架完成,处理WMS回传
                            if (inboundOrderDetails.Any(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()) && inboundOrder.System.Equals("ERP"))
                            {
                                foreach (var detail in inboundOrderDetails.Where(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()))
                                {
                                    FeedBackInboundERP(inboundOrder.UpperOrderNo, detail.LinId);
                                }
                            }
                            if (inboundOrder.OrderStatus == InboundStatusEnum.入库完成.ObjToInt() && inboundOrder.OrderType == 0 && inboundOrder.System.Equals("SMOM"))
                            {
                                List<Dt_StockInfo> StockInfos = _stockRepository.StockInfoRepository.Db
                                    .Queryable<Dt_StockInfo>()
                                    .Includes(x => x.Details, d => d.StockDetails)
                                    .Where(x => x.WarehouseId == task.WarehouseId &&
                                                x.Details.Any(v => v.OrderNo == inboundOrder.OrderNo))
                                    .ToList();
                                if (StockInfos.Count == 0) throw new Exception("未找到库存信息");
                                var houseInboundPassBack = new HouseInboundPassBack
                                {
                                    ApiType = "AsnController",
                                    Method = "AsrsGroudingAsn",
                                    Parameters = new List<HouseInboundPassBack.data>
                {
                    new HouseInboundPassBack.data
                    {
                        Value = new List<data.data1>
                        {
                            new data.data1
                            {
                                AsnNo = inboundOrder.OrderNo,
                                //InWarehouse = task.Roadway,
                                TransactionCode = inboundOrder.TransactionCode,
                                InoutType = inboundOrder.OrderType,
                                OrderType = inboundOrder.InoutType,
                                // 遍历所有库存明细,添加到 DetailList
                                DetailList = StockInfos.Select(d => new data.data1.Inbound
                                {
                                    LinId = d.Details.FirstOrDefault()?.LinId?? "",
                                    MaterielCode = d.Details.FirstOrDefault()?.MaterielCode?? "",
                                    OrderQuantity = d.Details.FirstOrDefault().StockQuantity,
                                    BatchNo = d.Details.FirstOrDefault()?.BatchNo,
                                    LPNNo = d.PalletCode,
                                    FinishQty = d.Details.FirstOrDefault().StockQuantity,
                                    LocationName = d.LocationCode,
                                    LabelList= d.Details
        .Where(detail => detail.StockDetails != null)
        .SelectMany(detail => detail.StockDetails)
        .Where(stockDetail => !string.IsNullOrEmpty(stockDetail.BoxCode))
        .Select(stockDetail => stockDetail.BoxCode )
        .ToList()
                                }).ToList()
                            }
                        }
                    }
                }
                                };
                                var authResult = AuthenticateWithWMS();
                                if (authResult.IsSuccess)
                                {
                                    houseInboundPassBack.Context = new Dictionary<string, string>
            {
                { "Ticket", authResult.Ticket },
                { "InvOrgId", authResult.InvOrgId }
            };
                                    var response = HttpHelper.Post<MomRequestContent>(ReceiveWMSTaskin, houseInboundPassBack, "立库入库数量回传WMS");
                                    // 判断Success的值
                                    if (!response.Success)
                                    {
                                        throw new Exception($"操作失败: {response.Message ?? "未提供错误信息"}");
                                    }
                                }
                            }
                            else if (inboundOrder.OrderStatus == InboundStatusEnum.入库完成.ObjToInt() && inboundOrder.OrderType == 2 && inboundOrder.System.Equals("SMOM"))
                            {
                                SendAllocateInfoToWMS(task, inboundOrder, dt_StockInfo);
                            }
                            _unitOfWorkManage.CommitTran();
                            return WebResponseContent.Instance.OK();
                        }
                        catch (Exception ex)
                        {
                            _unitOfWorkManage.RollbackTran();
                            throw new Exception($"入库处理失败:{ex.Message}", ex);
                        }
                    }
                }
                else
                {
                    Dt_InboundOrder? inboundOrder = _inboundService.InbounOrderService.Db.Queryable<Dt_InboundOrder>().Where(x => x.OrderNo == dt_StockInfo.Details.FirstOrDefault().OrderNo).Includes(x => x.Details).First();
                    Dt_InboundOrderDetail? inboundOrderDetail = null;
                    // 3. 处理入库逻辑
                    if (task.TaskType == TaskTypeEnum.Inbound.ObjToInt())
                    {
                        return ProcessInbound(task, dt_StockInfo, dt_LocationInfo);
                    }
                    if (task.TaskType == TaskTypeEnum.SurplusReturn.ObjToInt() || task.TaskType == TaskTypeEnum.ReverseIn.ObjToInt())
                    {
                        return ReturnInbound(task, dt_StockInfo, dt_LocationInfo);
                    }
                    if (task.TaskType == TaskTypeEnum.InInventory.ObjToInt())
                    {
                        int lastStatus = dt_LocationInfo.LocationStatus;
                        dt_LocationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
                        dt_StockInfo.StockStatus = StockStatusEmun.入库完成.ObjToInt();
                        // 更新库存明细状态
                        dt_StockInfo.Details.ForEach(x => x.Status = StockStatusEmun.入库完成.ObjToInt());
                        _unitOfWorkManage.BeginTran();
                        UpdateTaskStatus(task);
                        UpdateLocationStatus(dt_LocationInfo, lastStatus);
                        UpdateStockInfo(dt_StockInfo);
                        AddRecords(task, dt_StockInfo, dt_LocationInfo, lastStatus);
                        _unitOfWorkManage.CommitTran();
                        return WebResponseContent.Instance.OK();
                    }
                }
                return WebResponseContent.Instance.OK();
            }
            catch (Exception ex)
@@ -887,7 +1185,7 @@
                                System = returnOrder.System,
                            }
                        }
                   }
                   }
                }
            };
            var authResult = AuthenticateWithWMS();
@@ -910,7 +1208,7 @@
                    // 如果Success为false,抛出异常并包含错误信息
                    throw new Exception($"操作失败: {response.Message ?? "未提供错误信息"}");
                }
            }
            return WebResponseContent.Instance.OK();
        }
@@ -1136,7 +1434,7 @@
            if (stockInfo == null) return WebResponseContent.Instance.Error("未找到库存信息");
            if (locationInfo == null) return WebResponseContent.Instance.Error("未找到货位信息");
            if ((outStockLockInfos == null || outStockLockInfos.Count == 0)&& task.TaskType != TaskTypeEnum.OutInventory.ObjToInt())
            if ((outStockLockInfos == null || outStockLockInfos.Count == 0) && task.TaskType != TaskTypeEnum.OutInventory.ObjToInt())
                return WebResponseContent.Instance.Error("未找到出库详情信息");
            return WebResponseContent.Instance.OK();
@@ -1243,7 +1541,7 @@
            {
                if (inboundOrderDetail == null) continue;
                inboundOrderDetail.OverOutQuantity += item.OutboundQuantity;
                inboundOrderDetail.OverOutQuantity += item.OutboundQuantity;
                if (inboundOrderDetail.OverOutQuantity == inboundOrderDetail.OrderQuantity)
                {