wangxinhui
2025-03-31 638a684258fb4bc6adf76a1964bdf0d7f99e404f
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/ProOutOrderService.cs
@@ -1,21 +1,28 @@
using AutoMapper;
using Castle.Core.Resource;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Common.OrderEnum;
using WIDESEA_Common.StockEnum;
using WIDESEA_Common.WareHouseEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
using WIDESEA_Core.CodeConfigEnum;
using WIDESEA_Core.Enums;
using WIDESEA_Core.Helper;
using WIDESEA_DTO.ERP;
using WIDESEA_External.ERPService;
using WIDESEA_External.Model;
using WIDESEA_IBasicRepository;
using WIDESEA_IBasicService;
using WIDESEA_IOutboundRepository;
using WIDESEA_IOutboundService;
using WIDESEA_IRecordService;
using WIDESEA_IStockRepository;
using WIDESEA_IStockService;
using WIDESEA_Model.Models;
@@ -26,14 +33,22 @@
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly IBasicRepository _basicRepository;
        private readonly IMapper _mapper;
        private readonly IStockRepository _stockRepository;
        private readonly IOutboundRepository _outboundRepository;
        private readonly IOutboundOrderService _outboundOrderService;
        private readonly IInvokeERPService _invokeERPService;
        public IProOutOrderRepository Repository => BaseDal;
        public ProOutOrderService(IProOutOrderRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IBasicRepository basicRepository, IMapper mapper) : base(BaseDal)
        public ProOutOrderService(IProOutOrderRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IBasicRepository basicRepository, IMapper mapper, IStockRepository stockRepository, IOutboundRepository outboundRepository, IOutboundOrderService outboundOrderService,IInvokeERPService invokeERPService) : base(BaseDal)
        {
            _unitOfWorkManage = unitOfWorkManage;
            _basicRepository = basicRepository;
            _mapper = mapper;
            _stockRepository = stockRepository;
            _outboundRepository = outboundRepository;
            _outboundOrderService = outboundOrderService;
            _invokeERPService = invokeERPService;
        }
        /// <summary>
        /// æŽ¥æ”¶ERP成品出库单
