using AngleSharp.Dom; using Mapster; using Masuit.Tools; using NewLife.Reflection; using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; using SqlSugar; using System.Collections; using System.Collections.Generic; using System.Drawing.Printing; using System.Linq.Expressions; using System.Threading.Tasks; using WIDESEA_Cache; using WIDESEA_Common; using WIDESEA_Core; using WIDESEA_DTO; using WIDESEA_DTO.Basic; using WIDESEA_DTO.Stock; using WIDESEA_IOrderRepository; using WIDESEA_Model.Models; using WIDESEA_Model.Models.Order; using WIDESEA_OrderRepository; namespace WIDESEA_StorageBasicService; public class StockInfoService : ServiceBase, IStockInfoService { private readonly ILocationStatusChangeRecordRepository _locationStatusChangeRecordRepository; private readonly IDt_InboundOrderRepository _inboundOrderRepository; private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IDt_OutboundOrderRepository _outorderRepository; private readonly IDt_OutboundOrderDetailRepository _outorderdetailRepository; public StockInfoService(IStockInfoRepository BaseDal, ILocationStatusChangeRecordRepository locationStatusChangeRecordRepository, IDt_InboundOrderRepository inboundOrderRepository, IUnitOfWorkManage unitOfWorkManage, IDt_OutboundOrderRepository outorderRepository, IDt_OutboundOrderDetailRepository outorderdetailRepository) : base(BaseDal) { _locationStatusChangeRecordRepository = locationStatusChangeRecordRepository; _inboundOrderRepository = inboundOrderRepository; _unitOfWorkManage = unitOfWorkManage; _outorderRepository = outorderRepository; _outorderdetailRepository = outorderdetailRepository; } /// /// 分页 /// /// /// public override PageGridData GetPageData(PageDataOptions options) { string wheres = ValidatePageOptions(options); //获取排序字段 Dictionary orderbyDic = GetPageDataSort(options, TProperties); List orderByModels = new List(); foreach (var item in orderbyDic) { OrderByModel orderByModel = new() { FieldName = item.Key, OrderByType = item.Value }; orderByModels.Add(orderByModel); } int totalCount = 0; List searchParametersList = new List(); if (!string.IsNullOrEmpty(options.Wheres)) { try { searchParametersList = options.Wheres.DeserializeObject>(); options.Filter = searchParametersList; } catch { } } Expression> locationStatus = null; Expression> floor = null; Expression> areaId = null; Expression> materielCode = null; foreach (var item in searchParametersList) { if (item.Name.Contains("locationStatus")) { locationStatus = x => x.LocationInfo.LocationStatus == Convert.ToInt32(item.Value); } else if (item.Name.Contains("floor")) { floor = x => x.LocationInfo.Floor.Contains(item.Value); } else if (item.Name.Contains("areaId")) { areaId = x => x.LocationInfo.AreaId== Convert.ToInt32(item.Value); } else if (item.Name.Contains("materielCode")) { materielCode = x => x.StockInfoDetails.Any(d => d.MaterielCode == item.Value); } } //.IncludesAllFirstLayer() var data = BaseDal.Db.Queryable() .Includes(x => x.StockInfoDetails) .Includes(x => x.LocationInfo) .WhereIF(!wheres.IsNullOrEmpty(), wheres) .WhereIF(locationStatus != null, locationStatus) .WhereIF(floor != null, floor) .WhereIF(areaId != null, areaId) .WhereIF(materielCode != null, materielCode) .OrderBy(orderByModels) .ToPageList(options.Page, options.Rows, ref totalCount); new PageGridData(totalCount, data); return new PageGridData(totalCount, data); } public List GetStockSelectViews(string materielCode) { var stock = BaseDal.Db.Queryable() .Includes(x => x.StockInfoDetails) .Includes(x => x.LocationInfo) .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) .Where(x => x.StockInfoDetails.Any(d => d.MaterielCode == materielCode && d.Quantity > 0)).ToList().OrderBy(x=>x.CreateDate); var result = stock.Select(s => new StockSelectViewDTO { MaterielCode = s.StockInfoDetails .FirstOrDefault(d => d.MaterielCode == materielCode)?.MaterielCode ?? string.Empty, MaterielName = s.StockInfoDetails .FirstOrDefault(d => d.MaterielCode == materielCode)?.MaterielName ?? string.Empty, UseableQuantity = s.StockInfoDetails .Where(d => d.MaterielCode == materielCode && d.Quantity > 0) .Sum(d => (decimal?)d.Quantity) ?? 0, // 处理空值情况 PalletCode = s.PalletCode ?? string.Empty, LocationCode = s.LocationInfo?.LocationCode ?? string.Empty }).ToList(); return result; } #region 根据单据明细生成出库任务 public WebResponseContent GenerateOutboundTask(GenerateOutTaskDto requestOut) { WebResponseContent content = new WebResponseContent(); try { List taskDtos = new List(); Dt_OutboundOrder outboundOrder = _outorderRepository.QueryFirst(x => x.Id == requestOut.orderId); if (outboundOrder == null) { throw new Exception("未找到出库单明细信息!"); } List? stockInfos = null; Dt_OutboundOrderDetail? orderDetail = null; List? locationInfos = null; if (outboundOrder.OrderStatus != OrderStateEmun.已完成.ObjToInt()) { return content.Error("该出库单已完成,无法生成出库任务"); } else { if (requestOut.stockViews.Count == 0) { } else { foreach (var item in requestOut.stockViews) { decimal availableQuantity = item.UseableQuantity; if (availableQuantity <= 0) { continue; // 无可用库存,继续下一个 } var stock = BaseDal.QueryFirst(x => x.LocationCode == item.LocationCode && x.PalletCode == item.PalletCode); // 创建任务 RequestTaskDto task = new RequestTaskDto { TaskType = outboundOrder.OrderStatus, OrderNo = outboundOrder.OrderNo, MaterielCode = item.MaterielCode, Position = item.LocationCode, }; taskDtos.Add(task); } } } return content.OK("出库任务生成成功"); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion 根据单据明细生成出库任务 public async Task AddGroupPlateAsync(GroupPlate groupPlate) { WebResponseContent content = new WebResponseContent(); try { if (groupPlate == null || groupPlate.OrderNos.IsNullOrEmpty() || groupPlate.palletCode.IsNullOrEmpty()) { return content.Error("参数错误"); } var info = await BaseDal.QueryFirstAsync(x => x.PalletCode == groupPlate.palletCode); if (!info.IsNullOrEmpty()) { content.Error("该托盘已存在组盘"); } else { List details = new List(); foreach (var item in groupPlate.OrderNos) { var InboundOrder = _inboundOrderRepository.QueryFirst(x => x.OrderNo == item); if (InboundOrder != null) { var x = details.Where(x => x.MaterielCode == InboundOrder.MaterialNo && x.Warehouse == InboundOrder.WarehouseName && x.DrawingNumber == InboundOrder.ProductDrawingNumber && x.DemandClassification == InboundOrder.DemandClassification).FirstOrDefault(); if (x != null) { details.Remove(x); x.MaterielCode = InboundOrder.MaterialNo; x.MaterielName = InboundOrder.MaterialName; x.DemandClassification = InboundOrder.DemandClassification; x.Warehouse = InboundOrder.WarehouseName; x.OrderNo = InboundOrder.UpperOrderNo; x.Unit = InboundOrder.Unit; x.Specs = InboundOrder.Specs; x.Weight = InboundOrder.Weight; x.Quantity = x.Quantity + InboundOrder.Quantity; x.DrawingNumber = InboundOrder.ProductDrawingNumber; x.Date = InboundOrder.Datetime; details.Add(x); } else { DtStockInfoDetail detail = new DtStockInfoDetail() { MaterielCode = InboundOrder.MaterialNo, MaterielName = InboundOrder.MaterialName, DemandClassification = InboundOrder.DemandClassification, Warehouse = InboundOrder.WarehouseName, OrderNo = InboundOrder.UpperOrderNo, Unit = InboundOrder.Unit, Specs = InboundOrder.Specs, Weight = InboundOrder.Weight, Quantity = InboundOrder.Quantity, DrawingNumber = InboundOrder.ProductDrawingNumber, Date = InboundOrder.Datetime, }; details.Add(detail); } } else { return content.Error("未找到入库单据信息"); } } DtStockInfo boxing = new DtStockInfo() { PalletCode = groupPlate.palletCode, StockStatus = (int)StockStateEmun.组盘暂存, StockInfoDetails = details }; await BaseDal.AddDataNavAsync(boxing); content.OK("组盘成功"); } return content; } catch (Exception ex) { return content.Error(ex.Message); } } public async Task DeleteGroupPlateAsync(GroupPlate groupPlate) { WebResponseContent content = new WebResponseContent(); try { if (groupPlate == null || groupPlate.palletCode.IsNullOrEmpty()) { return content.Error("参数错误"); } var stock = await BaseDal.QueryFirstNavAsync(x => x.PalletCode == groupPlate.palletCode && x.StockStatus == (int)StockStateEmun.组盘暂存); if (!stock.IsNullOrEmpty()) { stock.StockStatus = (int)StockStateEmun.组盘撤销; DtStockInfo_Hty stockhty = stock.Adapt(); stockhty.ModifyDate = DateTime.Now; await _unitOfWorkManage.UseTranAsync(async () => { await BaseDal.Db.DeleteNav(x => x.Id == stock.Id) .Include(x => x.StockInfoDetails) .ExecuteCommandAsync(); await AddStockHtyAsync(stockhty); }); content.OK("解盘成功"); } else { content.Error("未找到组盘数据"); } return content; } catch (Exception ex) { return content.Error(ex.Message); } } private async Task AddStockHtyAsync(DtStockInfo_Hty stockhty) { var isStockAdd = await SqlSugarHelper.DbWMS.InsertNav(stockhty).IncludesAllFirstLayer().ExecuteCommandAsync(); if (!isStockAdd) { throw new Exception("库存历史信息添加失败"); } } /// /// 批量删除 /// /// /// public override WebResponseContent DeleteData(object[] keys) { try { List stockInfos = new List(); List locationInfos = new List(); foreach (var item in keys) { var stock = BaseDal.QueryFirstNavAsync(x => x.Id == item.ObjToInt()).Result; var stockHty = stock.Adapt(); stockInfos.Add(stockHty); var location = SqlSugarHelper.DbWMS.Queryable().FirstAsync(x => x.LocationCode == stock.LocationCode).Result; var lastStatus = location.LocationStatus; location.LocationStatus = (int)LocationEnum.Free; locationInfos.Add(location); _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.ManualOperation, 0); } //var hty = BaseDal.Db.InsertNav(stockInfos) // .Include(x => x.StockInfoDetails) // .ExecuteCommand(); var isStockAdd = SqlSugarHelper.DbWMS.InsertNav(stockInfos).IncludesAllFirstLayer().ExecuteCommandAsync(); var locationd = SqlSugarHelper.DbWMS.Updateable(locationInfos).ExecuteCommandHasChange(); return base.DeleteData(keys); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } }