| 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); | 
|         } | 
|     } | 
| } |