@@ -70,6 +85,7 @@
                    return content.Error($"出库单号{outOrderDTO.OrderNo}已存在!");
                }
                Dt_Warehouse warehouse=null;
                List<Dt_CustomerInfo> customerInfos = _basicRepository.CustomerInfoRepository.QueryData();
                if (outOrderDTO.OType==1 && string.IsNullOrEmpty(outOrderDTO.WaType))
                {
                    warehouse = _basicRepository.WarehouseRepository.QueryFirst(x=>x.WarehouseCode==WarehouseEnum.HA71.ToString());
@@ -81,6 +97,12 @@
                List<Dt_ProOutOrderDetail> proOutOrderDetails = new List<Dt_ProOutOrderDetail>();
                foreach (var item in outOrderDTO.OrderDetails)
                {
                    //判断客户是否存在
                    Dt_CustomerInfo? customerInfo = customerInfos.Where(x=>x.Code== item.Customer).FirstOrDefault();
                    if (customerInfo==null)
                    {
                        return content.Error($"客户{item.Customer}不存在!");
                    }
                    proOutOrderDetails.Add(_mapper.Map<Dt_ProOutOrderDetail>(item));
                }
                Dt_ProOutOrder  proOutOrder= new Dt_ProOutOrder()
@@ -136,5 +158,329 @@
            }
            return content;
        }
        /// <summary>
        /// æˆå“å‡ºå¾…发货区(平库)+同步ERP出库(绑定了出库单库存)
        /// </summary>
        /// <returns></returns>
        public WebResponseContent OutProductPK(string[] OutPKCodes,string ProOutNo)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (OutPKCodes.IsNullOrEmpty())
                {
                    return content.Error("不能为空");
                }
                Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.Db.Queryable<Dt_ProOutOrder>().Where(x => x.ProOutOrderNo == ProOutNo).Includes(x => x.Details).First();
                if (proOutOrder == null)
                {
                    return content.Error($"出库单{ProOutNo}不存在");
                }
                if (proOutOrder.ProOrderStatus==OutOrderStatusEnum.出库完成.ObjToInt())
                {
                    return content.Error($"出库单{ProOutNo}已完成");
                }
                string? userName = App.User.UserName;//GSWMS
                //获取所有外箱的数据
                List<Dt_ProStockInfo> AllproStockInfos = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>()
                    .Where(x => OutPKCodes.Contains(x.PalletCode) && x.ShipmentOrder == proOutOrder.ProOutOrderNo && x.StockStatus == StockStatusEmun.平库入库完成.ObjToInt())
                    .Includes(x => x.proStockInfoDetails).ToList();
                if (AllproStockInfos.Count<=0)
                {
                    return content.Error($"出库单{ProOutNo}已无绑定库存");
                }
                List<Dt_ProStockInfo> proStockInfos = new List<Dt_ProStockInfo>();
                List<Dt_ProStockInfoDetail> proStockInfoDetails=new List<Dt_ProStockInfoDetail>();
                List<Dt_Warehouse> warehouses = _basicRepository.WarehouseRepository.QueryData(x => x.WarehouseType == WarehouseTypEnum.成品.ToString());
                foreach (var item in OutPKCodes)
                {
                    //获取库存
                    Dt_ProStockInfo? proStockInfo = AllproStockInfos.Where(x => x.PalletCode == item).FirstOrDefault();
                    if (proStockInfo == null)
                    {
                        return content.Error($"未找到{item}库存");
                    }
                    Dt_Warehouse? dt_Warehouse = warehouses.Where(x=>x.WarehouseId== proStockInfo.WarehouseId).FirstOrDefault();
                    if (dt_Warehouse==null)
                    {
                        return content.Error($"外箱号{item},不属于成品仓");
                    }
                    if (proStockInfo.ShipmentOrder!= proOutOrder.ProOutOrderNo)
                    {
                        return content.Error($"外箱号{item},不属于出库订单{proOutOrder.ProOutOrderNo}");
                    }
                    proStockInfos.Add(proStockInfo);
                    proStockInfoDetails.AddRange(proStockInfo.proStockInfoDetails);
                }
                if (proOutOrder.Details.Sum(x=>x.LockQtyPcs-x.OverQtyPcs)< proStockInfoDetails.Sum(x=>x.StockPcsQty))
                {
                    return content.Error($"出库数量{proStockInfoDetails.Sum(x => x.StockPcsQty)}>所剩订单数量{proOutOrder.Details.Sum(x => x.LockQtyPcs - x.OverQtyPcs)}");
                }
                List<StockOutItemsItem> stockOutItems = new List<StockOutItemsItem>();
                List<Dt_ProOutOrderDetail> proOutOrderDetails = proOutOrder.Details.Where(x=> proStockInfoDetails.Select(x=>x.SaleOrder).Contains(x.SaleOrder) && proStockInfoDetails.Select(x=>x.ProductCode).Contains(x.PCode) && proStockInfoDetails.Select(x => x.ProductVersion).Contains(x.PVer)).ToList();
                if (proOutOrderDetails==null || proOutOrderDetails.Count<=0)
                {
                    return content.Error("对应出库订单明细为空");
                }
                int OldOverCount = proOutOrder.Details.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count();
                foreach (var item in proStockInfoDetails)
                {
                    //获取对应明细处理出库数据
                    Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrderDetails.Where(x => x.SaleOrder == item.SaleOrder && x.PVer == item.ProductVersion && x.PCode == item.ProductCode).FirstOrDefault();
                    if (proOutOrderDetail==null)
                    {
                        return content.Error("未找到对应出库订单明细");
                    }
                    proOutOrderDetail.OverQtyPcs += item.StockPcsQty;
                    if (proOutOrderDetail.OverQtyPcs> proOutOrderDetail.QtyPcs)
                    {
                        return content.Error($"出库订单明细行{proOutOrderDetail.RowId},溢出{proOutOrderDetail.QtyPcs - proOutOrderDetail.OverQtyPcs}");
                    }
                    if (proOutOrderDetail.OverQtyPcs == proOutOrderDetail.QtyPcs)
                    {
                        proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt();
                    }
                }
                int AddOverCount = proOutOrderDetails.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count();
                if (proOutOrder.Details.Count == (AddOverCount + OldOverCount))
                {
                    proOutOrder.ProOrderStatus = OutOrderStatusEnum.出库完成.ObjToInt();
                    //获取所有已扫码待发货的库存
                    List<Dt_ProStockInfo> AllOutStocks = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>()
                    .Where(x => x.ShipmentOrder== ProOutNo && x.StockStatus == StockStatusEmun.平库待发货.ObjToInt())
                    .Includes(x => x.proStockInfoDetails).ToList();
                    AllOutStocks.ForEach(x =>
                    {
                        proStockInfoDetails.AddRange(x.proStockInfoDetails);
                    });
                    proStockInfos.AddRange(AllOutStocks);
                    foreach (var item in proStockInfoDetails)
                    {
                        StockOutItemsItem outItemsItem = new StockOutItemsItem()
                        {
                            PartNum = item.ProductCode,
                            Rev = item.ProductVersion,
                            SoNumber = item.SaleOrder,
                            BatchNumber = item.BagNo,
                            QtyPcs = item.StockPcsQty,
                            QtySet = item.SETQty
                        };
                        stockOutItems.Add(outItemsItem);
                    }
                }
                _unitOfWorkManage.BeginTran();
                Dt_Warehouse warehouse = warehouses.Where(x => x.WarehouseId == proOutOrder.WarehouseId).FirstOrDefault();
                //处理库存数据和上传ERP
                if (proOutOrder.ProOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt())
                {
                    //成品库存记录变动待加入
                    ERPProOutOrderModel proOutOrderModel = new ERPProOutOrderModel()
                    {
                        Way = 1,
                        StockOutCode = _outboundOrderService.CreateCodeByRule(nameof(RuleCodeEnum.ProOutCOdeRule)),
                        ConfirmedUserNo = "admin",
                        AssignUserNo = "admin",
                        WarehouseCode = warehouse.WarehouseCode,
                        ShipDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        DeliverplanCode = proOutOrder.ProOutOrderNo,
                        Remark = proOutOrder.Remark,
                        StockOutItems = stockOutItems
                    };
                    _stockRepository.ProStockInfoRepository.DeleteAndMoveIntoHty(proStockInfos, OperateTypeEnum.自动完成);
                    _stockRepository.ProStockInfoDetailRepository.DeleteAndMoveIntoHty(proStockInfoDetails, OperateTypeEnum.自动完成);
                    string response = _invokeERPService.InvokeProOutApi(proOutOrderModel);
                    ErpRequestContent erpRequestContent = response.DeserializeObject<ErpRequestContent>();
                    if (erpRequestContent.res != 1)
                    {
                        throw new Exception("同步ERP失败,错误信息:" + erpRequestContent.Data);
                    }
                }
                else
                {
                    proStockInfos.ForEach(x =>
                    {
                        x.StockStatus = StockStatusEmun.平库待发货.ObjToInt();
                    });
                    proStockInfoDetails.ForEach(x =>
                    {
                        x.ProOutDetailStatus = StockStatusEmun.平库待发货.ObjToInt();
                    });
                    _stockRepository.ProStockInfoRepository.UpdateData(proStockInfos);
                    _stockRepository.ProStockInfoDetailRepository.UpdateData(proStockInfoDetails);
                }
                _outboundRepository.ProOutOrderDetailRepository.UpdateData(proOutOrderDetails);
                BaseDal.UpdateData(proOutOrder);
                _unitOfWorkManage.CommitTran();
                content.OK();
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                content.Error(ex.Message);
            }
            return content;
        }
        /// <summary>
        /// æˆå“å‡ºå¾…发货区(平库)+同步ERP出库(未绑定出库单库存)
        /// </summary>
        /// <returns></returns>
        public WebResponseContent OutProductNoPK(string[] OutPKCodes, string ProOutNo)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (OutPKCodes.IsNullOrEmpty())
                {
                    return content.Error("不能为空");
                }
                Dt_ProOutOrder proOutOrder = _outboundRepository.ProOutOrderRepository.Db.Queryable<Dt_ProOutOrder>().Where(x => x.ProOutOrderNo == ProOutNo).Includes(x => x.Details).First();
                if (proOutOrder == null)
                {
                    return content.Error($"出库单{ProOutNo}不存在");
                }
                if (proOutOrder.ProOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt())
                {
                    return content.Error($"出库单{ProOutNo}已完成");
                }
                string? userName = App.User.UserName;//GSWMS
                //获取所有外箱的数据
                List<Dt_ProStockInfo> AllproStockInfos = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>()
                    .Where(x => OutPKCodes.Contains(x.PalletCode) && x.StockStatus == StockStatusEmun.平库入库完成.ObjToInt())
                    .Includes(x => x.proStockInfoDetails).ToList();
                List<Dt_ProStockInfo> proStockInfos = new List<Dt_ProStockInfo>();
                List<Dt_ProStockInfoDetail> proStockInfoDetails = new List<Dt_ProStockInfoDetail>();
                List<Dt_Warehouse> warehouses = _basicRepository.WarehouseRepository.QueryData(x => x.WarehouseType == WarehouseTypEnum.成品.ToString());
                foreach (var item in OutPKCodes)
                {
                    //获取库存
                    Dt_ProStockInfo? proStockInfo = AllproStockInfos.Where(x => x.PalletCode == item).FirstOrDefault();
                    if (proStockInfo == null)
                    {
                        return content.Error($"未找到{item}库存");
                    }
                    if (proStockInfo.ShipmentOrder!=null)
                    {
                        return content.Error($"外箱号{item}为出库单{proStockInfo.ShipmentOrder}指定库存!");
                    }
                    Dt_Warehouse? dt_Warehouse = warehouses.Where(x => x.WarehouseId == proStockInfo.WarehouseId).FirstOrDefault();
                    if (dt_Warehouse == null)
                    {
                        return content.Error($"外箱号{item},不属于成品仓");
                    }
                    proStockInfos.Add(proStockInfo);
                    proStockInfoDetails.AddRange(proStockInfo.proStockInfoDetails);
                }
                if (proOutOrder.Details.Sum(x => x.QtyPcs - x.OverQtyPcs) < proStockInfoDetails.Sum(x => x.StockPcsQty))
                {
                    return content.Error($"出库数量{proStockInfoDetails.Sum(x => x.StockPcsQty)}>所剩订单数量{proOutOrder.Details.Sum(x => x.QtyPcs - x.OverQtyPcs)}");
                }
                List<StockOutItemsItem> stockOutItems = new List<StockOutItemsItem>();
                List<Dt_ProOutOrderDetail> proOutOrderDetails = proOutOrder.Details.Where(x => proStockInfoDetails.Select(x => x.SaleOrder).Contains(x.SaleOrder) && proStockInfoDetails.Select(x => x.ProductCode).Contains(x.PCode) && proStockInfoDetails.Select(x => x.ProductVersion).Contains(x.PVer)).ToList();
                if (proOutOrderDetails == null || proOutOrderDetails.Count <= 0)
                {
                    return content.Error("对应出库订单明细为空");
                }
                int OldOverCount = proOutOrder.Details.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count();
                foreach (var item in proStockInfoDetails)
                {
                    //获取对应明细处理出库数据
                    Dt_ProOutOrderDetail? proOutOrderDetail = proOutOrderDetails.Where(x => x.SaleOrder == item.SaleOrder && x.PVer == item.ProductVersion && x.PCode == item.ProductCode).FirstOrDefault();
                    if (proOutOrderDetail == null)
                    {
                        return content.Error("未找到对应出库订单明细");
                    }
                    proOutOrderDetail.OverQtyPcs += item.StockPcsQty;
                    if (proOutOrderDetail.OverQtyPcs > proOutOrderDetail.QtyPcs)
                    {
                        return content.Error($"出库订单明细行{proOutOrderDetail.RowId},溢出{proOutOrderDetail.QtyPcs - proOutOrderDetail.OverQtyPcs}");
                    }
                    if (proOutOrderDetail.OverQtyPcs == proOutOrderDetail.QtyPcs)
                    {
                        proOutOrderDetail.ProOrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt();
                    }
                }
                proStockInfos.ForEach(x =>
                {
                    x.StockStatus = StockStatusEmun.平库待发货.ObjToInt();
                });
                proStockInfoDetails.ForEach(x =>
                {
                    x.ProOutDetailStatus = StockStatusEmun.平库待发货.ObjToInt();
                });
                int AddOverCount = proOutOrderDetails.Where(x => x.ProOrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count();
                if (proOutOrder.Details.Count == (AddOverCount + OldOverCount))
                {
                    proOutOrder.ProOrderStatus = OutOrderStatusEnum.出库完成.ObjToInt();
                    //获取所有已扫码待发货的库存
                    List<Dt_ProStockInfo> AllOutStocks = _stockRepository.ProStockInfoRepository.Db.Queryable<Dt_ProStockInfo>()
                    .Where(x => x.ShipmentOrder == ProOutNo && x.StockStatus == StockStatusEmun.平库待发货.ObjToInt())
                    .Includes(x => x.proStockInfoDetails).ToList();
                    AllOutStocks.ForEach(x =>
                    {
                        proStockInfoDetails.AddRange(x.proStockInfoDetails);
                    });
                    proStockInfos.AddRange(AllOutStocks);
                    foreach (var item in proStockInfoDetails)
                    {
                        StockOutItemsItem outItemsItem = new StockOutItemsItem()
                        {
                            PartNum = item.ProductCode,
                            Rev = item.ProductVersion,
                            SoNumber = item.SaleOrder,
                            BatchNumber = item.BagNo,
                            QtyPcs = item.StockPcsQty,
                            QtySet = item.SETQty
                        };
                        stockOutItems.Add(outItemsItem);
                    }
                }
                _unitOfWorkManage.BeginTran();
                Dt_Warehouse warehouse = warehouses.Where(x => x.WarehouseId == proOutOrder.WarehouseId).FirstOrDefault();
                //处理库存数据和上传ERP
                if (proOutOrder.ProOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt())
                {
                    //成品库存记录变动待加入
                    ERPProOutOrderModel proOutOrderModel = new ERPProOutOrderModel()
                    {
                        Way = 1,
                        StockOutCode = _outboundOrderService.CreateCodeByRule(nameof(RuleCodeEnum.ProOutCOdeRule)),
                        ConfirmedUserNo = "admin",
                        AssignUserNo = "admin",
                        WarehouseCode = warehouse.WarehouseCode,
                        ShipDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        DeliverplanCode = proOutOrder.ProOutOrderNo,
                        Remark = proOutOrder.Remark,
                        StockOutItems = stockOutItems
                    };
                    _stockRepository.ProStockInfoRepository.DeleteAndMoveIntoHty(proStockInfos, OperateTypeEnum.自动完成);
                    _stockRepository.ProStockInfoDetailRepository.DeleteAndMoveIntoHty(proStockInfoDetails, OperateTypeEnum.自动完成);
                    string response = _invokeERPService.InvokeProOutApi(proOutOrderModel);
                    ErpRequestContent erpRequestContent = response.DeserializeObject<ErpRequestContent>();
                    if (erpRequestContent.res != 1)
                    {
                        throw new Exception("同步ERP失败,错误信息:" + erpRequestContent.Data);
                    }
                }
                else
                {
                    _stockRepository.ProStockInfoRepository.UpdateData(proStockInfos);
                    _stockRepository.ProStockInfoDetailRepository.UpdateData(proStockInfoDetails);
                }
                _outboundRepository.ProOutOrderDetailRepository.UpdateData(proOutOrderDetails);
                BaseDal.UpdateData(proOutOrder);
                _unitOfWorkManage.CommitTran();
                content.OK();
            }
            catch (Exception ex)
            {
                content.Error(ex.Message);
            }
            return content;
        }
    }
}