using AutoMapper; 
 | 
using MailKit.Search; 
 | 
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; 
 | 
using SqlSugar; 
 | 
using System; 
 | 
using System.Collections.Generic; 
 | 
using System.Linq; 
 | 
using System.Text; 
 | 
using System.Threading.Tasks; 
 | 
using WIDESEA_Core; 
 | 
using WIDESEA_Core.BaseServices; 
 | 
using WIDESEA_Core.Enums; 
 | 
using WIDESEA_Core.Helper; 
 | 
using WIDESEA_DTO.Stock; 
 | 
using WIDESEA_IBasicRepository; 
 | 
using WIDESEA_IOutboundRepository; 
 | 
using WIDESEA_IRecordRepository; 
 | 
using WIDESEA_IRecordService; 
 | 
using WIDESEA_IStockRepository; 
 | 
using WIDESEA_IStockService; 
 | 
using WIDESEA_Model.Models; 
 | 
  
 | 
namespace WIDESEA_StockService 
 | 
{ 
 | 
    public partial class StockInfoService : ServiceBase<Dt_StockInfo, IStockInfoRepository>, IStockInfoService 
 | 
    { 
 | 
        private readonly IMapper _mapper; 
 | 
        private readonly IBasicRepository _basicRepository; 
 | 
        private readonly IOutboundRepository _outboundRepository; 
 | 
  
 | 
        public IStockInfoRepository Repository => BaseDal; 
 | 
  
 | 
        public StockInfoService(IStockInfoRepository BaseDal, IMapper mapper, IBasicRepository basicRepository, IOutboundRepository outboundRepository) : base(BaseDal) 
 | 
        { 
 | 
            _mapper = mapper; 
 | 
            _basicRepository = basicRepository; 
 | 
            _outboundRepository = outboundRepository; 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 查询订单立库库存视图 
 | 
        /// </summary> 
 | 
        /// <param name="orderId"></param> 
 | 
        /// <param name="materielCode"></param> 
 | 
        /// <returns></returns> 
 | 
        public List<StockSelectViewDTO> GetStockSelectViews(int orderId, string materielCode) 
 | 
        { 
 | 
            try 
 | 
            { 
 | 
                Dt_OutboundOrder outboundOrder = _outboundRepository.OutboundOrderRepository.QueryFirst(x => x.Id == orderId); 
 | 
                if (outboundOrder == null) 
 | 
                { 
 | 
                    throw new Exception($"未找到出库单信息"); 
 | 
                } 
 | 
  
 | 
                List<string> locationCodes = _basicRepository.LocationInfoRepository.GetCanOutLocationCodes(outboundOrder.WarehouseId); 
 | 
  
 | 
                return BaseDal.QueryTabs<Dt_StockInfo, Dt_StockInfoDetail, StockSelectViewDTO>((a, b) => a.Id == b.StockId, (a, b) => new StockSelectViewDTO 
 | 
                { 
 | 
                    LocationCode = a.LocationCode, 
 | 
                    MaterielCode = b.MaterielCode, 
 | 
                    MaterielName = b.MaterielName, 
 | 
                    PalletCode = a.PalletCode, 
 | 
                    UseableQuantity = b.StockQuantity - b.OutboundQuantity 
 | 
                }, a => locationCodes.Contains(a.LocationCode), b => b.StockQuantity > b.OutboundQuantity && b.MaterielCode == materielCode, x => true).GroupBy(x => x.PalletCode).Select(x => new StockSelectViewDTO 
 | 
                { 
 | 
                    LocationCode = x.FirstOrDefault()?.LocationCode ?? "", 
 | 
                    MaterielCode = x.FirstOrDefault()?.MaterielCode ?? "", 
 | 
                    MaterielName = x.FirstOrDefault()?.MaterielName ?? "", 
 | 
                    PalletCode = x.Key, 
 | 
                    UseableQuantity = x.Sum(x => x.UseableQuantity) 
 | 
                }).ToList(); 
 | 
            } 
 | 
            catch (Exception ex) 
 | 
            { 
 | 
                return null; 
 | 
            } 
 | 
  
 | 
        } 
 | 
        /// <summary> 
 | 
        /// 查询订单平库库存视图 
 | 
        /// </summary> 
 | 
        /// <param name="orderId"></param> 
 | 
        /// <param name="materielCode"></param> 
 | 
        /// <returns></returns> 
 | 
        public List<StockSelectViewDTO> GetPKStockSelectViews(int orderId, string materielCode) 
 | 
        { 
 | 
            try 
 | 
            { 
 | 
                Dt_OutboundOrder outboundOrder = _outboundRepository.OutboundOrderRepository.QueryFirst(x => x.Id == orderId); 
 | 
                if (outboundOrder == null) 
 | 
                { 
 | 
                    throw new Exception($"未找到出库单信息"); 
 | 
                } 
 | 
                return BaseDal.QueryTabs<Dt_StockInfo, Dt_StockInfoDetail, StockSelectViewDTO>((a, b) => a.Id == b.StockId && a.WarehouseId == outboundOrder.WarehouseId, (a, b) => new StockSelectViewDTO 
 | 
                { 
 | 
                    LocationCode = a.LocationCode, 
 | 
                    MaterielCode = b.MaterielCode, 
 | 
                    MaterielName = b.MaterielName, 
 | 
                    PalletCode = a.PalletCode, 
 | 
                    UseableQuantity = b.StockQuantity - b.OutboundQuantity 
 | 
                }, a => a.LocationCode == "平库位", b => b.StockQuantity > b.OutboundQuantity && b.MaterielCode == materielCode, x => true).GroupBy(x => x.PalletCode).Select(x => new StockSelectViewDTO 
 | 
                { 
 | 
                    LocationCode = x.FirstOrDefault()?.LocationCode ?? "", 
 | 
                    MaterielCode = x.FirstOrDefault()?.MaterielCode ?? "", 
 | 
                    MaterielName = x.FirstOrDefault()?.MaterielName ?? "", 
 | 
                    PalletCode = x.Key, 
 | 
                    UseableQuantity = x.Sum(x => x.UseableQuantity) 
 | 
                }).ToList(); 
 | 
            } 
 | 
            catch (Exception ex) 
 | 
            { 
 | 
                return null; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        public WebResponseContent StockQueryData(SaveModel saveModel) 
 | 
        { 
 | 
            try 
 | 
            { 
 | 
                var barcode = saveModel.MainData["barcode"].ToString(); 
 | 
                var warehouseId = saveModel.MainData["warehouseId"].ObjToInt(); 
 | 
                Dt_StockInfo stockInfo = BaseDal.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletCode == barcode && x.WarehouseId == warehouseId).Includes(x => x.Details).First(); 
 | 
                if (stockInfo == null) throw new Exception("未找到托盘信息"); 
 | 
                return WebResponseContent.Instance.OK(data: stockInfo); 
 | 
            } 
 | 
            catch (Exception ex) 
 | 
            { 
 | 
                return WebResponseContent.Instance.Error(ex.Message); 
 | 
            } 
 | 
        } 
 | 
        /// <summary> 
 | 
        ///  
 | 
        /// </summary> 
 | 
        /// <param name="stockInfos"></param> 
 | 
        /// <param name="materielCode"></param> 
 | 
        /// <param name="needQuantity"></param> 
 | 
        /// <param name="residueQuantity"></param> 
 | 
        /// <returns></returns> 
 | 
        public List<Dt_StockInfo> GetOutboundStocks(List<Dt_StockInfo> stockInfos, string materielCode, float needQuantity, out float residueQuantity) 
 | 
        { 
 | 
            List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>(); 
 | 
            float stockTotalQuantity = stockInfos.Select(x => x.Details.Sum(v => v.StockQuantity - v.OutboundQuantity)).Sum(x => x); 
 | 
            stockInfos = stockInfos.OrderBy(x => x.Id).ToList(); 
 | 
            if (stockTotalQuantity >= needQuantity)//库存够 
 | 
            { 
 | 
                int index = 0; 
 | 
                while (needQuantity > 0) 
 | 
                { 
 | 
                    Dt_StockInfo stockInfo = stockInfos[index]; 
 | 
                    float useableStockQuantity = stockInfo.Details.Where(x => x.MaterielCode == materielCode).Sum(x => x.StockQuantity - x.OutboundQuantity); 
 | 
                    if (useableStockQuantity < needQuantity) 
 | 
                    { 
 | 
                        stockInfo.Details.ForEach(x => x.OutboundQuantity = x.StockQuantity); 
 | 
                        needQuantity -= useableStockQuantity; 
 | 
                    } 
 | 
                    else 
 | 
                    { 
 | 
                        stockInfo.Details.ForEach(x => 
 | 
                        { 
 | 
                            if (x.StockQuantity > x.OutboundQuantity && x.MaterielCode == materielCode) 
 | 
                            { 
 | 
                                if (x.StockQuantity - x.OutboundQuantity >= needQuantity) 
 | 
                                { 
 | 
                                    x.OutboundQuantity += needQuantity; 
 | 
                                    needQuantity = 0; 
 | 
                                } 
 | 
                                else 
 | 
                                { 
 | 
                                    needQuantity -= (x.StockQuantity - x.OutboundQuantity); 
 | 
                                    x.OutboundQuantity = x.StockQuantity; 
 | 
                                } 
 | 
                            } 
 | 
                        }); 
 | 
                    } 
 | 
                    outStocks.Add(stockInfo); 
 | 
                    index++; 
 | 
                } 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                for (int i = 0; i < stockInfos.Count; i++) 
 | 
                { 
 | 
                    Dt_StockInfo stockInfo = stockInfos[i]; 
 | 
                    float useableStockQuantity = stockInfo.Details.Where(x => x.MaterielCode == materielCode).Sum(x => x.StockQuantity - x.OutboundQuantity); 
 | 
                    if (useableStockQuantity < needQuantity) 
 | 
                    { 
 | 
                        stockInfo.Details.ForEach(x => x.OutboundQuantity = x.StockQuantity); 
 | 
                        needQuantity -= useableStockQuantity; 
 | 
                    } 
 | 
                    else 
 | 
                    { 
 | 
                        stockInfo.Details.ForEach(x => 
 | 
                        { 
 | 
                            if (x.StockQuantity > x.OutboundQuantity && x.MaterielCode == materielCode) 
 | 
                            { 
 | 
                                if (x.StockQuantity - x.OutboundQuantity >= needQuantity) 
 | 
                                { 
 | 
                                    x.OutboundQuantity += needQuantity; 
 | 
                                    needQuantity = 0; 
 | 
                                } 
 | 
                                else 
 | 
                                { 
 | 
                                    needQuantity -= (x.StockQuantity - x.OutboundQuantity); 
 | 
                                    x.OutboundQuantity = x.StockQuantity; 
 | 
                                } 
 | 
                            } 
 | 
                        }); 
 | 
                    } 
 | 
                    outStocks.Add(stockInfo); 
 | 
                } 
 | 
            } 
 | 
            residueQuantity = needQuantity; 
 | 
            return outStocks; 
 | 
        } 
 | 
  
 | 
        public List<Dt_StockInfo> GetUseableStocks(string materielCode, string batchNo, int warehoseId) 
 | 
        { 
 | 
            List<string> locationCodes = _basicRepository.LocationInfoRepository.GetCanOutLocationCodes(warehoseId); 
 | 
  
 | 
            return BaseDal.GetStockInfos(materielCode, batchNo, locationCodes); 
 | 
        } 
 | 
    } 
 | 
} 
 |